Просмотр исходного кода

wip: Initial commit for PanelHeaderMenu

Johannes Schill 7 лет назад
Родитель
Сommit
9f6683de2c

+ 0 - 1
public/app/features/dashboard/dashgrid/DataPanel.tsx

@@ -38,7 +38,6 @@ export class DataPanel extends Component<Props, State> {
 
   constructor(props: Props) {
     super(props);
-
     this.state = {
       loading: LoadingState.NotStarted,
       response: {

+ 1 - 1
public/app/features/dashboard/dashgrid/PanelChrome.tsx

@@ -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

+ 0 - 83
public/app/features/dashboard/dashgrid/PanelHeader.tsx

@@ -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>
-    );
-  }
-}

+ 50 - 0
public/app/features/dashboard/dashgrid/PanelHeader/PanelHeader.tsx

@@ -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>
+    );
+  }
+}

+ 109 - 0
public/app/features/dashboard/dashgrid/PanelHeader/PanelHeaderMenu.tsx

@@ -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>
+    );
+  }
+}

+ 34 - 0
public/app/features/dashboard/dashgrid/PanelHeader/PanelHeaderMenuItem.tsx

@@ -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>
+  );
+};

+ 5 - 0
public/sass/components/_dropdown.scss

@@ -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;

+ 0 - 1
public/sass/pages/_dashboard.scss

@@ -138,7 +138,6 @@ div.flot-text {
   padding: 3px 5px;
   visibility: hidden;
   opacity: 0;
-  position: absolute;
   width: 16px;
   height: 16px;
   left: 1px;