diff --git a/public/app/features/dashboard/dashgrid/PanelHeader/PanelHeaderMenu.tsx b/public/app/features/dashboard/dashgrid/PanelHeader/PanelHeaderMenu.tsx index 826406fddff..adce83e8c40 100644 --- a/public/app/features/dashboard/dashgrid/PanelHeader/PanelHeaderMenu.tsx +++ b/public/app/features/dashboard/dashgrid/PanelHeader/PanelHeaderMenu.tsx @@ -1,16 +1,7 @@ -import React, { PureComponent } from 'react'; +import React, { PureComponent, Fragment } from 'react'; import { DashboardModel } from 'app/features/dashboard/dashboard_model'; -import { PanelHeaderMenuItem, PanelHeaderMenuItemTypes } from './PanelHeaderMenuItem'; -import { store } from 'app/store/configureStore'; -import { updateLocation } from 'app/core/actions'; -import { - removePanel, - duplicatePanel, - copyPanel, - editPanelJson, - sharePanel, - toggleLegend, -} from 'app/features/dashboard/utils/panel'; +import { PanelHeaderMenuItem, PanelHeaderMenuItemProps } from './PanelHeaderMenuItem'; +import { getPanelMenu } from 'app/features/dashboard/utils/panel_menu'; export interface PanelHeaderMenuProps { panelId: number; @@ -25,130 +16,32 @@ export class PanelHeaderMenu extends PureComponent { return panelInfo.panel; }; - onEditPanel = () => { - store.dispatch( - updateLocation({ - query: { - panelId: this.props.panelId, - edit: true, - fullscreen: true, - }, - }) + renderItems = (menu: PanelHeaderMenuItemProps[], isSubMenu = false) => { + return ( + ); }; - onViewPanel = () => { - store.dispatch( - updateLocation({ - query: { - panelId: this.props.panelId, - edit: false, - fullscreen: true, - }, - }) - ); - }; - - onRemovePanel = () => { - const { dashboard } = this.props; - const panel = this.getPanel(); - removePanel(dashboard, panel, true); - }; - - onSharePanel = () => { - const { dashboard } = this.props; - const panel = this.getPanel(); - - sharePanel(dashboard, panel); - }; - - onDuplicatePanel = () => { - const { dashboard } = this.props; - const panel = this.getPanel(); - - duplicatePanel(dashboard, panel); - }; - - onCopyPanel = () => { - const panel = this.getPanel(); - copyPanel(panel); - }; - - onEditPanelJson = () => { - const { dashboard } = this.props; - const panel = this.getPanel(); - editPanelJson(dashboard, panel); - }; - - onToggleLegend = () => { - const panel = this.getPanel(); - toggleLegend(panel); - }; - render() { - return ( -
- -
- ); + const { dashboard } = this.props; + const menu = getPanelMenu(dashboard, this.getPanel()); + return
{this.renderItems(menu)}
; } } diff --git a/public/app/features/dashboard/dashgrid/PanelHeader/PanelHeaderMenuItem.tsx b/public/app/features/dashboard/dashgrid/PanelHeader/PanelHeaderMenuItem.tsx index 3eb4e72ca9d..f0b5579c2a1 100644 --- a/public/app/features/dashboard/dashgrid/PanelHeader/PanelHeaderMenuItem.tsx +++ b/public/app/features/dashboard/dashgrid/PanelHeader/PanelHeaderMenuItem.tsx @@ -1,6 +1,6 @@ import React, { SFC } from 'react'; -export enum PanelHeaderMenuItemTypes { +export enum PanelHeaderMenuItemTypes { // TODO: Evaluate. Remove? Button = 'Button', // ? Divider = 'Divider', Link = 'Link', @@ -14,6 +14,8 @@ export interface PanelHeaderMenuItemProps { handleClick?: () => void; shortcut?: string; children?: any; + subMenu?: PanelHeaderMenuItemProps[]; + role?: string; } export const PanelHeaderMenuItem: SFC = props => { diff --git a/public/app/features/dashboard/utils/panel_menu.ts b/public/app/features/dashboard/utils/panel_menu.ts new file mode 100644 index 00000000000..de2ba852d13 --- /dev/null +++ b/public/app/features/dashboard/utils/panel_menu.ts @@ -0,0 +1,140 @@ +import { PanelHeaderMenuItemTypes, PanelHeaderMenuItemProps } from './../dashgrid/PanelHeader/PanelHeaderMenuItem'; +import { store } from 'app/store/configureStore'; +import { updateLocation } from 'app/core/actions'; +import { PanelModel } from 'app/features/dashboard/panel_model'; +import { DashboardModel } from 'app/features/dashboard/dashboard_model'; +import { removePanel, duplicatePanel, copyPanel, editPanelJson, sharePanel } from 'app/features/dashboard/utils/panel'; + +export const getPanelMenu = (dashboard: DashboardModel, panel: PanelModel) => { + const onViewPanel = () => { + store.dispatch( + updateLocation({ + query: { + panelId: panel.id, + edit: false, + fullscreen: true, + }, + }) + ); + }; + + const onEditPanel = () => { + store.dispatch( + updateLocation({ + query: { + panelId: panel.id, + edit: true, + fullscreen: true, + }, + }) + ); + }; + + const onSharePanel = () => { + sharePanel(dashboard, panel); + }; + + const onDuplicatePanel = () => { + duplicatePanel(dashboard, panel); + }; + + const onCopyPanel = () => { + copyPanel(panel); + }; + + const onEditPanelJson = () => { + editPanelJson(dashboard, panel); + }; + + const onRemovePanel = () => { + removePanel(dashboard, panel, true); + }; + + const getSubMenu = () => { + const menu: PanelHeaderMenuItemProps[] = []; + + if (!panel.fullscreen && dashboard.meta.canEdit) { + menu.push({ + type: PanelHeaderMenuItemTypes.Link, + text: 'Duplicate', + handleClick: onDuplicatePanel, + shortcut: 'p d', + role: 'Editor', + }); + menu.push({ + type: PanelHeaderMenuItemTypes.Link, + text: 'Copy', + handleClick: onCopyPanel, + role: 'Editor', + }); + } + + menu.push({ + type: PanelHeaderMenuItemTypes.Link, + text: 'Panel JSON', + handleClick: onEditPanelJson, + }); + + // TODO: Handle this somehow + // this.events.emit('init-panel-actions', menu); + return menu; + }; + + const menu: PanelHeaderMenuItemProps[] = []; + + menu.push({ + type: PanelHeaderMenuItemTypes.Link, + text: 'View', + iconClassName: 'fa fa-fw fa-eye', + handleClick: onViewPanel, + shortcut: 'v', + }); + + if (dashboard.meta.canEdit) { + menu.push({ + type: PanelHeaderMenuItemTypes.Link, + text: 'Edit', + iconClassName: 'fa fa-fw fa-edit', + handleClick: onEditPanel, + shortcut: 'e', + role: 'Editor', + }); + } + + menu.push({ + type: PanelHeaderMenuItemTypes.Link, + text: 'Share', + iconClassName: 'fa fa-fw fa-share', + handleClick: onSharePanel, + shortcut: 'p s', + }); + + const subMenu: PanelHeaderMenuItemProps[] = getSubMenu(); + + menu.push({ + type: PanelHeaderMenuItemTypes.SubMenu, + text: 'More...', + iconClassName: 'fa fa-fw fa-cube', + handleClick: null, + subMenu: subMenu, + }); + + if (dashboard.meta.canEdit) { + menu.push({ + type: PanelHeaderMenuItemTypes.Divider, + role: 'Editor', + }); + menu.push({ + type: PanelHeaderMenuItemTypes.Link, + text: 'Remove', + iconClassName: 'fa fa-fw fa-trash', + handleClick: onRemovePanel, + shortcut: 'p r', + role: 'Editor', + }); + } + + // Additional items from sub-class + // menu.push(...this.getAdditionalMenuItems()); + return menu; +};