Commit ca4612af by Johannes Schill

wip: panel-header: Merge conflicts

parent f4714825
import React, { PureComponent } from 'react'; import React, { PureComponent } from 'react';
import config from 'app/core/config'; import config from 'app/core/config';
import { PanelModel } from '../panel_model'; import { PanelModel } from '../panel_model';
import { DashboardModel } from '../dashboard_model'; import { DashboardModel } from '../dashboard_model';
...@@ -123,6 +123,7 @@ export class DashboardPanel extends PureComponent<Props, State> { ...@@ -123,6 +123,7 @@ export class DashboardPanel extends PureComponent<Props, State> {
<div className={panelWrapperClass}> <div className={panelWrapperClass}>
<PanelChrome <PanelChrome
component={pluginExports.PanelComponent} component={pluginExports.PanelComponent}
withMenuOptions={pluginExports.withMenuOptions}
panel={this.props.panel} panel={this.props.panel}
dashboard={this.props.dashboard} dashboard={this.props.dashboard}
/> />
......
...@@ -13,19 +13,20 @@ import { PanelModel } from '../panel_model'; ...@@ -13,19 +13,20 @@ import { PanelModel } from '../panel_model';
import { DashboardModel } from '../dashboard_model'; import { DashboardModel } from '../dashboard_model';
import { TimeRange, PanelProps } from 'app/types'; import { TimeRange, PanelProps } from 'app/types';
export interface Props { export interface PanelChromeProps {
panel: PanelModel; panel: PanelModel;
dashboard: DashboardModel; dashboard: DashboardModel;
component: ComponentClass<PanelProps>; component: ComponentClass<PanelProps>;
withMenuOptions: any;
} }
export interface State { export interface PanelChromeState {
refreshCounter: number; refreshCounter: number;
renderCounter: number; renderCounter: number;
timeRange?: TimeRange; timeRange?: TimeRange;
} }
export class PanelChrome extends PureComponent<Props, State> { export class PanelChrome extends PureComponent<PanelChromeProps, PanelChromeState> {
constructor(props) { constructor(props) {
super(props); super(props);
...@@ -67,16 +68,15 @@ export class PanelChrome extends PureComponent<Props, State> { ...@@ -67,16 +68,15 @@ export class PanelChrome extends PureComponent<Props, State> {
} }
render() { render() {
const { panel, dashboard } = this.props; const { panel, dashboard, withMenuOptions } = this.props;
const { datasource, targets } = panel; const { datasource, targets } = panel;
const { timeRange, renderCounter, refreshCounter } = this.state; const { timeRange, renderCounter, refreshCounter } = this.state;
const PanelComponent = this.props.component; const PanelComponent = this.props.component;
console.log('Panel chrome render'); console.log('Panel chrome render');
return ( return (
<div className="panel-container"> <div className="panel-container">
<PanelHeader panel={panel} dashboard={dashboard} /> <PanelHeader panel={panel} dashboard={dashboard} withMenuOptions={withMenuOptions} />
<div className="panel-content"> <div className="panel-content">
<DataPanel <DataPanel
datasource={datasource} datasource={datasource}
......
import React from 'react'; import React, { PureComponent } from 'react';
import classNames from 'classnames'; import classNames from 'classnames';
import { PanelModel } from 'app/features/dashboard/panel_model'; import { PanelModel } from 'app/features/dashboard/panel_model';
import { DashboardModel } from 'app/features/dashboard/dashboard_model'; import { DashboardModel } from 'app/features/dashboard/dashboard_model';
// import { store } from 'app/store/configureStore';
// import { updateLocation } from 'app/core/actions';
import { PanelHeaderMenu } from './PanelHeaderMenu'; import { PanelHeaderMenu } from './PanelHeaderMenu';
// import appEvents from 'app/core/app_events';
interface PanelHeaderProps { interface PanelHeaderProps {
panel: PanelModel; panel: PanelModel;
dashboard: DashboardModel; dashboard: DashboardModel;
withMenuOptions: any;
} }
export class PanelHeader extends PureComponent<PanelHeaderProps, any> {
export class PanelHeader extends React.Component<PanelHeaderProps, any> {
render() { render() {
const { dashboard } = this.props; const { dashboard, withMenuOptions, panel } = this.props;
const isFullscreen = false; const isFullscreen = false;
const isLoading = false; const isLoading = false;
const panelHeaderClass = classNames({ 'panel-header': true, 'grid-drag-handle': !isFullscreen }); const panelHeaderClass = classNames({ 'panel-header': true, 'grid-drag-handle': !isFullscreen });
const PanelHeaderMenuComponent = withMenuOptions ? withMenuOptions(PanelHeaderMenu, panel) : PanelHeaderMenu;
return ( return (
<div className={panelHeaderClass}> <div className={panelHeaderClass}>
...@@ -39,7 +37,7 @@ export class PanelHeader extends React.Component<PanelHeaderProps, any> { ...@@ -39,7 +37,7 @@ export class PanelHeader extends React.Component<PanelHeaderProps, any> {
{this.props.panel.title} <span className="fa fa-caret-down panel-menu-toggle" /> {this.props.panel.title} <span className="fa fa-caret-down panel-menu-toggle" />
</span> </span>
<PanelHeaderMenu panelId={this.props.panel.id} dashboard={dashboard} /> <PanelHeaderMenuComponent panelId={panel.id} dashboard={dashboard} />
<span className="panel-time-info"> <span className="panel-time-info">
<i className="fa fa-clock-o" /> 4m <i className="fa fa-clock-o" /> 4m
</span> </span>
......
...@@ -6,6 +6,9 @@ import { getPanelMenu } from 'app/features/dashboard/utils/panel_menu'; ...@@ -6,6 +6,9 @@ import { getPanelMenu } from 'app/features/dashboard/utils/panel_menu';
export interface PanelHeaderMenuProps { export interface PanelHeaderMenuProps {
panelId: number; panelId: number;
dashboard: DashboardModel; dashboard: DashboardModel;
datasource: any;
additionalMenuItems?: PanelHeaderMenuItemProps[];
additionalSubMenuItems?: PanelHeaderMenuItemProps[];
} }
export class PanelHeaderMenu extends PureComponent<PanelHeaderMenuProps, any> { export class PanelHeaderMenu extends PureComponent<PanelHeaderMenuProps, any> {
...@@ -19,10 +22,10 @@ export class PanelHeaderMenu extends PureComponent<PanelHeaderMenuProps, any> { ...@@ -19,10 +22,10 @@ export class PanelHeaderMenu extends PureComponent<PanelHeaderMenuProps, any> {
renderItems = (menu: PanelHeaderMenuItemProps[], isSubMenu = false) => { renderItems = (menu: PanelHeaderMenuItemProps[], isSubMenu = false) => {
return ( return (
<ul className="dropdown-menu dropdown-menu--menu panel-menu" role={isSubMenu ? '' : 'menu'}> <ul className="dropdown-menu dropdown-menu--menu panel-menu" role={isSubMenu ? '' : 'menu'}>
{menu.map(menuItem => { {menu.map((menuItem, idx) => {
console.log(this);
return ( return (
<PanelHeaderMenuItem <PanelHeaderMenuItem
key={idx} // TODO: Fix proper key
type={menuItem.type} type={menuItem.type}
text={menuItem.text} text={menuItem.text}
iconClassName={menuItem.iconClassName} iconClassName={menuItem.iconClassName}
...@@ -38,8 +41,9 @@ export class PanelHeaderMenu extends PureComponent<PanelHeaderMenuProps, any> { ...@@ -38,8 +41,9 @@ export class PanelHeaderMenu extends PureComponent<PanelHeaderMenuProps, any> {
}; };
render() { render() {
const { dashboard } = this.props; console.log('PanelHeaderMenu render');
const menu = getPanelMenu(dashboard, this.getPanel()); const { dashboard, additionalMenuItems, additionalSubMenuItems } = this.props;
const menu = getPanelMenu(dashboard, this.getPanel(), additionalMenuItems, additionalSubMenuItems);
return <div className="panel-menu-container dropdown">{this.renderItems(menu)}</div>; return <div className="panel-menu-container dropdown">{this.renderItems(menu)}</div>;
} }
} }
...@@ -8,8 +8,8 @@ import { removePanel, duplicatePanel, copyPanel, editPanelJson, sharePanel } fro ...@@ -8,8 +8,8 @@ import { removePanel, duplicatePanel, copyPanel, editPanelJson, sharePanel } fro
export const getPanelMenu = ( export const getPanelMenu = (
dashboard: DashboardModel, dashboard: DashboardModel,
panel: PanelModel, panel: PanelModel,
extraMenuItems: PanelHeaderMenuItemProps[] = [], additionalMenuItems: PanelHeaderMenuItemProps[] = [],
extraSubMenuItems: PanelHeaderMenuItemProps[] = [] additionalSubMenuItems: PanelHeaderMenuItemProps[] = []
) => { ) => {
const onViewPanel = () => { const onViewPanel = () => {
store.dispatch( store.dispatch(
...@@ -80,9 +80,7 @@ export const getPanelMenu = ( ...@@ -80,9 +80,7 @@ export const getPanelMenu = (
handleClick: onEditPanelJson, handleClick: onEditPanelJson,
}); });
// TODO: Handle this somehow additionalSubMenuItems.forEach(item => {
// this.events.emit('init-panel-actions', menu);
extraSubMenuItems.forEach(item => {
menu.push(item); menu.push(item);
}); });
return menu; return menu;
...@@ -117,7 +115,7 @@ export const getPanelMenu = ( ...@@ -117,7 +115,7 @@ export const getPanelMenu = (
shortcut: 'p s', shortcut: 'p s',
}); });
extraMenuItems.forEach(item => { additionalMenuItems.forEach(item => {
menu.push(item); menu.push(item);
}); });
......
...@@ -73,3 +73,4 @@ export class GraphOptions extends PureComponent<PanelOptionsProps<Options>> { ...@@ -73,3 +73,4 @@ export class GraphOptions extends PureComponent<PanelOptionsProps<Options>> {
} }
export { Graph2 as PanelComponent, GraphOptions as PanelOptionsComponent }; export { Graph2 as PanelComponent, GraphOptions as PanelOptionsComponent };
export { withMenuOptions } from './withMenuOptions';
// 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<PanelHeaderMenuProps, LocalState> {
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 <WrappedPanelHeaderMenu {...this.props} additionalMenuItems={menu} additionalSubMenuItems={subMenu} />;
}
};
};
...@@ -13,6 +13,7 @@ export interface PluginExports { ...@@ -13,6 +13,7 @@ export interface PluginExports {
PanelCtrl?; PanelCtrl?;
PanelComponent?: ComponentClass<PanelProps>; PanelComponent?: ComponentClass<PanelProps>;
PanelOptionsComponent: ComponentClass<PanelOptionsProps>; PanelOptionsComponent: ComponentClass<PanelOptionsProps>;
withMenuOptions?: any;
} }
export interface PanelPlugin { export interface PanelPlugin {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment