diff --git a/public/app/features/dashboard-scene/scene/layout-default/DefaultGridLayoutManager.tsx b/public/app/features/dashboard-scene/scene/layout-default/DefaultGridLayoutManager.tsx index c4e1c481b0e..6fbeb6064ec 100644 --- a/public/app/features/dashboard-scene/scene/layout-default/DefaultGridLayoutManager.tsx +++ b/public/app/features/dashboard-scene/scene/layout-default/DefaultGridLayoutManager.tsx @@ -237,7 +237,11 @@ export class DefaultGridLayoutManager // when we duplicate a panel we don't want to clone the alert state delete panelData.state.data?.alertState; - const newPanel = new VizPanel({ ...panelState, $data: panelData, key: getVizPanelKeyForPanelId(newPanelId) }); + const newPanel = new VizPanel({ + ...panelState, + $data: panelData, + key: getVizPanelKeyForPanelId(newPanelId), + }); newGridItem = new DashboardGridItem({ x: gridItem.state.x, @@ -252,16 +256,38 @@ export class DefaultGridLayoutManager body: newPanel, }); - if (gridItem.parent instanceof SceneGridRow) { - const row = gridItem.parent; + // No undo/redo support in legacy edit mode + if (!config.featureToggles.dashboardNewLayouts) { + if (gridItem.parent instanceof SceneGridRow) { + const row = gridItem.parent; - row.setState({ children: [...row.state.children, newGridItem] }); - grid.forceRender(); + row.setState({ children: [...row.state.children, newGridItem] }); + grid.forceRender(); + return; + } + + grid.setState({ children: [...grid.state.children, newGridItem] }); + this.publishEvent(new NewObjectAddedToCanvasEvent(newPanel), true); return; } - grid.setState({ children: [...grid.state.children, newGridItem] }); - this.publishEvent(new NewObjectAddedToCanvasEvent(newPanel), true); + const parent = gridItem.parent instanceof SceneGridRow ? gridItem.parent : grid; + dashboardEditActions.edit({ + description: t('dashboard.edit-actions.duplicate-panel', 'Duplicate panel'), + addedObject: newGridItem.state.body, + source: this, + perform: () => { + const oldGridItemIndex = parent.state.children.indexOf(gridItem); + const newChildrenArray = [...parent.state.children]; + newChildrenArray.splice(oldGridItemIndex + 1, 0, newGridItem); + parent.setState({ children: newChildrenArray }); + }, + undo: () => { + parent.setState({ + children: parent.state.children.filter((child) => child !== newGridItem), + }); + }, + }); } public duplicate(): DashboardLayoutManager { diff --git a/public/locales/en-US/grafana.json b/public/locales/en-US/grafana.json index 722e201bae1..2c50b0db303 100644 --- a/public/locales/en-US/grafana.json +++ b/public/locales/en-US/grafana.json @@ -4567,6 +4567,7 @@ "edit-actions": { "add": "Add {{typeName}}", "add-conditional-rule": "Add {{ruleDescription}} rule", + "duplicate-panel": "Duplicate panel", "edit-query-result-rule": "Change query result rule", "edit-template-variable-rule": "Change template variable rule", "edit-time-range-rule": "Change time range rule",