@grafana/scenes 6.11.0--canary.1121.15019988505.0 → 6.11.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (42) hide show
  1. package/CHANGELOG.md +19 -0
  2. package/dist/esm/components/SceneApp/SceneApp.js +2 -2
  3. package/dist/esm/components/SceneApp/SceneApp.js.map +1 -1
  4. package/dist/esm/components/SceneApp/SceneAppPage.js +18 -2
  5. package/dist/esm/components/SceneApp/SceneAppPage.js.map +1 -1
  6. package/dist/esm/components/VizPanel/VizPanel.js +3 -0
  7. package/dist/esm/components/VizPanel/VizPanel.js.map +1 -1
  8. package/dist/esm/core/SceneObjectBase.js +1 -1
  9. package/dist/esm/core/SceneObjectBase.js.map +1 -1
  10. package/dist/esm/core/SceneScopesBridge.js +93 -0
  11. package/dist/esm/core/SceneScopesBridge.js.map +1 -0
  12. package/dist/esm/core/sceneGraph/cloneSceneObject.js +45 -0
  13. package/dist/esm/core/sceneGraph/cloneSceneObject.js.map +1 -0
  14. package/dist/esm/core/sceneGraph/index.js +2 -2
  15. package/dist/esm/core/sceneGraph/index.js.map +1 -1
  16. package/dist/esm/core/sceneGraph/sceneGraph.js +5 -9
  17. package/dist/esm/core/sceneGraph/sceneGraph.js.map +1 -1
  18. package/dist/esm/core/sceneGraph/utils.js +1 -43
  19. package/dist/esm/core/sceneGraph/utils.js.map +1 -1
  20. package/dist/esm/index.js +2 -2
  21. package/dist/esm/index.js.map +1 -1
  22. package/dist/esm/querying/SceneQueryRunner.js +33 -10
  23. package/dist/esm/querying/SceneQueryRunner.js.map +1 -1
  24. package/dist/esm/variables/VariableDependencyConfig.js +1 -4
  25. package/dist/esm/variables/VariableDependencyConfig.js.map +1 -1
  26. package/dist/esm/variables/adhoc/AdHocFiltersVariable.js +18 -19
  27. package/dist/esm/variables/adhoc/AdHocFiltersVariable.js.map +1 -1
  28. package/dist/esm/variables/components/VariableValueSelectors.js +0 -3
  29. package/dist/esm/variables/components/VariableValueSelectors.js.map +1 -1
  30. package/dist/esm/variables/constants.js +1 -2
  31. package/dist/esm/variables/constants.js.map +1 -1
  32. package/dist/esm/variables/groupby/GroupByVariable.js +2 -2
  33. package/dist/esm/variables/groupby/GroupByVariable.js.map +1 -1
  34. package/dist/esm/variables/sets/SceneVariableSet.js +7 -10
  35. package/dist/esm/variables/sets/SceneVariableSet.js.map +1 -1
  36. package/dist/esm/variables/types.js.map +1 -1
  37. package/dist/index.d.ts +52 -54
  38. package/dist/index.js +162 -119
  39. package/dist/index.js.map +1 -1
  40. package/package.json +2 -2
  41. package/dist/esm/variables/variants/ScopesVariable.js +0 -80
  42. package/dist/esm/variables/variants/ScopesVariable.js.map +0 -1
package/dist/index.js CHANGED
@@ -513,15 +513,6 @@ function cloneSceneObjectState(sceneState, withState) {
513
513
  }
514
514
  return clonedState;
515
515
  }
516
- function getClosest(sceneObject, extract) {
517
- let curSceneObject = sceneObject;
518
- let extracted = void 0;
519
- while (curSceneObject && !extracted) {
520
- extracted = extract(curSceneObject);
521
- curSceneObject = curSceneObject.parent;
522
- }
523
- return extracted;
524
- }
525
516
 
526
517
  class RuntimeDataSource extends data.DataSourceApi {
527
518
  constructor(pluginId, uid) {
@@ -897,6 +888,16 @@ class SceneObjectUrlSyncConfig {
897
888
  }
898
889
  }
899
890
 
891
+ function getClosest(sceneObject, extract) {
892
+ let curSceneObject = sceneObject;
893
+ let extracted = void 0;
894
+ while (curSceneObject && !extracted) {
895
+ extracted = extract(curSceneObject);
896
+ curSceneObject = curSceneObject.parent;
897
+ }
898
+ return extracted;
899
+ }
900
+
900
901
  const INTERVAL_STRING_REGEX = /^\d+[yYmMsSwWhHdD]$/;
901
902
  function parseUrlParam(value) {
902
903
  if (typeof value !== "string") {
@@ -1282,7 +1283,6 @@ const AUTO_VARIABLE_TEXT = "Auto";
1282
1283
  const AUTO_VARIABLE_VALUE = "$__auto";
1283
1284
  const VARIABLE_REGEX = /\$(\w+)|\[\[(\w+?)(?::(\w+))?\]\]|\${(\w+)(?:\.([^:^\}]+))?(?::([^\}]+))?}/g;
1284
1285
  const SEARCH_FILTER_VARIABLE = "__searchFilter";
1285
- const SCOPES_VARIABLE_NAME = "__scopes";
1286
1286
 
1287
1287
  const formatRegistry = new data.Registry(() => {
1288
1288
  const formats = [
@@ -3098,7 +3098,7 @@ class GroupByVariable extends MultiValueVariable {
3098
3098
  * Get possible keys given current filters. Do not call from plugins directly
3099
3099
  */
3100
3100
  this._getKeys = async (ds) => {
3101
- var _a, _b, _c;
3101
+ var _a, _b, _c, _d;
3102
3102
  const override = await ((_b = (_a = this.state).getTagKeysProvider) == null ? void 0 : _b.call(_a, this, null));
3103
3103
  if (override && override.replace) {
3104
3104
  return override.values;
@@ -3116,7 +3116,7 @@ class GroupByVariable extends MultiValueVariable {
3116
3116
  filters: otherFilters,
3117
3117
  queries,
3118
3118
  timeRange,
3119
- scopes: sceneGraph.getScopes(this),
3119
+ scopes: (_d = this._scopesBridge) == null ? void 0 : _d.getValue(),
3120
3120
  ...getEnrichedFiltersRequest(this)
3121
3121
  });
3122
3122
  if (responseHasError(response)) {
@@ -5350,21 +5350,25 @@ class AdHocFiltersVariable extends SceneObjectBase {
5350
5350
  // are set on construct and used to restore a baseFilter with an origin
5351
5351
  // to its original value if edited at some point
5352
5352
  this._originalValues = /* @__PURE__ */ new Map();
5353
- /** Needed for scopes dependency */
5354
- this._variableDependency = new VariableDependencyConfig(this, {
5355
- dependsOnScopes: true,
5356
- onReferencedVariableValueChanged: () => this._updateScopesFilters()
5357
- });
5358
5353
  this._urlSync = new AdHocFiltersVariableUrlSyncHandler(this);
5359
5354
  this._activationHandler = () => {
5360
- this._updateScopesFilters();
5355
+ var _a, _b;
5356
+ this._scopesBridge = sceneGraph.getScopesBridge(this);
5357
+ const scopes = (_a = this._scopesBridge) == null ? void 0 : _a.getValue();
5358
+ if (scopes) {
5359
+ this._updateScopesFilters(scopes);
5360
+ }
5361
+ const sub = (_b = this._scopesBridge) == null ? void 0 : _b.subscribeToValue((n, _) => {
5362
+ this._updateScopesFilters(n);
5363
+ });
5361
5364
  return () => {
5362
- var _a, _b;
5363
- if ((_a = this.state.baseFilters) == null ? void 0 : _a.length) {
5365
+ var _a2, _b2;
5366
+ sub == null ? void 0 : sub.unsubscribe();
5367
+ if ((_a2 = this.state.baseFilters) == null ? void 0 : _a2.length) {
5364
5368
  this.setState({
5365
5369
  baseFilters: [...this.state.baseFilters.filter((filter) => filter.origin !== "scope")]
5366
5370
  });
5367
- (_b = this.state.baseFilters) == null ? void 0 : _b.forEach((filter) => {
5371
+ (_b2 = this.state.baseFilters) == null ? void 0 : _b2.forEach((filter) => {
5368
5372
  if (filter.origin === "dashboard" && filter.restorable) {
5369
5373
  this.restoreOriginalFilter(filter);
5370
5374
  }
@@ -5386,12 +5390,8 @@ class AdHocFiltersVariable extends SceneObjectBase {
5386
5390
  });
5387
5391
  this.addActivationHandler(this._activationHandler);
5388
5392
  }
5389
- _updateScopesFilters() {
5393
+ _updateScopesFilters(scopes) {
5390
5394
  var _a, _b;
5391
- const scopes = sceneGraph.getScopes(this);
5392
- if (!scopes) {
5393
- return;
5394
- }
5395
5395
  if (!scopes.length) {
5396
5396
  this.setState({
5397
5397
  baseFilters: (_a = this.state.baseFilters) == null ? void 0 : _a.filter((filter) => filter.origin !== "scope")
@@ -5592,7 +5592,7 @@ class AdHocFiltersVariable extends SceneObjectBase {
5592
5592
  * Get possible keys given current filters. Do not call from plugins directly
5593
5593
  */
5594
5594
  async _getKeys(currentKey) {
5595
- var _a, _b, _c;
5595
+ var _a, _b, _c, _d;
5596
5596
  const override = await ((_b = (_a = this.state).getTagKeysProvider) == null ? void 0 : _b.call(_a, this, currentKey));
5597
5597
  if (override && override.replace) {
5598
5598
  return dataFromResponse(override.values).map(toSelectableValue);
@@ -5611,7 +5611,7 @@ class AdHocFiltersVariable extends SceneObjectBase {
5611
5611
  filters: otherFilters,
5612
5612
  queries,
5613
5613
  timeRange,
5614
- scopes: sceneGraph.getScopes(this),
5614
+ scopes: (_d = this._scopesBridge) == null ? void 0 : _d.getValue(),
5615
5615
  ...getEnrichedFiltersRequest(this)
5616
5616
  });
5617
5617
  if (responseHasError(response)) {
@@ -5631,7 +5631,7 @@ class AdHocFiltersVariable extends SceneObjectBase {
5631
5631
  * Get possible key values for a specific key given current filters. Do not call from plugins directly
5632
5632
  */
5633
5633
  async _getValuesFor(filter) {
5634
- var _a, _b, _c, _d;
5634
+ var _a, _b, _c, _d, _e;
5635
5635
  const override = await ((_b = (_a = this.state).getTagValuesProvider) == null ? void 0 : _b.call(_a, this, filter));
5636
5636
  if (override && override.replace) {
5637
5637
  return dataFromResponse(override.values).map(toSelectableValue);
@@ -5644,7 +5644,7 @@ class AdHocFiltersVariable extends SceneObjectBase {
5644
5644
  const otherFilters = this.state.filters.filter((f) => f.key !== filter.key).concat(filteredBaseFilters);
5645
5645
  const timeRange = sceneGraph.getTimeRange(this).state.value;
5646
5646
  const queries = this.state.useQueriesAsFilterForOptions ? getQueriesForVariables(this) : void 0;
5647
- let scopes = sceneGraph.getScopes(this);
5647
+ let scopes = (_e = this._scopesBridge) == null ? void 0 : _e.getValue();
5648
5648
  if (filter.origin === "scope") {
5649
5649
  scopes = scopes == null ? void 0 : scopes.map((scope) => {
5650
5650
  return {
@@ -5802,8 +5802,7 @@ class SceneQueryRunner extends SceneObjectBase {
5802
5802
  this._variableDependency = new VariableDependencyConfig(this, {
5803
5803
  statePaths: ["queries", "datasource", "minInterval"],
5804
5804
  onVariableUpdateCompleted: this.onVariableUpdatesCompleted.bind(this),
5805
- onAnyVariableChanged: this.onAnyVariableChanged.bind(this),
5806
- dependsOnScopes: true
5805
+ onAnyVariableChanged: this.onAnyVariableChanged.bind(this)
5807
5806
  });
5808
5807
  this.onDataReceived = (data$1) => {
5809
5808
  const preProcessedData = data.preProcessPanelData(data$1, this.state.data);
@@ -5824,6 +5823,7 @@ class SceneQueryRunner extends SceneObjectBase {
5824
5823
  _onActivate() {
5825
5824
  if (this.isQueryModeAuto()) {
5826
5825
  const timeRange = sceneGraph.getTimeRange(this);
5826
+ const scopesBridge = sceneGraph.getScopesBridge(this);
5827
5827
  const providers = this.getClosestExtraQueryProviders();
5828
5828
  for (const provider of providers) {
5829
5829
  this._subs.add(
@@ -5834,6 +5834,7 @@ class SceneQueryRunner extends SceneObjectBase {
5834
5834
  })
5835
5835
  );
5836
5836
  }
5837
+ this.subscribeToScopesChanges(scopesBridge);
5837
5838
  this.subscribeToTimeRangeChanges(timeRange);
5838
5839
  if (this.shouldRunQueriesOnActivate()) {
5839
5840
  this.runQueries();
@@ -5997,6 +5998,21 @@ class SceneQueryRunner extends SceneObjectBase {
5997
5998
  isDataReadyToDisplay() {
5998
5999
  return Boolean(this.state._hasFetchedData);
5999
6000
  }
6001
+ subscribeToScopesChanges(scopesBridge) {
6002
+ if (!scopesBridge) {
6003
+ return;
6004
+ }
6005
+ if (this._scopesSubBridge === scopesBridge) {
6006
+ return;
6007
+ }
6008
+ if (this._scopesSub) {
6009
+ this._scopesSub.unsubscribe();
6010
+ }
6011
+ this._scopesSubBridge = scopesBridge;
6012
+ this._scopesSub = scopesBridge.subscribeToValue(() => {
6013
+ this.runWithTimeRangeAndScopes(sceneGraph.getTimeRange(this), scopesBridge);
6014
+ });
6015
+ }
6000
6016
  subscribeToTimeRangeChanges(timeRange) {
6001
6017
  if (this._timeSubRange === timeRange) {
6002
6018
  return;
@@ -6006,15 +6022,17 @@ class SceneQueryRunner extends SceneObjectBase {
6006
6022
  }
6007
6023
  this._timeSubRange = timeRange;
6008
6024
  this._timeSub = timeRange.subscribeToState(() => {
6009
- this.runWithTimeRange(timeRange);
6025
+ this.runWithTimeRangeAndScopes(timeRange, sceneGraph.getScopesBridge(this));
6010
6026
  });
6011
6027
  }
6012
6028
  runQueries() {
6013
6029
  const timeRange = sceneGraph.getTimeRange(this);
6030
+ const scopesBridge = sceneGraph.getScopesBridge(this);
6014
6031
  if (this.isQueryModeAuto()) {
6015
6032
  this.subscribeToTimeRangeChanges(timeRange);
6033
+ this.subscribeToScopesChanges(scopesBridge);
6016
6034
  }
6017
- this.runWithTimeRange(timeRange);
6035
+ this.runWithTimeRangeAndScopes(timeRange, scopesBridge);
6018
6036
  }
6019
6037
  getMaxDataPoints() {
6020
6038
  var _a;
@@ -6034,8 +6052,8 @@ class SceneQueryRunner extends SceneObjectBase {
6034
6052
  data: { ...this.state.data, state: schema.LoadingState.Done }
6035
6053
  });
6036
6054
  }
6037
- async runWithTimeRange(timeRange) {
6038
- var _a, _b, _c;
6055
+ async runWithTimeRangeAndScopes(timeRange, scopesBridge) {
6056
+ var _a, _b, _c, _d;
6039
6057
  if (!this.state.maxDataPoints && this.state.maxDataPointsFromWidth && !this._containerWidth) {
6040
6058
  return;
6041
6059
  }
@@ -6048,17 +6066,22 @@ class SceneQueryRunner extends SceneObjectBase {
6048
6066
  this.setState({ data: { ...(_b = this.state.data) != null ? _b : emptyPanelData, state: schema.LoadingState.Loading } });
6049
6067
  return;
6050
6068
  }
6069
+ if ((scopesBridge == null ? void 0 : scopesBridge.isLoading()) && (scopesBridge == null ? void 0 : scopesBridge.getValue().length)) {
6070
+ writeSceneLog("SceneQueryRunner", "Scopes are in loading state, skipping query execution");
6071
+ this.setState({ data: { ...(_c = this.state.data) != null ? _c : emptyPanelData, state: schema.LoadingState.Loading } });
6072
+ return;
6073
+ }
6051
6074
  const { queries } = this.state;
6052
6075
  if (!(queries == null ? void 0 : queries.length)) {
6053
6076
  this._setNoDataState();
6054
6077
  return;
6055
6078
  }
6056
6079
  try {
6057
- const datasource = (_c = this.state.datasource) != null ? _c : findFirstDatasource(queries);
6080
+ const datasource = (_d = this.state.datasource) != null ? _d : findFirstDatasource(queries);
6058
6081
  const ds = await getDataSource(datasource, this._scopedVars);
6059
6082
  this.findAndSubscribeToAdHocFilters(ds.uid);
6060
6083
  const runRequest = runtime.getRunRequest();
6061
- const { primary, secondaries, processors } = this.prepareRequests(timeRange, ds);
6084
+ const { primary, secondaries, processors } = this.prepareRequests(timeRange, ds, scopesBridge);
6062
6085
  writeSceneLog("SceneQueryRunner", "Starting runRequest", this.state.key);
6063
6086
  let stream = runRequest(ds, primary);
6064
6087
  if (secondaries.length > 0) {
@@ -6099,7 +6122,7 @@ class SceneQueryRunner extends SceneObjectBase {
6099
6122
  clone["_results"].next({ origin: this, data: (_a = this.state.data) != null ? _a : emptyPanelData });
6100
6123
  return clone;
6101
6124
  }
6102
- prepareRequests(timeRange, ds) {
6125
+ prepareRequests(timeRange, ds, scopesBridge) {
6103
6126
  var _a, _b;
6104
6127
  const { minInterval, queries } = this.state;
6105
6128
  let request = {
@@ -6120,7 +6143,7 @@ class SceneQueryRunner extends SceneObjectBase {
6120
6143
  },
6121
6144
  cacheTimeout: this.state.cacheTimeout,
6122
6145
  queryCachingTTL: this.state.queryCachingTTL,
6123
- scopes: sceneGraph.getScopes(this),
6146
+ scopes: scopesBridge == null ? void 0 : scopesBridge.getValue(),
6124
6147
  // This asks the scene root to provide context properties like app, panel and dashboardUID
6125
6148
  ...getEnrichedDataRequest(this)
6126
6149
  };
@@ -6543,9 +6566,6 @@ class VariableDependencyConfig {
6543
6566
  this._dependencies.add(name);
6544
6567
  }
6545
6568
  }
6546
- if (this._options.dependsOnScopes) {
6547
- this._dependencies.add(SCOPES_VARIABLE_NAME);
6548
- }
6549
6569
  if (this._statePaths) {
6550
6570
  for (const path of this._statePaths) {
6551
6571
  if (path === "*") {
@@ -7074,73 +7094,87 @@ function containsSearchFilter(query) {
7074
7094
  return str.indexOf(SEARCH_FILTER_VARIABLE) > -1;
7075
7095
  }
7076
7096
 
7077
- class ScopesVariable extends SceneObjectBase {
7078
- constructor(state) {
7079
- super({
7080
- skipUrlSync: true,
7081
- loading: true,
7082
- scopes: [],
7083
- ...state,
7084
- type: "system",
7085
- name: SCOPES_VARIABLE_NAME,
7086
- hide: schema.VariableHide.hideVariable
7087
- });
7097
+ class SceneScopesBridge extends SceneObjectBase {
7098
+ constructor() {
7099
+ super(...arguments);
7088
7100
  this._renderBeforeActivation = true;
7101
+ this._contextSubject = new rxjs.BehaviorSubject(void 0);
7102
+ }
7103
+ getValue() {
7104
+ var _a, _b;
7105
+ return (_b = (_a = this.context) == null ? void 0 : _a.state.value) != null ? _b : [];
7089
7106
  }
7090
7107
  /**
7091
- * Temporary simple implementation to stringify the scopes.
7108
+ * Emits values of the selected scopes array. It emits the current value and the previous value if there is a change.
7109
+ * @param cb
7092
7110
  */
7093
- getValue(fieldPath) {
7111
+ subscribeToValue(cb) {
7112
+ return this.contextObservable.pipe(
7113
+ rxjs.map((context) => {
7114
+ var _a;
7115
+ return (_a = context == null ? void 0 : context.state.value) != null ? _a : [];
7116
+ }),
7117
+ rxjs.pairwise(),
7118
+ rxjs.filter(([prevScopes, newScopes]) => !lodash.isEqual(prevScopes, newScopes))
7119
+ ).subscribe(([prevScopes, newScopes]) => {
7120
+ cb(newScopes, prevScopes);
7121
+ });
7122
+ }
7123
+ isLoading() {
7124
+ var _a, _b;
7125
+ return (_b = (_a = this.context) == null ? void 0 : _a.state.loading) != null ? _b : false;
7126
+ }
7127
+ subscribeToLoading(cb) {
7128
+ return this.contextObservable.pipe(
7129
+ rxjs.filter((context) => !!context),
7130
+ rxjs.pairwise(),
7131
+ rxjs.map(
7132
+ ([prevContext, newContext]) => {
7133
+ var _a, _b;
7134
+ return [(_a = prevContext == null ? void 0 : prevContext.state.loading) != null ? _a : false, (_b = newContext == null ? void 0 : newContext.state.loading) != null ? _b : false];
7135
+ }
7136
+ ),
7137
+ rxjs.filter(([prevLoading, newLoading]) => prevLoading !== newLoading)
7138
+ ).subscribe(([_prevLoading, newLoading]) => {
7139
+ cb(newLoading);
7140
+ });
7141
+ }
7142
+ setEnabled(enabled) {
7094
7143
  var _a;
7095
- const scopes = (_a = this.state.scopes) != null ? _a : [];
7096
- const scopeNames = scopes.map((scope) => scope.metadata.name);
7097
- return scopeNames.join(", ");
7144
+ (_a = this.context) == null ? void 0 : _a.setEnabled(enabled);
7098
7145
  }
7099
- getScopes() {
7100
- return this.state.scopes;
7146
+ setReadOnly(readOnly) {
7147
+ var _a;
7148
+ (_a = this.context) == null ? void 0 : _a.setReadOnly(readOnly);
7101
7149
  }
7102
7150
  /**
7103
7151
  * This method is used to keep the context up to date with the scopes context received from React
7104
- * 1) Subscribes to ScopesContext state changes and synchronizes it with the variable state
7105
- * 2) Handles enable / disabling of scopes based on variable enable option.
7152
+ *
7153
+ * Its rationale is:
7154
+ * - When a new context is available, check if we have pending scopes passed from the URL
7155
+ * - If we have pending scopes, ask the new context to load them
7156
+ * - The loading should happen in a setTimeout to allow the existing context to pass its values to the URL sync handler
7157
+ * - If a new context is received, propagate it as a new value in the behavior subject
7158
+ * - If a new value is received, force a re-render to trigger the URL sync handler
7106
7159
  */
7107
- setContext(context) {
7108
- if (!context) {
7109
- return;
7110
- }
7111
- this._context = context;
7112
- const oldState = context.state;
7113
- if (this.state.enable != null) {
7114
- context.setEnabled(this.state.enable);
7160
+ updateContext(newContext) {
7161
+ var _a;
7162
+ if (this.context !== newContext || ((_a = this.context) == null ? void 0 : _a.state) !== (newContext == null ? void 0 : newContext.state)) {
7163
+ this._contextSubject.next(newContext);
7115
7164
  }
7116
- const sub = context.stateObservable.subscribe((state) => {
7117
- this.updateStateFromContext(state);
7118
- });
7119
- return () => {
7120
- sub.unsubscribe();
7121
- if (this.state.enable != null) {
7122
- context.setEnabled(oldState.enabled);
7123
- }
7124
- };
7125
7165
  }
7126
- updateStateFromContext(state) {
7127
- const loading = state.value.length === 0 ? false : state.loading;
7128
- this.setState({ scopes: state.value, loading });
7129
- if (!loading) {
7130
- this.publishEvent(new SceneVariableValueChangedEvent(this), true);
7131
- }
7166
+ get context() {
7167
+ return this._contextSubject.getValue();
7132
7168
  }
7133
- /**
7134
- * Special function that enables variables to be hidden but still render to access react contexts
7135
- */
7136
- hiddenRender() {
7137
- return /* @__PURE__ */ React__default.default.createElement(ScopesVariableRenderer, { model: this });
7169
+ get contextObservable() {
7170
+ return this._contextSubject.asObservable();
7138
7171
  }
7139
7172
  }
7140
- function ScopesVariableRenderer({ model }) {
7141
- const context = React.useContext(runtime.ScopesContext);
7173
+ SceneScopesBridge.Component = SceneScopesBridgeRenderer;
7174
+ function SceneScopesBridgeRenderer({ model }) {
7175
+ const context = runtime.useScopes();
7142
7176
  React.useEffect(() => {
7143
- return model.setContext(context);
7177
+ model.updateContext(context);
7144
7178
  }, [context, model]);
7145
7179
  return null;
7146
7180
  }
@@ -7288,12 +7322,9 @@ function findDescendents(scene, descendentType) {
7288
7322
  const targetScenes = findAllObjects(scene, isDescendentType);
7289
7323
  return targetScenes.filter(isDescendentType);
7290
7324
  }
7291
- function getScopes(sceneObject) {
7292
- const scopesVariable = lookupVariable(SCOPES_VARIABLE_NAME, sceneObject);
7293
- if (scopesVariable instanceof ScopesVariable) {
7294
- return scopesVariable.state.scopes;
7295
- }
7296
- return void 0;
7325
+ function getScopesBridge(sceneObject) {
7326
+ var _a;
7327
+ return (_a = findObject(sceneObject, (s) => s instanceof SceneScopesBridge)) != null ? _a : void 0;
7297
7328
  }
7298
7329
 
7299
7330
  const sceneGraph = {
@@ -7312,7 +7343,7 @@ const sceneGraph = {
7312
7343
  getAncestor,
7313
7344
  getQueryController,
7314
7345
  findDescendents,
7315
- getScopes
7346
+ getScopesBridge
7316
7347
  };
7317
7348
 
7318
7349
  class UniqueUrlKeyMapper {
@@ -8350,6 +8381,9 @@ class VizPanel extends SceneObjectBase {
8350
8381
  this._prevData = rawData;
8351
8382
  return this._dataWithFieldConfig;
8352
8383
  }
8384
+ clone() {
8385
+ return super.clone({ _pluginInstanceState: void 0, _pluginLoadError: void 0 });
8386
+ }
8353
8387
  buildPanelContext() {
8354
8388
  const sync = getCursorSyncScope(this);
8355
8389
  const context = {
@@ -9403,9 +9437,6 @@ function VariableValueSelectorsRenderer({ model }) {
9403
9437
  function VariableValueSelectWrapper({ variable, layout, showAlways, hideLabel }) {
9404
9438
  const state = useSceneObjectState(variable, { shouldActivateOrKeepAlive: true });
9405
9439
  if (state.hide === data.VariableHide.hideVariable && !showAlways) {
9406
- if (variable.hiddenRender) {
9407
- return variable.hiddenRender();
9408
- }
9409
9440
  return null;
9410
9441
  }
9411
9442
  if (layout === "vertical") {
@@ -9469,6 +9500,8 @@ function VariableValueControlRenderer({ model }) {
9469
9500
  class SceneVariableSet extends SceneObjectBase {
9470
9501
  constructor(state) {
9471
9502
  super(state);
9503
+ /** Variables that have changed in since the activation or since the first manual value change */
9504
+ this._variablesThatHaveChanged = /* @__PURE__ */ new Set();
9472
9505
  /** Variables that are scheduled to be validated and updated */
9473
9506
  this._variablesToUpdate = /* @__PURE__ */ new Set();
9474
9507
  /** Variables currently updating */
@@ -9595,8 +9628,7 @@ class SceneVariableSet extends SceneObjectBase {
9595
9628
  _updateNextBatch() {
9596
9629
  for (const variable of this._variablesToUpdate) {
9597
9630
  if (!variable.validateAndUpdate) {
9598
- console.error("Variable added to variablesToUpdate but does not have validateAndUpdate");
9599
- continue;
9631
+ throw new Error("Variable added to variablesToUpdate but does not have validateAndUpdate");
9600
9632
  }
9601
9633
  if (this._updating.has(variable)) {
9602
9634
  continue;
@@ -9652,6 +9684,7 @@ class SceneVariableSet extends SceneObjectBase {
9652
9684
  this._updateNextBatch();
9653
9685
  }
9654
9686
  _handleVariableValueChanged(variableThatChanged) {
9687
+ this._variablesThatHaveChanged.add(variableThatChanged);
9655
9688
  this._addDependentVariablesToUpdateQueue(variableThatChanged);
9656
9689
  if (!this._updating.has(variableThatChanged)) {
9657
9690
  this._updateNextBatch();
@@ -9678,10 +9711,7 @@ class SceneVariableSet extends SceneObjectBase {
9678
9711
  if (this._updating.has(otherVariable) && otherVariable.onCancel) {
9679
9712
  otherVariable.onCancel();
9680
9713
  }
9681
- if (otherVariable.validateAndUpdate) {
9682
- this._variablesToUpdate.add(otherVariable);
9683
- }
9684
- otherVariable.variableDependency.variableUpdateCompleted(variableThatChanged, true);
9714
+ this._variablesToUpdate.add(otherVariable);
9685
9715
  }
9686
9716
  }
9687
9717
  }
@@ -9693,7 +9723,8 @@ class SceneVariableSet extends SceneObjectBase {
9693
9723
  if (!this.parent) {
9694
9724
  return;
9695
9725
  }
9696
- this._traverseSceneAndNotify(this.parent, variable, true);
9726
+ this._traverseSceneAndNotify(this.parent, variable, this._variablesThatHaveChanged.has(variable));
9727
+ this._variablesThatHaveChanged.delete(variable);
9697
9728
  }
9698
9729
  /**
9699
9730
  * Recursivly walk the full scene object graph and notify all objects with dependencies that include any of changed variables
@@ -9725,9 +9756,6 @@ class SceneVariableSet extends SceneObjectBase {
9725
9756
  * For example if C depends on variable B which depends on variable A and A is loading this returns true for variable C and B.
9726
9757
  */
9727
9758
  isVariableLoadingOrWaitingToUpdate(variable) {
9728
- if (variable.state.loading) {
9729
- return true;
9730
- }
9731
9759
  if (variable.isAncestorLoading && variable.isAncestorLoading()) {
9732
9760
  return true;
9733
9761
  }
@@ -12616,8 +12644,8 @@ class SceneApp extends SceneObjectBase {
12616
12644
  }
12617
12645
  }
12618
12646
  SceneApp.Component = ({ model }) => {
12619
- const { pages } = model.useState();
12620
- return /* @__PURE__ */ React__default.default.createElement(React__default.default.Fragment, null, /* @__PURE__ */ React__default.default.createElement(SceneAppContext.Provider, { value: model }, /* @__PURE__ */ React__default.default.createElement(reactRouterDom.Routes, null, pages.map((page) => /* @__PURE__ */ React__default.default.createElement(reactRouterDom.Route, { key: page.state.url, path: page.state.routePath, element: /* @__PURE__ */ React__default.default.createElement(page.Component, { model: page }) })))));
12647
+ const { pages, scopesBridge } = model.useState();
12648
+ return /* @__PURE__ */ React__default.default.createElement(React__default.default.Fragment, null, scopesBridge && /* @__PURE__ */ React__default.default.createElement(scopesBridge.Component, { model: scopesBridge }), /* @__PURE__ */ React__default.default.createElement(SceneAppContext.Provider, { value: model }, /* @__PURE__ */ React__default.default.createElement(reactRouterDom.Routes, null, pages.map((page) => /* @__PURE__ */ React__default.default.createElement(reactRouterDom.Route, { key: page.state.url, path: page.state.routePath, element: /* @__PURE__ */ React__default.default.createElement(page.Component, { model: page }) })))));
12621
12649
  };
12622
12650
  const SceneAppContext = React.createContext(null);
12623
12651
  const sceneAppCache = /* @__PURE__ */ new Map();
@@ -12893,10 +12921,25 @@ function SceneAppDrilldownViewRender({ drilldown, parent }) {
12893
12921
  }
12894
12922
 
12895
12923
  class SceneAppPage extends SceneObjectBase {
12896
- constructor() {
12897
- super(...arguments);
12924
+ constructor(state) {
12925
+ super(state);
12898
12926
  this._sceneCache = /* @__PURE__ */ new Map();
12899
12927
  this._drilldownCache = /* @__PURE__ */ new Map();
12928
+ this._activationHandler = () => {
12929
+ if (!this.state.useScopes) {
12930
+ return;
12931
+ }
12932
+ this._scopesBridge = sceneGraph.getScopesBridge(this);
12933
+ if (!this._scopesBridge) {
12934
+ throw new Error("Use of scopes is enabled but no scopes bridge found");
12935
+ }
12936
+ this._scopesBridge.setEnabled(true);
12937
+ return () => {
12938
+ var _a;
12939
+ (_a = this._scopesBridge) == null ? void 0 : _a.setEnabled(false);
12940
+ };
12941
+ };
12942
+ this.addActivationHandler(this._activationHandler);
12900
12943
  }
12901
12944
  initializeScene(scene) {
12902
12945
  this.setState({ initializedScene: scene });
@@ -14004,6 +14047,7 @@ exports.SceneObjectUrlSyncConfig = SceneObjectUrlSyncConfig;
14004
14047
  exports.SceneQueryRunner = SceneQueryRunner;
14005
14048
  exports.SceneReactObject = SceneReactObject;
14006
14049
  exports.SceneRefreshPicker = SceneRefreshPicker;
14050
+ exports.SceneScopesBridge = SceneScopesBridge;
14007
14051
  exports.SceneTimePicker = SceneTimePicker;
14008
14052
  exports.SceneTimeRange = SceneTimeRange;
14009
14053
  exports.SceneTimeRangeCompare = SceneTimeRangeCompare;
@@ -14013,7 +14057,6 @@ exports.SceneToolbarButton = SceneToolbarButton;
14013
14057
  exports.SceneToolbarInput = SceneToolbarInput;
14014
14058
  exports.SceneVariableSet = SceneVariableSet;
14015
14059
  exports.SceneVariableValueChangedEvent = SceneVariableValueChangedEvent;
14016
- exports.ScopesVariable = ScopesVariable;
14017
14060
  exports.SplitLayout = SplitLayout;
14018
14061
  exports.TestVariable = TestVariable;
14019
14062
  exports.TextBoxVariable = TextBoxVariable;