Skip to content

Commit 33dc1fd

Browse files
committed
Introduce version names
1 parent 780c527 commit 33dc1fd

File tree

10 files changed

+296
-266
lines changed

10 files changed

+296
-266
lines changed

assets/js/dashboard.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ import { createAppRouter } from './dashboard/router'
99
import ErrorBoundary from './dashboard/error/error-boundary'
1010
import * as api from './dashboard/api'
1111
import * as timer from './dashboard/util/realtime-update-timer'
12-
import { filtersBackwardsCompatibilityRedirect } from './dashboard/query'
12+
import { redirectForLegacyParams } from './dashboard/util/url-search-params'
1313
import SiteContextProvider, {
1414
parseSiteFromDataset
1515
} from './dashboard/site-context'
@@ -38,7 +38,7 @@ if (container && container.dataset) {
3838
}
3939

4040
try {
41-
filtersBackwardsCompatibilityRedirect(window.location, window.history)
41+
redirectForLegacyParams(window.location, window.history)
4242
} catch (e) {
4343
console.error('Error redirecting in a backwards compatible way', e)
4444
}

assets/js/dashboard/index.tsx

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
11
/** @format */
22

3-
import React, { useState } from 'react'
4-
5-
import { useIsRealtimeDashboard } from './util/filters'
3+
import React, { useMemo, useState } from 'react'
64
import VisitorGraph from './stats/graph/visitor-graph'
75
import Sources from './stats/sources'
86
import Pages from './stats/pages'
@@ -11,6 +9,8 @@ import Devices from './stats/devices'
119
import { TopBar } from './nav-menu/top-bar'
1210
import Behaviours from './stats/behaviours'
1311
import { FiltersBar } from './nav-menu/filters-bar'
12+
import { useQueryContext } from './query-context'
13+
import { isRealTimeDashboard } from './util/filters'
1414

1515
function DashboardStats({
1616
importedDataInView,
@@ -48,6 +48,13 @@ function DashboardStats({
4848
)
4949
}
5050

51+
function useIsRealtimeDashboard() {
52+
const {
53+
query: { period }
54+
} = useQueryContext()
55+
return useMemo(() => isRealTimeDashboard({ period }), [period])
56+
}
57+
5158
function Dashboard() {
5259
const isRealTimeDashboard = useIsRealtimeDashboard()
5360
const [importedDataInView, setImportedDataInView] = useState(false)

assets/js/dashboard/query.test.ts

Lines changed: 0 additions & 58 deletions
This file was deleted.

assets/js/dashboard/query.ts

Lines changed: 1 addition & 107 deletions
Original file line numberDiff line numberDiff line change
@@ -9,21 +9,11 @@ import {
99
parseUTCDate,
1010
isAfter
1111
} from './util/date'
12-
import {
13-
FILTER_OPERATIONS,
14-
getFiltersByKeyPrefix,
15-
parseLegacyFilter,
16-
parseLegacyPropsFilter
17-
} from './util/filters'
12+
import { FILTER_OPERATIONS, getFiltersByKeyPrefix } from './util/filters'
1813
import { PlausibleSite } from './site-context'
1914
import { ComparisonMode, QueryPeriod } from './query-time-periods'
2015
import { AppNavigationTarget } from './navigation/use-app-navigate'
2116
import { Dayjs } from 'dayjs'
22-
import { legacyParseSearch } from './util/legacy-jsonurl-url-search-params'
23-
import {
24-
FILTER_URL_PARAM_NAME,
25-
stringifySearch
26-
} from './util/url-search-params'
2717

2818
export type FilterClause = string | number
2919

@@ -71,29 +61,6 @@ export function addFilter(
7161
return { ...query, filters: [...query.filters, filter] }
7262
}
7363

74-
const LEGACY_URL_PARAMETERS = {
75-
goal: null,
76-
source: null,
77-
utm_medium: null,
78-
utm_source: null,
79-
utm_campaign: null,
80-
utm_content: null,
81-
utm_term: null,
82-
referrer: null,
83-
screen: null,
84-
browser: null,
85-
browser_version: null,
86-
os: null,
87-
os_version: null,
88-
country: 'country_labels',
89-
region: 'region_labels',
90-
city: 'city_labels',
91-
page: null,
92-
hostname: null,
93-
entry_page: null,
94-
exit_page: null
95-
}
96-
9764
export function postProcessFilters(filters: Array<Filter>): Array<Filter> {
9865
return filters.map(([operation, dimension, clauses]) => {
9966
// Rename old name of the operation
@@ -104,79 +71,6 @@ export function postProcessFilters(filters: Array<Filter>): Array<Filter> {
10471
})
10572
}
10673

107-
export function maybeGetRedirectTargetFromLegacySearchParams(
108-
windowLocation: Location
109-
): null | string {
110-
const searchParams = new URLSearchParams(windowLocation.search)
111-
const isCurrentVersion = searchParams.get(FILTER_URL_PARAM_NAME)
112-
if (isCurrentVersion) {
113-
return null
114-
}
115-
116-
const isJsonURLVersion = searchParams.get('filters')
117-
if (isJsonURLVersion) {
118-
return `${windowLocation.pathname}${stringifySearch(legacyParseSearch(windowLocation.search))}`
119-
}
120-
121-
const searchRecord = legacyParseSearch(windowLocation.search)
122-
const searchRecordEntries = Object.entries(
123-
legacyParseSearch(windowLocation.search)
124-
)
125-
126-
const isBeforeJsonURLVersion = searchRecordEntries.some(
127-
([k]) => k === 'props' || LEGACY_URL_PARAMETERS.hasOwnProperty(k)
128-
)
129-
130-
if (!isBeforeJsonURLVersion) {
131-
return null
132-
}
133-
134-
const changedSearchRecordEntries = []
135-
const filters: DashboardQuery['filters'] = []
136-
let labels: DashboardQuery['labels'] = {}
137-
138-
for (const [key, value] of searchRecordEntries) {
139-
if (LEGACY_URL_PARAMETERS.hasOwnProperty(key)) {
140-
const filter = parseLegacyFilter(key, value) as Filter
141-
filters.push(filter)
142-
const labelsKey: string | null | undefined =
143-
LEGACY_URL_PARAMETERS[key as keyof typeof LEGACY_URL_PARAMETERS]
144-
if (labelsKey && searchRecord[labelsKey]) {
145-
const clauses = filter[2]
146-
const labelsValues = (searchRecord[labelsKey] as string)
147-
.split('|')
148-
.filter((label) => !!label)
149-
const newLabels = Object.fromEntries(
150-
clauses.map((clause, index) => [clause, labelsValues[index]])
151-
)
152-
153-
labels = Object.assign(labels, newLabels)
154-
}
155-
} else {
156-
changedSearchRecordEntries.push([key, value])
157-
}
158-
}
159-
160-
if (searchRecord['props']) {
161-
filters.push(...(parseLegacyPropsFilter(searchRecord['props']) as Filter[]))
162-
}
163-
changedSearchRecordEntries.push(['filters', filters], ['labels', labels])
164-
return `${windowLocation.pathname}${stringifySearch(Object.fromEntries(changedSearchRecordEntries))}`
165-
}
166-
167-
/** Called once before React app mounts. If legacy url search params are present, does a redirect to new format. */
168-
export function filtersBackwardsCompatibilityRedirect(
169-
windowLocation: Location,
170-
windowHistory: History
171-
) {
172-
const redirectTargetURL =
173-
maybeGetRedirectTargetFromLegacySearchParams(windowLocation)
174-
if (redirectTargetURL === null) {
175-
return
176-
}
177-
windowHistory.pushState({}, '', redirectTargetURL)
178-
}
179-
18074
// Returns a boolean indicating whether the given query includes a
18175
// non-empty goal filterset containing a single, or multiple revenue
18276
// goals with the same currency. Used to decide whether to render

assets/js/dashboard/util/filters.js

Lines changed: 1 addition & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,7 @@
11
/** @format */
22

3-
import React, { useMemo } from 'react'
3+
import React from 'react'
44
import * as api from '../api'
5-
import { useQueryContext } from '../query-context'
65

76
export const FILTER_MODAL_TO_FILTER_GROUP = {
87
page: ['page', 'entry_page', 'exit_page'],
@@ -40,12 +39,6 @@ export const FILTER_OPERATIONS_DISPLAY_NAMES = {
4039
[FILTER_OPERATIONS.contains_not]: 'does not contain'
4140
}
4241

43-
const OPERATION_PREFIX = {
44-
[FILTER_OPERATIONS.isNot]: '!',
45-
[FILTER_OPERATIONS.contains]: '~',
46-
[FILTER_OPERATIONS.is]: ''
47-
}
48-
4942
export function supportsIsNot(filterName) {
5043
return !['goal', 'prop_key'].includes(filterName)
5144
}
@@ -62,17 +55,6 @@ export function isFreeChoiceFilterOperation(operation) {
6255
)
6356
}
6457

65-
// As of March 2023, Safari does not support negative lookbehind regexes. In case it throws an error, falls back to plain | matching. This means
66-
// escaping pipe characters in filters does not currently work in Safari
67-
let NON_ESCAPED_PIPE_REGEX
68-
try {
69-
NON_ESCAPED_PIPE_REGEX = new RegExp('(?<!\\\\)\\|', 'g')
70-
} catch (_e) {
71-
NON_ESCAPED_PIPE_REGEX = '|'
72-
}
73-
74-
const ESCAPED_PIPE = '\\|'
75-
7658
export function getLabel(labels, filterKey, value) {
7759
if (['country', 'region', 'city'].includes(filterKey)) {
7860
return labels[value]
@@ -118,27 +100,10 @@ export function hasGoalFilter(query) {
118100
return getFiltersByKeyPrefix(query, 'goal').length > 0
119101
}
120102

121-
export function useHasGoalFilter() {
122-
const {
123-
query: { filters }
124-
} = useQueryContext()
125-
return useMemo(
126-
() => getFiltersByKeyPrefix({ filters }, 'goal').length > 0,
127-
[filters]
128-
)
129-
}
130-
131103
export function isRealTimeDashboard(query) {
132104
return query?.period === 'realtime'
133105
}
134106

135-
export function useIsRealtimeDashboard() {
136-
const {
137-
query: { period }
138-
} = useQueryContext()
139-
return useMemo(() => isRealTimeDashboard({ period }), [period])
140-
}
141-
142107
export function plainFilterText(query, [operation, filterKey, clauses]) {
143108
const formattedFilter = formattedFilters[filterKey]
144109

@@ -295,26 +260,3 @@ export const formattedFilters = {
295260
entry_page: 'Entry Page',
296261
exit_page: 'Exit Page'
297262
}
298-
299-
export function parseLegacyFilter(filterKey, rawValue) {
300-
const operation =
301-
Object.keys(OPERATION_PREFIX).find(
302-
(operation) => OPERATION_PREFIX[operation] === rawValue[0]
303-
) || FILTER_OPERATIONS.is
304-
305-
const value =
306-
operation === FILTER_OPERATIONS.is ? rawValue : rawValue.substring(1)
307-
308-
const clauses = value
309-
.split(NON_ESCAPED_PIPE_REGEX)
310-
.filter((clause) => !!clause)
311-
.map((val) => val.replaceAll(ESCAPED_PIPE, '|'))
312-
313-
return [operation, filterKey, clauses]
314-
}
315-
316-
export function parseLegacyPropsFilter(rawValue) {
317-
return Object.entries(JSON.parse(rawValue)).map(([key, propVal]) => {
318-
return parseLegacyFilter(`${EVENT_PROPS_PREFIX}${key}`, propVal)
319-
})
320-
}

0 commit comments

Comments
 (0)