Browse Source

add ui elements for plugins.

This includes support for cusom plugin config directives.
woodsaj 10 years ago
parent
commit
3c13901695

+ 3 - 0
pkg/api/api.go

@@ -41,6 +41,9 @@ func Register(r *macaron.Macaron) {
 	r.Get("/admin/orgs", reqGrafanaAdmin, Index)
 	r.Get("/admin/orgs/edit/:id", reqGrafanaAdmin, Index)
 
+	r.Get("/plugins", reqSignedIn, Index)
+	r.Get("/plugins/edit/*", reqSignedIn, Index)
+
 	r.Get("/dashboard/*", reqSignedIn, Index)
 	r.Get("/dashboard-solo/*", reqSignedIn, Index)
 

+ 4 - 0
pkg/api/index.go

@@ -60,6 +60,10 @@ func setIndexViewData(c *middleware.Context) (*dtos.IndexViewData, error) {
 			Text: "Data Sources",
 			Icon: "fa fa-fw fa-database",
 			Href: "/datasources",
+		}, &dtos.NavLink{
+			Text: "Plugins",
+			Icon: "fa fa-fw fa-cubes",
+			Href: "/plugins",
 		})
 	}
 

+ 10 - 0
public/app/core/routes/all.js

@@ -131,6 +131,16 @@ define([
         templateUrl: 'app/partials/reset_password.html',
         controller : 'ResetPasswordCtrl',
       })
+      .when('/plugins', {
+        templateUrl: 'app/features/org/partials/plugins.html',
+        controller: 'PluginsCtrl',
+        resolve: loadOrgBundle,
+      })
+      .when('/plugins/edit/:type', {
+        templateUrl: 'app/features/org/partials/pluginEdit.html',
+        controller: 'PluginEditCtrl',
+        resolve: loadOrgBundle,
+      })
       .otherwise({
         templateUrl: 'app/partials/error.html',
         controller: 'ErrorCtrl'

+ 4 - 0
public/app/features/org/all.js

@@ -6,4 +6,8 @@ define([
   './userInviteCtrl',
   './orgApiKeysCtrl',
   './orgDetailsCtrl',
+  './pluginsCtrl',
+  './pluginEditCtrl',
+  './plugin_srv',
+  './plugin_directive',
 ], function () {});

+ 3 - 0
public/app/features/org/partials/pluginConfigCore.html

@@ -0,0 +1,3 @@
+<div>
+{{current.type}} plugin does not have any additional config.
+</div>

+ 42 - 0
public/app/features/org/partials/pluginEdit.html

@@ -0,0 +1,42 @@
+<topnav title="Plugins" icon="fa fa-fw fa-cubes" subnav="true">
+	<ul class="nav">
+		<li ><a href="plugins">Overview</a></li>
+		<li class="active" ><a href="plugins/edit/{{current.type}}">Edit</a></li>
+	</ul>
+</topnav>
+
+<div class="page-container">
+	<div class="page">
+		<h2>Edit Plugin</h2>
+
+
+		<form name="editForm">
+			<div class="tight-form">
+				<ul class="tight-form-list">
+					<li class="tight-form-item" style="width: 80px">
+						Type
+					</li>
+					<li>
+						<li>
+							<input type="text" disabled="disabled" class="input-xlarge tight-form-input" ng-model="current.type">
+						</li>
+					</li>
+					<li class="tight-form-item">
+						Default&nbsp;
+						<input class="cr1" id="current.enabled" type="checkbox" ng-model="current.enabled" ng-checked="current.enabled">
+						<label for="current.enabled" class="cr1"></label>
+					</li>
+				</ul>
+				<div class="clearfix"></div>
+			</div>
+			<br>
+			<plugin-config-loader></plugin-config-loader>
+			<div class="pull-right" style="margin-top: 35px">
+				<button type="submit" class="btn btn-success" ng-click="update()">Save</button>
+				<a class="btn btn-inverse" href="plugins">Cancel</a>
+			</div>
+			<br>
+		</form>
+
+	</div>
+</div>

+ 41 - 0
public/app/features/org/partials/plugins.html

@@ -0,0 +1,41 @@
+<topnav title="Plugins" icon="fa fa-fw fa-cubes" subnav="true">
+	<ul class="nav">
+		<li class="active" ><a href="plugins">Overview</a></li>
+	</ul>
+</topnav>
+
+<div class="page-container">
+	<div class="page">
+		<h2>Plugins</h2>
+
+		<div ng-if="!plugins">
+			<em>No plugins defined</em>
+		</div>
+
+		<table class="grafana-options-table" ng-if="plugins">
+			<tr>
+				<td><strong>Type</strong></td>
+				<td></td>
+				<td></td>
+			</tr>
+			<tr ng-repeat="(type, p) in plugins">
+				<td style="width:1%">
+					<i class="fa fa-cubes"></i> &nbsp;
+					{{p.type}}
+				</td>
+				<td style="width: 1%">
+					<a href="plugins/edit/{{p.type}}" class="btn btn-inverse btn-mini">
+						<i class="fa fa-edit"></i>
+						Edit
+					</a>
+				</td>
+				<td style="width: 1%">
+					Enabled&nbsp;
+					<input  id="p.enabled" type="checkbox" ng-model="p.enabled" ng-checked="p.enabled" ng-change="update(p)">
+					<label for="p.enabled"></label>
+				</td>
+			</tr>
+		</table>
+
+	</div>
+</div>

+ 35 - 0
public/app/features/org/pluginEditCtrl.js

@@ -0,0 +1,35 @@
+define([
+  'angular',
+  'lodash',
+  'app/core/config',
+],
+function (angular, _, config) {
+  'use strict';
+
+  var module = angular.module('grafana.controllers');
+
+  module.controller('PluginEditCtrl', function($scope, pluginSrv, $routeParams) {
+    $scope.init = function() {
+      $scope.current = {};
+      $scope.getPlugins();
+    };
+
+    $scope.getPlugins = function() {
+      pluginSrv.get($routeParams.type).then(function(result) {
+        $scope.current = _.clone(result);
+      });
+    };
+
+    $scope.update = function() {
+      $scope._update();
+    };
+
+    $scope._update = function() {
+      pluginSrv.update($scope.current).then(function() {
+        window.location.href = config.appSubUrl + "plugins";
+      });
+    };
+
+    $scope.init();
+  });
+});

+ 43 - 0
public/app/features/org/plugin_directive.js

@@ -0,0 +1,43 @@
+define([
+  'angular',
+],
+function (angular) {
+  'use strict';
+
+  var module = angular.module('grafana.directives');
+
+  module.directive('pluginConfigLoader', function($compile) {
+    return {
+      restrict: 'E',
+      link: function(scope, elem) {
+        var directive = 'grafana-plugin-core';
+        if (scope.current.module) {
+          directive = 'grafana-plugin-'+scope.current.type;
+        }
+        scope.require([scope.current.module], function () {
+          var panelEl = angular.element(document.createElement(directive));
+          elem.append(panelEl);
+          $compile(panelEl)(scope);
+        });
+      }
+    };
+  });
+
+  module.directive('grafanaPluginCore', function() {
+    return {
+      restrict: 'E',
+      templateUrl: 'app/features/org/partials/pluginConfigCore.html',
+      transclude: true,
+      link: function(scope, elem) {
+        console.log("grafana plugin core", scope, elem);
+        scope.update = function() {
+          //Perform custom save events to the plugins own backend if needed.
+
+          // call parent update to commit the change to the plugin object.
+          // this will cause the page to reload.
+          scope._update();
+        };
+      }
+    };
+  });
+});

+ 58 - 0
public/app/features/org/plugin_srv.js

@@ -0,0 +1,58 @@
+define([
+  'angular',
+  'lodash',
+],
+function (angular, _) {
+  'use strict';
+
+  var module = angular.module('grafana.services');
+
+  module.service('pluginSrv', function($rootScope, $timeout, $q, backendSrv) {
+    var self = this;
+    this.init = function() {
+      console.log("pluginSrv init");
+      this.plugins = {};
+    };
+
+    this.get = function(type) {
+      return $q(function(resolve) {
+        if (type in self.plugins) {
+          return resolve(self.plugins[type]);
+        }
+        backendSrv.get('/api/plugins').then(function(results) {
+          _.forEach(results, function(p) {
+            self.plugins[p.type] = p;
+          });
+          return resolve(self.plugins[type]);
+        });
+      });
+    };
+
+    this.getAll = function() {
+      return $q(function(resolve) {
+        if (!_.isEmpty(self.plugins)) {
+          return resolve(self.plugins);
+        }
+        backendSrv.get('api/plugins').then(function(results) {
+          _.forEach(results, function(p) {
+            self.plugins[p.type] = p;
+          });
+          return resolve(self.plugins);
+        });
+      });
+    };
+
+    this.update = function(plugin) {
+      return $q(function(resolve, reject) {
+        backendSrv.post('/api/plugins', plugin).then(function(resp) {
+          self.plugins[plugin.type] = plugin;
+          resolve(resp);
+        }, function(resp) {
+          reject(resp);
+        });
+      });
+    };
+
+    this.init();
+  });
+});

+ 33 - 0
public/app/features/org/pluginsCtrl.js

@@ -0,0 +1,33 @@
+define([
+  'angular',
+  'app/core/config',
+],
+function (angular, config) {
+  'use strict';
+
+  var module = angular.module('grafana.controllers');
+
+  module.controller('PluginsCtrl', function($scope, $location, pluginSrv) {
+
+    $scope.init = function() {
+      $scope.plugins = {};
+      $scope.getPlugins();
+    };
+
+    $scope.getPlugins = function() {
+      pluginSrv.getAll().then(function(result) {
+        console.log(result);
+        $scope.plugins = result;
+      });
+    };
+
+    $scope.update = function(plugin) {
+      pluginSrv.update(plugin).then(function() {
+        window.location.href = config.appSubUrl + $location.path();
+      });
+    };
+
+    $scope.init();
+
+  });
+});