mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
Scenes: Add 'Import from library' functionality (#83498)
* wip * tests + refactor ad panel func * Add row functionality * update row state only when there are children * Add new row + copy paste panels * Add library panel functionality * tests * PR mods * reafctor + tests * reafctor * fix test * refactor * fix bug on cancelling lib widget * dashboard now saves with lib panel widget * add lib panels widget works in rows as well * split add lib panel func to another PR * Add library panel functionality * refactor * take panelKey into account when getting next panel id in dashboard * fix tests
This commit is contained in:
@@ -0,0 +1,252 @@
|
||||
import { SceneGridItem, SceneGridLayout, SceneGridRow, SceneTimeRange } from '@grafana/scenes';
|
||||
import { LibraryPanel } from '@grafana/schema/dist/esm/index.gen';
|
||||
|
||||
import { DashboardScene } from '../scene/DashboardScene';
|
||||
import { activateFullSceneTree } from '../utils/test-utils';
|
||||
|
||||
import { AddLibraryPanelWidget } from './AddLibraryPanelWidget';
|
||||
import { LibraryVizPanel } from './LibraryVizPanel';
|
||||
|
||||
describe('AddLibraryPanelWidget', () => {
|
||||
let dashboard: DashboardScene;
|
||||
let addLibPanelWidget: AddLibraryPanelWidget;
|
||||
const mockEvent = {
|
||||
preventDefault: jest.fn(),
|
||||
} as unknown as React.MouseEvent<HTMLButtonElement>;
|
||||
|
||||
beforeEach(async () => {
|
||||
const result = await buildTestScene();
|
||||
dashboard = result.dashboard;
|
||||
addLibPanelWidget = result.addLibPanelWidget;
|
||||
});
|
||||
|
||||
it('should return the dashboard', () => {
|
||||
expect(addLibPanelWidget.getDashboard()).toBe(dashboard);
|
||||
});
|
||||
|
||||
it('should cancel adding a lib panel', () => {
|
||||
addLibPanelWidget.onCancelAddPanel(mockEvent);
|
||||
|
||||
const body = dashboard.state.body as SceneGridLayout;
|
||||
|
||||
expect(body.state.children.length).toBe(0);
|
||||
});
|
||||
|
||||
it('should cancel lib panel at correct position', () => {
|
||||
const anotherLibPanelWidget = new AddLibraryPanelWidget({ key: 'panel-2' });
|
||||
const body = dashboard.state.body as SceneGridLayout;
|
||||
|
||||
body.setState({
|
||||
children: [
|
||||
...body.state.children,
|
||||
new SceneGridItem({
|
||||
key: 'griditem-2',
|
||||
x: 0,
|
||||
y: 0,
|
||||
width: 10,
|
||||
height: 12,
|
||||
body: anotherLibPanelWidget,
|
||||
}),
|
||||
],
|
||||
});
|
||||
dashboard.setState({ body });
|
||||
|
||||
anotherLibPanelWidget.onCancelAddPanel(mockEvent);
|
||||
|
||||
const gridItem = body.state.children[0] as SceneGridItem;
|
||||
|
||||
expect(body.state.children.length).toBe(1);
|
||||
expect(gridItem.state.body!.state.key).toBe(addLibPanelWidget.state.key);
|
||||
});
|
||||
|
||||
it('should cancel lib panel inside a row child', () => {
|
||||
const anotherLibPanelWidget = new AddLibraryPanelWidget({ key: 'panel-2' });
|
||||
dashboard.setState({
|
||||
body: new SceneGridLayout({
|
||||
children: [
|
||||
new SceneGridRow({
|
||||
key: 'panel-2',
|
||||
children: [
|
||||
new SceneGridItem({
|
||||
key: 'griditem-2',
|
||||
x: 0,
|
||||
y: 0,
|
||||
width: 10,
|
||||
height: 12,
|
||||
body: anotherLibPanelWidget,
|
||||
}),
|
||||
],
|
||||
}),
|
||||
],
|
||||
}),
|
||||
});
|
||||
|
||||
const body = dashboard.state.body as SceneGridLayout;
|
||||
|
||||
anotherLibPanelWidget.onCancelAddPanel(mockEvent);
|
||||
|
||||
const gridRow = body.state.children[0] as SceneGridRow;
|
||||
|
||||
expect(body.state.children.length).toBe(1);
|
||||
expect(gridRow.state.children.length).toBe(0);
|
||||
});
|
||||
|
||||
it('should add library panel from menu', () => {
|
||||
const panelInfo: LibraryPanel = {
|
||||
uid: 'uid',
|
||||
model: {
|
||||
type: 'timeseries',
|
||||
},
|
||||
name: 'name',
|
||||
version: 1,
|
||||
type: 'timeseries',
|
||||
};
|
||||
|
||||
const body = dashboard.state.body as SceneGridLayout;
|
||||
const gridItem = body.state.children[0] as SceneGridItem;
|
||||
|
||||
expect(gridItem.state.body!).toBeInstanceOf(AddLibraryPanelWidget);
|
||||
|
||||
addLibPanelWidget.onAddLibraryPanel(panelInfo);
|
||||
|
||||
expect(body.state.children.length).toBe(1);
|
||||
expect(gridItem.state.body!).toBeInstanceOf(LibraryVizPanel);
|
||||
expect((gridItem.state.body! as LibraryVizPanel).state.panelKey).toBe(addLibPanelWidget.state.key);
|
||||
});
|
||||
|
||||
it('should add a lib panel at correct position', () => {
|
||||
const anotherLibPanelWidget = new AddLibraryPanelWidget({ key: 'panel-2' });
|
||||
const body = dashboard.state.body as SceneGridLayout;
|
||||
|
||||
body.setState({
|
||||
children: [
|
||||
...body.state.children,
|
||||
new SceneGridItem({
|
||||
key: 'griditem-2',
|
||||
x: 0,
|
||||
y: 0,
|
||||
width: 10,
|
||||
height: 12,
|
||||
body: anotherLibPanelWidget,
|
||||
}),
|
||||
],
|
||||
});
|
||||
dashboard.setState({ body });
|
||||
|
||||
const panelInfo: LibraryPanel = {
|
||||
uid: 'uid',
|
||||
model: {
|
||||
type: 'timeseries',
|
||||
},
|
||||
name: 'name',
|
||||
version: 1,
|
||||
type: 'timeseries',
|
||||
};
|
||||
|
||||
anotherLibPanelWidget.onAddLibraryPanel(panelInfo);
|
||||
|
||||
const gridItemOne = body.state.children[0] as SceneGridItem;
|
||||
const gridItemTwo = body.state.children[1] as SceneGridItem;
|
||||
|
||||
expect(body.state.children.length).toBe(2);
|
||||
expect(gridItemOne.state.body!).toBeInstanceOf(AddLibraryPanelWidget);
|
||||
expect((gridItemTwo.state.body! as LibraryVizPanel).state.panelKey).toBe(anotherLibPanelWidget.state.key);
|
||||
});
|
||||
|
||||
it('should add library panel from menu to a row child', () => {
|
||||
const anotherLibPanelWidget = new AddLibraryPanelWidget({ key: 'panel-2' });
|
||||
dashboard.setState({
|
||||
body: new SceneGridLayout({
|
||||
children: [
|
||||
new SceneGridRow({
|
||||
key: 'panel-2',
|
||||
children: [
|
||||
new SceneGridItem({
|
||||
key: 'griditem-2',
|
||||
x: 0,
|
||||
y: 0,
|
||||
width: 10,
|
||||
height: 12,
|
||||
body: anotherLibPanelWidget,
|
||||
}),
|
||||
],
|
||||
}),
|
||||
],
|
||||
}),
|
||||
});
|
||||
|
||||
const panelInfo: LibraryPanel = {
|
||||
uid: 'uid',
|
||||
model: {
|
||||
type: 'timeseries',
|
||||
},
|
||||
name: 'name',
|
||||
version: 1,
|
||||
type: 'timeseries',
|
||||
};
|
||||
|
||||
const body = dashboard.state.body as SceneGridLayout;
|
||||
|
||||
anotherLibPanelWidget.onAddLibraryPanel(panelInfo);
|
||||
|
||||
const gridRow = body.state.children[0] as SceneGridRow;
|
||||
const gridItem = gridRow.state.children[0] as SceneGridItem;
|
||||
|
||||
expect(body.state.children.length).toBe(1);
|
||||
expect(gridItem.state.body!).toBeInstanceOf(LibraryVizPanel);
|
||||
expect((gridItem.state.body! as LibraryVizPanel).state.panelKey).toBe(anotherLibPanelWidget.state.key);
|
||||
});
|
||||
|
||||
it('should throw error if adding lib panel in a layout that is not SceneGridLayout', () => {
|
||||
dashboard.setState({
|
||||
body: undefined,
|
||||
});
|
||||
|
||||
expect(() => addLibPanelWidget.onAddLibraryPanel({} as LibraryPanel)).toThrow(
|
||||
'Trying to add a library panel in a layout that is not SceneGridLayout'
|
||||
);
|
||||
});
|
||||
|
||||
it('should throw error if removing the library panel widget in a layout that is not SceneGridLayout', () => {
|
||||
dashboard.setState({
|
||||
body: undefined,
|
||||
});
|
||||
|
||||
expect(() => addLibPanelWidget.onCancelAddPanel(mockEvent)).toThrow(
|
||||
'Trying to remove the library panel widget in a layout that is not SceneGridLayout'
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
async function buildTestScene() {
|
||||
const addLibPanelWidget = new AddLibraryPanelWidget({ key: 'panel-1' });
|
||||
const dashboard = new DashboardScene({
|
||||
$timeRange: new SceneTimeRange({}),
|
||||
title: 'hello',
|
||||
uid: 'dash-1',
|
||||
version: 4,
|
||||
meta: {
|
||||
canEdit: true,
|
||||
},
|
||||
body: new SceneGridLayout({
|
||||
children: [
|
||||
new SceneGridItem({
|
||||
key: 'griditem-1',
|
||||
x: 0,
|
||||
y: 0,
|
||||
width: 10,
|
||||
height: 12,
|
||||
body: addLibPanelWidget,
|
||||
}),
|
||||
],
|
||||
}),
|
||||
});
|
||||
|
||||
activateFullSceneTree(dashboard);
|
||||
|
||||
await new Promise((r) => setTimeout(r, 1));
|
||||
|
||||
dashboard.onEnterEditMode();
|
||||
|
||||
return { dashboard, addLibPanelWidget };
|
||||
}
|
||||
Reference in New Issue
Block a user