Browse Source

poc: began react panel experiments

Torkel Ödegaard 8 năm trước cách đây
mục cha
commit
13efc529ec

+ 66 - 12
public/app/features/dashboard/dashgrid/DashboardPanel.tsx

@@ -1,9 +1,12 @@
 import React from 'react';
-import {PanelModel} from '../panel_model';
-import {PanelContainer} from './PanelContainer';
-import {AttachedPanel} from './PanelLoader';
-import {DashboardRow} from './DashboardRow';
-import {AddPanelPanel} from './AddPanelPanel';
+import config from 'app/core/config';
+import classNames from 'classnames';
+import { PanelModel } from '../panel_model';
+import { PanelContainer } from './PanelContainer';
+import { AttachedPanel } from './PanelLoader';
+import { DashboardRow } from './DashboardRow';
+import { AddPanelPanel } from './AddPanelPanel';
+import { importPluginModule } from 'app/features/plugins/plugin_loader';
 
 export interface DashboardPanelProps {
   panel: PanelModel;
@@ -13,10 +16,26 @@ export interface DashboardPanelProps {
 export class DashboardPanel extends React.Component<DashboardPanelProps, any> {
   element: any;
   attachedPanel: AttachedPanel;
+  pluginInfo: any;
+  pluginExports: any;
+  specialPanels = {};
 
   constructor(props) {
     super(props);
     this.state = {};
+
+    this.specialPanels['row'] = this.renderRow.bind(this);
+    this.specialPanels['add-panel'] = this.renderAddPanel.bind(this);
+
+    if (!this.isSpecial()) {
+      this.pluginInfo = config.panels[this.props.panel.type];
+
+      // load panel plugin
+      importPluginModule(this.pluginInfo.module).then(pluginExports => {
+        this.pluginExports = pluginExports;
+        this.forceUpdate();
+      });
+    }
   }
 
   componentDidMount() {
@@ -36,19 +55,54 @@ export class DashboardPanel extends React.Component<DashboardPanelProps, any> {
     }
   }
 
+  isSpecial() {
+    return this.specialPanels[this.props.panel.type];
+  }
+
+  renderRow() {
+    return <DashboardRow panel={this.props.panel} getPanelContainer={this.props.getPanelContainer} />;
+  }
+
+  renderAddPanel() {
+    return <AddPanelPanel panel={this.props.panel} getPanelContainer={this.props.getPanelContainer} />;
+  }
+
   render() {
-    // special handling for rows
-    if (this.props.panel.type === 'row') {
-      return <DashboardRow panel={this.props.panel} getPanelContainer={this.props.getPanelContainer} />;
+    if (this.isSpecial()) {
+      return this.specialPanels[this.props.panel.type]();
     }
 
-    if (this.props.panel.type === 'add-panel') {
-      return <AddPanelPanel panel={this.props.panel} getPanelContainer={this.props.getPanelContainer} />;
+    let isFullscreen = false;
+    let isLoading = false;
+    let panelHeaderClass = classNames({ 'panel-header': true, 'grid-drag-handle': !isFullscreen });
+    let PanelComponent = null;
+
+    if (this.pluginExports && this.pluginExports.PanelComponent) {
+      PanelComponent = this.pluginExports.PanelComponent;
     }
 
     return (
-      <div ref={element => this.element = element} className="panel-height-helper" />
+      <div className="panel-container">
+        <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">{this.props.panel.title}</div>
+        </div>
+
+        <div className="panel-content">{PanelComponent && <PanelComponent />}</div>
+      </div>
     );
+
+    // return (
+    //   <div ref={element => this.element = element} className="panel-height-helper" />
+    // );
   }
 }
-

+ 2 - 0
public/app/features/plugins/built_in_plugins.ts

@@ -10,6 +10,7 @@ import * as postgresPlugin from 'app/plugins/datasource/postgres/module';
 import * as prometheusPlugin from 'app/plugins/datasource/prometheus/module';
 
 import * as textPanel from 'app/plugins/panel/text/module';
+import * as text2Panel from 'app/plugins/panel/text2/module';
 import * as graphPanel from 'app/plugins/panel/graph/module';
 import * as dashListPanel from 'app/plugins/panel/dashlist/module';
 import * as pluginsListPanel from 'app/plugins/panel/pluginlist/module';
@@ -37,6 +38,7 @@ const builtInPlugins = {
   'app/plugins/app/testdata/datasource/module': testDataDSPlugin,
 
   'app/plugins/panel/text/module': textPanel,
+  'app/plugins/panel/text2/module': text2Panel,
   'app/plugins/panel/graph/module': graphPanel,
   'app/plugins/panel/dashlist/module': dashListPanel,
   'app/plugins/panel/pluginlist/module': pluginsListPanel,

+ 5 - 0
public/app/plugins/panel/text2/README.md

@@ -0,0 +1,5 @@
+# Text Panel -  Native Plugin
+
+The Text Panel is **included** with Grafana.
+
+The Text Panel is a very simple panel that displays text. The source text is written in the Markdown syntax meaning you can format the text. Read [GitHub's Mastering Markdown](https://guides.github.com/features/mastering-markdown/) to learn more.

+ 26 - 0
public/app/plugins/panel/text2/img/icn-text-panel.svg

@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="iso-8859-1"?>
+<!-- Generator: Adobe Illustrator 19.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+	 width="100px" height="100px" viewBox="0 0 100 100" style="enable-background:new 0 0 100 100;" xml:space="preserve">
+<rect style="opacity:0.2;fill:#414042;" width="100" height="100"/>
+<g>
+	<linearGradient id="SVGID_1_" gradientUnits="userSpaceOnUse" x1="50" y1="88.2189" x2="50" y2="11.7811">
+		<stop  offset="0" style="stop-color:#FFF33B"/>
+		<stop  offset="0.0595" style="stop-color:#FFE029"/>
+		<stop  offset="0.1303" style="stop-color:#FFD218"/>
+		<stop  offset="0.2032" style="stop-color:#FEC90F"/>
+		<stop  offset="0.2809" style="stop-color:#FDC70C"/>
+		<stop  offset="0.6685" style="stop-color:#F3903F"/>
+		<stop  offset="0.8876" style="stop-color:#ED683C"/>
+		<stop  offset="1" style="stop-color:#E93E3A"/>
+	</linearGradient>
+	<path style="fill:url(#SVGID_1_);" d="M15.107,30.157h-2.593l0.395-18.376h74.183l0.395,18.376h-2.424
+		c-0.865-5.035-2.049-8.671-3.551-10.908c-1.504-2.235-3.12-3.607-4.848-4.115c-1.729-0.507-4.679-0.761-8.85-0.761H55.524V68.32
+		c0,5.975,0.141,9.903,0.423,11.781c0.282,1.88,1.043,3.27,2.283,4.171c1.24,0.902,3.57,1.353,6.99,1.353h3.72v2.593H30.834v-2.593
+		h3.946c3.269,0,5.533-0.413,6.793-1.24c1.258-0.826,2.066-2.114,2.424-3.861c0.357-1.747,0.535-5.815,0.535-12.204V14.374h-11.33
+		c-4.924,0-8.23,0.235-9.921,0.704c-1.691,0.471-3.279,1.888-4.764,4.256C17.032,21.702,15.896,25.31,15.107,30.157z"/>
+</g>
+<g>
+	<path style="fill:#898989;" d="M99,1v98H1V1H99 M100,0H0v100h100V0L100,0z"/>
+</g>
+</svg>

+ 13 - 0
public/app/plugins/panel/text2/module.tsx

@@ -0,0 +1,13 @@
+import React from 'react';
+
+export class ReactTestPanel extends React.Component<any, any> {
+  constructor(props) {
+    super(props);
+  }
+
+  render() {
+    return <h2>Panel content</h2>;
+  }
+}
+
+export { ReactTestPanel as PanelComponent };

+ 17 - 0
public/app/plugins/panel/text2/plugin.json

@@ -0,0 +1,17 @@
+{
+  "type": "panel",
+  "name": "Text2",
+  "id": "text2",
+
+  "info": {
+    "author": {
+      "name": "Grafana Project",
+      "url": "https://grafana.com"
+    },
+    "logos": {
+      "small": "img/icn-text-panel.svg",
+      "large": "img/icn-text-panel.svg"
+    }
+  }
+}
+