@grafana/scenes 5.15.0--canary.845.11012035874.0 → 5.15.1--canary.899.11016830015.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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, 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":"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"}
1
+ {"version":3,"file":"UrlSyncManager.js","sources":["../../../src/services/UrlSyncManager.ts"],"sourcesContent":["import { Location } from 'history';\n\nimport { LocationService, locationService as locationServiceRuntime } 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 _locationService: LocationService;\n private _paramsCache: UrlParamsCache;\n private _options: SceneUrlSyncOptions;\n\n public constructor(_options: SceneUrlSyncOptions = {}, locationService: LocationService = locationServiceRuntime) {\n this._options = _options;\n this._locationService = locationService;\n this._paramsCache = new UrlParamsCache(locationService);\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 = this._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 this._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 = this._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 this._locationService.partial(mappedUpdated, shouldReplace);\n\n /// Mark the location already handled\n this._lastLocation = this._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 constructor(private locationService: LocationService) {}\n\n public getParams(): URLSearchParams {\n const location = this.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, locationService: LocationService): UrlSyncManagerLike {\n return useMemo(\n () =>\n new UrlSyncManager(\n {\n updateUrlOnInit: options.updateUrlOnInit,\n createBrowserHistorySteps: options.createBrowserHistorySteps,\n },\n locationService\n ),\n [options.updateUrlOnInit, options.createBrowserHistorySteps, locationService]\n );\n}\n"],"names":["locationService","locationServiceRuntime"],"mappings":"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"}
@@ -1,13 +1,14 @@
1
1
  import { useState, useEffect } from 'react';
2
2
  import { useLocation } from 'react-router-dom';
3
- import { locationService } from '@grafana/runtime';
4
3
  import { writeSceneLog } from '../utils/writeSceneLog.js';
5
4
  import { useUrlSyncManager } from './UrlSyncManager.js';
5
+ import { useLocationServiceSafe } from '../utils/utils.js';
6
6
 
7
7
  function useUrlSync(sceneRoot, options = {}) {
8
8
  const location = useLocation();
9
+ const locationService = useLocationServiceSafe();
9
10
  const [isInitialized, setIsInitialized] = useState(false);
10
- const urlSyncManager = useUrlSyncManager(options);
11
+ const urlSyncManager = useUrlSyncManager(options, locationService);
11
12
  useEffect(() => {
12
13
  urlSyncManager.initSync(sceneRoot);
13
14
  setIsInitialized(true);
@@ -20,7 +21,7 @@ function useUrlSync(sceneRoot, options = {}) {
20
21
  writeSceneLog("useUrlSync", "latestLocation different from location");
21
22
  }
22
23
  urlSyncManager.handleNewLocation(locationToHandle);
23
- }, [sceneRoot, urlSyncManager, location]);
24
+ }, [sceneRoot, urlSyncManager, location, locationService]);
24
25
  return isInitialized;
25
26
  }
26
27
 
@@ -1 +1 @@
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;;;;"}
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 { writeSceneLog } from '../utils/writeSceneLog';\nimport { useUrlSyncManager } from './UrlSyncManager';\nimport { useLocationServiceSafe } from '../utils/utils';\n\nexport function useUrlSync(sceneRoot: SceneObject, options: SceneUrlSyncOptions = {}): boolean {\n const location = useLocation();\n const locationService = useLocationServiceSafe();\n const [isInitialized, setIsInitialized] = useState(false);\n const urlSyncManager = useUrlSyncManager(options, locationService);\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, locationService]);\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,kBAAkB,sBAAuB,EAAA,CAAA;AAC/C,EAAA,MAAM,CAAC,aAAA,EAAe,gBAAgB,CAAA,GAAI,SAAS,KAAK,CAAA,CAAA;AACxD,EAAM,MAAA,cAAA,GAAiB,iBAAkB,CAAA,OAAA,EAAS,eAAe,CAAA,CAAA;AAEjE,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,KAChD,CAAC,SAAA,EAAW,cAAgB,EAAA,QAAA,EAAU,eAAe,CAAC,CAAA,CAAA;AAEzD,EAAO,OAAA,aAAA,CAAA;AACT;;;;"}
@@ -1,6 +1,11 @@
1
+ import { useLocationService, locationService } from '@grafana/runtime';
2
+
1
3
  function setBaseClassState(sceneObject, newState) {
2
4
  sceneObject.setState(newState);
3
5
  }
6
+ function useLocationServiceSafe() {
7
+ return useLocationService ? useLocationService() : locationService;
8
+ }
4
9
 
5
- export { setBaseClassState };
10
+ export { setBaseClassState, useLocationServiceSafe };
6
11
  //# sourceMappingURL=utils.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"utils.js","sources":["../../../src/utils/utils.ts"],"sourcesContent":["import { SceneObject, SceneObjectState } from '../core/types';\n\n/**\n * This function works around the problem of Contravariance of the SceneObject.setState function\n * Contravariance is not enforce by interfaces and here we use the SceneObject interface to access the setState function\n */\nexport function setBaseClassState<T extends SceneObjectState>(sceneObject: SceneObject<T>, newState: Partial<T>) {\n sceneObject.setState(newState);\n}\n"],"names":[],"mappings":"AAMgB,SAAA,iBAAA,CAA8C,aAA6B,QAAsB,EAAA;AAC/G,EAAA,WAAA,CAAY,SAAS,QAAQ,CAAA,CAAA;AAC/B;;;;"}
1
+ {"version":3,"file":"utils.js","sources":["../../../src/utils/utils.ts"],"sourcesContent":["import { SceneObject, SceneObjectState } from '../core/types';\nimport { locationService as locationServiceRuntime } from '@grafana/runtime';\n// @ts-ignore\n// eslint-disable-next-line no-duplicate-imports\nimport { useLocationService } from '@grafana/runtime';\n\n/**\n * This function works around the problem of Contravariance of the SceneObject.setState function\n * Contravariance is not enforce by interfaces and here we use the SceneObject interface to access the setState function\n */\nexport function setBaseClassState<T extends SceneObjectState>(sceneObject: SceneObject<T>, newState: Partial<T>) {\n sceneObject.setState(newState);\n}\n\n/**\n * Safe way to get location service that fallbacks to singleton for older runtime versions where useLocationService is\n * not available.\n */\nexport function useLocationServiceSafe() {\n // This is basically a version/feature check for grafana/runtime so this 'if' should be stable (ie for one instance\n // of grafana this will always be true or false) so it should be safe to ignore the hook rule here\n // eslint-disable-next-line react-hooks/rules-of-hooks\n return useLocationService ? useLocationService() : locationServiceRuntime;\n}\n"],"names":["locationServiceRuntime"],"mappings":";;AAUgB,SAAA,iBAAA,CAA8C,aAA6B,QAAsB,EAAA;AAC/G,EAAA,WAAA,CAAY,SAAS,QAAQ,CAAA,CAAA;AAC/B,CAAA;AAMO,SAAS,sBAAyB,GAAA;AAIvC,EAAO,OAAA,kBAAA,GAAqB,oBAAuB,GAAAA,eAAA,CAAA;AACrD;;;;"}
package/dist/index.d.ts CHANGED
@@ -1,12 +1,12 @@
1
1
  import * as _grafana_data from '@grafana/data';
2
- import { BusEventWithPayload, PanelData, BusEvent, BusEventType, BusEventHandler, TimeRange, DataQueryRequest, DataSourceGetTagKeysOptions, DataSourceGetTagValuesOptions, DataTransformContext, DataFrame, PanelPlugin, EventBus, DataQuery as DataQuery$1, DataSourceApi, Registry, RegistryItem, ScopedVars, AdHocVariableFilter, SelectableValue, MetricFindValue, GetTagResponse, VariableRefresh as VariableRefresh$1, VariableSort, EventFilterOptions, AnnotationEvent, AnnotationQuery, DataTransformerConfig, PanelMenuItem, FieldConfigSource, PanelModel, AbsoluteTimeRange, InterpolateFunction, IconName as IconName$1, PageLayoutType, FieldConfig, FieldType, FieldValueMatcherConfig, ScopedVar } from '@grafana/data';
2
+ import { BusEventWithPayload, PanelData, BusEvent, BusEventType, BusEventHandler, TimeRange, DataQueryRequest, DataSourceGetTagKeysOptions, DataSourceGetTagValuesOptions, DataTransformContext, DataFrame, UrlQueryMap, PanelPlugin, EventBus, DataQuery as DataQuery$1, DataSourceApi, Registry, RegistryItem, ScopedVars, AdHocVariableFilter, SelectableValue, MetricFindValue, GetTagResponse, VariableRefresh as VariableRefresh$1, VariableSort, EventFilterOptions, AnnotationEvent, AnnotationQuery, DataTransformerConfig, PanelMenuItem, FieldConfigSource, PanelModel, AbsoluteTimeRange, InterpolateFunction, IconName as IconName$1, PageLayoutType, FieldConfig, FieldType, FieldValueMatcherConfig, ScopedVar } from '@grafana/data';
3
3
  import * as React$1 from 'react';
4
4
  import React__default, { CSSProperties, ComponentType } from 'react';
5
5
  import * as rxjs from 'rxjs';
6
6
  import { Observable, Unsubscribable, MonoTypeOperatorFunction, Subscription, ReplaySubject } from 'rxjs';
7
7
  import * as _grafana_schema from '@grafana/schema';
8
8
  import { VariableType, VariableHide, TimeZone, DataTopic, DataQuery, DataSourceRef, VariableRefresh, LoadingState, DashboardCursorSync, MatcherConfig, TableFieldOptions } from '@grafana/schema';
9
- import { VariableInterpolation } from '@grafana/runtime';
9
+ import { LocationService, VariableInterpolation } from '@grafana/runtime';
10
10
  import { Location } from 'history';
11
11
  import { PanelContext, IconName } from '@grafana/ui';
12
12
  import ReactGridLayout from 'react-grid-layout';
@@ -349,10 +349,11 @@ interface SceneUrlSyncOptions {
349
349
  /**
350
350
  *
351
351
  * @param path Url to append query params to
352
+ * @param searchObject Query params of the URL
352
353
  * @param preserveParams Query params to preserve
353
354
  * @returns Url with query params
354
355
  */
355
- declare function getUrlWithAppState(path: string, preserveParams?: string[]): string;
356
+ declare function getUrlWithAppState(path: string, searchObject: UrlQueryMap, preserveParams?: string[]): string;
356
357
 
357
358
  interface RuntimePanelPluginOptions {
358
359
  /**
@@ -997,9 +998,10 @@ declare class UrlSyncManager implements UrlSyncManagerLike {
997
998
  private _sceneRoot?;
998
999
  private _subs;
999
1000
  private _lastLocation;
1001
+ private _locationService;
1000
1002
  private _paramsCache;
1001
1003
  private _options;
1002
- constructor(_options?: SceneUrlSyncOptions);
1004
+ constructor(_options?: SceneUrlSyncOptions, locationService?: LocationService);
1003
1005
  /**
1004
1006
  * Updates the current scene state to match URL state.
1005
1007
  */
@@ -2127,10 +2129,6 @@ interface SceneGridLayoutState extends SceneObjectState {
2127
2129
  /** Enable or disable item resizing */
2128
2130
  isResizable?: boolean;
2129
2131
  isLazy?: boolean;
2130
- /** Panel search */
2131
- showPanelSearch?: boolean;
2132
- searchString?: string;
2133
- panelsPerRow?: number;
2134
2132
  /**
2135
2133
  * Fit panels to height of the grid. This will scale down the panels vertically to fit available height.
2136
2134
  * The row height is not changed, only the y position and height of the panels.
@@ -2144,7 +2142,6 @@ declare class SceneGridLayout extends SceneObjectBase<SceneGridLayoutState> impl
2144
2142
  private _skipOnLayoutChange;
2145
2143
  private _oldLayout;
2146
2144
  private _loadOldLayout;
2147
- private savedLayout;
2148
2145
  constructor(state: SceneGridLayoutState);
2149
2146
  /**
2150
2147
  * SceneLayout interface. Used for example by VizPanelRenderer
package/dist/index.js CHANGED
@@ -61,8 +61,8 @@ function useAppQueryParams() {
61
61
  const location = reactRouterDom.useLocation();
62
62
  return runtime.locationSearchToObject(location.search || "");
63
63
  }
64
- function getUrlWithAppState(path, preserveParams) {
65
- const paramsCopy = __spreadValues$O({}, runtime.locationService.getSearchObject());
64
+ function getUrlWithAppState(path, searchObject, preserveParams) {
65
+ const paramsCopy = __spreadValues$O({}, searchObject);
66
66
  if (preserveParams) {
67
67
  for (const key of Object.keys(paramsCopy)) {
68
68
  if (!preserveParams.includes(key)) {
@@ -2196,6 +2196,9 @@ function findActiveGroupByVariablesByUid(dsUid) {
2196
2196
  function setBaseClassState(sceneObject, newState) {
2197
2197
  sceneObject.setState(newState);
2198
2198
  }
2199
+ function useLocationServiceSafe() {
2200
+ return runtime.useLocationService ? runtime.useLocationService() : runtime.locationService;
2201
+ }
2199
2202
 
2200
2203
  class MultiValueVariable extends SceneObjectBase {
2201
2204
  constructor() {
@@ -9399,10 +9402,11 @@ class NewSceneObjectAddedEvent extends data.BusEventWithPayload {
9399
9402
  }
9400
9403
  NewSceneObjectAddedEvent.type = "new-scene-object-added";
9401
9404
  class UrlSyncManager {
9402
- constructor(_options = {}) {
9405
+ constructor(_options = {}, locationService = runtime.locationService) {
9403
9406
  this._urlKeyMapper = new UniqueUrlKeyMapper();
9404
- this._paramsCache = new UrlParamsCache();
9405
9407
  this._options = _options;
9408
+ this._locationService = locationService;
9409
+ this._paramsCache = new UrlParamsCache(locationService);
9406
9410
  }
9407
9411
  initSync(root) {
9408
9412
  var _a;
@@ -9424,12 +9428,12 @@ class UrlSyncManager {
9424
9428
  })
9425
9429
  );
9426
9430
  this._urlKeyMapper.clear();
9427
- this._lastLocation = runtime.locationService.getLocation();
9431
+ this._lastLocation = this._locationService.getLocation();
9428
9432
  this.handleNewObject(this._sceneRoot);
9429
9433
  if (this._options.updateUrlOnInit) {
9430
9434
  const urlState = getUrlState(root);
9431
9435
  if (isUrlStateDifferent(urlState, this._paramsCache.getParams())) {
9432
- runtime.locationService.partial(urlState, true);
9436
+ this._locationService.partial(urlState, true);
9433
9437
  }
9434
9438
  }
9435
9439
  }
@@ -9471,7 +9475,7 @@ class UrlSyncManager {
9471
9475
  return;
9472
9476
  }
9473
9477
  const newUrlState = changedObject.urlSync.getUrlState();
9474
- const searchParams = runtime.locationService.getSearch();
9478
+ const searchParams = this._locationService.getSearch();
9475
9479
  const mappedUpdated = {};
9476
9480
  for (const [key, newUrlValue] of Object.entries(newUrlState)) {
9477
9481
  const uniqueKey = this._urlKeyMapper.getUniqueKey(key, changedObject);
@@ -9484,8 +9488,8 @@ class UrlSyncManager {
9484
9488
  const shouldCreateHistoryEntry = (_b = (_a = changedObject.urlSync).shouldCreateHistoryStep) == null ? void 0 : _b.call(_a, newUrlState);
9485
9489
  const shouldReplace = shouldCreateHistoryEntry !== true;
9486
9490
  writeSceneLog("UrlSyncManager", "onStateChange updating URL");
9487
- runtime.locationService.partial(mappedUpdated, shouldReplace);
9488
- this._lastLocation = runtime.locationService.getLocation();
9491
+ this._locationService.partial(mappedUpdated, shouldReplace);
9492
+ this._lastLocation = this._locationService.getLocation();
9489
9493
  }
9490
9494
  }
9491
9495
  getUrlState(root) {
@@ -9493,12 +9497,13 @@ class UrlSyncManager {
9493
9497
  }
9494
9498
  }
9495
9499
  class UrlParamsCache {
9496
- constructor() {
9500
+ constructor(locationService) {
9501
+ this.locationService = locationService;
9497
9502
  __privateAdd(this, _cache, void 0);
9498
9503
  __privateAdd(this, _location, void 0);
9499
9504
  }
9500
9505
  getParams() {
9501
- const location = runtime.locationService.getLocation();
9506
+ const location = this.locationService.getLocation();
9502
9507
  if (__privateGet(this, _location) === location) {
9503
9508
  return __privateGet(this, _cache);
9504
9509
  }
@@ -9517,33 +9522,37 @@ function isUrlStateDifferent(sceneUrlState, currentParams) {
9517
9522
  }
9518
9523
  return false;
9519
9524
  }
9520
- function useUrlSyncManager(options) {
9525
+ function useUrlSyncManager(options, locationService) {
9521
9526
  return React.useMemo(
9522
- () => new UrlSyncManager({
9523
- updateUrlOnInit: options.updateUrlOnInit,
9524
- createBrowserHistorySteps: options.createBrowserHistorySteps
9525
- }),
9526
- [options.updateUrlOnInit, options.createBrowserHistorySteps]
9527
+ () => new UrlSyncManager(
9528
+ {
9529
+ updateUrlOnInit: options.updateUrlOnInit,
9530
+ createBrowserHistorySteps: options.createBrowserHistorySteps
9531
+ },
9532
+ locationService
9533
+ ),
9534
+ [options.updateUrlOnInit, options.createBrowserHistorySteps, locationService]
9527
9535
  );
9528
9536
  }
9529
9537
 
9530
9538
  function useUrlSync(sceneRoot, options = {}) {
9531
9539
  const location = reactRouterDom.useLocation();
9540
+ const locationService = useLocationServiceSafe();
9532
9541
  const [isInitialized, setIsInitialized] = React.useState(false);
9533
- const urlSyncManager = useUrlSyncManager(options);
9542
+ const urlSyncManager = useUrlSyncManager(options, locationService);
9534
9543
  React.useEffect(() => {
9535
9544
  urlSyncManager.initSync(sceneRoot);
9536
9545
  setIsInitialized(true);
9537
9546
  return () => urlSyncManager.cleanUp(sceneRoot);
9538
9547
  }, [sceneRoot, urlSyncManager]);
9539
9548
  React.useEffect(() => {
9540
- const latestLocation = runtime.locationService.getLocation();
9549
+ const latestLocation = locationService.getLocation();
9541
9550
  const locationToHandle = latestLocation !== location ? latestLocation : location;
9542
9551
  if (latestLocation !== location) {
9543
9552
  writeSceneLog("useUrlSync", "latestLocation different from location");
9544
9553
  }
9545
9554
  urlSyncManager.handleNewLocation(locationToHandle);
9546
- }, [sceneRoot, urlSyncManager, location]);
9555
+ }, [sceneRoot, urlSyncManager, location, locationService]);
9547
9556
  return isInitialized;
9548
9557
  }
9549
9558
 
@@ -9830,7 +9839,7 @@ var __objRest = (source, exclude) => {
9830
9839
  return target;
9831
9840
  };
9832
9841
  function SceneGridLayoutRenderer({ model }) {
9833
- const { children, isLazy, isDraggable, isResizable, showPanelSearch } = model.useState();
9842
+ const { children, isLazy, isDraggable, isResizable } = model.useState();
9834
9843
  const [outerDivRef, { width, height }] = reactUse.useMeasure();
9835
9844
  const ref = React.useRef(null);
9836
9845
  React.useEffect(() => {
@@ -9876,67 +9885,7 @@ function SceneGridLayoutRenderer({ model }) {
9876
9885
  return /* @__PURE__ */ React__default["default"].createElement("div", {
9877
9886
  ref: outerDivRef,
9878
9887
  style: { flex: "1 1 auto", position: "relative", zIndex: 1, width: "100%" }
9879
- }, showPanelSearch && /* @__PURE__ */ React__default["default"].createElement(PanelSearchControls, {
9880
- model
9881
- }), renderGrid(width, height));
9882
- }
9883
- function PanelSearchControls({ model }) {
9884
- const { searchString, panelsPerRow } = model.useState();
9885
- const styles = ui.useStyles2(getPanelSearchStyles);
9886
- const onSearchStringChange = React.useCallback(
9887
- (e) => {
9888
- model.setState({ searchString: e.currentTarget.value });
9889
- },
9890
- [model]
9891
- );
9892
- const onPanelsPerRowChange = React.useCallback(
9893
- (e) => {
9894
- model.setState({ panelsPerRow: Number.parseInt(e.currentTarget.value, 10) });
9895
- },
9896
- [model]
9897
- );
9898
- return /* @__PURE__ */ React__default["default"].createElement("div", {
9899
- className: styles.wrapper
9900
- }, /* @__PURE__ */ React__default["default"].createElement("div", {
9901
- id: "panel-search",
9902
- className: styles.input
9903
- }, /* @__PURE__ */ React__default["default"].createElement(ControlsLabel, {
9904
- isLoading: false,
9905
- label: "Panel search",
9906
- htmlFor: "panel-search-input"
9907
- }), /* @__PURE__ */ React__default["default"].createElement(ui.Input, {
9908
- id: "panel-search-input",
9909
- label: "Search",
9910
- placeholder: "Enter value",
9911
- value: searchString,
9912
- onChange: onSearchStringChange
9913
- })), /* @__PURE__ */ React__default["default"].createElement("div", {
9914
- id: "panels-per-row",
9915
- className: styles.input
9916
- }, /* @__PURE__ */ React__default["default"].createElement(ControlsLabel, {
9917
- isLoading: false,
9918
- label: "Panels per row",
9919
- htmlFor: "panels-per-row-input"
9920
- }), /* @__PURE__ */ React__default["default"].createElement(ui.Input, {
9921
- id: "panels-per-row-input",
9922
- type: "number",
9923
- placeholder: "Enter value",
9924
- label: "Panels per row",
9925
- value: panelsPerRow,
9926
- onChange: onPanelsPerRowChange
9927
- })));
9928
- }
9929
- function getPanelSearchStyles(theme) {
9930
- return {
9931
- wrapper: css.css({
9932
- display: "flex",
9933
- gap: theme.spacing(1),
9934
- marginBottom: theme.spacing(1)
9935
- }),
9936
- input: css.css({
9937
- display: "flex"
9938
- })
9939
- };
9888
+ }, renderGrid(width, height));
9940
9889
  }
9941
9890
  const GridItemWrapper = React__default["default"].forwardRef((props, ref) => {
9942
9891
  var _b;
@@ -10085,7 +10034,6 @@ const _SceneGridLayout = class extends SceneObjectBase {
10085
10034
  this._skipOnLayoutChange = false;
10086
10035
  this._oldLayout = [];
10087
10036
  this._loadOldLayout = false;
10088
- this.savedLayout = void 0;
10089
10037
  this.onLayoutChange = (layout) => {
10090
10038
  if (this._skipOnLayoutChange) {
10091
10039
  this._skipOnLayoutChange = false;
@@ -10294,38 +10242,7 @@ const _SceneGridLayout = class extends SceneObjectBase {
10294
10242
  }
10295
10243
  buildGridLayout(width, height) {
10296
10244
  let cells = [];
10297
- const searchString = this.state.searchString;
10298
- const panelsPerRow = this.state.panelsPerRow;
10299
- let children = this.state.children;
10300
- if (searchString && searchString !== "" || panelsPerRow && Number.isInteger(panelsPerRow)) {
10301
- if (this.savedLayout === void 0) {
10302
- this.savedLayout = this.state.children.map((v) => v.clone());
10303
- }
10304
- const panelFilterInterpolated = interpolate(this, searchString).toLowerCase();
10305
- const filteredChildren = this.state.children.filter((v) => {
10306
- var _a, _b, _c, _d;
10307
- const panelTitleInterpolated = interpolate(v, (_b = (_a = v.state.body) == null ? void 0 : _a.state) == null ? void 0 : _b.title).toLowerCase();
10308
- return typeof ((_d = (_c = v.state.body) == null ? void 0 : _c.state) == null ? void 0 : _d.title) === "string" && panelTitleInterpolated.includes(panelFilterInterpolated);
10309
- });
10310
- this._skipOnLayoutChange = true;
10311
- const rowSize = typeof panelsPerRow === "number" && Number.isInteger(panelsPerRow) && panelsPerRow > 0 ? panelsPerRow : 2;
10312
- const panelWidth = GRID_COLUMN_COUNT / rowSize;
10313
- const panelHeight = 5;
10314
- return filteredChildren.map((child, i) => __spreadProps$5(__spreadValues$8({}, this.toGridCell(child)), {
10315
- x: i % rowSize * panelWidth,
10316
- y: Math.floor(i / rowSize) * panelHeight,
10317
- w: panelWidth,
10318
- h: panelHeight,
10319
- isResizable: false,
10320
- isDraggable: false
10321
- }));
10322
- } else if ((!searchString || searchString === "") && !panelsPerRow) {
10323
- if (this.savedLayout) {
10324
- children = this.savedLayout;
10325
- this.savedLayout = void 0;
10326
- }
10327
- }
10328
- for (const child of children) {
10245
+ for (const child of this.state.children) {
10329
10246
  cells.push(this.toGridCell(child));
10330
10247
  if (child instanceof SceneGridRow && !child.state.isCollapsed) {
10331
10248
  for (const rowChild of child.state.children) {
@@ -12203,6 +12120,7 @@ function SceneAppPageView({ page, routeProps }) {
12203
12120
  const appContext = React.useContext(SceneAppContext);
12204
12121
  const isInitialized = containerState.initializedScene === scene;
12205
12122
  const { layout } = page.state;
12123
+ const locationService = useLocationServiceSafe();
12206
12124
  React.useLayoutEffect(() => {
12207
12125
  if (!isInitialized) {
12208
12126
  containerPage.initializeScene(scene);
@@ -12219,10 +12137,13 @@ function SceneAppPageView({ page, routeProps }) {
12219
12137
  text: containerState.title,
12220
12138
  img: containerState.titleImg,
12221
12139
  icon: containerState.titleIcon,
12222
- url: getUrlWithAppState(containerState.url, containerState.preserveUrlKeys),
12140
+ url: getUrlWithAppState(containerState.url, locationService.getSearchObject(), containerState.preserveUrlKeys),
12223
12141
  hideFromBreadcrumbs: containerState.hideFromBreadcrumbs,
12224
12142
  parentItem: getParentBreadcrumbs(
12225
- containerState.getParentPage ? containerState.getParentPage() : containerPage.parent)
12143
+ containerState.getParentPage ? containerState.getParentPage() : containerPage.parent,
12144
+ params,
12145
+ locationService.getSearchObject()
12146
+ )
12226
12147
  };
12227
12148
  if (containerState.tabs) {
12228
12149
  pageNav.children = containerState.tabs.map((tab) => {
@@ -12231,7 +12152,7 @@ function SceneAppPageView({ page, routeProps }) {
12231
12152
  icon: tab.state.titleIcon,
12232
12153
  tabSuffix: tab.state.tabSuffix,
12233
12154
  active: page === tab,
12234
- url: getUrlWithAppState(tab.state.url, tab.state.preserveUrlKeys),
12155
+ url: getUrlWithAppState(tab.state.url, locationService.getSearchObject(), tab.state.preserveUrlKeys),
12235
12156
  parentItem: pageNav
12236
12157
  };
12237
12158
  });
@@ -12265,14 +12186,17 @@ function getParentPageIfTab(page) {
12265
12186
  }
12266
12187
  return page;
12267
12188
  }
12268
- function getParentBreadcrumbs(parent, params) {
12189
+ function getParentBreadcrumbs(parent, params, searchObject) {
12269
12190
  if (parent instanceof SceneAppPage) {
12270
12191
  return {
12271
12192
  text: parent.state.title,
12272
- url: getUrlWithAppState(parent.state.url, parent.state.preserveUrlKeys),
12193
+ url: getUrlWithAppState(parent.state.url, searchObject, parent.state.preserveUrlKeys),
12273
12194
  hideFromBreadcrumbs: parent.state.hideFromBreadcrumbs,
12274
12195
  parentItem: getParentBreadcrumbs(
12275
- parent.state.getParentPage ? parent.state.getParentPage() : parent.parent)
12196
+ parent.state.getParentPage ? parent.state.getParentPage() : parent.parent,
12197
+ params,
12198
+ searchObject
12199
+ )
12276
12200
  };
12277
12201
  }
12278
12202
  return void 0;