@grafana/scenes 5.12.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/index.js CHANGED
@@ -643,6 +643,7 @@ const emptyPanelData = {
643
643
  class SceneObjectUrlSyncConfig {
644
644
  constructor(_sceneObject, _options) {
645
645
  this._sceneObject = _sceneObject;
646
+ this._nextChangeShouldAddHistoryStep = false;
646
647
  this._keys = _options.keys;
647
648
  }
648
649
  getKeys() {
@@ -657,6 +658,14 @@ class SceneObjectUrlSyncConfig {
657
658
  updateFromUrl(values) {
658
659
  this._sceneObject.updateFromUrl(values);
659
660
  }
661
+ performBrowserHistoryAction(callback) {
662
+ this._nextChangeShouldAddHistoryStep = true;
663
+ callback();
664
+ this._nextChangeShouldAddHistoryStep = false;
665
+ }
666
+ shouldCreateHistoryStep(values) {
667
+ return this._nextChangeShouldAddHistoryStep;
668
+ }
660
669
  }
661
670
 
662
671
  const INTERVAL_STRING_REGEX = /^\d+[yYmMsSwWhHdD]$/;
@@ -760,11 +769,15 @@ class SceneTimeRange extends SceneObjectBase {
760
769
  this.state.UNSAFE_nowDelay
761
770
  );
762
771
  if (update.from !== this.state.from || update.to !== this.state.to) {
763
- this.setState(update);
772
+ this._urlSync.performBrowserHistoryAction(() => {
773
+ this.setState(update);
774
+ });
764
775
  }
765
776
  };
766
777
  this.onTimeZoneChange = (timeZone) => {
767
- this.setState({ timeZone });
778
+ this._urlSync.performBrowserHistoryAction(() => {
779
+ this.setState({ timeZone });
780
+ });
768
781
  };
769
782
  this.onRefresh = () => {
770
783
  this.setState({
@@ -6001,6 +6014,16 @@ function getQueryController(sceneObject) {
6001
6014
  }
6002
6015
  return void 0;
6003
6016
  }
6017
+ function getUrlSyncManager(sceneObject) {
6018
+ let parent = sceneObject;
6019
+ while (parent) {
6020
+ if ("urlSyncManager" in parent.state) {
6021
+ return parent.state.urlSyncManager;
6022
+ }
6023
+ parent = parent.parent;
6024
+ }
6025
+ return void 0;
6026
+ }
6004
6027
 
6005
6028
  const sceneGraph = {
6006
6029
  getVariables,
@@ -6016,7 +6039,8 @@ const sceneGraph = {
6016
6039
  findObject,
6017
6040
  findAllObjects,
6018
6041
  getAncestor,
6019
- getQueryController
6042
+ getQueryController,
6043
+ getUrlSyncManager
6020
6044
  };
6021
6045
 
6022
6046
  class UniqueUrlKeyMapper {
@@ -9018,54 +9042,53 @@ var __privateSet = (obj, member, value, setter) => {
9018
9042
  setter ? setter.call(obj, value) : member.set(obj, value);
9019
9043
  return value;
9020
9044
  };
9021
- var _onStateChanged, _cache, _location;
9045
+ var _cache, _location;
9046
+ class NewSceneObjectAddedEvent extends data.BusEventWithPayload {
9047
+ }
9048
+ NewSceneObjectAddedEvent.type = "new-scene-object-added";
9022
9049
  class UrlSyncManager {
9023
- constructor() {
9050
+ constructor(_options = {}) {
9024
9051
  this._urlKeyMapper = new UniqueUrlKeyMapper();
9025
- this._stateSub = null;
9026
9052
  this._paramsCache = new UrlParamsCache();
9027
- __privateAdd(this, _onStateChanged, ({ payload }) => {
9028
- const changedObject = payload.changedObject;
9029
- if (changedObject.urlSync) {
9030
- const newUrlState = changedObject.urlSync.getUrlState();
9031
- const searchParams = runtime.locationService.getSearch();
9032
- const mappedUpdated = {};
9033
- for (const [key, newUrlValue] of Object.entries(newUrlState)) {
9034
- const uniqueKey = this._urlKeyMapper.getUniqueKey(key, changedObject);
9035
- const currentUrlValue = searchParams.getAll(uniqueKey);
9036
- if (!isUrlValueEqual(currentUrlValue, newUrlValue)) {
9037
- mappedUpdated[uniqueKey] = newUrlValue;
9038
- }
9039
- }
9040
- if (Object.keys(mappedUpdated).length > 0) {
9041
- writeSceneLog("UrlSyncManager", "onStateChange updating URL");
9042
- runtime.locationService.partial(mappedUpdated, true);
9043
- this._lastLocation = runtime.locationService.getLocation();
9044
- }
9045
- }
9046
- });
9053
+ this._options = _options;
9047
9054
  }
9048
9055
  initSync(root) {
9049
9056
  var _a;
9050
- if (this._stateSub) {
9057
+ if (this._subs) {
9051
9058
  writeSceneLog("UrlSyncManager", "Unregister previous scene state subscription", (_a = this._sceneRoot) == null ? void 0 : _a.state.key);
9052
- this._stateSub.unsubscribe();
9059
+ this._subs.unsubscribe();
9053
9060
  }
9054
9061
  writeSceneLog("UrlSyncManager", "init", root.state.key);
9055
9062
  this._sceneRoot = root;
9056
- this._stateSub = root.subscribeToEvent(SceneObjectStateChangedEvent, __privateGet(this, _onStateChanged));
9063
+ this._subs = new rxjs.Subscription();
9064
+ this._subs.add(
9065
+ root.subscribeToEvent(SceneObjectStateChangedEvent, (evt) => {
9066
+ this.handleSceneObjectStateChanged(evt.payload.changedObject);
9067
+ })
9068
+ );
9069
+ this._subs.add(
9070
+ root.subscribeToEvent(NewSceneObjectAddedEvent, (evt) => {
9071
+ this.handleNewObject(evt.payload);
9072
+ })
9073
+ );
9057
9074
  this._urlKeyMapper.clear();
9058
9075
  this._lastLocation = runtime.locationService.getLocation();
9059
9076
  this.handleNewObject(this._sceneRoot);
9077
+ if (this._options.updateUrlOnInit) {
9078
+ const urlState = getUrlState(root);
9079
+ if (isUrlStateDifferent(urlState, this._paramsCache.getParams())) {
9080
+ runtime.locationService.partial(urlState, true);
9081
+ }
9082
+ }
9060
9083
  }
9061
9084
  cleanUp(root) {
9062
9085
  if (this._sceneRoot !== root) {
9063
9086
  return;
9064
9087
  }
9065
9088
  writeSceneLog("UrlSyncManager", "Clean up");
9066
- if (this._stateSub) {
9067
- this._stateSub.unsubscribe();
9068
- this._stateSub = null;
9089
+ if (this._subs) {
9090
+ this._subs.unsubscribe();
9091
+ this._subs = void 0;
9069
9092
  writeSceneLog(
9070
9093
  "UrlSyncManager",
9071
9094
  "Root deactived, unsub to state",
@@ -9090,11 +9113,33 @@ class UrlSyncManager {
9090
9113
  }
9091
9114
  syncStateFromUrl(sceneObj, this._paramsCache.getParams(), this._urlKeyMapper);
9092
9115
  }
9116
+ handleSceneObjectStateChanged(changedObject) {
9117
+ var _a, _b;
9118
+ if (!changedObject.urlSync) {
9119
+ return;
9120
+ }
9121
+ const newUrlState = changedObject.urlSync.getUrlState();
9122
+ const searchParams = runtime.locationService.getSearch();
9123
+ const mappedUpdated = {};
9124
+ for (const [key, newUrlValue] of Object.entries(newUrlState)) {
9125
+ const uniqueKey = this._urlKeyMapper.getUniqueKey(key, changedObject);
9126
+ const currentUrlValue = searchParams.getAll(uniqueKey);
9127
+ if (!isUrlValueEqual(currentUrlValue, newUrlValue)) {
9128
+ mappedUpdated[uniqueKey] = newUrlValue;
9129
+ }
9130
+ }
9131
+ if (Object.keys(mappedUpdated).length > 0) {
9132
+ const shouldCreateHistoryEntry = (_b = (_a = changedObject.urlSync).shouldCreateHistoryStep) == null ? void 0 : _b.call(_a, newUrlState);
9133
+ const shouldReplace = shouldCreateHistoryEntry !== true;
9134
+ writeSceneLog("UrlSyncManager", "onStateChange updating URL");
9135
+ runtime.locationService.partial(mappedUpdated, shouldReplace);
9136
+ this._lastLocation = runtime.locationService.getLocation();
9137
+ }
9138
+ }
9093
9139
  getUrlState(root) {
9094
9140
  return getUrlState(root);
9095
9141
  }
9096
9142
  }
9097
- _onStateChanged = new WeakMap();
9098
9143
  class UrlParamsCache {
9099
9144
  constructor() {
9100
9145
  __privateAdd(this, _cache, void 0);
@@ -9112,18 +9157,28 @@ class UrlParamsCache {
9112
9157
  }
9113
9158
  _cache = new WeakMap();
9114
9159
  _location = new WeakMap();
9115
- let urlSyncManager;
9116
- function getUrlSyncManager() {
9117
- if (!urlSyncManager) {
9118
- urlSyncManager = new UrlSyncManager();
9160
+ function isUrlStateDifferent(sceneUrlState, currentParams) {
9161
+ for (let key in sceneUrlState) {
9162
+ if (!isUrlValueEqual(currentParams.getAll(key), sceneUrlState[key])) {
9163
+ return true;
9164
+ }
9119
9165
  }
9120
- return urlSyncManager;
9166
+ return false;
9167
+ }
9168
+ function useUrlSyncManager(options) {
9169
+ return React.useMemo(
9170
+ () => new UrlSyncManager({
9171
+ updateUrlOnInit: options.updateUrlOnInit,
9172
+ createBrowserHistorySteps: options.createBrowserHistorySteps
9173
+ }),
9174
+ [options.updateUrlOnInit, options.createBrowserHistorySteps]
9175
+ );
9121
9176
  }
9122
9177
 
9123
- function useUrlSync(sceneRoot) {
9124
- const urlSyncManager = getUrlSyncManager();
9178
+ function useUrlSync(sceneRoot, options = {}) {
9125
9179
  const location = reactRouterDom.useLocation();
9126
9180
  const [isInitialized, setIsInitialized] = React.useState(false);
9181
+ const urlSyncManager = useUrlSyncManager(options);
9127
9182
  React.useEffect(() => {
9128
9183
  urlSyncManager.initSync(sceneRoot);
9129
9184
  setIsInitialized(true);
@@ -9140,8 +9195,13 @@ function useUrlSync(sceneRoot) {
9140
9195
  return isInitialized;
9141
9196
  }
9142
9197
 
9143
- function UrlSyncContextProvider({ children, scene }) {
9144
- const isInitialized = useUrlSync(scene);
9198
+ function UrlSyncContextProvider({
9199
+ children,
9200
+ scene,
9201
+ updateUrlOnInit,
9202
+ createBrowserHistorySteps
9203
+ }) {
9204
+ const isInitialized = useUrlSync(scene, { updateUrlOnInit, createBrowserHistorySteps });
9145
9205
  if (!isInitialized) {
9146
9206
  return null;
9147
9207
  }
@@ -11432,13 +11492,16 @@ class SceneApp extends SceneObjectBase {
11432
11492
  }
11433
11493
  SceneApp.Component = ({ model }) => {
11434
11494
  const { pages } = model.useState();
11435
- return /* @__PURE__ */ React__default["default"].createElement(reactRouterDom.Switch, null, pages.map((page) => /* @__PURE__ */ React__default["default"].createElement(reactRouterDom.Route, {
11495
+ return /* @__PURE__ */ React__default["default"].createElement(SceneAppContext.Provider, {
11496
+ value: model
11497
+ }, /* @__PURE__ */ React__default["default"].createElement(reactRouterDom.Switch, null, pages.map((page) => /* @__PURE__ */ React__default["default"].createElement(reactRouterDom.Route, {
11436
11498
  key: page.state.url,
11437
11499
  exact: false,
11438
11500
  path: page.state.url,
11439
11501
  render: (props) => renderSceneComponentWithRouteProps(page, props)
11440
- })));
11502
+ }))));
11441
11503
  };
11504
+ const SceneAppContext = React.createContext(null);
11442
11505
  const sceneAppCache = /* @__PURE__ */ new Map();
11443
11506
  function useSceneApp(factory) {
11444
11507
  const cachedApp = sceneAppCache.get(factory);
@@ -11693,6 +11756,7 @@ function SceneAppPageView({ page, routeProps }) {
11693
11756
  const containerState = containerPage.useState();
11694
11757
  const params = useAppQueryParams();
11695
11758
  const scene = page.getScene(routeProps.match);
11759
+ const appContext = React.useContext(SceneAppContext);
11696
11760
  const isInitialized = containerState.initializedScene === scene;
11697
11761
  const { layout } = page.state;
11698
11762
  React.useLayoutEffect(() => {
@@ -11703,7 +11767,7 @@ function SceneAppPageView({ page, routeProps }) {
11703
11767
  React.useEffect(() => {
11704
11768
  return () => containerPage.setState({ initializedScene: void 0 });
11705
11769
  }, [containerPage]);
11706
- const urlSyncInitialized = useUrlSync(containerPage);
11770
+ const urlSyncInitialized = useUrlSync(containerPage, appContext == null ? void 0 : appContext.state.urlSyncOptions);
11707
11771
  if (!isInitialized && !urlSyncInitialized) {
11708
11772
  return null;
11709
11773
  }
@@ -12732,6 +12796,7 @@ exports.IntervalVariable = IntervalVariable;
12732
12796
  exports.LocalValueVariable = LocalValueVariable;
12733
12797
  exports.MultiValueVariable = MultiValueVariable;
12734
12798
  exports.NestedScene = NestedScene;
12799
+ exports.NewSceneObjectAddedEvent = NewSceneObjectAddedEvent;
12735
12800
  exports.PanelBuilders = PanelBuilders;
12736
12801
  exports.PanelOptionsBuilders = PanelOptionsBuilders;
12737
12802
  exports.QueryVariable = QueryVariable;
@@ -12791,7 +12856,6 @@ exports.VizPanelMenu = VizPanelMenu;
12791
12856
  exports.behaviors = index$1;
12792
12857
  exports.dataLayers = index;
12793
12858
  exports.formatRegistry = formatRegistry;
12794
- exports.getUrlSyncManager = getUrlSyncManager;
12795
12859
  exports.isCustomVariableValue = isCustomVariableValue;
12796
12860
  exports.isDataLayer = isDataLayer;
12797
12861
  exports.isDataRequestEnricher = isDataRequestEnricher;