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

Refactoring base panel features, trying to get controller unit tests to work

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

+ 35 - 34
src/app/app.js

@@ -78,42 +78,43 @@ function (angular, $, _, appLevelRequire, config) {
     apps_deps.push(module_name);
   });
 
-  // load the core components
-  require([
-    'controllers/all',
-    'directives/all',
-    'filters/all',
-    'components/partials',
-    'routes/all',
-  ], function () {
+  app.boot = function() {
+    require([
+      'controllers/all',
+      'directives/all',
+      'filters/all',
+      'components/partials',
+      'routes/all',
+    ], function () {
 
-    // bootstrap the app
-    angular
-      .element(document)
-      .ready(function() {
-        angular.bootstrap(document, apps_deps)
-          .invoke(['$rootScope', function ($rootScope) {
-            _.each(pre_boot_modules, function (module) {
-              _.extend(module, register_fns);
-            });
-            pre_boot_modules = false;
-
-            $rootScope.requireContext = appLevelRequire;
-            $rootScope.require = function (deps, fn) {
-              var $scope = this;
-              $scope.requireContext(deps, function () {
-                var deps = _.toArray(arguments);
-                // Check that this is a valid scope.
-                if($scope.$id) {
-                  $scope.$apply(function () {
-                    fn.apply($scope, deps);
-                  });
-                }
+      // bootstrap the app
+      angular
+        .element(document)
+        .ready(function() {
+          angular.bootstrap(document, apps_deps)
+            .invoke(['$rootScope', function ($rootScope) {
+              _.each(pre_boot_modules, function (module) {
+                _.extend(module, register_fns);
               });
-            };
-          }]);
-      });
-  });
+              pre_boot_modules = false;
+
+              $rootScope.requireContext = appLevelRequire;
+              $rootScope.require = function (deps, fn) {
+                var $scope = this;
+                $scope.requireContext(deps, function () {
+                  var deps = _.toArray(arguments);
+                  // Check that this is a valid scope.
+                  if($scope.$id) {
+                    $scope.$apply(function () {
+                      fn.apply($scope, deps);
+                    });
+                  }
+                });
+              };
+            }]);
+        });
+    });
+  };
 
   return app;
 });

+ 1 - 2
src/app/controllers/graphiteTarget.js

@@ -289,8 +289,7 @@ function (angular, _, config, gfunc, Parser) {
       this.expandable = options.expandable;
 
       if (options.type === 'template') {
-        this.value = '[[' + options.value + ']]';
-        this.html = $sce.trustAsHtml("<span style='color: #ECEC09'>" + this.value + "</span>");
+        this.html = $sce.trustAsHtml("<span style='color: #ECEC09'>" + options.value + "</span>");
       }
       else {
         this.html = $sce.trustAsHtml(this.value);

+ 0 - 138
src/app/controllers/panelBaseCtrl.js

@@ -1,138 +0,0 @@
-define([
-  'angular',
-  'underscore',
-  'jquery'
-],
-function (angular, _, $) {
-  'use strict';
-
-  // This function needs $inject annotations, update below
-  // when changing arguments to this function
-  function PanelBaseCtrl($scope, $rootScope, $timeout) {
-
-    if (!$scope.panel.span) {
-      $scope.panel.span = 12;
-    }
-
-    var menu = [
-      {
-        text: 'Edit',
-        configModal: "app/partials/paneleditor.html",
-        condition: !$scope.panelMeta.fullscreenEdit
-      },
-      {
-        text: 'Edit',
-        click: "toggleFullscreenEdit()",
-        condition: $scope.panelMeta.fullscreenEdit
-      },
-      {
-        text: "Fullscreen",
-        click: 'toggleFullscreen()',
-        condition: $scope.panelMeta.fullscreenView
-      },
-      {
-        text: 'Duplicate',
-        click: 'duplicatePanel(panel)',
-        condition: true
-      },
-      {
-        text: 'Span',
-        submenu: [
-          { text: '1', click: 'updateColumnSpan(1)' },
-          { text: '2', click: 'updateColumnSpan(2)' },
-          { text: '3', click: 'updateColumnSpan(3)' },
-          { text: '4', click: 'updateColumnSpan(4)' },
-          { text: '5', click: 'updateColumnSpan(5)' },
-          { text: '6', click: 'updateColumnSpan(6)' },
-          { text: '7', click: 'updateColumnSpan(7)' },
-          { text: '8', click: 'updateColumnSpan(8)' },
-          { text: '9', click: 'updateColumnSpan(9)' },
-          { text: '10', click: 'updateColumnSpan(10)' },
-          { text: '11', click: 'updateColumnSpan(11)' },
-          { text: '12', click: 'updateColumnSpan(12)' },
-        ],
-        condition: true
-      },
-      {
-        text: 'Remove',
-        click: 'remove_panel_from_row(row, panel)',
-        condition: true
-      }
-    ];
-
-    $scope.inspector = {};
-    $scope.panelMeta.menu = _.where(menu, { condition: true });
-
-    $scope.updateColumnSpan = function(span) {
-      $scope.panel.span = span;
-
-      $timeout(function() {
-        $scope.$emit('render');
-      });
-    };
-
-    $scope.enterFullscreenMode = function(options) {
-      var docHeight = $(window).height();
-      var editHeight = Math.floor(docHeight * 0.3);
-      var fullscreenHeight = Math.floor(docHeight * 0.7);
-      var oldTimeRange = $scope.range;
-
-      $scope.height = options.edit ? editHeight : fullscreenHeight;
-      $scope.editMode = options.edit;
-
-      if (!$scope.fullscreen) {
-        var closeEditMode = $rootScope.$on('panel-fullscreen-exit', function() {
-          $scope.editMode = false;
-          $scope.fullscreen = false;
-          delete $scope.height;
-
-          closeEditMode();
-
-          $timeout(function() {
-            if (oldTimeRange !== $scope.range) {
-              $scope.dashboard.emit_refresh();
-            }
-            else {
-              $scope.$emit('render');
-            }
-          });
-        });
-      }
-
-      $(window).scrollTop(0);
-
-      $scope.fullscreen = true;
-
-      $rootScope.$emit('panel-fullscreen-enter');
-
-      $timeout(function() {
-        $scope.$emit('render');
-      });
-
-    };
-
-    $scope.toggleFullscreenEdit = function() {
-      if ($scope.editMode) {
-        $rootScope.$emit('panel-fullscreen-exit');
-        return;
-      }
-
-      $scope.enterFullscreenMode({edit: true});
-    };
-
-    $scope.toggleFullscreen = function() {
-      if ($scope.fullscreen && !$scope.editMode) {
-        $rootScope.$emit('panel-fullscreen-exit');
-        return;
-      }
-
-      $scope.enterFullscreenMode({ edit: false });
-    };
-
-  }
-
-  PanelBaseCtrl['$inject'] = ['$scope', '$rootScope', '$timeout'];
-
-  return PanelBaseCtrl;
-
-});

+ 3 - 8
src/app/directives/grafanaPanel.js

@@ -2,14 +2,13 @@ define([
   'angular',
   'jquery',
   'underscore',
-  '../controllers/panelBaseCtrl'
 ],
-function (angular, $, _, PanelBaseCtrl) {
+function (angular, $) {
   'use strict';
 
   angular
     .module('grafana.directives')
-    .directive('grafanaPanel', function($compile, $timeout, $rootScope, $injector) {
+    .directive('grafanaPanel', function($compile) {
 
       var container = '<div class="panel-container"></div>';
       var content = '<div class="panel-content"></div>';
@@ -80,10 +79,6 @@ function (angular, $, _, PanelBaseCtrl) {
             elem.remove();
           });
 
-          newScope.initBaseController = function(self, scope) {
-            $injector.invoke(PanelBaseCtrl, self, { $scope: scope });
-          };
-
           $scope.$watch(attr.type, function (name) {
             elem.addClass("ng-cloak");
             // load the panels module file, then render it in the dom.
@@ -115,4 +110,4 @@ function (angular, $, _, PanelBaseCtrl) {
       };
     });
 
-});
+});

+ 0 - 1
src/app/panels/graph/module.html

@@ -1,5 +1,4 @@
 <div  ng-controller='graph'
-      ng-init="init()"
       style="min-height:{{panel.height || row.height}}"
       ng-class="{'panel-fullscreen': fullscreen}">
 

+ 4 - 35
src/app/panels/graph/module.js

@@ -35,7 +35,7 @@ function (angular, app, $, _, kbn, moment, timeSeries) {
   var module = angular.module('grafana.panels.graph', []);
   app.useModule(module);
 
-  module.controller('graph', function($scope, $rootScope, datasourceSrv, $timeout, annotationsSrv) {
+  module.controller('graph', function($scope, $rootScope, $timeout, panelSrv, annotationsSrv) {
 
     $scope.panelMeta = {
       modals : [],
@@ -175,7 +175,7 @@ function (angular, app, $, _, kbn, moment, timeSeries) {
         query_as_alias: true
       },
 
-      targets: [],
+      targets: [{}],
 
       aliasColors: {},
       aliasYAxis: {},
@@ -188,35 +188,8 @@ function (angular, app, $, _, kbn, moment, timeSeries) {
     _.defaults($scope.panel.legend, _d.legend);
 
     $scope.init = function() {
-      $scope.initBaseController(this, $scope);
-
-      $scope.fullscreen = false;
-      $scope.editor = { index: 1 };
-      $scope.editorTabs = _.pluck($scope.panelMeta.fullEditorTabs,'title');
+      panelSrv.init($scope);
       $scope.hiddenSeries = {};
-
-      $scope.datasources = datasourceSrv.getMetricSources();
-      $scope.setDatasource($scope.panel.datasource);
-
-      if ($scope.panel.targets.length === 0) {
-        $scope.panel.targets.push({});
-      }
-    };
-
-    $scope.setDatasource = function(datasource) {
-      $scope.panel.datasource = datasource;
-      $scope.datasource = datasourceSrv.get(datasource);
-
-      if (!$scope.datasource) {
-        $scope.panel.error = "Cannot find datasource " + datasource;
-        return;
-      }
-
-      $scope.get_data();
-    };
-
-    $scope.removeTarget = function (target) {
-      $scope.panel.targets = _.without($scope.panel.targets, target);
       $scope.get_data();
     };
 
@@ -246,7 +219,6 @@ function (angular, app, $, _, kbn, moment, timeSeries) {
         targets: $scope.panel.targets,
         format: $scope.panel.renderer === 'png' ? 'png' : 'json',
         maxDataPoints: $scope.resolution,
-        datasource: $scope.panel.datasource,
         cacheTimeout: $scope.panel.cacheTimeout
       };
 
@@ -322,10 +294,6 @@ function (angular, app, $, _, kbn, moment, timeSeries) {
       return series;
     };
 
-    $scope.add_target = function() {
-      $scope.panel.targets.push({target: ''});
-    };
-
     $scope.otherPanelInFullscreenMode = function() {
       return $rootScope.fullscreen && !$scope.fullscreen;
     };
@@ -400,6 +368,7 @@ function (angular, app, $, _, kbn, moment, timeSeries) {
       $scope.render();
     };
 
+    $scope.init();
   });
 
 });

+ 1 - 1
src/app/panels/text/module.html

@@ -1,4 +1,4 @@
-<div ng-controller='text' ng-init="init()" style="min-height:{{panel.height || row.height}}">
+<div ng-controller='text' style="min-height:{{panel.height || row.height}}">
   <p ng-bind-html="content">
   </p>
 </div>

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

@@ -23,7 +23,7 @@ function (angular, app, _, require) {
   var module = angular.module('grafana.panels.text', []);
   app.useModule(module);
 
-  module.controller('text', function($scope, filterSrv, $sce) {
+  module.controller('text', function($scope, filterSrv, $sce, panelSrv) {
 
     $scope.panelMeta = {
       description : "A static text panel that can use plain text, markdown, or (sanitized) HTML"
@@ -39,7 +39,7 @@ function (angular, app, _, require) {
     _.defaults($scope.panel, _d);
 
     $scope.init = function() {
-      $scope.initBaseController(this, $scope);
+      panelSrv.init(this);
       $scope.ready = false;
       $scope.$on('refresh', $scope.render);
       $scope.render();
@@ -93,5 +93,6 @@ function (angular, app, _, require) {
     $scope.openEditor = function() {
     };
 
+    $scope.init();
   });
 });

+ 1 - 1
src/app/partials/graphite/editor.html

@@ -41,7 +41,7 @@
           </ul>
         </li>
         <li>
-          <a class="pointer" tabindex="1" ng-click="removeTarget(target)">
+          <a class="pointer" tabindex="1" ng-click="removeDataQuery(target)">
             <i class="icon-remove"></i>
           </a>
         </li>

+ 1 - 1
src/app/partials/influxdb/editor.html

@@ -25,7 +25,7 @@
            </ul>
           </li>
           <li>
-            <a class="pointer" tabindex="1" ng-click="removeTarget(target)">
+            <a class="pointer" tabindex="1" ng-click="removeDataQuery(target)">
               <i class="icon-remove"></i>
             </a>
           </li>

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

@@ -2,14 +2,14 @@
 
 
 <div class="editor-row" style="margin-top: 30px">
-  <button class="btn btn-success pull-right" ng-click="add_target(panel.target)">Add query</button>
+  <button class="btn btn-success pull-right" ng-click="addDataQuery(panel.target)">Add query</button>
 
   <div class="btn-group pull-right" style="margin-right: 10px;">
     <button class="btn btn-info dropdown-toggle" data-toggle="dropdown" bs-tooltip="'Datasource'">{{datasource.name}} <span class="caret"></span></button>
 
     <ul class="dropdown-menu" role="menu">
       <li ng-repeat="datasource in datasources" role="menuitem">
-        <a ng-click="setDatasource(datasource.value);">{{datasource.name}}</a>
+        <a ng-click="changeDatasource(datasource.value);">{{datasource.name}}</a>
       </li>
     </ul>
   </div>

+ 1 - 1
src/app/partials/opentsdb/editor.html

@@ -24,7 +24,7 @@
             </ul>
           </li>
           <li>
-            <a class="pointer" tabindex="1" ng-click="removeTarget(target)">
+            <a class="pointer" tabindex="1" ng-click="removeDataQuery(target)">
               <i class="icon-remove"></i>
             </a>
           </li>

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

@@ -2,6 +2,7 @@ define([
   './alertSrv',
   './datasourceSrv',
   './filterSrv',
+  './panelSrv',
   './timer',
   './panelMove',
   './keyboardManager',

+ 168 - 0
src/app/services/panelSrv.js

@@ -0,0 +1,168 @@
+define([
+  'angular',
+  'underscore',
+  'jquery',
+],
+function (angular, _, $) {
+  'use strict';
+
+  var module = angular.module('grafana.services');
+  module.service('panelSrv', function($rootScope, $timeout, datasourceSrv) {
+
+    this.init = function($scope) {
+      if (!$scope.panel.span) {
+        $scope.panel.span = 12;
+      }
+
+      var menu = [
+        {
+          text: 'Edit',
+          configModal: "app/partials/paneleditor.html",
+          condition: !$scope.panelMeta.fullscreenEdit
+        },
+        {
+          text: 'Edit',
+          click: "toggleFullscreenEdit()",
+          condition: $scope.panelMeta.fullscreenEdit
+        },
+        {
+          text: "Fullscreen",
+          click: 'toggleFullscreen()',
+          condition: $scope.panelMeta.fullscreenView
+        },
+        {
+          text: 'Duplicate',
+          click: 'duplicatePanel(panel)',
+          condition: true
+        },
+        {
+          text: 'Span',
+          submenu: [
+            { text: '1', click: 'updateColumnSpan(1)' },
+            { text: '2', click: 'updateColumnSpan(2)' },
+            { text: '3', click: 'updateColumnSpan(3)' },
+            { text: '4', click: 'updateColumnSpan(4)' },
+            { text: '5', click: 'updateColumnSpan(5)' },
+            { text: '6', click: 'updateColumnSpan(6)' },
+            { text: '7', click: 'updateColumnSpan(7)' },
+            { text: '8', click: 'updateColumnSpan(8)' },
+            { text: '9', click: 'updateColumnSpan(9)' },
+            { text: '10', click: 'updateColumnSpan(10)' },
+            { text: '11', click: 'updateColumnSpan(11)' },
+            { text: '12', click: 'updateColumnSpan(12)' },
+          ],
+          condition: true
+        },
+        {
+          text: 'Remove',
+          click: 'remove_panel_from_row(row, panel)',
+          condition: true
+        }
+      ];
+
+      $scope.inspector = {};
+      $scope.panelMeta.menu = _.where(menu, { condition: true });
+
+      $scope.updateColumnSpan = function(span) {
+        $scope.panel.span = span;
+
+        $timeout(function() {
+          $scope.$emit('render');
+        });
+      };
+
+      $scope.enterFullscreenMode = function(options) {
+        var docHeight = $(window).height();
+        var editHeight = Math.floor(docHeight * 0.3);
+        var fullscreenHeight = Math.floor(docHeight * 0.7);
+        var oldTimeRange = $scope.range;
+
+        $scope.height = options.edit ? editHeight : fullscreenHeight;
+        $scope.editMode = options.edit;
+
+        if (!$scope.fullscreen) {
+          var closeEditMode = $rootScope.$on('panel-fullscreen-exit', function() {
+            $scope.editMode = false;
+            $scope.fullscreen = false;
+            delete $scope.height;
+
+            closeEditMode();
+
+            $timeout(function() {
+              if (oldTimeRange !== $scope.range) {
+                $scope.dashboard.emit_refresh();
+              }
+              else {
+                $scope.$emit('render');
+              }
+            });
+          });
+        }
+
+        $(window).scrollTop(0);
+
+        $scope.fullscreen = true;
+
+        $rootScope.$emit('panel-fullscreen-enter');
+
+        $timeout(function() {
+          $scope.$emit('render');
+        });
+
+      };
+
+      $scope.addDataQuery = function() {
+        $scope.panel.targets.push({target: ''});
+      };
+
+      $scope.removeDataQuery = function (query) {
+        $scope.panel.targets = _.without($scope.panel.targets, query);
+        $scope.get_data();
+      };
+
+      $scope.setDatasource = function(datasource) {
+        $scope.panel.datasource = datasource;
+        $scope.datasource = datasourceSrv.get(datasource);
+
+        if (!$scope.datasource) {
+          $scope.panel.error = "Cannot find datasource " + datasource;
+          return;
+        }
+      };
+
+      $scope.changeDatasource = function(datasource) {
+        $scope.setDatasource(datasource);
+        $scope.get_data();
+      };
+
+      $scope.toggleFullscreenEdit = function() {
+        if ($scope.editMode) {
+          $rootScope.$emit('panel-fullscreen-exit');
+          return;
+        }
+
+        $scope.enterFullscreenMode({edit: true});
+      };
+
+      $scope.toggleFullscreen = function() {
+        if ($scope.fullscreen && !$scope.editMode) {
+          $rootScope.$emit('panel-fullscreen-exit');
+          return;
+        }
+
+        $scope.enterFullscreenMode({ edit: false });
+      };
+
+      // Post init phase
+      $scope.fullscreen = false;
+      $scope.editor = { index: 1 };
+      if ($scope.panelMeta.fullEditorTabs) {
+        $scope.editorTabs = _.pluck($scope.panelMeta.fullEditorTabs, 'title');
+      }
+
+      $scope.datasources = datasourceSrv.getMetricSources();
+      $scope.setDatasource($scope.panel.datasource);
+    };
+  });
+
+});

+ 1 - 1
src/index.html

@@ -14,7 +14,7 @@
     <script src="app/components/require.config.js"></script>
     <!-- endbuild -->
 
-    <script>require(['app'], function () {})</script>
+    <script>require(['app'], function (app) { app.boot(); })</script>
 
   </head>
 

+ 1 - 1
src/test/karma.conf.js

@@ -18,7 +18,7 @@ module.exports = function(config) {
     // list of files to exclude
     exclude: [],
 
-    reporters: ['progress'],
+    reporters: ['dots'],
     port: 9876,
     colors: true,
     logLevel: config.LOG_INFO,

+ 8 - 9
src/test/test-main.js

@@ -1,5 +1,11 @@
+for (var file in window.__karma__.files) {
+  if (/spec\.js$/.test(file)) {
+    tests.push(file.replace(/^\/base\//, 'http://localhost:9876/base/'));
+  }
+}
+
 require.config({
-  baseUrl: 'base/app',
+  baseUrl: 'http://localhost:9876/base/app',
 
   paths: {
     specs:                 '../test/specs',
@@ -101,15 +107,8 @@ require.config({
 
 require([
   'angular',
-  'angular-route',
   'angularMocks',
-  'jquery',
-  'underscore',
-  'bootstrap',
-  'angular-strap',
-  'angular-dragdrop',
-  'extend-jquery',
-  'bindonce'
+  'app',
 ], function(angular) {
   'use strict';