@grafana/scenes 6.19.0 → 6.20.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/CHANGELOG.md +17 -0
- package/dist/esm/querying/SceneQueryRunner.js +4 -6
- package/dist/esm/querying/SceneQueryRunner.js.map +1 -1
- package/dist/esm/variables/VariableDependencyConfig.js +12 -32
- package/dist/esm/variables/VariableDependencyConfig.js.map +1 -1
- package/dist/esm/variables/adhoc/AdHocFiltersCombobox/AdHocFiltersComboboxRenderer.js +2 -2
- package/dist/esm/variables/adhoc/AdHocFiltersCombobox/AdHocFiltersComboboxRenderer.js.map +1 -1
- package/dist/esm/variables/adhoc/AdHocFiltersVariable.js +43 -51
- package/dist/esm/variables/adhoc/AdHocFiltersVariable.js.map +1 -1
- package/dist/esm/variables/adhoc/AdHocFiltersVariableUrlSyncHandler.js +32 -28
- package/dist/esm/variables/adhoc/AdHocFiltersVariableUrlSyncHandler.js.map +1 -1
- package/dist/esm/variables/utils.js +2 -2
- package/dist/esm/variables/utils.js.map +1 -1
- package/dist/index.d.ts +3 -0
- package/dist/index.js +92 -118
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"utils.js","sources":["../../../src/variables/utils.ts"],"sourcesContent":["import { isEqual } from 'lodash';\nimport { VariableValue } from './types';\nimport { AdHocVariableFilter, DataQueryError, GetTagResponse, MetricFindValue, SelectableValue } from '@grafana/data';\nimport { sceneGraph } from '../core/sceneGraph';\nimport { SceneDataQuery, SceneObject, SceneObjectState } from '../core/types';\nimport { 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 let operator = filter.operator;\n\n // map \"one of\" operator to regex\n if (operator === '=|') {\n operator = '=~';\n // TODO remove when we're on the latest version of @grafana/data\n // @ts-expect-error\n value = filter.values?.map(escapeLabelValueInRegexSelector).join('|');\n } else if (operator === '!=|') {\n operator = '!~';\n // TODO remove when we're on the latest version of @grafana/data\n // @ts-expect-error\n value = filter.values?.map(escapeLabelValueInRegexSelector).join('|');\n } else if (operator === '=~' || operator === '!~') {\n value = escapeLabelValueInRegexSelector(filter.value);\n } else {\n value = escapeLabelValueInExactSelector(filter.value);\n }\n\n return `${filter.key}${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 interpolatedDsUuid = sceneGraph.interpolate(sourceObject, sourceObject.state.datasource?.uid);\n\n const applicableRunners = filterOutInactiveRunnerDuplicates(runners).filter((r) => {\n const interpolatedQueryDsUuid = sceneGraph.interpolate(sourceObject, r.state.datasource?.uid);\n\n return interpolatedQueryDsUuid === interpolatedDsUuid;\n });\n\n if (applicableRunners.length === 0) {\n return [];\n }\n\n const result: SceneDataQuery[] = [];\n applicableRunners.forEach((r) => {\n result.push(\n ...r.state.queries.filter((q) => {\n if (!q.datasource || !q.datasource.uid) {\n return true;\n }\n\n const interpolatedQueryDsUuid = sceneGraph.interpolate(sourceObject, q.datasource.uid);\n return interpolatedQueryDsUuid === interpolatedDsUuid;\n })\n );\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 escapeUrlHashDelimiters(value: string | undefined): string {\n if (value === null || value === undefined) {\n return '';\n }\n\n // Replace the hash due to using it as a value/label separator\n return /#/g[Symbol.replace](value, '__gfh__');\n}\n\nexport function escapeInjectedFilterUrlDelimiters(value: string | undefined): string {\n return escapeUrlHashDelimiters(escapeUrlPipeDelimiters(value));\n}\n\nexport function escapeURLDelimiters(value: string | undefined): string {\n return escapeUrlCommaDelimiters(escapeUrlPipeDelimiters(value));\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 value = /__gfh__/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\nexport function dataFromResponse(response: GetTagResponse | MetricFindValue[]) {\n return Array.isArray(response) ? response : response.data;\n}\n\nexport function responseHasError(\n response: GetTagResponse | MetricFindValue[]\n): response is GetTagResponse & { error: DataQueryError } {\n return !Array.isArray(response) && Boolean(response.error);\n}\n\n// Collect a flat list of SelectableValues with a `group` property into a hierarchical list with groups\nexport function handleOptionGroups(values: SelectableValue[]): Array<SelectableValue<string>> {\n const result: Array<SelectableValue<string>> = [];\n const groupedResults = new Map<string, Array<SelectableValue<string>>>();\n\n for (const value of values) {\n const groupLabel = value.group;\n if (groupLabel) {\n let group = groupedResults.get(groupLabel);\n\n if (!group) {\n group = [];\n groupedResults.set(groupLabel, group);\n result.push({ label: groupLabel, options: group });\n }\n\n group.push(value);\n } else {\n result.push(value);\n }\n }\n\n return result;\n}\n"],"names":["value","_a"],"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, DataQueryError, GetTagResponse, MetricFindValue, SelectableValue } from '@grafana/data';\nimport { sceneGraph } from '../core/sceneGraph';\nimport { SceneDataQuery, SceneObject, SceneObjectState } from '../core/types';\nimport { 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 let operator = filter.operator;\n\n // map \"one of\" operator to regex\n if (operator === '=|') {\n operator = '=~';\n // TODO remove when we're on the latest version of @grafana/data\n // @ts-expect-error\n value = filter.values?.map(escapeLabelValueInRegexSelector).join('|');\n } else if (operator === '!=|') {\n operator = '!~';\n // TODO remove when we're on the latest version of @grafana/data\n // @ts-expect-error\n value = filter.values?.map(escapeLabelValueInRegexSelector).join('|');\n } else if (operator === '=~' || operator === '!~') {\n value = escapeLabelValueInRegexSelector(filter.value);\n } else {\n value = escapeLabelValueInExactSelector(filter.value);\n }\n\n return `${filter.key}${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 interpolatedDsUuid = sceneGraph.interpolate(sourceObject, sourceObject.state.datasource?.uid);\n\n const applicableRunners = filterOutInactiveRunnerDuplicates(runners).filter((r) => {\n const interpolatedQueryDsUuid = sceneGraph.interpolate(sourceObject, r.state.datasource?.uid);\n\n return interpolatedQueryDsUuid === interpolatedDsUuid;\n });\n\n if (applicableRunners.length === 0) {\n return [];\n }\n\n const result: SceneDataQuery[] = [];\n applicableRunners.forEach((r) => {\n result.push(\n ...r.state.queries.filter((q) => {\n if (!q.datasource || !q.datasource.uid) {\n return true;\n }\n\n const interpolatedQueryDsUuid = sceneGraph.interpolate(sourceObject, q.datasource.uid);\n return interpolatedQueryDsUuid === interpolatedDsUuid;\n })\n );\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 escapeUrlHashDelimiters(value: string | undefined): string {\n if (value === null || value === undefined) {\n return '';\n }\n\n // Replace the hash due to using it as a value/label separator\n return /#/g[Symbol.replace](value, '__gfh__');\n}\n\nexport function escapeOriginFilterUrlDelimiters(value: string | undefined): string {\n return escapeUrlHashDelimiters(escapeUrlPipeDelimiters(value));\n}\n\nexport function escapeURLDelimiters(value: string | undefined): string {\n return escapeUrlCommaDelimiters(escapeUrlPipeDelimiters(value));\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 value = /__gfh__/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\nexport function dataFromResponse(response: GetTagResponse | MetricFindValue[]) {\n return Array.isArray(response) ? response : response.data;\n}\n\nexport function responseHasError(\n response: GetTagResponse | MetricFindValue[]\n): response is GetTagResponse & { error: DataQueryError } {\n return !Array.isArray(response) && Boolean(response.error);\n}\n\n// Collect a flat list of SelectableValues with a `group` property into a hierarchical list with groups\nexport function handleOptionGroups(values: SelectableValue[]): Array<SelectableValue<string>> {\n const result: Array<SelectableValue<string>> = [];\n const groupedResults = new Map<string, Array<SelectableValue<string>>>();\n\n for (const value of values) {\n const groupLabel = value.group;\n if (groupLabel) {\n let group = groupedResults.get(groupLabel);\n\n if (!group) {\n group = [];\n groupedResults.set(groupLabel, group);\n result.push({ label: groupLabel, options: group });\n }\n\n group.push(value);\n } else {\n result.push(value);\n }\n }\n\n return result;\n}\n"],"names":["value","_a"],"mappings":"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"}
|
package/dist/index.d.ts
CHANGED
@@ -849,6 +849,8 @@ interface AdHocFiltersVariableState extends SceneVariableState {
|
|
849
849
|
filters: AdHocFilterWithLabels[];
|
850
850
|
/** Base filters to always apply when looking up keys*/
|
851
851
|
baseFilters?: AdHocFilterWithLabels[];
|
852
|
+
/** Filters originated from a source */
|
853
|
+
originFilters?: AdHocFilterWithLabels[];
|
852
854
|
/** Datasource to use for getTagKeys and getTagValues and also controls which scene queries the filters should apply to */
|
853
855
|
datasource: DataSourceRef | null;
|
854
856
|
/** Controls if the filters can be changed */
|
@@ -943,6 +945,7 @@ declare class AdHocFiltersVariable extends SceneObjectBase<AdHocFiltersVariableS
|
|
943
945
|
private _scopedVars;
|
944
946
|
private _dataSourceSrv;
|
945
947
|
private _originalValues;
|
948
|
+
private _prevScopes;
|
946
949
|
/** Needed for scopes dependency */
|
947
950
|
protected _variableDependency: VariableDependencyConfig<AdHocFiltersVariableState>;
|
948
951
|
protected _urlSync: AdHocFiltersVariableUrlSyncHandler;
|
package/dist/index.js
CHANGED
@@ -3957,20 +3957,20 @@ class AdHocFiltersVariableUrlSyncHandler {
|
|
3957
3957
|
}
|
3958
3958
|
getUrlState() {
|
3959
3959
|
const filters = this._variable.state.filters;
|
3960
|
-
const
|
3960
|
+
const originFilters = this._variable.state.originFilters;
|
3961
3961
|
let value = [];
|
3962
|
-
if (filters.length === 0 && (
|
3962
|
+
if (filters.length === 0 && (originFilters == null ? void 0 : originFilters.length) === 0) {
|
3963
3963
|
return { [this.getKey()]: [""] };
|
3964
3964
|
}
|
3965
3965
|
if (filters.length) {
|
3966
3966
|
value.push(
|
3967
|
-
...filters.filter(isFilterComplete).filter((filter) => !filter.hidden).map((filter) => toArray(filter).map(
|
3967
|
+
...filters.filter(isFilterComplete).filter((filter) => !filter.hidden).map((filter) => toArray(filter).map(escapeOriginFilterUrlDelimiters).join("|"))
|
3968
3968
|
);
|
3969
3969
|
}
|
3970
|
-
if (
|
3970
|
+
if (originFilters == null ? void 0 : originFilters.length) {
|
3971
3971
|
value.push(
|
3972
|
-
...
|
3973
|
-
(filter) => toArray(filter).map(
|
3972
|
+
...originFilters == null ? void 0 : originFilters.filter(isFilterComplete).filter((filter) => !filter.hidden && filter.origin && filter.restorable).map(
|
3973
|
+
(filter) => toArray(filter).map(escapeOriginFilterUrlDelimiters).join("|").concat(`#${filter.origin}#restorable`)
|
3974
3974
|
)
|
3975
3975
|
);
|
3976
3976
|
}
|
@@ -3984,31 +3984,35 @@ class AdHocFiltersVariableUrlSyncHandler {
|
|
3984
3984
|
return;
|
3985
3985
|
}
|
3986
3986
|
const filters = deserializeUrlToFilters(urlValue);
|
3987
|
-
const
|
3988
|
-
for (let i = 0; i < filters.length; i++) {
|
3989
|
-
const foundBaseFilterIndex = baseFilters.findIndex((f) => f.key === filters[i].key);
|
3990
|
-
if (foundBaseFilterIndex > -1) {
|
3991
|
-
if (!filters[i].origin && baseFilters[foundBaseFilterIndex].origin === "dashboard") {
|
3992
|
-
filters[i].origin = "dashboard";
|
3993
|
-
filters[i].restorable = true;
|
3994
|
-
}
|
3995
|
-
if (isMatchAllFilter(filters[i])) {
|
3996
|
-
filters[i].matchAllFilter = true;
|
3997
|
-
}
|
3998
|
-
baseFilters[foundBaseFilterIndex] = filters[i];
|
3999
|
-
} else if (filters[i].origin === "dashboard") {
|
4000
|
-
delete filters[i].origin;
|
4001
|
-
delete filters[i].restorable;
|
4002
|
-
} else if (foundBaseFilterIndex === -1 && filters[i].origin === "scope" && filters[i].restorable) {
|
4003
|
-
baseFilters.push(filters[i]);
|
4004
|
-
}
|
4005
|
-
}
|
3987
|
+
const originFilters = updateOriginFilters([...this._variable.state.originFilters || []], filters);
|
4006
3988
|
this._variable.setState({
|
4007
3989
|
filters: filters.filter((f) => !f.origin),
|
4008
|
-
|
3990
|
+
originFilters
|
4009
3991
|
});
|
4010
3992
|
}
|
4011
3993
|
}
|
3994
|
+
function updateOriginFilters(prevOriginFilters, filters) {
|
3995
|
+
const updatedOriginFilters = [...prevOriginFilters];
|
3996
|
+
for (let i = 0; i < filters.length; i++) {
|
3997
|
+
const foundOriginFilterIndex = prevOriginFilters.findIndex((f) => f.key === filters[i].key);
|
3998
|
+
if (foundOriginFilterIndex > -1) {
|
3999
|
+
if (!filters[i].origin && prevOriginFilters[foundOriginFilterIndex].origin === "dashboard") {
|
4000
|
+
filters[i].origin = "dashboard";
|
4001
|
+
filters[i].restorable = true;
|
4002
|
+
}
|
4003
|
+
if (isMatchAllFilter(filters[i])) {
|
4004
|
+
filters[i].matchAllFilter = true;
|
4005
|
+
}
|
4006
|
+
updatedOriginFilters[foundOriginFilterIndex] = filters[i];
|
4007
|
+
} else if (filters[i].origin === "dashboard") {
|
4008
|
+
delete filters[i].origin;
|
4009
|
+
delete filters[i].restorable;
|
4010
|
+
} else if (foundOriginFilterIndex === -1 && filters[i].origin === "scope" && filters[i].restorable) {
|
4011
|
+
updatedOriginFilters.push(filters[i]);
|
4012
|
+
}
|
4013
|
+
}
|
4014
|
+
return updatedOriginFilters;
|
4015
|
+
}
|
4012
4016
|
function deserializeUrlToFilters(value) {
|
4013
4017
|
if (Array.isArray(value)) {
|
4014
4018
|
const values = value;
|
@@ -5336,7 +5340,7 @@ const AdHocFiltersAlwaysWipCombobox = React.forwardRef(function AdHocFiltersAlwa
|
|
5336
5340
|
});
|
5337
5341
|
|
5338
5342
|
const AdHocFiltersComboboxRenderer = React.memo(function AdHocFiltersComboboxRenderer2({ model }) {
|
5339
|
-
const {
|
5343
|
+
const { originFilters, filters, readOnly } = model.useState();
|
5340
5344
|
const styles = ui.useStyles2(getStyles$a);
|
5341
5345
|
const focusOnWipInputRef = React.useRef();
|
5342
5346
|
return /* @__PURE__ */ React__default.default.createElement(
|
@@ -5349,7 +5353,7 @@ const AdHocFiltersComboboxRenderer = React.memo(function AdHocFiltersComboboxRen
|
|
5349
5353
|
}
|
5350
5354
|
},
|
5351
5355
|
/* @__PURE__ */ React__default.default.createElement(ui.Icon, { name: "filter", className: styles.filterIcon, size: "lg" }),
|
5352
|
-
|
5356
|
+
originFilters == null ? void 0 : originFilters.map(
|
5353
5357
|
(filter, index) => filter.origin ? /* @__PURE__ */ React__default.default.createElement(
|
5354
5358
|
AdHocFilterPill,
|
5355
5359
|
{
|
@@ -5513,17 +5517,14 @@ const OPERATORS = [
|
|
5513
5517
|
];
|
5514
5518
|
class AdHocFiltersVariable extends SceneObjectBase {
|
5515
5519
|
constructor(state) {
|
5516
|
-
var _a, _b, _c, _d, _e
|
5520
|
+
var _a, _b, _c, _d, _e;
|
5517
5521
|
super({
|
5518
5522
|
type: "adhoc",
|
5519
5523
|
name: (_a = state.name) != null ? _a : "Filters",
|
5520
5524
|
filters: [],
|
5521
5525
|
datasource: null,
|
5522
5526
|
applyMode: "auto",
|
5523
|
-
filterExpression: (
|
5524
|
-
...(_c = (_b = state.baseFilters) == null ? void 0 : _b.filter((filter) => filter.origin)) != null ? _c : [],
|
5525
|
-
...(_d = state.filters) != null ? _d : []
|
5526
|
-
]),
|
5527
|
+
filterExpression: (_d = state.filterExpression) != null ? _d : renderExpression(state.expressionBuilder, [...(_b = state.originFilters) != null ? _b : [], ...(_c = state.filters) != null ? _c : []]),
|
5527
5528
|
...state
|
5528
5529
|
});
|
5529
5530
|
this._scopedVars = { __sceneObject: wrapInSafeSerializableSceneObject(this) };
|
@@ -5532,6 +5533,7 @@ class AdHocFiltersVariable extends SceneObjectBase {
|
|
5532
5533
|
// are set on construct and used to restore a baseFilter with an origin
|
5533
5534
|
// to its original value if edited at some point
|
5534
5535
|
this._originalValues = /* @__PURE__ */ new Map();
|
5536
|
+
this._prevScopes = [];
|
5535
5537
|
/** Needed for scopes dependency */
|
5536
5538
|
this._variableDependency = new VariableDependencyConfig(this, {
|
5537
5539
|
dependsOnScopes: true,
|
@@ -5539,44 +5541,33 @@ class AdHocFiltersVariable extends SceneObjectBase {
|
|
5539
5541
|
});
|
5540
5542
|
this._urlSync = new AdHocFiltersVariableUrlSyncHandler(this);
|
5541
5543
|
this._activationHandler = () => {
|
5542
|
-
this._updateScopesFilters();
|
5543
5544
|
return () => {
|
5544
|
-
var _a
|
5545
|
-
|
5546
|
-
|
5547
|
-
|
5548
|
-
}
|
5549
|
-
|
5550
|
-
if (filter.origin === "dashboard" && filter.restorable) {
|
5551
|
-
this.restoreOriginalFilter(filter);
|
5552
|
-
}
|
5553
|
-
});
|
5554
|
-
}
|
5545
|
+
var _a;
|
5546
|
+
(_a = this.state.originFilters) == null ? void 0 : _a.forEach((filter) => {
|
5547
|
+
if (filter.restorable) {
|
5548
|
+
this.restoreOriginalFilter(filter);
|
5549
|
+
}
|
5550
|
+
});
|
5555
5551
|
};
|
5556
5552
|
};
|
5557
5553
|
if (this.state.applyMode === "auto") {
|
5558
5554
|
patchGetAdhocFilters(this);
|
5559
5555
|
}
|
5560
|
-
(
|
5556
|
+
(_e = this.state.originFilters) == null ? void 0 : _e.forEach((filter) => {
|
5561
5557
|
var _a2;
|
5562
|
-
|
5563
|
-
|
5564
|
-
|
5565
|
-
|
5566
|
-
});
|
5567
|
-
}
|
5558
|
+
this._originalValues.set(filter.key, {
|
5559
|
+
operator: filter.operator,
|
5560
|
+
value: (_a2 = filter.values) != null ? _a2 : [filter.value]
|
5561
|
+
});
|
5568
5562
|
});
|
5569
5563
|
this.addActivationHandler(this._activationHandler);
|
5570
5564
|
}
|
5571
5565
|
_updateScopesFilters() {
|
5572
5566
|
var _a, _b;
|
5573
5567
|
const scopes = sceneGraph.getScopes(this);
|
5574
|
-
if (!scopes) {
|
5575
|
-
return;
|
5576
|
-
}
|
5577
|
-
if (!scopes.length) {
|
5568
|
+
if (!scopes || !scopes.length) {
|
5578
5569
|
this.setState({
|
5579
|
-
|
5570
|
+
originFilters: (_a = this.state.originFilters) == null ? void 0 : _a.filter((filter) => filter.origin !== "scope")
|
5580
5571
|
});
|
5581
5572
|
return;
|
5582
5573
|
}
|
@@ -5594,13 +5585,18 @@ class AdHocFiltersVariable extends SceneObjectBase {
|
|
5594
5585
|
operator: scopeFilter.operator
|
5595
5586
|
});
|
5596
5587
|
});
|
5597
|
-
(_b = this.state.
|
5588
|
+
(_b = this.state.originFilters) == null ? void 0 : _b.forEach((filter) => {
|
5598
5589
|
if (filter.origin === "scope") {
|
5599
5590
|
scopeInjectedFilters.push(filter);
|
5600
5591
|
} else {
|
5601
5592
|
remainingFilters.push(filter);
|
5602
5593
|
}
|
5603
5594
|
});
|
5595
|
+
if (this._prevScopes.length) {
|
5596
|
+
this.setState({ originFilters: [...finalFilters, ...remainingFilters] });
|
5597
|
+
this._prevScopes = scopes;
|
5598
|
+
return;
|
5599
|
+
}
|
5604
5600
|
const editedScopeFilters = scopeInjectedFilters.filter((filter) => filter.restorable);
|
5605
5601
|
const editedScopeFilterKeys = editedScopeFilters.map((filter) => filter.key);
|
5606
5602
|
const scopeFilterKeys = scopeFilters.map((filter) => filter.key);
|
@@ -5608,18 +5604,16 @@ class AdHocFiltersVariable extends SceneObjectBase {
|
|
5608
5604
|
...editedScopeFilters.filter((filter) => scopeFilterKeys.includes(filter.key)),
|
5609
5605
|
...scopeFilters.filter((filter) => !editedScopeFilterKeys.includes(filter.key))
|
5610
5606
|
];
|
5611
|
-
this.setState({
|
5607
|
+
this.setState({ originFilters: [...finalFilters, ...remainingFilters] });
|
5608
|
+
this._prevScopes = scopes;
|
5612
5609
|
}
|
5613
5610
|
setState(update) {
|
5614
|
-
var _a, _b
|
5611
|
+
var _a, _b;
|
5615
5612
|
let filterExpressionChanged = false;
|
5616
|
-
if ((update.filters && update.filters !== this.state.filters || update.
|
5613
|
+
if ((update.filters && update.filters !== this.state.filters || update.originFilters && update.originFilters !== this.state.originFilters) && !update.filterExpression) {
|
5617
5614
|
const filters = (_a = update.filters) != null ? _a : this.state.filters;
|
5618
|
-
const
|
5619
|
-
update.filterExpression = renderExpression(this.state.expressionBuilder, [
|
5620
|
-
...(_c = baseFilters == null ? void 0 : baseFilters.filter((filter) => filter.origin)) != null ? _c : [],
|
5621
|
-
...filters != null ? filters : []
|
5622
|
-
]);
|
5615
|
+
const originFilters = (_b = update.originFilters) != null ? _b : this.state.originFilters;
|
5616
|
+
update.filterExpression = renderExpression(this.state.expressionBuilder, [...originFilters != null ? originFilters : [], ...filters]);
|
5623
5617
|
filterExpressionChanged = update.filterExpression !== this.state.filterExpression;
|
5624
5618
|
}
|
5625
5619
|
super.setState(update);
|
@@ -5633,12 +5627,12 @@ class AdHocFiltersVariable extends SceneObjectBase {
|
|
5633
5627
|
* allowing consumers to update the filters without triggering dependent data providers.
|
5634
5628
|
*/
|
5635
5629
|
updateFilters(filters, options) {
|
5636
|
-
var _a
|
5630
|
+
var _a;
|
5637
5631
|
let filterExpressionChanged = false;
|
5638
5632
|
let filterExpression = void 0;
|
5639
5633
|
if (filters && filters !== this.state.filters) {
|
5640
5634
|
filterExpression = renderExpression(this.state.expressionBuilder, [
|
5641
|
-
...(
|
5635
|
+
...(_a = this.state.originFilters) != null ? _a : [],
|
5642
5636
|
...filters
|
5643
5637
|
]);
|
5644
5638
|
filterExpressionChanged = filterExpression !== this.state.filterExpression;
|
@@ -5658,32 +5652,34 @@ class AdHocFiltersVariable extends SceneObjectBase {
|
|
5658
5652
|
};
|
5659
5653
|
if (filter.restorable) {
|
5660
5654
|
const originalFilter = this._originalValues.get(filter.key);
|
5655
|
+
if (!originalFilter) {
|
5656
|
+
return;
|
5657
|
+
}
|
5661
5658
|
original.value = originalFilter == null ? void 0 : originalFilter.value[0];
|
5662
5659
|
original.values = originalFilter == null ? void 0 : originalFilter.value;
|
5663
5660
|
original.valueLabels = originalFilter == null ? void 0 : originalFilter.value;
|
5664
5661
|
original.operator = originalFilter == null ? void 0 : originalFilter.operator;
|
5662
|
+
this._updateFilter(filter, original);
|
5665
5663
|
}
|
5666
|
-
this._updateFilter(filter, original);
|
5667
5664
|
}
|
5668
5665
|
getValue() {
|
5669
5666
|
return this.state.filterExpression;
|
5670
5667
|
}
|
5671
5668
|
_updateFilter(filter, update) {
|
5672
5669
|
var _a;
|
5673
|
-
const {
|
5670
|
+
const { originFilters, filters, _wip } = this.state;
|
5674
5671
|
if (filter.origin) {
|
5675
5672
|
const originalValues = this._originalValues.get(filter.key);
|
5676
5673
|
const updateValues = update.values || (update.value ? [update.value] : void 0);
|
5677
|
-
|
5678
|
-
if (!isRestorableOverride && (updateValues && !lodash.isEqual(updateValues, originalValues == null ? void 0 : originalValues.value) || update.operator && update.operator !== (originalValues == null ? void 0 : originalValues.operator))) {
|
5674
|
+
if (updateValues && !lodash.isEqual(updateValues, originalValues == null ? void 0 : originalValues.value) || update.operator && update.operator !== (originalValues == null ? void 0 : originalValues.operator)) {
|
5679
5675
|
update.restorable = true;
|
5680
5676
|
} else if (updateValues && lodash.isEqual(updateValues, originalValues == null ? void 0 : originalValues.value)) {
|
5681
5677
|
update.restorable = false;
|
5682
5678
|
}
|
5683
|
-
const
|
5679
|
+
const updatedFilters2 = (_a = originFilters == null ? void 0 : originFilters.map((f) => {
|
5684
5680
|
return f === filter ? { ...f, ...update } : f;
|
5685
5681
|
})) != null ? _a : [];
|
5686
|
-
this.setState({
|
5682
|
+
this.setState({ originFilters: updatedFilters2 });
|
5687
5683
|
return;
|
5688
5684
|
}
|
5689
5685
|
if (filter === _wip) {
|
@@ -5746,13 +5742,13 @@ class AdHocFiltersVariable extends SceneObjectBase {
|
|
5746
5742
|
return [...acc, f];
|
5747
5743
|
}, [])
|
5748
5744
|
});
|
5749
|
-
} else if ((_a = this.state.
|
5750
|
-
let filterToForceIndex = this.state.
|
5745
|
+
} else if ((_a = this.state.originFilters) == null ? void 0 : _a.length) {
|
5746
|
+
let filterToForceIndex = this.state.originFilters.length - 1;
|
5751
5747
|
if (filter !== this.state._wip) {
|
5752
5748
|
filterToForceIndex = -1;
|
5753
5749
|
}
|
5754
5750
|
this.setState({
|
5755
|
-
|
5751
|
+
originFilters: this.state.originFilters.reduce((acc, f, index) => {
|
5756
5752
|
if (index === filterToForceIndex && !f.readOnly) {
|
5757
5753
|
return [
|
5758
5754
|
...acc,
|
@@ -5822,8 +5818,8 @@ class AdHocFiltersVariable extends SceneObjectBase {
|
|
5822
5818
|
if (!ds || !ds.getTagValues) {
|
5823
5819
|
return [];
|
5824
5820
|
}
|
5825
|
-
const
|
5826
|
-
const otherFilters = this.state.filters.filter((f) => f.key !== filter.key).concat(
|
5821
|
+
const originFilters = (_d = (_c = this.state.originFilters) == null ? void 0 : _c.filter((f) => f.key !== filter.key)) != null ? _d : [];
|
5822
|
+
const otherFilters = this.state.filters.filter((f) => f.key !== filter.key).concat(originFilters);
|
5827
5823
|
const timeRange = sceneGraph.getTimeRange(this).state.value;
|
5828
5824
|
const queries = this.state.useQueriesAsFilterForOptions ? getQueriesForVariables(this) : void 0;
|
5829
5825
|
let scopes = sceneGraph.getScopes(this);
|
@@ -6307,12 +6303,10 @@ class SceneQueryRunner extends SceneObjectBase {
|
|
6307
6303
|
...getEnrichedDataRequest(this)
|
6308
6304
|
};
|
6309
6305
|
if (this._adhocFiltersVar) {
|
6310
|
-
request.filters = [
|
6311
|
-
|
6312
|
-
|
6313
|
-
|
6314
|
-
}
|
6315
|
-
request.filters = request.filters.concat(this._adhocFiltersVar.state.filters.filter(isFilterComplete));
|
6306
|
+
request.filters = [
|
6307
|
+
...(_a = this._adhocFiltersVar.state.originFilters) != null ? _a : [],
|
6308
|
+
...this._adhocFiltersVar.state.filters
|
6309
|
+
].filter(isFilterComplete);
|
6316
6310
|
}
|
6317
6311
|
if (this._groupByVar) {
|
6318
6312
|
request.groupByKeys = this._groupByVar.state.value;
|
@@ -6549,7 +6543,7 @@ function escapeUrlHashDelimiters(value) {
|
|
6549
6543
|
}
|
6550
6544
|
return /#/g[Symbol.replace](value, "__gfh__");
|
6551
6545
|
}
|
6552
|
-
function
|
6546
|
+
function escapeOriginFilterUrlDelimiters(value) {
|
6553
6547
|
return escapeUrlHashDelimiters(escapeUrlPipeDelimiters(value));
|
6554
6548
|
}
|
6555
6549
|
function escapeURLDelimiters(value) {
|
@@ -6651,11 +6645,9 @@ class VariableDependencyConfig {
|
|
6651
6645
|
* This is called whenever any set of variables have new values. It is up to this implementation to check if it's relevant given the current dependencies.
|
6652
6646
|
*/
|
6653
6647
|
variableUpdateCompleted(variable, hasChanged) {
|
6648
|
+
var _a, _b, _c, _d;
|
6654
6649
|
const deps = this.getNames();
|
6655
|
-
|
6656
|
-
if ((deps.has(variable.state.name) || deps.has(data.DataLinkBuiltInVars.includeVars)) && hasChanged) {
|
6657
|
-
dependencyChanged = true;
|
6658
|
-
}
|
6650
|
+
const dependencyChanged = (deps.has(variable.state.name) || deps.has(data.DataLinkBuiltInVars.includeVars)) && hasChanged;
|
6659
6651
|
writeSceneLog(
|
6660
6652
|
"VariableDependencyConfig",
|
6661
6653
|
"variableUpdateCompleted",
|
@@ -6663,47 +6655,29 @@ class VariableDependencyConfig {
|
|
6663
6655
|
dependencyChanged,
|
6664
6656
|
this._isWaitingForVariables
|
6665
6657
|
);
|
6666
|
-
|
6667
|
-
this._options.onAnyVariableChanged(variable);
|
6668
|
-
}
|
6658
|
+
(_b = (_a = this._options).onAnyVariableChanged) == null ? void 0 : _b.call(_a, variable);
|
6669
6659
|
if (this._options.onVariableUpdateCompleted && (this._isWaitingForVariables || dependencyChanged)) {
|
6670
6660
|
this._options.onVariableUpdateCompleted();
|
6671
6661
|
}
|
6672
6662
|
if (dependencyChanged) {
|
6673
|
-
|
6674
|
-
this._options.onReferencedVariableValueChanged(variable);
|
6675
|
-
}
|
6663
|
+
(_d = (_c = this._options).onReferencedVariableValueChanged) == null ? void 0 : _d.call(_c, variable);
|
6676
6664
|
if (!this._options.onReferencedVariableValueChanged && !this._options.onVariableUpdateCompleted) {
|
6677
6665
|
this._sceneObject.forceRender();
|
6678
6666
|
}
|
6679
6667
|
}
|
6680
6668
|
}
|
6681
6669
|
hasDependencyInLoadingState() {
|
6682
|
-
|
6683
|
-
|
6684
|
-
return true;
|
6685
|
-
}
|
6686
|
-
this._isWaitingForVariables = false;
|
6687
|
-
return false;
|
6670
|
+
this._isWaitingForVariables = sceneGraph.hasVariableDependencyInLoadingState(this._sceneObject);
|
6671
|
+
return this._isWaitingForVariables;
|
6688
6672
|
}
|
6689
6673
|
getNames() {
|
6690
6674
|
const prevState = this._state;
|
6691
6675
|
const newState = this._state = this._sceneObject.state;
|
6692
|
-
|
6693
|
-
|
6694
|
-
|
6695
|
-
|
6696
|
-
|
6697
|
-
if (this._statePaths) {
|
6698
|
-
for (const path of this._statePaths) {
|
6699
|
-
if (path === "*" || newState[path] !== prevState[path]) {
|
6700
|
-
this.scanStateForDependencies(newState);
|
6701
|
-
break;
|
6702
|
-
}
|
6703
|
-
}
|
6704
|
-
} else {
|
6705
|
-
this.scanStateForDependencies(newState);
|
6706
|
-
}
|
6676
|
+
const noPreviousState = !prevState;
|
6677
|
+
const stateDiffers = newState !== prevState;
|
6678
|
+
const shouldScanForDependencies = noPreviousState || stateDiffers && (!this._statePaths || this._statePaths.some((path) => path === "*" || newState[path] !== prevState[path]));
|
6679
|
+
if (shouldScanForDependencies) {
|
6680
|
+
this.scanStateForDependencies(newState);
|
6707
6681
|
}
|
6708
6682
|
return this._dependencies;
|
6709
6683
|
}
|
@@ -6719,7 +6693,7 @@ class VariableDependencyConfig {
|
|
6719
6693
|
}
|
6720
6694
|
scanStateForDependencies(state) {
|
6721
6695
|
this._dependencies.clear();
|
6722
|
-
this.scanCount
|
6696
|
+
this.scanCount++;
|
6723
6697
|
if (this._options.variableNames) {
|
6724
6698
|
for (const name of this._options.variableNames) {
|
6725
6699
|
this._dependencies.add(name);
|