mirror of
https://github.com/grafana/grafana.git
synced 2025-08-06 05:30:12 +08:00
DashboardScene: Allow unlinking a library panel (#83956)
* DashboardScene: Allow unlinking a library panel * Betterer * Revert * Review
This commit is contained in:
@ -490,6 +490,39 @@ describe('DashboardScene', () => {
|
||||
const gridRow = body.state.children[2] as SceneGridRow;
|
||||
expect(gridRow.state.children.length).toBe(1);
|
||||
});
|
||||
|
||||
it('Should unlink a library panel', () => {
|
||||
const libPanel = new LibraryVizPanel({
|
||||
title: 'title',
|
||||
uid: 'abc',
|
||||
name: 'lib panel',
|
||||
panelKey: 'panel-1',
|
||||
isLoaded: true,
|
||||
panel: new VizPanel({
|
||||
title: 'Panel B',
|
||||
pluginId: 'table',
|
||||
}),
|
||||
});
|
||||
|
||||
const scene = buildTestScene({
|
||||
body: new SceneGridLayout({
|
||||
children: [
|
||||
new SceneGridItem({
|
||||
key: 'griditem-2',
|
||||
body: libPanel,
|
||||
}),
|
||||
],
|
||||
}),
|
||||
});
|
||||
|
||||
scene.unlinkLibraryPanel(libPanel);
|
||||
|
||||
const body = scene.state.body as SceneGridLayout;
|
||||
const gridItem = body.state.children[0] as SceneGridItem;
|
||||
|
||||
expect(body.state.children.length).toBe(1);
|
||||
expect(gridItem.state.body).toBeInstanceOf(VizPanel);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
|
@ -603,6 +603,23 @@ export class DashboardScene extends SceneObjectBase<DashboardSceneState> {
|
||||
}
|
||||
}
|
||||
|
||||
public unlinkLibraryPanel(panel: LibraryVizPanel) {
|
||||
if (!panel.parent) {
|
||||
return;
|
||||
}
|
||||
|
||||
const gridItem = panel.parent;
|
||||
|
||||
if (!(gridItem instanceof SceneGridItem || gridItem instanceof PanelRepeaterGridItem)) {
|
||||
console.error('Trying to duplicate a panel in a layout that is not SceneGridItem or PanelRepeaterGridItem');
|
||||
return;
|
||||
}
|
||||
|
||||
gridItem?.setState({
|
||||
body: panel.state.panel?.clone(),
|
||||
});
|
||||
}
|
||||
|
||||
public showModal(modal: SceneObject) {
|
||||
this.setState({ overlay: modal });
|
||||
}
|
||||
|
@ -28,6 +28,7 @@ import { getDashboardSceneFor, getPanelIdForVizPanel, getQueryRunnerFor } from '
|
||||
import { DashboardScene } from './DashboardScene';
|
||||
import { LibraryVizPanel } from './LibraryVizPanel';
|
||||
import { VizPanelLinks, VizPanelLinksMenu } from './PanelLinks';
|
||||
import { UnlinkLibraryPanelModal } from './UnlinkLibraryPanelModal';
|
||||
|
||||
/**
|
||||
* Behavior is called when VizPanelMenu is activated (ie when it's opened).
|
||||
@ -37,6 +38,7 @@ export function panelMenuBehavior(menu: VizPanelMenu) {
|
||||
// hm.. add another generic param to SceneObject to specify parent type?
|
||||
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
||||
const panel = menu.parent as VizPanel;
|
||||
const parent = panel.parent;
|
||||
const plugin = panel.getPlugin();
|
||||
|
||||
const items: PanelMenuItem[] = [];
|
||||
@ -101,8 +103,18 @@ export function panelMenuBehavior(menu: VizPanelMenu) {
|
||||
},
|
||||
});
|
||||
|
||||
if (panel.parent instanceof LibraryVizPanel) {
|
||||
// TODO: Implement lib panel unlinking
|
||||
if (parent instanceof LibraryVizPanel) {
|
||||
moreSubMenu.push({
|
||||
text: t('panel.header-menu.unlink-library-panel', `Unlink library panel`),
|
||||
onClick: () => {
|
||||
DashboardInteractions.panelMenuItemClicked('unlinkLibraryPanel');
|
||||
dashboard.showModal(
|
||||
new UnlinkLibraryPanelModal({
|
||||
panelRef: parent.getRef(),
|
||||
})
|
||||
);
|
||||
},
|
||||
});
|
||||
} else {
|
||||
moreSubMenu.push({
|
||||
text: t('panel.header-menu.create-library-panel', `Create library panel`),
|
||||
|
@ -0,0 +1,44 @@
|
||||
import React from 'react';
|
||||
|
||||
import { SceneComponentProps, SceneObjectBase, SceneObjectRef, SceneObjectState } from '@grafana/scenes';
|
||||
|
||||
import { ModalSceneObjectLike } from '../sharing/types';
|
||||
import { getDashboardSceneFor } from '../utils/utils';
|
||||
|
||||
import { LibraryVizPanel } from './LibraryVizPanel';
|
||||
import { UnlinkModal } from './UnlinkModal';
|
||||
|
||||
interface UnlinkLibraryPanelModalState extends SceneObjectState {
|
||||
panelRef?: SceneObjectRef<LibraryVizPanel>;
|
||||
}
|
||||
|
||||
export class UnlinkLibraryPanelModal
|
||||
extends SceneObjectBase<UnlinkLibraryPanelModalState>
|
||||
implements ModalSceneObjectLike
|
||||
{
|
||||
static Component = UnlinkLibraryPanelModalRenderer;
|
||||
|
||||
public onDismiss = () => {
|
||||
const dashboard = getDashboardSceneFor(this);
|
||||
dashboard.closeModal();
|
||||
};
|
||||
|
||||
public onConfirm = () => {
|
||||
const dashboard = getDashboardSceneFor(this);
|
||||
dashboard.unlinkLibraryPanel(this.state.panelRef!.resolve());
|
||||
dashboard.closeModal();
|
||||
};
|
||||
}
|
||||
|
||||
function UnlinkLibraryPanelModalRenderer({ model }: SceneComponentProps<UnlinkLibraryPanelModal>) {
|
||||
return (
|
||||
<UnlinkModal
|
||||
isOpen={true}
|
||||
onConfirm={() => {
|
||||
model.onConfirm();
|
||||
model.onDismiss();
|
||||
}}
|
||||
onDismiss={model.onDismiss}
|
||||
/>
|
||||
);
|
||||
}
|
@ -33,7 +33,7 @@ import { StoreState } from 'app/types';
|
||||
import { PanelOptionsChangedEvent, ShowModalReactEvent } from 'app/types/events';
|
||||
|
||||
import { notifyApp } from '../../../../core/actions';
|
||||
import { UnlinkModal } from '../../../library-panels/components/UnlinkModal/UnlinkModal';
|
||||
import { UnlinkModal } from '../../../dashboard-scene/scene/UnlinkModal';
|
||||
import { isPanelModelLibraryPanel } from '../../../library-panels/guard';
|
||||
import { getVariablesByKey } from '../../../variables/state/selectors';
|
||||
import { DashboardPanel } from '../../dashgrid/DashboardPanel';
|
||||
|
@ -9,8 +9,8 @@ import store from 'app/core/store';
|
||||
import { ShareModal } from 'app/features/dashboard/components/ShareModal';
|
||||
import { DashboardModel } from 'app/features/dashboard/state/DashboardModel';
|
||||
import { PanelModel } from 'app/features/dashboard/state/PanelModel';
|
||||
import { UnlinkModal } from 'app/features/dashboard-scene/scene/UnlinkModal';
|
||||
import { AddLibraryPanelModal } from 'app/features/library-panels/components/AddLibraryPanelModal/AddLibraryPanelModal';
|
||||
import { UnlinkModal } from 'app/features/library-panels/components/UnlinkModal/UnlinkModal';
|
||||
import { cleanUpPanelState } from 'app/features/panel/state/actions';
|
||||
import { dispatch } from 'app/store/store';
|
||||
|
||||
|
Reference in New Issue
Block a user