From e28c993465dc32405ac51484bf1db0b37178b865 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Torkel=20=C3=96degaard?= Date: Wed, 12 Mar 2025 08:35:44 +0100 Subject: [PATCH] DashboardScene: De-select object after they are removed (#101940) --- .../dashboard-scene/edit-pane/DashboardEditPane.tsx | 8 +++++++- public/app/features/dashboard-scene/edit-pane/shared.ts | 4 ++++ .../scene/layout-default/DefaultGridLayoutManager.tsx | 4 +++- .../ResponsiveGridLayoutManager.tsx | 3 ++- .../scene/layout-rows/RowsLayoutManager.tsx | 3 ++- .../scene/layout-tabs/TabsLayoutManager.tsx | 3 +++ 6 files changed, 21 insertions(+), 4 deletions(-) diff --git a/public/app/features/dashboard-scene/edit-pane/DashboardEditPane.tsx b/public/app/features/dashboard-scene/edit-pane/DashboardEditPane.tsx index cef94e5be88..072d80ba367 100644 --- a/public/app/features/dashboard-scene/edit-pane/DashboardEditPane.tsx +++ b/public/app/features/dashboard-scene/edit-pane/DashboardEditPane.tsx @@ -21,7 +21,7 @@ import { DashboardAddPane } from './DashboardAddPane'; import { DashboardOutline } from './DashboardOutline'; import { ElementEditPane } from './ElementEditPane'; import { ElementSelection } from './ElementSelection'; -import { NewObjectAddedToCanvasEvent } from './shared'; +import { NewObjectAddedToCanvasEvent, ObjectRemovedFromCanvasEvent } from './shared'; import { useEditableElement } from './useEditableElement'; export interface DashboardEditPaneState extends SceneObjectState { @@ -53,6 +53,12 @@ export class DashboardEditPane extends SceneObjectBase { this.newObjectAddedToCanvas(payload); }) ); + + this._subs.add( + dashboard.subscribeToEvent(ObjectRemovedFromCanvasEvent, ({ payload }) => { + this.clearSelection(); + }) + ); } public enableSelection() { diff --git a/public/app/features/dashboard-scene/edit-pane/shared.ts b/public/app/features/dashboard-scene/edit-pane/shared.ts index 7f284ef945c..f599a50ef8c 100644 --- a/public/app/features/dashboard-scene/edit-pane/shared.ts +++ b/public/app/features/dashboard-scene/edit-pane/shared.ts @@ -58,3 +58,7 @@ export function hasEditableElement(sceneObj: SceneObject | undefined): boolean { export class NewObjectAddedToCanvasEvent extends BusEventWithPayload { static type = 'new-object-added-to-canvas'; } + +export class ObjectRemovedFromCanvasEvent extends BusEventWithPayload { + static type = 'object-removed-from-canvas'; +} 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 992a6f9102d..c30558f3221 100644 --- a/public/app/features/dashboard-scene/scene/layout-default/DefaultGridLayoutManager.tsx +++ b/public/app/features/dashboard-scene/scene/layout-default/DefaultGridLayoutManager.tsx @@ -15,7 +15,7 @@ import { GRID_COLUMN_COUNT } from 'app/core/constants'; import { t } from 'app/core/internationalization'; import DashboardEmpty from 'app/features/dashboard/dashgrid/DashboardEmpty'; -import { NewObjectAddedToCanvasEvent } from '../../edit-pane/shared'; +import { NewObjectAddedToCanvasEvent, ObjectRemovedFromCanvasEvent } from '../../edit-pane/shared'; import { isClonedKey, joinCloneKeys } from '../../utils/clone'; import { dashboardSceneGraph } from '../../utils/dashboardSceneGraph'; import { @@ -108,6 +108,8 @@ export class DefaultGridLayoutManager this.state.grid.setState({ children: layout.state.children.filter((child) => child !== gridItem), }); + + this.publishEvent(new ObjectRemovedFromCanvasEvent(panel), true); } public duplicatePanel(vizPanel: VizPanel) { diff --git a/public/app/features/dashboard-scene/scene/layout-responsive-grid/ResponsiveGridLayoutManager.tsx b/public/app/features/dashboard-scene/scene/layout-responsive-grid/ResponsiveGridLayoutManager.tsx index f610ceac675..eefe03a13a5 100644 --- a/public/app/features/dashboard-scene/scene/layout-responsive-grid/ResponsiveGridLayoutManager.tsx +++ b/public/app/features/dashboard-scene/scene/layout-responsive-grid/ResponsiveGridLayoutManager.tsx @@ -2,7 +2,7 @@ import { SceneComponentProps, SceneCSSGridLayout, SceneObjectBase, SceneObjectSt import { t } from 'app/core/internationalization'; import { OptionsPaneItemDescriptor } from 'app/features/dashboard/components/PanelEditor/OptionsPaneItemDescriptor'; -import { NewObjectAddedToCanvasEvent } from '../../edit-pane/shared'; +import { NewObjectAddedToCanvasEvent, ObjectRemovedFromCanvasEvent } from '../../edit-pane/shared'; import { joinCloneKeys } from '../../utils/clone'; import { dashboardSceneGraph } from '../../utils/dashboardSceneGraph'; import { getGridItemKeyForPanelId, getPanelIdForVizPanel, getVizPanelKeyForPanelId } from '../../utils/utils'; @@ -68,6 +68,7 @@ export class ResponsiveGridLayoutManager public removePanel(panel: VizPanel) { const element = panel.parent; this.state.layout.setState({ children: this.state.layout.state.children.filter((child) => child !== element) }); + this.publishEvent(new ObjectRemovedFromCanvasEvent(panel), true); } public duplicatePanel(panel: VizPanel) { diff --git a/public/app/features/dashboard-scene/scene/layout-rows/RowsLayoutManager.tsx b/public/app/features/dashboard-scene/scene/layout-rows/RowsLayoutManager.tsx index ceccc165557..4c1acfe940a 100644 --- a/public/app/features/dashboard-scene/scene/layout-rows/RowsLayoutManager.tsx +++ b/public/app/features/dashboard-scene/scene/layout-rows/RowsLayoutManager.tsx @@ -1,7 +1,7 @@ import { SceneGridItemLike, SceneGridRow, SceneObjectBase, SceneObjectState, VizPanel } from '@grafana/scenes'; import { t } from 'app/core/internationalization'; -import { NewObjectAddedToCanvasEvent } from '../../edit-pane/shared'; +import { NewObjectAddedToCanvasEvent, ObjectRemovedFromCanvasEvent } from '../../edit-pane/shared'; import { isClonedKey } from '../../utils/clone'; import { dashboardSceneGraph } from '../../utils/dashboardSceneGraph'; import { DashboardGridItem } from '../layout-default/DashboardGridItem'; @@ -128,6 +128,7 @@ export class RowsLayoutManager extends SceneObjectBase i public removeRow(row: RowItem) { const rows = this.state.rows.filter((r) => r !== row); this.setState({ rows: rows.length === 0 ? [new RowItem()] : rows }); + this.publishEvent(new ObjectRemovedFromCanvasEvent(row), true); } public moveRowUp(row: RowItem) { diff --git a/public/app/features/dashboard-scene/scene/layout-tabs/TabsLayoutManager.tsx b/public/app/features/dashboard-scene/scene/layout-tabs/TabsLayoutManager.tsx index 319210697cd..3c7f1b24bd4 100644 --- a/public/app/features/dashboard-scene/scene/layout-tabs/TabsLayoutManager.tsx +++ b/public/app/features/dashboard-scene/scene/layout-tabs/TabsLayoutManager.tsx @@ -7,6 +7,7 @@ import { } from '@grafana/scenes'; import { t } from 'app/core/internationalization'; +import { ObjectRemovedFromCanvasEvent } from '../../edit-pane/shared'; import { DashboardLayoutManager } from '../types/DashboardLayoutManager'; import { LayoutRegistryItem } from '../types/LayoutRegistryItem'; @@ -115,6 +116,7 @@ export class TabsLayoutManager extends SceneObjectBase i if (currentTab === tabToRemove) { const nextTabIndex = this.state.currentTabIndex > 0 ? this.state.currentTabIndex - 1 : 0; this.setState({ tabs: this.state.tabs.filter((t) => t !== tabToRemove), currentTabIndex: nextTabIndex }); + this.publishEvent(new ObjectRemovedFromCanvasEvent(tabToRemove), true); return; } @@ -122,6 +124,7 @@ export class TabsLayoutManager extends SceneObjectBase i const tabs = filteredTab.length === 0 ? [new TabItem()] : filteredTab; this.setState({ tabs, currentTabIndex: 0 }); + this.publishEvent(new ObjectRemovedFromCanvasEvent(tabToRemove), true); } public addTabBefore(tab: TabItem) {