@grafana/scenes 8.9.2 → 8.9.3

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.
@@ -1 +1 @@
1
- {"version":3,"file":"sceneInterpolator.js","sources":["../../../../src/variables/interpolation/sceneInterpolator.ts"],"sourcesContent":["import { ScopedVars } from '@grafana/data';\nimport { VariableInterpolation } from '@grafana/runtime';\nimport { VariableType, VariableFormatID } from '@grafana/schema';\n\nimport { SceneObject } from '../../core/types';\nimport { InterpolationFormatParameter, isCustomVariableValue, VariableValue } from '../types';\n\nimport { getSceneVariableForScopedVar } from './ScopedVarsVariable';\nimport { formatRegistry, FormatVariable } from './formatRegistry';\nimport { VARIABLE_REGEX } from '../constants';\nimport { lookupVariable } from '../lookupVariable';\nimport { macrosIndex } from '../macros';\n\n/**\n * This function will try to parse and replace any variable expression found in the target string. The sceneObject will be used as the source of variables. It will\n * use the scene graph and walk up the parent tree until it finds the closest variable.\n *\n * ScopedVars should not really be needed much in the new scene architecture as they can be added to the local scene node instead of passed in interpolate function.\n * It is supported here for backward compatibility and some edge cases where adding scoped vars to local scene node is not practical.\n */\nexport function sceneInterpolator(\n sceneObject: SceneObject,\n target: string | undefined | null,\n scopedVars?: ScopedVars,\n format?: InterpolationFormatParameter,\n interpolations?: VariableInterpolation[]\n): string {\n if (!target || typeof target !== 'string') {\n return target ?? '';\n }\n\n VARIABLE_REGEX.lastIndex = 0;\n\n return target.replace(VARIABLE_REGEX, (match, var1, var2, fmt2, var3, fieldPath, fmt3) => {\n const variableName = var1 || var2 || var3;\n const fmt = fmt2 || fmt3 || format;\n const variable = lookupFormatVariable(variableName, match, scopedVars, sceneObject);\n\n if (!variable) {\n if (interpolations) {\n // Set `value` equal to `match` as documented in the `VariableInterpolation` interface.\n interpolations.push({ match, variableName, fieldPath, format: fmt, value: match, found: false });\n }\n return match;\n }\n\n const value = formatValue(sceneObject, variable, variable.getValue(fieldPath), fmt, fieldPath);\n\n if (interpolations) {\n interpolations.push({ match, variableName, fieldPath, format: fmt, value, found: value !== match });\n }\n\n return value;\n });\n}\n\nfunction lookupFormatVariable(\n name: string,\n match: string,\n scopedVars: ScopedVars | undefined,\n sceneObject: SceneObject\n): FormatVariable | null {\n if (scopedVars && scopedVars.hasOwnProperty(name)) {\n const scopedVar = scopedVars[name];\n\n if (scopedVar) {\n return getSceneVariableForScopedVar(name, scopedVar);\n }\n }\n\n const variable = lookupVariable(name, sceneObject);\n if (variable) {\n return variable;\n }\n\n const Macro = macrosIndex.get(name);\n if (Macro) {\n return new Macro(name, sceneObject, match, scopedVars);\n }\n\n return null;\n}\n\nfunction formatValue(\n context: SceneObject,\n variable: FormatVariable,\n value: VariableValue | undefined | null,\n formatNameOrFn?: InterpolationFormatParameter,\n fieldPath?: string\n): string {\n if (value === null || value === undefined) {\n return '';\n }\n\n // Variable can return a custom value that handles formatting\n // This is useful for customAllValue and macros that return values that are already formatted or need special formatting\n if (isCustomVariableValue(value)) {\n return sceneInterpolator(context, value.formatter(formatNameOrFn));\n }\n\n // if it's an object transform value to string\n if (!Array.isArray(value) && typeof value === 'object') {\n value = `${value}`;\n }\n\n if (typeof formatNameOrFn === 'function') {\n return formatNameOrFn(value, {\n name: variable.state.name,\n type: variable.state.type as VariableType,\n multi: variable.state.isMulti,\n includeAll: variable.state.includeAll,\n });\n }\n\n let args: string[] = [];\n\n if (!formatNameOrFn) {\n formatNameOrFn = VariableFormatID.Glob;\n } else {\n // some formats have arguments that come after ':' character\n args = formatNameOrFn.split(':');\n if (args.length > 1) {\n formatNameOrFn = args[0];\n args = args.slice(1);\n } else {\n args = [];\n }\n }\n\n let formatter = formatRegistry.getIfExists(formatNameOrFn);\n\n if (!formatter) {\n console.error(`Variable format ${formatNameOrFn} not found. Using glob format as fallback.`);\n formatter = formatRegistry.get(VariableFormatID.Glob);\n }\n\n return formatter.formatter(value, args, variable, fieldPath);\n}\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"sceneInterpolator.js","sources":["../../../../src/variables/interpolation/sceneInterpolator.ts"],"sourcesContent":["import { ScopedVars } from '@grafana/data';\nimport { VariableInterpolation } from '@grafana/runtime';\nimport { VariableType, VariableFormatID } from '@grafana/schema';\n\nimport { SceneObject } from '../../core/types';\nimport { InterpolationFormatParameter, isCustomVariableValue, VariableValue } from '../types';\n\nimport { getSceneVariableForScopedVar } from './ScopedVarsVariable';\nimport { formatRegistry, FormatVariable } from './formatRegistry';\nimport { VARIABLE_REGEX } from '../constants';\nimport { lookupVariable } from '../lookupVariable';\nimport { macrosIndex } from '../macros';\n\n/**\n * This function will try to parse and replace any variable expression found in the target string. The sceneObject will be used as the source of variables. It will\n * use the scene graph and walk up the parent tree until it finds the closest variable.\n *\n * ScopedVars should not really be needed much in the new scene architecture as they can be added to the local scene node instead of passed in interpolate function.\n * It is supported here for backward compatibility and some edge cases where adding scoped vars to local scene node is not practical.\n */\nexport function sceneInterpolator(\n sceneObject: SceneObject,\n target: string | undefined | null,\n scopedVars?: ScopedVars,\n format?: InterpolationFormatParameter,\n interpolations?: VariableInterpolation[]\n): string {\n if (!target || typeof target !== 'string') {\n return target ?? '';\n }\n\n VARIABLE_REGEX.lastIndex = 0;\n\n return target.replace(VARIABLE_REGEX, (match, var1, var2, fmt2, var3, rawFieldPath, fmt3) => {\n const variableName = var1 || var2 || var3;\n const fmt = fmt2 || fmt3 || format;\n // The widened regex captures the leading `.` for dot-paths (`.field`), whereas the legacy\n // regex captured `field`. Strip one leading dot so dot-path consumers (getValue/getFieldAccessor)\n // and the VariableInterpolation instrumentation see the same string as before. Bracket paths\n // (`[\"env\"]`, `[\"env\"].operator`) start with `[` and are passed through untouched.\n const fieldPath =\n rawFieldPath && rawFieldPath.charCodeAt(0) === 0x2e /* '.' */ ? rawFieldPath.slice(1) : rawFieldPath || undefined;\n const variable = lookupFormatVariable(variableName, match, scopedVars, sceneObject);\n\n if (!variable) {\n if (interpolations) {\n // Set `value` equal to `match` as documented in the `VariableInterpolation` interface.\n interpolations.push({ match, variableName, fieldPath, format: fmt, value: match, found: false });\n }\n return match;\n }\n\n const value = formatValue(sceneObject, variable, variable.getValue(fieldPath), fmt, fieldPath);\n\n if (interpolations) {\n interpolations.push({ match, variableName, fieldPath, format: fmt, value, found: value !== match });\n }\n\n return value;\n });\n}\n\nfunction lookupFormatVariable(\n name: string,\n match: string,\n scopedVars: ScopedVars | undefined,\n sceneObject: SceneObject\n): FormatVariable | null {\n if (scopedVars && scopedVars.hasOwnProperty(name)) {\n const scopedVar = scopedVars[name];\n\n if (scopedVar) {\n return getSceneVariableForScopedVar(name, scopedVar);\n }\n }\n\n const variable = lookupVariable(name, sceneObject);\n if (variable) {\n return variable;\n }\n\n const Macro = macrosIndex.get(name);\n if (Macro) {\n return new Macro(name, sceneObject, match, scopedVars);\n }\n\n return null;\n}\n\nfunction formatValue(\n context: SceneObject,\n variable: FormatVariable,\n value: VariableValue | undefined | null,\n formatNameOrFn?: InterpolationFormatParameter,\n fieldPath?: string\n): string {\n if (value === null || value === undefined) {\n return '';\n }\n\n // Variable can return a custom value that handles formatting\n // This is useful for customAllValue and macros that return values that are already formatted or need special formatting\n if (isCustomVariableValue(value)) {\n return sceneInterpolator(context, value.formatter(formatNameOrFn));\n }\n\n // if it's an object transform value to string\n if (!Array.isArray(value) && typeof value === 'object') {\n value = `${value}`;\n }\n\n if (typeof formatNameOrFn === 'function') {\n return formatNameOrFn(value, {\n name: variable.state.name,\n type: variable.state.type as VariableType,\n multi: variable.state.isMulti,\n includeAll: variable.state.includeAll,\n });\n }\n\n let args: string[] = [];\n\n if (!formatNameOrFn) {\n formatNameOrFn = VariableFormatID.Glob;\n } else {\n // some formats have arguments that come after ':' character\n args = formatNameOrFn.split(':');\n if (args.length > 1) {\n formatNameOrFn = args[0];\n args = args.slice(1);\n } else {\n args = [];\n }\n }\n\n let formatter = formatRegistry.getIfExists(formatNameOrFn);\n\n if (!formatter) {\n console.error(`Variable format ${formatNameOrFn} not found. Using glob format as fallback.`);\n formatter = formatRegistry.get(VariableFormatID.Glob);\n }\n\n return formatter.formatter(value, args, variable, fieldPath);\n}\n"],"names":[],"mappings":"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"}
package/dist/index.d.ts CHANGED
@@ -1285,6 +1285,16 @@ declare class AdHocFiltersVariable extends SceneObjectBase<AdHocFiltersVariableS
1285
1285
  */
1286
1286
  clearAll(): void;
1287
1287
  getValue(fieldPath?: string): VariableValue | undefined;
1288
+ /**
1289
+ * Resolves a single filter key (and optional accessor) to its value(s). Candidate filters are
1290
+ * the combined origin + user filters, excluding groupBy and WIP filters - the same set used to
1291
+ * build `filterExpression`. Returns:
1292
+ * - value accessor (default): the flattened value(s) of all filters matching `key` - a scalar
1293
+ * string when exactly one value resolves, otherwise a `string[]` for the formatter to render.
1294
+ * - `operator` accessor: the operator token of the first matching filter.
1295
+ * - any other accessor, or a missing key: an empty string.
1296
+ */
1297
+ private getFilterValueByKey;
1288
1298
  _updateFilter(filter: AdHocFilterWithLabels, update: Partial<AdHocFilterWithLabels>): void;
1289
1299
  updateToMatchAll(filter: AdHocFilterWithLabels): void;
1290
1300
  _removeFilter(filter: AdHocFilterWithLabels): void;
package/dist/index.js CHANGED
@@ -1354,7 +1354,7 @@ const ALL_VARIABLE_TEXT = "All";
1354
1354
  const ALL_VARIABLE_VALUE = "$__all";
1355
1355
  const AUTO_VARIABLE_TEXT = "Auto";
1356
1356
  const AUTO_VARIABLE_VALUE = "$__auto";
1357
- const VARIABLE_REGEX = /\$(\w+)|\[\[(\w+?)(?::(\w+))?\]\]|\${(\w+)(?:\.([^:^\}]+))?(?::([^\}]+))?}/g;
1357
+ const VARIABLE_REGEX = /\$(\w+)|\[\[(\w+?)(?::(\w+))?\]\]|\${(\w+)((?:\.[^:^{}\[\]]+|\["[^"]*"\]|\['[^']*'\]|\[[^\]"']*\])*)(?::([^}]+))?}/g;
1358
1358
  const SEARCH_FILTER_VARIABLE = "__searchFilter";
1359
1359
  const SCOPES_VARIABLE_NAME = "__scopes";
1360
1360
 
@@ -2501,9 +2501,10 @@ function sceneInterpolator(sceneObject, target, scopedVars, format, interpolatio
2501
2501
  return target != null ? target : "";
2502
2502
  }
2503
2503
  VARIABLE_REGEX.lastIndex = 0;
2504
- return target.replace(VARIABLE_REGEX, (match, var1, var2, fmt2, var3, fieldPath, fmt3) => {
2504
+ return target.replace(VARIABLE_REGEX, (match, var1, var2, fmt2, var3, rawFieldPath, fmt3) => {
2505
2505
  const variableName = var1 || var2 || var3;
2506
2506
  const fmt = fmt2 || fmt3 || format;
2507
+ const fieldPath = rawFieldPath && rawFieldPath.charCodeAt(0) === 46 ? rawFieldPath.slice(1) : rawFieldPath || void 0;
2507
2508
  const variable = lookupFormatVariable(variableName, match, scopedVars, sceneObject);
2508
2509
  if (!variable) {
2509
2510
  if (interpolations) {
@@ -9525,8 +9526,53 @@ class AdHocFiltersVariable extends SceneObjectBase {
9525
9526
  ...originFilters.filter((filter) => !filter.nonApplicable).map((filter) => toArray(filter).map(escapeOriginFilterUrlDelimiters).join("|").concat(`#${filter.origin}`))
9526
9527
  ];
9527
9528
  }
9529
+ if (fieldPath) {
9530
+ const parsed = parseFilterFieldPath(fieldPath);
9531
+ if (parsed) {
9532
+ return this.getFilterValueByKey(parsed.key, parsed.accessor);
9533
+ }
9534
+ if (process.env.NODE_ENV !== "production") {
9535
+ console.warn(
9536
+ `[AdHocFiltersVariable] "${fieldPath}" is not a per-key accessor. Use bracket-quoted key syntax, e.g. \${${this.state.name}["${fieldPath}"]}. Falling back to the whole filter expression.`
9537
+ );
9538
+ }
9539
+ }
9528
9540
  return this.state.filterExpression;
9529
9541
  }
9542
+ /**
9543
+ * Resolves a single filter key (and optional accessor) to its value(s). Candidate filters are
9544
+ * the combined origin + user filters, excluding groupBy and WIP filters - the same set used to
9545
+ * build `filterExpression`. Returns:
9546
+ * - value accessor (default): the flattened value(s) of all filters matching `key` - a scalar
9547
+ * string when exactly one value resolves, otherwise a `string[]` for the formatter to render.
9548
+ * - `operator` accessor: the operator token of the first matching filter.
9549
+ * - any other accessor, or a missing key: an empty string.
9550
+ */
9551
+ getFilterValueByKey(key, accessor) {
9552
+ const { originFilters, filters, _wip } = this.state;
9553
+ const matches = [...originFilters != null ? originFilters : [], ...filters].filter(
9554
+ (f) => f !== _wip && !isGroupByFilter(f) && f.key === key
9555
+ );
9556
+ if (matches.length === 0) {
9557
+ return "";
9558
+ }
9559
+ if (accessor === "operator") {
9560
+ return matches[0].operator;
9561
+ }
9562
+ if (accessor !== void 0) {
9563
+ return "";
9564
+ }
9565
+ const values = matches.flatMap(
9566
+ (f) => {
9567
+ var _a;
9568
+ return isMultiValueOperator(f.operator) ? (_a = f.values) != null ? _a : [] : f.value != null ? [f.value] : [];
9569
+ }
9570
+ );
9571
+ if (values.length === 1) {
9572
+ return values[0];
9573
+ }
9574
+ return values;
9575
+ }
9530
9576
  _updateFilter(filter, update) {
9531
9577
  var _a, _b, _c, _d, _e, _f, _g, _h;
9532
9578
  const { originFilters, filters, _wip } = this.state;
@@ -10032,6 +10078,16 @@ function findLastAdhocFilterIndex(filters) {
10032
10078
  function originalValueKey({ key, origin, operator }) {
10033
10079
  return operator === GROUP_BY_OPERATOR ? `${key}${VALUE_KEY_DELIMITER}${origin}${VALUE_KEY_DELIMITER}${GROUP_BY_OPERATOR}` : `${key}${VALUE_KEY_DELIMITER}${origin}`;
10034
10080
  }
10081
+ function parseFilterFieldPath(fieldPath) {
10082
+ if (fieldPath.charAt(0) !== "[") {
10083
+ return null;
10084
+ }
10085
+ const segments = lodash.toPath(fieldPath);
10086
+ if (segments.length === 0) {
10087
+ return null;
10088
+ }
10089
+ return { key: segments[0], accessor: segments[1] };
10090
+ }
10035
10091
  function isMultiValueOperator(operatorValue) {
10036
10092
  const operator = OPERATORS.find((o) => o.value === operatorValue);
10037
10093
  if (!operator) {