From 2a34acfa7bcf8174f5409eafa554dc51dc16e48c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Torkel=20=C3=96degaard?= Date: Thu, 28 May 2020 08:06:24 +0200 Subject: [PATCH] Transformations: Fixed transformation crash issue (#25152) * Transformations: Fixed transformation crash issue * Updated (cherry picked from commit 3833aa416df94ae93f25454316248a4ff366c177) --- e2e/suite1/specs/panelEdit_transforms.spec.ts | 26 ++++++++++ .../src/selectors/components.ts | 6 +++ .../ReduceTransformerEditor.tsx | 5 +- .../PanelEditor/PanelEditorTabs.tsx | 13 +---- .../TransformationsEditor.tsx | 51 ++++++++++++------- 5 files changed, 70 insertions(+), 31 deletions(-) create mode 100644 e2e/suite1/specs/panelEdit_transforms.spec.ts diff --git a/e2e/suite1/specs/panelEdit_transforms.spec.ts b/e2e/suite1/specs/panelEdit_transforms.spec.ts new file mode 100644 index 00000000000..bd1f4fb42a6 --- /dev/null +++ b/e2e/suite1/specs/panelEdit_transforms.spec.ts @@ -0,0 +1,26 @@ +import { e2e } from '@grafana/e2e'; + +const PANEL_UNDER_TEST = 'Random walk series'; + +e2e.scenario({ + describeName: 'Panel edit tests - transformations', + itName: 'Tests transformations editor', + addScenarioDataSource: false, + addScenarioDashBoard: false, + skipScenario: false, + scenario: () => { + e2e.flows.openDashboard('5SdHCadmz'); + + e2e.flows.openPanelMenuItem(e2e.flows.PanelMenuItems.Edit, PANEL_UNDER_TEST); + + e2e.components.Tab.title('Transform') + .should('be.visible') + .click(); + + e2e.components.TransformTab.newTransform('Reduce') + .should('be.visible') + .click(); + + e2e.components.Transforms.Reduce.calculationsLabel().should('be.visible'); + }, +}); diff --git a/packages/grafana-e2e-selectors/src/selectors/components.ts b/packages/grafana-e2e-selectors/src/selectors/components.ts index f7b8a93f442..72489b57204 100644 --- a/packages/grafana-e2e-selectors/src/selectors/components.ts +++ b/packages/grafana-e2e-selectors/src/selectors/components.ts @@ -97,6 +97,12 @@ export const Components = { }, TransformTab: { content: 'Transform editor tab content', + newTransform: (title: string) => `New transform ${title}`, + }, + Transforms: { + Reduce: { + calculationsLabel: 'Transform calculations label', + }, }, QueryEditorToolbarItem: { button: (title: string) => `QueryEditor toolbar item button ${title}`, diff --git a/public/app/core/components/TransformersUI/ReduceTransformerEditor.tsx b/public/app/core/components/TransformersUI/ReduceTransformerEditor.tsx index 964f5b3653f..40079f6f10b 100644 --- a/public/app/core/components/TransformersUI/ReduceTransformerEditor.tsx +++ b/public/app/core/components/TransformersUI/ReduceTransformerEditor.tsx @@ -9,6 +9,7 @@ import { } from '@grafana/data'; import { ReduceTransformerOptions } from '@grafana/data/src/transformations/transformers/reduce'; +import { selectors } from '@grafana/e2e-selectors'; // TODO: Minimal implementation, needs some <3 export const ReduceTransformerEditor: React.FC> = ({ @@ -18,7 +19,9 @@ export const ReduceTransformerEditor: React.FC
-
Calculations
+
+ Calculations +
= ({ panel, dashboa return null; } - const onTransformersChange = (transformers: DataTransformerConfig[]) => { - panel.setTransformations(transformers); - }; - return (
@@ -65,13 +60,7 @@ export const PanelEditorTabs: React.FC = ({ panel, dashboa {activeTab.id === PanelEditorTabId.Query && } {activeTab.id === PanelEditorTabId.Alert && } - {activeTab.id === PanelEditorTabId.Transform && ( - - )} + {activeTab.id === PanelEditorTabId.Transform && }
); diff --git a/public/app/features/dashboard/components/TransformationsEditor/TransformationsEditor.tsx b/public/app/features/dashboard/components/TransformationsEditor/TransformationsEditor.tsx index 2bce1ce778a..b50b718e523 100644 --- a/public/app/features/dashboard/components/TransformationsEditor/TransformationsEditor.tsx +++ b/public/app/features/dashboard/components/TransformationsEditor/TransformationsEditor.tsx @@ -28,17 +28,25 @@ import { PanelModel } from '../../state'; interface Props { panel: PanelModel; - onChange: (transformations: DataTransformerConfig[]) => void; - transformations: DataTransformerConfig[]; } interface State { - data?: DataFrame[]; + data: DataFrame[]; + transformations: DataTransformerConfig[]; } export class TransformationsEditor extends React.PureComponent { subscription?: Unsubscribable; + constructor(props: Props) { + super(props); + + this.state = { + transformations: props.panel.transformations || [], + data: [], + }; + } + componentDidMount() { this.subscription = this.props.panel .getQueryRunner() @@ -54,9 +62,15 @@ export class TransformationsEditor extends React.PureComponent { } } + onChange(transformations: DataTransformerConfig[]) { + this.props.panel.setTransformations(transformations); + this.setState({ transformations }); + } + onTransformationAdd = (selectable: SelectableValue) => { - const { transformations, onChange } = this.props; - onChange([ + const { transformations } = this.state; + + this.onChange([ ...transformations, { id: selectable.value as string, @@ -66,17 +80,17 @@ export class TransformationsEditor extends React.PureComponent { }; onTransformationChange = (idx: number, config: DataTransformerConfig) => { - const { transformations, onChange } = this.props; + const { transformations } = this.state; const next = Array.from(transformations); next[idx] = config; - onChange(next); + this.onChange(next); }; onTransformationRemove = (idx: number) => { - const { transformations, onChange } = this.props; + const { transformations } = this.state; const next = Array.from(transformations); next.splice(idx, 1); - onChange(next); + this.onChange(next); }; renderTransformationSelector = () => { @@ -108,10 +122,7 @@ export class TransformationsEditor extends React.PureComponent { }; renderTransformationEditors = () => { - const { transformations } = this.props; - const { data } = this.state; - - const preTransformData = data ?? []; + const { data, transformations } = this.state; return ( <> @@ -123,7 +134,7 @@ export class TransformationsEditor extends React.PureComponent { return null; } - const input = transformDataFrame(transformations.slice(0, i), preTransformData); + const input = transformDataFrame(transformations.slice(0, i), data); const output = transformDataFrame(transformations.slice(i), input); if (transformationUI) { @@ -182,6 +193,7 @@ export class TransformationsEditor extends React.PureComponent { title={t.name} description={t.description} actions={} + ariaLabel={selectors.components.TransformTab.newTransform(t.name)} onClick={() => { this.onTransformationAdd({ value: t.id }); }} @@ -194,14 +206,17 @@ export class TransformationsEditor extends React.PureComponent { } render() { - const hasTransformationsConfigured = this.props.transformations.length > 0; + const { transformations } = this.state; + + const hasTransforms = transformations.length > 0; + return (
- {!hasTransformationsConfigured && this.renderNoAddedTransformsState()} - {hasTransformationsConfigured && this.renderTransformationEditors()} - {hasTransformationsConfigured && this.renderTransformationSelector()} + {!hasTransforms && this.renderNoAddedTransformsState()} + {hasTransforms && this.renderTransformationEditors()} + {hasTransforms && this.renderTransformationSelector()}