@grafana/scenes 4.12.1 → 4.13.0--canary.705.8801395113.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/dist/esm/variables/adhoc/AdHocFiltersVariableUrlSyncHandler.js +6 -30
- package/dist/esm/variables/adhoc/AdHocFiltersVariableUrlSyncHandler.js.map +1 -1
- package/dist/esm/variables/groupby/GroupByVariable.js +24 -10
- package/dist/esm/variables/groupby/GroupByVariable.js.map +1 -1
- package/dist/esm/variables/groupby/GroupByVariableUrlSyncHandler.js +58 -0
- package/dist/esm/variables/groupby/GroupByVariableUrlSyncHandler.js.map +1 -0
- package/dist/esm/variables/utils.js +27 -1
- package/dist/esm/variables/utils.js.map +1 -1
- package/dist/index.d.ts +3 -0
- package/dist/index.js +105 -39
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { escapeUrlPipeDelimiters, toUrlCommaDelimitedString, unescapeUrlDelimiters } from '../utils.js';
|
|
2
|
+
|
|
1
3
|
class AdHocFiltersVariableUrlSyncHandler {
|
|
2
4
|
constructor(_variable) {
|
|
3
5
|
this._variable = _variable;
|
|
@@ -13,7 +15,7 @@ class AdHocFiltersVariableUrlSyncHandler {
|
|
|
13
15
|
if (filters.length === 0) {
|
|
14
16
|
return { [this.getKey()]: [""] };
|
|
15
17
|
}
|
|
16
|
-
const value = filters.map((filter) => toArray(filter).map(
|
|
18
|
+
const value = filters.map((filter) => toArray(filter).map(escapeUrlPipeDelimiters).join("|"));
|
|
17
19
|
return { [this.getKey()]: value };
|
|
18
20
|
}
|
|
19
21
|
updateFromUrl(values) {
|
|
@@ -33,39 +35,13 @@ function deserializeUrlToFilters(value) {
|
|
|
33
35
|
const filter = toFilter(value);
|
|
34
36
|
return filter === null ? [] : [filter];
|
|
35
37
|
}
|
|
36
|
-
function escapePipeDelimiters(value) {
|
|
37
|
-
if (value === null || value === void 0) {
|
|
38
|
-
return "";
|
|
39
|
-
}
|
|
40
|
-
return value = /\|/g[Symbol.replace](value, "__gfp__");
|
|
41
|
-
}
|
|
42
|
-
function escapeCommaDelimiters(value) {
|
|
43
|
-
if (value === null || value === void 0) {
|
|
44
|
-
return "";
|
|
45
|
-
}
|
|
46
|
-
return /,/g[Symbol.replace](value, "__gfc__");
|
|
47
|
-
}
|
|
48
|
-
function unescapeDelimiters(value) {
|
|
49
|
-
if (value === null || value === void 0) {
|
|
50
|
-
return "";
|
|
51
|
-
}
|
|
52
|
-
value = /__gfp__/g[Symbol.replace](value, "|");
|
|
53
|
-
value = /__gfc__/g[Symbol.replace](value, ",");
|
|
54
|
-
return value;
|
|
55
|
-
}
|
|
56
38
|
function toArray(filter) {
|
|
57
39
|
return [
|
|
58
|
-
|
|
40
|
+
toUrlCommaDelimitedString(filter.key, filter.keyLabel),
|
|
59
41
|
filter.operator,
|
|
60
|
-
|
|
42
|
+
toUrlCommaDelimitedString(filter.value, filter.valueLabel)
|
|
61
43
|
];
|
|
62
44
|
}
|
|
63
|
-
function toCommaDelimitedString(key, label) {
|
|
64
|
-
if (!label || key === label) {
|
|
65
|
-
return escapeCommaDelimiters(key);
|
|
66
|
-
}
|
|
67
|
-
return [key, label].map(escapeCommaDelimiters).join(",");
|
|
68
|
-
}
|
|
69
45
|
function toFilter(urlValue) {
|
|
70
46
|
if (typeof urlValue !== "string" || urlValue.length === 0) {
|
|
71
47
|
return null;
|
|
@@ -74,7 +50,7 @@ function toFilter(urlValue) {
|
|
|
74
50
|
const [key2, label] = v.split(",");
|
|
75
51
|
acc.push(key2, label != null ? label : key2);
|
|
76
52
|
return acc;
|
|
77
|
-
}, []).map(
|
|
53
|
+
}, []).map(unescapeUrlDelimiters);
|
|
78
54
|
return {
|
|
79
55
|
key,
|
|
80
56
|
keyLabel,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AdHocFiltersVariableUrlSyncHandler.js","sources":["../../../../src/variables/adhoc/AdHocFiltersVariableUrlSyncHandler.ts"],"sourcesContent":["import { SceneObjectUrlSyncHandler, SceneObjectUrlValue, SceneObjectUrlValues } from '../../core/types';\nimport { AdHocFiltersVariable, AdHocFilterWithLabels } from './AdHocFiltersVariable';\n\nexport class AdHocFiltersVariableUrlSyncHandler implements SceneObjectUrlSyncHandler {\n public constructor(private _variable: AdHocFiltersVariable) {}\n\n private getKey(): string {\n return `var-${this._variable.state.name}`;\n }\n\n public getKeys(): string[] {\n return [this.getKey()];\n }\n\n public getUrlState(): SceneObjectUrlValues {\n const filters = this._variable.state.filters;\n\n if (filters.length === 0) {\n return { [this.getKey()]: [''] };\n }\n\n const value = filters.map((filter) => toArray(filter).map(
|
|
1
|
+
{"version":3,"file":"AdHocFiltersVariableUrlSyncHandler.js","sources":["../../../../src/variables/adhoc/AdHocFiltersVariableUrlSyncHandler.ts"],"sourcesContent":["import { SceneObjectUrlSyncHandler, SceneObjectUrlValue, SceneObjectUrlValues } from '../../core/types';\nimport { AdHocFiltersVariable, AdHocFilterWithLabels } from './AdHocFiltersVariable';\nimport { escapeUrlPipeDelimiters, toUrlCommaDelimitedString, unescapeUrlDelimiters } from '../utils';\n\nexport class AdHocFiltersVariableUrlSyncHandler implements SceneObjectUrlSyncHandler {\n public constructor(private _variable: AdHocFiltersVariable) {}\n\n private getKey(): string {\n return `var-${this._variable.state.name}`;\n }\n\n public getKeys(): string[] {\n return [this.getKey()];\n }\n\n public getUrlState(): SceneObjectUrlValues {\n const filters = this._variable.state.filters;\n\n if (filters.length === 0) {\n return { [this.getKey()]: [''] };\n }\n\n const value = filters.map((filter) => toArray(filter).map(escapeUrlPipeDelimiters).join('|'));\n return { [this.getKey()]: value };\n }\n\n public updateFromUrl(values: SceneObjectUrlValues): void {\n const urlValue = values[this.getKey()];\n\n if (urlValue == null) {\n return;\n }\n\n const filters = deserializeUrlToFilters(urlValue);\n this._variable.setState({ filters });\n }\n}\n\nfunction deserializeUrlToFilters(value: SceneObjectUrlValue): AdHocFilterWithLabels[] {\n if (Array.isArray(value)) {\n const values = value;\n return values.map(toFilter).filter(isFilter);\n }\n\n const filter = toFilter(value);\n return filter === null ? [] : [filter];\n}\n\nfunction toArray(filter: AdHocFilterWithLabels): string[] {\n return [\n toUrlCommaDelimitedString(filter.key, filter.keyLabel),\n filter.operator,\n toUrlCommaDelimitedString(filter.value, filter.valueLabel),\n ];\n}\n\nfunction toFilter(urlValue: string | number | boolean | undefined | null): AdHocFilterWithLabels | null {\n if (typeof urlValue !== 'string' || urlValue.length === 0) {\n return null;\n }\n\n const [key, keyLabel, operator, _operatorLabel, value, valueLabel] = urlValue\n .split('|')\n .reduce<string[]>((acc, v) => {\n const [key, label] = v.split(',');\n\n acc.push(key, label ?? key);\n\n return acc;\n }, [])\n .map(unescapeUrlDelimiters);\n\n return {\n key,\n keyLabel,\n operator,\n value,\n valueLabel,\n condition: '',\n };\n}\n\nfunction isFilter(filter: AdHocFilterWithLabels | null): filter is AdHocFilterWithLabels {\n return filter !== null && typeof filter.key === 'string' && typeof filter.value === 'string';\n}\n"],"names":["key"],"mappings":"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"}
|
|
@@ -5,8 +5,9 @@ import { MultiValueVariable } from '../variants/MultiValueVariable.js';
|
|
|
5
5
|
import { map, of, from, mergeMap, take, lastValueFrom } from 'rxjs';
|
|
6
6
|
import { getDataSource } from '../../utils/getDataSource.js';
|
|
7
7
|
import { MultiSelect } from '@grafana/ui';
|
|
8
|
-
import { isArray } from 'lodash';
|
|
8
|
+
import { unionBy, isArray } from 'lodash';
|
|
9
9
|
import { getQueriesForVariables } from '../utils.js';
|
|
10
|
+
import { GroupByVariableUrlSyncHandler } from './GroupByVariableUrlSyncHandler.js';
|
|
10
11
|
|
|
11
12
|
var __defProp = Object.defineProperty;
|
|
12
13
|
var __defProps = Object.defineProperties;
|
|
@@ -44,6 +45,7 @@ class GroupByVariable extends MultiValueVariable {
|
|
|
44
45
|
noValueOnClear: true
|
|
45
46
|
}));
|
|
46
47
|
this.isLazy = true;
|
|
48
|
+
this._urlSync = new GroupByVariableUrlSyncHandler(this);
|
|
47
49
|
this._getKeys = async (ds) => {
|
|
48
50
|
var _a, _b, _c;
|
|
49
51
|
const override = await ((_b = (_a = this.state).getTagKeysProvider) == null ? void 0 : _b.call(_a, this, null));
|
|
@@ -93,9 +95,11 @@ class GroupByVariable extends MultiValueVariable {
|
|
|
93
95
|
this.setState(stateUpdate);
|
|
94
96
|
}
|
|
95
97
|
getValueOptions(args) {
|
|
98
|
+
var _a;
|
|
99
|
+
const urlOptions = (_a = this.state.urlOptions) != null ? _a : [];
|
|
96
100
|
if (this.state.defaultOptions) {
|
|
97
101
|
return of(
|
|
98
|
-
this.state.defaultOptions.map((o) => ({
|
|
102
|
+
unionBy(this.state.defaultOptions, urlOptions, "value").map((o) => ({
|
|
99
103
|
label: o.text,
|
|
100
104
|
value: String(o.value)
|
|
101
105
|
}))
|
|
@@ -111,7 +115,7 @@ class GroupByVariable extends MultiValueVariable {
|
|
|
111
115
|
return from(this._getKeys(ds)).pipe(
|
|
112
116
|
take(1),
|
|
113
117
|
mergeMap((data) => {
|
|
114
|
-
const a = data.map((i) => {
|
|
118
|
+
const a = unionBy(data, urlOptions, "value").map((i) => {
|
|
115
119
|
return {
|
|
116
120
|
label: i.text,
|
|
117
121
|
value: i.value ? String(i.value) : i.text
|
|
@@ -129,14 +133,24 @@ class GroupByVariable extends MultiValueVariable {
|
|
|
129
133
|
}
|
|
130
134
|
GroupByVariable.Component = GroupByVariableRenderer;
|
|
131
135
|
function GroupByVariableRenderer({ model }) {
|
|
132
|
-
const { value, key, maxVisibleValues, noValueOnClear } = model.useState();
|
|
133
|
-
const
|
|
136
|
+
const { value, text, key, maxVisibleValues, noValueOnClear } = model.useState();
|
|
137
|
+
const values = useMemo(() => {
|
|
138
|
+
const arrayValue = isArray(value) ? value : [value];
|
|
139
|
+
const arrayText = isArray(text) ? text : [text];
|
|
140
|
+
return arrayValue.map((value2, idx) => {
|
|
141
|
+
var _a;
|
|
142
|
+
return {
|
|
143
|
+
value: value2,
|
|
144
|
+
label: String((_a = arrayText[idx]) != null ? _a : value2)
|
|
145
|
+
};
|
|
146
|
+
});
|
|
147
|
+
}, [value, text]);
|
|
134
148
|
const [isFetchingOptions, setIsFetchingOptions] = useState(false);
|
|
135
149
|
const [isOptionsOpen, setIsOptionsOpen] = useState(false);
|
|
136
|
-
const [uncommittedValue, setUncommittedValue] = useState(
|
|
150
|
+
const [uncommittedValue, setUncommittedValue] = useState(values);
|
|
137
151
|
useEffect(() => {
|
|
138
|
-
setUncommittedValue(
|
|
139
|
-
}, [
|
|
152
|
+
setUncommittedValue(values);
|
|
153
|
+
}, [values]);
|
|
140
154
|
const onInputChange = model.onSearchChange ? (value2, meta) => {
|
|
141
155
|
if (meta.action === "input-change") {
|
|
142
156
|
model.onSearchChange(value2);
|
|
@@ -161,13 +175,13 @@ function GroupByVariableRenderer({ model }) {
|
|
|
161
175
|
isLoading: isFetchingOptions,
|
|
162
176
|
onInputChange,
|
|
163
177
|
onBlur: () => {
|
|
164
|
-
model.changeValueTo(uncommittedValue);
|
|
178
|
+
model.changeValueTo(uncommittedValue.map((x) => x.value));
|
|
165
179
|
},
|
|
166
180
|
onChange: (newValue, action) => {
|
|
167
181
|
if (action.action === "clear" && noValueOnClear) {
|
|
168
182
|
model.changeValueTo([]);
|
|
169
183
|
}
|
|
170
|
-
setUncommittedValue(newValue
|
|
184
|
+
setUncommittedValue(newValue);
|
|
171
185
|
},
|
|
172
186
|
onOpenMenu: async () => {
|
|
173
187
|
setIsFetchingOptions(true);
|
|
@@ -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, MetricFindValue } from '@grafana/data';\nimport { allActiveGroupByVariables } from './findActiveGroupByVariablesByUid';\nimport { DataSourceRef, VariableType } from '@grafana/schema';\nimport { SceneComponentProps, ControlsLayout } 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 } from 'rxjs';\nimport { getDataSource } from '../../utils/getDataSource';\nimport { InputActionMeta, MultiSelect } from '@grafana/ui';\nimport { isArray } from 'lodash';\nimport { getQueriesForVariables } from '../utils';\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[] }>;\n\nexport class GroupByVariable extends MultiValueVariable<GroupByVariableState> {\n static Component = GroupByVariableRenderer;\n isLazy = true;\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 }))\n );\n }\n\n this.setState({ loading: true, error: null });\n\n return from(\n getDataSource(this.state.datasource, {\n __sceneObject: { text: '__sceneObject', value: this },\n })\n ).pipe(\n mergeMap((ds) => {\n return from(this._getKeys(ds)).pipe(\n take(1),\n mergeMap((data: MetricFindValue[]) => {\n const a: VariableValueOption[] = data.map((i) => {\n return {\n label: i.text,\n value: i.value ? String(i.value) : i.text,\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 this.addActivationHandler(() => {\n allActiveGroupByVariables.add(this);\n\n return () => allActiveGroupByVariables.delete(this);\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(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 // @ts-expect-error TODO: remove this once 10.4.0 is released\n let keys = await ds.getTagKeys({ filters: otherFilters, queries, timeRange });\n\n if (override) {\n keys = keys.concat(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}\nexport function GroupByVariableRenderer({ model }: SceneComponentProps<MultiValueVariable>) {\n const { value, key, maxVisibleValues, noValueOnClear } = model.useState();\n const arrayValue = useMemo(() => (isArray(value) ? value : [value]), [value]);\n const [isFetchingOptions, setIsFetchingOptions] = useState(false);\n const [isOptionsOpen, setIsOptionsOpen] = useState(false);\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(arrayValue);\n\n // Detect value changes outside\n useEffect(() => {\n setUncommittedValue(arrayValue);\n }, [arrayValue]);\n\n const onInputChange = model.onSearchChange\n ? (value: string, meta: InputActionMeta) => {\n if (meta.action === 'input-change') {\n model.onSearchChange!(value);\n }\n }\n : undefined;\n\n const placeholder = 'Select value';\n\n return (\n <MultiSelect<VariableValueSingle>\n data-testid={`GroupBySelect-${key}`}\n id={key}\n placeholder={placeholder}\n width=\"auto\"\n value={uncommittedValue}\n noMultiValueWrap={true}\n maxVisibleValues={maxVisibleValues ?? 5}\n tabSelectsValue={false}\n virtualized\n allowCustomValue\n options={model.getOptionsForSelect()}\n closeMenuOnSelect={false}\n isOpen={isOptionsOpen}\n isClearable={true}\n isLoading={isFetchingOptions}\n onInputChange={onInputChange}\n onBlur={() => {\n model.changeValueTo(uncommittedValue);\n }}\n onChange={(newValue, action) => {\n if (action.action === 'clear' && noValueOnClear) {\n model.changeValueTo([]);\n }\n setUncommittedValue(newValue.map((x) => x.value!));\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"],"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, 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 } from 'rxjs';\nimport { getDataSource } from '../../utils/getDataSource';\nimport { InputActionMeta, MultiSelect } from '@grafana/ui';\nimport { isArray, unionBy } from 'lodash';\nimport { getQueriesForVariables } from '../utils';\nimport { GroupByVariableUrlSyncHandler } from './GroupByVariableUrlSyncHandler';\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 /** Options obtained through URL sync */\n urlOptions?: 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[] }>;\n\nexport class GroupByVariable extends MultiValueVariable<GroupByVariableState> {\n static Component = GroupByVariableRenderer;\n isLazy = true;\n\n protected _urlSync: SceneObjectUrlSyncHandler = new GroupByVariableUrlSyncHandler(this);\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 const urlOptions = this.state.urlOptions ?? [];\n\n // When default dimensions are provided, return the static list\n if (this.state.defaultOptions) {\n return of(\n unionBy(this.state.defaultOptions, urlOptions, 'value').map((o) => ({\n label: o.text,\n value: String(o.value),\n }))\n );\n }\n\n this.setState({ loading: true, error: null });\n\n return from(\n getDataSource(this.state.datasource, {\n __sceneObject: { text: '__sceneObject', value: this },\n })\n ).pipe(\n mergeMap((ds) => {\n return from(this._getKeys(ds)).pipe(\n take(1),\n mergeMap((data: MetricFindValue[]) => {\n const a: VariableValueOption[] = unionBy(data, urlOptions, 'value').map((i) => {\n return {\n label: i.text,\n value: i.value ? String(i.value) : i.text,\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 this.addActivationHandler(() => {\n allActiveGroupByVariables.add(this);\n\n return () => allActiveGroupByVariables.delete(this);\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(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 // @ts-expect-error TODO: remove this once 10.4.0 is released\n let keys = await ds.getTagKeys({ filters: otherFilters, queries, timeRange });\n\n if (override) {\n keys = keys.concat(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}\nexport function GroupByVariableRenderer({ model }: SceneComponentProps<MultiValueVariable>) {\n const { value, text, key, maxVisibleValues, noValueOnClear } = model.useState();\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 const [isFetchingOptions, setIsFetchingOptions] = useState(false);\n const [isOptionsOpen, setIsOptionsOpen] = useState(false);\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 // Detect value changes outside\n useEffect(() => {\n setUncommittedValue(values);\n }, [values]);\n\n const onInputChange = model.onSearchChange\n ? (value: string, meta: InputActionMeta) => {\n if (meta.action === 'input-change') {\n model.onSearchChange!(value);\n }\n }\n : undefined;\n\n const placeholder = 'Select value';\n\n return (\n <MultiSelect<VariableValueSingle>\n data-testid={`GroupBySelect-${key}`}\n id={key}\n placeholder={placeholder}\n width=\"auto\"\n value={uncommittedValue}\n noMultiValueWrap={true}\n maxVisibleValues={maxVisibleValues ?? 5}\n tabSelectsValue={false}\n virtualized\n allowCustomValue\n options={model.getOptionsForSelect()}\n closeMenuOnSelect={false}\n isOpen={isOptionsOpen}\n isClearable={true}\n isLoading={isFetchingOptions}\n onInputChange={onInputChange}\n onBlur={() => {\n model.changeValueTo(uncommittedValue.map((x) => x.value!));\n }}\n onChange={(newValue, action) => {\n if (action.action === 'clear' && noValueOnClear) {\n model.changeValueTo([]);\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}\n"],"names":["value"],"mappings":"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"}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { zip, unzip } from 'lodash';
|
|
2
|
+
import { unescapeUrlDelimiters, toUrlCommaDelimitedString } from '../utils.js';
|
|
3
|
+
|
|
4
|
+
class GroupByVariableUrlSyncHandler {
|
|
5
|
+
constructor(_sceneObject) {
|
|
6
|
+
this._sceneObject = _sceneObject;
|
|
7
|
+
}
|
|
8
|
+
getKey() {
|
|
9
|
+
return `var-${this._sceneObject.state.name}`;
|
|
10
|
+
}
|
|
11
|
+
getKeys() {
|
|
12
|
+
if (this._sceneObject.state.skipUrlSync) {
|
|
13
|
+
return [];
|
|
14
|
+
}
|
|
15
|
+
return [this.getKey()];
|
|
16
|
+
}
|
|
17
|
+
getUrlState() {
|
|
18
|
+
if (this._sceneObject.state.skipUrlSync) {
|
|
19
|
+
return {};
|
|
20
|
+
}
|
|
21
|
+
let { value: values, text: texts } = this._sceneObject.state;
|
|
22
|
+
values = Array.isArray(values) ? values : [values];
|
|
23
|
+
texts = Array.isArray(texts) ? texts : [texts];
|
|
24
|
+
const urlValue = zip(values, texts).map(toUrlValues);
|
|
25
|
+
return { [this.getKey()]: urlValue };
|
|
26
|
+
}
|
|
27
|
+
updateFromUrl(values) {
|
|
28
|
+
let urlValue = values[this.getKey()];
|
|
29
|
+
if (urlValue != null) {
|
|
30
|
+
if (!this._sceneObject.isActive) {
|
|
31
|
+
this._sceneObject.skipNextValidation = true;
|
|
32
|
+
}
|
|
33
|
+
urlValue = Array.isArray(urlValue) ? urlValue : [urlValue];
|
|
34
|
+
const valuesLabelsPairs = urlValue.map((value) => value ? value.split(",") : [value]);
|
|
35
|
+
let [values2, labels] = unzip(valuesLabelsPairs);
|
|
36
|
+
values2 = (values2 != null ? values2 : []).map(unescapeUrlDelimiters);
|
|
37
|
+
labels = (labels != null ? labels : []).map(unescapeUrlDelimiters);
|
|
38
|
+
this._sceneObject.setState({
|
|
39
|
+
urlOptions: values2.map((value, idx) => ({
|
|
40
|
+
value,
|
|
41
|
+
text: labels[idx]
|
|
42
|
+
}))
|
|
43
|
+
});
|
|
44
|
+
this._sceneObject.changeValueTo(values2, labels);
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
function toUrlValues([value, label]) {
|
|
49
|
+
if (value === void 0 || value === null) {
|
|
50
|
+
return "";
|
|
51
|
+
}
|
|
52
|
+
value = String(value);
|
|
53
|
+
label = label === void 0 || label === null ? value : String(label);
|
|
54
|
+
return toUrlCommaDelimitedString(value, label);
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
export { GroupByVariableUrlSyncHandler };
|
|
58
|
+
//# sourceMappingURL=GroupByVariableUrlSyncHandler.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"GroupByVariableUrlSyncHandler.js","sources":["../../../../src/variables/groupby/GroupByVariableUrlSyncHandler.ts"],"sourcesContent":["import { unzip, zip } from 'lodash';\nimport { SceneObjectUrlSyncHandler, SceneObjectUrlValues } from '../../core/types';\nimport { GroupByVariable } from './GroupByVariable';\nimport { toUrlCommaDelimitedString, unescapeUrlDelimiters } from '../utils';\nimport { VariableValueSingle } from '../types';\n\nexport class GroupByVariableUrlSyncHandler implements SceneObjectUrlSyncHandler {\n public constructor(private _sceneObject: GroupByVariable) {}\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 let { value: values, text: texts } = this._sceneObject.state;\n\n values = Array.isArray(values) ? values : [values];\n texts = Array.isArray(texts) ? texts : [texts];\n\n const urlValue = zip(values, texts).map(toUrlValues);\n\n return { [this.getKey()]: urlValue };\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 urlValue = Array.isArray(urlValue) ? urlValue : [urlValue];\n const valuesLabelsPairs = urlValue.map((value) => (value ? value.split(',') : [value]));\n let [values, labels] = unzip(valuesLabelsPairs);\n\n values = (values ?? []).map(unescapeUrlDelimiters);\n labels = (labels ?? []).map(unescapeUrlDelimiters);\n\n this._sceneObject.setState({\n urlOptions: values.map((value, idx) => ({\n value,\n text: labels[idx],\n })),\n });\n\n this._sceneObject.changeValueTo(values, labels);\n }\n }\n}\n\nfunction toUrlValues([value, label]: [VariableValueSingle | undefined, VariableValueSingle | undefined]): string {\n if (value === undefined || value === null) {\n return '';\n }\n\n value = String(value);\n label = label === undefined || label === null ? value : String(label);\n\n return toUrlCommaDelimitedString(value, label);\n}\n"],"names":["values"],"mappings":"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"}
|
|
@@ -86,6 +86,32 @@ function filterOutInactiveRunnerDuplicates(runners) {
|
|
|
86
86
|
return activeItems;
|
|
87
87
|
});
|
|
88
88
|
}
|
|
89
|
+
function escapeUrlPipeDelimiters(value) {
|
|
90
|
+
if (value === null || value === void 0) {
|
|
91
|
+
return "";
|
|
92
|
+
}
|
|
93
|
+
return value = /\|/g[Symbol.replace](value, "__gfp__");
|
|
94
|
+
}
|
|
95
|
+
function escapeUrlCommaDelimiters(value) {
|
|
96
|
+
if (value === null || value === void 0) {
|
|
97
|
+
return "";
|
|
98
|
+
}
|
|
99
|
+
return /,/g[Symbol.replace](value, "__gfc__");
|
|
100
|
+
}
|
|
101
|
+
function unescapeUrlDelimiters(value) {
|
|
102
|
+
if (value === null || value === void 0) {
|
|
103
|
+
return "";
|
|
104
|
+
}
|
|
105
|
+
value = /__gfp__/g[Symbol.replace](value, "|");
|
|
106
|
+
value = /__gfc__/g[Symbol.replace](value, ",");
|
|
107
|
+
return value;
|
|
108
|
+
}
|
|
109
|
+
function toUrlCommaDelimitedString(key, label) {
|
|
110
|
+
if (!label || key === label) {
|
|
111
|
+
return escapeUrlCommaDelimiters(key);
|
|
112
|
+
}
|
|
113
|
+
return [key, label].map(escapeUrlCommaDelimiters).join(",");
|
|
114
|
+
}
|
|
89
115
|
|
|
90
|
-
export { escapeLabelValueInExactSelector, escapeLabelValueInRegexSelector, getQueriesForVariables, isVariableValueEqual, renderPrometheusLabelFilters, safeStringifyValue };
|
|
116
|
+
export { escapeLabelValueInExactSelector, escapeLabelValueInRegexSelector, escapeUrlCommaDelimiters, escapeUrlPipeDelimiters, getQueriesForVariables, isVariableValueEqual, renderPrometheusLabelFilters, safeStringifyValue, toUrlCommaDelimitedString, unescapeUrlDelimiters };
|
|
91
117
|
//# sourceMappingURL=utils.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"utils.js","sources":["../../../src/variables/utils.ts"],"sourcesContent":["import { isEqual } from 'lodash';\nimport { VariableValue } from './types';\nimport { AdHocVariableFilter } from '@grafana/data';\nimport { sceneGraph } from '../core/sceneGraph';\nimport { SceneObject, SceneObjectState } from '../core/types';\nimport { DataQueryExtended, SceneQueryRunner } from '../querying/SceneQueryRunner';\nimport { DataSourceRef } from '@grafana/schema';\n\nexport function isVariableValueEqual(a: VariableValue | null | undefined, b: VariableValue | null | undefined) {\n if (a === b) {\n return true;\n }\n\n return isEqual(a, b);\n}\n\nexport function safeStringifyValue(value: unknown) {\n // Avoid circular references ignoring those references\n const getCircularReplacer = () => {\n const seen = new WeakSet();\n return (_: string, value: object | null) => {\n if (typeof value === 'object' && value !== null) {\n if (seen.has(value)) {\n return;\n }\n seen.add(value);\n }\n return value;\n };\n };\n\n try {\n return JSON.stringify(value, getCircularReplacer());\n } catch (error) {\n console.error(error);\n }\n\n return '';\n}\n\nexport function renderPrometheusLabelFilters(filters: AdHocVariableFilter[]) {\n return filters.map((filter) => renderFilter(filter)).join(',');\n}\n\nfunction renderFilter(filter: AdHocVariableFilter) {\n let value = '';\n\n if (filter.operator === '=~' || filter.operator === '!~¨') {\n value = escapeLabelValueInRegexSelector(filter.value);\n } else {\n value = escapeLabelValueInExactSelector(filter.value);\n }\n\n return `${filter.key}${filter.operator}\"${value}\"`;\n}\n\n// based on the openmetrics-documentation, the 3 symbols we have to handle are:\n// - \\n ... the newline character\n// - \\ ... the backslash character\n// - \" ... the double-quote character\nexport function escapeLabelValueInExactSelector(labelValue: string): string {\n return labelValue.replace(/\\\\/g, '\\\\\\\\').replace(/\\n/g, '\\\\n').replace(/\"/g, '\\\\\"');\n}\n\nexport function escapeLabelValueInRegexSelector(labelValue: string): string {\n return escapeLabelValueInExactSelector(escapeLokiRegexp(labelValue));\n}\n\nexport function isRegexSelector(selector?: string) {\n if (selector && (selector.includes('=~') || selector.includes('!~'))) {\n return true;\n }\n return false;\n}\n\n// Loki regular-expressions use the RE2 syntax (https://github.com/google/re2/wiki/Syntax),\n// so every character that matches something in that list has to be escaped.\n// the list of meta characters is: *+?()|\\.[]{}^$\n// we make a javascript regular expression that matches those characters:\nconst RE2_METACHARACTERS = /[*+?()|\\\\.\\[\\]{}^$]/g;\nfunction escapeLokiRegexp(value: string): string {\n return value.replace(RE2_METACHARACTERS, '\\\\$&');\n}\n\n/**\n * Get all queries in the scene that have the same datasource as provided source object\n */\nexport function getQueriesForVariables(\n sourceObject: SceneObject<SceneObjectState & { datasource: DataSourceRef | null }>\n) {\n const runners = sceneGraph.findAllObjects(\n sourceObject.getRoot(),\n (o) => o instanceof SceneQueryRunner\n ) as SceneQueryRunner[];\n\n const applicableRunners = filterOutInactiveRunnerDuplicates(runners).filter((r) => {\n return r.state.datasource?.uid === sourceObject.state.datasource?.uid;\n });\n\n if (applicableRunners.length === 0) {\n return [];\n }\n\n const result: DataQueryExtended[] = [];\n applicableRunners.forEach((r) => {\n result.push(...r.state.queries);\n });\n\n return result;\n}\n\n// Filters out inactive runner duplicates, keeping only the ones that are currently active.\n// This is needed for scnearios whan a query runner is cloned and the original is not removed but de-activated.\n// Can happen i.e. when editing a panel in Grafana Core dashboards.\nfunction filterOutInactiveRunnerDuplicates(runners: SceneQueryRunner[]) {\n // Group items by key\n const groupedItems: { [key: string]: SceneQueryRunner[] } = {};\n\n for (const item of runners) {\n if (item.state.key) {\n if (!(item.state.key in groupedItems)) {\n groupedItems[item.state.key] = [];\n }\n groupedItems[item.state.key].push(item);\n }\n }\n\n // Filter out inactive items and concatenate active items\n return Object.values(groupedItems).flatMap((group) => {\n const activeItems = group.filter((item) => item.isActive);\n // Keep inactive items if there's only one item with the key\n if (activeItems.length === 0 && group.length === 1) {\n return group;\n }\n return activeItems;\n });\n}\n"],"names":["value"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"utils.js","sources":["../../../src/variables/utils.ts"],"sourcesContent":["import { isEqual } from 'lodash';\nimport { VariableValue } from './types';\nimport { AdHocVariableFilter } from '@grafana/data';\nimport { sceneGraph } from '../core/sceneGraph';\nimport { SceneObject, SceneObjectState } from '../core/types';\nimport { DataQueryExtended, SceneQueryRunner } from '../querying/SceneQueryRunner';\nimport { DataSourceRef } from '@grafana/schema';\n\nexport function isVariableValueEqual(a: VariableValue | null | undefined, b: VariableValue | null | undefined) {\n if (a === b) {\n return true;\n }\n\n return isEqual(a, b);\n}\n\nexport function safeStringifyValue(value: unknown) {\n // Avoid circular references ignoring those references\n const getCircularReplacer = () => {\n const seen = new WeakSet();\n return (_: string, value: object | null) => {\n if (typeof value === 'object' && value !== null) {\n if (seen.has(value)) {\n return;\n }\n seen.add(value);\n }\n return value;\n };\n };\n\n try {\n return JSON.stringify(value, getCircularReplacer());\n } catch (error) {\n console.error(error);\n }\n\n return '';\n}\n\nexport function renderPrometheusLabelFilters(filters: AdHocVariableFilter[]) {\n return filters.map((filter) => renderFilter(filter)).join(',');\n}\n\nfunction renderFilter(filter: AdHocVariableFilter) {\n let value = '';\n\n if (filter.operator === '=~' || filter.operator === '!~¨') {\n value = escapeLabelValueInRegexSelector(filter.value);\n } else {\n value = escapeLabelValueInExactSelector(filter.value);\n }\n\n return `${filter.key}${filter.operator}\"${value}\"`;\n}\n\n// based on the openmetrics-documentation, the 3 symbols we have to handle are:\n// - \\n ... the newline character\n// - \\ ... the backslash character\n// - \" ... the double-quote character\nexport function escapeLabelValueInExactSelector(labelValue: string): string {\n return labelValue.replace(/\\\\/g, '\\\\\\\\').replace(/\\n/g, '\\\\n').replace(/\"/g, '\\\\\"');\n}\n\nexport function escapeLabelValueInRegexSelector(labelValue: string): string {\n return escapeLabelValueInExactSelector(escapeLokiRegexp(labelValue));\n}\n\nexport function isRegexSelector(selector?: string) {\n if (selector && (selector.includes('=~') || selector.includes('!~'))) {\n return true;\n }\n return false;\n}\n\n// Loki regular-expressions use the RE2 syntax (https://github.com/google/re2/wiki/Syntax),\n// so every character that matches something in that list has to be escaped.\n// the list of meta characters is: *+?()|\\.[]{}^$\n// we make a javascript regular expression that matches those characters:\nconst RE2_METACHARACTERS = /[*+?()|\\\\.\\[\\]{}^$]/g;\nfunction escapeLokiRegexp(value: string): string {\n return value.replace(RE2_METACHARACTERS, '\\\\$&');\n}\n\n/**\n * Get all queries in the scene that have the same datasource as provided source object\n */\nexport function getQueriesForVariables(\n sourceObject: SceneObject<SceneObjectState & { datasource: DataSourceRef | null }>\n) {\n const runners = sceneGraph.findAllObjects(\n sourceObject.getRoot(),\n (o) => o instanceof SceneQueryRunner\n ) as SceneQueryRunner[];\n\n const applicableRunners = filterOutInactiveRunnerDuplicates(runners).filter((r) => {\n return r.state.datasource?.uid === sourceObject.state.datasource?.uid;\n });\n\n if (applicableRunners.length === 0) {\n return [];\n }\n\n const result: DataQueryExtended[] = [];\n applicableRunners.forEach((r) => {\n result.push(...r.state.queries);\n });\n\n return result;\n}\n\n// Filters out inactive runner duplicates, keeping only the ones that are currently active.\n// This is needed for scnearios whan a query runner is cloned and the original is not removed but de-activated.\n// Can happen i.e. when editing a panel in Grafana Core dashboards.\nfunction filterOutInactiveRunnerDuplicates(runners: SceneQueryRunner[]) {\n // Group items by key\n const groupedItems: { [key: string]: SceneQueryRunner[] } = {};\n\n for (const item of runners) {\n if (item.state.key) {\n if (!(item.state.key in groupedItems)) {\n groupedItems[item.state.key] = [];\n }\n groupedItems[item.state.key].push(item);\n }\n }\n\n // Filter out inactive items and concatenate active items\n return Object.values(groupedItems).flatMap((group) => {\n const activeItems = group.filter((item) => item.isActive);\n // Keep inactive items if there's only one item with the key\n if (activeItems.length === 0 && group.length === 1) {\n return group;\n }\n return activeItems;\n });\n}\n\nexport function escapeUrlPipeDelimiters(value: string | undefined): string {\n if (value === null || value === undefined) {\n return '';\n }\n\n // Replace the pipe due to using it as a filter separator\n return (value = /\\|/g[Symbol.replace](value, '__gfp__'));\n}\n\nexport function escapeUrlCommaDelimiters(value: string | undefined): string {\n if (value === null || value === undefined) {\n return '';\n }\n\n // Replace the comma due to using it as a value/label separator\n return /,/g[Symbol.replace](value, '__gfc__');\n}\n\nexport function unescapeUrlDelimiters(value: string | undefined): string {\n if (value === null || value === undefined) {\n return '';\n }\n\n value = /__gfp__/g[Symbol.replace](value, '|');\n value = /__gfc__/g[Symbol.replace](value, ',');\n\n return value;\n}\n\nexport function toUrlCommaDelimitedString(key: string, label?: string): string {\n // Omit for identical key/label or when label is not set at all\n if (!label || key === label) {\n return escapeUrlCommaDelimiters(key);\n }\n\n return [key, label].map(escapeUrlCommaDelimiters).join(',');\n}\n"],"names":["value"],"mappings":"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"}
|
package/dist/index.d.ts
CHANGED
|
@@ -878,6 +878,8 @@ interface GroupByVariableState extends MultiValueVariableState {
|
|
|
878
878
|
name: string;
|
|
879
879
|
/** The visible keys to group on */
|
|
880
880
|
defaultOptions?: MetricFindValue[];
|
|
881
|
+
/** Options obtained through URL sync */
|
|
882
|
+
urlOptions?: MetricFindValue[];
|
|
881
883
|
/** Base filters to always apply when looking up keys */
|
|
882
884
|
baseFilters?: AdHocVariableFilter[];
|
|
883
885
|
/** Datasource to use for getTagKeys and also controls which scene queries the group by should apply to */
|
|
@@ -913,6 +915,7 @@ type getTagKeysProvider = (set: GroupByVariable, currentKey: string | null) => P
|
|
|
913
915
|
declare class GroupByVariable extends MultiValueVariable<GroupByVariableState> {
|
|
914
916
|
static Component: typeof GroupByVariableRenderer;
|
|
915
917
|
isLazy: boolean;
|
|
918
|
+
protected _urlSync: SceneObjectUrlSyncHandler;
|
|
916
919
|
validateAndUpdate(): Observable<ValidateAndUpdateResult>;
|
|
917
920
|
private _updateValueGivenNewOptions;
|
|
918
921
|
getValueOptions(args: VariableGetOptionsArgs): Observable<VariableValueOption[]>;
|
package/dist/index.js
CHANGED
|
@@ -2840,6 +2840,59 @@ class CustomAllValue {
|
|
|
2840
2840
|
}
|
|
2841
2841
|
}
|
|
2842
2842
|
|
|
2843
|
+
class GroupByVariableUrlSyncHandler {
|
|
2844
|
+
constructor(_sceneObject) {
|
|
2845
|
+
this._sceneObject = _sceneObject;
|
|
2846
|
+
}
|
|
2847
|
+
getKey() {
|
|
2848
|
+
return `var-${this._sceneObject.state.name}`;
|
|
2849
|
+
}
|
|
2850
|
+
getKeys() {
|
|
2851
|
+
if (this._sceneObject.state.skipUrlSync) {
|
|
2852
|
+
return [];
|
|
2853
|
+
}
|
|
2854
|
+
return [this.getKey()];
|
|
2855
|
+
}
|
|
2856
|
+
getUrlState() {
|
|
2857
|
+
if (this._sceneObject.state.skipUrlSync) {
|
|
2858
|
+
return {};
|
|
2859
|
+
}
|
|
2860
|
+
let { value: values, text: texts } = this._sceneObject.state;
|
|
2861
|
+
values = Array.isArray(values) ? values : [values];
|
|
2862
|
+
texts = Array.isArray(texts) ? texts : [texts];
|
|
2863
|
+
const urlValue = lodash.zip(values, texts).map(toUrlValues);
|
|
2864
|
+
return { [this.getKey()]: urlValue };
|
|
2865
|
+
}
|
|
2866
|
+
updateFromUrl(values) {
|
|
2867
|
+
let urlValue = values[this.getKey()];
|
|
2868
|
+
if (urlValue != null) {
|
|
2869
|
+
if (!this._sceneObject.isActive) {
|
|
2870
|
+
this._sceneObject.skipNextValidation = true;
|
|
2871
|
+
}
|
|
2872
|
+
urlValue = Array.isArray(urlValue) ? urlValue : [urlValue];
|
|
2873
|
+
const valuesLabelsPairs = urlValue.map((value) => value ? value.split(",") : [value]);
|
|
2874
|
+
let [values2, labels] = lodash.unzip(valuesLabelsPairs);
|
|
2875
|
+
values2 = (values2 != null ? values2 : []).map(unescapeUrlDelimiters);
|
|
2876
|
+
labels = (labels != null ? labels : []).map(unescapeUrlDelimiters);
|
|
2877
|
+
this._sceneObject.setState({
|
|
2878
|
+
urlOptions: values2.map((value, idx) => ({
|
|
2879
|
+
value,
|
|
2880
|
+
text: labels[idx]
|
|
2881
|
+
}))
|
|
2882
|
+
});
|
|
2883
|
+
this._sceneObject.changeValueTo(values2, labels);
|
|
2884
|
+
}
|
|
2885
|
+
}
|
|
2886
|
+
}
|
|
2887
|
+
function toUrlValues([value, label]) {
|
|
2888
|
+
if (value === void 0 || value === null) {
|
|
2889
|
+
return "";
|
|
2890
|
+
}
|
|
2891
|
+
value = String(value);
|
|
2892
|
+
label = label === void 0 || label === null ? value : String(label);
|
|
2893
|
+
return toUrlCommaDelimitedString(value, label);
|
|
2894
|
+
}
|
|
2895
|
+
|
|
2843
2896
|
var __defProp$z = Object.defineProperty;
|
|
2844
2897
|
var __defProps$n = Object.defineProperties;
|
|
2845
2898
|
var __getOwnPropDescs$n = Object.getOwnPropertyDescriptors;
|
|
@@ -2876,6 +2929,7 @@ class GroupByVariable extends MultiValueVariable {
|
|
|
2876
2929
|
noValueOnClear: true
|
|
2877
2930
|
}));
|
|
2878
2931
|
this.isLazy = true;
|
|
2932
|
+
this._urlSync = new GroupByVariableUrlSyncHandler(this);
|
|
2879
2933
|
this._getKeys = async (ds) => {
|
|
2880
2934
|
var _a, _b, _c;
|
|
2881
2935
|
const override = await ((_b = (_a = this.state).getTagKeysProvider) == null ? void 0 : _b.call(_a, this, null));
|
|
@@ -2925,9 +2979,11 @@ class GroupByVariable extends MultiValueVariable {
|
|
|
2925
2979
|
this.setState(stateUpdate);
|
|
2926
2980
|
}
|
|
2927
2981
|
getValueOptions(args) {
|
|
2982
|
+
var _a;
|
|
2983
|
+
const urlOptions = (_a = this.state.urlOptions) != null ? _a : [];
|
|
2928
2984
|
if (this.state.defaultOptions) {
|
|
2929
2985
|
return rxjs.of(
|
|
2930
|
-
this.state.defaultOptions.map((o) => ({
|
|
2986
|
+
lodash.unionBy(this.state.defaultOptions, urlOptions, "value").map((o) => ({
|
|
2931
2987
|
label: o.text,
|
|
2932
2988
|
value: String(o.value)
|
|
2933
2989
|
}))
|
|
@@ -2943,7 +2999,7 @@ class GroupByVariable extends MultiValueVariable {
|
|
|
2943
2999
|
return rxjs.from(this._getKeys(ds)).pipe(
|
|
2944
3000
|
rxjs.take(1),
|
|
2945
3001
|
rxjs.mergeMap((data) => {
|
|
2946
|
-
const a = data.map((i) => {
|
|
3002
|
+
const a = lodash.unionBy(data, urlOptions, "value").map((i) => {
|
|
2947
3003
|
return {
|
|
2948
3004
|
label: i.text,
|
|
2949
3005
|
value: i.value ? String(i.value) : i.text
|
|
@@ -2961,14 +3017,24 @@ class GroupByVariable extends MultiValueVariable {
|
|
|
2961
3017
|
}
|
|
2962
3018
|
GroupByVariable.Component = GroupByVariableRenderer;
|
|
2963
3019
|
function GroupByVariableRenderer({ model }) {
|
|
2964
|
-
const { value, key, maxVisibleValues, noValueOnClear } = model.useState();
|
|
2965
|
-
const
|
|
3020
|
+
const { value, text, key, maxVisibleValues, noValueOnClear } = model.useState();
|
|
3021
|
+
const values = React.useMemo(() => {
|
|
3022
|
+
const arrayValue = lodash.isArray(value) ? value : [value];
|
|
3023
|
+
const arrayText = lodash.isArray(text) ? text : [text];
|
|
3024
|
+
return arrayValue.map((value2, idx) => {
|
|
3025
|
+
var _a;
|
|
3026
|
+
return {
|
|
3027
|
+
value: value2,
|
|
3028
|
+
label: String((_a = arrayText[idx]) != null ? _a : value2)
|
|
3029
|
+
};
|
|
3030
|
+
});
|
|
3031
|
+
}, [value, text]);
|
|
2966
3032
|
const [isFetchingOptions, setIsFetchingOptions] = React.useState(false);
|
|
2967
3033
|
const [isOptionsOpen, setIsOptionsOpen] = React.useState(false);
|
|
2968
|
-
const [uncommittedValue, setUncommittedValue] = React.useState(
|
|
3034
|
+
const [uncommittedValue, setUncommittedValue] = React.useState(values);
|
|
2969
3035
|
React.useEffect(() => {
|
|
2970
|
-
setUncommittedValue(
|
|
2971
|
-
}, [
|
|
3036
|
+
setUncommittedValue(values);
|
|
3037
|
+
}, [values]);
|
|
2972
3038
|
const onInputChange = model.onSearchChange ? (value2, meta) => {
|
|
2973
3039
|
if (meta.action === "input-change") {
|
|
2974
3040
|
model.onSearchChange(value2);
|
|
@@ -2993,13 +3059,13 @@ function GroupByVariableRenderer({ model }) {
|
|
|
2993
3059
|
isLoading: isFetchingOptions,
|
|
2994
3060
|
onInputChange,
|
|
2995
3061
|
onBlur: () => {
|
|
2996
|
-
model.changeValueTo(uncommittedValue);
|
|
3062
|
+
model.changeValueTo(uncommittedValue.map((x) => x.value));
|
|
2997
3063
|
},
|
|
2998
3064
|
onChange: (newValue, action) => {
|
|
2999
3065
|
if (action.action === "clear" && noValueOnClear) {
|
|
3000
3066
|
model.changeValueTo([]);
|
|
3001
3067
|
}
|
|
3002
|
-
setUncommittedValue(newValue
|
|
3068
|
+
setUncommittedValue(newValue);
|
|
3003
3069
|
},
|
|
3004
3070
|
onOpenMenu: async () => {
|
|
3005
3071
|
setIsFetchingOptions(true);
|
|
@@ -3322,7 +3388,7 @@ class AdHocFiltersVariableUrlSyncHandler {
|
|
|
3322
3388
|
if (filters.length === 0) {
|
|
3323
3389
|
return { [this.getKey()]: [""] };
|
|
3324
3390
|
}
|
|
3325
|
-
const value = filters.map((filter) => toArray(filter).map(
|
|
3391
|
+
const value = filters.map((filter) => toArray(filter).map(escapeUrlPipeDelimiters).join("|"));
|
|
3326
3392
|
return { [this.getKey()]: value };
|
|
3327
3393
|
}
|
|
3328
3394
|
updateFromUrl(values) {
|
|
@@ -3342,39 +3408,13 @@ function deserializeUrlToFilters(value) {
|
|
|
3342
3408
|
const filter = toFilter(value);
|
|
3343
3409
|
return filter === null ? [] : [filter];
|
|
3344
3410
|
}
|
|
3345
|
-
function escapePipeDelimiters(value) {
|
|
3346
|
-
if (value === null || value === void 0) {
|
|
3347
|
-
return "";
|
|
3348
|
-
}
|
|
3349
|
-
return value = /\|/g[Symbol.replace](value, "__gfp__");
|
|
3350
|
-
}
|
|
3351
|
-
function escapeCommaDelimiters(value) {
|
|
3352
|
-
if (value === null || value === void 0) {
|
|
3353
|
-
return "";
|
|
3354
|
-
}
|
|
3355
|
-
return /,/g[Symbol.replace](value, "__gfc__");
|
|
3356
|
-
}
|
|
3357
|
-
function unescapeDelimiters(value) {
|
|
3358
|
-
if (value === null || value === void 0) {
|
|
3359
|
-
return "";
|
|
3360
|
-
}
|
|
3361
|
-
value = /__gfp__/g[Symbol.replace](value, "|");
|
|
3362
|
-
value = /__gfc__/g[Symbol.replace](value, ",");
|
|
3363
|
-
return value;
|
|
3364
|
-
}
|
|
3365
3411
|
function toArray(filter) {
|
|
3366
3412
|
return [
|
|
3367
|
-
|
|
3413
|
+
toUrlCommaDelimitedString(filter.key, filter.keyLabel),
|
|
3368
3414
|
filter.operator,
|
|
3369
|
-
|
|
3415
|
+
toUrlCommaDelimitedString(filter.value, filter.valueLabel)
|
|
3370
3416
|
];
|
|
3371
3417
|
}
|
|
3372
|
-
function toCommaDelimitedString(key, label) {
|
|
3373
|
-
if (!label || key === label) {
|
|
3374
|
-
return escapeCommaDelimiters(key);
|
|
3375
|
-
}
|
|
3376
|
-
return [key, label].map(escapeCommaDelimiters).join(",");
|
|
3377
|
-
}
|
|
3378
3418
|
function toFilter(urlValue) {
|
|
3379
3419
|
if (typeof urlValue !== "string" || urlValue.length === 0) {
|
|
3380
3420
|
return null;
|
|
@@ -3383,7 +3423,7 @@ function toFilter(urlValue) {
|
|
|
3383
3423
|
const [key2, label] = v.split(",");
|
|
3384
3424
|
acc.push(key2, label != null ? label : key2);
|
|
3385
3425
|
return acc;
|
|
3386
|
-
}, []).map(
|
|
3426
|
+
}, []).map(unescapeUrlDelimiters);
|
|
3387
3427
|
return {
|
|
3388
3428
|
key,
|
|
3389
3429
|
keyLabel,
|
|
@@ -4080,6 +4120,32 @@ function filterOutInactiveRunnerDuplicates(runners) {
|
|
|
4080
4120
|
return activeItems;
|
|
4081
4121
|
});
|
|
4082
4122
|
}
|
|
4123
|
+
function escapeUrlPipeDelimiters(value) {
|
|
4124
|
+
if (value === null || value === void 0) {
|
|
4125
|
+
return "";
|
|
4126
|
+
}
|
|
4127
|
+
return value = /\|/g[Symbol.replace](value, "__gfp__");
|
|
4128
|
+
}
|
|
4129
|
+
function escapeUrlCommaDelimiters(value) {
|
|
4130
|
+
if (value === null || value === void 0) {
|
|
4131
|
+
return "";
|
|
4132
|
+
}
|
|
4133
|
+
return /,/g[Symbol.replace](value, "__gfc__");
|
|
4134
|
+
}
|
|
4135
|
+
function unescapeUrlDelimiters(value) {
|
|
4136
|
+
if (value === null || value === void 0) {
|
|
4137
|
+
return "";
|
|
4138
|
+
}
|
|
4139
|
+
value = /__gfp__/g[Symbol.replace](value, "|");
|
|
4140
|
+
value = /__gfc__/g[Symbol.replace](value, ",");
|
|
4141
|
+
return value;
|
|
4142
|
+
}
|
|
4143
|
+
function toUrlCommaDelimitedString(key, label) {
|
|
4144
|
+
if (!label || key === label) {
|
|
4145
|
+
return escapeUrlCommaDelimiters(key);
|
|
4146
|
+
}
|
|
4147
|
+
return [key, label].map(escapeUrlCommaDelimiters).join(",");
|
|
4148
|
+
}
|
|
4083
4149
|
|
|
4084
4150
|
function isAdHocVariable(variable) {
|
|
4085
4151
|
return variable.state.type === "adhoc";
|