@grafana/scenes 6.4.0 → 6.5.0--canary.1062.13949528214.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.
@@ -117,6 +117,15 @@ function escapeUrlCommaDelimiters(value) {
117
117
  }
118
118
  return /,/g[Symbol.replace](value, "__gfc__");
119
119
  }
120
+ function escapeUrlHashDelimiters(value) {
121
+ if (value === null || value === void 0) {
122
+ return "";
123
+ }
124
+ return /#/g[Symbol.replace](value, "__gfh__");
125
+ }
126
+ function escapeInjectedFilterUrlDelimiters(value) {
127
+ return escapeUrlHashDelimiters(escapeUrlPipeDelimiters(value));
128
+ }
120
129
  function escapeURLDelimiters(value) {
121
130
  return escapeUrlCommaDelimiters(escapeUrlPipeDelimiters(value));
122
131
  }
@@ -126,6 +135,7 @@ function unescapeUrlDelimiters(value) {
126
135
  }
127
136
  value = /__gfp__/g[Symbol.replace](value, "|");
128
137
  value = /__gfc__/g[Symbol.replace](value, ",");
138
+ value = /__gfh__/g[Symbol.replace](value, "#");
129
139
  return value;
130
140
  }
131
141
  function toUrlCommaDelimitedString(key, label) {
@@ -160,5 +170,5 @@ function handleOptionGroups(values) {
160
170
  return result;
161
171
  }
162
172
 
163
- export { dataFromResponse, escapeLabelValueInExactSelector, escapeLabelValueInRegexSelector, escapeURLDelimiters, escapeUrlCommaDelimiters, escapeUrlPipeDelimiters, getQueriesForVariables, handleOptionGroups, isVariableValueEqual, renderPrometheusLabelFilters, responseHasError, safeStringifyValue, toUrlCommaDelimitedString, unescapeUrlDelimiters };
173
+ export { dataFromResponse, escapeInjectedFilterUrlDelimiters, escapeLabelValueInExactSelector, escapeLabelValueInRegexSelector, escapeURLDelimiters, escapeUrlCommaDelimiters, escapeUrlHashDelimiters, escapeUrlPipeDelimiters, getQueriesForVariables, handleOptionGroups, isVariableValueEqual, renderPrometheusLabelFilters, responseHasError, safeStringifyValue, toUrlCommaDelimitedString, unescapeUrlDelimiters };
164
174
  //# 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, 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 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\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 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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"}
package/dist/index.d.ts CHANGED
@@ -878,6 +878,7 @@ interface AdHocFilterWithLabels<M extends Record<string, any> = {}> extends AdHo
878
878
  hidden?: boolean;
879
879
  meta?: M;
880
880
  origin?: FilterOrigin;
881
+ originalValue?: string[];
881
882
  }
882
883
  type AdHocControlsLayout = ControlsLayout | 'combobox';
883
884
  declare enum FilterOrigin {
@@ -985,9 +986,11 @@ declare class AdHocFiltersVariable extends SceneObjectBase<AdHocFiltersVariableS
985
986
  private _scopedVars;
986
987
  private _dataSourceSrv;
987
988
  private _scopesBridge;
989
+ private _overwriteScopes;
988
990
  protected _urlSync: AdHocFiltersVariableUrlSyncHandler;
989
991
  constructor(state: Partial<AdHocFiltersVariableState>);
990
992
  private _activationHandler;
993
+ private _updateScopesFilters;
991
994
  setState(update: Partial<AdHocFiltersVariableState>): void;
992
995
  /**
993
996
  * Updates the variable's `filters` and `filterExpression` state.
@@ -998,6 +1001,7 @@ declare class AdHocFiltersVariable extends SceneObjectBase<AdHocFiltersVariableS
998
1001
  skipPublish?: boolean;
999
1002
  forcePublish?: boolean;
1000
1003
  }): void;
1004
+ restoreOriginalFilter(filter: AdHocFilterWithLabels): void;
1001
1005
  getValue(): VariableValue | undefined;
1002
1006
  _updateFilter(filter: AdHocFilterWithLabels, update: Partial<AdHocFilterWithLabels>): void;
1003
1007
  _removeFilter(filter: AdHocFilterWithLabels): void;
package/dist/index.js CHANGED
@@ -3972,19 +3972,44 @@ class AdHocFiltersVariableUrlSyncHandler {
3972
3972
  }
3973
3973
  getUrlState() {
3974
3974
  const filters = this._variable.state.filters;
3975
- if (filters.length === 0) {
3975
+ const baseFilters = this._variable.state.baseFilters;
3976
+ let value = [];
3977
+ if (filters.length === 0 && (baseFilters == null ? void 0 : baseFilters.length) === 0) {
3976
3978
  return { [this.getKey()]: [""] };
3977
3979
  }
3978
- const value = filters.filter(isFilterComplete).filter((filter) => !filter.hidden).map((filter) => toArray(filter).map(escapeUrlPipeDelimiters).join("|"));
3979
- return { [this.getKey()]: value };
3980
+ if (filters.length) {
3981
+ value.push(
3982
+ ...filters.filter(isFilterComplete).filter((filter) => !filter.hidden).map((filter) => toArray(filter).map(escapeUrlPipeDelimiters).join("|"))
3983
+ );
3984
+ }
3985
+ if (baseFilters == null ? void 0 : baseFilters.length) {
3986
+ value.push(
3987
+ ...baseFilters == null ? void 0 : baseFilters.filter(isFilterComplete).filter((filter) => !filter.hidden && filter.origin && filter.originalValue).map(
3988
+ (filter) => {
3989
+ var _a, _b;
3990
+ return toArray(filter).map(escapeInjectedFilterUrlDelimiters).join("|").concat(
3991
+ `#${(_b = (_a = filter.originalValue) == null ? void 0 : _a.map(escapeInjectedFilterUrlDelimiters).join("|")) != null ? _b : ""}#${filter.origin}`
3992
+ );
3993
+ }
3994
+ )
3995
+ );
3996
+ }
3997
+ return {
3998
+ [this.getKey()]: value.length ? value : [""]
3999
+ };
3980
4000
  }
3981
4001
  updateFromUrl(values) {
3982
4002
  const urlValue = values[this.getKey()];
3983
4003
  if (urlValue == null) {
3984
4004
  return;
3985
4005
  }
3986
- const filters = deserializeUrlToFilters(urlValue);
3987
- this._variable.setState({ filters });
4006
+ if (urlValue) {
4007
+ const filters = deserializeUrlToFilters(urlValue);
4008
+ this._variable.setState({
4009
+ filters: filters.filter((f) => !f.origin),
4010
+ baseFilters: filters.filter((f) => f.origin)
4011
+ });
4012
+ }
3988
4013
  }
3989
4014
  }
3990
4015
  function deserializeUrlToFilters(value) {
@@ -4009,10 +4034,12 @@ function toArray(filter) {
4009
4034
  return result;
4010
4035
  }
4011
4036
  function toFilter(urlValue) {
4037
+ var _a;
4012
4038
  if (typeof urlValue !== "string" || urlValue.length === 0) {
4013
4039
  return null;
4014
4040
  }
4015
- const [key, keyLabel, operator, _operatorLabel, ...values] = urlValue.split("|").reduce((acc, v) => {
4041
+ const [filter, originalValues, origin] = urlValue.split("#");
4042
+ const [key, keyLabel, operator, _operatorLabel, ...values] = filter.split("|").reduce((acc, v) => {
4016
4043
  const [key2, label] = v.split(",");
4017
4044
  acc.push(key2, label != null ? label : key2);
4018
4045
  return acc;
@@ -4024,9 +4051,14 @@ function toFilter(urlValue) {
4024
4051
  value: values[0],
4025
4052
  values: isMultiValueOperator(operator) ? values.filter((_, index) => index % 2 === 0) : void 0,
4026
4053
  valueLabels: values.filter((_, index) => index % 2 === 1),
4027
- condition: ""
4054
+ condition: "",
4055
+ origin: isFilterOrigin(origin) ? origin : void 0,
4056
+ originalValue: originalValues && originalValues.length ? (_a = originalValues.split("|")) != null ? _a : [originalValues] : void 0
4028
4057
  };
4029
4058
  }
4059
+ function isFilterOrigin(value) {
4060
+ return value === FilterOrigin.Scopes || value === FilterOrigin.Dashboards;
4061
+ }
4030
4062
  function isFilter(filter) {
4031
4063
  return filter !== null && typeof filter.key === "string" && typeof filter.value === "string";
4032
4064
  }
@@ -4688,6 +4720,9 @@ const AdHocCombobox = React.forwardRef(function AdHocCombobox2({ filter, model,
4688
4720
  return;
4689
4721
  }
4690
4722
  }
4723
+ if (filter == null ? void 0 : filter.origin) {
4724
+ return;
4725
+ }
4691
4726
  setInputType("operator");
4692
4727
  return;
4693
4728
  }
@@ -4874,25 +4909,36 @@ const AdHocCombobox = React.forwardRef(function AdHocCombobox2({ filter, model,
4874
4909
  className: styles.pillWrapper
4875
4910
  }, (filter == null ? void 0 : filter.key) ? /* @__PURE__ */ React__default["default"].createElement("div", {
4876
4911
  className: css.cx(styles.basePill, styles.keyPill)
4877
- }, keyLabel) : null, (filter == null ? void 0 : filter.key) && (filter == null ? void 0 : filter.operator) && filterInputType !== "operator" ? /* @__PURE__ */ React__default["default"].createElement("div", {
4912
+ }, keyLabel) : null, (filter == null ? void 0 : filter.key) && (filter == null ? void 0 : filter.operator) && filterInputType !== "operator" ? /* @__PURE__ */ React__default["default"].createElement("div", __spreadValues$B({
4878
4913
  id: operatorIdentifier,
4879
- className: css.cx(styles.basePill, styles.operatorPill, operatorIdentifier),
4880
- role: "button",
4914
+ className: css.cx(
4915
+ styles.basePill,
4916
+ !filter.origin && styles.operatorPill,
4917
+ filter.origin && styles.keyPill,
4918
+ operatorIdentifier
4919
+ ),
4881
4920
  "aria-label": "Edit filter operator",
4882
- tabIndex: 0,
4921
+ tabIndex: filter.origin ? -1 : 0,
4883
4922
  onClick: (event) => {
4923
+ if (filter.origin) {
4924
+ handleChangeViewMode == null ? void 0 : handleChangeViewMode();
4925
+ return;
4926
+ }
4884
4927
  event.stopPropagation();
4885
4928
  setInputValue("");
4886
4929
  switchInputType("operator", setInputType, void 0, refs.domReference.current);
4887
4930
  },
4888
4931
  onKeyDown: (event) => {
4932
+ if (filter.origin) {
4933
+ return;
4934
+ }
4889
4935
  handleShiftTabInput(event, hasMultiValueOperator);
4890
4936
  if (event.key === "Enter") {
4891
4937
  setInputValue("");
4892
4938
  switchInputType("operator", setInputType, void 0, refs.domReference.current);
4893
4939
  }
4894
4940
  }
4895
- }, filter.operator) : null, /* @__PURE__ */ React__default["default"].createElement("div", {
4941
+ }, !filter.origin && { role: "button" }), filter.operator) : null, /* @__PURE__ */ React__default["default"].createElement("div", {
4896
4942
  ref: multiValuePillWrapperRef
4897
4943
  }), isMultiValueEdit ? filterMultiValues.map((item, i) => /* @__PURE__ */ React__default["default"].createElement(MultiValuePill, {
4898
4944
  key: `${item.value}-${i}`,
@@ -5139,13 +5185,13 @@ function AdHocFilterPill({ filter, model, readOnly, focusOnWipInputRef }) {
5139
5185
  const handleChangeViewMode = React.useCallback(
5140
5186
  (event, shouldFocusOnPillWrapperOverride) => {
5141
5187
  event == null ? void 0 : event.stopPropagation();
5142
- if (readOnly || filter.origin) {
5188
+ if (readOnly) {
5143
5189
  return;
5144
5190
  }
5145
5191
  setShouldFocusOnPillWrapper(shouldFocusOnPillWrapperOverride != null ? shouldFocusOnPillWrapperOverride : !viewMode);
5146
5192
  setViewMode(!viewMode);
5147
5193
  },
5148
- [readOnly, viewMode, filter.origin]
5194
+ [readOnly, viewMode]
5149
5195
  );
5150
5196
  React.useEffect(() => {
5151
5197
  var _a2;
@@ -5209,11 +5255,20 @@ function AdHocFilterPill({ filter, model, readOnly, focusOnWipInputRef }) {
5209
5255
  size: "md",
5210
5256
  className: styles.pillIcon,
5211
5257
  tooltip: `Remove filter with key ${keyLabel}`
5212
- }) : null, filter.origin && /* @__PURE__ */ React__default["default"].createElement(ui.IconButton, {
5258
+ }) : null, filter.origin && !filter.originalValue && /* @__PURE__ */ React__default["default"].createElement(ui.IconButton, {
5213
5259
  name: "info-circle",
5214
5260
  size: "md",
5215
5261
  className: styles.pillIcon,
5216
5262
  tooltip: `This is a ${filter.origin} injected filter`
5263
+ }), filter.origin && filter.originalValue && /* @__PURE__ */ React__default["default"].createElement(ui.IconButton, {
5264
+ onClick: (e) => {
5265
+ e.stopPropagation();
5266
+ model.restoreOriginalFilter(filter);
5267
+ },
5268
+ name: "history",
5269
+ size: "md",
5270
+ className: styles.pillIcon,
5271
+ tooltip: `Restore filter to its original value`
5217
5272
  }));
5218
5273
  }
5219
5274
  return /* @__PURE__ */ React__default["default"].createElement(AdHocCombobox, {
@@ -5347,6 +5402,73 @@ const getStyles$a = (theme) => ({
5347
5402
  })
5348
5403
  });
5349
5404
 
5405
+ const reverseScopeFilterOperatorMap = Object.fromEntries(
5406
+ Object.entries(data.scopeFilterOperatorMap).map(([symbol, operator]) => [operator, symbol])
5407
+ );
5408
+ function isEqualityOrMultiOperator(value) {
5409
+ const operators = /* @__PURE__ */ new Set(["equals", "not-equals", "one-of", "not-one-of"]);
5410
+ return operators.has(value);
5411
+ }
5412
+ function getAdHocFiltersFromScopes(scopes) {
5413
+ const formattedFilters = /* @__PURE__ */ new Map();
5414
+ const duplicatedFilters = [];
5415
+ const allFilters = scopes.flatMap((scope) => scope.spec.filters);
5416
+ for (const filter of allFilters) {
5417
+ processFilter(formattedFilters, duplicatedFilters, filter);
5418
+ }
5419
+ return [...formattedFilters.values(), ...duplicatedFilters];
5420
+ }
5421
+ function processFilter(formattedFilters, duplicatedFilters, filter) {
5422
+ var _a, _b;
5423
+ const existingFilter = formattedFilters.get(filter.key);
5424
+ if (existingFilter && canValueBeMerged(existingFilter.operator, filter.operator)) {
5425
+ mergeFilterValues(existingFilter, filter);
5426
+ } else if (!existingFilter) {
5427
+ formattedFilters.set(filter.key, {
5428
+ key: filter.key,
5429
+ operator: reverseScopeFilterOperatorMap[filter.operator],
5430
+ value: filter.value,
5431
+ values: (_a = filter.values) != null ? _a : [filter.value],
5432
+ origin: FilterOrigin.Scopes
5433
+ });
5434
+ } else {
5435
+ duplicatedFilters.push({
5436
+ key: filter.key,
5437
+ operator: reverseScopeFilterOperatorMap[filter.operator],
5438
+ value: filter.value,
5439
+ values: (_b = filter.values) != null ? _b : [filter.value],
5440
+ origin: FilterOrigin.Scopes
5441
+ });
5442
+ }
5443
+ }
5444
+ function mergeFilterValues(adHocFilter, filter) {
5445
+ var _a, _b, _c, _d;
5446
+ const values = (_a = filter.values) != null ? _a : [filter.value];
5447
+ for (const value of values) {
5448
+ if (!((_b = adHocFilter.values) == null ? void 0 : _b.includes(value))) {
5449
+ (_c = adHocFilter.values) == null ? void 0 : _c.push(value);
5450
+ }
5451
+ }
5452
+ if (((_d = adHocFilter.values) == null ? void 0 : _d.length) === 1) {
5453
+ return;
5454
+ }
5455
+ if (filter.operator === "equals" && adHocFilter.operator === reverseScopeFilterOperatorMap["equals"]) {
5456
+ adHocFilter.operator = reverseScopeFilterOperatorMap["one-of"];
5457
+ } else if (filter.operator === "not-equals" && adHocFilter.operator === reverseScopeFilterOperatorMap["not-equals"]) {
5458
+ adHocFilter.operator = reverseScopeFilterOperatorMap["not-one-of"];
5459
+ }
5460
+ }
5461
+ function canValueBeMerged(adHocFilterOperator, filterOperator) {
5462
+ const scopeConvertedOperator = data.scopeFilterOperatorMap[adHocFilterOperator];
5463
+ if (!isEqualityOrMultiOperator(scopeConvertedOperator) || !isEqualityOrMultiOperator(filterOperator)) {
5464
+ return false;
5465
+ }
5466
+ if (scopeConvertedOperator.includes("not") && !filterOperator.includes("not") || !scopeConvertedOperator.includes("not") && filterOperator.includes("not")) {
5467
+ return false;
5468
+ }
5469
+ return true;
5470
+ }
5471
+
5350
5472
  var __defProp$z = Object.defineProperty;
5351
5473
  var __defProps$n = Object.defineProperties;
5352
5474
  var __getOwnPropDescs$n = Object.getOwnPropertyDescriptors;
@@ -5411,20 +5533,68 @@ const OPERATORS = [
5411
5533
  ];
5412
5534
  class AdHocFiltersVariable extends SceneObjectBase {
5413
5535
  constructor(state) {
5414
- var _a, _b;
5536
+ var _a, _b, _c, _d, _e;
5415
5537
  super(__spreadValues$z({
5416
5538
  type: "adhoc",
5417
5539
  name: (_a = state.name) != null ? _a : "Filters",
5418
5540
  filters: [],
5419
5541
  datasource: null,
5420
5542
  applyMode: "auto",
5421
- filterExpression: (_b = state.filterExpression) != null ? _b : renderExpression(state.expressionBuilder, state.filters)
5543
+ filterExpression: (_e = state.filterExpression) != null ? _e : renderExpression(state.expressionBuilder, [
5544
+ ...(_c = (_b = state.baseFilters) == null ? void 0 : _b.filter((filter) => filter.origin)) != null ? _c : [],
5545
+ ...(_d = state.filters) != null ? _d : []
5546
+ ])
5422
5547
  }, state));
5423
5548
  this._scopedVars = { __sceneObject: wrapInSafeSerializableSceneObject(this) };
5424
5549
  this._dataSourceSrv = runtime.getDataSourceSrv();
5425
5550
  this._urlSync = new AdHocFiltersVariableUrlSyncHandler(this);
5426
5551
  this._activationHandler = () => {
5552
+ var _a, _b;
5427
5553
  this._scopesBridge = sceneGraph.getScopesBridge(this);
5554
+ const scopes = (_a = this._scopesBridge) == null ? void 0 : _a.getValue();
5555
+ if (scopes) {
5556
+ this._updateScopesFilters(scopes);
5557
+ }
5558
+ const sub = (_b = this._scopesBridge) == null ? void 0 : _b.subscribeToValue((n, _) => {
5559
+ var _a2;
5560
+ this._updateScopesFilters(n, (_a2 = this._scopesBridge) == null ? void 0 : _a2.isLoading());
5561
+ });
5562
+ return () => {
5563
+ sub == null ? void 0 : sub.unsubscribe();
5564
+ };
5565
+ };
5566
+ this._updateScopesFilters = (scopes, areScopesLoading) => {
5567
+ var _a;
5568
+ const scopeFilters = getAdHocFiltersFromScopes(scopes);
5569
+ if (!scopeFilters.length) {
5570
+ this._overwriteScopes = areScopesLoading;
5571
+ return;
5572
+ }
5573
+ let finalFilters = scopeFilters;
5574
+ const scopeInjectedFilters = [];
5575
+ const remainingFilters = [];
5576
+ (_a = this.state.baseFilters) == null ? void 0 : _a.forEach((filter) => {
5577
+ if (filter.origin === "scopes" /* Scopes */) {
5578
+ scopeInjectedFilters.push(filter);
5579
+ } else {
5580
+ remainingFilters.push(filter);
5581
+ }
5582
+ });
5583
+ if (!this._overwriteScopes) {
5584
+ const editedScopeFilters = scopeInjectedFilters.filter((filter) => {
5585
+ var _a2;
5586
+ return (_a2 = filter.originalValue) == null ? void 0 : _a2.length;
5587
+ });
5588
+ const editedScopeFilterKeys = editedScopeFilters.map((filter) => filter.key);
5589
+ const scopeFilterKeys = scopeFilters.map((filter) => filter.key);
5590
+ finalFilters = [
5591
+ ...editedScopeFilters.filter((filter) => scopeFilterKeys.includes(filter.key)),
5592
+ ...scopeFilters.filter((filter) => !editedScopeFilterKeys.includes(filter.key))
5593
+ ];
5594
+ this._overwriteScopes = false;
5595
+ }
5596
+ const newFilters = [...remainingFilters, ...finalFilters];
5597
+ this.setState({ baseFilters: newFilters });
5428
5598
  };
5429
5599
  if (this.state.applyMode === "auto") {
5430
5600
  patchGetAdhocFilters(this);
@@ -5432,9 +5602,15 @@ class AdHocFiltersVariable extends SceneObjectBase {
5432
5602
  this.addActivationHandler(this._activationHandler);
5433
5603
  }
5434
5604
  setState(update) {
5605
+ var _a, _b, _c;
5435
5606
  let filterExpressionChanged = false;
5436
- if (update.filters && update.filters !== this.state.filters && !update.filterExpression) {
5437
- update.filterExpression = renderExpression(this.state.expressionBuilder, update.filters);
5607
+ if ((update.filters && update.filters !== this.state.filters || update.baseFilters && update.baseFilters !== this.state.baseFilters) && !update.filterExpression) {
5608
+ const filters = (_a = update.filters) != null ? _a : this.state.filters;
5609
+ const baseFilters = (_b = update.baseFilters) != null ? _b : this.state.baseFilters;
5610
+ update.filterExpression = renderExpression(this.state.expressionBuilder, [
5611
+ ...(_c = baseFilters == null ? void 0 : baseFilters.filter((filter) => filter.origin)) != null ? _c : [],
5612
+ ...filters != null ? filters : []
5613
+ ]);
5438
5614
  filterExpressionChanged = update.filterExpression !== this.state.filterExpression;
5439
5615
  }
5440
5616
  super.setState(update);
@@ -5443,10 +5619,14 @@ class AdHocFiltersVariable extends SceneObjectBase {
5443
5619
  }
5444
5620
  }
5445
5621
  updateFilters(filters, options) {
5622
+ var _a, _b;
5446
5623
  let filterExpressionChanged = false;
5447
5624
  let filterExpression = void 0;
5448
5625
  if (filters && filters !== this.state.filters) {
5449
- filterExpression = renderExpression(this.state.expressionBuilder, filters);
5626
+ filterExpression = renderExpression(this.state.expressionBuilder, [
5627
+ ...(_b = (_a = this.state.baseFilters) == null ? void 0 : _a.filter((filter) => filter.origin)) != null ? _b : [],
5628
+ ...filters
5629
+ ]);
5450
5630
  filterExpressionChanged = filterExpression !== this.state.filterExpression;
5451
5631
  }
5452
5632
  super.setState({
@@ -5457,11 +5637,40 @@ class AdHocFiltersVariable extends SceneObjectBase {
5457
5637
  this.publishEvent(new SceneVariableValueChangedEvent(this), true);
5458
5638
  }
5459
5639
  }
5640
+ restoreOriginalFilter(filter) {
5641
+ var _a;
5642
+ const original = {
5643
+ originalValue: void 0
5644
+ };
5645
+ if ((_a = filter.originalValue) == null ? void 0 : _a.length) {
5646
+ original.value = filter.originalValue[0];
5647
+ original.values = filter.originalValue;
5648
+ original.valueLabels = filter.originalValue;
5649
+ }
5650
+ this._updateFilter(filter, original);
5651
+ }
5460
5652
  getValue() {
5461
5653
  return this.state.filterExpression;
5462
5654
  }
5463
5655
  _updateFilter(filter, update) {
5464
- const { filters, _wip } = this.state;
5656
+ var _a;
5657
+ const { baseFilters, filters, _wip } = this.state;
5658
+ if (filter.origin) {
5659
+ const currentValues = filter.values ? filter.values : [filter.value];
5660
+ const updateValues = update.values || (update.value ? [update.value] : void 0);
5661
+ const originalValueOverride = update.hasOwnProperty("originalValue");
5662
+ if (!originalValueOverride && updateValues && !filter.originalValue && !lodash.isEqual(currentValues, updateValues)) {
5663
+ update.originalValue = currentValues;
5664
+ }
5665
+ if (!originalValueOverride && lodash.isEqual(updateValues, filter.originalValue)) {
5666
+ update.originalValue = void 0;
5667
+ }
5668
+ const updatedBaseFilters = (_a = baseFilters == null ? void 0 : baseFilters.map((f) => {
5669
+ return f === filter ? __spreadValues$z(__spreadValues$z({}, f), update) : f;
5670
+ })) != null ? _a : [];
5671
+ this.setState({ baseFilters: updatedBaseFilters });
5672
+ return;
5673
+ }
5465
5674
  if (filter === _wip) {
5466
5675
  if ("value" in update && update["value"] !== "") {
5467
5676
  this.setState({ filters: [...filters, __spreadValues$z(__spreadValues$z({}, _wip), update)], _wip: void 0 });
@@ -5489,6 +5698,7 @@ class AdHocFiltersVariable extends SceneObjectBase {
5489
5698
  }
5490
5699
  }
5491
5700
  _handleComboboxBackspace(filter) {
5701
+ var _a;
5492
5702
  if (this.state.filters.length) {
5493
5703
  let filterToForceIndex = this.state.filters.length - 1;
5494
5704
  if (filter !== this.state._wip) {
@@ -5510,6 +5720,27 @@ class AdHocFiltersVariable extends SceneObjectBase {
5510
5720
  return [...acc, f];
5511
5721
  }, [])
5512
5722
  });
5723
+ } else if ((_a = this.state.baseFilters) == null ? void 0 : _a.length) {
5724
+ let filterToForceIndex = this.state.baseFilters.length - 1;
5725
+ if (filter !== this.state._wip) {
5726
+ filterToForceIndex = -1;
5727
+ }
5728
+ this.setState({
5729
+ baseFilters: this.state.baseFilters.reduce((acc, f, index) => {
5730
+ if (index === filterToForceIndex) {
5731
+ return [
5732
+ ...acc,
5733
+ __spreadProps$n(__spreadValues$z({}, f), {
5734
+ forceEdit: true
5735
+ })
5736
+ ];
5737
+ }
5738
+ if (f === filter) {
5739
+ return acc;
5740
+ }
5741
+ return [...acc, f];
5742
+ }, [])
5743
+ });
5513
5744
  }
5514
5745
  }
5515
5746
  async _getKeys(currentKey) {
@@ -5548,7 +5779,7 @@ class AdHocFiltersVariable extends SceneObjectBase {
5548
5779
  return keys.map(toSelectableValue);
5549
5780
  }
5550
5781
  async _getValuesFor(filter) {
5551
- var _a, _b, _c, _d;
5782
+ var _a, _b, _c, _d, _e;
5552
5783
  const override = await ((_b = (_a = this.state).getTagValuesProvider) == null ? void 0 : _b.call(_a, this, filter));
5553
5784
  if (override && override.replace) {
5554
5785
  return dataFromResponse(override.values).map(toSelectableValue);
@@ -5557,15 +5788,26 @@ class AdHocFiltersVariable extends SceneObjectBase {
5557
5788
  if (!ds || !ds.getTagValues) {
5558
5789
  return [];
5559
5790
  }
5560
- const otherFilters = this.state.filters.filter((f) => f.key !== filter.key).concat((_c = this.state.baseFilters) != null ? _c : []);
5791
+ const filteredBaseFilters = (_d = (_c = this.state.baseFilters) == null ? void 0 : _c.filter((f) => f.origin && f.key !== filter.key)) != null ? _d : [];
5792
+ const otherFilters = this.state.filters.filter((f) => f.key !== filter.key).concat(filteredBaseFilters);
5561
5793
  const timeRange = sceneGraph.getTimeRange(this).state.value;
5562
5794
  const queries = this.state.useQueriesAsFilterForOptions ? getQueriesForVariables(this) : void 0;
5795
+ let scopes = (_e = this._scopesBridge) == null ? void 0 : _e.getValue();
5796
+ if (filter.origin === "scopes" /* Scopes */) {
5797
+ scopes = scopes == null ? void 0 : scopes.map((scope) => {
5798
+ return __spreadProps$n(__spreadValues$z({}, scope), {
5799
+ spec: __spreadProps$n(__spreadValues$z({}, scope.spec), {
5800
+ filters: scope.spec.filters.filter((f) => f.key !== filter.key)
5801
+ })
5802
+ });
5803
+ });
5804
+ }
5563
5805
  const response = await ds.getTagValues(__spreadValues$z({
5564
5806
  key: filter.key,
5565
5807
  filters: otherFilters,
5566
5808
  timeRange,
5567
5809
  queries,
5568
- scopes: (_d = this._scopesBridge) == null ? void 0 : _d.getValue()
5810
+ scopes
5569
5811
  }, getEnrichedFiltersRequest(this)));
5570
5812
  if (responseHasError(response)) {
5571
5813
  this.setState({ error: response.error.message });
@@ -6284,6 +6526,15 @@ function escapeUrlCommaDelimiters(value) {
6284
6526
  }
6285
6527
  return /,/g[Symbol.replace](value, "__gfc__");
6286
6528
  }
6529
+ function escapeUrlHashDelimiters(value) {
6530
+ if (value === null || value === void 0) {
6531
+ return "";
6532
+ }
6533
+ return /#/g[Symbol.replace](value, "__gfh__");
6534
+ }
6535
+ function escapeInjectedFilterUrlDelimiters(value) {
6536
+ return escapeUrlHashDelimiters(escapeUrlPipeDelimiters(value));
6537
+ }
6287
6538
  function escapeURLDelimiters(value) {
6288
6539
  return escapeUrlCommaDelimiters(escapeUrlPipeDelimiters(value));
6289
6540
  }
@@ -6293,6 +6544,7 @@ function unescapeUrlDelimiters(value) {
6293
6544
  }
6294
6545
  value = /__gfp__/g[Symbol.replace](value, "|");
6295
6546
  value = /__gfc__/g[Symbol.replace](value, ",");
6547
+ value = /__gfh__/g[Symbol.replace](value, "#");
6296
6548
  return value;
6297
6549
  }
6298
6550
  function toUrlCommaDelimitedString(key, label) {
@@ -10738,11 +10990,7 @@ async function getExploreURL(data, model, timeRange, transform) {
10738
10990
  return (_a2 = transform == null ? void 0 : transform(q)) != null ? _a2 : q;
10739
10991
  });
10740
10992
  const queries = interpolatedQueries != null ? interpolatedQueries : [];
10741
- const hasMixedDatasources = new Set(queries.map((q) => {
10742
- var _a2;
10743
- return (_a2 = q.datasource) == null ? void 0 : _a2.uid;
10744
- })).size > 1;
10745
- let datasource = hasMixedDatasources ? "-- Mixed --" : (_d = (_c = queries.find((query) => {
10993
+ const datasource = (_d = (_c = queries.find((query) => {
10746
10994
  var _a2;
10747
10995
  return !!((_a2 = query.datasource) == null ? void 0 : _a2.uid);
10748
10996
  })) == null ? void 0 : _c.datasource) == null ? void 0 : _d.uid;
@@ -10772,12 +11020,10 @@ function VizPanelExploreButtonComponent({ model }) {
10772
11020
  const { options } = model.useState();
10773
11021
  const { data } = sceneGraph.getData(model).useState();
10774
11022
  const { from, to } = sceneGraph.getTimeRange(model).useState();
10775
- const { value: exploreLink } = reactUse.useAsync(async () => {
10776
- if (!data) {
10777
- return "";
10778
- }
10779
- return getExploreURL(data, model, { from, to }, options.transform);
10780
- }, [data, model, from, to]);
11023
+ const { value: exploreLink } = reactUse.useAsync(
11024
+ async () => data ? getExploreURL(data, model, { from, to }, options.transform) : "",
11025
+ [data, model, from, to]
11026
+ );
10781
11027
  const returnToPrevious = runtime.useReturnToPrevious();
10782
11028
  if (exploreLink) {
10783
11029
  return /* @__PURE__ */ React__default["default"].createElement(ui.LinkButton, {