diff --git a/src/app/app.js b/src/app/app.js
index 31f3f78e593..c7b7ffc69a4 100644
--- a/src/app/app.js
+++ b/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;
});
diff --git a/src/app/controllers/graphiteTarget.js b/src/app/controllers/graphiteTarget.js
index 37e760d63a2..71edbdfaed7 100644
--- a/src/app/controllers/graphiteTarget.js
+++ b/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("" + this.value + "");
+ this.html = $sce.trustAsHtml("" + options.value + "");
}
else {
this.html = $sce.trustAsHtml(this.value);
diff --git a/src/app/controllers/panelBaseCtrl.js b/src/app/controllers/panelBaseCtrl.js
deleted file mode 100644
index 3ea05611cfd..00000000000
--- a/src/app/controllers/panelBaseCtrl.js
+++ /dev/null
@@ -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;
-
-});
diff --git a/src/app/directives/grafanaPanel.js b/src/app/directives/grafanaPanel.js
index f962c1634f8..14b6b71124d 100644
--- a/src/app/directives/grafanaPanel.js
+++ b/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 = '
';
var content = '';
@@ -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) {
};
});
-});
\ No newline at end of file
+});
diff --git a/src/app/panels/graph/module.html b/src/app/panels/graph/module.html
index f414b19bd79..a61a632dd8e 100644
--- a/src/app/panels/graph/module.html
+++ b/src/app/panels/graph/module.html
@@ -1,5 +1,4 @@
diff --git a/src/app/panels/graph/module.js b/src/app/panels/graph/module.js
index 83da216b8d8..2e69235f4b5 100644
--- a/src/app/panels/graph/module.js
+++ b/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();
});
});
diff --git a/src/app/panels/text/module.html b/src/app/panels/text/module.html
index 5fd3733cb50..c0455d849a5 100644
--- a/src/app/panels/text/module.html
+++ b/src/app/panels/text/module.html
@@ -1,4 +1,4 @@
-
+
diff --git a/src/app/panels/text/module.js b/src/app/panels/text/module.js
index 5127896e4cb..a9ea95d298f 100644
--- a/src/app/panels/text/module.js
+++ b/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();
});
});
diff --git a/src/app/partials/graphite/editor.html b/src/app/partials/graphite/editor.html
index 8d0a957db15..a3805c7fd9a 100755
--- a/src/app/partials/graphite/editor.html
+++ b/src/app/partials/graphite/editor.html
@@ -41,7 +41,7 @@
-
+
diff --git a/src/app/partials/influxdb/editor.html b/src/app/partials/influxdb/editor.html
index b5f27372a82..8bc3baf8ff7 100644
--- a/src/app/partials/influxdb/editor.html
+++ b/src/app/partials/influxdb/editor.html
@@ -25,7 +25,7 @@
-
+
diff --git a/src/app/partials/metrics.html b/src/app/partials/metrics.html
index 1a5d6ed5d1d..7478890b925 100644
--- a/src/app/partials/metrics.html
+++ b/src/app/partials/metrics.html
@@ -2,14 +2,14 @@
-
+
diff --git a/src/app/partials/opentsdb/editor.html b/src/app/partials/opentsdb/editor.html
index 797e7c0fa72..bce27f230f2 100644
--- a/src/app/partials/opentsdb/editor.html
+++ b/src/app/partials/opentsdb/editor.html
@@ -24,7 +24,7 @@
-
+
diff --git a/src/app/services/all.js b/src/app/services/all.js
index 7f00219dbca..a9462629f5d 100644
--- a/src/app/services/all.js
+++ b/src/app/services/all.js
@@ -2,6 +2,7 @@ define([
'./alertSrv',
'./datasourceSrv',
'./filterSrv',
+ './panelSrv',
'./timer',
'./panelMove',
'./keyboardManager',
diff --git a/src/app/services/panelSrv.js b/src/app/services/panelSrv.js
new file mode 100644
index 00000000000..496b4586857
--- /dev/null
+++ b/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);
+ };
+ });
+
+});
diff --git a/src/index.html b/src/index.html
index 5e3bc08309e..ce39254ebfd 100644
--- a/src/index.html
+++ b/src/index.html
@@ -14,7 +14,7 @@
-
+
diff --git a/src/test/karma.conf.js b/src/test/karma.conf.js
index 79dc674ff24..042a056f97b 100644
--- a/src/test/karma.conf.js
+++ b/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,
diff --git a/src/test/test-main.js b/src/test/test-main.js
index 609a4563a58..1cc8036c0c9 100644
--- a/src/test/test-main.js
+++ b/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';