@grafana/scenes 6.12.0--canary.1122.15063334499.0 → 6.12.0--canary.1121.15070832166.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 (37) hide show
  1. package/dist/esm/components/SceneApp/SceneApp.js +2 -2
  2. package/dist/esm/components/SceneApp/SceneApp.js.map +1 -1
  3. package/dist/esm/components/SceneApp/SceneAppPage.js +2 -18
  4. package/dist/esm/components/SceneApp/SceneAppPage.js.map +1 -1
  5. package/dist/esm/core/sceneGraph/index.js +2 -2
  6. package/dist/esm/core/sceneGraph/index.js.map +1 -1
  7. package/dist/esm/core/sceneGraph/sceneGraph.js +9 -5
  8. package/dist/esm/core/sceneGraph/sceneGraph.js.map +1 -1
  9. package/dist/esm/index.js +1 -1
  10. package/dist/esm/index.js.map +1 -1
  11. package/dist/esm/querying/SceneQueryRunner.js +10 -33
  12. package/dist/esm/querying/SceneQueryRunner.js.map +1 -1
  13. package/dist/esm/variables/VariableDependencyConfig.js +4 -1
  14. package/dist/esm/variables/VariableDependencyConfig.js.map +1 -1
  15. package/dist/esm/variables/adhoc/AdHocFiltersVariable.js +19 -18
  16. package/dist/esm/variables/adhoc/AdHocFiltersVariable.js.map +1 -1
  17. package/dist/esm/variables/components/VariableValueSelectors.js +3 -0
  18. package/dist/esm/variables/components/VariableValueSelectors.js.map +1 -1
  19. package/dist/esm/variables/constants.js +2 -1
  20. package/dist/esm/variables/constants.js.map +1 -1
  21. package/dist/esm/variables/groupby/GroupByVariable.js +7 -40
  22. package/dist/esm/variables/groupby/GroupByVariable.js.map +1 -1
  23. package/dist/esm/variables/groupby/GroupByVariableUrlSyncHandler.js +7 -31
  24. package/dist/esm/variables/groupby/GroupByVariableUrlSyncHandler.js.map +1 -1
  25. package/dist/esm/variables/sets/SceneVariableSet.js +10 -7
  26. package/dist/esm/variables/sets/SceneVariableSet.js.map +1 -1
  27. package/dist/esm/variables/types.js.map +1 -1
  28. package/dist/esm/variables/variants/ScopesVariable.js +87 -0
  29. package/dist/esm/variables/variants/ScopesVariable.js.map +1 -0
  30. package/dist/index.d.ts +51 -56
  31. package/dist/index.js +128 -310
  32. package/dist/index.js.map +1 -1
  33. package/package.json +2 -2
  34. package/dist/esm/core/SceneScopesBridge.js +0 -93
  35. package/dist/esm/core/SceneScopesBridge.js.map +0 -1
  36. package/dist/esm/variables/groupby/DefaultGroupByCustomIndicatorContainer.js +0 -102
  37. package/dist/esm/variables/groupby/DefaultGroupByCustomIndicatorContainer.js.map +0 -1
package/dist/index.js CHANGED
@@ -1283,6 +1283,7 @@ const AUTO_VARIABLE_TEXT = "Auto";
1283
1283
  const AUTO_VARIABLE_VALUE = "$__auto";
1284
1284
  const VARIABLE_REGEX = /\$(\w+)|\[\[(\w+?)(?::(\w+))?\]\]|\${(\w+)(?:\.([^:^\}]+))?(?::([^\}]+))?}/g;
1285
1285
  const SEARCH_FILTER_VARIABLE = "__searchFilter";
1286
+ const SCOPES_VARIABLE_NAME = "__scopes";
1286
1287
 
1287
1288
  const formatRegistry = new data.Registry(() => {
1288
1289
  const formats = [
@@ -2964,34 +2965,18 @@ class GroupByVariableUrlSyncHandler {
2964
2965
  return [this.getKey()];
2965
2966
  }
2966
2967
  getUrlState() {
2967
- var _a;
2968
2968
  if (this._sceneObject.state.skipUrlSync) {
2969
2969
  return {};
2970
2970
  }
2971
- return {
2972
- [this.getKey()]: toUrlValues(
2973
- this._sceneObject.state.value,
2974
- this._sceneObject.state.text,
2975
- (_a = this._sceneObject.state.defaultValues) == null ? void 0 : _a.value
2976
- )
2977
- };
2971
+ return { [this.getKey()]: toUrlValues(this._sceneObject.state.value, this._sceneObject.state.text) };
2978
2972
  }
2979
2973
  updateFromUrl(values) {
2980
- var _a, _b;
2981
2974
  let urlValue = values[this.getKey()];
2982
2975
  if (urlValue != null) {
2983
2976
  if (!this._sceneObject.isActive) {
2984
2977
  this._sceneObject.skipNextValidation = true;
2985
2978
  }
2986
- const { values: values2, texts, defaults } = fromUrlValues(urlValue);
2987
- if (lodash.isEqual(values2, defaults) && this._sceneObject.state.defaultValues) {
2988
- this._sceneObject.changeValueTo(
2989
- (_a = this._sceneObject.state.defaultValues) == null ? void 0 : _a.value,
2990
- (_b = this._sceneObject.state.defaultValues) == null ? void 0 : _b.text,
2991
- false
2992
- );
2993
- return;
2994
- }
2979
+ const { values: values2, texts } = fromUrlValues(urlValue);
2995
2980
  this._sceneObject.changeValueTo(values2, texts);
2996
2981
  }
2997
2982
  }
@@ -3004,10 +2989,9 @@ class GroupByVariableUrlSyncHandler {
3004
2989
  return this._nextChangeShouldAddHistoryStep;
3005
2990
  }
3006
2991
  }
3007
- function toUrlValues(values, texts, defaultValues) {
2992
+ function toUrlValues(values, texts) {
3008
2993
  values = Array.isArray(values) ? values : [values];
3009
2994
  texts = Array.isArray(texts) ? texts : [texts];
3010
- const defaults = defaultValues ? Array.isArray(defaultValues) ? defaultValues : [defaultValues] : [];
3011
2995
  return values.map((value, idx) => {
3012
2996
  if (value === void 0 || value === null) {
3013
2997
  return "";
@@ -3015,27 +2999,21 @@ function toUrlValues(values, texts, defaultValues) {
3015
2999
  value = String(value);
3016
3000
  let text = texts[idx];
3017
3001
  text = text === void 0 || text === null ? value : String(text);
3018
- return toUrlCommaDelimitedString(value, text) + (defaults.includes(value) ? escapeUrlPipeDelimiters("|default") : "");
3002
+ return toUrlCommaDelimitedString(value, text);
3019
3003
  });
3020
3004
  }
3021
3005
  function fromUrlValues(urlValues) {
3022
3006
  urlValues = Array.isArray(urlValues) ? urlValues : [urlValues];
3023
3007
  return urlValues.reduce(
3024
3008
  (acc, urlValue) => {
3025
- const pipeEscapedVal = /__gfp__/g[Symbol.replace](urlValue, "|");
3026
- const [commaValues, isDefault] = (pipeEscapedVal != null ? pipeEscapedVal : "").split("|");
3027
- const [value, label] = (commaValues != null ? commaValues : "").split(",");
3009
+ const [value, label] = (urlValue != null ? urlValue : "").split(",");
3028
3010
  acc.values.push(unescapeUrlDelimiters(value));
3029
3011
  acc.texts.push(unescapeUrlDelimiters(label != null ? label : value));
3030
- if (isDefault) {
3031
- acc.defaults.push(value);
3032
- }
3033
3012
  return acc;
3034
3013
  },
3035
3014
  {
3036
3015
  values: [],
3037
- texts: [],
3038
- defaults: []
3016
+ texts: []
3039
3017
  }
3040
3018
  );
3041
3019
  }
@@ -3099,101 +3077,6 @@ function wrapInSafeSerializableSceneObject(sceneObject) {
3099
3077
  return { value: sceneObject, text: "__sceneObject" };
3100
3078
  }
3101
3079
 
3102
- function DefaultGroupByCustomIndicatorContainer(props) {
3103
- const { model } = props;
3104
- const theme = ui.useTheme2();
3105
- const styles = getStyles$h(theme);
3106
- const inputStyles = ui.getInputStyles({ theme, invalid: false });
3107
- const value = React.useMemo(
3108
- () => lodash.isArray(model.state.value) ? model.state.value : model.state.value ? [model.state.value] : [],
3109
- [model.state.value]
3110
- );
3111
- const isRestorable = React.useMemo(() => {
3112
- return model.checkIfRestorable(value);
3113
- }, [value, model]);
3114
- let buttons = [];
3115
- if (value && value.length) {
3116
- buttons.push(
3117
- /* @__PURE__ */ React__default.default.createElement(
3118
- ui.IconButton,
3119
- {
3120
- "aria-label": "clear",
3121
- key: "clear",
3122
- name: "times",
3123
- size: "md",
3124
- className: styles.clearIcon,
3125
- onClick: (e) => {
3126
- model.changeValueTo([], void 0, true);
3127
- }
3128
- }
3129
- )
3130
- );
3131
- }
3132
- if (isRestorable) {
3133
- buttons.push(
3134
- /* @__PURE__ */ React__default.default.createElement(
3135
- ui.IconButton,
3136
- {
3137
- onClick: (e) => {
3138
- props.model.restoreDefaultValues();
3139
- },
3140
- onKeyDownCapture: (e) => {
3141
- if (e.key === "Enter") {
3142
- props.model.restoreDefaultValues();
3143
- }
3144
- },
3145
- key: "restore",
3146
- name: "history",
3147
- size: "md",
3148
- className: styles.clearIcon,
3149
- tooltip: "Restore groupby set by this dashboard."
3150
- }
3151
- )
3152
- );
3153
- }
3154
- if (!isRestorable) {
3155
- buttons.push(
3156
- /* @__PURE__ */ React__default.default.createElement(
3157
- ui.Tooltip,
3158
- {
3159
- key: "tooltip",
3160
- content: "Applied by default in this dashboard. If edited, it carries over to other dashboards.",
3161
- placement: "bottom"
3162
- },
3163
- /* @__PURE__ */ React__default.default.createElement(ui.Icon, { name: "info-circle", size: "md" })
3164
- )
3165
- );
3166
- }
3167
- return /* @__PURE__ */ React__default.default.createElement(
3168
- "div",
3169
- {
3170
- onMouseDown: (e) => {
3171
- e.preventDefault();
3172
- e.stopPropagation();
3173
- },
3174
- className: css.cx(
3175
- inputStyles.suffix,
3176
- css.css({
3177
- position: "relative"
3178
- })
3179
- )
3180
- },
3181
- buttons
3182
- );
3183
- }
3184
- const getStyles$h = (theme) => ({
3185
- clearIcon: css.css({
3186
- color: theme.colors.action.disabledText,
3187
- cursor: "pointer",
3188
- "&:hover:before": {
3189
- backgroundColor: "transparent"
3190
- },
3191
- "&:hover": {
3192
- color: theme.colors.text.primary
3193
- }
3194
- })
3195
- });
3196
-
3197
3080
  class GroupByVariable extends MultiValueVariable {
3198
3081
  constructor(initialState) {
3199
3082
  super({
@@ -3212,20 +3095,11 @@ class GroupByVariable extends MultiValueVariable {
3212
3095
  });
3213
3096
  this.isLazy = true;
3214
3097
  this._urlSync = new GroupByVariableUrlSyncHandler(this);
3215
- this._activationHandler = () => {
3216
- if (this.state.defaultValues && (lodash.isArray(this.state.value) && !this.state.value.length || !this.state.value)) {
3217
- this.setState({
3218
- value: this.state.defaultValues.value,
3219
- text: this.state.defaultValues.text
3220
- });
3221
- return;
3222
- }
3223
- };
3224
3098
  /**
3225
3099
  * Get possible keys given current filters. Do not call from plugins directly
3226
3100
  */
3227
3101
  this._getKeys = async (ds) => {
3228
- var _a, _b, _c, _d;
3102
+ var _a, _b, _c;
3229
3103
  const override = await ((_b = (_a = this.state).getTagKeysProvider) == null ? void 0 : _b.call(_a, this, null));
3230
3104
  if (override && override.replace) {
3231
3105
  return override.values;
@@ -3243,7 +3117,7 @@ class GroupByVariable extends MultiValueVariable {
3243
3117
  filters: otherFilters,
3244
3118
  queries,
3245
3119
  timeRange,
3246
- scopes: (_d = this._scopesBridge) == null ? void 0 : _d.getValue(),
3120
+ scopes: sceneGraph.getScopes(this),
3247
3121
  ...getEnrichedFiltersRequest(this)
3248
3122
  });
3249
3123
  if (responseHasError(response)) {
@@ -3265,7 +3139,6 @@ class GroupByVariable extends MultiValueVariable {
3265
3139
  return () => allActiveGroupByVariables.delete(this);
3266
3140
  });
3267
3141
  }
3268
- this.addActivationHandler(this._activationHandler);
3269
3142
  }
3270
3143
  validateAndUpdate() {
3271
3144
  return this.getValueOptions({}).pipe(
@@ -3324,21 +3197,6 @@ class GroupByVariable extends MultiValueVariable {
3324
3197
  })
3325
3198
  );
3326
3199
  }
3327
- checkIfRestorable(values) {
3328
- var _a, _b, _c, _d;
3329
- const originalValues = lodash.isArray((_a = this.state.defaultValues) == null ? void 0 : _a.value) ? (_b = this.state.defaultValues) == null ? void 0 : _b.value : ((_c = this.state.defaultValues) == null ? void 0 : _c.value) ? [(_d = this.state.defaultValues) == null ? void 0 : _d.value] : [];
3330
- const vals = lodash.isArray(values) ? values : [values];
3331
- if (vals.length !== originalValues.length) {
3332
- return true;
3333
- }
3334
- return !lodash.isEqual(vals, originalValues);
3335
- }
3336
- restoreDefaultValues() {
3337
- if (!this.state.defaultValues) {
3338
- return;
3339
- }
3340
- this.changeValueTo(this.state.defaultValues.value, this.state.defaultValues.text, true);
3341
- }
3342
3200
  /**
3343
3201
  * Allows clearing the value of the variable to an empty value. Overrides default behavior of a MultiValueVariable
3344
3202
  */
@@ -3357,8 +3215,7 @@ function GroupByVariableRenderer({ model }) {
3357
3215
  noValueOnClear,
3358
3216
  options,
3359
3217
  includeAll,
3360
- allowCustomValue = true,
3361
- defaultValues
3218
+ allowCustomValue = true
3362
3219
  } = model.useState();
3363
3220
  const values = React.useMemo(() => {
3364
3221
  const arrayValue = lodash.isArray(value) ? value : [value];
@@ -3376,7 +3233,6 @@ function GroupByVariableRenderer({ model }) {
3376
3233
  const [inputValue, setInputValue] = React.useState("");
3377
3234
  const [uncommittedValue, setUncommittedValue] = React.useState(values);
3378
3235
  const optionSearcher = React.useMemo(() => getOptionSearcher(options, includeAll), [options, includeAll]);
3379
- const hasDefaultValues = defaultValues !== void 0;
3380
3236
  React.useEffect(() => {
3381
3237
  setUncommittedValue(values);
3382
3238
  }, [values]);
@@ -3404,7 +3260,7 @@ function GroupByVariableRenderer({ model }) {
3404
3260
  "aria-label": "Group by selector",
3405
3261
  "data-testid": `GroupBySelect-${key}`,
3406
3262
  id: key,
3407
- placeholder: "Group by label",
3263
+ placeholder: "Select value",
3408
3264
  width: "auto",
3409
3265
  allowCustomValue,
3410
3266
  inputValue,
@@ -3420,12 +3276,7 @@ function GroupByVariableRenderer({ model }) {
3420
3276
  isClearable: true,
3421
3277
  hideSelectedOptions: false,
3422
3278
  isLoading: isFetchingOptions,
3423
- components: {
3424
- Option: OptionWithCheckbox,
3425
- ...hasDefaultValues ? {
3426
- IndicatorsContainer: () => /* @__PURE__ */ React__default.default.createElement(DefaultGroupByCustomIndicatorContainer, { model })
3427
- } : {}
3428
- },
3279
+ components: { Option: OptionWithCheckbox },
3429
3280
  onInputChange,
3430
3281
  onBlur: () => {
3431
3282
  model.changeValueTo(
@@ -3456,7 +3307,7 @@ function GroupByVariableRenderer({ model }) {
3456
3307
  "aria-label": "Group by selector",
3457
3308
  "data-testid": `GroupBySelect-${key}`,
3458
3309
  id: key,
3459
- placeholder: "Group by label",
3310
+ placeholder: "Select value",
3460
3311
  width: "auto",
3461
3312
  inputValue,
3462
3313
  value: uncommittedValue && uncommittedValue.length > 0 ? uncommittedValue : null,
@@ -5500,25 +5351,21 @@ class AdHocFiltersVariable extends SceneObjectBase {
5500
5351
  // are set on construct and used to restore a baseFilter with an origin
5501
5352
  // to its original value if edited at some point
5502
5353
  this._originalValues = /* @__PURE__ */ new Map();
5354
+ /** Needed for scopes dependency */
5355
+ this._variableDependency = new VariableDependencyConfig(this, {
5356
+ dependsOnScopes: true,
5357
+ onReferencedVariableValueChanged: () => this._updateScopesFilters()
5358
+ });
5503
5359
  this._urlSync = new AdHocFiltersVariableUrlSyncHandler(this);
5504
5360
  this._activationHandler = () => {
5505
- var _a, _b;
5506
- this._scopesBridge = sceneGraph.getScopesBridge(this);
5507
- const scopes = (_a = this._scopesBridge) == null ? void 0 : _a.getValue();
5508
- if (scopes) {
5509
- this._updateScopesFilters(scopes);
5510
- }
5511
- const sub = (_b = this._scopesBridge) == null ? void 0 : _b.subscribeToValue((n, _) => {
5512
- this._updateScopesFilters(n);
5513
- });
5361
+ this._updateScopesFilters();
5514
5362
  return () => {
5515
- var _a2, _b2;
5516
- sub == null ? void 0 : sub.unsubscribe();
5517
- if ((_a2 = this.state.baseFilters) == null ? void 0 : _a2.length) {
5363
+ var _a, _b;
5364
+ if ((_a = this.state.baseFilters) == null ? void 0 : _a.length) {
5518
5365
  this.setState({
5519
5366
  baseFilters: [...this.state.baseFilters.filter((filter) => filter.origin !== "scope")]
5520
5367
  });
5521
- (_b2 = this.state.baseFilters) == null ? void 0 : _b2.forEach((filter) => {
5368
+ (_b = this.state.baseFilters) == null ? void 0 : _b.forEach((filter) => {
5522
5369
  if (filter.origin === "dashboard" && filter.restorable) {
5523
5370
  this.restoreOriginalFilter(filter);
5524
5371
  }
@@ -5540,8 +5387,12 @@ class AdHocFiltersVariable extends SceneObjectBase {
5540
5387
  });
5541
5388
  this.addActivationHandler(this._activationHandler);
5542
5389
  }
5543
- _updateScopesFilters(scopes) {
5390
+ _updateScopesFilters() {
5544
5391
  var _a, _b;
5392
+ const scopes = sceneGraph.getScopes(this);
5393
+ if (!scopes) {
5394
+ return;
5395
+ }
5545
5396
  if (!scopes.length) {
5546
5397
  this.setState({
5547
5398
  baseFilters: (_a = this.state.baseFilters) == null ? void 0 : _a.filter((filter) => filter.origin !== "scope")
@@ -5742,7 +5593,7 @@ class AdHocFiltersVariable extends SceneObjectBase {
5742
5593
  * Get possible keys given current filters. Do not call from plugins directly
5743
5594
  */
5744
5595
  async _getKeys(currentKey) {
5745
- var _a, _b, _c, _d;
5596
+ var _a, _b, _c;
5746
5597
  const override = await ((_b = (_a = this.state).getTagKeysProvider) == null ? void 0 : _b.call(_a, this, currentKey));
5747
5598
  if (override && override.replace) {
5748
5599
  return dataFromResponse(override.values).map(toSelectableValue);
@@ -5761,7 +5612,7 @@ class AdHocFiltersVariable extends SceneObjectBase {
5761
5612
  filters: otherFilters,
5762
5613
  queries,
5763
5614
  timeRange,
5764
- scopes: (_d = this._scopesBridge) == null ? void 0 : _d.getValue(),
5615
+ scopes: sceneGraph.getScopes(this),
5765
5616
  ...getEnrichedFiltersRequest(this)
5766
5617
  });
5767
5618
  if (responseHasError(response)) {
@@ -5781,7 +5632,7 @@ class AdHocFiltersVariable extends SceneObjectBase {
5781
5632
  * Get possible key values for a specific key given current filters. Do not call from plugins directly
5782
5633
  */
5783
5634
  async _getValuesFor(filter) {
5784
- var _a, _b, _c, _d, _e;
5635
+ var _a, _b, _c, _d;
5785
5636
  const override = await ((_b = (_a = this.state).getTagValuesProvider) == null ? void 0 : _b.call(_a, this, filter));
5786
5637
  if (override && override.replace) {
5787
5638
  return dataFromResponse(override.values).map(toSelectableValue);
@@ -5794,7 +5645,7 @@ class AdHocFiltersVariable extends SceneObjectBase {
5794
5645
  const otherFilters = this.state.filters.filter((f) => f.key !== filter.key).concat(filteredBaseFilters);
5795
5646
  const timeRange = sceneGraph.getTimeRange(this).state.value;
5796
5647
  const queries = this.state.useQueriesAsFilterForOptions ? getQueriesForVariables(this) : void 0;
5797
- let scopes = (_e = this._scopesBridge) == null ? void 0 : _e.getValue();
5648
+ let scopes = sceneGraph.getScopes(this);
5798
5649
  if (filter.origin === "scope") {
5799
5650
  scopes = scopes == null ? void 0 : scopes.map((scope) => {
5800
5651
  return {
@@ -5952,7 +5803,8 @@ class SceneQueryRunner extends SceneObjectBase {
5952
5803
  this._variableDependency = new VariableDependencyConfig(this, {
5953
5804
  statePaths: ["queries", "datasource", "minInterval"],
5954
5805
  onVariableUpdateCompleted: this.onVariableUpdatesCompleted.bind(this),
5955
- onAnyVariableChanged: this.onAnyVariableChanged.bind(this)
5806
+ onAnyVariableChanged: this.onAnyVariableChanged.bind(this),
5807
+ dependsOnScopes: true
5956
5808
  });
5957
5809
  this.onDataReceived = (data$1) => {
5958
5810
  const preProcessedData = data.preProcessPanelData(data$1, this.state.data);
@@ -5973,7 +5825,6 @@ class SceneQueryRunner extends SceneObjectBase {
5973
5825
  _onActivate() {
5974
5826
  if (this.isQueryModeAuto()) {
5975
5827
  const timeRange = sceneGraph.getTimeRange(this);
5976
- const scopesBridge = sceneGraph.getScopesBridge(this);
5977
5828
  const providers = this.getClosestExtraQueryProviders();
5978
5829
  for (const provider of providers) {
5979
5830
  this._subs.add(
@@ -5984,7 +5835,6 @@ class SceneQueryRunner extends SceneObjectBase {
5984
5835
  })
5985
5836
  );
5986
5837
  }
5987
- this.subscribeToScopesChanges(scopesBridge);
5988
5838
  this.subscribeToTimeRangeChanges(timeRange);
5989
5839
  if (this.shouldRunQueriesOnActivate()) {
5990
5840
  this.runQueries();
@@ -6148,21 +5998,6 @@ class SceneQueryRunner extends SceneObjectBase {
6148
5998
  isDataReadyToDisplay() {
6149
5999
  return Boolean(this.state._hasFetchedData);
6150
6000
  }
6151
- subscribeToScopesChanges(scopesBridge) {
6152
- if (!scopesBridge) {
6153
- return;
6154
- }
6155
- if (this._scopesSubBridge === scopesBridge) {
6156
- return;
6157
- }
6158
- if (this._scopesSub) {
6159
- this._scopesSub.unsubscribe();
6160
- }
6161
- this._scopesSubBridge = scopesBridge;
6162
- this._scopesSub = scopesBridge.subscribeToValue(() => {
6163
- this.runWithTimeRangeAndScopes(sceneGraph.getTimeRange(this), scopesBridge);
6164
- });
6165
- }
6166
6001
  subscribeToTimeRangeChanges(timeRange) {
6167
6002
  if (this._timeSubRange === timeRange) {
6168
6003
  return;
@@ -6172,17 +6007,15 @@ class SceneQueryRunner extends SceneObjectBase {
6172
6007
  }
6173
6008
  this._timeSubRange = timeRange;
6174
6009
  this._timeSub = timeRange.subscribeToState(() => {
6175
- this.runWithTimeRangeAndScopes(timeRange, sceneGraph.getScopesBridge(this));
6010
+ this.runWithTimeRange(timeRange);
6176
6011
  });
6177
6012
  }
6178
6013
  runQueries() {
6179
6014
  const timeRange = sceneGraph.getTimeRange(this);
6180
- const scopesBridge = sceneGraph.getScopesBridge(this);
6181
6015
  if (this.isQueryModeAuto()) {
6182
6016
  this.subscribeToTimeRangeChanges(timeRange);
6183
- this.subscribeToScopesChanges(scopesBridge);
6184
6017
  }
6185
- this.runWithTimeRangeAndScopes(timeRange, scopesBridge);
6018
+ this.runWithTimeRange(timeRange);
6186
6019
  }
6187
6020
  getMaxDataPoints() {
6188
6021
  var _a;
@@ -6202,8 +6035,8 @@ class SceneQueryRunner extends SceneObjectBase {
6202
6035
  data: { ...this.state.data, state: schema.LoadingState.Done }
6203
6036
  });
6204
6037
  }
6205
- async runWithTimeRangeAndScopes(timeRange, scopesBridge) {
6206
- var _a, _b, _c, _d;
6038
+ async runWithTimeRange(timeRange) {
6039
+ var _a, _b, _c;
6207
6040
  if (!this.state.maxDataPoints && this.state.maxDataPointsFromWidth && !this._containerWidth) {
6208
6041
  return;
6209
6042
  }
@@ -6216,22 +6049,17 @@ class SceneQueryRunner extends SceneObjectBase {
6216
6049
  this.setState({ data: { ...(_b = this.state.data) != null ? _b : emptyPanelData, state: schema.LoadingState.Loading } });
6217
6050
  return;
6218
6051
  }
6219
- if ((scopesBridge == null ? void 0 : scopesBridge.isLoading()) && (scopesBridge == null ? void 0 : scopesBridge.getValue().length)) {
6220
- writeSceneLog("SceneQueryRunner", "Scopes are in loading state, skipping query execution");
6221
- this.setState({ data: { ...(_c = this.state.data) != null ? _c : emptyPanelData, state: schema.LoadingState.Loading } });
6222
- return;
6223
- }
6224
6052
  const { queries } = this.state;
6225
6053
  if (!(queries == null ? void 0 : queries.length)) {
6226
6054
  this._setNoDataState();
6227
6055
  return;
6228
6056
  }
6229
6057
  try {
6230
- const datasource = (_d = this.state.datasource) != null ? _d : findFirstDatasource(queries);
6058
+ const datasource = (_c = this.state.datasource) != null ? _c : findFirstDatasource(queries);
6231
6059
  const ds = await getDataSource(datasource, this._scopedVars);
6232
6060
  this.findAndSubscribeToAdHocFilters(ds.uid);
6233
6061
  const runRequest = runtime.getRunRequest();
6234
- const { primary, secondaries, processors } = this.prepareRequests(timeRange, ds, scopesBridge);
6062
+ const { primary, secondaries, processors } = this.prepareRequests(timeRange, ds);
6235
6063
  writeSceneLog("SceneQueryRunner", "Starting runRequest", this.state.key);
6236
6064
  let stream = runRequest(ds, primary);
6237
6065
  if (secondaries.length > 0) {
@@ -6272,7 +6100,7 @@ class SceneQueryRunner extends SceneObjectBase {
6272
6100
  clone["_results"].next({ origin: this, data: (_a = this.state.data) != null ? _a : emptyPanelData });
6273
6101
  return clone;
6274
6102
  }
6275
- prepareRequests(timeRange, ds, scopesBridge) {
6103
+ prepareRequests(timeRange, ds) {
6276
6104
  var _a, _b;
6277
6105
  const { minInterval, queries } = this.state;
6278
6106
  let request = {
@@ -6293,7 +6121,7 @@ class SceneQueryRunner extends SceneObjectBase {
6293
6121
  },
6294
6122
  cacheTimeout: this.state.cacheTimeout,
6295
6123
  queryCachingTTL: this.state.queryCachingTTL,
6296
- scopes: scopesBridge == null ? void 0 : scopesBridge.getValue(),
6124
+ scopes: sceneGraph.getScopes(this),
6297
6125
  // This asks the scene root to provide context properties like app, panel and dashboardUID
6298
6126
  ...getEnrichedDataRequest(this)
6299
6127
  };
@@ -6716,6 +6544,9 @@ class VariableDependencyConfig {
6716
6544
  this._dependencies.add(name);
6717
6545
  }
6718
6546
  }
6547
+ if (this._options.dependsOnScopes) {
6548
+ this._dependencies.add(SCOPES_VARIABLE_NAME);
6549
+ }
6719
6550
  if (this._statePaths) {
6720
6551
  for (const path of this._statePaths) {
6721
6552
  if (path === "*") {
@@ -7244,90 +7075,83 @@ function containsSearchFilter(query) {
7244
7075
  return str.indexOf(SEARCH_FILTER_VARIABLE) > -1;
7245
7076
  }
7246
7077
 
7247
- class SceneScopesBridge extends SceneObjectBase {
7248
- constructor() {
7249
- super(...arguments);
7078
+ class ScopesVariable extends SceneObjectBase {
7079
+ constructor(state) {
7080
+ super({
7081
+ skipUrlSync: true,
7082
+ loading: true,
7083
+ scopes: [],
7084
+ ...state,
7085
+ type: "system",
7086
+ name: SCOPES_VARIABLE_NAME,
7087
+ hide: schema.VariableHide.hideVariable
7088
+ });
7250
7089
  this._renderBeforeActivation = true;
7251
- this._contextSubject = new rxjs.BehaviorSubject(void 0);
7252
- }
7253
- getValue() {
7254
- var _a, _b;
7255
- return (_b = (_a = this.context) == null ? void 0 : _a.state.value) != null ? _b : [];
7090
+ // Special options that enables variables to be hidden but still render to access react contexts
7091
+ this.UNSAFE_renderAsHidden = true;
7256
7092
  }
7257
7093
  /**
7258
- * Emits values of the selected scopes array. It emits the current value and the previous value if there is a change.
7259
- * @param cb
7094
+ * Temporary simple implementation to stringify the scopes.
7260
7095
  */
7261
- subscribeToValue(cb) {
7262
- return this.contextObservable.pipe(
7263
- rxjs.map((context) => {
7264
- var _a;
7265
- return (_a = context == null ? void 0 : context.state.value) != null ? _a : [];
7266
- }),
7267
- rxjs.pairwise(),
7268
- rxjs.filter(([prevScopes, newScopes]) => !lodash.isEqual(prevScopes, newScopes))
7269
- ).subscribe(([prevScopes, newScopes]) => {
7270
- cb(newScopes, prevScopes);
7271
- });
7272
- }
7273
- isLoading() {
7274
- var _a, _b;
7275
- return (_b = (_a = this.context) == null ? void 0 : _a.state.loading) != null ? _b : false;
7276
- }
7277
- subscribeToLoading(cb) {
7278
- return this.contextObservable.pipe(
7279
- rxjs.filter((context) => !!context),
7280
- rxjs.pairwise(),
7281
- rxjs.map(
7282
- ([prevContext, newContext]) => {
7283
- var _a, _b;
7284
- return [(_a = prevContext == null ? void 0 : prevContext.state.loading) != null ? _a : false, (_b = newContext == null ? void 0 : newContext.state.loading) != null ? _b : false];
7285
- }
7286
- ),
7287
- rxjs.filter(([prevLoading, newLoading]) => prevLoading !== newLoading)
7288
- ).subscribe(([_prevLoading, newLoading]) => {
7289
- cb(newLoading);
7290
- });
7291
- }
7292
- setEnabled(enabled) {
7096
+ getValue() {
7293
7097
  var _a;
7294
- (_a = this.context) == null ? void 0 : _a.setEnabled(enabled);
7098
+ const scopes = (_a = this.state.scopes) != null ? _a : [];
7099
+ return new ScopesVariableFormatter(scopes.map((scope) => scope.metadata.name));
7295
7100
  }
7296
- setReadOnly(readOnly) {
7297
- var _a;
7298
- (_a = this.context) == null ? void 0 : _a.setReadOnly(readOnly);
7101
+ getScopes() {
7102
+ return this.state.scopes;
7299
7103
  }
7300
7104
  /**
7301
7105
  * This method is used to keep the context up to date with the scopes context received from React
7302
- *
7303
- * Its rationale is:
7304
- * - When a new context is available, check if we have pending scopes passed from the URL
7305
- * - If we have pending scopes, ask the new context to load them
7306
- * - The loading should happen in a setTimeout to allow the existing context to pass its values to the URL sync handler
7307
- * - If a new context is received, propagate it as a new value in the behavior subject
7308
- * - If a new value is received, force a re-render to trigger the URL sync handler
7106
+ * 1) Subscribes to ScopesContext state changes and synchronizes it with the variable state
7107
+ * 2) Handles enable / disabling of scopes based on variable enable option.
7309
7108
  */
7310
- updateContext(newContext) {
7311
- var _a;
7312
- if (this.context !== newContext || ((_a = this.context) == null ? void 0 : _a.state) !== (newContext == null ? void 0 : newContext.state)) {
7313
- this._contextSubject.next(newContext);
7109
+ setContext(context) {
7110
+ if (!context) {
7111
+ return;
7314
7112
  }
7113
+ this._context = context;
7114
+ const oldState = context.state;
7115
+ if (this.state.enable != null) {
7116
+ context.setEnabled(this.state.enable);
7117
+ }
7118
+ const sub = context.stateObservable.subscribe((state) => {
7119
+ this.updateStateFromContext(state);
7120
+ });
7121
+ return () => {
7122
+ sub.unsubscribe();
7123
+ if (this.state.enable != null) {
7124
+ context.setEnabled(oldState.enabled);
7125
+ }
7126
+ };
7315
7127
  }
7316
- get context() {
7317
- return this._contextSubject.getValue();
7318
- }
7319
- get contextObservable() {
7320
- return this._contextSubject.asObservable();
7128
+ updateStateFromContext(state) {
7129
+ const loading = state.value.length === 0 ? false : state.loading;
7130
+ this.setState({ scopes: state.value, loading });
7131
+ if (!loading) {
7132
+ this.publishEvent(new SceneVariableValueChangedEvent(this), true);
7133
+ }
7321
7134
  }
7322
7135
  }
7323
- SceneScopesBridge.Component = SceneScopesBridgeRenderer;
7324
- function SceneScopesBridgeRenderer({ model }) {
7325
- const context = runtime.useScopes();
7136
+ ScopesVariable.Component = ScopesVariableRenderer;
7137
+ function ScopesVariableRenderer({ model }) {
7138
+ const context = React.useContext(runtime.ScopesContext);
7326
7139
  React.useEffect(() => {
7327
- model.updateContext(context);
7140
+ return model.setContext(context);
7328
7141
  }, [context, model]);
7329
7142
  return null;
7330
7143
  }
7144
+ class ScopesVariableFormatter {
7145
+ constructor(_value) {
7146
+ this._value = _value;
7147
+ }
7148
+ formatter(formatNameOrFn) {
7149
+ if (formatNameOrFn === schema.VariableFormatID.QueryParam) {
7150
+ return this._value.map((scope) => `scope=${encodeURIComponent(scope)}`).join("&");
7151
+ }
7152
+ return this._value.join(", ");
7153
+ }
7154
+ }
7331
7155
 
7332
7156
  function getVariables(sceneObject) {
7333
7157
  var _a;
@@ -7472,9 +7296,12 @@ function findDescendents(scene, descendentType) {
7472
7296
  const targetScenes = findAllObjects(scene, isDescendentType);
7473
7297
  return targetScenes.filter(isDescendentType);
7474
7298
  }
7475
- function getScopesBridge(sceneObject) {
7476
- var _a;
7477
- return (_a = findObject(sceneObject, (s) => s instanceof SceneScopesBridge)) != null ? _a : void 0;
7299
+ function getScopes(sceneObject) {
7300
+ const scopesVariable = lookupVariable(SCOPES_VARIABLE_NAME, sceneObject);
7301
+ if (scopesVariable instanceof ScopesVariable) {
7302
+ return scopesVariable.state.scopes;
7303
+ }
7304
+ return void 0;
7478
7305
  }
7479
7306
 
7480
7307
  const sceneGraph = {
@@ -7493,7 +7320,7 @@ const sceneGraph = {
7493
7320
  getAncestor,
7494
7321
  getQueryController,
7495
7322
  findDescendents,
7496
- getScopesBridge
7323
+ getScopes
7497
7324
  };
7498
7325
 
7499
7326
  class UniqueUrlKeyMapper {
@@ -9587,6 +9414,9 @@ function VariableValueSelectorsRenderer({ model }) {
9587
9414
  function VariableValueSelectWrapper({ variable, layout, showAlways, hideLabel }) {
9588
9415
  const state = useSceneObjectState(variable, { shouldActivateOrKeepAlive: true });
9589
9416
  if (state.hide === data.VariableHide.hideVariable && !showAlways) {
9417
+ if (variable.UNSAFE_renderAsHidden) {
9418
+ return /* @__PURE__ */ React__default.default.createElement(variable.Component, { model: variable });
9419
+ }
9590
9420
  return null;
9591
9421
  }
9592
9422
  if (layout === "vertical") {
@@ -9650,8 +9480,6 @@ function VariableValueControlRenderer({ model }) {
9650
9480
  class SceneVariableSet extends SceneObjectBase {
9651
9481
  constructor(state) {
9652
9482
  super(state);
9653
- /** Variables that have changed in since the activation or since the first manual value change */
9654
- this._variablesThatHaveChanged = /* @__PURE__ */ new Set();
9655
9483
  /** Variables that are scheduled to be validated and updated */
9656
9484
  this._variablesToUpdate = /* @__PURE__ */ new Set();
9657
9485
  /** Variables currently updating */
@@ -9778,7 +9606,8 @@ class SceneVariableSet extends SceneObjectBase {
9778
9606
  _updateNextBatch() {
9779
9607
  for (const variable of this._variablesToUpdate) {
9780
9608
  if (!variable.validateAndUpdate) {
9781
- throw new Error("Variable added to variablesToUpdate but does not have validateAndUpdate");
9609
+ console.error("Variable added to variablesToUpdate but does not have validateAndUpdate");
9610
+ continue;
9782
9611
  }
9783
9612
  if (this._updating.has(variable)) {
9784
9613
  continue;
@@ -9834,7 +9663,6 @@ class SceneVariableSet extends SceneObjectBase {
9834
9663
  this._updateNextBatch();
9835
9664
  }
9836
9665
  _handleVariableValueChanged(variableThatChanged) {
9837
- this._variablesThatHaveChanged.add(variableThatChanged);
9838
9666
  this._addDependentVariablesToUpdateQueue(variableThatChanged);
9839
9667
  if (!this._updating.has(variableThatChanged)) {
9840
9668
  this._updateNextBatch();
@@ -9861,7 +9689,10 @@ class SceneVariableSet extends SceneObjectBase {
9861
9689
  if (this._updating.has(otherVariable) && otherVariable.onCancel) {
9862
9690
  otherVariable.onCancel();
9863
9691
  }
9864
- this._variablesToUpdate.add(otherVariable);
9692
+ if (otherVariable.validateAndUpdate) {
9693
+ this._variablesToUpdate.add(otherVariable);
9694
+ }
9695
+ otherVariable.variableDependency.variableUpdateCompleted(variableThatChanged, true);
9865
9696
  }
9866
9697
  }
9867
9698
  }
@@ -9873,8 +9704,7 @@ class SceneVariableSet extends SceneObjectBase {
9873
9704
  if (!this.parent) {
9874
9705
  return;
9875
9706
  }
9876
- this._traverseSceneAndNotify(this.parent, variable, this._variablesThatHaveChanged.has(variable));
9877
- this._variablesThatHaveChanged.delete(variable);
9707
+ this._traverseSceneAndNotify(this.parent, variable, true);
9878
9708
  }
9879
9709
  /**
9880
9710
  * Recursivly walk the full scene object graph and notify all objects with dependencies that include any of changed variables
@@ -9906,6 +9736,9 @@ class SceneVariableSet extends SceneObjectBase {
9906
9736
  * 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.
9907
9737
  */
9908
9738
  isVariableLoadingOrWaitingToUpdate(variable) {
9739
+ if (variable.state.loading) {
9740
+ return true;
9741
+ }
9909
9742
  if (variable.isAncestorLoading && variable.isAncestorLoading()) {
9910
9743
  return true;
9911
9744
  }
@@ -12794,8 +12627,8 @@ class SceneApp extends SceneObjectBase {
12794
12627
  }
12795
12628
  }
12796
12629
  SceneApp.Component = ({ model }) => {
12797
- const { pages, scopesBridge } = model.useState();
12798
- 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 }) })))));
12630
+ const { pages } = model.useState();
12631
+ 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 }) })))));
12799
12632
  };
12800
12633
  const SceneAppContext = React.createContext(null);
12801
12634
  const sceneAppCache = /* @__PURE__ */ new Map();
@@ -13071,25 +12904,10 @@ function SceneAppDrilldownViewRender({ drilldown, parent }) {
13071
12904
  }
13072
12905
 
13073
12906
  class SceneAppPage extends SceneObjectBase {
13074
- constructor(state) {
13075
- super(state);
12907
+ constructor() {
12908
+ super(...arguments);
13076
12909
  this._sceneCache = /* @__PURE__ */ new Map();
13077
12910
  this._drilldownCache = /* @__PURE__ */ new Map();
13078
- this._activationHandler = () => {
13079
- if (!this.state.useScopes) {
13080
- return;
13081
- }
13082
- this._scopesBridge = sceneGraph.getScopesBridge(this);
13083
- if (!this._scopesBridge) {
13084
- throw new Error("Use of scopes is enabled but no scopes bridge found");
13085
- }
13086
- this._scopesBridge.setEnabled(true);
13087
- return () => {
13088
- var _a;
13089
- (_a = this._scopesBridge) == null ? void 0 : _a.setEnabled(false);
13090
- };
13091
- };
13092
- this.addActivationHandler(this._activationHandler);
13093
12911
  }
13094
12912
  initializeScene(scene) {
13095
12913
  this.setState({ initializedScene: scene });
@@ -14197,7 +14015,6 @@ exports.SceneObjectUrlSyncConfig = SceneObjectUrlSyncConfig;
14197
14015
  exports.SceneQueryRunner = SceneQueryRunner;
14198
14016
  exports.SceneReactObject = SceneReactObject;
14199
14017
  exports.SceneRefreshPicker = SceneRefreshPicker;
14200
- exports.SceneScopesBridge = SceneScopesBridge;
14201
14018
  exports.SceneTimePicker = SceneTimePicker;
14202
14019
  exports.SceneTimeRange = SceneTimeRange;
14203
14020
  exports.SceneTimeRangeCompare = SceneTimeRangeCompare;
@@ -14207,6 +14024,7 @@ exports.SceneToolbarButton = SceneToolbarButton;
14207
14024
  exports.SceneToolbarInput = SceneToolbarInput;
14208
14025
  exports.SceneVariableSet = SceneVariableSet;
14209
14026
  exports.SceneVariableValueChangedEvent = SceneVariableValueChangedEvent;
14027
+ exports.ScopesVariable = ScopesVariable;
14210
14028
  exports.SplitLayout = SplitLayout;
14211
14029
  exports.TestVariable = TestVariable;
14212
14030
  exports.TextBoxVariable = TextBoxVariable;