Skip to content

Commit 09a1d35

Browse files
authored
revert(insights): persist q in url hash, remove beforeUnload (#35286)
1 parent 56494da commit 09a1d35

File tree

3 files changed

+80
-33
lines changed

3 files changed

+80
-33
lines changed

frontend/src/scenes/insights/InsightPageHeader.tsx

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { IconInfo, IconPencil, IconShare, IconTrash, IconWarning } from '@posthog/icons'
22
import { useActions, useMountedLogic, useValues } from 'kea'
3-
import { router, combineUrl } from 'kea-router'
3+
import { router } from 'kea-router'
44
import { AccessControlledLemonButton } from 'lib/components/AccessControlledLemonButton'
55
import { AddToDashboard } from 'lib/components/AddToDashboard/AddToDashboard'
66
import { AddToDashboardModal } from 'lib/components/AddToDashboard/AddToDashboardModal'
@@ -265,13 +265,7 @@ export function InsightPageHeader({ insightLogicProps }: { insightLogicProps: In
265265
if (isDataVisualizationNode(query) && insight.short_id) {
266266
router.actions.push(urls.sqlEditor(undefined, undefined, insight.short_id))
267267
} else if (insight.short_id) {
268-
push(
269-
combineUrl(
270-
urls.insightEdit(insight.short_id),
271-
undefined,
272-
queryChanged ? { q: query } : undefined
273-
).url
274-
)
268+
push(urls.insightEdit(insight.short_id))
275269
} else {
276270
setInsightMode(ItemMode.Edit, null)
277271
}

frontend/src/scenes/insights/insightDataLogic.tsx

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -245,7 +245,11 @@ export const insightDataLogic = kea<insightDataLogicType>([
245245
}),
246246
actionToUrl(({ values }) => ({
247247
setQuery: ({ query }) => {
248-
if (values.queryChanged && insightSceneLogic.values.activeScene === Scene.Insight) {
248+
if (
249+
values.queryChanged &&
250+
insightSceneLogic.values.activeScene === Scene.Insight &&
251+
insightSceneLogic.values.insightId === 'new'
252+
) {
249253
// query is changed and we are in edit mode
250254
return [
251255
router.values.currentLocation.pathname,
@@ -256,9 +260,6 @@ export const insightDataLogic = kea<insightDataLogicType>([
256260
...router.values.currentLocation.hashParams,
257261
q: crushDraftQueryForURL(query),
258262
},
259-
{
260-
replace: true,
261-
},
262263
]
263264
}
264265
},

frontend/src/scenes/insights/insightSceneLogic.tsx

Lines changed: 73 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import { actions, BuiltLogic, connect, kea, listeners, path, reducers, selectors, sharedListeners } from 'kea'
2-
import { actionToUrl, router, urlToAction } from 'kea-router'
2+
import { actionToUrl, beforeUnload, router, urlToAction } from 'kea-router'
3+
import { CombinedLocation } from 'kea-router/lib/utils'
34
import { objectsEqual } from 'kea-test-utils'
45
import { AlertType } from 'lib/components/Alerts/types'
56
import { isEmptyObject } from 'lib/utils'
@@ -31,7 +32,7 @@ import {
3132
import { insightDataLogic } from './insightDataLogic'
3233
import { insightDataLogicType } from './insightDataLogicType'
3334
import type { insightSceneLogicType } from './insightSceneLogicType'
34-
import { parseDraftQueryFromURL } from './utils'
35+
import { parseDraftQueryFromLocalStorage, parseDraftQueryFromURL } from './utils'
3536
import api from 'lib/api'
3637
import { checkLatestVersionsOnQuery } from '~/queries/utils'
3738

@@ -417,37 +418,88 @@ export const insightSceneLogic = kea<insightSceneLogicType>([
417418
},
418419
})),
419420
actionToUrl(({ values }) => {
421+
// Use the browser redirect to determine state to hook into beforeunload prevention
420422
const actionToUrl = ({
421423
insightMode = values.insightMode,
422424
insightId = values.insightId,
423425
}: {
424426
insightMode?: ItemMode
425427
insightId?: InsightShortId | 'new' | null
426-
}): [
427-
string,
428-
string | Record<string, any> | undefined,
429-
string | Record<string, any> | undefined,
430-
{ replace?: boolean }
431-
] => {
432-
const baseUrl =
433-
!insightId || insightId === 'new'
434-
? urls.insightNew()
435-
: insightMode === ItemMode.View
436-
? urls.insightView(insightId)
437-
: urls.insightEdit(insightId)
438-
const searchParams = router.values.currentLocation.searchParams
439-
// TODO: also kepe these in the URL?
440-
// const metadataChanged = !!values.insightLogicRef?.logic.values.insightChanged
441-
const queryChanged = !!values.insightDataLogicRef?.logic.values.queryChanged
442-
const query = values.insightDataLogicRef?.logic.values.query
443-
const hashParams = queryChanged ? { q: query } : undefined
428+
}): string | undefined => {
429+
if (!insightId || insightId === 'new') {
430+
return undefined
431+
}
444432

445-
return [baseUrl, searchParams, hashParams, { replace: true }]
433+
const baseUrl = insightMode === ItemMode.View ? urls.insightView(insightId) : urls.insightEdit(insightId)
434+
const searchParams = window.location.search
435+
return searchParams ? `${baseUrl}${searchParams}` : baseUrl
446436
}
447437

448438
return {
449439
setInsightId: actionToUrl,
450440
setInsightMode: actionToUrl,
451441
}
452442
}),
443+
beforeUnload(({ values }) => ({
444+
enabled: (newLocation?: CombinedLocation) => {
445+
// Don't run this check on other scenes
446+
if (values.activeScene !== Scene.Insight) {
447+
return false
448+
}
449+
450+
if (values.disableNavigationHooks) {
451+
return false
452+
}
453+
454+
// If just the hash or project part changes, don't show the prompt
455+
const currentPathname = router.values.currentLocation.pathname.replace(/\/project\/\d+/, '')
456+
const newPathname = newLocation?.pathname.replace(/\/project\/\d+/, '')
457+
if (currentPathname === newPathname) {
458+
return false
459+
}
460+
461+
// Don't show the prompt if we're in edit mode (just exploring)
462+
if (values.insightMode !== ItemMode.Edit) {
463+
return false
464+
}
465+
466+
const metadataChanged = !!values.insightLogicRef?.logic.values.insightChanged
467+
const queryChanged = !!values.insightDataLogicRef?.logic.values.queryChanged
468+
const draftQueryFromLocalStorage = localStorage.getItem(`draft-query-${values.currentTeamId}`)
469+
let draftQuery: { query: Node; timestamp: number } | null = null
470+
if (draftQueryFromLocalStorage) {
471+
const parsedQuery = parseDraftQueryFromLocalStorage(draftQueryFromLocalStorage)
472+
if (parsedQuery) {
473+
draftQuery = parsedQuery
474+
} else {
475+
// If the draft query is invalid, remove it
476+
localStorage.removeItem(`draft-query-${values.currentTeamId}`)
477+
}
478+
}
479+
const query = values.insightDataLogicRef?.logic.values.query
480+
481+
if (draftQuery && query && objectsEqual(draftQuery.query, query)) {
482+
return false
483+
}
484+
485+
const isChanged = metadataChanged || queryChanged
486+
487+
if (!isChanged) {
488+
return false
489+
}
490+
491+
// Do not show confirmation if newPathname is undefined; this usually means back button in browser
492+
if (newPathname === undefined) {
493+
const savedQuery = values.insightDataLogicRef?.logic.values.savedInsight.query
494+
values.insightDataLogicRef?.logic.actions.setQuery(savedQuery || null)
495+
return false
496+
}
497+
498+
return true
499+
},
500+
message: 'Leave insight?\nChanges you made will be discarded.',
501+
onConfirm: () => {
502+
values.insightDataLogicRef?.logic.actions.cancelChanges()
503+
},
504+
})),
453505
])

0 commit comments

Comments
 (0)