Skip to content

Commit 8be0e42

Browse files
committed
Consume DAUs from insights
1 parent e91ca19 commit 8be0e42

File tree

2 files changed

+67
-38
lines changed

2 files changed

+67
-38
lines changed

site/src/api/api.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1386,7 +1386,10 @@ export const getInsightsUserLatency = async (
13861386
export const getInsightsTemplate = async (
13871387
filters: InsightsFilter,
13881388
): Promise<TypesGen.TemplateInsightsResponse> => {
1389-
const params = new URLSearchParams(filters)
1389+
const params = new URLSearchParams({
1390+
...filters,
1391+
interval: "day",
1392+
})
13901393
const response = await axios.get(`/api/v2/insights/templates?${params}`)
13911394
return response.data
13921395
}

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

Lines changed: 63 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,7 @@ import Box from "@mui/material/Box"
33
import { styled, useTheme } from "@mui/material/styles"
44
import { BoxProps } from "@mui/system"
55
import { useQuery } from "@tanstack/react-query"
6-
import {
7-
getInsightsTemplate,
8-
getInsightsUserLatency,
9-
getTemplateDAUs,
10-
} from "api/api"
6+
import { getInsightsTemplate, getInsightsUserLatency } from "api/api"
117
import { DAUChart } from "components/DAUChart/DAUChart"
128
import { useTemplateLayoutContext } from "components/TemplateLayout/TemplateLayout"
139
import {
@@ -22,9 +18,21 @@ import { colors } from "theme/colors"
2218
import { Helmet } from "react-helmet-async"
2319
import { getTemplatePageTitle } from "../utils"
2420
import { Loader } from "components/Loader/Loader"
21+
import { DAUsResponse, TemplateInsightsResponse } from "api/typesGenerated"
22+
import { ComponentProps } from "react"
23+
import subDays from "date-fns/subDays"
2524

2625
export default function TemplateInsightsPage() {
2726
const { template } = useTemplateLayoutContext()
27+
const { data: templateInsights } = useQuery({
28+
queryKey: ["templates", template.id, "usage"],
29+
queryFn: () =>
30+
getInsightsTemplate({
31+
template_ids: template.id,
32+
start_time: toTimeFilter(sevenDaysAgo()),
33+
end_time: toTimeFilter(new Date()),
34+
}),
35+
})
2836

2937
return (
3038
<>
@@ -40,22 +48,28 @@ export default function TemplateInsightsPage() {
4048
gap: (theme) => theme.spacing(3),
4149
}}
4250
>
43-
<DailyUsersPanel sx={{ gridColumn: "span 2" }} />
51+
<DailyUsersPanel
52+
sx={{ gridColumn: "span 2" }}
53+
data={templateInsights?.interval_reports}
54+
/>
4455
<UserLatencyPanel />
45-
<TemplateUsagePanel sx={{ gridColumn: "span 3" }} />
56+
<TemplateUsagePanel
57+
sx={{ gridColumn: "span 3" }}
58+
data={templateInsights?.report.apps_usage}
59+
/>
4660
</Box>
4761
</>
4862
)
4963
}
5064

51-
const DailyUsersPanel = (props: BoxProps) => {
52-
const { template } = useTemplateLayoutContext()
53-
const { data } = useQuery({
54-
queryKey: ["templates", template.id, "dau"],
55-
queryFn: () => getTemplateDAUs(template.id),
56-
})
65+
const DailyUsersPanel = ({
66+
data,
67+
...panelProps
68+
}: PanelProps & {
69+
data: TemplateInsightsResponse["interval_reports"] | undefined
70+
}) => {
5771
return (
58-
<Panel {...props}>
72+
<Panel {...panelProps}>
5973
<PanelHeader sx={{ display: "flex", alignItems: "center", gap: 1 }}>
6074
Active daily users
6175
<HelpTooltip size="small">
@@ -67,21 +81,21 @@ const DailyUsersPanel = (props: BoxProps) => {
6781
</PanelHeader>
6882
<PanelContent>
6983
{!data && <Loader sx={{ height: "100%" }} />}
70-
{data && data.entries.length === 0 && <NoDataAvailable />}
71-
{data && data.entries.length > 0 && <DAUChart daus={data} />}
84+
{data && data.length === 0 && <NoDataAvailable />}
85+
{data && data.length > 0 && <DAUChart daus={mapToDAUsResponse(data)} />}
7286
</PanelContent>
7387
</Panel>
7488
)
7589
}
7690

77-
const UserLatencyPanel = (props: BoxProps) => {
91+
const UserLatencyPanel = (props: PanelProps) => {
7892
const { template } = useTemplateLayoutContext()
7993
const { data } = useQuery({
8094
queryKey: ["templates", template.id, "user-latency"],
8195
queryFn: () =>
8296
getInsightsUserLatency({
8397
template_ids: template.id,
84-
start_time: toTimeFilter(new Date(template.created_at)),
98+
start_time: toTimeFilter(sevenDaysAgo()),
8599
end_time: toTimeFilter(new Date()),
86100
}),
87101
})
@@ -133,37 +147,29 @@ const UserLatencyPanel = (props: BoxProps) => {
133147
)
134148
}
135149

136-
const TemplateUsagePanel = (props: BoxProps) => {
137-
const { template } = useTemplateLayoutContext()
138-
const { data } = useQuery({
139-
queryKey: ["templates", template.id, "usage"],
140-
queryFn: () =>
141-
getInsightsTemplate({
142-
template_ids: template.id,
143-
start_time: toTimeFilter(new Date(template.created_at)),
144-
end_time: toTimeFilter(new Date()),
145-
}),
146-
})
150+
const TemplateUsagePanel = ({
151+
data,
152+
...panelProps
153+
}: PanelProps & {
154+
data: TemplateInsightsResponse["report"]["apps_usage"] | undefined
155+
}) => {
147156
const totalInSeconds =
148-
data?.report.apps_usage.reduce(
149-
(total, usage) => total + usage.seconds,
150-
0,
151-
) ?? 1
157+
data?.reduce((total, usage) => total + usage.seconds, 0) ?? 1
152158
const usageColors = chroma
153159
.scale([colors.green[8], colors.blue[8]])
154160
.mode("lch")
155-
.colors(data?.report.apps_usage.length ?? 0)
161+
.colors(data?.length ?? 0)
156162
// The API returns a row for each app, even if the user didn't use it.
157-
const hasDataAvailable = data?.report.apps_usage.some((u) => u.seconds > 0)
163+
const hasDataAvailable = data?.some((u) => u.seconds > 0)
158164
return (
159-
<Panel {...props}>
165+
<Panel {...panelProps}>
160166
<PanelHeader>App&lsquo;s & IDE usage</PanelHeader>
161167
<PanelContent>
162168
{!data && <Loader sx={{ height: 200 }} />}
163169
{data && !hasDataAvailable && <NoDataAvailable sx={{ height: 200 }} />}
164170
{data && hasDataAvailable && (
165171
<Box sx={{ display: "flex", flexDirection: "column", gap: 3 }}>
166-
{data.report.apps_usage
172+
{data
167173
.sort((a, b) => b.seconds - a.seconds)
168174
.map((usage, i) => {
169175
const percentage = (usage.seconds / totalInSeconds) * 100
@@ -237,6 +243,8 @@ const Panel = styled(Box)(({ theme }) => ({
237243
flexDirection: "column",
238244
}))
239245

246+
type PanelProps = ComponentProps<typeof Panel>
247+
240248
const PanelHeader = styled(Box)(({ theme }) => ({
241249
fontSize: 14,
242250
fontWeight: 500,
@@ -269,6 +277,20 @@ const NoDataAvailable = (props: BoxProps) => {
269277
)
270278
}
271279

280+
function mapToDAUsResponse(
281+
data: TemplateInsightsResponse["interval_reports"],
282+
): DAUsResponse {
283+
return {
284+
tz_hour_offset: 0,
285+
entries: data.map((d) => {
286+
return {
287+
amount: d.active_users,
288+
date: d.end_time,
289+
}
290+
}),
291+
}
292+
}
293+
272294
function toTimeFilter(date: Date) {
273295
date.setHours(0, 0, 0, 0)
274296
const year = date.getUTCFullYear()
@@ -294,3 +316,7 @@ function formatTime(seconds: number): string {
294316
}
295317
}
296318
}
319+
320+
function sevenDaysAgo() {
321+
return subDays(new Date(), 7)
322+
}

0 commit comments

Comments
 (0)