mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
Scenes: Remove normal and library panels from layout or rows (#83969)
* Remove normal/lib panels from layout or rows * refactor
This commit is contained in:
parent
8e827afb8c
commit
20d201ca6a
@ -261,7 +261,7 @@ describe('DashboardScene', () => {
|
||||
const gridItem = body.state.children[0] as SceneGridItem;
|
||||
|
||||
expect(body.state.children.length).toBe(6);
|
||||
expect(gridItem.state.body!.state.key).toBe('panel-5');
|
||||
expect(gridItem.state.body!.state.key).toBe('panel-7');
|
||||
});
|
||||
|
||||
it('Should create and add a new row to the dashboard', () => {
|
||||
@ -271,7 +271,7 @@ describe('DashboardScene', () => {
|
||||
const gridRow = body.state.children[0] as SceneGridRow;
|
||||
|
||||
expect(body.state.children.length).toBe(4);
|
||||
expect(gridRow.state.key).toBe('panel-5');
|
||||
expect(gridRow.state.key).toBe('panel-7');
|
||||
expect(gridRow.state.children[0].state.key).toBe('griditem-1');
|
||||
expect(gridRow.state.children[1].state.key).toBe('griditem-2');
|
||||
});
|
||||
@ -405,7 +405,7 @@ describe('DashboardScene', () => {
|
||||
|
||||
expect(buildGridItemForPanel).toHaveBeenCalledTimes(1);
|
||||
expect(body.state.children.length).toBe(6);
|
||||
expect(gridItem.state.body!.state.key).toBe('panel-5');
|
||||
expect(gridItem.state.body!.state.key).toBe('panel-7');
|
||||
expect(gridItem.state.y).toBe(0);
|
||||
expect(scene.state.hasCopiedPanel).toBe(false);
|
||||
});
|
||||
@ -433,8 +433,8 @@ describe('DashboardScene', () => {
|
||||
|
||||
expect(buildGridItemForLibPanel).toHaveBeenCalledTimes(1);
|
||||
expect(body.state.children.length).toBe(6);
|
||||
expect(libVizPanel.state.panelKey).toBe('panel-5');
|
||||
expect(libVizPanel.state.panel?.state.key).toBe('panel-5');
|
||||
expect(libVizPanel.state.panelKey).toBe('panel-7');
|
||||
expect(libVizPanel.state.panel?.state.key).toBe('panel-7');
|
||||
expect(gridItem.state.y).toBe(0);
|
||||
expect(scene.state.hasCopiedPanel).toBe(false);
|
||||
});
|
||||
@ -446,9 +446,50 @@ describe('DashboardScene', () => {
|
||||
const gridItem = body.state.children[0] as SceneGridItem;
|
||||
|
||||
expect(body.state.children.length).toBe(6);
|
||||
expect(gridItem.state.body!.state.key).toBe('panel-5');
|
||||
expect(gridItem.state.body!.state.key).toBe('panel-7');
|
||||
expect(gridItem.state.y).toBe(0);
|
||||
});
|
||||
|
||||
it('Should remove a panel', () => {
|
||||
const vizPanel = ((scene.state.body as SceneGridLayout).state.children[0] as SceneGridItem).state.body;
|
||||
scene.removePanel(vizPanel as VizPanel);
|
||||
|
||||
const body = scene.state.body as SceneGridLayout;
|
||||
expect(body.state.children.length).toBe(4);
|
||||
});
|
||||
|
||||
it('Should remove a panel within a row', () => {
|
||||
const vizPanel = (
|
||||
((scene.state.body as SceneGridLayout).state.children[2] as SceneGridRow).state.children[0] as SceneGridItem
|
||||
).state.body;
|
||||
scene.removePanel(vizPanel as VizPanel);
|
||||
|
||||
const body = scene.state.body as SceneGridLayout;
|
||||
const gridRow = body.state.children[2] as SceneGridRow;
|
||||
expect(gridRow.state.children.length).toBe(1);
|
||||
});
|
||||
|
||||
it('Should remove a library panel', () => {
|
||||
const libraryPanel = ((scene.state.body as SceneGridLayout).state.children[4] as SceneGridItem).state.body;
|
||||
const vizPanel = (libraryPanel as LibraryVizPanel).state.panel;
|
||||
scene.removePanel(vizPanel as VizPanel);
|
||||
|
||||
const body = scene.state.body as SceneGridLayout;
|
||||
expect(body.state.children.length).toBe(4);
|
||||
});
|
||||
|
||||
it('Should remove a library panel within a row', () => {
|
||||
const libraryPanel = (
|
||||
((scene.state.body as SceneGridLayout).state.children[2] as SceneGridRow).state.children[1] as SceneGridItem
|
||||
).state.body;
|
||||
const vizPanel = (libraryPanel as LibraryVizPanel).state.panel;
|
||||
|
||||
scene.removePanel(vizPanel as VizPanel);
|
||||
|
||||
const body = scene.state.body as SceneGridLayout;
|
||||
const gridRow = body.state.children[2] as SceneGridRow;
|
||||
expect(gridRow.state.children.length).toBe(1);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@ -639,6 +680,19 @@ function buildTestScene(overrides?: Partial<DashboardSceneState>) {
|
||||
pluginId: 'table',
|
||||
}),
|
||||
}),
|
||||
new SceneGridItem({
|
||||
body: new LibraryVizPanel({
|
||||
uid: 'uid',
|
||||
name: 'libraryPanel',
|
||||
panelKey: 'panel-5',
|
||||
title: 'Library Panel',
|
||||
panel: new VizPanel({
|
||||
title: 'Library Panel',
|
||||
key: 'panel-5',
|
||||
pluginId: 'table',
|
||||
}),
|
||||
}),
|
||||
}),
|
||||
],
|
||||
}),
|
||||
new SceneGridItem({
|
||||
@ -653,11 +707,11 @@ function buildTestScene(overrides?: Partial<DashboardSceneState>) {
|
||||
body: new LibraryVizPanel({
|
||||
uid: 'uid',
|
||||
name: 'libraryPanel',
|
||||
panelKey: 'panel-4',
|
||||
panelKey: 'panel-6',
|
||||
title: 'Library Panel',
|
||||
panel: new VizPanel({
|
||||
title: 'Library Panel',
|
||||
key: 'panel-4',
|
||||
key: 'panel-6',
|
||||
pluginId: 'table',
|
||||
}),
|
||||
}),
|
||||
|
@ -560,6 +560,49 @@ export class DashboardScene extends SceneObjectBase<DashboardSceneState> {
|
||||
store.delete(LS_PANEL_COPY_KEY);
|
||||
}
|
||||
|
||||
public removePanel(panel: VizPanel) {
|
||||
const panels: SceneObject[] = [];
|
||||
const key = panel.parent instanceof LibraryVizPanel ? panel.parent.parent?.state.key : panel.parent?.state.key;
|
||||
|
||||
if (!key) {
|
||||
return;
|
||||
}
|
||||
|
||||
let row: SceneGridRow | undefined;
|
||||
|
||||
try {
|
||||
row = sceneGraph.getAncestor(panel, SceneGridRow);
|
||||
} catch {
|
||||
row = undefined;
|
||||
}
|
||||
|
||||
if (row) {
|
||||
row.forEachChild((child: SceneObject) => {
|
||||
if (child.state.key !== key) {
|
||||
panels.push(child);
|
||||
}
|
||||
});
|
||||
|
||||
row.setState({ children: panels });
|
||||
|
||||
this.state.body.forceRender();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
this.state.body.forEachChild((child: SceneObject) => {
|
||||
if (child.state.key !== key) {
|
||||
panels.push(child);
|
||||
}
|
||||
});
|
||||
|
||||
const layout = this.state.body;
|
||||
|
||||
if (layout instanceof SceneGridLayout || layout instanceof SceneFlexLayout) {
|
||||
layout.setState({ children: panels });
|
||||
}
|
||||
}
|
||||
|
||||
public showModal(modal: SceneObject) {
|
||||
this.setState({ overlay: modal });
|
||||
}
|
||||
|
@ -8,16 +8,7 @@ import {
|
||||
urlUtil,
|
||||
} from '@grafana/data';
|
||||
import { config, getPluginLinkExtensions, locationService } from '@grafana/runtime';
|
||||
import {
|
||||
LocalValueVariable,
|
||||
SceneFlexLayout,
|
||||
SceneGridLayout,
|
||||
SceneGridRow,
|
||||
SceneObject,
|
||||
VizPanel,
|
||||
VizPanelMenu,
|
||||
sceneGraph,
|
||||
} from '@grafana/scenes';
|
||||
import { LocalValueVariable, SceneGridRow, VizPanel, VizPanelMenu, sceneGraph } from '@grafana/scenes';
|
||||
import { DataQuery, OptionsWithLegend } from '@grafana/schema';
|
||||
import appEvents from 'app/core/app_events';
|
||||
import { t } from 'app/core/internationalization';
|
||||
@ -203,7 +194,7 @@ export function panelMenuBehavior(menu: VizPanelMenu) {
|
||||
iconClassName: 'trash-alt',
|
||||
onClick: () => {
|
||||
DashboardInteractions.panelMenuItemClicked('remove');
|
||||
removePanel(dashboard, panel, true);
|
||||
onRemovePanel(dashboard, panel);
|
||||
},
|
||||
shortcut: 'p r',
|
||||
});
|
||||
@ -377,7 +368,7 @@ function createExtensionContext(panel: VizPanel, dashboard: DashboardScene): Plu
|
||||
};
|
||||
}
|
||||
|
||||
export function removePanel(dashboard: DashboardScene, panel: VizPanel, ask: boolean) {
|
||||
export function onRemovePanel(dashboard: DashboardScene, panel: VizPanel) {
|
||||
const vizPanelData = sceneGraph.getData(panel);
|
||||
let panelHasAlert = false;
|
||||
|
||||
@ -385,40 +376,23 @@ export function removePanel(dashboard: DashboardScene, panel: VizPanel, ask: boo
|
||||
panelHasAlert = true;
|
||||
}
|
||||
|
||||
if (ask !== false) {
|
||||
const text2 =
|
||||
panelHasAlert && !config.unifiedAlertingEnabled
|
||||
? 'Panel includes an alert rule. removing the panel will also remove the alert rule'
|
||||
: undefined;
|
||||
const confirmText = panelHasAlert ? 'YES' : undefined;
|
||||
const text2 =
|
||||
panelHasAlert && !config.unifiedAlertingEnabled
|
||||
? 'Panel includes an alert rule. removing the panel will also remove the alert rule'
|
||||
: undefined;
|
||||
const confirmText = panelHasAlert ? 'YES' : undefined;
|
||||
|
||||
appEvents.publish(
|
||||
new ShowConfirmModalEvent({
|
||||
title: 'Remove panel',
|
||||
text: 'Are you sure you want to remove this panel?',
|
||||
text2: text2,
|
||||
icon: 'trash-alt',
|
||||
confirmText: confirmText,
|
||||
yesText: 'Remove',
|
||||
onConfirm: () => removePanel(dashboard, panel, false),
|
||||
})
|
||||
);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
const panels: SceneObject[] = [];
|
||||
dashboard.state.body.forEachChild((child: SceneObject) => {
|
||||
if (child.state.key !== panel.parent?.state.key) {
|
||||
panels.push(child);
|
||||
}
|
||||
});
|
||||
|
||||
const layout = dashboard.state.body;
|
||||
|
||||
if (layout instanceof SceneGridLayout || SceneFlexLayout) {
|
||||
layout.setState({ children: panels });
|
||||
}
|
||||
appEvents.publish(
|
||||
new ShowConfirmModalEvent({
|
||||
title: 'Remove panel',
|
||||
text: 'Are you sure you want to remove this panel?',
|
||||
text2: text2,
|
||||
icon: 'trash-alt',
|
||||
confirmText: confirmText,
|
||||
yesText: 'Remove',
|
||||
onConfirm: () => dashboard.removePanel(panel),
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
const onCreateAlert = async (panel: VizPanel) => {
|
||||
|
@ -8,7 +8,7 @@ import { getEditPanelUrl, getInspectUrl, getViewPanelUrl, tryGetExploreUrlForPan
|
||||
import { getPanelIdForVizPanel } from '../utils/utils';
|
||||
|
||||
import { DashboardScene } from './DashboardScene';
|
||||
import { removePanel, toggleVizPanelLegend } from './PanelMenuBehavior';
|
||||
import { onRemovePanel, toggleVizPanelLegend } from './PanelMenuBehavior';
|
||||
|
||||
export function setupKeyboardShortcuts(scene: DashboardScene) {
|
||||
const keybindings = new KeybindingSet();
|
||||
@ -120,7 +120,7 @@ export function setupKeyboardShortcuts(scene: DashboardScene) {
|
||||
keybindings.addBinding({
|
||||
key: 'p r',
|
||||
onTrigger: withFocusedPanel(scene, (vizPanel: VizPanel) => {
|
||||
removePanel(scene, vizPanel, true);
|
||||
onRemovePanel(scene, vizPanel);
|
||||
}),
|
||||
});
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user