@grafana/scenes 6.40.0--canary.1255.18001595104.0 → 6.40.0--canary.1272.18407272616.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 (31) hide show
  1. package/CHANGELOG.md +48 -0
  2. package/dist/esm/components/VizPanel/VizPanel.js +14 -15
  3. package/dist/esm/components/VizPanel/VizPanel.js.map +1 -1
  4. package/dist/esm/index.js +5 -1
  5. package/dist/esm/index.js.map +1 -1
  6. package/dist/esm/querying/layers/SceneDataLayerControls.js +13 -1
  7. package/dist/esm/querying/layers/SceneDataLayerControls.js.map +1 -1
  8. package/dist/esm/variables/adhoc/AdHocFiltersCombobox/AdHocFilterPill.js +10 -10
  9. package/dist/esm/variables/adhoc/AdHocFiltersCombobox/AdHocFilterPill.js.map +1 -1
  10. package/dist/esm/variables/adhoc/AdHocFiltersCombobox/AdHocFiltersAlwaysWipCombobox.js +6 -6
  11. package/dist/esm/variables/adhoc/AdHocFiltersCombobox/AdHocFiltersAlwaysWipCombobox.js.map +1 -1
  12. package/dist/esm/variables/adhoc/AdHocFiltersCombobox/AdHocFiltersCombobox.js +57 -55
  13. package/dist/esm/variables/adhoc/AdHocFiltersCombobox/AdHocFiltersCombobox.js.map +1 -1
  14. package/dist/esm/variables/adhoc/AdHocFiltersCombobox/AdHocFiltersComboboxRenderer.js +5 -5
  15. package/dist/esm/variables/adhoc/AdHocFiltersCombobox/AdHocFiltersComboboxRenderer.js.map +1 -1
  16. package/dist/esm/variables/adhoc/AdHocFiltersCombobox/utils.js +4 -4
  17. package/dist/esm/variables/adhoc/AdHocFiltersCombobox/utils.js.map +1 -1
  18. package/dist/esm/variables/adhoc/AdHocFiltersVariable.js +4 -2
  19. package/dist/esm/variables/adhoc/AdHocFiltersVariable.js.map +1 -1
  20. package/dist/esm/variables/adhoc/controller/VariableBackedAdHocFiltersController.js +65 -0
  21. package/dist/esm/variables/adhoc/controller/VariableBackedAdHocFiltersController.js.map +1 -0
  22. package/dist/esm/variables/variants/CustomVariable.js +9 -4
  23. package/dist/esm/variables/variants/CustomVariable.js.map +1 -1
  24. package/dist/esm/variables/variants/SwitchVariable.js +108 -0
  25. package/dist/esm/variables/variants/SwitchVariable.js.map +1 -0
  26. package/dist/esm/variables/variants/guards.js +4 -1
  27. package/dist/esm/variables/variants/guards.js.map +1 -1
  28. package/dist/index.d.ts +148 -4
  29. package/dist/index.js +308 -122
  30. package/dist/index.js.map +1 -1
  31. package/package.json +2 -2
package/dist/index.js CHANGED
@@ -3603,7 +3603,7 @@ function wrapInSafeSerializableSceneObject(sceneObject) {
3603
3603
  function DefaultGroupByCustomIndicatorContainer(props) {
3604
3604
  const { model } = props;
3605
3605
  const theme = ui.useTheme2();
3606
- const styles = getStyles$h(theme);
3606
+ const styles = getStyles$i(theme);
3607
3607
  const inputStyles = ui.getInputStyles({ theme, invalid: false });
3608
3608
  const value = lodash.isArray(model.state.value) ? model.state.value : model.state.value ? [model.state.value] : [];
3609
3609
  let buttons = [];
@@ -3685,7 +3685,7 @@ function DefaultGroupByCustomIndicatorContainer(props) {
3685
3685
  buttons
3686
3686
  );
3687
3687
  }
3688
- const getStyles$h = (theme) => ({
3688
+ const getStyles$i = (theme) => ({
3689
3689
  clearIcon: css.css({
3690
3690
  color: theme.colors.action.disabledText,
3691
3691
  cursor: "pointer",
@@ -4206,7 +4206,7 @@ function LoadingIndicator(props) {
4206
4206
  }
4207
4207
 
4208
4208
  function ControlsLabel(props) {
4209
- const styles = ui.useStyles2(getStyles$g);
4209
+ const styles = ui.useStyles2(getStyles$h);
4210
4210
  const theme = ui.useTheme2();
4211
4211
  const isVertical = props.layout === "vertical";
4212
4212
  const loadingIndicator = Boolean(props.isLoading) ? /* @__PURE__ */ React__default.default.createElement(
@@ -4253,7 +4253,7 @@ function ControlsLabel(props) {
4253
4253
  }
4254
4254
  return labelElement;
4255
4255
  }
4256
- const getStyles$g = (theme) => ({
4256
+ const getStyles$h = (theme) => ({
4257
4257
  horizontalLabel: css.css({
4258
4258
  background: theme.isDark ? theme.colors.background.primary : theme.colors.background.secondary,
4259
4259
  display: `flex`,
@@ -4306,7 +4306,7 @@ function keyLabelToOption(key, label) {
4306
4306
  const filterNoOp = () => true;
4307
4307
  function AdHocFilterRenderer({ filter, model }) {
4308
4308
  var _a, _b, _c, _d, _e;
4309
- const styles = ui.useStyles2(getStyles$f);
4309
+ const styles = ui.useStyles2(getStyles$g);
4310
4310
  const [keys, setKeys] = React.useState([]);
4311
4311
  const [values, setValues] = React.useState([]);
4312
4312
  const [isKeysLoading, setIsKeysLoading] = React.useState(false);
@@ -4533,7 +4533,7 @@ function AdHocFilterRenderer({ filter, model }) {
4533
4533
  }
4534
4534
  ));
4535
4535
  }
4536
- const getStyles$f = (theme) => ({
4536
+ const getStyles$g = (theme) => ({
4537
4537
  field: css.css({
4538
4538
  marginBottom: 0
4539
4539
  }),
@@ -4733,7 +4733,7 @@ function isFilter(filter) {
4733
4733
 
4734
4734
  const DropdownItem = React.forwardRef(
4735
4735
  function DropdownItem2({ children, active, addGroupBottomBorder, isMultiValueEdit, checked, ...rest }, ref) {
4736
- const styles = ui.useStyles2(getStyles$e);
4736
+ const styles = ui.useStyles2(getStyles$f);
4737
4737
  const id = React.useId();
4738
4738
  return /* @__PURE__ */ React__default.default.createElement(
4739
4739
  "div",
@@ -4749,7 +4749,7 @@ const DropdownItem = React.forwardRef(
4749
4749
  );
4750
4750
  }
4751
4751
  );
4752
- const getStyles$e = (theme) => ({
4752
+ const getStyles$f = (theme) => ({
4753
4753
  option: css.css({
4754
4754
  label: "grafana-select-option",
4755
4755
  top: 0,
@@ -4819,7 +4819,7 @@ const MultiValueApplyButton = ({
4819
4819
  maxOptionWidth,
4820
4820
  menuHeight
4821
4821
  }) => {
4822
- const styles = ui.useStyles2(getStyles$e);
4822
+ const styles = ui.useStyles2(getStyles$f);
4823
4823
  const floatingElementRect = floatingElement == null ? void 0 : floatingElement.getBoundingClientRect();
4824
4824
  return /* @__PURE__ */ React__default.default.createElement(
4825
4825
  "div",
@@ -4939,11 +4939,11 @@ const generateFilterUpdatePayload = ({
4939
4939
  [filterInputType]: item.value
4940
4940
  };
4941
4941
  };
4942
- const INPUT_PLACEHOLDER = "Filter by label values";
4943
- const generatePlaceholder = (filter, filterInputType, isMultiValueEdit, isAlwaysWip) => {
4942
+ const INPUT_PLACEHOLDER_DEFAULT = "Filter by label values";
4943
+ const generatePlaceholder = (filter, filterInputType, isMultiValueEdit, isAlwaysWip, inputPlaceholder) => {
4944
4944
  var _a;
4945
4945
  if (filterInputType === "key") {
4946
- return INPUT_PLACEHOLDER;
4946
+ return inputPlaceholder || INPUT_PLACEHOLDER_DEFAULT;
4947
4947
  }
4948
4948
  if (filterInputType === "value") {
4949
4949
  if (isMultiValueEdit) {
@@ -4951,7 +4951,7 @@ const generatePlaceholder = (filter, filterInputType, isMultiValueEdit, isAlways
4951
4951
  }
4952
4952
  return ((_a = filter.valueLabels) == null ? void 0 : _a[0]) || "";
4953
4953
  }
4954
- return filter[filterInputType] && !isAlwaysWip ? `${filter[filterInputType]}` : INPUT_PLACEHOLDER;
4954
+ return filter[filterInputType] && !isAlwaysWip ? `${filter[filterInputType]}` : inputPlaceholder || INPUT_PLACEHOLDER_DEFAULT;
4955
4955
  };
4956
4956
  const populateInputValueOnInputTypeSwitch = ({
4957
4957
  populateInputOnEdit,
@@ -5040,7 +5040,7 @@ const MultiValuePill = ({
5040
5040
  handleEditMultiValuePill
5041
5041
  }) => {
5042
5042
  var _a, _b;
5043
- const styles = ui.useStyles2(getStyles$d);
5043
+ const styles = ui.useStyles2(getStyles$e);
5044
5044
  const editMultiValuePill = React.useCallback(
5045
5045
  (e) => {
5046
5046
  e.stopPropagation();
@@ -5104,7 +5104,7 @@ const MultiValuePill = ({
5104
5104
  )
5105
5105
  );
5106
5106
  };
5107
- const getStyles$d = (theme) => ({
5107
+ const getStyles$e = (theme) => ({
5108
5108
  basePill: css.css({
5109
5109
  display: "flex",
5110
5110
  alignItems: "center",
@@ -5133,8 +5133,15 @@ const getStyles$d = (theme) => ({
5133
5133
  })
5134
5134
  });
5135
5135
 
5136
- const AdHocCombobox = React.forwardRef(function AdHocCombobox2({ filter, model, isAlwaysWip, handleChangeViewMode, focusOnWipInputRef, populateInputOnEdit }, parentRef) {
5137
- var _a, _b, _c, _d;
5136
+ const AdHocCombobox = React.forwardRef(function AdHocCombobox2({
5137
+ filter,
5138
+ controller,
5139
+ isAlwaysWip,
5140
+ handleChangeViewMode,
5141
+ focusOnWipInputRef,
5142
+ populateInputOnEdit
5143
+ }, parentRef) {
5144
+ var _a, _b, _c;
5138
5145
  const [open, setOpen] = React.useState(false);
5139
5146
  const [options, setOptions] = React.useState([]);
5140
5147
  const [optionsLoading, setOptionsLoading] = React.useState(false);
@@ -5143,10 +5150,10 @@ const AdHocCombobox = React.forwardRef(function AdHocCombobox2({ filter, model,
5143
5150
  const [activeIndex, setActiveIndex] = React.useState(null);
5144
5151
  const [filterInputType, setInputType] = React.useState(!isAlwaysWip ? "value" : "key");
5145
5152
  const [preventFiltering, setPreventFiltering] = React.useState(!isAlwaysWip && filterInputType === "value");
5146
- const styles = ui.useStyles2(getStyles$c);
5153
+ const styles = ui.useStyles2(getStyles$d);
5147
5154
  const [filterMultiValues, setFilterMultiValues] = React.useState([]);
5148
5155
  const [_, setForceRefresh] = React.useState({});
5149
- const allowCustomValue = (_a = model.state.allowCustomValue) != null ? _a : true;
5156
+ const { allowCustomValue = true, onAddCustomValue, filters, inputPlaceholder } = controller.useState();
5150
5157
  const multiValuePillWrapperRef = React.useRef(null);
5151
5158
  const hasMultiValueOperator = isMultiValueOperator((filter == null ? void 0 : filter.operator) || "");
5152
5159
  const isMultiValueEdit = hasMultiValueOperator && filterInputType === "value";
@@ -5159,29 +5166,30 @@ const AdHocCombobox = React.forwardRef(function AdHocCombobox2({ filter, model,
5159
5166
  if (isAlwaysWip) {
5160
5167
  return false;
5161
5168
  }
5162
- if (model.state.filters.at(-1) === filter) {
5169
+ if (filters.at(-1) === filter) {
5163
5170
  return true;
5164
5171
  }
5165
5172
  return false;
5166
- }, [filter, isAlwaysWip, model.state.filters]);
5173
+ }, [filter, isAlwaysWip, filters]);
5167
5174
  const handleResetWip = React.useCallback(() => {
5168
5175
  if (isAlwaysWip) {
5169
- model._addWip();
5176
+ controller.addWip();
5170
5177
  setInputType("key");
5171
5178
  setInputValue("");
5172
5179
  }
5173
- }, [model, isAlwaysWip]);
5180
+ }, [controller, isAlwaysWip]);
5174
5181
  const handleMultiValueFilterCommit = React.useCallback(
5175
- (model2, filter2, filterMultiValues2, preventFocus) => {
5182
+ (controller2, filter2, filterMultiValues2, preventFocus) => {
5183
+ var _a2;
5176
5184
  if (!filterMultiValues2.length && filter2.origin) {
5177
- model2.updateToMatchAll(filter2);
5185
+ controller2.updateToMatchAll(filter2);
5178
5186
  }
5179
5187
  if (filterMultiValues2.length) {
5180
5188
  const valueLabels = [];
5181
5189
  const values = [];
5182
5190
  filterMultiValues2.forEach((item) => {
5183
- var _a2;
5184
- valueLabels.push((_a2 = item.label) != null ? _a2 : item.value);
5191
+ var _a3;
5192
+ valueLabels.push((_a3 = item.label) != null ? _a3 : item.value);
5185
5193
  values.push(item.value);
5186
5194
  });
5187
5195
  let shouldUpdate = true;
@@ -5189,16 +5197,15 @@ const AdHocCombobox = React.forwardRef(function AdHocCombobox2({ filter, model,
5189
5197
  shouldUpdate = !filter2.values.every((v, i) => v === values[i]);
5190
5198
  }
5191
5199
  if (shouldUpdate) {
5192
- const queryController = getQueryController(model2);
5193
- queryController == null ? void 0 : queryController.startProfile(FILTER_CHANGED_INTERACTION);
5200
+ (_a2 = controller2.startProfile) == null ? void 0 : _a2.call(controller2, FILTER_CHANGED_INTERACTION);
5194
5201
  }
5195
- model2._updateFilter(filter2, { valueLabels, values, value: values[0] });
5202
+ controller2.updateFilter(filter2, { valueLabels, values, value: values[0] });
5196
5203
  setFilterMultiValues([]);
5197
5204
  }
5198
5205
  if (!preventFocus) {
5199
5206
  setTimeout(() => {
5200
- var _a2;
5201
- return (_a2 = refs.domReference.current) == null ? void 0 : _a2.focus();
5207
+ var _a3;
5208
+ return (_a3 = refs.domReference.current) == null ? void 0 : _a3.focus();
5202
5209
  });
5203
5210
  }
5204
5211
  },
@@ -5218,10 +5225,10 @@ const AdHocCombobox = React.forwardRef(function AdHocCombobox2({ filter, model,
5218
5225
  setOpen(nextOpen);
5219
5226
  if (reason && ["outside-press", "escape-key"].includes(reason)) {
5220
5227
  if (isMultiValueEdit) {
5221
- handleMultiValueFilterCommit(model, filter, filterMultiValues);
5228
+ handleMultiValueFilterCommit(controller, filter, filterMultiValues);
5222
5229
  } else {
5223
5230
  if (filter && filter.origin && inputValue === "") {
5224
- model.updateToMatchAll(filter);
5231
+ controller.updateToMatchAll(filter);
5225
5232
  }
5226
5233
  }
5227
5234
  handleResetWip();
@@ -5236,7 +5243,7 @@ const AdHocCombobox = React.forwardRef(function AdHocCombobox2({ filter, model,
5236
5243
  handleResetWip,
5237
5244
  inputValue,
5238
5245
  isMultiValueEdit,
5239
- model
5246
+ controller
5240
5247
  ]
5241
5248
  );
5242
5249
  const outsidePressIdsToIgnore = React.useMemo(() => {
@@ -5295,15 +5302,13 @@ const AdHocCombobox = React.forwardRef(function AdHocCombobox2({ filter, model,
5295
5302
  filteredDropDownItems.push(customOptionValue);
5296
5303
  }
5297
5304
  }
5298
- const onAddCustomValue = model.state.onAddCustomValue;
5299
5305
  const maxOptionWidth = setupDropdownAccessibility(filteredDropDownItems, listRef, disabledIndicesRef);
5300
5306
  const handleFetchOptions = React.useCallback(
5301
5307
  async (inputType) => {
5302
- var _a2;
5303
- const profiler = getInteractionTracker(model);
5308
+ var _a2, _b2, _c2, _d;
5304
5309
  const interactionName = inputType === "key" ? ADHOC_KEYS_DROPDOWN_INTERACTION : ADHOC_VALUES_DROPDOWN_INTERACTION;
5305
5310
  if (inputType !== "operator") {
5306
- profiler == null ? void 0 : profiler.startInteraction(interactionName);
5311
+ (_a2 = controller.startInteraction) == null ? void 0 : _a2.call(controller, interactionName);
5307
5312
  }
5308
5313
  setOptionsError(false);
5309
5314
  setOptionsLoading(true);
@@ -5311,18 +5316,18 @@ const AdHocCombobox = React.forwardRef(function AdHocCombobox2({ filter, model,
5311
5316
  let options2 = [];
5312
5317
  try {
5313
5318
  if (inputType === "key") {
5314
- options2 = await model._getKeys(null);
5319
+ options2 = await controller.getKeys(null);
5315
5320
  } else if (inputType === "operator") {
5316
- options2 = model._getOperators();
5321
+ options2 = controller.getOperators();
5317
5322
  } else if (inputType === "value") {
5318
- options2 = await model._getValuesFor(filter);
5323
+ options2 = await controller.getValuesFor(filter);
5319
5324
  }
5320
5325
  if (filterInputTypeRef.current !== inputType) {
5321
- profiler == null ? void 0 : profiler.stopInteraction();
5326
+ (_b2 = controller.stopInteraction) == null ? void 0 : _b2.call(controller);
5322
5327
  return;
5323
5328
  }
5324
5329
  setOptions(options2);
5325
- if ((_a2 = options2[0]) == null ? void 0 : _a2.group) {
5330
+ if ((_c2 = options2[0]) == null ? void 0 : _c2.group) {
5326
5331
  setActiveIndex(1);
5327
5332
  } else {
5328
5333
  setActiveIndex(0);
@@ -5331,9 +5336,9 @@ const AdHocCombobox = React.forwardRef(function AdHocCombobox2({ filter, model,
5331
5336
  setOptionsError(true);
5332
5337
  }
5333
5338
  setOptionsLoading(false);
5334
- profiler == null ? void 0 : profiler.stopInteraction();
5339
+ (_d = controller.stopInteraction) == null ? void 0 : _d.call(controller);
5335
5340
  },
5336
- [filter, model]
5341
+ [filter, controller]
5337
5342
  );
5338
5343
  const rowVirtualizer = reactVirtual.useVirtualizer({
5339
5344
  count: filteredDropDownItems.length,
@@ -5343,6 +5348,7 @@ const AdHocCombobox = React.forwardRef(function AdHocCombobox2({ filter, model,
5343
5348
  });
5344
5349
  const handleBackspaceInput = React.useCallback(
5345
5350
  (event, multiValueEdit) => {
5351
+ var _a2;
5346
5352
  if (event.key === "Backspace" && !inputValue) {
5347
5353
  if (filterInputType === "value") {
5348
5354
  if (multiValueEdit) {
@@ -5363,10 +5369,9 @@ const AdHocCombobox = React.forwardRef(function AdHocCombobox2({ filter, model,
5363
5369
  }
5364
5370
  focusOnWipInputRef == null ? void 0 : focusOnWipInputRef();
5365
5371
  if (isFilterComplete(filter)) {
5366
- const queryController = getQueryController(model);
5367
- queryController == null ? void 0 : queryController.startProfile(FILTER_REMOVED_INTERACTION);
5372
+ (_a2 = controller.startProfile) == null ? void 0 : _a2.call(controller, FILTER_REMOVED_INTERACTION);
5368
5373
  }
5369
- model._handleComboboxBackspace(filter);
5374
+ controller.handleComboboxBackspace(filter);
5370
5375
  if (isAlwaysWip) {
5371
5376
  handleResetWip();
5372
5377
  }
@@ -5375,7 +5380,7 @@ const AdHocCombobox = React.forwardRef(function AdHocCombobox2({ filter, model,
5375
5380
  [
5376
5381
  inputValue,
5377
5382
  filterInputType,
5378
- model,
5383
+ controller,
5379
5384
  filter,
5380
5385
  isAlwaysWip,
5381
5386
  filterMultiValues.length,
@@ -5389,7 +5394,7 @@ const AdHocCombobox = React.forwardRef(function AdHocCombobox2({ filter, model,
5389
5394
  if (event.key === "Tab" && !event.shiftKey) {
5390
5395
  if (multiValueEdit) {
5391
5396
  event.preventDefault();
5392
- handleMultiValueFilterCommit(model, filter, filterMultiValues);
5397
+ handleMultiValueFilterCommit(controller, filter, filterMultiValues);
5393
5398
  (_a2 = refs.domReference.current) == null ? void 0 : _a2.focus();
5394
5399
  }
5395
5400
  handleChangeViewMode == null ? void 0 : handleChangeViewMode();
@@ -5402,7 +5407,7 @@ const AdHocCombobox = React.forwardRef(function AdHocCombobox2({ filter, model,
5402
5407
  handleChangeViewMode,
5403
5408
  handleMultiValueFilterCommit,
5404
5409
  handleResetWip,
5405
- model,
5410
+ controller,
5406
5411
  refs.domReference
5407
5412
  ]
5408
5413
  );
@@ -5411,16 +5416,17 @@ const AdHocCombobox = React.forwardRef(function AdHocCombobox2({ filter, model,
5411
5416
  if (event.key === "Tab" && event.shiftKey) {
5412
5417
  if (multiValueEdit) {
5413
5418
  event.preventDefault();
5414
- handleMultiValueFilterCommit(model, filter, filterMultiValues, true);
5419
+ handleMultiValueFilterCommit(controller, filter, filterMultiValues, true);
5415
5420
  }
5416
5421
  handleChangeViewMode == null ? void 0 : handleChangeViewMode();
5417
5422
  handleResetWip();
5418
5423
  }
5419
5424
  },
5420
- [filter, filterMultiValues, handleChangeViewMode, handleMultiValueFilterCommit, handleResetWip, model]
5425
+ [filter, filterMultiValues, handleChangeViewMode, handleMultiValueFilterCommit, handleResetWip, controller]
5421
5426
  );
5422
5427
  const handleEnterInput = React.useCallback(
5423
5428
  (event, multiValueEdit) => {
5429
+ var _a2;
5424
5430
  if (event.key === "Enter" && activeIndex != null) {
5425
5431
  if (!filteredDropDownItems[activeIndex]) {
5426
5432
  return;
@@ -5438,10 +5444,9 @@ const AdHocCombobox = React.forwardRef(function AdHocCombobox2({ filter, model,
5438
5444
  onAddCustomValue
5439
5445
  });
5440
5446
  if (filterInputType === "value" && payload.value !== (filter == null ? void 0 : filter.value)) {
5441
- const queryController = getQueryController(model);
5442
- queryController == null ? void 0 : queryController.startProfile(FILTER_CHANGED_INTERACTION);
5447
+ (_a2 = controller.startProfile) == null ? void 0 : _a2.call(controller, FILTER_CHANGED_INTERACTION);
5443
5448
  }
5444
- model._updateFilter(filter, payload);
5449
+ controller.updateFilter(filter, payload);
5445
5450
  populateInputValueOnInputTypeSwitch({
5446
5451
  populateInputOnEdit,
5447
5452
  item: selectedItem,
@@ -5468,7 +5473,7 @@ const AdHocCombobox = React.forwardRef(function AdHocCombobox2({ filter, model,
5468
5473
  activeIndex,
5469
5474
  filteredDropDownItems,
5470
5475
  handleLocalMultiValueChange,
5471
- model,
5476
+ controller,
5472
5477
  filter,
5473
5478
  filterInputType,
5474
5479
  populateInputOnEdit,
@@ -5500,7 +5505,7 @@ const AdHocCombobox = React.forwardRef(function AdHocCombobox2({ filter, model,
5500
5505
  }
5501
5506
  }, [open, filterInputType]);
5502
5507
  React.useEffect(() => {
5503
- var _a2, _b2, _c2, _d2;
5508
+ var _a2, _b2, _c2, _d;
5504
5509
  if (!isAlwaysWip) {
5505
5510
  if (hasMultiValueOperator && ((_a2 = filter == null ? void 0 : filter.values) == null ? void 0 : _a2.length)) {
5506
5511
  const multiValueOptions = filter.values.reduce(
@@ -5525,7 +5530,7 @@ const AdHocCombobox = React.forwardRef(function AdHocCombobox2({ filter, model,
5525
5530
  (_a3 = refs.domReference.current) == null ? void 0 : _a3.select();
5526
5531
  });
5527
5532
  }
5528
- (_d2 = refs.domReference.current) == null ? void 0 : _d2.focus();
5533
+ (_d = refs.domReference.current) == null ? void 0 : _d.focus();
5529
5534
  }
5530
5535
  }, []);
5531
5536
  React.useEffect(() => {
@@ -5544,7 +5549,7 @@ const AdHocCombobox = React.forwardRef(function AdHocCombobox2({ filter, model,
5544
5549
  rowVirtualizer.scrollToIndex(activeIndex);
5545
5550
  }
5546
5551
  }, [activeIndex, rowVirtualizer]);
5547
- const keyLabel = (_b = filter == null ? void 0 : filter.keyLabel) != null ? _b : filter == null ? void 0 : filter.key;
5552
+ const keyLabel = (_a = filter == null ? void 0 : filter.keyLabel) != null ? _a : filter == null ? void 0 : filter.key;
5548
5553
  return /* @__PURE__ */ React__default.default.createElement("div", { className: styles.comboboxWrapper }, filter ? /* @__PURE__ */ React__default.default.createElement("div", { className: styles.pillWrapper }, (filter == null ? void 0 : filter.key) ? /* @__PURE__ */ React__default.default.createElement("div", { className: css.cx(styles.basePill, styles.keyPill) }, keyLabel) : null, (filter == null ? void 0 : filter.key) && (filter == null ? void 0 : filter.operator) && filterInputType !== "operator" ? /* @__PURE__ */ React__default.default.createElement(
5549
5554
  "div",
5550
5555
  {
@@ -5599,7 +5604,7 @@ const AdHocCombobox = React.forwardRef(function AdHocCombobox2({ filter, model,
5599
5604
  onChange,
5600
5605
  value: inputValue,
5601
5606
  // dynamic placeholder to display operator and/or value in filter edit mode
5602
- placeholder: generatePlaceholder(filter, filterInputType, isMultiValueEdit, isAlwaysWip),
5607
+ placeholder: generatePlaceholder(filter, filterInputType, isMultiValueEdit, isAlwaysWip, inputPlaceholder),
5603
5608
  "aria-autocomplete": "list",
5604
5609
  onKeyDown(event) {
5605
5610
  if (!open) {
@@ -5623,13 +5628,13 @@ const AdHocCombobox = React.forwardRef(function AdHocCombobox2({ filter, model,
5623
5628
  setOpen(true);
5624
5629
  }
5625
5630
  }
5626
- ), optionsLoading ? /* @__PURE__ */ React__default.default.createElement(ui.Spinner, { className: styles.loadingIndicator, inline: true }) : null, /* @__PURE__ */ React__default.default.createElement(react.FloatingPortal, null, open && /* @__PURE__ */ React__default.default.createElement(react.FloatingFocusManager, { context, initialFocus: -1, visuallyHiddenDismiss: true, modal: false }, /* @__PURE__ */ React__default.default.createElement(React__default.default.Fragment, null, /* @__PURE__ */ React__default.default.createElement(
5631
+ ), optionsLoading ? /* @__PURE__ */ React__default.default.createElement(ui.Spinner, { className: styles.loadingIndicator, inline: true }) : null, /* @__PURE__ */ React__default.default.createElement(react.FloatingPortal, null, open && /* @__PURE__ */ React__default.default.createElement(react.FloatingFocusManager, { context, initialFocus: -1, visuallyHiddenDismiss: true, modal: true }, /* @__PURE__ */ React__default.default.createElement(React__default.default.Fragment, null, /* @__PURE__ */ React__default.default.createElement(
5627
5632
  "div",
5628
5633
  {
5629
5634
  style: {
5630
5635
  ...floatingStyles,
5631
5636
  width: `${optionsError ? ERROR_STATE_DROPDOWN_WIDTH : maxOptionWidth}px`,
5632
- transform: isMultiValueEdit ? `translate(${((_c = multiValuePillWrapperRef.current) == null ? void 0 : _c.getBoundingClientRect().left) || 0}px, ${(((_d = refs.domReference.current) == null ? void 0 : _d.getBoundingClientRect().bottom) || 0) + 10}px )` : floatingStyles.transform
5637
+ transform: isMultiValueEdit ? `translate(${((_b = multiValuePillWrapperRef.current) == null ? void 0 : _b.getBoundingClientRect().left) || 0}px, ${(((_c = refs.domReference.current) == null ? void 0 : _c.getBoundingClientRect().bottom) || 0) + 10}px )` : floatingStyles.transform
5633
5638
  },
5634
5639
  ref: refs.setFloating,
5635
5640
  className: styles.dropdownWrapper,
@@ -5678,7 +5683,7 @@ const AdHocCombobox = React.forwardRef(function AdHocCombobox2({ filter, model,
5678
5683
  listRef.current[index] = node;
5679
5684
  },
5680
5685
  onClick(event) {
5681
- var _a3;
5686
+ var _a3, _b2;
5682
5687
  if (filterInputType !== "value") {
5683
5688
  event.stopPropagation();
5684
5689
  }
@@ -5697,10 +5702,9 @@ const AdHocCombobox = React.forwardRef(function AdHocCombobox2({ filter, model,
5697
5702
  onAddCustomValue
5698
5703
  });
5699
5704
  if (filterInputType === "value" && payload.value !== (filter == null ? void 0 : filter.value)) {
5700
- const queryController = getQueryController(model);
5701
- queryController == null ? void 0 : queryController.startProfile(FILTER_CHANGED_INTERACTION);
5705
+ (_b2 = controller.startProfile) == null ? void 0 : _b2.call(controller, FILTER_CHANGED_INTERACTION);
5702
5706
  }
5703
- model._updateFilter(filter, payload);
5707
+ controller.updateFilter(filter, payload);
5704
5708
  populateInputValueOnInputTypeSwitch({
5705
5709
  populateInputOnEdit,
5706
5710
  item,
@@ -5744,7 +5748,7 @@ const AdHocCombobox = React.forwardRef(function AdHocCombobox2({ filter, model,
5744
5748
  MultiValueApplyButton,
5745
5749
  {
5746
5750
  onApply: () => {
5747
- handleMultiValueFilterCommit(model, filter, filterMultiValues);
5751
+ handleMultiValueFilterCommit(controller, filter, filterMultiValues);
5748
5752
  },
5749
5753
  floatingElement: refs.floating.current,
5750
5754
  maxOptionWidth,
@@ -5752,7 +5756,7 @@ const AdHocCombobox = React.forwardRef(function AdHocCombobox2({ filter, model,
5752
5756
  }
5753
5757
  ) : null))));
5754
5758
  });
5755
- const getStyles$c = (theme) => ({
5759
+ const getStyles$d = (theme) => ({
5756
5760
  comboboxWrapper: css.css({
5757
5761
  display: "flex",
5758
5762
  flexWrap: "wrap"
@@ -5824,9 +5828,9 @@ const getStyles$c = (theme) => ({
5824
5828
  });
5825
5829
 
5826
5830
  const LABEL_MAX_VISIBLE_LENGTH = 20;
5827
- function AdHocFilterPill({ filter, model, readOnly, focusOnWipInputRef }) {
5831
+ function AdHocFilterPill({ filter, controller, readOnly, focusOnWipInputRef }) {
5828
5832
  var _a, _b, _c, _d;
5829
- const styles = ui.useStyles2(getStyles$b);
5833
+ const styles = ui.useStyles2(getStyles$c);
5830
5834
  const [viewMode, setViewMode] = React.useState(true);
5831
5835
  const [shouldFocusOnPillWrapper, setShouldFocusOnPillWrapper] = React.useState(false);
5832
5836
  const pillWrapperRef = React.useRef(null);
@@ -5854,9 +5858,9 @@ function AdHocFilterPill({ filter, model, readOnly, focusOnWipInputRef }) {
5854
5858
  React.useEffect(() => {
5855
5859
  if (filter.forceEdit && viewMode) {
5856
5860
  setViewMode(false);
5857
- model._updateFilter(filter, { forceEdit: void 0 });
5861
+ controller.updateFilter(filter, { forceEdit: void 0 });
5858
5862
  }
5859
- }, [filter, model, viewMode]);
5863
+ }, [filter, controller, viewMode]);
5860
5864
  React.useEffect(() => {
5861
5865
  if (viewMode) {
5862
5866
  setPopulateInputOnEdit((prevValue) => prevValue ? false : prevValue);
@@ -5922,9 +5926,9 @@ function AdHocFilterPill({ filter, model, readOnly, focusOnWipInputRef }) {
5922
5926
  onClick: (e) => {
5923
5927
  e.stopPropagation();
5924
5928
  if (filter.origin && filter.origin === "dashboard") {
5925
- model.updateToMatchAll(filter);
5929
+ controller.updateToMatchAll(filter);
5926
5930
  } else {
5927
- model._removeFilter(filter);
5931
+ controller.removeFilter(filter);
5928
5932
  }
5929
5933
  setTimeout(() => focusOnWipInputRef == null ? void 0 : focusOnWipInputRef());
5930
5934
  },
@@ -5933,9 +5937,9 @@ function AdHocFilterPill({ filter, model, readOnly, focusOnWipInputRef }) {
5933
5937
  e.preventDefault();
5934
5938
  e.stopPropagation();
5935
5939
  if (filter.origin && filter.origin === "dashboard") {
5936
- model.updateToMatchAll(filter);
5940
+ controller.updateToMatchAll(filter);
5937
5941
  } else {
5938
- model._removeFilter(filter);
5942
+ controller.removeFilter(filter);
5939
5943
  }
5940
5944
  setTimeout(() => focusOnWipInputRef == null ? void 0 : focusOnWipInputRef());
5941
5945
  }
@@ -5968,13 +5972,13 @@ function AdHocFilterPill({ filter, model, readOnly, focusOnWipInputRef }) {
5968
5972
  {
5969
5973
  onClick: (e) => {
5970
5974
  e.stopPropagation();
5971
- model.restoreOriginalFilter(filter);
5975
+ controller.restoreOriginalFilter(filter);
5972
5976
  },
5973
5977
  onKeyDownCapture: (e) => {
5974
5978
  if (e.key === "Enter") {
5975
5979
  e.preventDefault();
5976
5980
  e.stopPropagation();
5977
- model.restoreOriginalFilter(filter);
5981
+ controller.restoreOriginalFilter(filter);
5978
5982
  }
5979
5983
  },
5980
5984
  name: "history",
@@ -5997,14 +6001,14 @@ function AdHocFilterPill({ filter, model, readOnly, focusOnWipInputRef }) {
5997
6001
  AdHocCombobox,
5998
6002
  {
5999
6003
  filter,
6000
- model,
6004
+ controller,
6001
6005
  handleChangeViewMode,
6002
6006
  focusOnWipInputRef,
6003
6007
  populateInputOnEdit
6004
6008
  }
6005
6009
  );
6006
6010
  }
6007
- const getStyles$b = (theme) => ({
6011
+ const getStyles$c = (theme) => ({
6008
6012
  combinedFilterPill: css.css({
6009
6013
  display: "flex",
6010
6014
  alignItems: "center",
@@ -6076,19 +6080,19 @@ const getStyles$b = (theme) => ({
6076
6080
  ...getNonApplicablePillStyles(theme)
6077
6081
  });
6078
6082
 
6079
- const AdHocFiltersAlwaysWipCombobox = React.forwardRef(function AdHocFiltersAlwaysWipCombobox2({ model }, parentRef) {
6080
- const { _wip } = model.useState();
6083
+ const AdHocFiltersAlwaysWipCombobox = React.forwardRef(function AdHocFiltersAlwaysWipCombobox2({ controller }, parentRef) {
6084
+ const { wip } = controller.useState();
6081
6085
  React.useLayoutEffect(() => {
6082
- if (!_wip) {
6083
- model._addWip();
6086
+ if (!wip) {
6087
+ controller.addWip();
6084
6088
  }
6085
- }, [_wip]);
6086
- return /* @__PURE__ */ React__default.default.createElement(AdHocCombobox, { model, filter: _wip, isAlwaysWip: true, ref: parentRef });
6089
+ }, [wip]);
6090
+ return /* @__PURE__ */ React__default.default.createElement(AdHocCombobox, { controller, filter: wip, isAlwaysWip: true, ref: parentRef });
6087
6091
  });
6088
6092
 
6089
- const AdHocFiltersComboboxRenderer = React.memo(function AdHocFiltersComboboxRenderer2({ model }) {
6090
- const { originFilters, filters, readOnly } = model.useState();
6091
- const styles = ui.useStyles2(getStyles$a);
6093
+ const AdHocFiltersComboboxRenderer = React.memo(function AdHocFiltersComboboxRenderer2({ controller }) {
6094
+ const { originFilters, filters, readOnly } = controller.useState();
6095
+ const styles = ui.useStyles2(getStyles$b);
6092
6096
  const focusOnWipInputRef = React.useRef();
6093
6097
  return /* @__PURE__ */ React__default.default.createElement(
6094
6098
  "div",
@@ -6106,7 +6110,7 @@ const AdHocFiltersComboboxRenderer = React.memo(function AdHocFiltersComboboxRen
6106
6110
  {
6107
6111
  key: `${index}-${filter.key}`,
6108
6112
  filter,
6109
- model,
6113
+ controller,
6110
6114
  focusOnWipInputRef: focusOnWipInputRef.current
6111
6115
  }
6112
6116
  ) : null
@@ -6116,15 +6120,15 @@ const AdHocFiltersComboboxRenderer = React.memo(function AdHocFiltersComboboxRen
6116
6120
  {
6117
6121
  key: `${index}-${filter.key}`,
6118
6122
  filter,
6119
- model,
6123
+ controller,
6120
6124
  readOnly: readOnly || filter.readOnly,
6121
6125
  focusOnWipInputRef: focusOnWipInputRef.current
6122
6126
  }
6123
6127
  )),
6124
- !readOnly ? /* @__PURE__ */ React__default.default.createElement(AdHocFiltersAlwaysWipCombobox, { model, ref: focusOnWipInputRef }) : null
6128
+ !readOnly ? /* @__PURE__ */ React__default.default.createElement(AdHocFiltersAlwaysWipCombobox, { controller, ref: focusOnWipInputRef }) : null
6125
6129
  );
6126
6130
  });
6127
- const getStyles$a = (theme) => ({
6131
+ const getStyles$b = (theme) => ({
6128
6132
  comboboxWrapper: css.css({
6129
6133
  display: "flex",
6130
6134
  flexWrap: "wrap",
@@ -6243,6 +6247,66 @@ function hasSameOperators(scopeConvertedOperator, filterOperator) {
6243
6247
  return true;
6244
6248
  }
6245
6249
 
6250
+ class VariableBackedAdHocFiltersController {
6251
+ constructor(model) {
6252
+ this.model = model;
6253
+ }
6254
+ useState() {
6255
+ const state = this.model.useState();
6256
+ return {
6257
+ filters: state.filters,
6258
+ originFilters: state.originFilters,
6259
+ readOnly: state.readOnly,
6260
+ allowCustomValue: state.allowCustomValue,
6261
+ supportsMultiValueOperators: state.supportsMultiValueOperators,
6262
+ onAddCustomValue: state.onAddCustomValue,
6263
+ wip: state._wip
6264
+ };
6265
+ }
6266
+ async getKeys(currentKey) {
6267
+ return this.model._getKeys(currentKey);
6268
+ }
6269
+ async getValuesFor(filter) {
6270
+ return this.model._getValuesFor(filter);
6271
+ }
6272
+ getOperators() {
6273
+ return this.model._getOperators();
6274
+ }
6275
+ updateFilter(filter, update) {
6276
+ this.model._updateFilter(filter, update);
6277
+ }
6278
+ updateToMatchAll(filter) {
6279
+ this.model.updateToMatchAll(filter);
6280
+ }
6281
+ removeFilter(filter) {
6282
+ this.model._removeFilter(filter);
6283
+ }
6284
+ removeLastFilter() {
6285
+ this.model._removeLastFilter();
6286
+ }
6287
+ handleComboboxBackspace(filter) {
6288
+ this.model._handleComboboxBackspace(filter);
6289
+ }
6290
+ addWip() {
6291
+ this.model._addWip();
6292
+ }
6293
+ restoreOriginalFilter(filter) {
6294
+ this.model.restoreOriginalFilter(filter);
6295
+ }
6296
+ startProfile(name) {
6297
+ const queryController = getQueryController(this.model);
6298
+ queryController == null ? void 0 : queryController.startProfile(name);
6299
+ }
6300
+ startInteraction(name) {
6301
+ const interactionTracker = getInteractionTracker(this.model);
6302
+ interactionTracker == null ? void 0 : interactionTracker.startInteraction(name);
6303
+ }
6304
+ stopInteraction() {
6305
+ const interactionTracker = getInteractionTracker(this.model);
6306
+ interactionTracker == null ? void 0 : interactionTracker.stopInteraction();
6307
+ }
6308
+ }
6309
+
6246
6310
  const OPERATORS = [
6247
6311
  {
6248
6312
  value: "=",
@@ -6717,13 +6781,14 @@ function renderExpression(builder, filters) {
6717
6781
  }
6718
6782
  function AdHocFiltersVariableRenderer({ model }) {
6719
6783
  const { filters, readOnly, addFilterButtonText } = model.useState();
6720
- const styles = ui.useStyles2(getStyles$9);
6784
+ const styles = ui.useStyles2(getStyles$a);
6785
+ const controller = React.useMemo(() => new VariableBackedAdHocFiltersController(model), [model]);
6721
6786
  if (model.state.layout === "combobox") {
6722
- return /* @__PURE__ */ React__default.default.createElement(AdHocFiltersComboboxRenderer, { model });
6787
+ return /* @__PURE__ */ React__default.default.createElement(AdHocFiltersComboboxRenderer, { controller });
6723
6788
  }
6724
6789
  return /* @__PURE__ */ React__default.default.createElement("div", { className: styles.wrapper }, filters.filter((filter) => !filter.hidden).map((filter, index) => /* @__PURE__ */ React__default.default.createElement(React__default.default.Fragment, { key: index }, /* @__PURE__ */ React__default.default.createElement(AdHocFilterRenderer, { filter, model }))), !readOnly && /* @__PURE__ */ React__default.default.createElement(AdHocFilterBuilder, { model, key: "'builder", addFilterButtonText }));
6725
6790
  }
6726
- const getStyles$9 = (theme) => ({
6791
+ const getStyles$a = (theme) => ({
6727
6792
  wrapper: css.css({
6728
6793
  display: "flex",
6729
6794
  flexWrap: "wrap",
@@ -8615,6 +8680,9 @@ function isTextBoxVariable(variable) {
8615
8680
  function isGroupByVariable(variable) {
8616
8681
  return variable.state.type === "groupby";
8617
8682
  }
8683
+ function isSwitchVariable(variable) {
8684
+ return variable.state.type === "switch";
8685
+ }
8618
8686
 
8619
8687
  class ActWhenVariableChanged extends SceneObjectBase {
8620
8688
  constructor() {
@@ -8690,7 +8758,7 @@ function getCursorSyncScope(sceneObject) {
8690
8758
  }
8691
8759
 
8692
8760
  function VizPanelSeriesLimit({ data, showAll, seriesLimit, onShowAllSeries }) {
8693
- const styles = ui.useStyles2(getStyles$8);
8761
+ const styles = ui.useStyles2(getStyles$9);
8694
8762
  const seriesCount = data == null ? void 0 : data.series.length;
8695
8763
  if (seriesCount === void 0 || seriesCount < seriesLimit) {
8696
8764
  return null;
@@ -8720,7 +8788,7 @@ function VizPanelSeriesLimit({ data, showAll, seriesLimit, onShowAllSeries }) {
8720
8788
  /* @__PURE__ */ React__default.default.createElement(ui.Button, { variant: "secondary", size: "sm", onClick: onShowAllSeries }, buttonText)
8721
8789
  ));
8722
8790
  }
8723
- const getStyles$8 = (theme) => ({
8791
+ const getStyles$9 = (theme) => ({
8724
8792
  timeSeriesDisclaimer: css.css({
8725
8793
  label: "time-series-disclaimer",
8726
8794
  display: "flex",
@@ -8745,7 +8813,7 @@ function useUniqueId() {
8745
8813
  const LazyLoader = React__default.default.forwardRef(
8746
8814
  ({ children, onLoad, onChange, className, ...rest }, ref) => {
8747
8815
  const id = useUniqueId();
8748
- const { hideEmpty } = ui.useStyles2(getStyles$7);
8816
+ const { hideEmpty } = ui.useStyles2(getStyles$8);
8749
8817
  const [loaded, setLoaded] = React.useState(false);
8750
8818
  const [isInView, setIsInView] = React.useState(false);
8751
8819
  const innerRef = React.useRef(null);
@@ -8774,7 +8842,7 @@ const LazyLoader = React__default.default.forwardRef(
8774
8842
  return /* @__PURE__ */ React__default.default.createElement("div", { id, ref: innerRef, className: `${hideEmpty} ${className}`, ...rest }, !loaded ? i18n.t("grafana-scenes.components.lazy-loader.placeholder", "\xA0") : /* @__PURE__ */ React__default.default.createElement(LazyLoaderInViewContext.Provider, { value: isInView }, children));
8775
8843
  }
8776
8844
  );
8777
- function getStyles$7() {
8845
+ function getStyles$8() {
8778
8846
  return {
8779
8847
  hideEmpty: css.css({
8780
8848
  "&:empty": {
@@ -9584,14 +9652,10 @@ class VizPanel extends SceneObjectBase {
9584
9652
  collapsed
9585
9653
  });
9586
9654
  };
9587
- this.onOptionsChange = (options, replace = false) => {
9655
+ this.onOptionsChange = (optionsUpdate, replace = false, isAfterPluginChange = false) => {
9588
9656
  var _a;
9589
- const { options: prevOptions } = this.state;
9590
- const _renderCounter = ((_a = this.state._renderCounter) != null ? _a : 0) + 1;
9591
- if (replace) {
9592
- return this.setState({ options, _renderCounter });
9593
- }
9594
- options = lodash.mergeWith(lodash.cloneDeep(prevOptions), options, (objValue, srcValue, key, obj) => {
9657
+ const { fieldConfig, options } = this.state;
9658
+ const nextOptions = replace ? optionsUpdate : lodash.mergeWith(lodash.cloneDeep(options), optionsUpdate, (objValue, srcValue, key, obj) => {
9595
9659
  if (lodash.isArray(srcValue)) {
9596
9660
  return srcValue;
9597
9661
  }
@@ -9601,7 +9665,16 @@ class VizPanel extends SceneObjectBase {
9601
9665
  }
9602
9666
  return;
9603
9667
  });
9604
- this.setState({ options, _renderCounter });
9668
+ const withDefaults = data.getPanelOptionsWithDefaults({
9669
+ plugin: this._plugin,
9670
+ currentOptions: nextOptions,
9671
+ currentFieldConfig: fieldConfig,
9672
+ isAfterPluginChange
9673
+ });
9674
+ this.setState({
9675
+ options: withDefaults.options,
9676
+ _renderCounter: ((_a = this.state._renderCounter) != null ? _a : 0) + 1
9677
+ });
9605
9678
  };
9606
9679
  this.onFieldConfigChange = (fieldConfigUpdate, replace) => {
9607
9680
  const { fieldConfig, options } = this.state;
@@ -9823,13 +9896,7 @@ class VizPanel extends SceneObjectBase {
9823
9896
  };
9824
9897
  const updatedOptions = (_b = (_a = this._plugin) == null ? void 0 : _a.onPanelTypeChanged) == null ? void 0 : _b.call(_a, panel, prevPluginId, prevOptions, prevFieldConfig);
9825
9898
  if (updatedOptions && !lodash.isEmpty(updatedOptions)) {
9826
- const { options } = data.getPanelOptionsWithDefaults({
9827
- plugin: this._plugin,
9828
- currentOptions: updatedOptions,
9829
- currentFieldConfig: this.state.fieldConfig,
9830
- isAfterPluginChange
9831
- });
9832
- this.onOptionsChange(options, true);
9899
+ this.onOptionsChange(updatedOptions, true, true);
9833
9900
  }
9834
9901
  }
9835
9902
  clearFieldConfigCache() {
@@ -10141,9 +10208,21 @@ function DataLayerControlSwitch({ layer }) {
10141
10208
  description: layer.state.description,
10142
10209
  error: (_b = (_a = layer.state.data) == null ? void 0 : _a.errors) == null ? void 0 : _b[0].message
10143
10210
  }
10144
- ), /* @__PURE__ */ React__default.default.createElement(ui.InlineSwitch, { id: elementId, value: isEnabled, onChange: () => layer.setState({ isEnabled: !isEnabled }) }));
10211
+ ), /* @__PURE__ */ React__default.default.createElement(
10212
+ ui.InlineSwitch,
10213
+ {
10214
+ className: switchStyle,
10215
+ id: elementId,
10216
+ value: isEnabled,
10217
+ onChange: () => layer.setState({ isEnabled: !isEnabled })
10218
+ }
10219
+ ));
10145
10220
  }
10146
10221
  const containerStyle$1 = css.css({ display: "flex" });
10222
+ const switchStyle = css.css({
10223
+ borderBottomLeftRadius: 0,
10224
+ borderTopLeftRadius: 0
10225
+ });
10147
10226
 
10148
10227
  const standardAnnotationSupport = {
10149
10228
  /**
@@ -11099,11 +11178,13 @@ class CustomVariable extends MultiValueVariable {
11099
11178
  statePaths: ["query"]
11100
11179
  });
11101
11180
  }
11102
- getValueOptions(args) {
11181
+ // We expose this publicly as we also need it outside the variable
11182
+ // The interpolate flag is needed since we don't always want to get the interpolated options
11183
+ transformCsvStringToOptions(str, interpolate = true) {
11103
11184
  var _a;
11104
- const interpolated = sceneGraph.interpolate(this, this.state.query);
11105
- const match = (_a = interpolated.match(/(?:\\,|[^,])+/g)) != null ? _a : [];
11106
- const options = match.map((text) => {
11185
+ str = interpolate ? sceneGraph.interpolate(this, str) : str;
11186
+ const match = (_a = str.match(/(?:\\,|[^,])+/g)) != null ? _a : [];
11187
+ return match.map((text) => {
11107
11188
  var _a2;
11108
11189
  text = text.replace(/\\,/g, ",");
11109
11190
  const textMatch = (_a2 = /^\s*(.+)\s:\s(.+)$/g.exec(text)) != null ? _a2 : [];
@@ -11114,6 +11195,9 @@ class CustomVariable extends MultiValueVariable {
11114
11195
  return { label: text.trim(), value: text.trim() };
11115
11196
  }
11116
11197
  });
11198
+ }
11199
+ getValueOptions(args) {
11200
+ const options = this.transformCsvStringToOptions(this.state.query);
11117
11201
  if (!options.length) {
11118
11202
  this.skipNextValidation = true;
11119
11203
  }
@@ -11124,6 +11208,104 @@ CustomVariable.Component = ({ model }) => {
11124
11208
  return /* @__PURE__ */ React__default.default.createElement(MultiOrSingleValueSelect, { model });
11125
11209
  };
11126
11210
 
11211
+ class SwitchVariable extends SceneObjectBase {
11212
+ constructor(initialState) {
11213
+ super({
11214
+ // TODO: remove this once switch is in the schema @leventebalogh
11215
+ // @ts-expect-error - switch is a valid variable type, but not in the schema yet
11216
+ type: "switch",
11217
+ value: "false",
11218
+ enabledValue: "true",
11219
+ disabledValue: "false",
11220
+ name: "",
11221
+ ...initialState
11222
+ });
11223
+ this._prevValue = "";
11224
+ this._urlSync = new SceneObjectUrlSyncConfig(this, { keys: () => this.getKeys() });
11225
+ }
11226
+ /**
11227
+ * This function is called on when SceneVariableSet is activated or when a dependency changes.
11228
+ */
11229
+ validateAndUpdate() {
11230
+ const newValue = this.getValue();
11231
+ if (this._prevValue !== newValue) {
11232
+ this._prevValue = newValue;
11233
+ this.publishEvent(new SceneVariableValueChangedEvent(this), true);
11234
+ }
11235
+ return rxjs.of({});
11236
+ }
11237
+ setValue(newValue) {
11238
+ if (this.getValue() === newValue) {
11239
+ return;
11240
+ }
11241
+ if ([this.state.enabledValue, this.state.disabledValue].includes(newValue)) {
11242
+ this.setState({ value: newValue });
11243
+ this.publishEvent(new SceneVariableValueChangedEvent(this), true);
11244
+ } else {
11245
+ console.error(
11246
+ `Invalid value for switch variable: "${newValue}". Valid values are: "${this.state.enabledValue}" and "${this.state.disabledValue}".`
11247
+ );
11248
+ }
11249
+ }
11250
+ getValue() {
11251
+ return this.state.value;
11252
+ }
11253
+ isEnabled() {
11254
+ return this.state.value === this.state.enabledValue;
11255
+ }
11256
+ isDisabled() {
11257
+ return this.state.value === this.state.disabledValue;
11258
+ }
11259
+ getKey() {
11260
+ return `var-${this.state.name}`;
11261
+ }
11262
+ getKeys() {
11263
+ if (this.state.skipUrlSync) {
11264
+ return [];
11265
+ }
11266
+ return [this.getKey()];
11267
+ }
11268
+ getUrlState() {
11269
+ if (this.state.skipUrlSync) {
11270
+ return {};
11271
+ }
11272
+ return { [this.getKey()]: this.state.value };
11273
+ }
11274
+ updateFromUrl(values) {
11275
+ const val = values[this.getKey()];
11276
+ if (typeof val === "string") {
11277
+ this.setValue(val);
11278
+ }
11279
+ }
11280
+ }
11281
+ SwitchVariable.Component = SwitchVariableRenderer;
11282
+ function SwitchVariableRenderer({ model }) {
11283
+ const state = model.useState();
11284
+ const styles = ui.useStyles2(getStyles$7);
11285
+ return /* @__PURE__ */ React__default.default.createElement("div", { className: styles.container }, /* @__PURE__ */ React__default.default.createElement(
11286
+ ui.Switch,
11287
+ {
11288
+ value: state.value === state.enabledValue,
11289
+ onChange: (event) => {
11290
+ model.setValue(event.currentTarget.checked ? state.enabledValue : state.disabledValue);
11291
+ }
11292
+ }
11293
+ ));
11294
+ }
11295
+ function getStyles$7(theme) {
11296
+ return {
11297
+ container: css.css({
11298
+ display: "flex",
11299
+ alignItems: "center",
11300
+ padding: theme.spacing(0, 1),
11301
+ height: theme.spacing(theme.components.height.md),
11302
+ borderRadius: theme.shape.radius.default,
11303
+ border: `1px solid ${theme.components.input.borderColor}`,
11304
+ background: theme.colors.background.primary
11305
+ })
11306
+ };
11307
+ }
11308
+
11127
11309
  class DataSourceVariable extends MultiValueVariable {
11128
11310
  constructor(initialState) {
11129
11311
  super({
@@ -15306,10 +15488,12 @@ const sceneUtils = {
15306
15488
  isQueryVariable,
15307
15489
  isTextBoxVariable,
15308
15490
  isGroupByVariable,
15491
+ isSwitchVariable,
15309
15492
  isRepeatCloneOrChildOf,
15310
15493
  buildPathIdFor
15311
15494
  };
15312
15495
 
15496
+ exports.AdHocFiltersComboboxRenderer = AdHocFiltersComboboxRenderer;
15313
15497
  exports.AdHocFiltersVariable = AdHocFiltersVariable;
15314
15498
  exports.ConstantVariable = ConstantVariable;
15315
15499
  exports.ControlsLabel = ControlsLabel;
@@ -15374,11 +15558,13 @@ exports.SceneVariableSet = SceneVariableSet;
15374
15558
  exports.SceneVariableValueChangedEvent = SceneVariableValueChangedEvent;
15375
15559
  exports.ScopesVariable = ScopesVariable;
15376
15560
  exports.SplitLayout = SplitLayout;
15561
+ exports.SwitchVariable = SwitchVariable;
15377
15562
  exports.TestVariable = TestVariable;
15378
15563
  exports.TextBoxVariable = TextBoxVariable;
15379
15564
  exports.UrlSyncContextProvider = UrlSyncContextProvider;
15380
15565
  exports.UrlSyncManager = UrlSyncManager;
15381
15566
  exports.UserActionEvent = UserActionEvent;
15567
+ exports.VariableBackedAdHocFiltersController = VariableBackedAdHocFiltersController;
15382
15568
  exports.VariableDependencyConfig = VariableDependencyConfig;
15383
15569
  exports.VariableValueControl = VariableValueControl;
15384
15570
  exports.VariableValueSelectWrapper = VariableValueSelectWrapper;