@grafana/scenes 5.13.0--canary.887.10699625611.0 → 5.13.0--canary.878.10702174754.0
Sign up to get free protection for your applications and to get access to all the features.
- package/dist/esm/components/SceneApp/SceneApp.js +7 -4
- package/dist/esm/components/SceneApp/SceneApp.js.map +1 -1
- package/dist/esm/components/SceneApp/SceneAppPageView.js +4 -2
- package/dist/esm/components/SceneApp/SceneAppPageView.js.map +1 -1
- package/dist/esm/core/SceneObjectBase.js +0 -8
- package/dist/esm/core/SceneObjectBase.js.map +1 -1
- package/dist/esm/core/SceneTimeRange.js +6 -2
- package/dist/esm/core/SceneTimeRange.js.map +1 -1
- package/dist/esm/core/sceneGraph/index.js +3 -2
- package/dist/esm/core/sceneGraph/index.js.map +1 -1
- package/dist/esm/core/sceneGraph/sceneGraph.js +11 -1
- package/dist/esm/core/sceneGraph/sceneGraph.js.map +1 -1
- package/dist/esm/core/types.js.map +1 -1
- package/dist/esm/index.js +1 -1
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/services/SceneObjectUrlSyncConfig.js +9 -0
- package/dist/esm/services/SceneObjectUrlSyncConfig.js.map +1 -1
- package/dist/esm/services/UrlSyncContextProvider.js +7 -2
- package/dist/esm/services/UrlSyncContextProvider.js.map +1 -1
- package/dist/esm/services/UrlSyncManager.js +71 -37
- package/dist/esm/services/UrlSyncManager.js.map +1 -1
- package/dist/esm/services/useUrlSync.js +3 -3
- package/dist/esm/services/useUrlSync.js.map +1 -1
- package/dist/index.d.ts +61 -34
- package/dist/index.js +110 -54
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
@@ -1,6 +1,7 @@
|
|
1
1
|
class SceneObjectUrlSyncConfig {
|
2
2
|
constructor(_sceneObject, _options) {
|
3
3
|
this._sceneObject = _sceneObject;
|
4
|
+
this._nextChangeShouldAddHistoryStep = false;
|
4
5
|
this._keys = _options.keys;
|
5
6
|
}
|
6
7
|
getKeys() {
|
@@ -15,6 +16,14 @@ class SceneObjectUrlSyncConfig {
|
|
15
16
|
updateFromUrl(values) {
|
16
17
|
this._sceneObject.updateFromUrl(values);
|
17
18
|
}
|
19
|
+
performBrowserHistoryAction(callback) {
|
20
|
+
this._nextChangeShouldAddHistoryStep = true;
|
21
|
+
callback();
|
22
|
+
this._nextChangeShouldAddHistoryStep = false;
|
23
|
+
}
|
24
|
+
shouldCreateHistoryStep(values) {
|
25
|
+
return this._nextChangeShouldAddHistoryStep;
|
26
|
+
}
|
18
27
|
}
|
19
28
|
|
20
29
|
export { SceneObjectUrlSyncConfig };
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"SceneObjectUrlSyncConfig.js","sources":["../../../src/services/SceneObjectUrlSyncConfig.ts"],"sourcesContent":["import { SceneObjectUrlSyncHandler, SceneObjectWithUrlSync, SceneObjectUrlValues } from '../core/types';\n\ninterface SceneObjectUrlSyncConfigOptions {\n keys: string[] | (() => string[]);\n}\n\nexport class SceneObjectUrlSyncConfig implements SceneObjectUrlSyncHandler {\n private _keys: string[] | (() => string[]);\n\n public constructor(private _sceneObject: SceneObjectWithUrlSync, _options: SceneObjectUrlSyncConfigOptions) {\n this._keys = _options.keys;\n }\n\n public getKeys(): string[] {\n if (typeof this._keys === 'function') {\n return this._keys();\n }\n\n return this._keys;\n }\n\n public getUrlState(): SceneObjectUrlValues {\n return this._sceneObject.getUrlState();\n }\n\n public updateFromUrl(values: SceneObjectUrlValues): void {\n this._sceneObject.updateFromUrl(values);\n }\n}\n"],"names":[],"mappings":"AAMO,MAAM,wBAA8D,CAAA;AAAA,
|
1
|
+
{"version":3,"file":"SceneObjectUrlSyncConfig.js","sources":["../../../src/services/SceneObjectUrlSyncConfig.ts"],"sourcesContent":["import { SceneObjectUrlSyncHandler, SceneObjectWithUrlSync, SceneObjectUrlValues } from '../core/types';\n\ninterface SceneObjectUrlSyncConfigOptions {\n keys: string[] | (() => string[]);\n}\n\nexport class SceneObjectUrlSyncConfig implements SceneObjectUrlSyncHandler {\n private _keys: string[] | (() => string[]);\n private _nextChangeShouldAddHistoryStep = false;\n\n public constructor(private _sceneObject: SceneObjectWithUrlSync, _options: SceneObjectUrlSyncConfigOptions) {\n this._keys = _options.keys;\n }\n\n public getKeys(): string[] {\n if (typeof this._keys === 'function') {\n return this._keys();\n }\n\n return this._keys;\n }\n\n public getUrlState(): SceneObjectUrlValues {\n return this._sceneObject.getUrlState();\n }\n\n public updateFromUrl(values: SceneObjectUrlValues): void {\n this._sceneObject.updateFromUrl(values);\n }\n\n public performBrowserHistoryAction(callback: () => void) {\n this._nextChangeShouldAddHistoryStep = true;\n callback();\n this._nextChangeShouldAddHistoryStep = false;\n }\n\n public shouldCreateHistoryStep(values: SceneObjectUrlValues): boolean {\n return this._nextChangeShouldAddHistoryStep;\n }\n}\n"],"names":[],"mappings":"AAMO,MAAM,wBAA8D,CAAA;AAAA,EAIlE,WAAA,CAAoB,cAAsC,QAA2C,EAAA;AAAjF,IAAA,IAAA,CAAA,YAAA,GAAA,YAAA,CAAA;AAF3B,IAAA,IAAA,CAAQ,+BAAkC,GAAA,KAAA,CAAA;AAGxC,IAAA,IAAA,CAAK,QAAQ,QAAS,CAAA,IAAA,CAAA;AAAA,GACxB;AAAA,EAEO,OAAoB,GAAA;AACzB,IAAI,IAAA,OAAO,IAAK,CAAA,KAAA,KAAU,UAAY,EAAA;AACpC,MAAA,OAAO,KAAK,KAAM,EAAA,CAAA;AAAA,KACpB;AAEA,IAAA,OAAO,IAAK,CAAA,KAAA,CAAA;AAAA,GACd;AAAA,EAEO,WAAoC,GAAA;AACzC,IAAO,OAAA,IAAA,CAAK,aAAa,WAAY,EAAA,CAAA;AAAA,GACvC;AAAA,EAEO,cAAc,MAAoC,EAAA;AACvD,IAAK,IAAA,CAAA,YAAA,CAAa,cAAc,MAAM,CAAA,CAAA;AAAA,GACxC;AAAA,EAEO,4BAA4B,QAAsB,EAAA;AACvD,IAAA,IAAA,CAAK,+BAAkC,GAAA,IAAA,CAAA;AACvC,IAAS,QAAA,EAAA,CAAA;AACT,IAAA,IAAA,CAAK,+BAAkC,GAAA,KAAA,CAAA;AAAA,GACzC;AAAA,EAEO,wBAAwB,MAAuC,EAAA;AACpE,IAAA,OAAO,IAAK,CAAA,+BAAA,CAAA;AAAA,GACd;AACF;;;;"}
|
@@ -1,7 +1,12 @@
|
|
1
1
|
import { useUrlSync } from './useUrlSync.js';
|
2
2
|
|
3
|
-
function UrlSyncContextProvider({
|
4
|
-
|
3
|
+
function UrlSyncContextProvider({
|
4
|
+
children,
|
5
|
+
scene,
|
6
|
+
updateUrlOnInit,
|
7
|
+
createBrowserHistorySteps
|
8
|
+
}) {
|
9
|
+
const isInitialized = useUrlSync(scene, { updateUrlOnInit, createBrowserHistorySteps });
|
5
10
|
if (!isInitialized) {
|
6
11
|
return null;
|
7
12
|
}
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"UrlSyncContextProvider.js","sources":["../../../src/services/UrlSyncContextProvider.ts"],"sourcesContent":["import { SceneObject } from '../core/types';\nimport { useUrlSync } from './useUrlSync';\n\nexport interface UrlSyncContextProviderProps {\n scene: SceneObject;\n children: React.ReactNode;\n}\n\n/**\n * Right now this is actually not defining a context, but think it might in the future (with UrlSyncManager as the context value)\n */\n\nexport function UrlSyncContextProvider({
|
1
|
+
{"version":3,"file":"UrlSyncContextProvider.js","sources":["../../../src/services/UrlSyncContextProvider.ts"],"sourcesContent":["import { SceneObject, SceneUrlSyncOptions } from '../core/types';\nimport { useUrlSync } from './useUrlSync';\n\nexport interface UrlSyncContextProviderProps extends SceneUrlSyncOptions {\n scene: SceneObject;\n children: React.ReactNode;\n}\n\n/**\n * Right now this is actually not defining a context, but think it might in the future (with UrlSyncManager as the context value)\n */\n\nexport function UrlSyncContextProvider({\n children,\n scene,\n updateUrlOnInit,\n createBrowserHistorySteps,\n}: UrlSyncContextProviderProps) {\n const isInitialized = useUrlSync(scene, { updateUrlOnInit, createBrowserHistorySteps });\n\n if (!isInitialized) {\n return null;\n }\n\n return children;\n}\n"],"names":[],"mappings":";;AAYO,SAAS,sBAAuB,CAAA;AAAA,EACrC,QAAA;AAAA,EACA,KAAA;AAAA,EACA,eAAA;AAAA,EACA,yBAAA;AACF,CAAgC,EAAA;AAC9B,EAAA,MAAM,gBAAgB,UAAW,CAAA,KAAA,EAAO,EAAE,eAAA,EAAiB,2BAA2B,CAAA,CAAA;AAEtF,EAAA,IAAI,CAAC,aAAe,EAAA;AAClB,IAAO,OAAA,IAAA,CAAA;AAAA,GACT;AAEA,EAAO,OAAA,QAAA,CAAA;AACT;;;;"}
|
@@ -1,8 +1,11 @@
|
|
1
1
|
import { locationService } from '@grafana/runtime';
|
2
2
|
import { SceneObjectStateChangedEvent } from '../core/events.js';
|
3
3
|
import { writeSceneLog } from '../utils/writeSceneLog.js';
|
4
|
+
import { Subscription } from 'rxjs';
|
4
5
|
import { UniqueUrlKeyMapper } from './UniqueUrlKeyMapper.js';
|
5
|
-
import {
|
6
|
+
import { getUrlState, syncStateFromUrl, isUrlValueEqual } from './utils.js';
|
7
|
+
import { BusEventWithPayload } from '@grafana/data';
|
8
|
+
import { useMemo } from 'react';
|
6
9
|
|
7
10
|
var __accessCheck = (obj, member, msg) => {
|
8
11
|
if (!member.has(obj))
|
@@ -22,54 +25,53 @@ var __privateSet = (obj, member, value, setter) => {
|
|
22
25
|
setter ? setter.call(obj, value) : member.set(obj, value);
|
23
26
|
return value;
|
24
27
|
};
|
25
|
-
var
|
28
|
+
var _cache, _location;
|
29
|
+
class NewSceneObjectAddedEvent extends BusEventWithPayload {
|
30
|
+
}
|
31
|
+
NewSceneObjectAddedEvent.type = "new-scene-object-added";
|
26
32
|
class UrlSyncManager {
|
27
|
-
constructor() {
|
33
|
+
constructor(_options = {}) {
|
28
34
|
this._urlKeyMapper = new UniqueUrlKeyMapper();
|
29
|
-
this._stateSub = null;
|
30
35
|
this._paramsCache = new UrlParamsCache();
|
31
|
-
|
32
|
-
const changedObject = payload.changedObject;
|
33
|
-
if (changedObject.urlSync) {
|
34
|
-
const newUrlState = changedObject.urlSync.getUrlState();
|
35
|
-
const searchParams = locationService.getSearch();
|
36
|
-
const mappedUpdated = {};
|
37
|
-
for (const [key, newUrlValue] of Object.entries(newUrlState)) {
|
38
|
-
const uniqueKey = this._urlKeyMapper.getUniqueKey(key, changedObject);
|
39
|
-
const currentUrlValue = searchParams.getAll(uniqueKey);
|
40
|
-
if (!isUrlValueEqual(currentUrlValue, newUrlValue)) {
|
41
|
-
mappedUpdated[uniqueKey] = newUrlValue;
|
42
|
-
}
|
43
|
-
}
|
44
|
-
if (Object.keys(mappedUpdated).length > 0) {
|
45
|
-
writeSceneLog("UrlSyncManager", "onStateChange updating URL");
|
46
|
-
locationService.partial(mappedUpdated, true);
|
47
|
-
this._lastLocation = locationService.getLocation();
|
48
|
-
}
|
49
|
-
}
|
50
|
-
});
|
36
|
+
this._options = _options;
|
51
37
|
}
|
52
38
|
initSync(root) {
|
53
39
|
var _a;
|
54
|
-
if (this.
|
40
|
+
if (this._subs) {
|
55
41
|
writeSceneLog("UrlSyncManager", "Unregister previous scene state subscription", (_a = this._sceneRoot) == null ? void 0 : _a.state.key);
|
56
|
-
this.
|
42
|
+
this._subs.unsubscribe();
|
57
43
|
}
|
58
44
|
writeSceneLog("UrlSyncManager", "init", root.state.key);
|
59
45
|
this._sceneRoot = root;
|
60
|
-
this.
|
46
|
+
this._subs = new Subscription();
|
47
|
+
this._subs.add(
|
48
|
+
root.subscribeToEvent(SceneObjectStateChangedEvent, (evt) => {
|
49
|
+
this.handleSceneObjectStateChanged(evt.payload.changedObject);
|
50
|
+
})
|
51
|
+
);
|
52
|
+
this._subs.add(
|
53
|
+
root.subscribeToEvent(NewSceneObjectAddedEvent, (evt) => {
|
54
|
+
this.handleNewObject(evt.payload);
|
55
|
+
})
|
56
|
+
);
|
61
57
|
this._urlKeyMapper.clear();
|
62
58
|
this._lastLocation = locationService.getLocation();
|
63
59
|
this.handleNewObject(this._sceneRoot);
|
60
|
+
if (this._options.updateUrlOnInit) {
|
61
|
+
const urlState = getUrlState(root);
|
62
|
+
if (isUrlStateDifferent(urlState, this._paramsCache.getParams())) {
|
63
|
+
locationService.partial(urlState, true);
|
64
|
+
}
|
65
|
+
}
|
64
66
|
}
|
65
67
|
cleanUp(root) {
|
66
68
|
if (this._sceneRoot !== root) {
|
67
69
|
return;
|
68
70
|
}
|
69
71
|
writeSceneLog("UrlSyncManager", "Clean up");
|
70
|
-
if (this.
|
71
|
-
this.
|
72
|
-
this.
|
72
|
+
if (this._subs) {
|
73
|
+
this._subs.unsubscribe();
|
74
|
+
this._subs = void 0;
|
73
75
|
writeSceneLog(
|
74
76
|
"UrlSyncManager",
|
75
77
|
"Root deactived, unsub to state",
|
@@ -94,11 +96,33 @@ class UrlSyncManager {
|
|
94
96
|
}
|
95
97
|
syncStateFromUrl(sceneObj, this._paramsCache.getParams(), this._urlKeyMapper);
|
96
98
|
}
|
99
|
+
handleSceneObjectStateChanged(changedObject) {
|
100
|
+
var _a, _b;
|
101
|
+
if (!changedObject.urlSync) {
|
102
|
+
return;
|
103
|
+
}
|
104
|
+
const newUrlState = changedObject.urlSync.getUrlState();
|
105
|
+
const searchParams = locationService.getSearch();
|
106
|
+
const mappedUpdated = {};
|
107
|
+
for (const [key, newUrlValue] of Object.entries(newUrlState)) {
|
108
|
+
const uniqueKey = this._urlKeyMapper.getUniqueKey(key, changedObject);
|
109
|
+
const currentUrlValue = searchParams.getAll(uniqueKey);
|
110
|
+
if (!isUrlValueEqual(currentUrlValue, newUrlValue)) {
|
111
|
+
mappedUpdated[uniqueKey] = newUrlValue;
|
112
|
+
}
|
113
|
+
}
|
114
|
+
if (Object.keys(mappedUpdated).length > 0) {
|
115
|
+
const shouldCreateHistoryEntry = (_b = (_a = changedObject.urlSync).shouldCreateHistoryStep) == null ? void 0 : _b.call(_a, newUrlState);
|
116
|
+
const shouldReplace = shouldCreateHistoryEntry !== true;
|
117
|
+
writeSceneLog("UrlSyncManager", "onStateChange updating URL");
|
118
|
+
locationService.partial(mappedUpdated, shouldReplace);
|
119
|
+
this._lastLocation = locationService.getLocation();
|
120
|
+
}
|
121
|
+
}
|
97
122
|
getUrlState(root) {
|
98
123
|
return getUrlState(root);
|
99
124
|
}
|
100
125
|
}
|
101
|
-
_onStateChanged = new WeakMap();
|
102
126
|
class UrlParamsCache {
|
103
127
|
constructor() {
|
104
128
|
__privateAdd(this, _cache, void 0);
|
@@ -116,13 +140,23 @@ class UrlParamsCache {
|
|
116
140
|
}
|
117
141
|
_cache = new WeakMap();
|
118
142
|
_location = new WeakMap();
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
143
|
+
function isUrlStateDifferent(sceneUrlState, currentParams) {
|
144
|
+
for (let key in sceneUrlState) {
|
145
|
+
if (!isUrlValueEqual(currentParams.getAll(key), sceneUrlState[key])) {
|
146
|
+
return true;
|
147
|
+
}
|
123
148
|
}
|
124
|
-
return
|
149
|
+
return false;
|
150
|
+
}
|
151
|
+
function useUrlSyncManager(options) {
|
152
|
+
return useMemo(
|
153
|
+
() => new UrlSyncManager({
|
154
|
+
updateUrlOnInit: options.updateUrlOnInit,
|
155
|
+
createBrowserHistorySteps: options.createBrowserHistorySteps
|
156
|
+
}),
|
157
|
+
[options.updateUrlOnInit, options.createBrowserHistorySteps]
|
158
|
+
);
|
125
159
|
}
|
126
160
|
|
127
|
-
export { UrlSyncManager,
|
161
|
+
export { NewSceneObjectAddedEvent, UrlSyncManager, useUrlSyncManager };
|
128
162
|
//# sourceMappingURL=UrlSyncManager.js.map
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"UrlSyncManager.js","sources":["../../../src/services/UrlSyncManager.ts"],"sourcesContent":["import { Location } from 'history';\n\nimport { locationService } from '@grafana/runtime';\n\nimport { SceneObjectStateChangedEvent } from '../core/events';\nimport { SceneObject, SceneObjectUrlValues } from '../core/types';\nimport { writeSceneLog } from '../utils/writeSceneLog';\nimport { Unsubscribable } from 'rxjs';\nimport { UniqueUrlKeyMapper } from './UniqueUrlKeyMapper';\nimport { getUrlState, isUrlValueEqual, syncStateFromUrl } from './utils';\n\nexport interface UrlSyncManagerLike {\n initSync(root: SceneObject): void;\n cleanUp(root: SceneObject): void;\n getUrlState(root: SceneObject): SceneObjectUrlValues;\n handleNewLocation(location: Location): void;\n handleNewObject(sceneObj: SceneObject): void;\n}\n\nexport class UrlSyncManager implements UrlSyncManagerLike {\n private _urlKeyMapper = new UniqueUrlKeyMapper();\n private _sceneRoot?: SceneObject;\n private _stateSub: Unsubscribable | null = null;\n private _lastLocation: Location | undefined;\n private _paramsCache = new UrlParamsCache();\n\n /**\n * Updates the current scene state to match URL state.\n */\n public initSync(root: SceneObject) {\n if (this._stateSub) {\n writeSceneLog('UrlSyncManager', 'Unregister previous scene state subscription', this._sceneRoot?.state.key);\n this._stateSub.unsubscribe();\n }\n\n writeSceneLog('UrlSyncManager', 'init', root.state.key);\n\n this._sceneRoot = root;\n this._stateSub = root.subscribeToEvent(SceneObjectStateChangedEvent, this.#onStateChanged);\n\n this._urlKeyMapper.clear();\n this._lastLocation = locationService.getLocation();\n\n this.handleNewObject(this._sceneRoot);\n }\n\n public cleanUp(root: SceneObject) {\n // Ignore this if we have a new or different root\n if (this._sceneRoot !== root) {\n return;\n }\n\n writeSceneLog('UrlSyncManager', 'Clean up');\n\n if (this._stateSub) {\n this._stateSub.unsubscribe();\n this._stateSub = null;\n writeSceneLog(\n 'UrlSyncManager',\n 'Root deactived, unsub to state',\n 'same key',\n this._sceneRoot.state.key === root.state.key\n );\n }\n\n this._sceneRoot = undefined;\n this._lastLocation = undefined;\n }\n\n public handleNewLocation(location: Location) {\n if (!this._sceneRoot || this._lastLocation === location) {\n return;\n }\n\n writeSceneLog('UrlSyncManager', 'handleNewLocation');\n\n this._lastLocation = location;\n\n // Sync scene state tree from url\n syncStateFromUrl(this._sceneRoot!, this._paramsCache.getParams(), this._urlKeyMapper);\n }\n\n public handleNewObject(sceneObj: SceneObject) {\n if (!this._sceneRoot) {\n return;\n }\n\n syncStateFromUrl(sceneObj, this._paramsCache.getParams(), this._urlKeyMapper);\n }\n\n #onStateChanged = ({ payload }: SceneObjectStateChangedEvent) => {\n const changedObject = payload.changedObject;\n\n if (changedObject.urlSync) {\n const newUrlState = changedObject.urlSync.getUrlState();\n\n const searchParams = locationService.getSearch();\n const mappedUpdated: SceneObjectUrlValues = {};\n\n for (const [key, newUrlValue] of Object.entries(newUrlState)) {\n const uniqueKey = this._urlKeyMapper.getUniqueKey(key, changedObject);\n const currentUrlValue = searchParams.getAll(uniqueKey);\n\n if (!isUrlValueEqual(currentUrlValue, newUrlValue)) {\n mappedUpdated[uniqueKey] = newUrlValue;\n }\n }\n\n if (Object.keys(mappedUpdated).length > 0) {\n writeSceneLog('UrlSyncManager', 'onStateChange updating URL');\n locationService.partial(mappedUpdated, true);\n\n /// Mark the location already handled\n this._lastLocation = locationService.getLocation();\n }\n }\n };\n\n public getUrlState(root: SceneObject): SceneObjectUrlValues {\n return getUrlState(root);\n }\n}\n\nclass UrlParamsCache {\n #cache: URLSearchParams | undefined;\n #location: Location | undefined;\n\n public getParams(): URLSearchParams {\n const location = locationService.getLocation();\n\n if (this.#location === location) {\n return this.#cache!;\n }\n\n this.#location = location;\n this.#cache = new URLSearchParams(location.search);\n\n return this.#cache;\n }\n}\n\nlet urlSyncManager: UrlSyncManagerLike | undefined;\n\nexport function getUrlSyncManager(): UrlSyncManagerLike {\n if (!urlSyncManager) {\n urlSyncManager = new UrlSyncManager();\n }\n\n return urlSyncManager;\n}\n"],"names":[],"mappings":"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"}
|
1
|
+
{"version":3,"file":"UrlSyncManager.js","sources":["../../../src/services/UrlSyncManager.ts"],"sourcesContent":["import { Location } from 'history';\n\nimport { locationService } from '@grafana/runtime';\n\nimport { SceneObjectStateChangedEvent } from '../core/events';\nimport { SceneObject, SceneObjectUrlValues, SceneUrlSyncOptions } from '../core/types';\nimport { writeSceneLog } from '../utils/writeSceneLog';\nimport { Subscription } from 'rxjs';\nimport { UniqueUrlKeyMapper } from './UniqueUrlKeyMapper';\nimport { getUrlState, isUrlValueEqual, syncStateFromUrl } from './utils';\nimport { BusEventWithPayload } from '@grafana/data';\nimport { useMemo } from 'react';\n\nexport interface UrlSyncManagerLike {\n initSync(root: SceneObject): void;\n cleanUp(root: SceneObject): void;\n handleNewLocation(location: Location): void;\n handleNewObject(sceneObj: SceneObject): void;\n}\n\n/**\n * Notify the url sync manager of a new object that has been added to the scene\n * that needs to init state from URL.\n */\nexport class NewSceneObjectAddedEvent extends BusEventWithPayload<SceneObject> {\n public static readonly type = 'new-scene-object-added';\n}\n\nexport class UrlSyncManager implements UrlSyncManagerLike {\n private _urlKeyMapper = new UniqueUrlKeyMapper();\n private _sceneRoot?: SceneObject;\n private _subs: Subscription | undefined;\n private _lastLocation: Location | undefined;\n private _paramsCache = new UrlParamsCache();\n private _options: SceneUrlSyncOptions;\n\n public constructor(_options: SceneUrlSyncOptions = {}) {\n this._options = _options;\n }\n\n /**\n * Updates the current scene state to match URL state.\n */\n public initSync(root: SceneObject) {\n if (this._subs) {\n writeSceneLog('UrlSyncManager', 'Unregister previous scene state subscription', this._sceneRoot?.state.key);\n this._subs.unsubscribe();\n }\n\n writeSceneLog('UrlSyncManager', 'init', root.state.key);\n\n this._sceneRoot = root;\n this._subs = new Subscription();\n\n this._subs.add(\n root.subscribeToEvent(SceneObjectStateChangedEvent, (evt) => {\n this.handleSceneObjectStateChanged(evt.payload.changedObject);\n })\n );\n\n this._subs.add(\n root.subscribeToEvent(NewSceneObjectAddedEvent, (evt) => {\n this.handleNewObject(evt.payload);\n })\n );\n\n this._urlKeyMapper.clear();\n this._lastLocation = locationService.getLocation();\n\n // Sync current url with state\n this.handleNewObject(this._sceneRoot);\n\n if (this._options.updateUrlOnInit) {\n // Get current url state and update url to match\n const urlState = getUrlState(root);\n\n if (isUrlStateDifferent(urlState, this._paramsCache.getParams())) {\n locationService.partial(urlState, true);\n }\n }\n }\n\n public cleanUp(root: SceneObject) {\n // Ignore this if we have a new or different root\n if (this._sceneRoot !== root) {\n return;\n }\n\n writeSceneLog('UrlSyncManager', 'Clean up');\n\n if (this._subs) {\n this._subs.unsubscribe();\n this._subs = undefined;\n\n writeSceneLog(\n 'UrlSyncManager',\n 'Root deactived, unsub to state',\n 'same key',\n this._sceneRoot.state.key === root.state.key\n );\n }\n\n this._sceneRoot = undefined;\n this._lastLocation = undefined;\n }\n\n public handleNewLocation(location: Location) {\n if (!this._sceneRoot || this._lastLocation === location) {\n return;\n }\n\n writeSceneLog('UrlSyncManager', 'handleNewLocation');\n\n this._lastLocation = location;\n\n // Sync scene state tree from url\n syncStateFromUrl(this._sceneRoot!, this._paramsCache.getParams(), this._urlKeyMapper);\n }\n\n public handleNewObject(sceneObj: SceneObject) {\n if (!this._sceneRoot) {\n return;\n }\n\n syncStateFromUrl(sceneObj, this._paramsCache.getParams(), this._urlKeyMapper);\n }\n\n private handleSceneObjectStateChanged(changedObject: SceneObject) {\n if (!changedObject.urlSync) {\n return;\n }\n\n const newUrlState = changedObject.urlSync.getUrlState();\n\n const searchParams = locationService.getSearch();\n const mappedUpdated: SceneObjectUrlValues = {};\n\n for (const [key, newUrlValue] of Object.entries(newUrlState)) {\n const uniqueKey = this._urlKeyMapper.getUniqueKey(key, changedObject);\n const currentUrlValue = searchParams.getAll(uniqueKey);\n\n if (!isUrlValueEqual(currentUrlValue, newUrlValue)) {\n mappedUpdated[uniqueKey] = newUrlValue;\n }\n }\n\n if (Object.keys(mappedUpdated).length > 0) {\n const shouldCreateHistoryEntry = changedObject.urlSync.shouldCreateHistoryStep?.(newUrlState);\n const shouldReplace = shouldCreateHistoryEntry !== true;\n\n writeSceneLog('UrlSyncManager', 'onStateChange updating URL');\n locationService.partial(mappedUpdated, shouldReplace);\n\n /// Mark the location already handled\n this._lastLocation = locationService.getLocation();\n }\n }\n\n public getUrlState(root: SceneObject): SceneObjectUrlValues {\n return getUrlState(root);\n }\n}\n\nclass UrlParamsCache {\n #cache: URLSearchParams | undefined;\n #location: Location | undefined;\n\n public getParams(): URLSearchParams {\n const location = locationService.getLocation();\n\n if (this.#location === location) {\n return this.#cache!;\n }\n\n this.#location = location;\n this.#cache = new URLSearchParams(location.search);\n\n return this.#cache;\n }\n}\n\nfunction isUrlStateDifferent(sceneUrlState: SceneObjectUrlValues, currentParams: URLSearchParams) {\n for (let key in sceneUrlState) {\n if (!isUrlValueEqual(currentParams.getAll(key), sceneUrlState[key])) {\n return true;\n }\n }\n\n return false;\n}\n\n/**\n * Creates a new memoized instance of the UrlSyncManager based on options\n */\nexport function useUrlSyncManager(options: SceneUrlSyncOptions): UrlSyncManagerLike {\n return useMemo(\n () =>\n new UrlSyncManager({\n updateUrlOnInit: options.updateUrlOnInit,\n createBrowserHistorySteps: options.createBrowserHistorySteps,\n }),\n [options.updateUrlOnInit, options.createBrowserHistorySteps]\n );\n}\n"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,IAAA,MAAA,EAAA,SAAA,CAAA;AAwBO,MAAM,iCAAiC,mBAAiC,CAAA;AAE/E,CAAA;AAFa,wBAAA,CACY,IAAO,GAAA,wBAAA,CAAA;AAGzB,MAAM,cAA6C,CAAA;AAAA,EAQjD,WAAA,CAAY,QAAgC,GAAA,EAAI,EAAA;AAPvD,IAAQ,IAAA,CAAA,aAAA,GAAgB,IAAI,kBAAmB,EAAA,CAAA;AAI/C,IAAQ,IAAA,CAAA,YAAA,GAAe,IAAI,cAAe,EAAA,CAAA;AAIxC,IAAA,IAAA,CAAK,QAAW,GAAA,QAAA,CAAA;AAAA,GAClB;AAAA,EAKO,SAAS,IAAmB,EAAA;AA3CrC,IAAA,IAAA,EAAA,CAAA;AA4CI,IAAA,IAAI,KAAK,KAAO,EAAA;AACd,MAAA,aAAA,CAAc,kBAAkB,8CAAgD,EAAA,CAAA,EAAA,GAAA,IAAA,CAAK,UAAL,KAAA,IAAA,GAAA,KAAA,CAAA,GAAA,EAAA,CAAiB,MAAM,GAAG,CAAA,CAAA;AAC1G,MAAA,IAAA,CAAK,MAAM,WAAY,EAAA,CAAA;AAAA,KACzB;AAEA,IAAA,aAAA,CAAc,gBAAkB,EAAA,MAAA,EAAQ,IAAK,CAAA,KAAA,CAAM,GAAG,CAAA,CAAA;AAEtD,IAAA,IAAA,CAAK,UAAa,GAAA,IAAA,CAAA;AAClB,IAAK,IAAA,CAAA,KAAA,GAAQ,IAAI,YAAa,EAAA,CAAA;AAE9B,IAAA,IAAA,CAAK,KAAM,CAAA,GAAA;AAAA,MACT,IAAK,CAAA,gBAAA,CAAiB,4BAA8B,EAAA,CAAC,GAAQ,KAAA;AAC3D,QAAK,IAAA,CAAA,6BAAA,CAA8B,GAAI,CAAA,OAAA,CAAQ,aAAa,CAAA,CAAA;AAAA,OAC7D,CAAA;AAAA,KACH,CAAA;AAEA,IAAA,IAAA,CAAK,KAAM,CAAA,GAAA;AAAA,MACT,IAAK,CAAA,gBAAA,CAAiB,wBAA0B,EAAA,CAAC,GAAQ,KAAA;AACvD,QAAK,IAAA,CAAA,eAAA,CAAgB,IAAI,OAAO,CAAA,CAAA;AAAA,OACjC,CAAA;AAAA,KACH,CAAA;AAEA,IAAA,IAAA,CAAK,cAAc,KAAM,EAAA,CAAA;AACzB,IAAK,IAAA,CAAA,aAAA,GAAgB,gBAAgB,WAAY,EAAA,CAAA;AAGjD,IAAK,IAAA,CAAA,eAAA,CAAgB,KAAK,UAAU,CAAA,CAAA;AAEpC,IAAI,IAAA,IAAA,CAAK,SAAS,eAAiB,EAAA;AAEjC,MAAM,MAAA,QAAA,GAAW,YAAY,IAAI,CAAA,CAAA;AAEjC,MAAA,IAAI,oBAAoB,QAAU,EAAA,IAAA,CAAK,YAAa,CAAA,SAAA,EAAW,CAAG,EAAA;AAChE,QAAgB,eAAA,CAAA,OAAA,CAAQ,UAAU,IAAI,CAAA,CAAA;AAAA,OACxC;AAAA,KACF;AAAA,GACF;AAAA,EAEO,QAAQ,IAAmB,EAAA;AAEhC,IAAI,IAAA,IAAA,CAAK,eAAe,IAAM,EAAA;AAC5B,MAAA,OAAA;AAAA,KACF;AAEA,IAAA,aAAA,CAAc,kBAAkB,UAAU,CAAA,CAAA;AAE1C,IAAA,IAAI,KAAK,KAAO,EAAA;AACd,MAAA,IAAA,CAAK,MAAM,WAAY,EAAA,CAAA;AACvB,MAAA,IAAA,CAAK,KAAQ,GAAA,KAAA,CAAA,CAAA;AAEb,MAAA,aAAA;AAAA,QACE,gBAAA;AAAA,QACA,gCAAA;AAAA,QACA,UAAA;AAAA,QACA,IAAK,CAAA,UAAA,CAAW,KAAM,CAAA,GAAA,KAAQ,KAAK,KAAM,CAAA,GAAA;AAAA,OAC3C,CAAA;AAAA,KACF;AAEA,IAAA,IAAA,CAAK,UAAa,GAAA,KAAA,CAAA,CAAA;AAClB,IAAA,IAAA,CAAK,aAAgB,GAAA,KAAA,CAAA,CAAA;AAAA,GACvB;AAAA,EAEO,kBAAkB,QAAoB,EAAA;AAC3C,IAAA,IAAI,CAAC,IAAA,CAAK,UAAc,IAAA,IAAA,CAAK,kBAAkB,QAAU,EAAA;AACvD,MAAA,OAAA;AAAA,KACF;AAEA,IAAA,aAAA,CAAc,kBAAkB,mBAAmB,CAAA,CAAA;AAEnD,IAAA,IAAA,CAAK,aAAgB,GAAA,QAAA,CAAA;AAGrB,IAAA,gBAAA,CAAiB,KAAK,UAAa,EAAA,IAAA,CAAK,aAAa,SAAU,EAAA,EAAG,KAAK,aAAa,CAAA,CAAA;AAAA,GACtF;AAAA,EAEO,gBAAgB,QAAuB,EAAA;AAC5C,IAAI,IAAA,CAAC,KAAK,UAAY,EAAA;AACpB,MAAA,OAAA;AAAA,KACF;AAEA,IAAA,gBAAA,CAAiB,UAAU,IAAK,CAAA,YAAA,CAAa,SAAU,EAAA,EAAG,KAAK,aAAa,CAAA,CAAA;AAAA,GAC9E;AAAA,EAEQ,8BAA8B,aAA4B,EAAA;AA/HpE,IAAA,IAAA,EAAA,EAAA,EAAA,CAAA;AAgII,IAAI,IAAA,CAAC,cAAc,OAAS,EAAA;AAC1B,MAAA,OAAA;AAAA,KACF;AAEA,IAAM,MAAA,WAAA,GAAc,aAAc,CAAA,OAAA,CAAQ,WAAY,EAAA,CAAA;AAEtD,IAAM,MAAA,YAAA,GAAe,gBAAgB,SAAU,EAAA,CAAA;AAC/C,IAAA,MAAM,gBAAsC,EAAC,CAAA;AAE7C,IAAA,KAAA,MAAW,CAAC,GAAK,EAAA,WAAW,KAAK,MAAO,CAAA,OAAA,CAAQ,WAAW,CAAG,EAAA;AAC5D,MAAA,MAAM,SAAY,GAAA,IAAA,CAAK,aAAc,CAAA,YAAA,CAAa,KAAK,aAAa,CAAA,CAAA;AACpE,MAAM,MAAA,eAAA,GAAkB,YAAa,CAAA,MAAA,CAAO,SAAS,CAAA,CAAA;AAErD,MAAA,IAAI,CAAC,eAAA,CAAgB,eAAiB,EAAA,WAAW,CAAG,EAAA;AAClD,QAAA,aAAA,CAAc,SAAa,CAAA,GAAA,WAAA,CAAA;AAAA,OAC7B;AAAA,KACF;AAEA,IAAA,IAAI,MAAO,CAAA,IAAA,CAAK,aAAa,CAAA,CAAE,SAAS,CAAG,EAAA;AACzC,MAAA,MAAM,wBAA2B,GAAA,CAAA,EAAA,GAAA,CAAA,EAAA,GAAA,aAAA,CAAc,OAAQ,EAAA,uBAAA,KAAtB,IAAgD,GAAA,KAAA,CAAA,GAAA,EAAA,CAAA,IAAA,CAAA,EAAA,EAAA,WAAA,CAAA,CAAA;AACjF,MAAA,MAAM,gBAAgB,wBAA6B,KAAA,IAAA,CAAA;AAEnD,MAAA,aAAA,CAAc,kBAAkB,4BAA4B,CAAA,CAAA;AAC5D,MAAgB,eAAA,CAAA,OAAA,CAAQ,eAAe,aAAa,CAAA,CAAA;AAGpD,MAAK,IAAA,CAAA,aAAA,GAAgB,gBAAgB,WAAY,EAAA,CAAA;AAAA,KACnD;AAAA,GACF;AAAA,EAEO,YAAY,IAAyC,EAAA;AAC1D,IAAA,OAAO,YAAY,IAAI,CAAA,CAAA;AAAA,GACzB;AACF,CAAA;AAEA,MAAM,cAAe,CAAA;AAAA,EAArB,WAAA,GAAA;AACE,IAAA,YAAA,CAAA,IAAA,EAAA,MAAA,EAAA,KAAA,CAAA,CAAA,CAAA;AACA,IAAA,YAAA,CAAA,IAAA,EAAA,SAAA,EAAA,KAAA,CAAA,CAAA,CAAA;AAAA,GAAA;AAAA,EAEO,SAA6B,GAAA;AAClC,IAAM,MAAA,QAAA,GAAW,gBAAgB,WAAY,EAAA,CAAA;AAE7C,IAAI,IAAA,YAAA,CAAA,IAAA,EAAK,eAAc,QAAU,EAAA;AAC/B,MAAA,OAAO,YAAK,CAAA,IAAA,EAAA,MAAA,CAAA,CAAA;AAAA,KACd;AAEA,IAAA,YAAA,CAAA,IAAA,EAAK,SAAY,EAAA,QAAA,CAAA,CAAA;AACjB,IAAA,YAAA,CAAA,IAAA,EAAK,MAAS,EAAA,IAAI,eAAgB,CAAA,QAAA,CAAS,MAAM,CAAA,CAAA,CAAA;AAEjD,IAAA,OAAO,YAAK,CAAA,IAAA,EAAA,MAAA,CAAA,CAAA;AAAA,GACd;AACF,CAAA;AAfE,MAAA,GAAA,IAAA,OAAA,EAAA,CAAA;AACA,SAAA,GAAA,IAAA,OAAA,EAAA,CAAA;AAgBF,SAAS,mBAAA,CAAoB,eAAqC,aAAgC,EAAA;AAChG,EAAA,KAAA,IAAS,OAAO,aAAe,EAAA;AAC7B,IAAI,IAAA,CAAC,gBAAgB,aAAc,CAAA,MAAA,CAAO,GAAG,CAAG,EAAA,aAAA,CAAc,IAAI,CAAG,EAAA;AACnE,MAAO,OAAA,IAAA,CAAA;AAAA,KACT;AAAA,GACF;AAEA,EAAO,OAAA,KAAA,CAAA;AACT,CAAA;AAKO,SAAS,kBAAkB,OAAkD,EAAA;AAClF,EAAO,OAAA,OAAA;AAAA,IACL,MACE,IAAI,cAAe,CAAA;AAAA,MACjB,iBAAiB,OAAQ,CAAA,eAAA;AAAA,MACzB,2BAA2B,OAAQ,CAAA,yBAAA;AAAA,KACpC,CAAA;AAAA,IACH,CAAC,OAAA,CAAQ,eAAiB,EAAA,OAAA,CAAQ,yBAAyB,CAAA;AAAA,GAC7D,CAAA;AACF;;;;"}
|
@@ -1,13 +1,13 @@
|
|
1
1
|
import { useState, useEffect } from 'react';
|
2
2
|
import { useLocation } from 'react-router-dom';
|
3
|
-
import { getUrlSyncManager } from './UrlSyncManager.js';
|
4
3
|
import { locationService } from '@grafana/runtime';
|
5
4
|
import { writeSceneLog } from '../utils/writeSceneLog.js';
|
5
|
+
import { useUrlSyncManager } from './UrlSyncManager.js';
|
6
6
|
|
7
|
-
function useUrlSync(sceneRoot) {
|
8
|
-
const urlSyncManager = getUrlSyncManager();
|
7
|
+
function useUrlSync(sceneRoot, options = {}) {
|
9
8
|
const location = useLocation();
|
10
9
|
const [isInitialized, setIsInitialized] = useState(false);
|
10
|
+
const urlSyncManager = useUrlSyncManager(options);
|
11
11
|
useEffect(() => {
|
12
12
|
urlSyncManager.initSync(sceneRoot);
|
13
13
|
setIsInitialized(true);
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"useUrlSync.js","sources":["../../../src/services/useUrlSync.ts"],"sourcesContent":["import { SceneObject } from '../core/types';\nimport { useEffect, useState } from 'react';\nimport { useLocation } from 'react-router-dom';\nimport {
|
1
|
+
{"version":3,"file":"useUrlSync.js","sources":["../../../src/services/useUrlSync.ts"],"sourcesContent":["import { SceneObject, SceneUrlSyncOptions } from '../core/types';\nimport { useEffect, useState } from 'react';\nimport { useLocation } from 'react-router-dom';\nimport { locationService } from '@grafana/runtime';\nimport { writeSceneLog } from '../utils/writeSceneLog';\nimport { useUrlSyncManager } from './UrlSyncManager';\n\nexport function useUrlSync(sceneRoot: SceneObject, options: SceneUrlSyncOptions = {}): boolean {\n const location = useLocation();\n const [isInitialized, setIsInitialized] = useState(false);\n const urlSyncManager = useUrlSyncManager(options);\n\n useEffect(() => {\n urlSyncManager.initSync(sceneRoot);\n setIsInitialized(true);\n return () => urlSyncManager.cleanUp(sceneRoot);\n }, [sceneRoot, urlSyncManager]);\n\n useEffect(() => {\n // Use latest location, as by the time this effect runs, the location might have changed again\n const latestLocation = locationService.getLocation();\n const locationToHandle = latestLocation !== location ? latestLocation : location;\n\n if (latestLocation !== location) {\n writeSceneLog('useUrlSync', 'latestLocation different from location');\n }\n\n urlSyncManager.handleNewLocation(locationToHandle);\n }, [sceneRoot, urlSyncManager, location]);\n\n return isInitialized;\n}\n\nexport interface UrlSyncContextProviderProps {\n scene: SceneObject;\n children: React.ReactNode;\n}\n"],"names":[],"mappings":";;;;;;AAOO,SAAS,UAAW,CAAA,SAAA,EAAwB,OAA+B,GAAA,EAAa,EAAA;AAC7F,EAAA,MAAM,WAAW,WAAY,EAAA,CAAA;AAC7B,EAAA,MAAM,CAAC,aAAA,EAAe,gBAAgB,CAAA,GAAI,SAAS,KAAK,CAAA,CAAA;AACxD,EAAM,MAAA,cAAA,GAAiB,kBAAkB,OAAO,CAAA,CAAA;AAEhD,EAAA,SAAA,CAAU,MAAM;AACd,IAAA,cAAA,CAAe,SAAS,SAAS,CAAA,CAAA;AACjC,IAAA,gBAAA,CAAiB,IAAI,CAAA,CAAA;AACrB,IAAO,OAAA,MAAM,cAAe,CAAA,OAAA,CAAQ,SAAS,CAAA,CAAA;AAAA,GAC5C,EAAA,CAAC,SAAW,EAAA,cAAc,CAAC,CAAA,CAAA;AAE9B,EAAA,SAAA,CAAU,MAAM;AAEd,IAAM,MAAA,cAAA,GAAiB,gBAAgB,WAAY,EAAA,CAAA;AACnD,IAAM,MAAA,gBAAA,GAAmB,cAAmB,KAAA,QAAA,GAAW,cAAiB,GAAA,QAAA,CAAA;AAExE,IAAA,IAAI,mBAAmB,QAAU,EAAA;AAC/B,MAAA,aAAA,CAAc,cAAc,wCAAwC,CAAA,CAAA;AAAA,KACtE;AAEA,IAAA,cAAA,CAAe,kBAAkB,gBAAgB,CAAA,CAAA;AAAA,GAChD,EAAA,CAAC,SAAW,EAAA,cAAA,EAAgB,QAAQ,CAAC,CAAA,CAAA;AAExC,EAAO,OAAA,aAAA,CAAA;AACT;;;;"}
|
package/dist/index.d.ts
CHANGED
@@ -262,11 +262,13 @@ declare function isSceneObject(obj: any): obj is SceneObject;
|
|
262
262
|
interface SceneObjectWithUrlSync extends SceneObject {
|
263
263
|
getUrlState(): SceneObjectUrlValues;
|
264
264
|
updateFromUrl(values: SceneObjectUrlValues): void;
|
265
|
+
shouldCreateHistoryStep?(values: SceneObjectUrlValues): boolean;
|
265
266
|
}
|
266
267
|
interface SceneObjectUrlSyncHandler {
|
267
268
|
getKeys(): string[];
|
268
269
|
getUrlState(): SceneObjectUrlValues;
|
269
270
|
updateFromUrl(values: SceneObjectUrlValues): void;
|
271
|
+
shouldCreateHistoryStep?(values: SceneObjectUrlValues): boolean;
|
270
272
|
}
|
271
273
|
interface DataRequestEnricher {
|
272
274
|
enrichDataRequest(source: SceneObject): Partial<DataQueryRequest> | null;
|
@@ -330,6 +332,19 @@ interface SceneDataQuery extends DataQuery {
|
|
330
332
|
[key: string]: any;
|
331
333
|
timeRangeCompare?: boolean;
|
332
334
|
}
|
335
|
+
interface SceneUrlSyncOptions {
|
336
|
+
/**
|
337
|
+
* This will update the url to contain all scene url state
|
338
|
+
* when the scene is initialized. Important for browser history "back" actions.
|
339
|
+
*/
|
340
|
+
updateUrlOnInit?: boolean;
|
341
|
+
/**
|
342
|
+
* This is only supported by some objects if they implement
|
343
|
+
* shouldCreateHistoryStep where they can control what changes
|
344
|
+
* url changes should add a new browser history entry.
|
345
|
+
*/
|
346
|
+
createBrowserHistorySteps?: boolean;
|
347
|
+
}
|
333
348
|
|
334
349
|
/**
|
335
350
|
*
|
@@ -364,11 +379,6 @@ declare abstract class SceneObjectBase<TState extends SceneObjectState = SceneOb
|
|
364
379
|
protected _refCount: number;
|
365
380
|
protected _variableDependency: SceneVariableDependencyConfigLike | undefined;
|
366
381
|
protected _urlSync: SceneObjectUrlSyncHandler | undefined;
|
367
|
-
/**
|
368
|
-
* @experimental feature to support rendering a child scene object without it's parent being rendered.
|
369
|
-
* This flag will make it so that the parent is activated (if it's inactive) when this object is activated.
|
370
|
-
*/
|
371
|
-
_UNSAFE_PARENT_ACTIVATION: boolean;
|
372
382
|
constructor(state: TState);
|
373
383
|
/** Current state */
|
374
384
|
get state(): TState;
|
@@ -964,6 +974,38 @@ declare class SceneQueryController extends SceneObjectBase<SceneQueryStateContro
|
|
964
974
|
cancelAll(): void;
|
965
975
|
}
|
966
976
|
|
977
|
+
interface UrlSyncManagerLike {
|
978
|
+
initSync(root: SceneObject): void;
|
979
|
+
cleanUp(root: SceneObject): void;
|
980
|
+
handleNewLocation(location: Location): void;
|
981
|
+
handleNewObject(sceneObj: SceneObject): void;
|
982
|
+
}
|
983
|
+
/**
|
984
|
+
* Notify the url sync manager of a new object that has been added to the scene
|
985
|
+
* that needs to init state from URL.
|
986
|
+
*/
|
987
|
+
declare class NewSceneObjectAddedEvent extends BusEventWithPayload<SceneObject> {
|
988
|
+
static readonly type = "new-scene-object-added";
|
989
|
+
}
|
990
|
+
declare class UrlSyncManager implements UrlSyncManagerLike {
|
991
|
+
private _urlKeyMapper;
|
992
|
+
private _sceneRoot?;
|
993
|
+
private _subs;
|
994
|
+
private _lastLocation;
|
995
|
+
private _paramsCache;
|
996
|
+
private _options;
|
997
|
+
constructor(_options?: SceneUrlSyncOptions);
|
998
|
+
/**
|
999
|
+
* Updates the current scene state to match URL state.
|
1000
|
+
*/
|
1001
|
+
initSync(root: SceneObject): void;
|
1002
|
+
cleanUp(root: SceneObject): void;
|
1003
|
+
handleNewLocation(location: Location): void;
|
1004
|
+
handleNewObject(sceneObj: SceneObject): void;
|
1005
|
+
private handleSceneObjectStateChanged;
|
1006
|
+
getUrlState(root: SceneObject): SceneObjectUrlValues;
|
1007
|
+
}
|
1008
|
+
|
967
1009
|
/**
|
968
1010
|
* Get the closest node with variables
|
969
1011
|
*/
|
@@ -1032,6 +1074,11 @@ declare function getAncestor<ParentType>(sceneObject: SceneObject, ancestorType:
|
|
1032
1074
|
* Returns the closest query controller undefined if none found
|
1033
1075
|
*/
|
1034
1076
|
declare function getQueryController(sceneObject: SceneObject): SceneQueryControllerLike | undefined;
|
1077
|
+
/**
|
1078
|
+
* Returns the closest SceneObject that has a state property with the
|
1079
|
+
* name urlSyncManager that is of type UrlSyncManager
|
1080
|
+
*/
|
1081
|
+
declare function getUrlSyncManager(sceneObject: SceneObject): UrlSyncManagerLike | undefined;
|
1035
1082
|
|
1036
1083
|
declare const sceneGraph: {
|
1037
1084
|
getVariables: typeof getVariables;
|
@@ -1048,6 +1095,7 @@ declare const sceneGraph: {
|
|
1048
1095
|
findAllObjects: typeof findAllObjects;
|
1049
1096
|
getAncestor: typeof getAncestor;
|
1050
1097
|
getQueryController: typeof getQueryController;
|
1098
|
+
getUrlSyncManager: typeof getUrlSyncManager;
|
1051
1099
|
};
|
1052
1100
|
|
1053
1101
|
interface ActWhenVariableChangedState extends SceneObjectState {
|
@@ -1218,10 +1266,13 @@ interface SceneObjectUrlSyncConfigOptions {
|
|
1218
1266
|
declare class SceneObjectUrlSyncConfig implements SceneObjectUrlSyncHandler {
|
1219
1267
|
private _sceneObject;
|
1220
1268
|
private _keys;
|
1269
|
+
private _nextChangeShouldAddHistoryStep;
|
1221
1270
|
constructor(_sceneObject: SceneObjectWithUrlSync, _options: SceneObjectUrlSyncConfigOptions);
|
1222
1271
|
getKeys(): string[];
|
1223
1272
|
getUrlState(): SceneObjectUrlValues;
|
1224
1273
|
updateFromUrl(values: SceneObjectUrlValues): void;
|
1274
|
+
performBrowserHistoryAction(callback: () => void): void;
|
1275
|
+
shouldCreateHistoryStep(values: SceneObjectUrlValues): boolean;
|
1225
1276
|
}
|
1226
1277
|
|
1227
1278
|
declare class SceneTimeRange extends SceneObjectBase<SceneTimeRangeState> implements SceneTimeRangeLike {
|
@@ -1602,41 +1653,16 @@ declare class LocalValueVariable extends SceneObjectBase<LocalValueVariableState
|
|
1602
1653
|
isAncestorLoading(): boolean;
|
1603
1654
|
}
|
1604
1655
|
|
1605
|
-
|
1606
|
-
initSync(root: SceneObject): void;
|
1607
|
-
cleanUp(root: SceneObject): void;
|
1608
|
-
getUrlState(root: SceneObject): SceneObjectUrlValues;
|
1609
|
-
handleNewLocation(location: Location): void;
|
1610
|
-
handleNewObject(sceneObj: SceneObject): void;
|
1611
|
-
}
|
1612
|
-
declare class UrlSyncManager implements UrlSyncManagerLike {
|
1613
|
-
#private;
|
1614
|
-
private _urlKeyMapper;
|
1615
|
-
private _sceneRoot?;
|
1616
|
-
private _stateSub;
|
1617
|
-
private _lastLocation;
|
1618
|
-
private _paramsCache;
|
1619
|
-
/**
|
1620
|
-
* Updates the current scene state to match URL state.
|
1621
|
-
*/
|
1622
|
-
initSync(root: SceneObject): void;
|
1623
|
-
cleanUp(root: SceneObject): void;
|
1624
|
-
handleNewLocation(location: Location): void;
|
1625
|
-
handleNewObject(sceneObj: SceneObject): void;
|
1626
|
-
getUrlState(root: SceneObject): SceneObjectUrlValues;
|
1627
|
-
}
|
1628
|
-
declare function getUrlSyncManager(): UrlSyncManagerLike;
|
1629
|
-
|
1630
|
-
declare function useUrlSync(sceneRoot: SceneObject): boolean;
|
1656
|
+
declare function useUrlSync(sceneRoot: SceneObject, options?: SceneUrlSyncOptions): boolean;
|
1631
1657
|
|
1632
|
-
interface UrlSyncContextProviderProps {
|
1658
|
+
interface UrlSyncContextProviderProps extends SceneUrlSyncOptions {
|
1633
1659
|
scene: SceneObject;
|
1634
1660
|
children: React.ReactNode;
|
1635
1661
|
}
|
1636
1662
|
/**
|
1637
1663
|
* Right now this is actually not defining a context, but think it might in the future (with UrlSyncManager as the context value)
|
1638
1664
|
*/
|
1639
|
-
declare function UrlSyncContextProvider({ children, scene }: UrlSyncContextProviderProps): React$1.ReactNode;
|
1665
|
+
declare function UrlSyncContextProvider({ children, scene, updateUrlOnInit, createBrowserHistorySteps, }: UrlSyncContextProviderProps): React$1.ReactNode;
|
1640
1666
|
|
1641
1667
|
interface EmbeddedSceneState extends SceneObjectState {
|
1642
1668
|
/**
|
@@ -2164,6 +2190,7 @@ interface SceneRouteMatch<Params extends {
|
|
2164
2190
|
interface SceneAppState extends SceneObjectState {
|
2165
2191
|
pages: SceneAppPageLike[];
|
2166
2192
|
name?: string;
|
2193
|
+
urlSyncOptions?: SceneUrlSyncOptions;
|
2167
2194
|
}
|
2168
2195
|
interface SceneAppRoute {
|
2169
2196
|
path: string;
|
@@ -2717,4 +2744,4 @@ declare const sceneUtils: {
|
|
2717
2744
|
isGroupByVariable: typeof isGroupByVariable;
|
2718
2745
|
};
|
2719
2746
|
|
2720
|
-
export { AdHocFiltersVariable, CancelActivationHandler, ConstantVariable, ControlsLayout, CustomFormatterVariable, CustomTransformOperator, CustomTransformerDefinition, CustomVariable, CustomVariableValue, DataLayerFilter, DataRequestEnricher, DataSourceVariable, DeepPartial, EmbeddedScene, EmbeddedSceneState, ExtraQueryDataProcessor, ExtraQueryDescriptor, ExtraQueryProvider, FieldConfigBuilder, FieldConfigBuilders, FieldConfigOverridesBuilder, FiltersRequestEnricher, FormatVariable, GroupByVariable, InterpolationFormatParameter, IntervalVariable, LocalValueVariable, MacroVariableConstructor, MultiValueVariable, MultiValueVariableState, NestedScene, PanelBuilders, PanelOptionsBuilders, QueryRunnerState, QueryVariable, RuntimeDataSource, SafeSerializableSceneObject, SceneActivationHandler, SceneApp, SceneAppDrilldownView, SceneAppPage, SceneAppPageLike, SceneAppPageState, SceneAppRoute, SceneByFrameRepeater, SceneByVariableRepeater, SceneCSSGridItem, SceneCSSGridLayout, SceneCanvasText, SceneComponent, SceneComponentProps, SceneControlsSpacer, SceneDataLayerBase, SceneDataLayerControls, SceneDataLayerProvider, SceneDataLayerProviderState, SceneDataLayerSet, SceneDataLayerSetBase, SceneDataNode, SceneDataProvider, SceneDataProviderResult, SceneDataQuery, SceneDataState, SceneDataTransformer, SceneDataTransformerState, SceneDeactivationHandler, SceneDebugger, SceneFlexItem, SceneFlexItemLike, SceneFlexItemState, SceneFlexLayout, SceneGridItem, SceneGridItemLike, SceneGridItemStateLike, SceneGridLayout, SceneGridRow, SceneLayout, SceneLayoutChildOptions, SceneLayoutState, SceneObject, SceneObjectBase, SceneObjectRef, SceneObjectState, SceneObjectStateChangedEvent, SceneObjectStateChangedPayload, SceneObjectUrlSyncConfig, SceneObjectUrlSyncHandler, SceneObjectUrlValue, SceneObjectUrlValues, SceneObjectWithUrlSync, SceneQueryControllerEntry, SceneQueryControllerEntryType, SceneQueryControllerLike, SceneQueryRunner, SceneReactObject, SceneRefreshPicker, SceneRefreshPickerState, SceneRouteMatch, SceneStateChangedHandler, SceneStatelessBehavior, SceneTimePicker, SceneTimeRange, SceneTimeRangeCompare, SceneTimeRangeLike, SceneTimeRangeState, SceneTimeRangeTransformerBase, SceneTimeZoneOverride, SceneToolbarButton, SceneToolbarInput, SceneVariable, SceneVariableDependencyConfigLike, SceneVariableSet, SceneVariableSetState, SceneVariableState, SceneVariableValueChangedEvent, SceneVariables, SplitLayout, TestVariable, TextBoxVariable, UrlSyncContextProvider, UrlSyncManager, UrlSyncManagerLike, UseStateHookOptions, UserActionEvent, ValidateAndUpdateResult, VariableCustomFormatterFn, VariableDependencyConfig, VariableGetOptionsArgs, VariableValue, VariableValueControl, VariableValueOption, VariableValueSelectWrapper, VariableValueSelectors, VariableValueSingle, VizConfig, VizConfigBuilder, VizConfigBuilders, VizPanel, VizPanelBuilder, VizPanelMenu, VizPanelState, index$1 as behaviors, index as dataLayers, formatRegistry,
|
2747
|
+
export { AdHocFiltersVariable, CancelActivationHandler, ConstantVariable, ControlsLayout, CustomFormatterVariable, CustomTransformOperator, CustomTransformerDefinition, CustomVariable, CustomVariableValue, DataLayerFilter, DataRequestEnricher, DataSourceVariable, DeepPartial, EmbeddedScene, EmbeddedSceneState, ExtraQueryDataProcessor, ExtraQueryDescriptor, ExtraQueryProvider, FieldConfigBuilder, FieldConfigBuilders, FieldConfigOverridesBuilder, FiltersRequestEnricher, FormatVariable, GroupByVariable, InterpolationFormatParameter, IntervalVariable, LocalValueVariable, MacroVariableConstructor, MultiValueVariable, MultiValueVariableState, NestedScene, NewSceneObjectAddedEvent, PanelBuilders, PanelOptionsBuilders, QueryRunnerState, QueryVariable, RuntimeDataSource, SafeSerializableSceneObject, SceneActivationHandler, SceneApp, SceneAppDrilldownView, SceneAppPage, SceneAppPageLike, SceneAppPageState, SceneAppRoute, SceneByFrameRepeater, SceneByVariableRepeater, SceneCSSGridItem, SceneCSSGridLayout, SceneCanvasText, SceneComponent, SceneComponentProps, SceneControlsSpacer, SceneDataLayerBase, SceneDataLayerControls, SceneDataLayerProvider, SceneDataLayerProviderState, SceneDataLayerSet, SceneDataLayerSetBase, SceneDataNode, SceneDataProvider, SceneDataProviderResult, SceneDataQuery, SceneDataState, SceneDataTransformer, SceneDataTransformerState, SceneDeactivationHandler, SceneDebugger, SceneFlexItem, SceneFlexItemLike, SceneFlexItemState, SceneFlexLayout, SceneGridItem, SceneGridItemLike, SceneGridItemStateLike, SceneGridLayout, SceneGridRow, SceneLayout, SceneLayoutChildOptions, SceneLayoutState, SceneObject, SceneObjectBase, SceneObjectRef, SceneObjectState, SceneObjectStateChangedEvent, SceneObjectStateChangedPayload, SceneObjectUrlSyncConfig, SceneObjectUrlSyncHandler, SceneObjectUrlValue, SceneObjectUrlValues, SceneObjectWithUrlSync, SceneQueryControllerEntry, SceneQueryControllerEntryType, SceneQueryControllerLike, SceneQueryRunner, SceneReactObject, SceneRefreshPicker, SceneRefreshPickerState, SceneRouteMatch, SceneStateChangedHandler, SceneStatelessBehavior, SceneTimePicker, SceneTimeRange, SceneTimeRangeCompare, SceneTimeRangeLike, SceneTimeRangeState, SceneTimeRangeTransformerBase, SceneTimeZoneOverride, SceneToolbarButton, SceneToolbarInput, SceneUrlSyncOptions, SceneVariable, SceneVariableDependencyConfigLike, SceneVariableSet, SceneVariableSetState, SceneVariableState, SceneVariableValueChangedEvent, SceneVariables, SplitLayout, TestVariable, TextBoxVariable, UrlSyncContextProvider, UrlSyncManager, UrlSyncManagerLike, UseStateHookOptions, UserActionEvent, ValidateAndUpdateResult, VariableCustomFormatterFn, VariableDependencyConfig, VariableGetOptionsArgs, VariableValue, VariableValueControl, VariableValueOption, VariableValueSelectWrapper, VariableValueSelectors, VariableValueSingle, VizConfig, VizConfigBuilder, VizConfigBuilders, VizPanel, VizPanelBuilder, VizPanelMenu, VizPanelState, index$1 as behaviors, index as dataLayers, formatRegistry, isCustomVariableValue, isDataLayer, isDataRequestEnricher, isFiltersRequestEnricher, isSceneObject, registerQueryWithController, registerRuntimeDataSource, renderSelectForVariable, sceneGraph, sceneUtils, useSceneApp, useSceneObjectState, useUrlSync };
|