Torkel Ödegaard 7 лет назад
Родитель
Сommit
aa5c9f199a

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

@@ -175,11 +175,10 @@ export class DashboardGrid extends React.Component<DashboardGridProps, any> {
     const panelElements = [];
 
     for (let panel of this.dashboard.panels) {
-      console.log('panel.fullscreen', panel.fullscreen);
       const panelClasses = classNames({ panel: true, 'panel--fullscreen': panel.fullscreen });
       panelElements.push(
         <div key={panel.id.toString()} className={panelClasses}>
-          <DashboardPanel panel={panel} dashboard={this.dashboard} />
+          <DashboardPanel panel={panel} dashboard={this.dashboard} panelContainer={this.panelContainer} />
         </div>
       );
     }

+ 32 - 132
public/app/features/dashboard/dashgrid/DashboardPanel.tsx

@@ -1,22 +1,18 @@
 import React from 'react';
-import $ from 'jquery';
 import config from 'app/core/config';
-import classNames from 'classnames';
 import { PanelModel } from '../panel_model';
 import { DashboardModel } from '../dashboard_model';
 import { AttachedPanel } from './PanelLoader';
 import { DashboardRow } from './DashboardRow';
+import { PanelContainer } from './PanelContainer';
 import { AddPanelPanel } from './AddPanelPanel';
 import { importPluginModule } from 'app/features/plugins/plugin_loader';
-import { store } from 'app/stores/store';
-import { GRID_CELL_HEIGHT, GRID_CELL_VMARGIN } from 'app/core/constants';
-
-const TITLE_HEIGHT = 27;
-const PANEL_BORDER = 2;
+import { PanelChrome } from './PanelChrome';
 
 export interface DashboardPanelProps {
   panel: PanelModel;
   dashboard: DashboardModel;
+  panelContainer: PanelContainer;
 }
 
 export class DashboardPanel extends React.Component<DashboardPanelProps, any> {
@@ -56,140 +52,44 @@ export class DashboardPanel extends React.Component<DashboardPanelProps, any> {
     return <AddPanelPanel panel={this.props.panel} dashboard={this.props.dashboard} />;
   }
 
-  render() {
-    if (this.isSpecial()) {
-      return this.specialPanels[this.props.panel.type]();
-    }
-
-    let PanelComponent = null;
-
-    if (this.pluginExports && this.pluginExports.PanelComponent) {
-      PanelComponent = this.pluginExports.PanelComponent;
+  componentDidUpdate() {
+    // skip loading angular component if we have no element
+    // or we have already loaded it
+    if (!this.element || this.attachedPanel) {
+      return;
     }
 
-    let panelContentStyle = {
-      height: this.getPanelHeight(),
-    };
-
-    return (
-      <div>
-        <div className="panel-container">
-          <PanelHeader panel={this.props.panel} dashboard={this.props.dashboard} />
-          <div className="panel-content" style={panelContentStyle}>
-            {PanelComponent && <PanelComponent />}
-          </div>
-        </div>
-        <div>
-          {this.props.panel.isEditing && <PanelEditor panel={this.props.panel} dashboard={this.props.dashboard} />}
-        </div>
-      </div>
-    );
+    const loader = this.props.panelContainer.getPanelLoader();
+    this.attachedPanel = loader.load(this.element, this.props.panel, this.props.dashboard);
   }
 
-  getPanelHeight() {
-    const panel = this.props.panel;
-    let height = 0;
-
-    if (panel.fullscreen) {
-      var docHeight = $(window).height();
-      var editHeight = Math.floor(docHeight * 0.4);
-      var fullscreenHeight = Math.floor(docHeight * 0.8);
-      height = panel.isEditing ? editHeight : fullscreenHeight;
-    } else {
-      height = panel.gridPos.h * GRID_CELL_HEIGHT + (panel.gridPos.h - 1) * GRID_CELL_VMARGIN;
+  componentWillUnmount() {
+    if (this.attachedPanel) {
+      this.attachedPanel.destroy();
     }
-
-    return height - PANEL_BORDER + TITLE_HEIGHT;
   }
-}
-
-interface PanelHeaderProps {
-  panel: PanelModel;
-  dashboard: DashboardModel;
-}
-
-export class PanelHeader extends React.Component<PanelHeaderProps, any> {
-  onEditPanel = () => {
-    store.view.updateQuery({
-      panelId: this.props.panel.id,
-      edit: true,
-      fullscreen: true,
-    });
-  };
 
   render() {
-    let isFullscreen = false;
-    let isLoading = false;
-    let 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 href="asd">asd</a>
-                </li>
-              </ul>
-            </span>
-            <span className="panel-time-info">
-              <i className="fa fa-clock-o" /> 4m
-            </span>
-          </span>
-        </div>
-      </div>
-    );
-  }
-}
+    if (this.isSpecial()) {
+      return this.specialPanels[this.props.panel.type]();
+    }
 
-interface PanelEditorProps {
-  panel: PanelModel;
-  dashboard: DashboardModel;
-}
+    if (!this.pluginExports) {
+      console.log('render null');
+      return null;
+    }
 
-export class PanelEditor extends React.Component<PanelEditorProps, any> {
-  render() {
-    return (
-      <div className="tabbed-view tabbed-view--panel-edit">
-        <div className="tabbed-view-header">
-          <h3 className="tabbed-view-panel-title">{this.props.panel.type}</h3>
-
-          <ul className="gf-tabs">
-            <li className="gf-tabs-item">
-              <a className="gf-tabs-link active">Queries</a>
-            </li>
-            <li className="gf-tabs-item">
-              <a className="gf-tabs-link">Visualization</a>
-            </li>
-          </ul>
-
-          <button className="tabbed-view-close-btn" ng-click="ctrl.exitFullscreen();">
-            <i className="fa fa-remove" />
-          </button>
-        </div>
-
-        <div className="tabbed-view-body">testing</div>
-      </div>
-    );
+    if (this.pluginExports.PanelComponent) {
+      return (
+        <PanelChrome
+          component={this.pluginExports.PanelComponent}
+          panel={this.props.panel}
+          dashboard={this.props.dashboard}
+        />
+      );
+    }
+
+    // legacy angular rendering
+    return <div ref={element => (this.element = element)} className="panel-height-helper" />;
   }
 }

+ 66 - 0
public/app/features/dashboard/dashgrid/PanelChrome.tsx

@@ -0,0 +1,66 @@
+import React from 'react';
+import $ from 'jquery';
+import { PanelModel } from '../panel_model';
+import { DashboardModel } from '../dashboard_model';
+import { GRID_CELL_HEIGHT, GRID_CELL_VMARGIN } from 'app/core/constants';
+import { PanelHeader } from './PanelHeader';
+import { PanelEditor } from './PanelEditor';
+
+const TITLE_HEIGHT = 27;
+const PANEL_BORDER = 2;
+
+export interface PanelChromeProps {
+  panel: PanelModel;
+  dashboard: DashboardModel;
+  component: any;
+}
+
+export class PanelChrome extends React.Component<PanelChromeProps, any> {
+  constructor(props) {
+    super(props);
+
+    this.props.panel.events.on('panel-size-changed', this.triggerForceUpdate.bind(this));
+  }
+
+  triggerForceUpdate() {
+    this.forceUpdate();
+  }
+
+  render() {
+    let panelContentStyle = {
+      height: this.getPanelHeight(),
+    };
+
+    let PanelComponent = this.props.component;
+
+    return (
+      <div className="panel-height-helper">
+        <div className="panel-container">
+          <PanelHeader panel={this.props.panel} dashboard={this.props.dashboard} />
+          <div className="panel-content" style={panelContentStyle}>
+            {<PanelComponent />}
+          </div>
+        </div>
+        <div>
+          {this.props.panel.isEditing && <PanelEditor panel={this.props.panel} dashboard={this.props.dashboard} />}
+        </div>
+      </div>
+    );
+  }
+
+  getPanelHeight() {
+    const panel = this.props.panel;
+    let height = 0;
+
+    if (panel.fullscreen) {
+      var docHeight = $(window).height();
+      var editHeight = Math.floor(docHeight * 0.4);
+      var fullscreenHeight = Math.floor(docHeight * 0.8);
+      height = panel.isEditing ? editHeight : fullscreenHeight;
+    } else {
+      height = panel.gridPos.h * GRID_CELL_HEIGHT + (panel.gridPos.h - 1) * GRID_CELL_VMARGIN;
+    }
+
+    return height - PANEL_BORDER + TITLE_HEIGHT;
+  }
+}

+ 35 - 0
public/app/features/dashboard/dashgrid/PanelEditor.tsx

@@ -0,0 +1,35 @@
+import React from 'react';
+import { PanelModel } from '../panel_model';
+import { DashboardModel } from '../dashboard_model';
+
+interface PanelEditorProps {
+  panel: PanelModel;
+  dashboard: DashboardModel;
+}
+
+export class PanelEditor extends React.Component<PanelEditorProps, any> {
+  render() {
+    return (
+      <div className="tabbed-view tabbed-view--panel-edit">
+        <div className="tabbed-view-header">
+          <h3 className="tabbed-view-panel-title">{this.props.panel.type}</h3>
+
+          <ul className="gf-tabs">
+            <li className="gf-tabs-item">
+              <a className="gf-tabs-link active">Queries</a>
+            </li>
+            <li className="gf-tabs-item">
+              <a className="gf-tabs-link">Visualization</a>
+            </li>
+          </ul>
+
+          <button className="tabbed-view-close-btn" ng-click="ctrl.exitFullscreen();">
+            <i className="fa fa-remove" />
+          </button>
+        </div>
+
+        <div className="tabbed-view-body">testing</div>
+      </div>
+    );
+  }
+}

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

@@ -0,0 +1,64 @@
+import React from 'react';
+import classNames from 'classnames';
+import { PanelModel } from '../panel_model';
+import { DashboardModel } from '../dashboard_model';
+import { store } from 'app/stores/store';
+
+interface PanelHeaderProps {
+  panel: PanelModel;
+  dashboard: DashboardModel;
+}
+
+export class PanelHeader extends React.Component<PanelHeaderProps, any> {
+  onEditPanel = () => {
+    store.view.updateQuery({
+      panelId: this.props.panel.id,
+      edit: true,
+      fullscreen: true,
+    });
+  };
+
+  render() {
+    let isFullscreen = false;
+    let isLoading = false;
+    let 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 href="asd">asd</a>
+                </li>
+              </ul>
+            </span>
+            <span className="panel-time-info">
+              <i className="fa fa-clock-o" /> 4m
+            </span>
+          </span>
+        </div>
+      </div>
+    );
+  }
+}

+ 1 - 1
public/app/features/dashboard/specs/AddPanelPanel.jest.tsx

@@ -14,7 +14,7 @@ jest.mock('app/core/store', () => ({
 }));
 
 describe('AddPanelPanel', () => {
-  let wrapper, dashboardMock, getPanelContainer, panel;
+  let wrapper, dashboardMock, panel;
 
   beforeEach(() => {
     config.panels = [