From ca4612af261aec49970ad45ca57a2e46e482cb62 Mon Sep 17 00:00:00 2001 From: Johannes Schill Date: Thu, 1 Nov 2018 12:01:27 +0100 Subject: [PATCH] wip: panel-header: Merge conflicts --- .../dashboard/dashgrid/DashboardPanel.tsx | 3 +- .../dashboard/dashgrid/PanelChrome.tsx | 12 +-- .../dashgrid/PanelHeader/PanelHeader.tsx | 14 ++- .../dashgrid/PanelHeader/PanelHeaderMenu.tsx | 12 ++- .../features/dashboard/utils/panel_menu.ts | 10 +- public/app/plugins/panel/graph2/module.tsx | 1 + .../plugins/panel/graph2/withMenuOptions.tsx | 94 +++++++++++++++++++ public/app/types/plugins.ts | 1 + 8 files changed, 122 insertions(+), 25 deletions(-) create mode 100644 public/app/plugins/panel/graph2/withMenuOptions.tsx diff --git a/public/app/features/dashboard/dashgrid/DashboardPanel.tsx b/public/app/features/dashboard/dashgrid/DashboardPanel.tsx index fcfc84e287b..cf41595ce8c 100644 --- a/public/app/features/dashboard/dashgrid/DashboardPanel.tsx +++ b/public/app/features/dashboard/dashgrid/DashboardPanel.tsx @@ -1,4 +1,4 @@ -import React, { PureComponent } from 'react'; +import React, { PureComponent } from 'react'; import config from 'app/core/config'; import { PanelModel } from '../panel_model'; import { DashboardModel } from '../dashboard_model'; @@ -123,6 +123,7 @@ export class DashboardPanel extends PureComponent {
diff --git a/public/app/features/dashboard/dashgrid/PanelChrome.tsx b/public/app/features/dashboard/dashgrid/PanelChrome.tsx index d4bfce67c48..1a6f5a3cee2 100644 --- a/public/app/features/dashboard/dashgrid/PanelChrome.tsx +++ b/public/app/features/dashboard/dashgrid/PanelChrome.tsx @@ -13,19 +13,20 @@ import { PanelModel } from '../panel_model'; import { DashboardModel } from '../dashboard_model'; import { TimeRange, PanelProps } from 'app/types'; -export interface Props { +export interface PanelChromeProps { panel: PanelModel; dashboard: DashboardModel; component: ComponentClass; + withMenuOptions: any; } -export interface State { +export interface PanelChromeState { refreshCounter: number; renderCounter: number; timeRange?: TimeRange; } -export class PanelChrome extends PureComponent { +export class PanelChrome extends PureComponent { constructor(props) { super(props); @@ -67,16 +68,15 @@ export class PanelChrome extends PureComponent { } render() { - const { panel, dashboard } = this.props; + const { panel, dashboard, withMenuOptions } = this.props; const { datasource, targets } = panel; const { timeRange, renderCounter, refreshCounter } = this.state; const PanelComponent = this.props.component; - console.log('Panel chrome render'); return (
- +
{ +export class PanelHeader extends PureComponent { render() { - const { dashboard } = this.props; + const { dashboard, withMenuOptions, panel } = this.props; const isFullscreen = false; const isLoading = false; const panelHeaderClass = classNames({ 'panel-header': true, 'grid-drag-handle': !isFullscreen }); + const PanelHeaderMenuComponent = withMenuOptions ? withMenuOptions(PanelHeaderMenu, panel) : PanelHeaderMenu; return (
@@ -39,7 +37,7 @@ export class PanelHeader extends React.Component { {this.props.panel.title} - + 4m diff --git a/public/app/features/dashboard/dashgrid/PanelHeader/PanelHeaderMenu.tsx b/public/app/features/dashboard/dashgrid/PanelHeader/PanelHeaderMenu.tsx index b454ccad4a6..c36eb9d8584 100644 --- a/public/app/features/dashboard/dashgrid/PanelHeader/PanelHeaderMenu.tsx +++ b/public/app/features/dashboard/dashgrid/PanelHeader/PanelHeaderMenu.tsx @@ -6,6 +6,9 @@ import { getPanelMenu } from 'app/features/dashboard/utils/panel_menu'; export interface PanelHeaderMenuProps { panelId: number; dashboard: DashboardModel; + datasource: any; + additionalMenuItems?: PanelHeaderMenuItemProps[]; + additionalSubMenuItems?: PanelHeaderMenuItemProps[]; } export class PanelHeaderMenu extends PureComponent { @@ -19,10 +22,10 @@ export class PanelHeaderMenu extends PureComponent { renderItems = (menu: PanelHeaderMenuItemProps[], isSubMenu = false) => { return (
    - {menu.map(menuItem => { - console.log(this); + {menu.map((menuItem, idx) => { return ( { }; render() { - const { dashboard } = this.props; - const menu = getPanelMenu(dashboard, this.getPanel()); + console.log('PanelHeaderMenu render'); + const { dashboard, additionalMenuItems, additionalSubMenuItems } = this.props; + const menu = getPanelMenu(dashboard, this.getPanel(), additionalMenuItems, additionalSubMenuItems); return
    {this.renderItems(menu)}
    ; } } diff --git a/public/app/features/dashboard/utils/panel_menu.ts b/public/app/features/dashboard/utils/panel_menu.ts index c86595953b5..67adf118edd 100644 --- a/public/app/features/dashboard/utils/panel_menu.ts +++ b/public/app/features/dashboard/utils/panel_menu.ts @@ -8,8 +8,8 @@ import { removePanel, duplicatePanel, copyPanel, editPanelJson, sharePanel } fro export const getPanelMenu = ( dashboard: DashboardModel, panel: PanelModel, - extraMenuItems: PanelHeaderMenuItemProps[] = [], - extraSubMenuItems: PanelHeaderMenuItemProps[] = [] + additionalMenuItems: PanelHeaderMenuItemProps[] = [], + additionalSubMenuItems: PanelHeaderMenuItemProps[] = [] ) => { const onViewPanel = () => { store.dispatch( @@ -80,9 +80,7 @@ export const getPanelMenu = ( handleClick: onEditPanelJson, }); - // TODO: Handle this somehow - // this.events.emit('init-panel-actions', menu); - extraSubMenuItems.forEach(item => { + additionalSubMenuItems.forEach(item => { menu.push(item); }); return menu; @@ -117,7 +115,7 @@ export const getPanelMenu = ( shortcut: 'p s', }); - extraMenuItems.forEach(item => { + additionalMenuItems.forEach(item => { menu.push(item); }); diff --git a/public/app/plugins/panel/graph2/module.tsx b/public/app/plugins/panel/graph2/module.tsx index b132d3374f1..88b679e1645 100644 --- a/public/app/plugins/panel/graph2/module.tsx +++ b/public/app/plugins/panel/graph2/module.tsx @@ -73,3 +73,4 @@ export class GraphOptions extends PureComponent> { } export { Graph2 as PanelComponent, GraphOptions as PanelOptionsComponent }; +export { withMenuOptions } from './withMenuOptions'; diff --git a/public/app/plugins/panel/graph2/withMenuOptions.tsx b/public/app/plugins/panel/graph2/withMenuOptions.tsx new file mode 100644 index 00000000000..aaa89bf3406 --- /dev/null +++ b/public/app/plugins/panel/graph2/withMenuOptions.tsx @@ -0,0 +1,94 @@ +// Libraries +import React, { PureComponent } from 'react'; + +// Services +import { getTimeSrv } from 'app/features/dashboard/time_srv'; +import { contextSrv } from 'app/core/services/context_srv'; +import { getDatasourceSrv } from 'app/features/plugins/datasource_srv'; +import { store } from 'app/store/configureStore'; + +// Components +import { PanelHeaderMenu } from 'app/features/dashboard/dashgrid/PanelHeader/PanelHeaderMenu'; +import config from 'app/core/config'; +import { getExploreUrl } from 'app/core/utils/explore'; +import { updateLocation } from 'app/core/actions'; + +// Types +import { PanelModel } from 'app/features/dashboard/panel_model'; +import { PanelHeaderMenuProps } from 'app/features/dashboard/dashgrid/PanelHeader/PanelHeaderMenu'; +import { + PanelHeaderMenuItemProps, + PanelHeaderMenuItemTypes, +} from 'app/features/dashboard/dashgrid/PanelHeader/PanelHeaderMenuItem'; + +interface LocalState { + datasource: any; +} + +export const withMenuOptions = (WrappedPanelHeaderMenu: typeof PanelHeaderMenu, panel: PanelModel) => { + return class extends PureComponent { + private datasourceSrv = getDatasourceSrv(); + private timeSrv = getTimeSrv(); + + constructor(props) { + super(props); + this.state = { + datasource: undefined, + }; + } + + componentDidMount() { + const dsPromise = getDatasourceSrv().get(panel.datasource); + dsPromise.then((datasource: any) => { + this.setState(() => ({ datasource })); + }); + } + + onExploreClick = async () => { + const { datasource } = this.state; + const url = await getExploreUrl(panel, panel.targets, datasource, this.datasourceSrv, this.timeSrv); + if (url) { + store.dispatch(updateLocation({ path: url })); + } + }; + + getAdditionalMenuItems = () => { + const { datasource } = this.state; + const items = []; + if ( + config.exploreEnabled && + contextSrv.isEditor && + datasource && + (datasource.meta.explore || datasource.meta.id === 'mixed') + ) { + items.push({ + type: PanelHeaderMenuItemTypes.Link, + text: 'Explore', + handleClick: this.onExploreClick, + iconClassName: 'fa fa-fw fa-rocket', + shortcut: 'x', + }); + } + return items; + }; + + getAdditionalSubMenuItems = () => { + return [ + { + type: PanelHeaderMenuItemTypes.Link, + text: 'Hello Sub Menu', + handleClick: () => { + alert('Hello world from HOC!'); + }, + shortcut: 's h w', + }, + ] as PanelHeaderMenuItemProps[]; + }; + + render() { + const menu: PanelHeaderMenuItemProps[] = this.getAdditionalMenuItems(); + const subMenu: PanelHeaderMenuItemProps[] = this.getAdditionalSubMenuItems(); + return ; + } + }; +}; diff --git a/public/app/types/plugins.ts b/public/app/types/plugins.ts index 817777669d8..9ede3dd9f4b 100644 --- a/public/app/types/plugins.ts +++ b/public/app/types/plugins.ts @@ -13,6 +13,7 @@ export interface PluginExports { PanelCtrl?; PanelComponent?: ComponentClass; PanelOptionsComponent: ComponentClass; + withMenuOptions?: any; } export interface PanelPlugin {