mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
wip: panel-header: Separate all panel actions to its own file so we decouple them from react
This commit is contained in:
parent
6151310216
commit
f124b9de6a
@ -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<PanelHeaderMenuProps, any> {
|
||||
return panelInfo.panel;
|
||||
};
|
||||
|
||||
onEditPanel = () => {
|
||||
store.dispatch(
|
||||
updateLocation({
|
||||
query: {
|
||||
panelId: this.props.panelId,
|
||||
edit: true,
|
||||
fullscreen: true,
|
||||
},
|
||||
})
|
||||
renderItems = (menu: PanelHeaderMenuItemProps[], isSubMenu = false) => {
|
||||
return (
|
||||
<ul className="dropdown-menu dropdown-menu--menu panel-menu" role={isSubMenu ? '' : 'menu'}>
|
||||
{menu.map(menuItem => {
|
||||
console.log(this);
|
||||
return (
|
||||
<Fragment>
|
||||
<PanelHeaderMenuItem
|
||||
type={menuItem.type}
|
||||
text={menuItem.text}
|
||||
iconClassName={menuItem.iconClassName}
|
||||
handleClick={menuItem.handleClick}
|
||||
shortcut={menuItem.shortcut}
|
||||
>
|
||||
{menuItem.subMenu && this.renderItems(menuItem.subMenu, true)}
|
||||
</PanelHeaderMenuItem>
|
||||
</Fragment>
|
||||
);
|
||||
})}
|
||||
</ul>
|
||||
);
|
||||
};
|
||||
|
||||
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 (
|
||||
<div className="panel-menu-container dropdown">
|
||||
<ul className="dropdown-menu dropdown-menu--menu panel-menu" role="menu">
|
||||
<PanelHeaderMenuItem
|
||||
type={PanelHeaderMenuItemTypes.Link}
|
||||
text="View"
|
||||
iconClassName="fa fa-fw fa-eye"
|
||||
handleClick={this.onViewPanel}
|
||||
shortcut="v"
|
||||
/>
|
||||
<PanelHeaderMenuItem
|
||||
type={PanelHeaderMenuItemTypes.Link}
|
||||
text="Edit"
|
||||
iconClassName="fa fa-fw fa-edit"
|
||||
handleClick={this.onEditPanel}
|
||||
shortcut="e"
|
||||
/>
|
||||
<PanelHeaderMenuItem
|
||||
type={PanelHeaderMenuItemTypes.Link}
|
||||
text="Share"
|
||||
iconClassName="fa fa-fw fa-share"
|
||||
handleClick={this.onSharePanel}
|
||||
shortcut="p s"
|
||||
/>
|
||||
<PanelHeaderMenuItem
|
||||
type={PanelHeaderMenuItemTypes.SubMenu}
|
||||
text="More ..."
|
||||
iconClassName="fa fa-fw fa-cube"
|
||||
handleClick={null}
|
||||
>
|
||||
<ul className="dropdown-menu dropdown-menu--menu panel-menu">
|
||||
<PanelHeaderMenuItem
|
||||
type={PanelHeaderMenuItemTypes.Link}
|
||||
text="Duplicate"
|
||||
iconClassName=""
|
||||
handleClick={this.onDuplicatePanel}
|
||||
shortcut="p d"
|
||||
/>
|
||||
<PanelHeaderMenuItem type={PanelHeaderMenuItemTypes.Link} text="Copy" handleClick={this.onCopyPanel} />
|
||||
<PanelHeaderMenuItem
|
||||
type={PanelHeaderMenuItemTypes.Link}
|
||||
text="Panel JSON"
|
||||
handleClick={this.onEditPanelJson}
|
||||
/>
|
||||
<PanelHeaderMenuItem type={PanelHeaderMenuItemTypes.Link} text="Export CSV" handleClick={() => {}} />
|
||||
<PanelHeaderMenuItem
|
||||
type={PanelHeaderMenuItemTypes.Link}
|
||||
text="Toggle legend"
|
||||
handleClick={this.onToggleLegend}
|
||||
shortcut="p l"
|
||||
/>
|
||||
</ul>
|
||||
</PanelHeaderMenuItem>
|
||||
<PanelHeaderMenuItem type={PanelHeaderMenuItemTypes.Divider} />
|
||||
<PanelHeaderMenuItem
|
||||
type={PanelHeaderMenuItemTypes.Link}
|
||||
text="Remove"
|
||||
iconClassName="fa fa-fw fa-trash"
|
||||
handleClick={this.onRemovePanel}
|
||||
shortcut="p r"
|
||||
/>
|
||||
</ul>
|
||||
</div>
|
||||
);
|
||||
const { dashboard } = this.props;
|
||||
const menu = getPanelMenu(dashboard, this.getPanel());
|
||||
return <div className="panel-menu-container dropdown">{this.renderItems(menu)}</div>;
|
||||
}
|
||||
}
|
||||
|
@ -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<PanelHeaderMenuItemProps> = props => {
|
||||
|
140
public/app/features/dashboard/utils/panel_menu.ts
Normal file
140
public/app/features/dashboard/utils/panel_menu.ts
Normal file
@ -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;
|
||||
};
|
Loading…
Reference in New Issue
Block a user