Skip to content

Commit c2a7edc

Browse files
authored
Introduce get metric label utility (#6234)
1 parent 1161d26 commit c2a7edc

3 files changed

Lines changed: 98 additions & 70 deletions

File tree

assets/js/dashboard/stats/graph/fetch-top-stats.test.ts

Lines changed: 23 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import { Metric } from '../../../types/query-api'
12
import {
23
DashboardState,
34
dashboardStateDefaultValue,
@@ -7,7 +8,7 @@ import { ComparisonMode, DashboardPeriod } from '../../dashboard-time-periods'
78
import { PlausibleSite, siteContextDefaultValue } from '../../site-context'
89
import { StatsQuery } from '../../stats-query'
910
import { remapToApiFilters } from '../../util/filters'
10-
import { chooseMetrics, MetricDef, topStatsQueries } from './fetch-top-stats'
11+
import { chooseMetrics, topStatsQueries } from './fetch-top-stats'
1112

1213
const aGoalFilter = ['is', 'goal', ['any goal']] as Filter
1314
const aPageFilter = ['is', 'page', ['/any/page']] as Filter
@@ -41,7 +42,7 @@ type TestCase = [
4142
Pick<DashboardState, 'filters' | 'period'> &
4243
Partial<{ site?: Pick<PlausibleSite, 'revenueGoals'> }>,
4344
/** expected metrics */
44-
MetricDef[],
45+
Metric[],
4546
/** expected queries */
4647
[StatsQuery, null | StatsQuery]
4748
]
@@ -50,10 +51,7 @@ const cases: TestCase[] = [
5051
[
5152
'realtime and goal filter',
5253
{ period: DashboardPeriod.realtime, filters: [aGoalFilter] },
53-
[
54-
{ key: 'visitors', label: 'Unique conversions (last 30 min)' },
55-
{ key: 'events', label: 'Total conversions (last 30 min)' }
56-
],
54+
['visitors', 'events'],
5755
[
5856
{
5957
date_range: DashboardPeriod.realtime_30m,
@@ -70,10 +68,7 @@ const cases: TestCase[] = [
7068
[
7169
'realtime',
7270
{ period: DashboardPeriod.realtime, filters: [] },
73-
[
74-
{ key: 'visitors', label: 'Unique visitors (last 30 min)' },
75-
{ key: 'pageviews', label: 'Pageviews (last 30 min)' }
76-
],
71+
['visitors', 'pageviews'],
7772
[
7873
{
7974
date_range: DashboardPeriod.realtime_30m,
@@ -100,11 +95,11 @@ const cases: TestCase[] = [
10095
}
10196
},
10297
[
103-
{ key: 'visitors', label: 'Unique conversions' },
104-
{ key: 'events', label: 'Total conversions' },
105-
{ key: 'total_revenue', label: 'Total revenue' },
106-
{ key: 'average_revenue', label: 'Average revenue' },
107-
{ key: 'conversion_rate', label: 'Conversion rate' }
98+
'visitors',
99+
'events',
100+
'total_revenue',
101+
'average_revenue',
102+
'conversion_rate'
108103
],
109104
[
110105
{
@@ -128,11 +123,7 @@ const cases: TestCase[] = [
128123
[
129124
'goal filter',
130125
{ period: aPeriodNotRealtime, filters: [aGoalFilter] },
131-
[
132-
{ key: 'visitors', label: 'Unique conversions' },
133-
{ key: 'events', label: 'Total conversions' },
134-
{ key: 'conversion_rate', label: 'Conversion rate' }
135-
],
126+
['visitors', 'events', 'conversion_rate'],
136127
[
137128
{
138129
date_range: aPeriodNotRealtime,
@@ -153,12 +144,12 @@ const cases: TestCase[] = [
153144
filters: [aPageFilter]
154145
},
155146
[
156-
{ key: 'visitors', label: 'Unique visitors' },
157-
{ key: 'visits', label: 'Total visits' },
158-
{ key: 'pageviews', label: 'Total pageviews' },
159-
{ key: 'bounce_rate', label: 'Bounce rate' },
160-
{ key: 'scroll_depth', label: 'Scroll depth' },
161-
{ key: 'time_on_page', label: 'Time on page' }
147+
'visitors',
148+
'visits',
149+
'pageviews',
150+
'bounce_rate',
151+
'scroll_depth',
152+
'time_on_page'
162153
],
163154

164155
[
@@ -185,12 +176,12 @@ const cases: TestCase[] = [
185176
'default',
186177
{ period: aPeriodNotRealtime, filters: [] },
187178
[
188-
{ key: 'visitors', label: 'Unique visitors' },
189-
{ key: 'visits', label: 'Total visits' },
190-
{ key: 'pageviews', label: 'Total pageviews' },
191-
{ key: 'views_per_visit', label: 'Views per visit' },
192-
{ key: 'bounce_rate', label: 'Bounce rate' },
193-
{ key: 'visit_duration', label: 'Visit duration' }
179+
'visitors',
180+
'visits',
181+
'pageviews',
182+
'views_per_visit',
183+
'bounce_rate',
184+
'visit_duration'
194185
],
195186
[
196187
{

assets/js/dashboard/stats/graph/fetch-top-stats.ts

Lines changed: 38 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import { Metric } from '../../../types/query-api'
22
import * as api from '../../api'
33
import { DashboardState } from '../../dashboard-state'
4+
import { getMetricLabel } from '../metrics'
45
import {
56
ComparisonMode,
67
DashboardPeriod,
@@ -17,7 +18,7 @@ import {
1718

1819
export function topStatsQueries(
1920
dashboardState: DashboardState,
20-
metrics: MetricDef[]
21+
metrics: Metric[]
2122
): [StatsQuery, StatsQuery | null] {
2223
let currentVisitorsQuery = null
2324

@@ -53,70 +54,69 @@ export async function fetchTopStats(
5354
currentVisitorsPromise
5455
])
5556

56-
return formatTopStatsData(topStatsResponse, currentVisitorsResponse, metrics)
57+
const metricLabelSuffix = isRealTimeDashboard(dashboardState)
58+
? ' (last 30 min)'
59+
: ''
60+
61+
const formattedMetrics = metrics.map((key) => ({
62+
key,
63+
label: `${getMetricLabel(key, {
64+
hasConversionGoalFilter: hasConversionGoalFilter(dashboardState)
65+
})}${metricLabelSuffix}`
66+
}))
67+
68+
return formatTopStatsData(
69+
topStatsResponse,
70+
currentVisitorsResponse,
71+
formattedMetrics
72+
)
5773
}
5874

5975
export type MetricDef = { key: Metric; label: string }
6076

6177
export function chooseMetrics(
6278
site: Pick<PlausibleSite, 'revenueGoals'>,
6379
dashboardState: DashboardState
64-
): MetricDef[] {
65-
const revenueMetrics: MetricDef[] =
66-
site.revenueGoals.length > 0
67-
? [
68-
{ key: 'total_revenue', label: 'Total revenue' },
69-
{ key: 'average_revenue', label: 'Average revenue' }
70-
]
71-
: []
80+
): Metric[] {
81+
const revenueMetrics: Metric[] =
82+
site.revenueGoals.length > 0 ? ['total_revenue', 'average_revenue'] : []
7283

7384
if (
7485
isRealTimeDashboard(dashboardState) &&
7586
hasConversionGoalFilter(dashboardState)
7687
) {
77-
return [
78-
{ key: 'visitors', label: 'Unique conversions (last 30 min)' },
79-
{ key: 'events', label: 'Total conversions (last 30 min)' }
80-
]
88+
return ['visitors', 'events']
8189
} else if (isRealTimeDashboard(dashboardState)) {
82-
return [
83-
{ key: 'visitors', label: 'Unique visitors (last 30 min)' },
84-
{ key: 'pageviews', label: 'Pageviews (last 30 min)' }
85-
]
90+
return ['visitors', 'pageviews']
8691
} else if (hasConversionGoalFilter(dashboardState)) {
87-
return [
88-
{ key: 'visitors', label: 'Unique conversions' },
89-
{ key: 'events', label: 'Total conversions' },
90-
...revenueMetrics,
91-
{ key: 'conversion_rate', label: 'Conversion rate' }
92-
]
92+
return ['visitors', 'events', ...revenueMetrics, 'conversion_rate']
9393
} else if (hasPageFilter(dashboardState)) {
9494
return [
95-
{ key: 'visitors', label: 'Unique visitors' },
96-
{ key: 'visits', label: 'Total visits' },
97-
{ key: 'pageviews', label: 'Total pageviews' },
98-
{ key: 'bounce_rate', label: 'Bounce rate' },
99-
{ key: 'scroll_depth', label: 'Scroll depth' },
100-
{ key: 'time_on_page', label: 'Time on page' }
95+
'visitors',
96+
'visits',
97+
'pageviews',
98+
'bounce_rate',
99+
'scroll_depth',
100+
'time_on_page'
101101
]
102102
} else {
103103
return [
104-
{ key: 'visitors', label: 'Unique visitors' },
105-
{ key: 'visits', label: 'Total visits' },
106-
{ key: 'pageviews', label: 'Total pageviews' },
107-
{ key: 'views_per_visit', label: 'Views per visit' },
108-
{ key: 'bounce_rate', label: 'Bounce rate' },
109-
{ key: 'visit_duration', label: 'Visit duration' }
104+
'visitors',
105+
'visits',
106+
'pageviews',
107+
'views_per_visit',
108+
'bounce_rate',
109+
'visit_duration'
110110
]
111111
}
112112
}
113113

114114
function constructTopStatsQuery(
115115
dashboardState: DashboardState,
116-
metrics: MetricDef[]
116+
metrics: Metric[]
117117
): StatsQuery {
118118
const reportParams: ReportParams = {
119-
metrics: metrics.map((m) => m.key),
119+
metrics,
120120
include: { imports_meta: true }
121121
}
122122

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
import { Metric } from '../../types/query-api'
2+
3+
export const getMetricLabel = (
4+
metric: Metric,
5+
{ hasConversionGoalFilter }: { hasConversionGoalFilter: boolean }
6+
): string => {
7+
switch (metric) {
8+
case 'visitors':
9+
return hasConversionGoalFilter ? 'Unique conversions' : 'Unique visitors'
10+
case 'events':
11+
return hasConversionGoalFilter ? 'Total conversions' : 'Total events'
12+
case 'visits':
13+
return 'Total visits'
14+
case 'pageviews':
15+
return 'Total pageviews'
16+
case 'views_per_visit':
17+
return 'Views per visit'
18+
case 'bounce_rate':
19+
return 'Bounce rate'
20+
case 'visit_duration':
21+
return 'Visit duration'
22+
case 'time_on_page':
23+
return 'Time on page'
24+
case 'scroll_depth':
25+
return 'Scroll depth'
26+
case 'conversion_rate':
27+
return 'Conversion rate'
28+
case 'total_revenue':
29+
return 'Total revenue'
30+
case 'average_revenue':
31+
return 'Average revenue'
32+
case 'percentage':
33+
return 'Percentage'
34+
case 'group_conversion_rate':
35+
return 'Conversion rate'
36+
}
37+
}

0 commit comments

Comments
 (0)