Skip to content

Commit 757fff0

Browse files
chore: improve dashboard cards
Signed-off-by: Henry Gressmann <[email protected]>
1 parent 146427b commit 757fff0

File tree

4 files changed

+91
-21
lines changed

4 files changed

+91
-21
lines changed

web/src/api/index.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -113,8 +113,10 @@ export const useDimension = ({
113113
data: DimensionTableRow[] | undefined;
114114
biggest: number;
115115
order: string[] | undefined;
116+
isLoading: boolean;
117+
error: unknown;
116118
} => {
117-
const { data } = useQuery({
119+
const { data, isLoading, error } = useQuery({
118120
placeholderData: (prev) => prev,
119121
queryKey: ["dimension", project.id, dimension, metric, range],
120122
queryFn: () =>
@@ -133,7 +135,7 @@ export const useDimension = ({
133135
const biggest = useMemo(() => data?.data?.reduce((acc, d) => Math.max(acc, d.value), 0) ?? 0, [data]);
134136
const order = useMemo(() => data?.data?.sort((a, b) => b.value - a.value).map((d) => d.dimensionValue), [data]);
135137

136-
return { data: data?.data, biggest, order };
138+
return { data: data?.data, biggest, order, isLoading, error };
137139
};
138140

139141
export const invalidateProjects = () => queryClient.invalidateQueries({ queryKey: ["projects"] });

web/src/components/dimensions/dimensions.module.css

Lines changed: 49 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,12 @@
11
.card {
22
padding: 1rem;
3+
padding-bottom: 0.6rem;
34
background-color: var(--pico-form-element-background-color);
45
border-radius: var(--pico-border-radius);
56
background: var(--pico-card-background-color);
67
box-shadow: var(--pico-card-box-shadow);
8+
display: flex;
9+
flex-direction: column;
710
}
811

912
.tabs {
@@ -13,7 +16,7 @@
1316
margin-bottom: 1rem;
1417
}
1518

16-
button {
19+
.tabsList > button {
1720
all: unset;
1821
cursor: pointer;
1922

@@ -26,6 +29,11 @@
2629
margin-right: auto;
2730
}
2831
}
32+
33+
.tabsContent {
34+
display: flex;
35+
flex-direction: column;
36+
}
2937
}
3038

3139
.percentage {
@@ -66,9 +74,49 @@
6674
margin-bottom: 1rem;
6775
}
6876

77+
.dimensionTable {
78+
flex: 1;
79+
display: flex;
80+
flex-direction: column;
81+
min-height: calc(var(--count) * (2.1rem + 0.2rem));
82+
}
83+
84+
.showMore {
85+
all: unset;
86+
cursor: pointer;
87+
color: var(--pico-contrast);
88+
margin-top: 0.2rem;
89+
display: flex;
90+
justify-content: center;
91+
align-items: center;
92+
gap: 0.3rem;
93+
transition: opacity 0.15s ease-in-out;
94+
opacity: 0.6;
95+
user-select: none;
96+
97+
&:hover {
98+
opacity: 1;
99+
}
100+
}
101+
102+
.showMoreHidden {
103+
opacity: 0;
104+
pointer-events: none;
105+
}
106+
69107
.dimensionRow {
108+
height: 2.1rem;
70109
display: flex;
71110
justify-content: space-between;
72111
gap: 1rem;
73112
margin-bottom: 0.2rem;
74113
}
114+
115+
.dimensionEmpty {
116+
flex: 1;
117+
display: flex;
118+
justify-content: center;
119+
align-items: center;
120+
margin-bottom: 1rem;
121+
opacity: 0.6;
122+
}

web/src/components/dimensions/index.tsx

Lines changed: 37 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import * as Tabs from "@radix-ui/react-tabs";
2-
import { LinkIcon } from "lucide-react";
2+
import { FullscreenIcon, LinkIcon, ZoomIn } from "lucide-react";
33
import styles from "./dimensions.module.css";
44

55
import {
@@ -71,7 +71,7 @@ export const DimensionTabs = ({
7171
<div>{metricNames[metric]}</div>
7272
</Tabs.List>
7373
{dimensions.map((dimension) => (
74-
<Tabs.Content key={dimension} value={dimension}>
74+
<Tabs.Content key={dimension} value={dimension} className={styles.tabsContent}>
7575
<DimensionTable dimension={dimension} metric={metric} range={range} project={project} noHeader />
7676
</Tabs.Content>
7777
))}
@@ -85,24 +85,43 @@ export const DimensionTable = ({
8585
metric,
8686
range,
8787
}: { project: ProjectResponse; dimension: Dimension; metric: Metric; range: DateRange; noHeader?: boolean }) => {
88-
const { data, biggest, order } = useDimension({ project, dimension, metric, range });
88+
const { data, biggest, order, isLoading } = useDimension({ project, dimension, metric, range });
89+
90+
const dataTruncated = data?.slice(0, 6);
8991
return (
90-
<div>
91-
{data?.map((d) => {
92-
return (
93-
<div
94-
key={d.dimensionValue}
95-
style={{ order: order?.indexOf(d.dimensionValue) }}
96-
className={styles.dimensionRow}
97-
>
98-
<DimensionValueBar value={d.value} biggest={biggest}>
99-
<DimensionLabel dimension={dimension} value={d} />
100-
</DimensionValueBar>
101-
<div>{formatMetricVal(metric, d.value)}</div>
92+
<>
93+
<div className={styles.dimensionTable} style={{ "--count": 6 } as React.CSSProperties}>
94+
{dataTruncated?.map((d) => {
95+
return (
96+
<div
97+
key={d.dimensionValue}
98+
style={{ order: order?.indexOf(d.dimensionValue) }}
99+
className={styles.dimensionRow}
100+
>
101+
<DimensionValueBar value={d.value} biggest={biggest}>
102+
<DimensionLabel dimension={dimension} value={d} />
103+
</DimensionValueBar>
104+
<div>{formatMetricVal(metric, d.value)}</div>
105+
</div>
106+
);
107+
})}
108+
{/* {isLoading && dataTruncated?.length === 0 && (
109+
)} */}
110+
{!isLoading && dataTruncated?.length === 0 && (
111+
<div className={styles.dimensionEmpty}>
112+
<div>No data available</div>
102113
</div>
103-
);
104-
})}
105-
</div>
114+
)}
115+
</div>
116+
<button
117+
type="button"
118+
className={`${styles.showMore} ${(dataTruncated?.length ?? 0) === 0 ? styles.showMoreHidden : ""}`}
119+
onClick={() => console.log("show more")}
120+
>
121+
<ZoomIn size={16} />
122+
Show details
123+
</button>
124+
</>
106125
);
107126
};
108127

web/src/components/project.module.css

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ div.graph {
5252
padding: 0;
5353
grid-column: span 2;
5454
display: flex;
55+
flex-direction: row;
5556

5657
> div {
5758
flex-direction: column;

0 commit comments

Comments
 (0)