From 7622a811584e4afdba5154c2058d80eab6f3d57c Mon Sep 17 00:00:00 2001 From: Kristina Durivage Date: Sun, 5 Oct 2025 19:42:49 -0500 Subject: [PATCH] display generated refID if exists, but do not persist it --- packages/grafana-data/src/index.ts | 2 +- .../src/transformations/transformers/joinByField.ts | 6 ++++-- .../grafana-data/src/transformations/transformers/merge.ts | 5 +++-- .../grafana-data/src/transformations/transformers/reduce.ts | 5 +++-- .../src/transformations/transformers/seriesToRows.ts | 5 +++-- .../grafana-data/src/transformations/transformers/utils.ts | 2 +- packages/grafana-data/src/types/transformations.ts | 4 ++++ .../TransformationsEditor/TransformationOperationRow.tsx | 4 ++++ .../TransformationOperationRowHeader.tsx | 4 +++- .../app/features/transformers/joinByLabels/joinByLabels.ts | 5 +++-- 10 files changed, 29 insertions(+), 13 deletions(-) diff --git a/packages/grafana-data/src/index.ts b/packages/grafana-data/src/index.ts index 5c3603fdba5..1f0f01f227b 100644 --- a/packages/grafana-data/src/index.ts +++ b/packages/grafana-data/src/index.ts @@ -268,7 +268,7 @@ export { fuzzySearch } from './utils/fuzzySearch'; // Transformations export { standardTransformers } from './transformations/transformers'; -export { getTransformationLegacyRefId } from './transformations/transformers/utils'; +export { getTransformationDynamicRefId } from './transformations/transformers/utils'; export { fieldMatchers, frameMatchers, diff --git a/packages/grafana-data/src/transformations/transformers/joinByField.ts b/packages/grafana-data/src/transformations/transformers/joinByField.ts index 9670cfe3a80..7869f93d2cf 100644 --- a/packages/grafana-data/src/transformations/transformers/joinByField.ts +++ b/packages/grafana-data/src/transformations/transformers/joinByField.ts @@ -7,7 +7,7 @@ import { FieldMatcherID } from '../matchers/ids'; import { DataTransformerID } from './ids'; import { joinDataFrames } from './joinDataFrames'; -import { getTransformationLegacyRefId } from './utils'; +import { getTransformationDynamicRefId } from './utils'; export enum JoinMode { outer = 'outer', // best for time series, non duplicated join on values @@ -44,11 +44,13 @@ export const joinByFieldTransformer: SynchronousDataTransformerInfo = { const fieldIndexByName: Record> = {}; const fieldNamesForKey: string[] = []; const dataFrame = new MutableDataFrame({ - refId: options.refId ?? getTransformationLegacyRefId(DataTransformerID.merge, data), + refId: options.refId ?? getTransformationDynamicRefId(DataTransformerID.merge, data), fields: [], }); @@ -125,6 +125,7 @@ export const mergeTransformer: DataTransformerInfo = { return [dataFrame]; }) ), + usesDynamicRefId: true, }; const copyFieldStructure = (field: Field): Field => { diff --git a/packages/grafana-data/src/transformations/transformers/reduce.ts b/packages/grafana-data/src/transformations/transformers/reduce.ts index 706d6799c54..272d9beeb4e 100644 --- a/packages/grafana-data/src/transformations/transformers/reduce.ts +++ b/packages/grafana-data/src/transformations/transformers/reduce.ts @@ -10,7 +10,7 @@ import { getFieldMatcher } from '../matchers'; import { alwaysFieldMatcher, notTimeFieldMatcher } from '../matchers/predicates'; import { DataTransformerID } from './ids'; -import { getTransformationLegacyRefId } from './utils'; +import { getTransformationDynamicRefId } from './utils'; export enum ReduceTransformerMode { SeriesToRows = 'seriesToRows', // default @@ -62,12 +62,13 @@ export const reduceTransformer: DataTransformerInfo = ? [ { ...res, - refId: options.refId ?? getTransformationLegacyRefId(DataTransformerID.reduce, data), + refId: options.refId ?? getTransformationDynamicRefId(DataTransformerID.reduce, data), }, ] : []; }) ), + usesDynamicRefId: true, }; /** diff --git a/packages/grafana-data/src/transformations/transformers/seriesToRows.ts b/packages/grafana-data/src/transformations/transformers/seriesToRows.ts index c737006c592..c6409f7fe7e 100644 --- a/packages/grafana-data/src/transformations/transformers/seriesToRows.ts +++ b/packages/grafana-data/src/transformations/transformers/seriesToRows.ts @@ -15,7 +15,7 @@ import { import { DataTransformerInfo } from '../../types/transformations'; import { DataTransformerID } from './ids'; -import { getTransformationLegacyRefId } from './utils'; +import { getTransformationDynamicRefId } from './utils'; export interface SeriesToRowsTransformerOptions { refId?: string; @@ -41,7 +41,7 @@ export const seriesToRowsTransformer: DataTransformerInfo = {}; const targetFields = new Set(); const dataFrame = new MutableDataFrame({ - refId: options.refId ?? getTransformationLegacyRefId(DataTransformerID.seriesToRows, data), + refId: options.refId ?? getTransformationDynamicRefId(DataTransformerID.seriesToRows, data), fields: [], }); const metricField: Field = { @@ -93,6 +93,7 @@ export const seriesToRowsTransformer: DataTransformerInfo { diff --git a/packages/grafana-data/src/transformations/transformers/utils.ts b/packages/grafana-data/src/transformations/transformers/utils.ts index a9e55bb733b..3cc695c9faf 100644 --- a/packages/grafana-data/src/transformations/transformers/utils.ts +++ b/packages/grafana-data/src/transformations/transformers/utils.ts @@ -34,6 +34,6 @@ export function getSpecialValue(specialValue: SpecialValue) { } } -export const getTransformationLegacyRefId = (transformationId: string, data: DataFrame[]) => { +export const getTransformationDynamicRefId = (transformationId: string, data: DataFrame[]) => { return `${transformationId}-${data.map((frame) => frame.refId).join('-')}`; }; diff --git a/packages/grafana-data/src/types/transformations.ts b/packages/grafana-data/src/types/transformations.ts index f002310e6e1..bc967834f01 100644 --- a/packages/grafana-data/src/types/transformations.ts +++ b/packages/grafana-data/src/types/transformations.ts @@ -55,6 +55,10 @@ export interface DataTransformerInfo extends RegistryItemWithOpt * This way descriptions can be tailored relative to the underlying data. */ isApplicableDescription?: string | ((data: DataFrame[]) => string); + /** + * Does the transformation generate a dataframe and thus generates a refID automatically based on incoming data + */ + usesDynamicRefId?: boolean; } /** diff --git a/public/app/features/dashboard/components/TransformationsEditor/TransformationOperationRow.tsx b/public/app/features/dashboard/components/TransformationsEditor/TransformationOperationRow.tsx index 9a74967223d..f3a19402a42 100644 --- a/public/app/features/dashboard/components/TransformationsEditor/TransformationOperationRow.tsx +++ b/public/app/features/dashboard/components/TransformationsEditor/TransformationOperationRow.tsx @@ -10,6 +10,7 @@ import { getFrameMatchers, transformDataFrame, DataFrame, + getTransformationDynamicRefId, } from '@grafana/data'; import { selectors } from '@grafana/e2e-selectors'; import { t } from '@grafana/i18n'; @@ -61,6 +62,8 @@ export const TransformationOperationRow = ({ // output of previous transformation const [prevOutput, setPrevOutput] = useState([]); + const dynamicRefId = getTransformationDynamicRefId(uiConfig.id, data.series); + const onDisableToggle = useCallback( (index: number) => { const current = configs[index].transformation; @@ -167,6 +170,7 @@ export const TransformationOperationRow = ({ transformationTypeName={`${index + 1} - ${uiConfig.name}`} disabled onChange={onChange} + dynamicRefId={uiConfig.transformation.usesDynamicRefId ? dynamicRefId : undefined} /> ); }; diff --git a/public/app/features/dashboard/components/TransformationsEditor/TransformationOperationRowHeader.tsx b/public/app/features/dashboard/components/TransformationsEditor/TransformationOperationRowHeader.tsx index c6fc3b82e18..cd4ea54861d 100644 --- a/public/app/features/dashboard/components/TransformationsEditor/TransformationOperationRowHeader.tsx +++ b/public/app/features/dashboard/components/TransformationsEditor/TransformationOperationRowHeader.tsx @@ -14,10 +14,11 @@ export interface Props { transformationTypeName: string; disabled?: boolean; onChange: (index: number, config: DataTransformerConfig) => void; + dynamicRefId?: string; } export const TransformationOperationRowHeader = (props: Props) => { - const { index, transformation, transformations, onChange, disabled, transformationTypeName } = props; + const { index, transformation, transformations, onChange, disabled, transformationTypeName, dynamicRefId } = props; const styles = useStyles2(getStyles); const [isRefIdEditing, toggleIsRefIdEditing] = useToggle(false); @@ -97,6 +98,7 @@ export const TransformationOperationRowHeader = (props: Props) => { > {transformation.refId || + dynamicRefId || t( 'dashboard.transformation-operation-row.transformation-editor-row-header.edit-refId-placeholder', '(Auto)' diff --git a/public/app/features/transformers/joinByLabels/joinByLabels.ts b/public/app/features/transformers/joinByLabels/joinByLabels.ts index 60f8cae378c..d9448c8ac07 100644 --- a/public/app/features/transformers/joinByLabels/joinByLabels.ts +++ b/public/app/features/transformers/joinByLabels/joinByLabels.ts @@ -5,7 +5,7 @@ import { DataTransformerID, Field, FieldType, - getTransformationLegacyRefId, + getTransformationDynamicRefId, SynchronousDataTransformerInfo, } from '@grafana/data'; import { t } from '@grafana/i18n'; @@ -38,6 +38,7 @@ export const getJoinByLabelsTransformer: () => SynchronousDataTransformerInfo