Skip to content

Commit b1fcd06

Browse files
committed
- Update labels in Dashboard components for clarity.
- Refactor dashboard data handling to improve maintainability and readability. - Introduce utility functions for building monthly distribution views. - Simplify interval selection logic for better user experience. #deploy-test-dolly-frontend
1 parent c9194ef commit b1fcd06

5 files changed

Lines changed: 108 additions & 128 deletions

File tree

apps/dolly-frontend/src/main/js/src/pages/adminPages/Dashboard/DashboardPage.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ const initAccessibilityModule =
2222
initAccessibilityModule?.(Highcharts)
2323

2424
Highcharts.setOptions({
25+
palette: { colorScheme: 'light' },
2526
xAxis: {
2627
labels: { style: { color: CHART_TEXT_COLOR, fontSize: '12px' } },
2728
title: { style: { color: CHART_TEXT_COLOR } },
@@ -55,7 +56,7 @@ export default () => {
5556
<VStack gap={{ xs: 'space-16', md: 'space-24' }}>
5657
<Box>
5758
<h1>Dashboard</h1>
58-
<p>Statistikk for syntetisering av identer og bruk av Dolly.</p>
59+
<p>Statistikk for syntetisering av personer og bruk av Dolly.</p>
5960
</Box>
6061

6162
{isDevDashboardMode && (

apps/dolly-frontend/src/main/js/src/pages/adminPages/Dashboard/dashboardDayPersonSections.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,7 @@ export const PreviousDaySection = ({
9292
<>
9393
<HGrid columns={{ xs: 1, sm: 2 }} gap="space-12">
9494
<DashboardKpiCard
95-
label="Identer opprettet/gjenopprettet"
95+
label="Personer opprettet/gjenopprettet"
9696
value={previousDaySummary.nyeInklGjenopprettede}
9797
/>
9898
{previousDaySummary.totaltFeil === 0 ? (

apps/dolly-frontend/src/main/js/src/pages/adminPages/Dashboard/dashboardTrendChartOptions.ts

Lines changed: 18 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,24 @@ export const createPersonTrendChartOptions = (
5151
itemMarginBottom: 4,
5252
},
5353
series: [
54+
{ type: 'line', name: 'Nye', data: personTrendData.map((point) => point.nye) },
55+
{
56+
type: 'line',
57+
name: 'Gjenopprettede',
58+
data: personTrendData.map((point) => point.gjenopprettede),
59+
},
60+
{
61+
type: 'line',
62+
name: 'PDL-feil',
63+
data: personTrendData.map((point) => point.pdlFeil),
64+
color: ERROR_PRIMARY_COLOR,
65+
},
66+
{
67+
type: 'line',
68+
name: 'Andre feil',
69+
data: personTrendData.map((point) => point.andreFeil),
70+
color: ERROR_SECONDARY_COLOR,
71+
},
5472
{
5573
type: 'line',
5674
name: 'Personer totalt',
@@ -61,12 +79,6 @@ export const createPersonTrendChartOptions = (
6179
hide: () => visibilityOptions?.onPersonerTotaltVisibilityChange?.(false),
6280
},
6381
},
64-
{ type: 'line', name: 'Nye', data: personTrendData.map((point) => point.nye) },
65-
{
66-
type: 'line',
67-
name: 'Gjenopprettede',
68-
data: personTrendData.map((point) => point.gjenopprettede),
69-
},
7082
{
7183
type: 'line',
7284
name: 'Feil totalt',
@@ -77,18 +89,6 @@ export const createPersonTrendChartOptions = (
7789
hide: () => visibilityOptions?.onFeilTotaltVisibilityChange?.(false),
7890
},
7991
},
80-
{
81-
type: 'line',
82-
name: 'PDL-feil',
83-
data: personTrendData.map((point) => point.pdlFeil),
84-
color: ERROR_PRIMARY_COLOR,
85-
},
86-
{
87-
type: 'line',
88-
name: 'Andre feil',
89-
data: personTrendData.map((point) => point.andreFeil),
90-
color: ERROR_SECONDARY_COLOR,
91-
},
9292
],
9393
})
9494

apps/dolly-frontend/src/main/js/src/pages/adminPages/Dashboard/useDashboardData.ts

Lines changed: 86 additions & 108 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import {
88
getPreviousBusinessPeriod,
99
MONTH_SCOPE_ALL,
1010
MONTH_SCOPE_LAST_12,
11+
type MonthlyTeamPoint,
1112
toDisplayDate,
1213
toMonthlyDollyTeamPoints,
1314
toMonthlyIntervalOptions,
@@ -44,6 +45,46 @@ const isQuickRangeValue = (value: string): value is QuickRangeValue =>
4445
const DAY_SCOPE_YESTERDAY = 'YESTERDAY'
4546
const DAY_SCOPE_TODAY = 'TODAY'
4647

48+
const buildMonthlyDistributionView = (
49+
monthlyPoints: MonthlyTeamPoint[],
50+
selectedInterval: string,
51+
) => {
52+
const intervalOptions = toMonthlyIntervalOptions(monthlyPoints)
53+
const yearOptions = [...new Set(intervalOptions.map((option) => option.value.slice(0, 4)))].sort(
54+
(a, b) => a.localeCompare(b),
55+
)
56+
const selectedYear = selectedInterval.slice(0, 4)
57+
const monthOptions = intervalOptions
58+
.filter((option) => option.value.startsWith(`${selectedYear}-`))
59+
.map((option) => ({ ...option, label: option.label.replace(/\s+\d{4}$/, '') }))
60+
const selectedPoint = monthlyPoints.find((point) => point.interval === selectedInterval) ?? null
61+
const distribution = toTeamDistributionForInterval(monthlyPoints, selectedInterval)
62+
return { intervalOptions, yearOptions, selectedYear, monthOptions, selectedPoint, distribution }
63+
}
64+
65+
const useAutoSelectLatestInterval = (
66+
intervalOptions: { value: string }[],
67+
selectedInterval: string,
68+
setSelectedInterval: (value: string) => void,
69+
) => {
70+
useEffect(() => {
71+
if (intervalOptions.length === 0) {
72+
if (selectedInterval !== '') setSelectedInterval('')
73+
return
74+
}
75+
if (!intervalOptions.some((option) => option.value === selectedInterval)) {
76+
setSelectedInterval(intervalOptions.at(-1)!.value)
77+
}
78+
}, [intervalOptions, selectedInterval, setSelectedInterval])
79+
}
80+
81+
const makeYearChangeHandler =
82+
(intervalOptions: { value: string }[], setSelectedInterval: (value: string) => void) =>
83+
(year: string) => {
84+
const lastOption = intervalOptions.findLast((option) => option.value.startsWith(`${year}-`))
85+
if (lastOption) setSelectedInterval(lastOption.value)
86+
}
87+
4788
export const useDashboardData = () => {
4889
const {
4990
dashboardPersoner,
@@ -186,18 +227,7 @@ export const useDashboardData = () => {
186227
organisasjonMonthlyPoints,
187228
organisasjonMonthScope,
188229
)
189-
const organisasjonIntervalOptions = toMonthlyIntervalOptions(organisasjonMonthlyPoints)
190-
const organisasjonYearOptions = [
191-
...new Set(organisasjonIntervalOptions.map((option) => option.value.slice(0, 4))),
192-
].sort((a, b) => a.localeCompare(b))
193-
const selectedOrganisasjonYear = selectedOrganisasjonInterval.slice(0, 4)
194-
const organisasjonMonthOptions = organisasjonIntervalOptions
195-
.filter((option) => option.value.startsWith(`${selectedOrganisasjonYear}-`))
196-
.map((option) => ({ ...option, label: option.label.replace(/\s+\d{4}$/, '') }))
197-
const selectedOrganisasjonPoint =
198-
organisasjonMonthlyPoints.find((point) => point.interval === selectedOrganisasjonInterval) ??
199-
null
200-
const organisasjonDistribution = toTeamDistributionForInterval(
230+
const organisasjonView = buildMonthlyDistributionView(
201231
organisasjonMonthlyPoints,
202232
selectedOrganisasjonInterval,
203233
)
@@ -209,39 +239,23 @@ export const useDashboardData = () => {
209239
secondSeriesName: 'Antall organisasjoner',
210240
},
211241
)
212-
const organisasjonDistributionChartOptions =
213-
createMonthlyTeamDistributionChartOptions(organisasjonDistribution)
242+
const organisasjonDistributionChartOptions = createMonthlyTeamDistributionChartOptions(
243+
organisasjonView.distribution,
244+
)
214245

215-
useEffect(() => {
216-
if (organisasjonIntervalOptions.length === 0) {
217-
setSelectedOrganisasjonInterval('')
218-
return
219-
}
220-
const selectedExists = organisasjonIntervalOptions.some(
221-
(option) => option.value === selectedOrganisasjonInterval,
222-
)
223-
if (!selectedExists) {
224-
setSelectedOrganisasjonInterval(organisasjonIntervalOptions.at(-1)!.value)
225-
}
226-
}, [organisasjonIntervalOptions, selectedOrganisasjonInterval])
246+
useAutoSelectLatestInterval(
247+
organisasjonView.intervalOptions,
248+
selectedOrganisasjonInterval,
249+
setSelectedOrganisasjonInterval,
250+
)
227251

228252
// --- Dolly Teams ---
229253
const dollyTeamsMonthlyPoints = toMonthlyDollyTeamPoints(activeDashboardDollyTeams)
230254
const filteredDollyTeamsPoints = filterMonthlyTeamPoints(
231255
dollyTeamsMonthlyPoints,
232256
dollyTeamsMonthScope,
233257
)
234-
const dollyTeamsIntervalOptions = toMonthlyIntervalOptions(dollyTeamsMonthlyPoints)
235-
const dollyTeamsYearOptions = [
236-
...new Set(dollyTeamsIntervalOptions.map((option) => option.value.slice(0, 4))),
237-
].sort((a, b) => a.localeCompare(b))
238-
const selectedDollyTeamsYear = selectedDollyTeamsInterval.slice(0, 4)
239-
const dollyTeamsMonthOptions = dollyTeamsIntervalOptions
240-
.filter((option) => option.value.startsWith(`${selectedDollyTeamsYear}-`))
241-
.map((option) => ({ ...option, label: option.label.replace(/\s+\d{4}$/, '') }))
242-
const selectedDollyTeamsPoint =
243-
dollyTeamsMonthlyPoints.find((point) => point.interval === selectedDollyTeamsInterval) ?? null
244-
const dollyTeamsDistribution = toTeamDistributionForInterval(
258+
const dollyTeamsView = buildMonthlyDistributionView(
245259
dollyTeamsMonthlyPoints,
246260
selectedDollyTeamsInterval,
247261
)
@@ -254,55 +268,28 @@ export const useDashboardData = () => {
254268
},
255269
)
256270
const dollyTeamsDistributionChartOptions = createMonthlyTeamDistributionChartOptions(
257-
dollyTeamsDistribution,
271+
dollyTeamsView.distribution,
258272
'Antall medlemmer',
259273
)
260274

261-
useEffect(() => {
262-
if (dollyTeamsIntervalOptions.length === 0) {
263-
setSelectedDollyTeamsInterval('')
264-
return
265-
}
266-
const selectedExists = dollyTeamsIntervalOptions.some(
267-
(option) => option.value === selectedDollyTeamsInterval,
268-
)
269-
if (!selectedExists) {
270-
setSelectedDollyTeamsInterval(dollyTeamsIntervalOptions.at(-1)!.value)
271-
}
272-
}, [dollyTeamsIntervalOptions, selectedDollyTeamsInterval])
275+
useAutoSelectLatestInterval(
276+
dollyTeamsView.intervalOptions,
277+
selectedDollyTeamsInterval,
278+
setSelectedDollyTeamsInterval,
279+
)
273280

274281
// --- Teams ---
275282
const monthlyTeamPoints = toMonthlyTeamPoints(activeDashboardTeams)
276283
const filteredMonthlyTeamPoints = filterMonthlyTeamPoints(monthlyTeamPoints, monthScope)
277-
const monthlyIntervalOptions = toMonthlyIntervalOptions(monthlyTeamPoints)
278-
const teamYearOptions = [
279-
...new Set(monthlyIntervalOptions.map((option) => option.value.slice(0, 4))),
280-
].sort((a, b) => a.localeCompare(b))
281-
const selectedTeamYear = selectedInterval.slice(0, 4)
282-
const teamMonthOptions = monthlyIntervalOptions
283-
.filter((option) => option.value.startsWith(`${selectedTeamYear}-`))
284-
.map((option) => ({ ...option, label: option.label.replace(/\s+\d{4}$/, '') }))
285-
const selectedMonthlyPoint =
286-
monthlyTeamPoints.find((point) => point.interval === selectedInterval) ?? null
287-
const teamDistribution = toTeamDistributionForInterval(monthlyTeamPoints, selectedInterval)
284+
const teamView = buildMonthlyDistributionView(monthlyTeamPoints, selectedInterval)
288285
const monthlyTrendChartOptions = createMonthlyTeamTrendChartOptions(
289286
toMonthlyTrendData(filteredMonthlyTeamPoints),
290287
)
291-
const monthlyDistributionChartOptions =
292-
createMonthlyTeamDistributionChartOptions(teamDistribution)
288+
const monthlyDistributionChartOptions = createMonthlyTeamDistributionChartOptions(
289+
teamView.distribution,
290+
)
293291

294-
useEffect(() => {
295-
if (monthlyIntervalOptions.length === 0) {
296-
setSelectedInterval('')
297-
return
298-
}
299-
const selectedExists = monthlyIntervalOptions.some(
300-
(option) => option.value === selectedInterval,
301-
)
302-
if (!selectedExists) {
303-
setSelectedInterval(monthlyIntervalOptions.at(-1)!.value)
304-
}
305-
}, [monthlyIntervalOptions, selectedInterval])
292+
useAutoSelectLatestInterval(teamView.intervalOptions, selectedInterval, setSelectedInterval)
306293

307294
const applyQuickRange = (quickRangeValue: string) => {
308295
const toDateValue = format(quickRangeAnchorDate, 'yyyy-MM-dd')
@@ -391,59 +378,50 @@ export const useDashboardData = () => {
391378
organisasjonMonthScope,
392379
onOrganisasjonMonthScopeChange: setOrganisasjonMonthScope,
393380
organisasjonMonthlyTrendChartOptions,
394-
organisasjonYearOptions,
395-
selectedOrganisasjonYear,
396-
organisasjonMonthOptions,
397-
onSelectedOrganisasjonYearChange: (year: string) => {
398-
const lastOption = organisasjonIntervalOptions.findLast((option) =>
399-
option.value.startsWith(`${year}-`),
400-
)
401-
if (lastOption) setSelectedOrganisasjonInterval(lastOption.value)
402-
},
381+
organisasjonYearOptions: organisasjonView.yearOptions,
382+
selectedOrganisasjonYear: organisasjonView.selectedYear,
383+
organisasjonMonthOptions: organisasjonView.monthOptions,
384+
onSelectedOrganisasjonYearChange: makeYearChangeHandler(
385+
organisasjonView.intervalOptions,
386+
setSelectedOrganisasjonInterval,
387+
),
403388
selectedOrganisasjonInterval,
404389
onSelectedOrganisasjonIntervalChange: setSelectedOrganisasjonInterval,
405-
selectedOrganisasjonPoint,
406-
organisasjonDistribution,
390+
selectedOrganisasjonPoint: organisasjonView.selectedPoint,
391+
organisasjonDistribution: organisasjonView.distribution,
407392
organisasjonDistributionChartOptions,
408393

409394
// Dolly teams section
410395
filteredDollyTeamsPointsLength: filteredDollyTeamsPoints.length,
411396
dollyTeamsMonthScope,
412397
onDollyTeamsMonthScopeChange: setDollyTeamsMonthScope,
413398
dollyTeamsMonthlyTrendChartOptions,
414-
dollyTeamsYearOptions,
415-
selectedDollyTeamsYear,
416-
dollyTeamsMonthOptions,
417-
onSelectedDollyTeamsYearChange: (year: string) => {
418-
const lastOption = dollyTeamsIntervalOptions.findLast((option) =>
419-
option.value.startsWith(`${year}-`),
420-
)
421-
if (lastOption) setSelectedDollyTeamsInterval(lastOption.value)
422-
},
399+
dollyTeamsYearOptions: dollyTeamsView.yearOptions,
400+
selectedDollyTeamsYear: dollyTeamsView.selectedYear,
401+
dollyTeamsMonthOptions: dollyTeamsView.monthOptions,
402+
onSelectedDollyTeamsYearChange: makeYearChangeHandler(
403+
dollyTeamsView.intervalOptions,
404+
setSelectedDollyTeamsInterval,
405+
),
423406
selectedDollyTeamsInterval,
424407
onSelectedDollyTeamsIntervalChange: setSelectedDollyTeamsInterval,
425-
selectedDollyTeamsPoint,
426-
dollyTeamsDistribution,
408+
selectedDollyTeamsPoint: dollyTeamsView.selectedPoint,
409+
dollyTeamsDistribution: dollyTeamsView.distribution,
427410
dollyTeamsDistributionChartOptions,
428411

429412
// Teams section
430413
filteredMonthlyTeamPointsLength: filteredMonthlyTeamPoints.length,
431414
monthScope,
432415
onMonthScopeChange: setMonthScope,
433416
monthlyTrendChartOptions,
434-
teamYearOptions,
435-
selectedTeamYear,
436-
teamMonthOptions,
437-
onSelectedTeamYearChange: (year: string) => {
438-
const lastOption = monthlyIntervalOptions.findLast((option) =>
439-
option.value.startsWith(`${year}-`),
440-
)
441-
if (lastOption) setSelectedInterval(lastOption.value)
442-
},
417+
teamYearOptions: teamView.yearOptions,
418+
selectedTeamYear: teamView.selectedYear,
419+
teamMonthOptions: teamView.monthOptions,
420+
onSelectedTeamYearChange: makeYearChangeHandler(teamView.intervalOptions, setSelectedInterval),
443421
selectedTeamInterval: selectedInterval,
444422
onSelectedTeamIntervalChange: setSelectedInterval,
445-
selectedMonthlyPoint,
446-
teamDistribution,
423+
selectedMonthlyPoint: teamView.selectedPoint,
424+
teamDistribution: teamView.distribution,
447425
monthlyDistributionChartOptions,
448426
}
449427
}

apps/dolly-frontend/src/main/js/vitest.setup.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import { cleanup } from '@testing-library/react'
2+
import { act } from 'react'
23
import * as matchers from '@testing-library/jest-dom/matchers'
34
import { test as testBase } from 'vitest'
45
import { worker } from './__tests__/mocks/browser.ts'

0 commit comments

Comments
 (0)