Prechádzať zdrojové kódy

poc(plugin editors): experimential test for plugin editors

Torkel Ödegaard 10 rokov pred
rodič
commit
2f78584cdb

+ 0 - 0
public/app/core/plugins/directive.ts


+ 1 - 38
public/app/features/panel/panel.ts

@@ -4,44 +4,7 @@ import config from 'app/core/config';
 
 
 import {PanelCtrl} from './panel_ctrl';
 import {PanelCtrl} from './panel_ctrl';
 import {MetricsPanelCtrl} from './metrics_panel_ctrl';
 import {MetricsPanelCtrl} from './metrics_panel_ctrl';
-
-export class DefaultPanelCtrl extends PanelCtrl {
-  constructor($scope, $injector) {
-    super($scope, $injector);
-  }
-}
-
-class PanelDirective {
-  template: string;
-  templateUrl: string;
-  bindToController: boolean;
-  scope: any;
-  controller: any;
-  controllerAs: string;
-
-  getDirective() {
-    if (!this.controller) {
-      this.controller = DefaultPanelCtrl;
-    }
-
-    return {
-      template: this.template,
-      templateUrl: this.templateUrl,
-      controller: this.controller,
-      controllerAs: 'ctrl',
-      bindToController: true,
-      scope: {dashboard: "=", panel: "=", row: "="},
-      link: (scope, elem, attrs, ctrl) => {
-        ctrl.init();
-        this.link(scope, elem, attrs, ctrl);
-      }
-    };
-  }
-
-  link(scope, elem, attrs, ctrl) {
-    return null;
-  }
-}
+import {PanelDirective} from './panel_directive';
 
 
 export {
 export {
   PanelCtrl,
   PanelCtrl,

+ 0 - 104
public/app/features/panel/panel_directive.js

@@ -1,104 +0,0 @@
-define([
-  'angular',
-  'jquery',
-],
-function (angular, $) {
-  'use strict';
-
-  var module = angular.module('grafana.directives');
-
-  module.directive('grafanaPanel', function() {
-    return {
-      restrict: 'E',
-      templateUrl: 'app/features/panel/partials/panel.html',
-      transclude: true,
-      scope: { ctrl: "=" },
-      link: function(scope, elem) {
-        var panelContainer = elem.find('.panel-container');
-        var ctrl = scope.ctrl;
-        scope.$watchGroup(['ctrl.fullscreen', 'ctrl.height', 'ctrl.panel.height', 'ctrl.row.height'], function() {
-          panelContainer.css({ minHeight: ctrl.height || ctrl.panel.height || ctrl.row.height, display: 'block' });
-          elem.toggleClass('panel-fullscreen', ctrl.fullscreen ? true : false);
-        });
-      }
-    };
-  });
-
-  module.directive('panelResizer', function($rootScope) {
-    return {
-      restrict: 'E',
-      template: '<span class="resize-panel-handle"></span>',
-      link: function(scope, elem) {
-        var resizing = false;
-        var lastPanel = false;
-        var ctrl = scope.ctrl;
-        var handleOffset;
-        var originalHeight;
-        var originalWidth;
-        var maxWidth;
-
-        function dragStartHandler(e) {
-          e.preventDefault();
-          resizing = true;
-
-          handleOffset = $(e.target).offset();
-          originalHeight = parseInt(ctrl.row.height);
-          originalWidth = ctrl.panel.span;
-          maxWidth = $(document).width();
-
-          lastPanel = ctrl.row.panels[ctrl.row.panels.length - 1];
-
-          $('body').on('mousemove', moveHandler);
-          $('body').on('mouseup', dragEndHandler);
-        }
-
-        function moveHandler(e) {
-          ctrl.row.height = originalHeight + (e.pageY - handleOffset.top);
-          ctrl.panel.span = originalWidth + (((e.pageX - handleOffset.left) / maxWidth) * 12);
-          ctrl.panel.span = Math.min(Math.max(ctrl.panel.span, 1), 12);
-
-          var rowSpan = ctrl.dashboard.rowSpan(ctrl.row);
-
-          // auto adjust other panels
-          if (Math.floor(rowSpan) < 14) {
-            // last panel should not push row down
-            if (lastPanel === ctrl.panel && rowSpan > 12) {
-              lastPanel.span -= rowSpan - 12;
-            }
-            // reduce width of last panel so total in row is 12
-            else if (lastPanel !== ctrl.panel) {
-              lastPanel.span = lastPanel.span - (rowSpan - 12);
-              lastPanel.span = Math.min(Math.max(lastPanel.span, 1), 12);
-            }
-          }
-
-          scope.$apply(function() {
-            scope.$broadcast('render');
-          });
-        }
-
-        function dragEndHandler() {
-          // if close to 12
-          var rowSpan = ctrl.dashboard.rowSpan(ctrl.row);
-          if (rowSpan < 12 && rowSpan > 11) {
-            lastPanel.span +=  12 - rowSpan;
-          }
-
-          scope.$apply(function() {
-            $rootScope.$broadcast('render');
-          });
-
-          $('body').off('mousemove', moveHandler);
-          $('body').off('mouseup', dragEndHandler);
-        }
-
-        elem.on('mousedown', dragStartHandler);
-
-        scope.$on("$destroy", function() {
-          elem.off('mousedown', dragStartHandler);
-        });
-      }
-    };
-  });
-
-});

+ 142 - 0
public/app/features/panel/panel_directive.ts

@@ -0,0 +1,142 @@
+///<reference path="../../headers/common.d.ts" />
+
+import angular from 'angular';
+import $ from 'jquery';
+
+import {PanelCtrl} from './panel_ctrl';
+
+export class DefaultPanelCtrl extends PanelCtrl {
+  constructor($scope, $injector) {
+    super($scope, $injector);
+  }
+}
+
+export class PanelDirective {
+  template: string;
+  templateUrl: string;
+  bindToController: boolean;
+  scope: any;
+  controller: any;
+  controllerAs: string;
+
+  getDirective() {
+    if (!this.controller) {
+      this.controller = DefaultPanelCtrl;
+    }
+
+    return {
+      template: this.template,
+      templateUrl: this.templateUrl,
+      controller: this.controller,
+      controllerAs: 'ctrl',
+      bindToController: true,
+      scope: {dashboard: "=", panel: "=", row: "="},
+      link: (scope, elem, attrs, ctrl) => {
+        ctrl.init();
+        this.link(scope, elem, attrs, ctrl);
+      }
+    };
+  }
+
+  link(scope, elem, attrs, ctrl) {
+    return null;
+  }
+}
+
+
+var module = angular.module('grafana.directives');
+
+module.directive('grafanaPanel', function() {
+  return {
+    restrict: 'E',
+    templateUrl: 'app/features/panel/partials/panel.html',
+    transclude: true,
+    scope: { ctrl: "=" },
+    link: function(scope, elem) {
+      var panelContainer = elem.find('.panel-container');
+      var ctrl = scope.ctrl;
+      scope.$watchGroup(['ctrl.fullscreen', 'ctrl.height', 'ctrl.panel.height', 'ctrl.row.height'], function() {
+        panelContainer.css({ minHeight: ctrl.height || ctrl.panel.height || ctrl.row.height, display: 'block' });
+        elem.toggleClass('panel-fullscreen', ctrl.fullscreen ? true : false);
+      });
+    }
+  };
+});
+
+module.directive('panelResizer', function($rootScope) {
+  return {
+    restrict: 'E',
+    template: '<span class="resize-panel-handle"></span>',
+    link: function(scope, elem) {
+      var resizing = false;
+      var lastPanel;
+      var ctrl = scope.ctrl;
+      var handleOffset;
+      var originalHeight;
+      var originalWidth;
+      var maxWidth;
+
+      function dragStartHandler(e) {
+        e.preventDefault();
+        resizing = true;
+
+        handleOffset = $(e.target).offset();
+        originalHeight = parseInt(ctrl.row.height);
+        originalWidth = ctrl.panel.span;
+        maxWidth = $(document).width();
+
+        lastPanel = ctrl.row.panels[ctrl.row.panels.length - 1];
+
+        $('body').on('mousemove', moveHandler);
+        $('body').on('mouseup', dragEndHandler);
+      }
+
+      function moveHandler(e) {
+        ctrl.row.height = originalHeight + (e.pageY - handleOffset.top);
+        ctrl.panel.span = originalWidth + (((e.pageX - handleOffset.left) / maxWidth) * 12);
+        ctrl.panel.span = Math.min(Math.max(ctrl.panel.span, 1), 12);
+
+        var rowSpan = ctrl.dashboard.rowSpan(ctrl.row);
+
+        // auto adjust other panels
+        if (Math.floor(rowSpan) < 14) {
+          // last panel should not push row down
+          if (lastPanel === ctrl.panel && rowSpan > 12) {
+            lastPanel.span -= rowSpan - 12;
+          } else if (lastPanel !== ctrl.panel) {
+            // reduce width of last panel so total in row is 12
+            lastPanel.span = lastPanel.span - (rowSpan - 12);
+            lastPanel.span = Math.min(Math.max(lastPanel.span, 1), 12);
+          }
+        }
+
+        scope.$apply(function() {
+          scope.$broadcast('render');
+        });
+      }
+
+      function dragEndHandler() {
+        // if close to 12
+        var rowSpan = ctrl.dashboard.rowSpan(ctrl.row);
+        if (rowSpan < 12 && rowSpan > 11) {
+          lastPanel.span +=  12 - rowSpan;
+        }
+
+        scope.$apply(function() {
+          $rootScope.$broadcast('render');
+        });
+
+        $('body').off('mousemove', moveHandler);
+        $('body').off('mouseup', dragEndHandler);
+      }
+
+      elem.on('mousedown', dragStartHandler);
+
+      scope.$on("$destroy", function() {
+        elem.off('mousedown', dragStartHandler);
+      });
+    }
+  };
+});
+
+

+ 77 - 3
public/app/features/panel/query_editor.ts

@@ -1,6 +1,80 @@
 ///<reference path="../../headers/common.d.ts" />
 ///<reference path="../../headers/common.d.ts" />
 
 
 import angular from 'angular';
 import angular from 'angular';
+import _ from 'lodash';
+
+var directivesModule = angular.module('grafana.directives');
+
+function pluginDirectiveLoader($compile, datasourceSrv) {
+
+  function getPluginComponentDirective(options) {
+    return function() {
+      return {
+        templateUrl: options.Component.templateUrl,
+        restrict: 'E',
+        controller: options.Component,
+        controllerAs: 'ctrl',
+        bindToController: true,
+        scope: options.bindings,
+        link: (scope, elem, attrs, ctrl) => {
+          if (ctrl.link) {
+            ctrl.link(scope, elem, attrs, ctrl);
+          }
+        }
+      };
+    };
+  }
+
+  function getModule(scope, attrs) {
+    switch (attrs.type) {
+      case "metrics-query-editor": {
+        let datasource = scope.target.datasource || scope.ctrl.panel.datasource;
+        return datasourceSrv.get(datasource).then(ds => {
+          return System.import(ds.meta.module).then(dsModule => {
+            return {
+              name: 'metrics-query-editor-' + ds.meta.id,
+              bindings: {target: "=", panelCtrl: "="},
+              attrs: {"target": "target", "panel-ctrl": "ctrl"},
+              Component: dsModule.MetricsQueryEditor
+            };
+          });
+        });
+      }
+    }
+  }
+
+  function appendAndCompile(scope, elem, componentInfo) {
+    var child = angular.element(document.createElement(componentInfo.name));
+    _.each(componentInfo.attrs, (value, key) => {
+      child.attr(key, value);
+    });
+
+    $compile(child)(scope);
+
+    elem.empty();
+    elem.append(child);
+  }
+
+  function registerPluginComponent(scope, elem, attrs, componentInfo) {
+    if (!componentInfo.Component.registered) {
+      var directiveName = attrs.$normalize(componentInfo.name);
+      var directiveFn = getPluginComponentDirective(componentInfo);
+      directivesModule.directive(directiveName, directiveFn);
+      componentInfo.Component.registered = true;
+    }
+
+    appendAndCompile(scope, elem, componentInfo);
+  }
+
+  return {
+    restrict: 'E',
+    link: function(scope, elem, attrs) {
+      getModule(scope, attrs).then(function (componentInfo) {
+        registerPluginComponent(scope, elem, attrs, componentInfo);
+      });
+    }
+  };
+}
 
 
 /** @ngInject */
 /** @ngInject */
 function metricsQueryEditor(dynamicDirectiveSrv, datasourceSrv) {
 function metricsQueryEditor(dynamicDirectiveSrv, datasourceSrv) {
@@ -43,6 +117,6 @@ function metricsQueryOptions(dynamicDirectiveSrv, datasourceSrv) {
   });
   });
 }
 }
 
 
-angular.module('grafana.directives')
-  .directive('metricsQueryEditor', metricsQueryEditor)
-  .directive('metricsQueryOptions', metricsQueryOptions);
+directivesModule.directive('pluginDirectiveLoader', pluginDirectiveLoader);
+directivesModule.directive('metricsQueryEditor', metricsQueryEditor);
+directivesModule.directive('metricsQueryOptions', metricsQueryOptions);

+ 2 - 2
public/app/partials/metrics.html

@@ -1,8 +1,8 @@
 <div class="editor-row">
 <div class="editor-row">
 
 
 	<div class="tight-form-container">
 	<div class="tight-form-container">
-		<metrics-query-editor ng-repeat="target in ctrl.panel.targets" ng-class="{'tight-form-disabled': target.hide}" >
-		</metrics-query-editor>
+		<plugin-directive-loader type="metrics-query-editor" ng-repeat="target in ctrl.panel.targets" ng-class="{'tight-form-disabled': target.hide}">
+		</plugin-directive-loader>
 	</div>
 	</div>
 
 
 	<div style="margin: 20px 0 0 0">
 	<div style="margin: 20px 0 0 0">

+ 14 - 1
public/app/plugins/datasource/grafana/module.ts

@@ -9,10 +9,23 @@ function grafanaMetricsQueryEditor() {
   return {templateUrl: 'app/plugins/datasource/grafana/partials/query.editor.html'};
   return {templateUrl: 'app/plugins/datasource/grafana/partials/query.editor.html'};
 }
 }
 
 
+export class MetricsQueryEditor {
+  panelCtrl: any;
+  target: any;
+}
+
+class GrafanaMetricsQueryEditor extends MetricsQueryEditor {
+  static templateUrl = 'app/plugins/datasource/grafana/partials/query.editor.html';
+
+  constructor() {
+    super();
+    console.log('this is a metrics editor', this.panelCtrl, this.target);
+  }
+}
 
 
 export {
 export {
   GrafanaDatasource,
   GrafanaDatasource,
   GrafanaDatasource as Datasource,
   GrafanaDatasource as Datasource,
-  grafanaMetricsQueryEditor as metricsQueryEditor
+  GrafanaMetricsQueryEditor as MetricsQueryEditor,
 };
 };