DashboardScenes: Fix duplicate query modifying original query on panel duplication (#93038)

make sure queries are cloned on panel duplicate
This commit is contained in:
Victor Marin 2024-09-09 10:09:22 +03:00 committed by GitHub
parent fc4b3a2b03
commit 8eb7e55f8f
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 31 additions and 3 deletions

View File

@ -785,6 +785,22 @@ describe('DashboardScene', () => {
expect(libVizPanel.state.key).toBe('panel-7'); expect(libVizPanel.state.key).toBe('panel-7');
}); });
it('Should deep clone data provider when duplicating a panel', () => {
const vizPanel = ((scene.state.body as SceneGridLayout).state.children[0] as DashboardGridItem).state.body;
scene.duplicatePanel(vizPanel as VizPanel);
const panelQueries = (
((scene.state.body as SceneGridLayout).state.children[0] as DashboardGridItem).state.body.state.$data?.state
.$data as SceneQueryRunner
).state.queries;
const duplicatedPanelQueries = (
((scene.state.body as SceneGridLayout).state.children[5] as DashboardGridItem).state.body.state.$data?.state
.$data as SceneQueryRunner
).state.queries;
expect(panelQueries[0]).not.toBe(duplicatedPanelQueries[0]);
});
it('Should duplicate a repeated panel', () => { it('Should duplicate a repeated panel', () => {
const scene = buildTestScene({ const scene = buildTestScene({
body: new SceneGridLayout({ body: new SceneGridLayout({
@ -1225,7 +1241,10 @@ function buildTestScene(overrides?: Partial<DashboardSceneState>) {
}), }),
$data: new SceneDataTransformer({ $data: new SceneDataTransformer({
transformations: [], transformations: [],
$data: new SceneQueryRunner({ key: 'data-query-runner', queries: [{ refId: 'A' }] }), $data: new SceneQueryRunner({
key: 'data-query-runner',
queries: [{ refId: 'A', target: 'aliasByMetric(carbon.**)' }],
}),
}), }),
}), }),
}), }),

View File

@ -60,6 +60,7 @@ import {
getDefaultRow, getDefaultRow,
getDefaultVizPanel, getDefaultVizPanel,
getPanelIdForVizPanel, getPanelIdForVizPanel,
getQueryRunnerFor,
getVizPanelKeyForPanelId, getVizPanelKeyForPanelId,
isPanelClone, isPanelClone,
} from '../utils/utils'; } from '../utils/utils';
@ -569,10 +570,18 @@ export class DashboardScene extends SceneObjectBase<DashboardSceneState> {
if (gridItem instanceof DashboardGridItem) { if (gridItem instanceof DashboardGridItem) {
panelState = sceneUtils.cloneSceneObjectState(gridItem.state.body.state); panelState = sceneUtils.cloneSceneObjectState(gridItem.state.body.state);
panelData = sceneGraph.getData(gridItem.state.body).clone();
let queryRunner = getQueryRunnerFor(gridItem.state.body);
const queries = queryRunner?.state.queries.map((q) => ({ ...q }));
queryRunner = queryRunner?.clone({ queries });
panelData = sceneGraph.getData(gridItem.state.body).clone({ $data: queryRunner });
} else { } else {
panelState = sceneUtils.cloneSceneObjectState(vizPanel.state); panelState = sceneUtils.cloneSceneObjectState(vizPanel.state);
panelData = sceneGraph.getData(vizPanel).clone();
let queryRunner = getQueryRunnerFor(vizPanel);
const queries = queryRunner?.state.queries.map((q) => ({ ...q }));
queryRunner = queryRunner?.clone({ queries });
panelData = sceneGraph.getData(vizPanel).clone({ $data: queryRunner });
} }
// when we duplicate a panel we don't want to clone the alert state // when we duplicate a panel we don't want to clone the alert state