@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.
- package/CHANGELOG.md +14 -0
- package/dist/esm/variables/adhoc/AdHocFiltersVariable.js +57 -2
- package/dist/esm/variables/adhoc/AdHocFiltersVariable.js.map +1 -1
- package/dist/esm/variables/constants.js +1 -1
- package/dist/esm/variables/constants.js.map +1 -1
- package/dist/esm/variables/interpolation/sceneInterpolator.js +2 -1
- package/dist/esm/variables/interpolation/sceneInterpolator.js.map +1 -1
- package/dist/index.d.ts +10 -0
- package/dist/index.js +58 -2
- package/dist/index.js.map +1 -1
- package/package.json +4 -4
|
@@ -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,
|
|
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+)(?:\.
|
|
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,
|
|
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) {
|