Skip to content

Commit a27af59

Browse files
committed
Add weekly control
1 parent f694204 commit a27af59

File tree

3 files changed

+105
-13
lines changed

3 files changed

+105
-13
lines changed

site/src/api/api.ts

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1483,12 +1483,9 @@ export const getInsightsUserLatency = async (
14831483
};
14841484

14851485
export const getInsightsTemplate = async (
1486-
filters: InsightsFilter,
1486+
filters: InsightsFilter & { interval: "day" | "week" },
14871487
): Promise<TypesGen.TemplateInsightsResponse> => {
1488-
const params = new URLSearchParams({
1489-
...filters,
1490-
interval: "day",
1491-
});
1488+
const params = new URLSearchParams(filters);
14921489
const response = await axios.get(`/api/v2/insights/templates?${params}`);
14931490
return response.data;
14941491
};
Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
import CheckOutlined from "@mui/icons-material/CheckOutlined";
2+
import ExpandMoreOutlined from "@mui/icons-material/ExpandMoreOutlined";
3+
import Box from "@mui/material/Box";
4+
import Button from "@mui/material/Button";
5+
import Menu from "@mui/material/Menu";
6+
import MenuItem from "@mui/material/MenuItem";
7+
import { useState, MouseEvent } from "react";
8+
9+
export const insightsIntervals = {
10+
day: {
11+
label: "Daily",
12+
},
13+
week: {
14+
label: "Weekly",
15+
},
16+
} as const;
17+
18+
export type InsightsInterval = keyof typeof insightsIntervals;
19+
20+
export const IntervalMenu = ({
21+
value,
22+
onChange,
23+
}: {
24+
value: InsightsInterval;
25+
onChange: (value: InsightsInterval) => void;
26+
}) => {
27+
const [anchorEl, setAnchorEl] = useState<null | HTMLElement>(null);
28+
const open = Boolean(anchorEl);
29+
const handleClick = (event: MouseEvent<HTMLButtonElement>) => {
30+
setAnchorEl(event.currentTarget);
31+
};
32+
const handleClose = () => {
33+
setAnchorEl(null);
34+
};
35+
36+
return (
37+
<div>
38+
<Button
39+
id="interval-button"
40+
aria-controls={open ? "interval-menu" : undefined}
41+
aria-haspopup="true"
42+
aria-expanded={open ? "true" : undefined}
43+
onClick={handleClick}
44+
endIcon={<ExpandMoreOutlined />}
45+
>
46+
{insightsIntervals[value].label}
47+
</Button>
48+
<Menu
49+
id="interval-menu"
50+
anchorEl={anchorEl}
51+
open={open}
52+
onClose={handleClose}
53+
MenuListProps={{
54+
"aria-labelledby": "interval-button",
55+
}}
56+
>
57+
{Object.keys(insightsIntervals).map((interval) => {
58+
const { label } = insightsIntervals[interval as InsightsInterval];
59+
return (
60+
<MenuItem
61+
css={{ fontSize: 14, justifyContent: "space-between" }}
62+
key={interval}
63+
onClick={() => {
64+
onChange(interval as InsightsInterval);
65+
handleClose();
66+
}}
67+
>
68+
{label}
69+
<Box css={{ width: 16, height: 16 }}>
70+
{value === interval && (
71+
<CheckOutlined css={{ width: 16, height: 16 }} />
72+
)}
73+
</Box>
74+
</MenuItem>
75+
);
76+
})}
77+
</Menu>
78+
</div>
79+
);
80+
};

site/src/pages/TemplatePage/TemplateInsightsPage/TemplateInsightsPage.tsx

Lines changed: 23 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -36,15 +36,17 @@ import CancelOutlined from "@mui/icons-material/CancelOutlined";
3636
import { getDateRangeFilter } from "./utils";
3737
import Tooltip from "@mui/material/Tooltip";
3838
import LinkOutlined from "@mui/icons-material/LinkOutlined";
39+
import { InsightsInterval, IntervalMenu } from "./IntervalMenu";
3940

4041
export default function TemplateInsightsPage() {
4142
const now = new Date();
43+
const [interval, setInterval] = useState<InsightsInterval>("day");
4244
const [dateRangeValue, setDateRangeValue] = useState<DateRangeValue>({
4345
startDate: subDays(now, 6),
4446
endDate: now,
4547
});
4648
const { template } = useTemplateLayoutContext();
47-
const insightsFilter = {
49+
const commonFilters = {
4850
template_ids: template.id,
4951
...getDateRangeFilter({
5052
startDate: dateRangeValue.startDate,
@@ -53,13 +55,14 @@ export default function TemplateInsightsPage() {
5355
isToday,
5456
}),
5557
};
58+
const insightsFilter = { ...commonFilters, interval };
5659
const { data: templateInsights } = useQuery({
5760
queryKey: ["templates", template.id, "usage", insightsFilter],
5861
queryFn: () => getInsightsTemplate(insightsFilter),
5962
});
6063
const { data: userLatency } = useQuery({
61-
queryKey: ["templates", template.id, "user-latency", insightsFilter],
62-
queryFn: () => getInsightsUserLatency(insightsFilter),
64+
queryKey: ["templates", template.id, "user-latency", commonFilters],
65+
queryFn: () => getInsightsUserLatency(commonFilters),
6366
});
6467

6568
return (
@@ -68,8 +71,11 @@ export default function TemplateInsightsPage() {
6871
<title>{getTemplatePageTitle("Insights", template)}</title>
6972
</Helmet>
7073
<TemplateInsightsPageView
71-
dateRange={
72-
<DateRange value={dateRangeValue} onChange={setDateRangeValue} />
74+
controls={
75+
<>
76+
<IntervalMenu value={interval} onChange={setInterval} />
77+
<DateRange value={dateRangeValue} onChange={setDateRangeValue} />
78+
</>
7379
}
7480
templateInsights={templateInsights}
7581
userLatency={userLatency}
@@ -81,15 +87,24 @@ export default function TemplateInsightsPage() {
8187
export const TemplateInsightsPageView = ({
8288
templateInsights,
8389
userLatency,
84-
dateRange,
90+
controls,
8591
}: {
8692
templateInsights: TemplateInsightsResponse | undefined;
8793
userLatency: UserLatencyInsightsResponse | undefined;
88-
dateRange: ReactNode;
94+
controls: ReactNode;
8995
}) => {
9096
return (
9197
<>
92-
<Box sx={{ mb: 4 }}>{dateRange}</Box>
98+
<Box
99+
css={(theme) => ({
100+
marginBottom: theme.spacing(4),
101+
display: "flex",
102+
alignItems: "center",
103+
gap: theme.spacing(1),
104+
})}
105+
>
106+
{controls}
107+
</Box>
93108
<Box
94109
sx={{
95110
display: "grid",

0 commit comments

Comments
 (0)