mirror of
https://github.com/grafana/grafana.git
synced 2025-02-14 17:43:35 -06:00
Dashboard scenes: Remove panel menu options that are dashboard editing activities when not in edit mode. (#84156)
* remove panel menu options that are dasbhoard editing activities when the dashboard is not in edit mode * remove corresponding keybindings when not in edit mode * add keyboard shortcuts but inactivate them when not in edit mode * Add tests; fix tests
This commit is contained in:
parent
e8ecbaffc2
commit
87d6bebb9e
@ -70,7 +70,7 @@ describe('panelMenuBehavior', () => {
|
|||||||
|
|
||||||
await new Promise((r) => setTimeout(r, 1));
|
await new Promise((r) => setTimeout(r, 1));
|
||||||
|
|
||||||
expect(menu.state.items?.length).toBe(8);
|
expect(menu.state.items?.length).toBe(6);
|
||||||
// verify view panel url keeps url params and adds viewPanel=<panel-key>
|
// verify view panel url keeps url params and adds viewPanel=<panel-key>
|
||||||
expect(menu.state.items?.[0].href).toBe('/d/dash-1?from=now-5m&to=now&viewPanel=panel-12');
|
expect(menu.state.items?.[0].href).toBe('/d/dash-1?from=now-5m&to=now&viewPanel=panel-12');
|
||||||
// verify edit url keeps url time range
|
// verify edit url keeps url time range
|
||||||
@ -119,7 +119,7 @@ describe('panelMenuBehavior', () => {
|
|||||||
|
|
||||||
await new Promise((r) => setTimeout(r, 1));
|
await new Promise((r) => setTimeout(r, 1));
|
||||||
|
|
||||||
expect(menu.state.items?.length).toBe(9);
|
expect(menu.state.items?.length).toBe(7);
|
||||||
|
|
||||||
const extensionsSubMenu = menu.state.items?.find((i) => i.text === 'Extensions')?.subMenu;
|
const extensionsSubMenu = menu.state.items?.find((i) => i.text === 'Extensions')?.subMenu;
|
||||||
|
|
||||||
@ -158,7 +158,7 @@ describe('panelMenuBehavior', () => {
|
|||||||
|
|
||||||
await new Promise((r) => setTimeout(r, 1));
|
await new Promise((r) => setTimeout(r, 1));
|
||||||
|
|
||||||
expect(menu.state.items?.length).toBe(9);
|
expect(menu.state.items?.length).toBe(7);
|
||||||
|
|
||||||
const extensionsSubMenu = menu.state.items?.find((i) => i.text === 'Extensions')?.subMenu;
|
const extensionsSubMenu = menu.state.items?.find((i) => i.text === 'Extensions')?.subMenu;
|
||||||
|
|
||||||
@ -199,7 +199,7 @@ describe('panelMenuBehavior', () => {
|
|||||||
|
|
||||||
await new Promise((r) => setTimeout(r, 1));
|
await new Promise((r) => setTimeout(r, 1));
|
||||||
|
|
||||||
expect(menu.state.items?.length).toBe(9);
|
expect(menu.state.items?.length).toBe(7);
|
||||||
|
|
||||||
const extensionsSubMenu = menu.state.items?.find((i) => i.text === 'Extensions')?.subMenu;
|
const extensionsSubMenu = menu.state.items?.find((i) => i.text === 'Extensions')?.subMenu;
|
||||||
const menuItem = extensionsSubMenu?.find((i) => (i.text = 'Declare incident when...'));
|
const menuItem = extensionsSubMenu?.find((i) => (i.text = 'Declare incident when...'));
|
||||||
@ -347,7 +347,7 @@ describe('panelMenuBehavior', () => {
|
|||||||
|
|
||||||
await new Promise((r) => setTimeout(r, 1));
|
await new Promise((r) => setTimeout(r, 1));
|
||||||
|
|
||||||
expect(menu.state.items?.length).toBe(9);
|
expect(menu.state.items?.length).toBe(7);
|
||||||
|
|
||||||
const extensionsSubMenu = menu.state.items?.find((i) => i.text === 'Extensions')?.subMenu;
|
const extensionsSubMenu = menu.state.items?.find((i) => i.text === 'Extensions')?.subMenu;
|
||||||
|
|
||||||
@ -392,7 +392,7 @@ describe('panelMenuBehavior', () => {
|
|||||||
|
|
||||||
await new Promise((r) => setTimeout(r, 1));
|
await new Promise((r) => setTimeout(r, 1));
|
||||||
|
|
||||||
expect(menu.state.items?.length).toBe(9);
|
expect(menu.state.items?.length).toBe(7);
|
||||||
|
|
||||||
const extensionsSubMenu = menu.state.items?.find((i) => i.text === 'Extensions')?.subMenu;
|
const extensionsSubMenu = menu.state.items?.find((i) => i.text === 'Extensions')?.subMenu;
|
||||||
|
|
||||||
@ -445,7 +445,7 @@ describe('panelMenuBehavior', () => {
|
|||||||
|
|
||||||
await new Promise((r) => setTimeout(r, 1));
|
await new Promise((r) => setTimeout(r, 1));
|
||||||
|
|
||||||
expect(menu.state.items?.length).toBe(9);
|
expect(menu.state.items?.length).toBe(7);
|
||||||
|
|
||||||
const extensionsSubMenu = menu.state.items?.find((i) => i.text === 'Extensions')?.subMenu;
|
const extensionsSubMenu = menu.state.items?.find((i) => i.text === 'Extensions')?.subMenu;
|
||||||
|
|
||||||
@ -470,6 +470,43 @@ describe('panelMenuBehavior', () => {
|
|||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('it should not contain remove and duplicate menu items when not in edit mode', async () => {
|
||||||
|
const { menu, panel } = await buildTestScene({});
|
||||||
|
|
||||||
|
panel.getPlugin = () => getPanelPlugin({ skipDataQuery: false });
|
||||||
|
|
||||||
|
mocks.contextSrv.hasAccessToExplore.mockReturnValue(true);
|
||||||
|
mocks.getExploreUrl.mockReturnValue(Promise.resolve('/explore'));
|
||||||
|
|
||||||
|
menu.activate();
|
||||||
|
|
||||||
|
await new Promise((r) => setTimeout(r, 1));
|
||||||
|
|
||||||
|
expect(menu.state.items?.find((i) => i.text === 'Remove')).toBeUndefined();
|
||||||
|
const moreMenu = menu.state.items?.find((i) => i.text === 'More...')?.subMenu;
|
||||||
|
expect(moreMenu?.find((i) => i.text === 'Duplicate')).toBeUndefined();
|
||||||
|
expect(moreMenu?.find((i) => i.text === 'Create library panel')).toBeUndefined();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('it should contain remove and duplicate menu items when in edit mode', async () => {
|
||||||
|
const { scene, menu, panel } = await buildTestScene({});
|
||||||
|
scene.setState({ isEditing: true });
|
||||||
|
|
||||||
|
panel.getPlugin = () => getPanelPlugin({ skipDataQuery: false });
|
||||||
|
|
||||||
|
mocks.contextSrv.hasAccessToExplore.mockReturnValue(true);
|
||||||
|
mocks.getExploreUrl.mockReturnValue(Promise.resolve('/explore'));
|
||||||
|
|
||||||
|
menu.activate();
|
||||||
|
|
||||||
|
await new Promise((r) => setTimeout(r, 1));
|
||||||
|
|
||||||
|
expect(menu.state.items?.find((i) => i.text === 'Remove')).toBeDefined();
|
||||||
|
const moreMenu = menu.state.items?.find((i) => i.text === 'More...')?.subMenu;
|
||||||
|
expect(moreMenu?.find((i) => i.text === 'Duplicate')).toBeDefined();
|
||||||
|
expect(moreMenu?.find((i) => i.text === 'Create library panel')).toBeDefined();
|
||||||
|
});
|
||||||
|
|
||||||
it('should only contain explore when embedded', async () => {
|
it('should only contain explore when embedded', async () => {
|
||||||
const { menu, panel } = await buildTestScene({ isEmbedded: true });
|
const { menu, panel } = await buildTestScene({ isEmbedded: true });
|
||||||
|
|
||||||
|
@ -86,14 +86,16 @@ export function panelMenuBehavior(menu: VizPanelMenu) {
|
|||||||
shortcut: 'p s',
|
shortcut: 'p s',
|
||||||
});
|
});
|
||||||
|
|
||||||
moreSubMenu.push({
|
if (dashboard.state.isEditing) {
|
||||||
text: t('panel.header-menu.duplicate', `Duplicate`),
|
moreSubMenu.push({
|
||||||
onClick: () => {
|
text: t('panel.header-menu.duplicate', `Duplicate`),
|
||||||
DashboardInteractions.panelMenuItemClicked('duplicate');
|
onClick: () => {
|
||||||
dashboard.duplicatePanel(panel);
|
DashboardInteractions.panelMenuItemClicked('duplicate');
|
||||||
},
|
dashboard.duplicatePanel(panel);
|
||||||
shortcut: 'p d',
|
},
|
||||||
});
|
shortcut: 'p d',
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
moreSubMenu.push({
|
moreSubMenu.push({
|
||||||
text: t('panel.header-menu.copy', `Copy`),
|
text: t('panel.header-menu.copy', `Copy`),
|
||||||
@ -103,32 +105,34 @@ export function panelMenuBehavior(menu: VizPanelMenu) {
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
if (parent instanceof LibraryVizPanel) {
|
if (dashboard.state.isEditing) {
|
||||||
moreSubMenu.push({
|
if (parent instanceof LibraryVizPanel) {
|
||||||
text: t('panel.header-menu.unlink-library-panel', `Unlink library panel`),
|
moreSubMenu.push({
|
||||||
onClick: () => {
|
text: t('panel.header-menu.unlink-library-panel', `Unlink library panel`),
|
||||||
DashboardInteractions.panelMenuItemClicked('unlinkLibraryPanel');
|
onClick: () => {
|
||||||
dashboard.showModal(
|
DashboardInteractions.panelMenuItemClicked('unlinkLibraryPanel');
|
||||||
new UnlinkLibraryPanelModal({
|
dashboard.showModal(
|
||||||
panelRef: parent.getRef(),
|
new UnlinkLibraryPanelModal({
|
||||||
})
|
panelRef: parent.getRef(),
|
||||||
);
|
})
|
||||||
},
|
);
|
||||||
});
|
},
|
||||||
} else {
|
});
|
||||||
moreSubMenu.push({
|
} else {
|
||||||
text: t('panel.header-menu.create-library-panel', `Create library panel`),
|
moreSubMenu.push({
|
||||||
onClick: () => {
|
text: t('panel.header-menu.create-library-panel', `Create library panel`),
|
||||||
DashboardInteractions.panelMenuItemClicked('createLibraryPanel');
|
onClick: () => {
|
||||||
dashboard.showModal(
|
DashboardInteractions.panelMenuItemClicked('createLibraryPanel');
|
||||||
new ShareModal({
|
dashboard.showModal(
|
||||||
panelRef: panel.getRef(),
|
new ShareModal({
|
||||||
dashboardRef: dashboard.getRef(),
|
panelRef: panel.getRef(),
|
||||||
activeTab: shareDashboardType.libraryPanel,
|
dashboardRef: dashboard.getRef(),
|
||||||
})
|
activeTab: shareDashboardType.libraryPanel,
|
||||||
);
|
})
|
||||||
},
|
);
|
||||||
});
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
moreSubMenu.push({
|
moreSubMenu.push({
|
||||||
@ -196,20 +200,22 @@ export function panelMenuBehavior(menu: VizPanelMenu) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
items.push({
|
if (dashboard.state.isEditing) {
|
||||||
text: '',
|
items.push({
|
||||||
type: 'divider',
|
text: '',
|
||||||
});
|
type: 'divider',
|
||||||
|
});
|
||||||
|
|
||||||
items.push({
|
items.push({
|
||||||
text: t('panel.header-menu.remove', `Remove`),
|
text: t('panel.header-menu.remove', `Remove`),
|
||||||
iconClassName: 'trash-alt',
|
iconClassName: 'trash-alt',
|
||||||
onClick: () => {
|
onClick: () => {
|
||||||
DashboardInteractions.panelMenuItemClicked('remove');
|
DashboardInteractions.panelMenuItemClicked('remove');
|
||||||
onRemovePanel(dashboard, panel);
|
onRemovePanel(dashboard, panel);
|
||||||
},
|
},
|
||||||
shortcut: 'p r',
|
shortcut: 'p r',
|
||||||
});
|
});
|
||||||
|
}
|
||||||
|
|
||||||
menu.setState({ items });
|
menu.setState({ items });
|
||||||
};
|
};
|
||||||
|
@ -120,7 +120,9 @@ export function setupKeyboardShortcuts(scene: DashboardScene) {
|
|||||||
keybindings.addBinding({
|
keybindings.addBinding({
|
||||||
key: 'p r',
|
key: 'p r',
|
||||||
onTrigger: withFocusedPanel(scene, (vizPanel: VizPanel) => {
|
onTrigger: withFocusedPanel(scene, (vizPanel: VizPanel) => {
|
||||||
onRemovePanel(scene, vizPanel);
|
if (scene.state.isEditing) {
|
||||||
|
onRemovePanel(scene, vizPanel);
|
||||||
|
}
|
||||||
}),
|
}),
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -128,7 +130,9 @@ export function setupKeyboardShortcuts(scene: DashboardScene) {
|
|||||||
keybindings.addBinding({
|
keybindings.addBinding({
|
||||||
key: 'p d',
|
key: 'p d',
|
||||||
onTrigger: withFocusedPanel(scene, (vizPanel: VizPanel) => {
|
onTrigger: withFocusedPanel(scene, (vizPanel: VizPanel) => {
|
||||||
scene.duplicatePanel(vizPanel);
|
if (scene.state.isEditing) {
|
||||||
|
scene.duplicatePanel(vizPanel);
|
||||||
|
}
|
||||||
}),
|
}),
|
||||||
});
|
});
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user