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

Merge branch 'panel-edit-in-react' of https://github.com/grafana/grafana into panel-edit-in-react

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

+ 3 - 0
public/app/features/alerting/AlertTabCtrl.ts

@@ -1,4 +1,5 @@
 import _ from 'lodash';
+import coreModule from 'app/core/core_module';
 import { ThresholdMapper } from './state/ThresholdMapper';
 import { QueryPart } from 'app/core/components/query_part/query_part';
 import alertDef from './state/alertDef';
@@ -430,3 +431,5 @@ export function alertTab() {
     controller: AlertTabCtrl,
   };
 }
+
+coreModule.directive('alertTab', alertTab);

+ 72 - 0
public/app/features/dashboard/dashgrid/AlertTab.tsx

@@ -0,0 +1,72 @@
+import React, { PureComponent } from 'react';
+
+import { getAngularLoader, AngularComponent } from 'app/core/services/AngularLoader';
+import { EditorTabBody } from './EditorTabBody';
+import 'app/features/alerting/AlertTabCtrl';
+
+interface Props {
+  angularPanel?: AngularComponent;
+}
+
+export class AlertTab extends PureComponent<Props> {
+  element: any;
+  component: AngularComponent;
+
+  constructor(props) {
+    super(props);
+  }
+
+  componentDidMount() {
+    if (this.shouldLoadAlertTab()) {
+      this.loadAlertTab();
+    }
+  }
+
+  componentDidUpdate(prevProps: Props) {
+    if (this.shouldLoadAlertTab()) {
+      this.loadAlertTab();
+    }
+  }
+
+  shouldLoadAlertTab() {
+    return this.props.angularPanel && this.element;
+  }
+
+  componentWillUnmount() {
+    if (this.component) {
+      this.component.destroy();
+    }
+  }
+
+  loadAlertTab() {
+    const { angularPanel } = this.props;
+
+    const scope = angularPanel.getScope();
+
+    // When full page reloading in edit mode the angular panel has on fully compiled & instantiated yet
+    if (!scope.$$childHead) {
+      setTimeout(() => {
+        this.forceUpdate();
+      });
+      return;
+    }
+
+    const panelCtrl = scope.$$childHead.ctrl;
+    const loader = getAngularLoader();
+    const template = '<alert-tab />';
+
+    const scopeProps = {
+      ctrl: panelCtrl,
+    };
+
+    this.component = loader.load(this.element, scopeProps, template);
+  }
+
+  render() {
+    return (
+      <EditorTabBody toolbarItems={[]}>
+        <div ref={element => (this.element = element)} />
+      </EditorTabBody>
+    );
+  }
+}

+ 1 - 2
public/app/features/dashboard/dashgrid/DashboardGrid.tsx

@@ -176,10 +176,9 @@ export class DashboardGrid extends React.Component<DashboardGridProps, any> {
 
   renderPanels() {
     const panelElements = [];
-    console.log('render panels');
 
     for (const panel of this.props.dashboard.panels) {
-      const panelClasses = classNames({ panel: true, 'panel--fullscreen': panel.fullscreen });
+      const panelClasses = classNames({ 'react-grid-item--fullscreen': panel.fullscreen });
       panelElements.push(
         <div key={panel.id.toString()} className={panelClasses} id={`panel-${panel.id}`}>
           <DashboardPanel

+ 8 - 3
public/app/features/dashboard/dashgrid/DashboardPanel.tsx

@@ -1,5 +1,6 @@
 import React, { PureComponent } from 'react';
 import config from 'app/core/config';
+import classNames from 'classnames';
 
 import { getAngularLoader, AngularComponent } from 'app/core/services/AngularLoader';
 import { importPluginModule } from 'app/features/plugins/plugin_loader';
@@ -136,7 +137,7 @@ export class DashboardPanel extends PureComponent<Props, State> {
   }
 
   render() {
-    const { panel, dashboard } = this.props;
+    const { panel, dashboard, isFullscreen, isEditing } = this.props;
     const { plugin, angularPanel } = this.state;
 
     if (this.isSpecial()) {
@@ -148,8 +149,12 @@ export class DashboardPanel extends PureComponent<Props, State> {
       return null;
     }
 
-    const containerClass = this.props.isEditing ? 'panel-editor-container' : 'panel-height-helper';
-    const panelWrapperClass = this.props.isEditing ? 'panel-editor-container__panel' : 'panel-height-helper';
+    const containerClass = classNames({ 'panel-editor-container': isEditing, 'panel-height-helper': !isEditing });
+    const panelWrapperClass = classNames({
+      'panel-wrapper': true,
+      'panel-wrapper--edit': isEditing,
+      'panel-wrapper--view': isFullscreen && !isEditing,
+    });
 
     return (
       <div className={containerClass}>

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

@@ -51,7 +51,7 @@ export class GeneralTab extends PureComponent<Props> {
 
     return (
       <EditorTabBody main={currentDataSource} toolbarItems={[]}>
-        <div ref={element => (this.element = element)} style={{ width: '100%' }} />
+        <div ref={element => (this.element = element)} />
       </EditorTabBody>
     );
   }

+ 44 - 36
public/app/features/dashboard/dashgrid/PanelEditor.tsx

@@ -4,7 +4,9 @@ import classNames from 'classnames';
 import { QueriesTab } from './QueriesTab';
 import { VisualizationTab } from './VisualizationTab';
 import { GeneralTab } from './GeneralTab';
+import { AlertTab } from './AlertTab';
 
+import config from 'app/core/config';
 import { store } from 'app/store/store';
 import { updateLocation } from 'app/core/actions';
 import { AngularComponent } from 'app/core/services/AngularLoader';
@@ -28,16 +30,8 @@ interface PanelEditorTab {
 }
 
 export class PanelEditor extends PureComponent<PanelEditorProps> {
-  tabs: PanelEditorTab[];
-
   constructor(props) {
     super(props);
-
-    this.tabs = [
-      { id: 'general', text: 'General', icon: 'gicon gicon-preferences' },
-      { id: 'queries', text: 'Queries', icon: 'fa fa-database' },
-      { id: 'visualization', text: 'Visualization', icon: 'fa fa-line-chart' },
-    ];
   }
 
   onChangeTab = (tab: PanelEditorTab) => {
@@ -50,19 +44,48 @@ export class PanelEditor extends PureComponent<PanelEditorProps> {
     this.forceUpdate();
   };
 
-  onClose = () => {
-    store.dispatch(
-      updateLocation({
-        query: { tab: null, fullscreen: null, edit: null },
-        partial: true,
-      })
-    );
-  };
+  renderCurrentTab(activeTab: string) {
+    const { panel, dashboard, onTypeChanged, plugin, angularPanel } = this.props;
+
+    switch (activeTab) {
+      case 'general':
+        return <GeneralTab panel={panel} />;
+      case 'queries':
+        return <QueriesTab panel={panel} dashboard={dashboard} />;
+      case 'alert':
+        return <AlertTab angularPanel={angularPanel} />;
+      case 'visualization':
+        return (
+          <VisualizationTab
+            panel={panel}
+            dashboard={dashboard}
+            plugin={plugin}
+            onTypeChanged={onTypeChanged}
+            angularPanel={angularPanel}
+          />
+        );
+      default:
+        return null;
+    }
+  }
 
   render() {
-    const { panel, dashboard, onTypeChanged, plugin, angularPanel } = this.props;
-    const { location } = store.getState();
-    const activeTab = location.query.tab || 'queries';
+    const { plugin } = this.props;
+    const activeTab = store.getState().location.query.tab || 'queries';
+
+    const tabs = [
+      { id: 'general', text: 'General', icon: 'gicon gicon-preferences' },
+      { id: 'queries', text: 'Queries', icon: 'fa fa-database' },
+      { id: 'visualization', text: 'Visualization', icon: 'fa fa-line-chart' },
+    ];
+
+    if (config.alertingEnabled && plugin.id === 'graph') {
+      tabs.push({
+        id: 'alert',
+        text: 'Alert',
+        icon: 'gicon gicon-alert',
+      });
+    }
 
     return (
       <div className="panel-editor-container__editor">
@@ -74,27 +97,12 @@ export class PanelEditor extends PureComponent<PanelEditorProps> {
 
         <div className="panel-editor-tabs">
           <ul className="gf-tabs">
-            {this.tabs.map(tab => {
+            {tabs.map(tab => {
               return <TabItem tab={tab} activeTab={activeTab} onClick={this.onChangeTab} key={tab.id} />;
             })}
           </ul>
-
-          <button className="panel-editor-tabs__close" onClick={this.onClose}>
-            <i className="fa fa-reply" />
-          </button>
         </div>
-
-        {activeTab === 'general' && <GeneralTab panel={panel} />}
-        {activeTab === 'queries' && <QueriesTab panel={panel} dashboard={dashboard} />}
-        {activeTab === 'visualization' && (
-          <VisualizationTab
-            panel={panel}
-            dashboard={dashboard}
-            plugin={plugin}
-            onTypeChanged={onTypeChanged}
-            angularPanel={angularPanel}
-          />
-        )}
+        {this.renderCurrentTab(activeTab)}
       </div>
     );
   }

+ 0 - 5
public/app/plugins/panel/graph/module.ts

@@ -138,11 +138,6 @@ class GraphCtrl extends MetricsPanelCtrl {
     this.addEditorTab('Display options', 'public/app/plugins/panel/graph/tab_display.html');
     this.addEditorTab('Axes', axesEditorComponent);
     this.addEditorTab('Legend', 'public/app/plugins/panel/graph/tab_legend.html');
-
-    // if (config.alertingEnabled) {
-    //   this.addEditorTab('Alert', alertTab, 5);
-    // }
-
     this.subTabIndex = 0;
   }
 

+ 9 - 13
public/sass/components/_dashboard_grid.scss

@@ -9,18 +9,14 @@
   .react-grid-item {
     display: none !important;
     transition-property: none !important;
-  }
 
-  .panel--fullscreen {
-    display: block !important;
-    position: unset !important;
-    width: 100% !important;
-    height: 100% !important;
-    transform: translate(0px, 0px) !important;
-  }
-
-  .panel {
-    margin: 0 !important;
+    &--fullscreen {
+      display: block !important;
+      position: unset !important;
+      width: 100% !important;
+      height: 100% !important;
+      transform: translate(0px, 0px) !important;
+    }
   }
 
   // Disable grid interaction indicators in fullscreen panels
@@ -83,10 +79,10 @@
 }
 
 // Disable animation on initial rendering and enable it when component has been mounted.
-.react-grid-item.cssTransforms.panel {
+.react-grid-item.cssTransforms {
   transition-property: none;
 }
 
-.animated .react-grid-item.cssTransforms.panel {
+.animated .react-grid-item.cssTransforms {
   transition-property: transform;
 }

+ 4 - 0
public/sass/components/_navbar.scss

@@ -50,6 +50,10 @@
   .navbar-page-btn .fa-caret-down {
     display: none;
   }
+
+  .navbar-buttons--close {
+    display: flex;
+  }
 }
 
 .navbar-page-btn {

+ 15 - 2
public/sass/components/_panel_editor.scss

@@ -4,8 +4,21 @@
   height: 100%;
 }
 
-.panel-editor-container__panel {
-  flex: 1 1 0;
+.panel-wrapper {
+  height: 100%;
+
+  &--edit {
+    flex: 1 1 0;
+    height: unset;
+    margin: 0 $dashboard-padding;
+  }
+
+  &--view {
+    flex: 1 1 0;
+    height: 80%;
+    margin: 0 $dashboard-padding;
+    padding-top: $dashboard-padding;
+  }
 }
 
 .panel-editor-container__editor {