@grafana/scenes 6.11.1 → 6.12.0--canary.1122.15063334499.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.
package/README.md CHANGED
@@ -37,6 +37,16 @@ To setup scenes with local Grafana, the following setup is required:
37
37
  1. From Grafana Scenes root directory run `./scripts/dev.sh`. This will compile @grafana/scenes with watch mode enabled and link it to your Grafana.
38
38
  1. From Grafana directory run `yarn install`.
39
39
 
40
+ If you are working on a feature in core, that needs a certain Scenes change:
41
+
42
+ 1. Add the "release" label to your PR. This will create a release for each commit you make and one when the PR is merged.
43
+ 2. Update the `@grafana/scenes` version in `package.json` to use the release you want to try
44
+ 3. Let people review your PR with this change
45
+ 4. Merge your Scenes PR
46
+ 5. Bump the Scenes version in core Grafana
47
+ 6. Sync with your branch
48
+ 7. Merge PR into grafana/grafana
49
+
40
50
  ### Setting up local version of @grafana/scenes with app plugin
41
51
 
42
52
  1. Run `YARN_IGNORE_PATH=1 yarn link` from `packages/scenes` directory.
@@ -0,0 +1,102 @@
1
+ import React, { useMemo } from 'react';
2
+ import { useTheme2, getInputStyles, IconButton, Tooltip, Icon } from '@grafana/ui';
3
+ import { isArray } from 'lodash';
4
+ import { css, cx } from '@emotion/css';
5
+
6
+ function DefaultGroupByCustomIndicatorContainer(props) {
7
+ const { model } = props;
8
+ const theme = useTheme2();
9
+ const styles = getStyles(theme);
10
+ const inputStyles = getInputStyles({ theme, invalid: false });
11
+ const value = useMemo(
12
+ () => isArray(model.state.value) ? model.state.value : model.state.value ? [model.state.value] : [],
13
+ [model.state.value]
14
+ );
15
+ const isRestorable = useMemo(() => {
16
+ return model.checkIfRestorable(value);
17
+ }, [value, model]);
18
+ let buttons = [];
19
+ if (value && value.length) {
20
+ buttons.push(
21
+ /* @__PURE__ */ React.createElement(
22
+ IconButton,
23
+ {
24
+ "aria-label": "clear",
25
+ key: "clear",
26
+ name: "times",
27
+ size: "md",
28
+ className: styles.clearIcon,
29
+ onClick: (e) => {
30
+ model.changeValueTo([], void 0, true);
31
+ }
32
+ }
33
+ )
34
+ );
35
+ }
36
+ if (isRestorable) {
37
+ buttons.push(
38
+ /* @__PURE__ */ React.createElement(
39
+ IconButton,
40
+ {
41
+ onClick: (e) => {
42
+ props.model.restoreDefaultValues();
43
+ },
44
+ onKeyDownCapture: (e) => {
45
+ if (e.key === "Enter") {
46
+ props.model.restoreDefaultValues();
47
+ }
48
+ },
49
+ key: "restore",
50
+ name: "history",
51
+ size: "md",
52
+ className: styles.clearIcon,
53
+ tooltip: "Restore groupby set by this dashboard."
54
+ }
55
+ )
56
+ );
57
+ }
58
+ if (!isRestorable) {
59
+ buttons.push(
60
+ /* @__PURE__ */ React.createElement(
61
+ Tooltip,
62
+ {
63
+ key: "tooltip",
64
+ content: "Applied by default in this dashboard. If edited, it carries over to other dashboards.",
65
+ placement: "bottom"
66
+ },
67
+ /* @__PURE__ */ React.createElement(Icon, { name: "info-circle", size: "md" })
68
+ )
69
+ );
70
+ }
71
+ return /* @__PURE__ */ React.createElement(
72
+ "div",
73
+ {
74
+ onMouseDown: (e) => {
75
+ e.preventDefault();
76
+ e.stopPropagation();
77
+ },
78
+ className: cx(
79
+ inputStyles.suffix,
80
+ css({
81
+ position: "relative"
82
+ })
83
+ )
84
+ },
85
+ buttons
86
+ );
87
+ }
88
+ const getStyles = (theme) => ({
89
+ clearIcon: css({
90
+ color: theme.colors.action.disabledText,
91
+ cursor: "pointer",
92
+ "&:hover:before": {
93
+ backgroundColor: "transparent"
94
+ },
95
+ "&:hover": {
96
+ color: theme.colors.text.primary
97
+ }
98
+ })
99
+ });
100
+
101
+ export { DefaultGroupByCustomIndicatorContainer };
102
+ //# sourceMappingURL=DefaultGroupByCustomIndicatorContainer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"DefaultGroupByCustomIndicatorContainer.js","sources":["../../../../src/variables/groupby/DefaultGroupByCustomIndicatorContainer.tsx"],"sourcesContent":["import React, { useMemo } from 'react';\nimport { Icon, IconButton, Tooltip, getInputStyles, useTheme2 } from '@grafana/ui';\nimport { GroupByVariable } from './GroupByVariable';\nimport { isArray } from 'lodash';\nimport { css, cx } from '@emotion/css';\nimport { GrafanaTheme2 } from '@grafana/data';\nimport { VariableValueSingle } from '../types';\n\ntype DefaultGroupByCustomIndicatorProps = {\n model: GroupByVariable;\n};\n\nexport function DefaultGroupByCustomIndicatorContainer(props: DefaultGroupByCustomIndicatorProps) {\n const { model } = props;\n const theme = useTheme2();\n const styles = getStyles(theme);\n const inputStyles = getInputStyles({ theme, invalid: false });\n const value = useMemo<VariableValueSingle[]>(\n () => (isArray(model.state.value) ? model.state.value : model.state.value ? [model.state.value] : []),\n [model.state.value]\n );\n\n const isRestorable = useMemo<boolean>(() => {\n return model.checkIfRestorable(value);\n }, [value, model]);\n\n let buttons: React.ReactNode[] = [];\n\n if (value && value.length) {\n buttons.push(\n <IconButton\n aria-label=\"clear\"\n key=\"clear\"\n name=\"times\"\n size=\"md\"\n className={styles.clearIcon}\n onClick={(e) => {\n model.changeValueTo([], undefined, true);\n }}\n />\n );\n }\n\n if (isRestorable) {\n buttons.push(\n <IconButton\n onClick={(e) => {\n props.model.restoreDefaultValues();\n }}\n onKeyDownCapture={(e) => {\n if (e.key === 'Enter') {\n props.model.restoreDefaultValues();\n }\n }}\n key=\"restore\"\n name=\"history\"\n size=\"md\"\n className={styles.clearIcon}\n tooltip=\"Restore groupby set by this dashboard.\"\n />\n );\n }\n\n if (!isRestorable) {\n buttons.push(\n <Tooltip\n key=\"tooltip\"\n content=\"Applied by default in this dashboard. If edited, it carries over to other dashboards.\"\n placement=\"bottom\"\n >\n <Icon name=\"info-circle\" size=\"md\" />\n </Tooltip>\n );\n }\n\n return (\n <div\n onMouseDown={(e) => {\n e.preventDefault();\n e.stopPropagation();\n }}\n className={cx(\n inputStyles.suffix,\n css({\n position: 'relative',\n })\n )}\n >\n {buttons}\n </div>\n );\n}\n\nconst getStyles = (theme: GrafanaTheme2) => ({\n clearIcon: css({\n color: theme.colors.action.disabledText,\n cursor: 'pointer',\n '&:hover:before': {\n backgroundColor: 'transparent',\n },\n '&:hover': {\n color: theme.colors.text.primary,\n },\n }),\n});\n"],"names":[],"mappings":"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"}
@@ -5,13 +5,14 @@ import { MultiValueVariable } from '../variants/MultiValueVariable.js';
5
5
  import { lastValueFrom, map, of, from, mergeMap, tap, take } from 'rxjs';
6
6
  import { getDataSource } from '../../utils/getDataSource.js';
7
7
  import { MultiSelect, Select } from '@grafana/ui';
8
- import { isArray } from 'lodash';
8
+ import { isArray, isEqual } from 'lodash';
9
9
  import { handleOptionGroups, dataFromResponse, getQueriesForVariables, responseHasError } from '../utils.js';
10
10
  import { OptionWithCheckbox } from '../components/VariableValueSelect.js';
11
11
  import { GroupByVariableUrlSyncHandler } from './GroupByVariableUrlSyncHandler.js';
12
12
  import { getOptionSearcher } from '../components/getOptionSearcher.js';
13
13
  import { getEnrichedFiltersRequest } from '../getEnrichedFiltersRequest.js';
14
14
  import { wrapInSafeSerializableSceneObject } from '../../utils/wrapInSafeSerializableSceneObject.js';
15
+ import { DefaultGroupByCustomIndicatorContainer } from './DefaultGroupByCustomIndicatorContainer.js';
15
16
 
16
17
  class GroupByVariable extends MultiValueVariable {
17
18
  constructor(initialState) {
@@ -31,6 +32,15 @@ class GroupByVariable extends MultiValueVariable {
31
32
  });
32
33
  this.isLazy = true;
33
34
  this._urlSync = new GroupByVariableUrlSyncHandler(this);
35
+ this._activationHandler = () => {
36
+ if (this.state.defaultValues && (isArray(this.state.value) && !this.state.value.length || !this.state.value)) {
37
+ this.setState({
38
+ value: this.state.defaultValues.value,
39
+ text: this.state.defaultValues.text
40
+ });
41
+ return;
42
+ }
43
+ };
34
44
  /**
35
45
  * Get possible keys given current filters. Do not call from plugins directly
36
46
  */
@@ -75,6 +85,7 @@ class GroupByVariable extends MultiValueVariable {
75
85
  return () => allActiveGroupByVariables.delete(this);
76
86
  });
77
87
  }
88
+ this.addActivationHandler(this._activationHandler);
78
89
  }
79
90
  validateAndUpdate() {
80
91
  return this.getValueOptions({}).pipe(
@@ -133,6 +144,21 @@ class GroupByVariable extends MultiValueVariable {
133
144
  })
134
145
  );
135
146
  }
147
+ checkIfRestorable(values) {
148
+ var _a, _b, _c, _d;
149
+ const originalValues = 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] : [];
150
+ const vals = isArray(values) ? values : [values];
151
+ if (vals.length !== originalValues.length) {
152
+ return true;
153
+ }
154
+ return !isEqual(vals, originalValues);
155
+ }
156
+ restoreDefaultValues() {
157
+ if (!this.state.defaultValues) {
158
+ return;
159
+ }
160
+ this.changeValueTo(this.state.defaultValues.value, this.state.defaultValues.text, true);
161
+ }
136
162
  /**
137
163
  * Allows clearing the value of the variable to an empty value. Overrides default behavior of a MultiValueVariable
138
164
  */
@@ -151,7 +177,8 @@ function GroupByVariableRenderer({ model }) {
151
177
  noValueOnClear,
152
178
  options,
153
179
  includeAll,
154
- allowCustomValue = true
180
+ allowCustomValue = true,
181
+ defaultValues
155
182
  } = model.useState();
156
183
  const values = useMemo(() => {
157
184
  const arrayValue = isArray(value) ? value : [value];
@@ -169,6 +196,7 @@ function GroupByVariableRenderer({ model }) {
169
196
  const [inputValue, setInputValue] = useState("");
170
197
  const [uncommittedValue, setUncommittedValue] = useState(values);
171
198
  const optionSearcher = useMemo(() => getOptionSearcher(options, includeAll), [options, includeAll]);
199
+ const hasDefaultValues = defaultValues !== void 0;
172
200
  useEffect(() => {
173
201
  setUncommittedValue(values);
174
202
  }, [values]);
@@ -196,7 +224,7 @@ function GroupByVariableRenderer({ model }) {
196
224
  "aria-label": "Group by selector",
197
225
  "data-testid": `GroupBySelect-${key}`,
198
226
  id: key,
199
- placeholder: "Select value",
227
+ placeholder: "Group by label",
200
228
  width: "auto",
201
229
  allowCustomValue,
202
230
  inputValue,
@@ -212,7 +240,12 @@ function GroupByVariableRenderer({ model }) {
212
240
  isClearable: true,
213
241
  hideSelectedOptions: false,
214
242
  isLoading: isFetchingOptions,
215
- components: { Option: OptionWithCheckbox },
243
+ components: {
244
+ Option: OptionWithCheckbox,
245
+ ...hasDefaultValues ? {
246
+ IndicatorsContainer: () => /* @__PURE__ */ React.createElement(DefaultGroupByCustomIndicatorContainer, { model })
247
+ } : {}
248
+ },
216
249
  onInputChange,
217
250
  onBlur: () => {
218
251
  model.changeValueTo(
@@ -243,7 +276,7 @@ function GroupByVariableRenderer({ model }) {
243
276
  "aria-label": "Group by selector",
244
277
  "data-testid": `GroupBySelect-${key}`,
245
278
  id: key,
246
- placeholder: "Select value",
279
+ placeholder: "Group by label",
247
280
  width: "auto",
248
281
  inputValue,
249
282
  value: uncommittedValue && uncommittedValue.length > 0 ? uncommittedValue : null,
@@ -1 +1 @@
1
- {"version":3,"file":"GroupByVariable.js","sources":["../../../../src/variables/groupby/GroupByVariable.tsx"],"sourcesContent":["import React, { useEffect, useMemo, useState } from 'react';\nimport { AdHocVariableFilter, DataSourceApi, GetTagResponse, MetricFindValue, SelectableValue } from '@grafana/data';\nimport { allActiveGroupByVariables } from './findActiveGroupByVariablesByUid';\nimport { DataSourceRef, VariableType } from '@grafana/schema';\nimport { SceneComponentProps, ControlsLayout, SceneObjectUrlSyncHandler } from '../../core/types';\nimport { sceneGraph } from '../../core/sceneGraph';\nimport { ValidateAndUpdateResult, VariableValueOption, VariableValueSingle } from '../types';\nimport { MultiValueVariable, MultiValueVariableState, VariableGetOptionsArgs } from '../variants/MultiValueVariable';\nimport { from, lastValueFrom, map, mergeMap, Observable, of, take, tap } from 'rxjs';\nimport { getDataSource } from '../../utils/getDataSource';\nimport { InputActionMeta, MultiSelect, Select } from '@grafana/ui';\nimport { isArray } from 'lodash';\nimport { dataFromResponse, getQueriesForVariables, handleOptionGroups, responseHasError } from '../utils';\nimport { OptionWithCheckbox } from '../components/VariableValueSelect';\nimport { GroupByVariableUrlSyncHandler } from './GroupByVariableUrlSyncHandler';\nimport { getOptionSearcher } from '../components/getOptionSearcher';\nimport { getEnrichedFiltersRequest } from '../getEnrichedFiltersRequest';\nimport { wrapInSafeSerializableSceneObject } from '../../utils/wrapInSafeSerializableSceneObject';\nimport { SceneScopesBridge } from '../../core/SceneScopesBridge';\n\nexport interface GroupByVariableState extends MultiValueVariableState {\n /** Defaults to \"Group\" */\n name: string;\n /** The visible keys to group on */\n // TODO review this type and name (naming is hard)\n defaultOptions?: MetricFindValue[];\n /** Base filters to always apply when looking up keys */\n baseFilters?: AdHocVariableFilter[];\n /** Datasource to use for getTagKeys and also controls which scene queries the group by should apply to */\n datasource: DataSourceRef | null;\n /** Controls if the group by can be changed */\n readOnly?: boolean;\n /**\n * @experimental\n * Controls the layout and design of the label.\n * Vertical layout does not yet support operator selector.\n */\n layout?: ControlsLayout;\n /**\n * Defaults to same-datasource which means group by will automatically be applied to all queries with the same data source as this GroupBySet.\n * In manual mode no queries are re-run on changes, and you have to manually apply the filter to whatever queries you want.\n */\n applyMode?: 'auto' | 'manual';\n /**\n * Filter out the keys that do not match the regex.\n */\n tagKeyRegexFilter?: RegExp;\n /**\n * Extension hook for customizing the key lookup.\n * Return replace: true if you want to override the default lookup\n * Return replace: false if you want to combine the results with the default lookup\n */\n getTagKeysProvider?: getTagKeysProvider;\n}\n\nexport type getTagKeysProvider = (\n set: GroupByVariable,\n currentKey: string | null\n) => Promise<{ replace?: boolean; values: MetricFindValue[] | GetTagResponse }>;\n\nexport class GroupByVariable extends MultiValueVariable<GroupByVariableState> {\n static Component = GroupByVariableRenderer;\n isLazy = true;\n\n protected _urlSync: SceneObjectUrlSyncHandler = new GroupByVariableUrlSyncHandler(this);\n\n private _scopesBridge: SceneScopesBridge | undefined;\n\n public validateAndUpdate(): Observable<ValidateAndUpdateResult> {\n return this.getValueOptions({}).pipe(\n map((options) => {\n this._updateValueGivenNewOptions(options);\n return {};\n })\n );\n }\n\n private _updateValueGivenNewOptions(options: VariableValueOption[]) {\n const { value: currentValue, text: currentText } = this.state;\n\n const stateUpdate: Partial<MultiValueVariableState> = {\n options,\n loading: false,\n value: currentValue ?? [],\n text: currentText ?? [],\n };\n\n this.setState(stateUpdate);\n }\n\n public getValueOptions(args: VariableGetOptionsArgs): Observable<VariableValueOption[]> {\n // When default dimensions are provided, return the static list\n if (this.state.defaultOptions) {\n return of(\n this.state.defaultOptions.map((o) => ({\n label: o.text,\n value: String(o.value),\n group: o.group,\n }))\n );\n }\n\n this.setState({ loading: true, error: null });\n\n return from(\n getDataSource(this.state.datasource, {\n __sceneObject: wrapInSafeSerializableSceneObject(this),\n })\n ).pipe(\n mergeMap((ds) => {\n return from(this._getKeys(ds)).pipe(\n tap((response) => {\n if (responseHasError(response)) {\n this.setState({ error: response.error.message });\n }\n }),\n map((response) => dataFromResponse(response)),\n take(1),\n mergeMap((data) => {\n const a: VariableValueOption[] = data.map((i) => {\n return {\n label: i.text,\n value: i.value ? String(i.value) : i.text,\n group: i.group,\n };\n });\n return of(a);\n })\n );\n })\n );\n }\n\n public constructor(initialState: Partial<GroupByVariableState>) {\n super({\n isMulti: true,\n name: '',\n value: [],\n text: [],\n options: [],\n datasource: null,\n baseFilters: [],\n applyMode: 'auto',\n layout: 'horizontal',\n type: 'groupby' as VariableType,\n ...initialState,\n noValueOnClear: true,\n });\n\n if (this.state.applyMode === 'auto') {\n this.addActivationHandler(() => {\n allActiveGroupByVariables.add(this);\n\n return () => allActiveGroupByVariables.delete(this);\n });\n }\n }\n\n /**\n * Get possible keys given current filters. Do not call from plugins directly\n */\n public _getKeys = async (ds: DataSourceApi) => {\n // TODO: provide current dimensions?\n const override = await this.state.getTagKeysProvider?.(this, null);\n\n if (override && override.replace) {\n return override.values;\n }\n\n if (this.state.defaultOptions) {\n return this.state.defaultOptions.concat(dataFromResponse(override?.values ?? []));\n }\n\n if (!ds.getTagKeys) {\n return [];\n }\n\n const queries = getQueriesForVariables(this);\n\n const otherFilters = this.state.baseFilters || [];\n const timeRange = sceneGraph.getTimeRange(this).state.value;\n const response = await ds.getTagKeys({\n filters: otherFilters,\n queries,\n timeRange,\n scopes: this._scopesBridge?.getValue(),\n ...getEnrichedFiltersRequest(this),\n });\n if (responseHasError(response)) {\n this.setState({ error: response.error.message });\n }\n\n let keys = dataFromResponse(response);\n if (override) {\n keys = keys.concat(dataFromResponse(override.values));\n }\n\n const tagKeyRegexFilter = this.state.tagKeyRegexFilter;\n if (tagKeyRegexFilter) {\n keys = keys.filter((f) => f.text.match(tagKeyRegexFilter));\n }\n\n return keys;\n };\n\n /**\n * Allows clearing the value of the variable to an empty value. Overrides default behavior of a MultiValueVariable\n */\n public getDefaultMultiState(options: VariableValueOption[]): { value: VariableValueSingle[]; text: string[] } {\n return { value: [], text: [] };\n }\n}\n\nexport function GroupByVariableRenderer({ model }: SceneComponentProps<GroupByVariable>) {\n const {\n value,\n text,\n key,\n isMulti = true,\n maxVisibleValues,\n noValueOnClear,\n options,\n includeAll,\n allowCustomValue = true,\n } = model.useState();\n\n const values = useMemo<Array<SelectableValue<VariableValueSingle>>>(() => {\n const arrayValue = isArray(value) ? value : [value];\n const arrayText = isArray(text) ? text : [text];\n\n return arrayValue.map((value, idx) => ({\n value,\n label: String(arrayText[idx] ?? value),\n }));\n }, [value, text]);\n\n const [isFetchingOptions, setIsFetchingOptions] = useState(false);\n const [isOptionsOpen, setIsOptionsOpen] = useState(false);\n const [inputValue, setInputValue] = useState('');\n\n // To not trigger queries on every selection we store this state locally here and only update the variable onBlur\n const [uncommittedValue, setUncommittedValue] = useState(values);\n\n const optionSearcher = useMemo(() => getOptionSearcher(options, includeAll), [options, includeAll]);\n\n // Detect value changes outside\n useEffect(() => {\n setUncommittedValue(values);\n }, [values]);\n\n const onInputChange = (value: string, { action }: InputActionMeta) => {\n if (action === 'input-change') {\n setInputValue(value);\n if (model.onSearchChange) {\n model.onSearchChange!(value);\n }\n return value;\n }\n\n if (action === 'input-blur') {\n setInputValue('');\n return '';\n }\n\n return inputValue;\n };\n\n const filteredOptions = useMemo(\n () => handleOptionGroups(optionSearcher(inputValue).map(toSelectableValue)),\n [optionSearcher, inputValue]\n );\n\n return isMulti ? (\n <MultiSelect<VariableValueSingle>\n aria-label=\"Group by selector\"\n data-testid={`GroupBySelect-${key}`}\n id={key}\n placeholder={'Select value'}\n width=\"auto\"\n allowCustomValue={allowCustomValue}\n inputValue={inputValue}\n value={uncommittedValue}\n noMultiValueWrap={true}\n maxVisibleValues={maxVisibleValues ?? 5}\n tabSelectsValue={false}\n virtualized\n options={filteredOptions}\n filterOption={filterNoOp}\n closeMenuOnSelect={false}\n isOpen={isOptionsOpen}\n isClearable={true}\n hideSelectedOptions={false}\n isLoading={isFetchingOptions}\n components={{ Option: OptionWithCheckbox }}\n onInputChange={onInputChange}\n onBlur={() => {\n model.changeValueTo(\n uncommittedValue.map((x) => x.value!),\n uncommittedValue.map((x) => x.label!),\n true\n );\n }}\n onChange={(newValue, action) => {\n if (action.action === 'clear' && noValueOnClear) {\n model.changeValueTo([], undefined, true);\n }\n setUncommittedValue(newValue);\n }}\n onOpenMenu={async () => {\n setIsFetchingOptions(true);\n await lastValueFrom(model.validateAndUpdate());\n setIsFetchingOptions(false);\n setIsOptionsOpen(true);\n }}\n onCloseMenu={() => {\n setIsOptionsOpen(false);\n }}\n />\n ) : (\n <Select\n aria-label=\"Group by selector\"\n data-testid={`GroupBySelect-${key}`}\n id={key}\n placeholder={'Select value'}\n width=\"auto\"\n inputValue={inputValue}\n value={uncommittedValue && uncommittedValue.length > 0 ? uncommittedValue : null}\n allowCustomValue={allowCustomValue}\n noMultiValueWrap={true}\n maxVisibleValues={maxVisibleValues ?? 5}\n tabSelectsValue={false}\n virtualized\n options={filteredOptions}\n filterOption={filterNoOp}\n closeMenuOnSelect={true}\n isOpen={isOptionsOpen}\n isClearable={true}\n hideSelectedOptions={false}\n noValueOnClear={true}\n isLoading={isFetchingOptions}\n onInputChange={onInputChange}\n onChange={(newValue, action) => {\n if (action.action === 'clear') {\n setUncommittedValue([]);\n if (noValueOnClear) {\n model.changeValueTo([]);\n }\n return;\n }\n if (newValue?.value) {\n setUncommittedValue([newValue]);\n model.changeValueTo([newValue.value], newValue.label ? [newValue.label] : undefined);\n }\n }}\n onOpenMenu={async () => {\n setIsFetchingOptions(true);\n await lastValueFrom(model.validateAndUpdate());\n setIsFetchingOptions(false);\n setIsOptionsOpen(true);\n }}\n onCloseMenu={() => {\n setIsOptionsOpen(false);\n }}\n />\n );\n}\n\nconst filterNoOp = () => true;\n\nfunction toSelectableValue(input: VariableValueOption): SelectableValue<VariableValueSingle> {\n const { label, value, group } = input;\n const result: SelectableValue<VariableValueSingle> = {\n label,\n value,\n };\n\n if (group) {\n result.group = group;\n }\n\n return result;\n}\n"],"names":["value"],"mappings":"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"}
1
+ {"version":3,"file":"GroupByVariable.js","sources":["../../../../src/variables/groupby/GroupByVariable.tsx"],"sourcesContent":["import React, { useEffect, useMemo, useState } from 'react';\nimport { AdHocVariableFilter, DataSourceApi, GetTagResponse, MetricFindValue, SelectableValue } from '@grafana/data';\nimport { allActiveGroupByVariables } from './findActiveGroupByVariablesByUid';\nimport { DataSourceRef, VariableType } from '@grafana/schema';\nimport { SceneComponentProps, ControlsLayout, SceneObjectUrlSyncHandler } from '../../core/types';\nimport { sceneGraph } from '../../core/sceneGraph';\nimport { ValidateAndUpdateResult, VariableValue, VariableValueOption, VariableValueSingle } from '../types';\nimport { MultiValueVariable, MultiValueVariableState, VariableGetOptionsArgs } from '../variants/MultiValueVariable';\nimport { from, lastValueFrom, map, mergeMap, Observable, of, take, tap } from 'rxjs';\nimport { getDataSource } from '../../utils/getDataSource';\nimport { InputActionMeta, MultiSelect, Select } from '@grafana/ui';\nimport { isArray, isEqual } from 'lodash';\nimport { dataFromResponse, getQueriesForVariables, handleOptionGroups, responseHasError } from '../utils';\nimport { OptionWithCheckbox } from '../components/VariableValueSelect';\nimport { GroupByVariableUrlSyncHandler } from './GroupByVariableUrlSyncHandler';\nimport { getOptionSearcher } from '../components/getOptionSearcher';\nimport { getEnrichedFiltersRequest } from '../getEnrichedFiltersRequest';\nimport { wrapInSafeSerializableSceneObject } from '../../utils/wrapInSafeSerializableSceneObject';\nimport { SceneScopesBridge } from '../../core/SceneScopesBridge';\nimport { DefaultGroupByCustomIndicatorContainer } from './DefaultGroupByCustomIndicatorContainer';\n\nexport interface GroupByVariableState extends MultiValueVariableState {\n /** Defaults to \"Group\" */\n name: string;\n /** The visible keys to group on */\n // TODO review this type and name (naming is hard)\n defaultOptions?: MetricFindValue[];\n /** Base filters to always apply when looking up keys */\n baseFilters?: AdHocVariableFilter[];\n /** Datasource to use for getTagKeys and also controls which scene queries the group by should apply to */\n datasource: DataSourceRef | null;\n defaultValues?: { text: VariableValue; value: VariableValue };\n /** Controls if the group by can be changed */\n readOnly?: boolean;\n /**\n * @experimental\n * Controls the layout and design of the label.\n * Vertical layout does not yet support operator selector.\n */\n layout?: ControlsLayout;\n /**\n * Defaults to same-datasource which means group by will automatically be applied to all queries with the same data source as this GroupBySet.\n * In manual mode no queries are re-run on changes, and you have to manually apply the filter to whatever queries you want.\n */\n applyMode?: 'auto' | 'manual';\n /**\n * Filter out the keys that do not match the regex.\n */\n tagKeyRegexFilter?: RegExp;\n /**\n * Extension hook for customizing the key lookup.\n * Return replace: true if you want to override the default lookup\n * Return replace: false if you want to combine the results with the default lookup\n */\n getTagKeysProvider?: getTagKeysProvider;\n}\n\nexport type getTagKeysProvider = (\n set: GroupByVariable,\n currentKey: string | null\n) => Promise<{ replace?: boolean; values: MetricFindValue[] | GetTagResponse }>;\n\nexport class GroupByVariable extends MultiValueVariable<GroupByVariableState> {\n static Component = GroupByVariableRenderer;\n isLazy = true;\n\n protected _urlSync: SceneObjectUrlSyncHandler = new GroupByVariableUrlSyncHandler(this);\n\n private _scopesBridge: SceneScopesBridge | undefined;\n\n public validateAndUpdate(): Observable<ValidateAndUpdateResult> {\n return this.getValueOptions({}).pipe(\n map((options) => {\n this._updateValueGivenNewOptions(options);\n return {};\n })\n );\n }\n\n private _updateValueGivenNewOptions(options: VariableValueOption[]) {\n const { value: currentValue, text: currentText } = this.state;\n\n const stateUpdate: Partial<MultiValueVariableState> = {\n options,\n loading: false,\n value: currentValue ?? [],\n text: currentText ?? [],\n };\n\n this.setState(stateUpdate);\n }\n\n public getValueOptions(args: VariableGetOptionsArgs): Observable<VariableValueOption[]> {\n // When default dimensions are provided, return the static list\n if (this.state.defaultOptions) {\n return of(\n this.state.defaultOptions.map((o) => ({\n label: o.text,\n value: String(o.value),\n group: o.group,\n }))\n );\n }\n\n this.setState({ loading: true, error: null });\n\n return from(\n getDataSource(this.state.datasource, {\n __sceneObject: wrapInSafeSerializableSceneObject(this),\n })\n ).pipe(\n mergeMap((ds) => {\n return from(this._getKeys(ds)).pipe(\n tap((response) => {\n if (responseHasError(response)) {\n this.setState({ error: response.error.message });\n }\n }),\n map((response) => dataFromResponse(response)),\n take(1),\n mergeMap((data) => {\n const a: VariableValueOption[] = data.map((i) => {\n return {\n label: i.text,\n value: i.value ? String(i.value) : i.text,\n group: i.group,\n };\n });\n return of(a);\n })\n );\n })\n );\n }\n\n public constructor(initialState: Partial<GroupByVariableState>) {\n super({\n isMulti: true,\n name: '',\n value: [],\n text: [],\n options: [],\n datasource: null,\n baseFilters: [],\n applyMode: 'auto',\n layout: 'horizontal',\n type: 'groupby' as VariableType,\n ...initialState,\n noValueOnClear: true,\n });\n\n if (this.state.applyMode === 'auto') {\n this.addActivationHandler(() => {\n allActiveGroupByVariables.add(this);\n\n return () => allActiveGroupByVariables.delete(this);\n });\n }\n\n this.addActivationHandler(this._activationHandler);\n }\n\n private _activationHandler = () => {\n if (this.state.defaultValues && ((isArray(this.state.value) && !this.state.value.length) || !this.state.value)) {\n this.setState({\n value: this.state.defaultValues.value,\n text: this.state.defaultValues.text,\n });\n return;\n }\n };\n\n public checkIfRestorable(values: VariableValue) {\n const originalValues = isArray(this.state.defaultValues?.value)\n ? this.state.defaultValues?.value\n : this.state.defaultValues?.value\n ? [this.state.defaultValues?.value]\n : [];\n const vals = isArray(values) ? values : [values];\n\n if (vals.length !== originalValues.length) {\n return true;\n }\n\n return !isEqual(vals, originalValues);\n }\n\n public restoreDefaultValues() {\n if (!this.state.defaultValues) {\n return;\n }\n\n this.changeValueTo(this.state.defaultValues.value, this.state.defaultValues.text, true);\n }\n\n /**\n * Get possible keys given current filters. Do not call from plugins directly\n */\n public _getKeys = async (ds: DataSourceApi) => {\n // TODO: provide current dimensions?\n const override = await this.state.getTagKeysProvider?.(this, null);\n\n if (override && override.replace) {\n return override.values;\n }\n\n if (this.state.defaultOptions) {\n return this.state.defaultOptions.concat(dataFromResponse(override?.values ?? []));\n }\n\n if (!ds.getTagKeys) {\n return [];\n }\n\n const queries = getQueriesForVariables(this);\n\n const otherFilters = this.state.baseFilters || [];\n const timeRange = sceneGraph.getTimeRange(this).state.value;\n const response = await ds.getTagKeys({\n filters: otherFilters,\n queries,\n timeRange,\n scopes: this._scopesBridge?.getValue(),\n ...getEnrichedFiltersRequest(this),\n });\n if (responseHasError(response)) {\n this.setState({ error: response.error.message });\n }\n\n let keys = dataFromResponse(response);\n if (override) {\n keys = keys.concat(dataFromResponse(override.values));\n }\n\n const tagKeyRegexFilter = this.state.tagKeyRegexFilter;\n if (tagKeyRegexFilter) {\n keys = keys.filter((f) => f.text.match(tagKeyRegexFilter));\n }\n\n return keys;\n };\n\n /**\n * Allows clearing the value of the variable to an empty value. Overrides default behavior of a MultiValueVariable\n */\n public getDefaultMultiState(options: VariableValueOption[]): { value: VariableValueSingle[]; text: string[] } {\n return { value: [], text: [] };\n }\n}\n\nexport function GroupByVariableRenderer({ model }: SceneComponentProps<GroupByVariable>) {\n const {\n value,\n text,\n key,\n isMulti = true,\n maxVisibleValues,\n noValueOnClear,\n options,\n includeAll,\n allowCustomValue = true,\n defaultValues,\n } = model.useState();\n\n const values = useMemo<Array<SelectableValue<VariableValueSingle>>>(() => {\n const arrayValue = isArray(value) ? value : [value];\n const arrayText = isArray(text) ? text : [text];\n\n return arrayValue.map((value, idx) => ({\n value,\n label: String(arrayText[idx] ?? value),\n }));\n }, [value, text]);\n\n const [isFetchingOptions, setIsFetchingOptions] = useState(false);\n const [isOptionsOpen, setIsOptionsOpen] = useState(false);\n const [inputValue, setInputValue] = useState('');\n\n // To not trigger queries on every selection we store this state locally here and only update the variable onBlur\n const [uncommittedValue, setUncommittedValue] = useState(values);\n\n const optionSearcher = useMemo(() => getOptionSearcher(options, includeAll), [options, includeAll]);\n\n const hasDefaultValues = defaultValues !== undefined;\n\n // Detect value changes outside\n useEffect(() => {\n setUncommittedValue(values);\n }, [values]);\n\n const onInputChange = (value: string, { action }: InputActionMeta) => {\n if (action === 'input-change') {\n setInputValue(value);\n if (model.onSearchChange) {\n model.onSearchChange!(value);\n }\n return value;\n }\n\n if (action === 'input-blur') {\n setInputValue('');\n return '';\n }\n\n return inputValue;\n };\n\n const filteredOptions = useMemo(\n () => handleOptionGroups(optionSearcher(inputValue).map(toSelectableValue)),\n [optionSearcher, inputValue]\n );\n\n return isMulti ? (\n <MultiSelect<VariableValueSingle>\n aria-label=\"Group by selector\"\n data-testid={`GroupBySelect-${key}`}\n id={key}\n placeholder={'Group by label'}\n width=\"auto\"\n allowCustomValue={allowCustomValue}\n inputValue={inputValue}\n value={uncommittedValue}\n noMultiValueWrap={true}\n maxVisibleValues={maxVisibleValues ?? 5}\n tabSelectsValue={false}\n virtualized\n options={filteredOptions}\n filterOption={filterNoOp}\n closeMenuOnSelect={false}\n isOpen={isOptionsOpen}\n isClearable={true}\n hideSelectedOptions={false}\n isLoading={isFetchingOptions}\n components={{\n Option: OptionWithCheckbox,\n ...(hasDefaultValues\n ? {\n IndicatorsContainer: () => <DefaultGroupByCustomIndicatorContainer model={model} />,\n }\n : {}),\n }}\n onInputChange={onInputChange}\n onBlur={() => {\n model.changeValueTo(\n uncommittedValue.map((x) => x.value!),\n uncommittedValue.map((x) => x.label!),\n true\n );\n }}\n onChange={(newValue, action) => {\n if (action.action === 'clear' && noValueOnClear) {\n model.changeValueTo([], undefined, true);\n }\n setUncommittedValue(newValue);\n }}\n onOpenMenu={async () => {\n setIsFetchingOptions(true);\n await lastValueFrom(model.validateAndUpdate());\n setIsFetchingOptions(false);\n setIsOptionsOpen(true);\n }}\n onCloseMenu={() => {\n setIsOptionsOpen(false);\n }}\n />\n ) : (\n <Select\n aria-label=\"Group by selector\"\n data-testid={`GroupBySelect-${key}`}\n id={key}\n placeholder={'Group by label'}\n width=\"auto\"\n inputValue={inputValue}\n value={uncommittedValue && uncommittedValue.length > 0 ? uncommittedValue : null}\n allowCustomValue={allowCustomValue}\n noMultiValueWrap={true}\n maxVisibleValues={maxVisibleValues ?? 5}\n tabSelectsValue={false}\n virtualized\n options={filteredOptions}\n filterOption={filterNoOp}\n closeMenuOnSelect={true}\n isOpen={isOptionsOpen}\n isClearable={true}\n hideSelectedOptions={false}\n noValueOnClear={true}\n isLoading={isFetchingOptions}\n onInputChange={onInputChange}\n onChange={(newValue, action) => {\n if (action.action === 'clear') {\n setUncommittedValue([]);\n if (noValueOnClear) {\n model.changeValueTo([]);\n }\n return;\n }\n if (newValue?.value) {\n setUncommittedValue([newValue]);\n model.changeValueTo([newValue.value], newValue.label ? [newValue.label] : undefined);\n }\n }}\n onOpenMenu={async () => {\n setIsFetchingOptions(true);\n await lastValueFrom(model.validateAndUpdate());\n setIsFetchingOptions(false);\n setIsOptionsOpen(true);\n }}\n onCloseMenu={() => {\n setIsOptionsOpen(false);\n }}\n />\n );\n}\n\nconst filterNoOp = () => true;\n\nfunction toSelectableValue(input: VariableValueOption): SelectableValue<VariableValueSingle> {\n const { label, value, group } = input;\n const result: SelectableValue<VariableValueSingle> = {\n label,\n value,\n };\n\n if (group) {\n result.group = group;\n }\n\n return result;\n}\n"],"names":["value"],"mappings":"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"}
@@ -1,4 +1,5 @@
1
- import { toUrlCommaDelimitedString, unescapeUrlDelimiters } from '../utils.js';
1
+ import { toUrlCommaDelimitedString, escapeUrlPipeDelimiters, unescapeUrlDelimiters } from '../utils.js';
2
+ import { isEqual } from 'lodash';
2
3
 
3
4
  class GroupByVariableUrlSyncHandler {
4
5
  constructor(_sceneObject) {
@@ -15,18 +16,34 @@ class GroupByVariableUrlSyncHandler {
15
16
  return [this.getKey()];
16
17
  }
17
18
  getUrlState() {
19
+ var _a;
18
20
  if (this._sceneObject.state.skipUrlSync) {
19
21
  return {};
20
22
  }
21
- return { [this.getKey()]: toUrlValues(this._sceneObject.state.value, this._sceneObject.state.text) };
23
+ return {
24
+ [this.getKey()]: toUrlValues(
25
+ this._sceneObject.state.value,
26
+ this._sceneObject.state.text,
27
+ (_a = this._sceneObject.state.defaultValues) == null ? void 0 : _a.value
28
+ )
29
+ };
22
30
  }
23
31
  updateFromUrl(values) {
32
+ var _a, _b;
24
33
  let urlValue = values[this.getKey()];
25
34
  if (urlValue != null) {
26
35
  if (!this._sceneObject.isActive) {
27
36
  this._sceneObject.skipNextValidation = true;
28
37
  }
29
- const { values: values2, texts } = fromUrlValues(urlValue);
38
+ const { values: values2, texts, defaults } = fromUrlValues(urlValue);
39
+ if (isEqual(values2, defaults) && this._sceneObject.state.defaultValues) {
40
+ this._sceneObject.changeValueTo(
41
+ (_a = this._sceneObject.state.defaultValues) == null ? void 0 : _a.value,
42
+ (_b = this._sceneObject.state.defaultValues) == null ? void 0 : _b.text,
43
+ false
44
+ );
45
+ return;
46
+ }
30
47
  this._sceneObject.changeValueTo(values2, texts);
31
48
  }
32
49
  }
@@ -39,9 +56,10 @@ class GroupByVariableUrlSyncHandler {
39
56
  return this._nextChangeShouldAddHistoryStep;
40
57
  }
41
58
  }
42
- function toUrlValues(values, texts) {
59
+ function toUrlValues(values, texts, defaultValues) {
43
60
  values = Array.isArray(values) ? values : [values];
44
61
  texts = Array.isArray(texts) ? texts : [texts];
62
+ const defaults = defaultValues ? Array.isArray(defaultValues) ? defaultValues : [defaultValues] : [];
45
63
  return values.map((value, idx) => {
46
64
  if (value === void 0 || value === null) {
47
65
  return "";
@@ -49,21 +67,27 @@ function toUrlValues(values, texts) {
49
67
  value = String(value);
50
68
  let text = texts[idx];
51
69
  text = text === void 0 || text === null ? value : String(text);
52
- return toUrlCommaDelimitedString(value, text);
70
+ return toUrlCommaDelimitedString(value, text) + (defaults.includes(value) ? escapeUrlPipeDelimiters("|default") : "");
53
71
  });
54
72
  }
55
73
  function fromUrlValues(urlValues) {
56
74
  urlValues = Array.isArray(urlValues) ? urlValues : [urlValues];
57
75
  return urlValues.reduce(
58
76
  (acc, urlValue) => {
59
- const [value, label] = (urlValue != null ? urlValue : "").split(",");
77
+ const pipeEscapedVal = /__gfp__/g[Symbol.replace](urlValue, "|");
78
+ const [commaValues, isDefault] = (pipeEscapedVal != null ? pipeEscapedVal : "").split("|");
79
+ const [value, label] = (commaValues != null ? commaValues : "").split(",");
60
80
  acc.values.push(unescapeUrlDelimiters(value));
61
81
  acc.texts.push(unescapeUrlDelimiters(label != null ? label : value));
82
+ if (isDefault) {
83
+ acc.defaults.push(value);
84
+ }
62
85
  return acc;
63
86
  },
64
87
  {
65
88
  values: [],
66
- texts: []
89
+ texts: [],
90
+ defaults: []
67
91
  }
68
92
  );
69
93
  }
@@ -1 +1 @@
1
- {"version":3,"file":"GroupByVariableUrlSyncHandler.js","sources":["../../../../src/variables/groupby/GroupByVariableUrlSyncHandler.ts"],"sourcesContent":["import { SceneObjectUrlSyncHandler, SceneObjectUrlValues } from '../../core/types';\nimport { GroupByVariable } from './GroupByVariable';\nimport { toUrlCommaDelimitedString, unescapeUrlDelimiters } from '../utils';\nimport { VariableValue } from '../types';\n\nexport class GroupByVariableUrlSyncHandler implements SceneObjectUrlSyncHandler {\n public constructor(private _sceneObject: GroupByVariable) {}\n\n protected _nextChangeShouldAddHistoryStep = false;\n\n private getKey(): string {\n return `var-${this._sceneObject.state.name}`;\n }\n\n public getKeys(): string[] {\n if (this._sceneObject.state.skipUrlSync) {\n return [];\n }\n\n return [this.getKey()];\n }\n\n public getUrlState(): SceneObjectUrlValues {\n if (this._sceneObject.state.skipUrlSync) {\n return {};\n }\n\n return { [this.getKey()]: toUrlValues(this._sceneObject.state.value, this._sceneObject.state.text) };\n }\n\n public updateFromUrl(values: SceneObjectUrlValues): void {\n let urlValue = values[this.getKey()];\n\n if (urlValue != null) {\n /**\n * Initial URL Sync happens before scene objects are activated.\n * We need to skip validation in this case to make sure values set via URL are maintained.\n */\n if (!this._sceneObject.isActive) {\n this._sceneObject.skipNextValidation = true;\n }\n\n const { values, texts } = fromUrlValues(urlValue);\n\n this._sceneObject.changeValueTo(values, texts);\n }\n }\n\n public performBrowserHistoryAction(callback: () => void) {\n this._nextChangeShouldAddHistoryStep = true;\n callback();\n this._nextChangeShouldAddHistoryStep = false;\n }\n\n public shouldCreateHistoryStep(values: SceneObjectUrlValues): boolean {\n return this._nextChangeShouldAddHistoryStep;\n }\n}\n\nfunction toUrlValues(values: VariableValue, texts: VariableValue): string[] {\n values = Array.isArray(values) ? values : [values];\n texts = Array.isArray(texts) ? texts : [texts];\n\n return values.map((value, idx) => {\n if (value === undefined || value === null) {\n return '';\n }\n\n value = String(value);\n\n let text = texts[idx];\n text = text === undefined || text === null ? value : String(text);\n\n return toUrlCommaDelimitedString(value, text);\n });\n}\n\nfunction fromUrlValues(urlValues: string | string[]): { values: string[]; texts: string[] } {\n urlValues = Array.isArray(urlValues) ? urlValues : [urlValues];\n\n return urlValues.reduce<{ values: string[]; texts: string[] }>(\n (acc, urlValue) => {\n const [value, label] = (urlValue ?? '').split(',');\n\n acc.values.push(unescapeUrlDelimiters(value));\n acc.texts.push(unescapeUrlDelimiters(label ?? value));\n\n return acc;\n },\n {\n values: [],\n texts: [],\n }\n );\n}\n"],"names":["values"],"mappings":"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"}
1
+ {"version":3,"file":"GroupByVariableUrlSyncHandler.js","sources":["../../../../src/variables/groupby/GroupByVariableUrlSyncHandler.ts"],"sourcesContent":["import { SceneObjectUrlSyncHandler, SceneObjectUrlValues } from '../../core/types';\nimport { GroupByVariable } from './GroupByVariable';\nimport { escapeUrlPipeDelimiters, toUrlCommaDelimitedString, unescapeUrlDelimiters } from '../utils';\nimport { VariableValue } from '../types';\nimport { isEqual } from 'lodash';\n\nexport class GroupByVariableUrlSyncHandler implements SceneObjectUrlSyncHandler {\n public constructor(private _sceneObject: GroupByVariable) {}\n\n protected _nextChangeShouldAddHistoryStep = false;\n\n private getKey(): string {\n return `var-${this._sceneObject.state.name}`;\n }\n\n public getKeys(): string[] {\n if (this._sceneObject.state.skipUrlSync) {\n return [];\n }\n\n return [this.getKey()];\n }\n\n public getUrlState(): SceneObjectUrlValues {\n if (this._sceneObject.state.skipUrlSync) {\n return {};\n }\n\n return {\n [this.getKey()]: toUrlValues(\n this._sceneObject.state.value,\n this._sceneObject.state.text,\n this._sceneObject.state.defaultValues?.value\n ),\n };\n }\n\n public updateFromUrl(values: SceneObjectUrlValues): void {\n let urlValue = values[this.getKey()];\n\n if (urlValue != null) {\n /**\n * Initial URL Sync happens before scene objects are activated.\n * We need to skip validation in this case to make sure values set via URL are maintained.\n */\n if (!this._sceneObject.isActive) {\n this._sceneObject.skipNextValidation = true;\n }\n\n const { values, texts, defaults } = fromUrlValues(urlValue);\n\n // if we only have defaults in our value set then the variable\n // is unmodified, meaning when we change dashboards we apply the default\n // values of the new dashboard instead of carrying these ones with us.\n // If there are also other values, then the variable is modified and we\n // do want to carry them all across\n if (isEqual(values, defaults) && this._sceneObject.state.defaultValues) {\n this._sceneObject.changeValueTo(\n this._sceneObject.state.defaultValues?.value,\n this._sceneObject.state.defaultValues?.text,\n false\n );\n return;\n }\n\n this._sceneObject.changeValueTo(values, texts);\n }\n }\n\n public performBrowserHistoryAction(callback: () => void) {\n this._nextChangeShouldAddHistoryStep = true;\n callback();\n this._nextChangeShouldAddHistoryStep = false;\n }\n\n public shouldCreateHistoryStep(values: SceneObjectUrlValues): boolean {\n return this._nextChangeShouldAddHistoryStep;\n }\n}\n\nfunction toUrlValues(values: VariableValue, texts: VariableValue, defaultValues?: VariableValue): string[] {\n values = Array.isArray(values) ? values : [values];\n texts = Array.isArray(texts) ? texts : [texts];\n const defaults = defaultValues ? (Array.isArray(defaultValues) ? defaultValues : [defaultValues]) : [];\n\n return values.map((value, idx) => {\n if (value === undefined || value === null) {\n return '';\n }\n\n value = String(value);\n\n let text = texts[idx];\n text = text === undefined || text === null ? value : String(text);\n\n return (\n toUrlCommaDelimitedString(value, text) + (defaults.includes(value) ? escapeUrlPipeDelimiters('|default') : '')\n );\n });\n}\n\nfunction fromUrlValues(urlValues: string | string[]): { values: string[]; texts: string[]; defaults: string[] } {\n urlValues = Array.isArray(urlValues) ? urlValues : [urlValues];\n\n return urlValues.reduce<{ values: string[]; texts: string[]; defaults: string[] }>(\n (acc, urlValue) => {\n const pipeEscapedVal = /__gfp__/g[Symbol.replace](urlValue, '|');\n const [commaValues, isDefault] = (pipeEscapedVal ?? '').split('|');\n const [value, label] = (commaValues ?? '').split(',');\n\n acc.values.push(unescapeUrlDelimiters(value));\n acc.texts.push(unescapeUrlDelimiters(label ?? value));\n\n if (isDefault) {\n acc.defaults.push(value);\n }\n\n return acc;\n },\n {\n values: [],\n texts: [],\n defaults: [],\n }\n );\n}\n"],"names":["values"],"mappings":"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"}
package/dist/index.d.ts CHANGED
@@ -1188,6 +1188,10 @@ interface GroupByVariableState extends MultiValueVariableState {
1188
1188
  baseFilters?: AdHocVariableFilter[];
1189
1189
  /** Datasource to use for getTagKeys and also controls which scene queries the group by should apply to */
1190
1190
  datasource: DataSourceRef | null;
1191
+ defaultValues?: {
1192
+ text: VariableValue;
1193
+ value: VariableValue;
1194
+ };
1191
1195
  /** Controls if the group by can be changed */
1192
1196
  readOnly?: boolean;
1193
1197
  /**
@@ -1225,6 +1229,9 @@ declare class GroupByVariable extends MultiValueVariable<GroupByVariableState> {
1225
1229
  private _updateValueGivenNewOptions;
1226
1230
  getValueOptions(args: VariableGetOptionsArgs): Observable<VariableValueOption[]>;
1227
1231
  constructor(initialState: Partial<GroupByVariableState>);
1232
+ private _activationHandler;
1233
+ checkIfRestorable(values: VariableValue): boolean;
1234
+ restoreDefaultValues(): void;
1228
1235
  /**
1229
1236
  * Get possible keys given current filters. Do not call from plugins directly
1230
1237
  */