mirror of
https://github.com/grafana/grafana.git
synced 2025-02-09 23:16:16 -06:00
wip: Initial commit for PanelHeaderMenu
This commit is contained in:
parent
b28b79100a
commit
9f6683de2c
@ -38,7 +38,6 @@ export class DataPanel extends Component<Props, State> {
|
||||
|
||||
constructor(props: Props) {
|
||||
super(props);
|
||||
|
||||
this.state = {
|
||||
loading: LoadingState.NotStarted,
|
||||
response: {
|
||||
|
@ -5,7 +5,7 @@ import React, { ComponentClass, PureComponent } from 'react';
|
||||
import { getTimeSrv } from '../time_srv';
|
||||
|
||||
// Components
|
||||
import { PanelHeader } from './PanelHeader';
|
||||
import { PanelHeader } from './PanelHeader/PanelHeader';
|
||||
import { DataPanel } from './DataPanel';
|
||||
|
||||
// Types
|
||||
|
@ -1,83 +0,0 @@
|
||||
import React from 'react';
|
||||
import classNames from 'classnames';
|
||||
import { PanelModel } from '../panel_model';
|
||||
import { DashboardModel } from '../dashboard_model';
|
||||
import { store } from 'app/store/configureStore';
|
||||
import { updateLocation } from 'app/core/actions';
|
||||
|
||||
interface PanelHeaderProps {
|
||||
panel: PanelModel;
|
||||
dashboard: DashboardModel;
|
||||
}
|
||||
|
||||
export class PanelHeader extends React.Component<PanelHeaderProps, any> {
|
||||
onEditPanel = () => {
|
||||
store.dispatch(
|
||||
updateLocation({
|
||||
query: {
|
||||
panelId: this.props.panel.id,
|
||||
edit: true,
|
||||
fullscreen: true,
|
||||
},
|
||||
})
|
||||
);
|
||||
};
|
||||
|
||||
onViewPanel = () => {
|
||||
store.dispatch(
|
||||
updateLocation({
|
||||
query: {
|
||||
panelId: this.props.panel.id,
|
||||
edit: false,
|
||||
fullscreen: true,
|
||||
},
|
||||
})
|
||||
);
|
||||
};
|
||||
|
||||
render() {
|
||||
const isFullscreen = false;
|
||||
const isLoading = false;
|
||||
const panelHeaderClass = classNames({ 'panel-header': true, 'grid-drag-handle': !isFullscreen });
|
||||
|
||||
return (
|
||||
<div className={panelHeaderClass}>
|
||||
<span className="panel-info-corner">
|
||||
<i className="fa" />
|
||||
<span className="panel-info-corner-inner" />
|
||||
</span>
|
||||
|
||||
{isLoading && (
|
||||
<span className="panel-loading">
|
||||
<i className="fa fa-spinner fa-spin" />
|
||||
</span>
|
||||
)}
|
||||
|
||||
<div className="panel-title-container">
|
||||
<span className="panel-title">
|
||||
<span className="icon-gf panel-alert-icon" />
|
||||
<span className="panel-title-text">{this.props.panel.title}</span>
|
||||
<span className="panel-menu-container dropdown">
|
||||
<span className="fa fa-caret-down panel-menu-toggle" data-toggle="dropdown" />
|
||||
<ul className="dropdown-menu dropdown-menu--menu panel-menu" role="menu">
|
||||
<li>
|
||||
<a onClick={this.onEditPanel}>
|
||||
<i className="fa fa-fw fa-edit" /> Edit
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a onClick={this.onViewPanel}>
|
||||
<i className="fa fa-fw fa-eye" /> View
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</span>
|
||||
<span className="panel-time-info">
|
||||
<i className="fa fa-clock-o" /> 4m
|
||||
</span>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
@ -0,0 +1,50 @@
|
||||
import React from 'react';
|
||||
import classNames from 'classnames';
|
||||
import { PanelModel } from 'app/features/dashboard/panel_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 appEvents from 'app/core/app_events';
|
||||
|
||||
interface PanelHeaderProps {
|
||||
panel: PanelModel;
|
||||
dashboard: DashboardModel;
|
||||
}
|
||||
|
||||
export class PanelHeader extends React.Component<PanelHeaderProps, any> {
|
||||
render() {
|
||||
const isFullscreen = false;
|
||||
const isLoading = false;
|
||||
const panelHeaderClass = classNames({ 'panel-header': true, 'grid-drag-handle': !isFullscreen });
|
||||
|
||||
return (
|
||||
<div className={panelHeaderClass}>
|
||||
<span className="panel-info-corner">
|
||||
<i className="fa" />
|
||||
<span className="panel-info-corner-inner" />
|
||||
</span>
|
||||
|
||||
{isLoading && (
|
||||
<span className="panel-loading">
|
||||
<i className="fa fa-spinner fa-spin" />
|
||||
</span>
|
||||
)}
|
||||
|
||||
<div className="panel-title-container">
|
||||
<div className="panel-title">
|
||||
<span className="icon-gf panel-alert-icon" />
|
||||
<span className="panel-title-text" data-toggle="dropdown">
|
||||
{this.props.panel.title} <span className="fa fa-caret-down panel-menu-toggle" />
|
||||
</span>
|
||||
|
||||
<PanelHeaderMenu panelId={this.props.panel.id} />
|
||||
<span className="panel-time-info">
|
||||
<i className="fa fa-clock-o" /> 4m
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
@ -0,0 +1,109 @@
|
||||
import React, { PureComponent } from 'react';
|
||||
// import { store } from 'app/store/configureStore';
|
||||
import { PanelHeaderMenuItem, PanelHeaderMenuItemTypes } from './PanelHeaderMenuItem';
|
||||
import appEvents from 'app/core/app_events';
|
||||
import { store } from 'app/store/configureStore';
|
||||
import { updateLocation } from 'app/core/actions';
|
||||
|
||||
export interface PanelHeaderMenuProps {
|
||||
panelId: number;
|
||||
}
|
||||
|
||||
export class PanelHeaderMenu extends PureComponent<PanelHeaderMenuProps, any> {
|
||||
onEditPanel = () => {
|
||||
store.dispatch(
|
||||
updateLocation({
|
||||
query: {
|
||||
panelId: this.props.panelId,
|
||||
edit: true,
|
||||
fullscreen: true,
|
||||
},
|
||||
})
|
||||
);
|
||||
};
|
||||
|
||||
onViewPanel = () => {
|
||||
store.dispatch(
|
||||
updateLocation({
|
||||
query: {
|
||||
panelId: this.props.panelId,
|
||||
edit: false,
|
||||
fullscreen: true,
|
||||
},
|
||||
})
|
||||
);
|
||||
};
|
||||
|
||||
onRemovePanel = () => {
|
||||
appEvents.emit('panel-remove', {
|
||||
panelId: this.props.panelId,
|
||||
});
|
||||
};
|
||||
|
||||
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={() => {}}
|
||||
shortcut="p s"
|
||||
/>
|
||||
<PanelHeaderMenuItem
|
||||
type={PanelHeaderMenuItemTypes.SubMenu}
|
||||
text="More ..."
|
||||
iconClassName="fa fa-fw fa-cube"
|
||||
handleClick={() => {}}
|
||||
>
|
||||
<ul className="dropdown-menu dropdown-menu--menu panel-menu">
|
||||
<PanelHeaderMenuItem
|
||||
type={PanelHeaderMenuItemTypes.Link}
|
||||
text="Duplicate"
|
||||
iconClassName=""
|
||||
handleClick={() => {}}
|
||||
shortcut="p d"
|
||||
/>
|
||||
|
||||
<PanelHeaderMenuItem type={PanelHeaderMenuItemTypes.Link} text="Copy" handleClick={() => {}} />
|
||||
|
||||
<PanelHeaderMenuItem type={PanelHeaderMenuItemTypes.Link} text="Panel JSON" handleClick={() => {}} />
|
||||
|
||||
<PanelHeaderMenuItem type={PanelHeaderMenuItemTypes.Link} text="Export CSV" handleClick={() => {}} />
|
||||
|
||||
<PanelHeaderMenuItem
|
||||
type={PanelHeaderMenuItemTypes.Link}
|
||||
text="Toggle legend"
|
||||
handleClick={() => {}}
|
||||
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>
|
||||
);
|
||||
}
|
||||
}
|
@ -0,0 +1,34 @@
|
||||
import React, { SFC } from 'react';
|
||||
|
||||
export enum PanelHeaderMenuItemTypes {
|
||||
Button = 'Button', // ?
|
||||
Divider = 'Divider',
|
||||
Link = 'Link',
|
||||
SubMenu = 'SubMenu',
|
||||
}
|
||||
|
||||
export interface PanelHeaderMenuItemProps {
|
||||
type: PanelHeaderMenuItemTypes;
|
||||
text?: string;
|
||||
iconClassName?: string;
|
||||
handleClick?: () => void;
|
||||
shortcut?: string;
|
||||
children?: any;
|
||||
}
|
||||
|
||||
export const PanelHeaderMenuItem: SFC<PanelHeaderMenuItemProps> = props => {
|
||||
const isSubMenu = props.type === PanelHeaderMenuItemTypes.SubMenu;
|
||||
const isDivider = props.type === PanelHeaderMenuItemTypes.Divider;
|
||||
return isDivider ? (
|
||||
<li className="divider" />
|
||||
) : (
|
||||
<li className={isSubMenu ? 'dropdown-submenu' : null}>
|
||||
<a onClick={props.handleClick}>
|
||||
{props.iconClassName && <i className={props.iconClassName} />}
|
||||
<span className="dropdown-item-text">{props.text}</span>
|
||||
{props.shortcut && <span className="dropdown-menu-item-shortcut">{props.shortcut}</span>}
|
||||
</a>
|
||||
{props.children}
|
||||
</li>
|
||||
);
|
||||
};
|
@ -183,6 +183,11 @@
|
||||
display: block;
|
||||
}
|
||||
|
||||
& > .dropdown > .dropdown-menu {
|
||||
// Panel menu. TODO: See if we can merge this with above
|
||||
display: block;
|
||||
}
|
||||
|
||||
&.cascade-open {
|
||||
.dropdown-menu {
|
||||
display: block;
|
||||
|
@ -138,7 +138,6 @@ div.flot-text {
|
||||
padding: 3px 5px;
|
||||
visibility: hidden;
|
||||
opacity: 0;
|
||||
position: absolute;
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
left: 1px;
|
||||
|
Loading…
Reference in New Issue
Block a user