From e8b035a5f713f9437e5242f8cf46e02688bbc63d Mon Sep 17 00:00:00 2001 From: Leon Sorokin Date: Fri, 28 Feb 2025 16:25:43 -0600 Subject: [PATCH] Transformations: Fix variable interpolation when Scenes is disabled (#101438) Co-authored-by: Dominik Prokop --- .betterer.results | 8 +++++ .../src/transformations/transformDataFrame.ts | 32 ++++++++++++++++++- 2 files changed, 39 insertions(+), 1 deletion(-) diff --git a/.betterer.results b/.betterer.results index f6c07dd6633..d5ac5c018d3 100644 --- a/.betterer.results +++ b/.betterer.results @@ -142,6 +142,14 @@ exports[`better eslint`] = { "packages/grafana-data/src/transformations/standardTransformersRegistry.ts:5381": [ [0, 0, 0, "Unexpected any. Specify a different type.", "0"] ], + "packages/grafana-data/src/transformations/transformDataFrame.ts:5381": [ + [0, 0, 0, "Unexpected any. Specify a different type.", "0"], + [0, 0, 0, "Unexpected any. Specify a different type.", "1"], + [0, 0, 0, "Unexpected any. Specify a different type.", "2"], + [0, 0, 0, "Unexpected any. Specify a different type.", "3"], + [0, 0, 0, "Unexpected any. Specify a different type.", "4"], + [0, 0, 0, "Unexpected any. Specify a different type.", "5"] + ], "packages/grafana-data/src/transformations/transformers/nulls/nullInsertThreshold.ts:5381": [ [0, 0, 0, "Unexpected any. Specify a different type.", "0"], [0, 0, 0, "Unexpected any. Specify a different type.", "1"] diff --git a/packages/grafana-data/src/transformations/transformDataFrame.ts b/packages/grafana-data/src/transformations/transformDataFrame.ts index 477801b650e..1a923ec0d86 100644 --- a/packages/grafana-data/src/transformations/transformDataFrame.ts +++ b/packages/grafana-data/src/transformations/transformDataFrame.ts @@ -12,6 +12,9 @@ import { import { getFrameMatchers } from './matchers'; import { standardTransformersRegistry, TransformerRegistryItem } from './standardTransformersRegistry'; +// when running within Scenes, we can skip var interpolation, since it's already handled upstream +const isScenes = window.__grafanaSceneContext != null; + const getOperator = (config: DataTransformerConfig, ctx: DataTransformContext): MonoTypeOperatorFunction => (source) => { @@ -24,11 +27,20 @@ const getOperator = const defaultOptions = info.transformation.defaultOptions ?? {}; const options = { ...defaultOptions, ...config.options }; + const interpolated = isScenes + ? options + : deepIterate(options, (v) => { + if (typeof v === 'string') { + return ctx.interpolate(v); + } + return v; + }); + const matcher = config.filter?.options ? getFrameMatchers(config.filter) : undefined; return source.pipe( mergeMap((before) => of(filterInput(before, matcher)).pipe( - info.transformation.operator(options, ctx), + info.transformation.operator(interpolated, ctx), postProcessTransform(before, info, matcher) ) ) @@ -107,3 +119,21 @@ export function transformDataFrame( function isCustomTransformation(t: DataTransformerConfig | CustomTransformOperator): t is CustomTransformOperator { return typeof t === 'function'; } + +function deepIterate(obj: T, doSomething: (current: any) => any): T; +// eslint-disable-next-line no-redeclare +function deepIterate(obj: any, doSomething: (current: any) => any): any { + if (Array.isArray(obj)) { + return obj.map((o) => deepIterate(o, doSomething)); + } + + if (typeof obj === 'object') { + for (const key in obj) { + obj[key] = deepIterate(obj[key], doSomething); + } + + return obj; + } else { + return doSomething(obj) ?? obj; + } +}