From 757fff0e0c409e77fe31ffd8da13dd206b69a439 Mon Sep 17 00:00:00 2001 From: Henry Gressmann Date: Tue, 20 Aug 2024 11:47:33 +0200 Subject: [PATCH] chore: improve dashboard cards Signed-off-by: Henry Gressmann --- web/src/api/index.ts | 6 +- .../dimensions/dimensions.module.css | 50 ++++++++++++++++- web/src/components/dimensions/index.tsx | 55 +++++++++++++------ web/src/components/project.module.css | 1 + 4 files changed, 91 insertions(+), 21 deletions(-) diff --git a/web/src/api/index.ts b/web/src/api/index.ts index a1f4bbe..0d2e2ab 100644 --- a/web/src/api/index.ts +++ b/web/src/api/index.ts @@ -113,8 +113,10 @@ export const useDimension = ({ data: DimensionTableRow[] | undefined; biggest: number; order: string[] | undefined; + isLoading: boolean; + error: unknown; } => { - const { data } = useQuery({ + const { data, isLoading, error } = useQuery({ placeholderData: (prev) => prev, queryKey: ["dimension", project.id, dimension, metric, range], queryFn: () => @@ -133,7 +135,7 @@ export const useDimension = ({ const biggest = useMemo(() => data?.data?.reduce((acc, d) => Math.max(acc, d.value), 0) ?? 0, [data]); const order = useMemo(() => data?.data?.sort((a, b) => b.value - a.value).map((d) => d.dimensionValue), [data]); - return { data: data?.data, biggest, order }; + return { data: data?.data, biggest, order, isLoading, error }; }; export const invalidateProjects = () => queryClient.invalidateQueries({ queryKey: ["projects"] }); diff --git a/web/src/components/dimensions/dimensions.module.css b/web/src/components/dimensions/dimensions.module.css index ed026c9..f68cf4f 100644 --- a/web/src/components/dimensions/dimensions.module.css +++ b/web/src/components/dimensions/dimensions.module.css @@ -1,9 +1,12 @@ .card { padding: 1rem; + padding-bottom: 0.6rem; background-color: var(--pico-form-element-background-color); border-radius: var(--pico-border-radius); background: var(--pico-card-background-color); box-shadow: var(--pico-card-box-shadow); + display: flex; + flex-direction: column; } .tabs { @@ -13,7 +16,7 @@ margin-bottom: 1rem; } - button { + .tabsList > button { all: unset; cursor: pointer; @@ -26,6 +29,11 @@ margin-right: auto; } } + + .tabsContent { + display: flex; + flex-direction: column; + } } .percentage { @@ -66,9 +74,49 @@ margin-bottom: 1rem; } +.dimensionTable { + flex: 1; + display: flex; + flex-direction: column; + min-height: calc(var(--count) * (2.1rem + 0.2rem)); +} + +.showMore { + all: unset; + cursor: pointer; + color: var(--pico-contrast); + margin-top: 0.2rem; + display: flex; + justify-content: center; + align-items: center; + gap: 0.3rem; + transition: opacity 0.15s ease-in-out; + opacity: 0.6; + user-select: none; + + &:hover { + opacity: 1; + } +} + +.showMoreHidden { + opacity: 0; + pointer-events: none; +} + .dimensionRow { + height: 2.1rem; display: flex; justify-content: space-between; gap: 1rem; margin-bottom: 0.2rem; } + +.dimensionEmpty { + flex: 1; + display: flex; + justify-content: center; + align-items: center; + margin-bottom: 1rem; + opacity: 0.6; +} diff --git a/web/src/components/dimensions/index.tsx b/web/src/components/dimensions/index.tsx index 5d97c8e..92db446 100644 --- a/web/src/components/dimensions/index.tsx +++ b/web/src/components/dimensions/index.tsx @@ -1,5 +1,5 @@ import * as Tabs from "@radix-ui/react-tabs"; -import { LinkIcon } from "lucide-react"; +import { FullscreenIcon, LinkIcon, ZoomIn } from "lucide-react"; import styles from "./dimensions.module.css"; import { @@ -71,7 +71,7 @@ export const DimensionTabs = ({
{metricNames[metric]}
{dimensions.map((dimension) => ( - + ))} @@ -85,24 +85,43 @@ export const DimensionTable = ({ metric, range, }: { project: ProjectResponse; dimension: Dimension; metric: Metric; range: DateRange; noHeader?: boolean }) => { - const { data, biggest, order } = useDimension({ project, dimension, metric, range }); + const { data, biggest, order, isLoading } = useDimension({ project, dimension, metric, range }); + + const dataTruncated = data?.slice(0, 6); return ( -
- {data?.map((d) => { - return ( -
- - - -
{formatMetricVal(metric, d.value)}
+ <> +
+ {dataTruncated?.map((d) => { + return ( +
+ + + +
{formatMetricVal(metric, d.value)}
+
+ ); + })} + {/* {isLoading && dataTruncated?.length === 0 && ( + )} */} + {!isLoading && dataTruncated?.length === 0 && ( +
+
No data available
- ); - })} -
+ )} +
+ + ); }; diff --git a/web/src/components/project.module.css b/web/src/components/project.module.css index 74329cd..724ff97 100644 --- a/web/src/components/project.module.css +++ b/web/src/components/project.module.css @@ -52,6 +52,7 @@ div.graph { padding: 0; grid-column: span 2; display: flex; + flex-direction: row; > div { flex-direction: column;