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

Big refactoring of the way panels are loaded and how they are built using directives, this way feel cleaner and allowed for placing the panel edit box outside the panel-container

Torkel Ödegaard 11 лет назад
Родитель
Сommit
04ec222462

+ 2 - 0
src/app/components/panelmeta.js

@@ -6,6 +6,8 @@ function () {
   function PanelMeta(options) {
   function PanelMeta(options) {
     this.description = options.description;
     this.description = options.description;
     this.fullscreen = options.fullscreen;
     this.fullscreen = options.fullscreen;
+    this.editIcon = options.editIcon;
+    this.panelName = options.panelName;
     this.menu = [];
     this.menu = [];
     this.editorTabs = [];
     this.editorTabs = [];
     this.extendedMenu = [];
     this.extendedMenu = [];

+ 1 - 1
src/app/components/settings.js

@@ -18,7 +18,7 @@ function (_, crypto) {
       panels                        : {
       panels                        : {
         'graph': { path: 'panels/graph' },
         'graph': { path: 'panels/graph' },
         'singlestat': { path: 'panels/singlestat' },
         'singlestat': { path: 'panels/singlestat' },
-        'text': { path: 'panels/text' }
+        'text': { path: 'panels/text' },
       },
       },
       plugins                       : {},
       plugins                       : {},
       default_route                 : '/dashboard/file/default.json',
       default_route                 : '/dashboard/file/default.json',

+ 0 - 1
src/app/controllers/search.js

@@ -143,7 +143,6 @@ function (angular, _, config, $) {
     };
     };
 
 
     $scope.newDashboard = function() {
     $scope.newDashboard = function() {
-      //$location.path('/dashboard/file/empty.json');
       $location.url('dashboard/new');
       $location.url('dashboard/new');
     };
     };
 
 

+ 0 - 1
src/app/directives/all.js

@@ -1,7 +1,6 @@
 define([
 define([
   './arrayJoin',
   './arrayJoin',
   './dashUpload',
   './dashUpload',
-  './grafanaPanel',
   './grafanaSimplePanel',
   './grafanaSimplePanel',
   './ngBlur',
   './ngBlur',
   './dashEditLink',
   './dashEditLink',

+ 0 - 80
src/app/directives/grafanaPanel.js

@@ -1,80 +0,0 @@
-define([
-  'angular',
-  'jquery',
-  'config',
-  './panelMenu',
-],
-function (angular, $, config) {
-  'use strict';
-
-  angular
-    .module('grafana.directives')
-    .directive('grafanaPanel', function($compile, $parse) {
-
-      var container = '<div class="panel-container"></div>';
-      var content = '<div class="panel-content"></div>';
-
-      var panelHeader =
-      '<div class="panel-header">'+
-          '<span class="alert-error panel-error small pointer"' +
-                'config-modal="app/partials/inspector.html" ng-if="panelMeta.error">' +
-            '<span data-placement="top" bs-tooltip="panelMeta.error">' +
-            '<i class="fa fa-exclamation"></i><span class="panel-error-arrow"></span>' +
-            '</span>' +
-          '</span>' +
-
-          '<span class="panel-loading" ng-show="panelMeta.loading">' +
-            '<i class="fa fa-spinner fa-spin"></i>' +
-          '</span>' +
-
-          '<div class="panel-title-container drag-handle" panel-menu></div>' +
-        '</div>'+
-      '</div>';
-
-      return {
-        restrict: 'E',
-        link: function($scope, elem, attr) {
-          var getter = $parse(attr.type), panelType = getter($scope);
-          var newScope = $scope.$new();
-
-          // compile the module and uncloack. We're done
-          function loadModule($module) {
-            $module.appendTo(elem);
-            elem.wrap(container);
-
-            $compile(elem.contents())(newScope);
-            elem.removeClass("ng-cloak");
-
-            var panelCtrlElem = $(elem.children()[0]);
-            var panelCtrlScope = panelCtrlElem.data().$scope;
-
-            panelCtrlScope.$watchGroup(['fullscreen', 'panel.height', 'row.height'], function() {
-              panelCtrlElem.css({ minHeight: panelCtrlScope.panel.height || panelCtrlScope.row.height });
-              panelCtrlElem.toggleClass('panel-fullscreen', panelCtrlScope.fullscreen ? true : false);
-            });
-          }
-
-          newScope.$on('$destroy',function() {
-            elem.unbind();
-            elem.remove();
-          });
-
-          elem.addClass('ng-cloak');
-
-          var panelPath = config.panels[panelType].path;
-
-          $scope.require([
-            'jquery',
-            'text!'+panelPath+'/module.html',
-            panelPath + "/module",
-          ], function ($, moduleTemplate) {
-            var $module = $(moduleTemplate);
-            $module.prepend(panelHeader);
-            $module.first().find('.panel-header').nextAll().wrapAll(content);
-            loadModule($module);
-          });
-        }
-      };
-    });
-
-});

+ 15 - 25
src/app/features/account/partials/account.html

@@ -1,18 +1,4 @@
 <topnav toggle="toggleSideMenu()" icon="fa fa-shield" section="Account" show-menu-btn="!grafana.sidemenu">
 <topnav toggle="toggleSideMenu()" icon="fa fa-shield" section="Account" show-menu-btn="!grafana.sidemenu">
-	<!-- <ul class="nav"> -->
-	<!-- 	<li> -->
-	<!-- 		<a href="asd">Details</a> -->
-	<!-- 	</li> -->
-	<!-- 	<li> -->
-	<!-- 		<a href="asd">Data Sources</a> -->
-	<!-- 	</li> -->
-	<!-- 	<li> -->
-	<!-- 		<a href="asd">Users</a> -->
-	<!-- 	</li> -->
-	<!-- 	<li> -->
-	<!-- 		<a href="asd">API Keys</a> -->
-	<!-- 	</li> -->
-	<!-- </ul> -->
 </topnav>
 </topnav>
 
 
 <div class="gf-box" style="min-height: 500px">
 <div class="gf-box" style="min-height: 500px">
@@ -22,18 +8,22 @@
 			<div class="section">
 			<div class="section">
 				<form name="accountForm">
 				<form name="accountForm">
 					<div>
 					<div>
-					<div class="tight-form">
-						<ul class="tight-form-list">
-							<li class="tight-form-item" style="width: 120px">
-								<strong>Account name</strong>
-							</li>
-							<li>
-								<input type="text" required ng-model="account.name" class="input-xlarge tight-form-input last" >
-							</li>
-						</ul>
-						<div class="clearfix"></div>
-					</div>
+						<div class="tight-form">
+							<ul class="tight-form-list">
+								<li class="tight-form-item" style="width: 120px">
+									<strong>Account name</strong>
+								</li>
+								<li>
+									<input type="text" required ng-model="account.name" class="input-xlarge tight-form-input last" >
+								</li>
+							</ul>
+							<div class="clearfix"></div>
+						</div>
 					</div>
 					</div>
+					<br>
+
+					<panel-loader type="'test'"></panel-loader>
+
 					<br>
 					<br>
 					<button type="submit" class="pull-right btn btn-success" ng-click="update()">Update</button>
 					<button type="submit" class="pull-right btn btn-success" ng-click="update()">Update</button>
 				</form>
 				</form>

+ 1 - 0
src/app/features/all.js

@@ -7,6 +7,7 @@ define([
   './opentsdb/datasource',
   './opentsdb/datasource',
   './elasticsearch/datasource',
   './elasticsearch/datasource',
   './dashboard/all',
   './dashboard/all',
+  './panel/all',
   './profile/profileCtrl',
   './profile/profileCtrl',
   './account/accountUsersCtrl',
   './account/accountUsersCtrl',
   './account/datasourcesCtrl',
   './account/datasourcesCtrl',

+ 0 - 1
src/app/features/dashboard/all.js

@@ -9,7 +9,6 @@ define([
   './keybindings',
   './keybindings',
   './viewStateSrv',
   './viewStateSrv',
   './playlistSrv',
   './playlistSrv',
-  './panelSrv',
   './soloPanelCtrl',
   './soloPanelCtrl',
   './timeSrv',
   './timeSrv',
   './unsavedChangesSrv',
   './unsavedChangesSrv',

+ 2 - 2
src/app/features/dashboard/viewStateSrv.js

@@ -118,7 +118,7 @@ function (angular, _, $) {
           self.$scope.dashboard.emit_refresh();
           self.$scope.dashboard.emit_refresh();
         }
         }
         else {
         else {
-          self.fullscreenPanel.$emit('render');
+          self.fullscreenPanel.$broadcast('render');
         }
         }
         delete self.fullscreenPanel;
         delete self.fullscreenPanel;
       });
       });
@@ -139,7 +139,7 @@ function (angular, _, $) {
       panelScope.fullscreen = true;
       panelScope.fullscreen = true;
 
 
       $timeout(function() {
       $timeout(function() {
-        panelScope.$emit('render');
+        panelScope.$broadcast('render');
       });
       });
     };
     };
 
 

+ 5 - 0
src/app/features/panel/all.js

@@ -0,0 +1,5 @@
+define([
+  './panelMenu',
+  './panelDirective',
+  './panelSrv',
+], function () {});

+ 40 - 0
src/app/features/panel/panelDirective.js

@@ -0,0 +1,40 @@
+define([
+  'angular',
+  'jquery',
+  'config',
+],
+function (angular, $, config) {
+  'use strict';
+
+  angular
+    .module('grafana.directives')
+    .directive('panelLoader', function($compile, $parse) {
+      return {
+        restrict: 'E',
+        link: function(scope, elem, attr) {
+          var getter = $parse(attr.type), panelType = getter(scope);
+          var panelPath = config.panels[panelType].path;
+
+          scope.require([panelPath + "/module"], function () {
+            var panelEl = angular.element(document.createElement('grafana-panel-' + panelType));
+            elem.append(panelEl);
+            $compile(panelEl)(scope);
+          });
+        }
+      };
+    }).directive('grafanaPanel', function() {
+      return {
+        restrict: 'E',
+        templateUrl: '/app/features/panel/partials/panel.html',
+        transclude: true,
+        link: function(scope, elem) {
+          var panelContainer = elem.find('.panel-container');
+
+          scope.$watchGroup(['fullscreen', 'panel.height', 'row.height'], function() {
+            panelContainer.css({ minHeight: scope.panel.height || scope.row.height, display: 'block' });
+            elem.toggleClass('panel-fullscreen', scope.fullscreen ? true : false);
+          });
+        }
+      };
+    });
+});

+ 0 - 0
src/app/directives/panelMenu.js → src/app/features/panel/panelMenu.js


+ 0 - 0
src/app/features/dashboard/panelSrv.js → src/app/features/panel/panelSrv.js


+ 42 - 0
src/app/features/panel/partials/panel.html

@@ -0,0 +1,42 @@
+<div class="panel-container">
+	<div class="panel-header">
+		<span class="alert-error panel-error small pointer" config-modal="app/partials/inspector.html" ng-if="panelMeta.error">
+			<span data-placement="top" bs-tooltip="panelMeta.error">
+				<i class="fa fa-exclamation"></i><span class="panel-error-arrow"></span>
+			</span>
+		</span>
+
+		<span class="panel-loading" ng-show="panelMeta.loading">
+			<i class="fa fa-spinner fa-spin"></i>
+		</span>
+
+		<div class="panel-title-container drag-handle" panel-menu></div>
+	</div>
+
+	<div class="panel-content">
+		<ng-transclude></ng-transclude>
+	</div>
+</div>
+
+<div class="panel-full-edit" ng-if="editMode">
+	<div class="gf-box">
+		<div class="gf-box-header">
+			<div class="gf-box-title">
+				<i ng-class="panelMeta.editIcon"></i>
+				{{panelMeta.panelName}}
+			</div>
+
+			<div ng-model="editor.index" bs-tabs>
+				<div ng-repeat="tab in panelMeta.editorTabs" data-title="{{tab.title}}">
+				</div>
+			</div>
+		</div>
+
+		<div class="gf-box-body">
+			<div ng-repeat="tab in panelMeta.editorTabs" ng-if="editor.index === $index">
+				<div ng-include src="tab.src"></div>
+			</div>
+		</div>
+	</div>
+</div>
+

+ 2 - 19
src/app/panels/graph/module.html

@@ -1,4 +1,4 @@
-<div ng-controller='GraphCtrl'>
+<grafana-panel>
 
 
 	<div class="graph-wrapper" ng-class="{'graph-legend-rightside': panel.legend.rightSide}">
 	<div class="graph-wrapper" ng-class="{'graph-legend-rightside': panel.legend.rightSide}">
 		<div class="graph-canvas-wrapper">
 		<div class="graph-canvas-wrapper">
@@ -24,23 +24,6 @@
 
 
 	<div class="clearfix"></div>
 	<div class="clearfix"></div>
 
 
-	<div class="gf-box gf-box-full-edit" ng-if="editMode">
-		<div class="gf-box-header">
-			<div class="gf-box-title">
-				<i class="fa fa-bar-chart"></i>
-				Graph
-			</div>
+</grafana-panel>
 
 
-			<div ng-model="editor.index" bs-tabs>
-				<div ng-repeat="tab in panelMeta.editorTabs" data-title="{{tab.title}}">
-				</div>
-			</div>
-		</div>
 
 
-		<div class="gf-box-body">
-			<div ng-repeat="tab in panelMeta.editorTabs" ng-if="editor.index === $index">
-				<div ng-include src="tab.src"></div>
-			</div>
-		</div>
-	</div>
-</div>

+ 9 - 1
src/app/panels/graph/module.js

@@ -16,10 +16,18 @@ function (angular, app, $, _, kbn, moment, TimeSeries, PanelMeta) {
 
 
   var module = angular.module('grafana.panels.graph');
   var module = angular.module('grafana.panels.graph');
 
 
+  module.directive('grafanaPanelGraph', function() {
+    return {
+      controller: 'GraphCtrl',
+      templateUrl: '/app/panels/graph/module.html',
+    };
+  });
+
   module.controller('GraphCtrl', function($scope, $rootScope, panelSrv, annotationsSrv, timeSrv) {
   module.controller('GraphCtrl', function($scope, $rootScope, panelSrv, annotationsSrv, timeSrv) {
 
 
     $scope.panelMeta = new PanelMeta({
     $scope.panelMeta = new PanelMeta({
-      description: 'Graph panel',
+      panelName: 'Graph',
+      editIcon:  "fa fa-bar-chart",
       fullscreen: true,
       fullscreen: true,
       metricsEditor: true
       metricsEditor: true
     });
     });

+ 2 - 24
src/app/panels/singlestat/module.html

@@ -1,26 +1,4 @@
-<div ng-controller='SingleStatCtrl'>
-
+<grafana-panel>
 	<div class="singlestat-panel" singlestat-panel></div>
 	<div class="singlestat-panel" singlestat-panel></div>
-
   <div class="clearfix"></div>
   <div class="clearfix"></div>
-
-	<div class="gf-box gf-box-full-edit" ng-if="editMode">
-		<div class="gf-box-header">
-			<div class="gf-box-title">
-				<i class="fa fa-dashboard"></i>
-			  Singlestat
-			</div>
-
-			<div ng-model="editor.index" bs-tabs>
-				<div ng-repeat="tab in panelMeta.editorTabs" data-title="{{tab.title}}">
-				</div>
-			</div>
-		</div>
-
-		<div class="gf-box-body">
-			<div ng-repeat="tab in panelMeta.editorTabs" ng-if="editor.index === $index">
-				<div ng-include src="tab.src"></div>
-			</div>
-		</div>
-	</div>
-</div>
+</grafana-panel>

+ 10 - 2
src/app/panels/singlestat/module.js

@@ -13,10 +13,18 @@ function (angular, app, _, TimeSeries, kbn, PanelMeta) {
   var module = angular.module('grafana.panels.singlestat');
   var module = angular.module('grafana.panels.singlestat');
   app.useModule(module);
   app.useModule(module);
 
 
+  module.directive('grafanaPanelSinglestat', function() {
+    return {
+      controller: 'SingleStatCtrl',
+      templateUrl: '/app/panels/singlestat/module.html',
+    };
+  });
+
   module.controller('SingleStatCtrl', function($scope, panelSrv, timeSrv) {
   module.controller('SingleStatCtrl', function($scope, panelSrv, timeSrv) {
 
 
     $scope.panelMeta = new PanelMeta({
     $scope.panelMeta = new PanelMeta({
-      description: 'Singlestat panel',
+      panelName: 'Singlestat',
+      editIcon:  "fa fa-dashboard",
       fullscreen: true,
       fullscreen: true,
       metricsEditor: true
       metricsEditor: true
     });
     });
@@ -192,7 +200,7 @@ function (angular, app, _, TimeSeries, kbn, PanelMeta) {
       data.colorMap = $scope.panel.colors;
       data.colorMap = $scope.panel.colors;
 
 
       $scope.data = data;
       $scope.data = data;
-      $scope.$emit('render');
+      $scope.$broadcast('render');
     };
     };
 
 
     $scope.getFormatedValue = function(mainValue) {
     $scope.getFormatedValue = function(mainValue) {

+ 3 - 4
src/app/panels/text/module.html

@@ -1,4 +1,3 @@
-<div ng-controller='text'>
-  <p ng-bind-html="content" ng-show="content">
-  </p>
-</div>
+<grafana-panel>
+  <p ng-bind-html="content" ng-show="content"></p>
+</grafana-panel>

+ 12 - 3
src/app/panels/text/module.js

@@ -8,15 +8,24 @@ define([
 function (angular, app, _, require, PanelMeta) {
 function (angular, app, _, require, PanelMeta) {
   'use strict';
   'use strict';
 
 
+  var converter;
+
   var module = angular.module('grafana.panels.text', []);
   var module = angular.module('grafana.panels.text', []);
   app.useModule(module);
   app.useModule(module);
 
 
-  var converter;
+  module.directive('grafanaPanelText', function() {
+    return {
+      controller: 'TextPanelCtrl',
+      templateUrl: '/app/panels/text/module.html',
+    };
+  });
 
 
-  module.controller('text', function($scope, templateSrv, $sce, panelSrv) {
+  module.controller('TextPanelCtrl', function($scope, templateSrv, $sce, panelSrv) {
 
 
     $scope.panelMeta = new PanelMeta({
     $scope.panelMeta = new PanelMeta({
-      description : "A static text panel that can use plain text, markdown, or (sanitized) HTML"
+      panelName: 'Text',
+      editIcon:  "fa fa-text-width",
+      fullscreen: true,
     });
     });
 
 
     $scope.panelMeta.addEditorTab('Edit text', 'app/panels/text/editor.html');
     $scope.panelMeta.addEditorTab('Edit text', 'app/panels/text/editor.html');

+ 3 - 4
src/app/partials/dashboard.html

@@ -79,12 +79,11 @@
 					</div>
 					</div>
 
 
 					<!-- Panels, draggable needs to be disabled in fullscreen because Firefox bug -->
 					<!-- Panels, draggable needs to be disabled in fullscreen because Firefox bug -->
-					<div ng-repeat="(name, panel) in row.panels"
-						class="panel"
+					<div ng-repeat="(name, panel) in row.panels" class="panel"
 						ui-draggable="{{!dashboardViewState.fullscreen}}" drag="panel.id"
 						ui-draggable="{{!dashboardViewState.fullscreen}}" drag="panel.id"
 						ui-on-Drop="onDrop($data, row, panel)"
 						ui-on-Drop="onDrop($data, row, panel)"
-						drag-handle-class="drag-handle" panel-width ng-model="panel">
-						<grafana-panel type="panel.type" ng-cloak></grafana-panel>
+						drag-handle-class="drag-handle" panel-width>
+						<panel-loader type="panel.type" class="panel-margin"></panel-loader>
 					</div>
 					</div>
 
 
 					<div panel-drop-zone class="panel panel-drop-zone"
 					<div panel-drop-zone class="panel panel-drop-zone"

+ 0 - 22
src/app/partials/paneleditor.html

@@ -1,22 +0,0 @@
-<div bindonce class="gf-box-header">
-	<div class="gf-box-title">
-		<i class="fa fa-text-width"></i>
-		<span bo-text="panel.type+' settings'"></span>
-	</div>
-
-	<div ng-model="editor.index" bs-tabs style="text-transform:capitalize;">
-		<div ng-repeat="tab in panelMeta.editorTabs" data-title="{{tab.title}}">
-		</div>
-	</div>
-
-	<button class="gf-box-header-close-btn" ng-click="dismiss();">
-		<i class="fa fa-remove"></i>
-	</button>
-</div>
-
-<div class="gf-box-body">
-	<div ng-repeat="tab in panelMeta.editorTabs" ng-show="editor.index == $index">
-		<div ng-include src="tab.src"></div>
-	</div>
-</div>
-

+ 1 - 1
src/app/routes/backend/dashboard.js

@@ -58,7 +58,7 @@ function (angular, store) {
       $location.path('');
       $location.path('');
       return;
       return;
     }
     }
-    $scope.initDashboard(window.grafanaImportDashboard, $scope);
+    $scope.initDashboard({ meta: {}, model: window.grafanaImportDashboard }, $scope);
   });
   });
 
 
   module.controller('NewDashboardCtrl', function($scope) {
   module.controller('NewDashboardCtrl', function($scope) {

+ 0 - 4
src/css/less/gfbox.less

@@ -5,10 +5,6 @@
   border: 1px solid @grafanaTargetFuncBackground;
   border: 1px solid @grafanaTargetFuncBackground;
 }
 }
 
 
-.gf-box-full-edit {
-  margin: 30px 0 0 0;
-}
-
 .gf-box-no-margin {
 .gf-box-no-margin {
   margin: 0;
   margin: 0;
 }
 }

+ 15 - 7
src/css/less/panel.less

@@ -5,10 +5,13 @@
   position: relative;
   position: relative;
 }
 }
 
 
+.panel-margin {
+  margin: 5px;
+  display: block;
+}
+
 .panel-container {
 .panel-container {
-  padding: 0px 0px 0px 0px;
   background: @grafanaPanelBackground;
   background: @grafanaPanelBackground;
-  margin: 5px;
   position: relative;
   position: relative;
   &:hover {
   &:hover {
     .panel-actions {
     .panel-actions {
@@ -91,17 +94,17 @@
   top: 60px;
   top: 60px;
   height: 100%;
   height: 100%;
   padding: 0;
   padding: 0;
-  background: @grafanaPanelBackground;
   overflow-y: auto;
   overflow-y: auto;
   height: 100%;
   height: 100%;
 
 
-  .panel-content {
-    padding-bottom: 130px;
-  }
-
   .dropdown-menu {
   .dropdown-menu {
     margin-bottom: 70px;
     margin-bottom: 70px;
   }
   }
+
+  .panel-container {
+    margin: 15px;
+  }
+
   .panel-menu {
   .panel-menu {
     top: 0px;
     top: 0px;
   }
   }
@@ -110,6 +113,11 @@
   }
   }
 }
 }
 
 
+.panel-full-edit {
+  margin-top: 30px;
+  padding-bottom: 130px;
+}
+
 .panel-menu {
 .panel-menu {
   z-index: 1000;
   z-index: 1000;
   position: absolute;
   position: absolute;

+ 1 - 1
src/test/specs/graph-ctrl-specs.js

@@ -1,6 +1,6 @@
 define([
 define([
   'helpers',
   'helpers',
-  'features/dashboard/panelSrv',
+  'features/panel/panelSrv',
   'panels/graph/module'
   'panels/graph/module'
 ], function(helpers) {
 ], function(helpers) {
   'use strict';
   'use strict';