Przeglądaj źródła

continued large refactoring of filterSrv, timeSrv and templating

Torkel Ödegaard 11 lat temu
rodzic
commit
9ee4fcb36c

+ 0 - 7
src/app/controllers/dashboardCtrl.js

@@ -41,8 +41,6 @@ function (angular, $, config, _) {
     };
     };
 
 
     $scope.setupDashboard = function(event, dashboardData) {
     $scope.setupDashboard = function(event, dashboardData) {
-      timer.cancel_all();
-
       $rootScope.performance.dashboardLoadStart = new Date().getTime();
       $rootScope.performance.dashboardLoadStart = new Date().getTime();
       $rootScope.performance.panelsInitialized = 0;
       $rootScope.performance.panelsInitialized = 0;
       $rootScope.performance.panelsRendered= 0;
       $rootScope.performance.panelsRendered= 0;
@@ -67,11 +65,6 @@ function (angular, $, config, _) {
 
 
       window.document.title = config.window_title_prefix + $scope.dashboard.title;
       window.document.title = config.window_title_prefix + $scope.dashboard.title;
 
 
-      // start auto refresh
-      if($scope.dashboard.refresh) {
-        $scope.dashboard.set_interval($scope.dashboard.refresh);
-      }
-
       dashboardKeybindings.shortcuts($scope);
       dashboardKeybindings.shortcuts($scope);
 
 
       $scope.emitAppEvent("dashboard-loaded", $scope.dashboard);
       $scope.emitAppEvent("dashboard-loaded", $scope.dashboard);

+ 6 - 57
src/app/controllers/submenuCtrl.js

@@ -8,7 +8,7 @@ function (angular, app, _) {
 
 
   var module = angular.module('grafana.controllers');
   var module = angular.module('grafana.controllers');
 
 
-  module.controller('SubmenuCtrl', function($scope, $q, $rootScope, datasourceSrv) {
+  module.controller('SubmenuCtrl', function($scope, $q, $rootScope, templateValuesSrv) {
     var _d = {
     var _d = {
       enable: true
       enable: true
     };
     };
@@ -18,62 +18,7 @@ function (angular, app, _) {
     $scope.init = function() {
     $scope.init = function() {
       $scope.panel = $scope.pulldown;
       $scope.panel = $scope.pulldown;
       $scope.row = $scope.pulldown;
       $scope.row = $scope.pulldown;
-    };
-
-    $scope.filterOptionSelected = function(templateParameter, option, recursive) {
-      templateParameter.current = option;
-
-      $scope.filter.updateTemplateData();
-
-      return $scope.applyFilterToOtherFilters(templateParameter)
-        .then(function() {
-          // only refresh in the outermost call
-          if (!recursive) {
-            $scope.dashboard.emit_refresh();
-          }
-        });
-    };
-
-    $scope.applyFilterToOtherFilters = function(updatedTemplatedParam) {
-      var promises = _.map($scope.filter.templateParameters, function(templateParam) {
-        if (templateParam === updatedTemplatedParam) {
-          return;
-        }
-        if (templateParam.query.indexOf('[[' + updatedTemplatedParam.name + ']]') !== -1) {
-          return $scope.applyFilter(templateParam);
-        }
-      });
-
-      return $q.all(promises);
-    };
-
-    $scope.applyFilter = function(templateParam) {
-      return datasourceSrv.default.metricFindQuery($scope.filter, templateParam.query)
-        .then(function (results) {
-          templateParam.options = _.map(results, function(node) {
-            return { text: node.text, value: node.text };
-          });
-
-          if (templateParam.includeAll) {
-            var allExpr = '{';
-            _.each(templateParam.options, function(option) {
-              allExpr += option.text + ',';
-            });
-            allExpr = allExpr.substring(0, allExpr.length - 1) + '}';
-            templateParam.options.unshift({text: 'All', value: allExpr});
-          }
-
-          // if parameter has current value
-          // if it exists in options array keep value
-          if (templateParam.current) {
-            var currentExists = _.findWhere(templateParam.options, { value: templateParam.current.value });
-            if (currentExists) {
-              return $scope.filterOptionSelected(templateParam, templateParam.current, true);
-            }
-          }
-
-          return $scope.filterOptionSelected(templateParam, templateParam.options[0], true);
-        });
+      $scope.templateParameters = $scope.dashboard.templating.list;
     };
     };
 
 
     $scope.disableAnnotation = function (annotation) {
     $scope.disableAnnotation = function (annotation) {
@@ -81,6 +26,10 @@ function (angular, app, _) {
       $rootScope.$broadcast('refresh');
       $rootScope.$broadcast('refresh');
     };
     };
 
 
+    $scope.filterOptionSelected = function(param, option) {
+      templateValuesSrv.filterOptionSelected(param, option);
+    };
+
     $scope.init();
     $scope.init();
 
 
   });
   });

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

@@ -12,7 +12,7 @@ function (angular, app, _, require) {
 
 
   var converter;
   var converter;
 
 
-  module.controller('text', function($scope, filterSrv, $sce, panelSrv) {
+  module.controller('text', function($scope, templateSrv, $sce, panelSrv) {
 
 
     $scope.panelMeta = {
     $scope.panelMeta = {
       description : "A static text panel that can use plain text, markdown, or (sanitized) HTML"
       description : "A static text panel that can use plain text, markdown, or (sanitized) HTML"
@@ -75,7 +75,7 @@ function (angular, app, _, require) {
 
 
     $scope.updateContent = function(html) {
     $scope.updateContent = function(html) {
       try {
       try {
-        $scope.content = $sce.trustAsHtml(filterSrv.applyTemplateToTarget(html));
+        $scope.content = $sce.trustAsHtml(templateSrv.replace(html));
       } catch(e) {
       } catch(e) {
         console.log('Text panel error: ', e);
         console.log('Text panel error: ', e);
         $scope.content = $sce.trustAsHtml(html);
         $scope.content = $sce.trustAsHtml(html);

+ 3 - 3
src/app/panels/timepicker/module.html

@@ -32,10 +32,10 @@
             <a href="#">Auto-Refresh</a>
             <a href="#">Auto-Refresh</a>
             <ul class="dropdown-menu">
             <ul class="dropdown-menu">
               <li>
               <li>
-                <a ng-click="dashboard.set_interval(false)">Off</a>
+                <a ng-click="timeSrv.set_interval(false)">Off</a>
               </li>
               </li>
               <li bindonce ng-repeat="interval in panel.refresh_intervals track by $index">
               <li bindonce ng-repeat="interval in panel.refresh_intervals track by $index">
-                <a ng-click="dashboard.set_interval(interval)" bo-text="'Every ' + interval"></a>
+                <a ng-click="timeSrv.set_interval(interval)" bo-text="'Every ' + interval"></a>
               </li>
               </li>
             </ul>
             </ul>
           </li>
           </li>
@@ -44,7 +44,7 @@
 
 
       </li>
       </li>
       <li ng-show="!dashboard.refresh" class="grafana-menu-refresh">
       <li ng-show="!dashboard.refresh" class="grafana-menu-refresh">
-        <a ng-click="dashboard.emit_refresh()"><i class="icon-refresh"></i></a>
+        <a ng-click="timeSrv.refreshDashboard()"><i class="icon-refresh"></i></a>
       </li>
       </li>
     </ul>
     </ul>
 
 

+ 3 - 1
src/app/panels/timepicker/module.js

@@ -25,7 +25,7 @@ function (angular, app, _, moment, kbn) {
   var module = angular.module('grafana.panels.timepicker', []);
   var module = angular.module('grafana.panels.timepicker', []);
   app.useModule(module);
   app.useModule(module);
 
 
-  module.controller('timepicker', function($scope, timeSrv) {
+  module.controller('timepicker', function($scope, $rootScope, timeSrv) {
 
 
     $scope.panelMeta = {
     $scope.panelMeta = {
       status  : "Stable",
       status  : "Stable",
@@ -50,6 +50,8 @@ function (angular, app, _, moment, kbn) {
       millisecond: /^[0-9]*$/
       millisecond: /^[0-9]*$/
     };
     };
 
 
+    $scope.timeSrv = timeSrv;
+
     $scope.$on('refresh', function() {
     $scope.$on('refresh', function() {
       $scope.init();
       $scope.init();
     });
     });

+ 1 - 1
src/app/partials/submenu.html

@@ -18,7 +18,7 @@
 					</ul>
 					</ul>
 
 
 					<ul class="grafana-segment-list">
 					<ul class="grafana-segment-list">
-						<li ng-repeat-start="param in filter.templateParameters" class="grafana-target-segment template-param-name">
+						<li ng-repeat-start="param in templateParameters" class="grafana-target-segment template-param-name">
 							{{param.name}}:
 							{{param.name}}:
 						</li>
 						</li>
 
 

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

@@ -3,6 +3,7 @@ define([
   './datasourceSrv',
   './datasourceSrv',
   './timeSrv',
   './timeSrv',
   './templateSrv',
   './templateSrv',
+  './templateValuesSrv',
   './panelSrv',
   './panelSrv',
   './timer',
   './timer',
   './panelMove',
   './panelMove',

+ 1 - 23
src/app/services/dashboard/dashboardSrv.js

@@ -11,7 +11,7 @@ function (angular, $, kbn, _, moment) {
 
 
   var module = angular.module('grafana.services');
   var module = angular.module('grafana.services');
 
 
-  module.factory('dashboardSrv', function(timer, $rootScope, $timeout) {
+  module.factory('dashboardSrv', function($rootScope)  {
 
 
     function DashboardModel (data) {
     function DashboardModel (data) {
 
 
@@ -115,28 +115,6 @@ function (angular, $, kbn, _, moment) {
       $rootScope.$broadcast('refresh');
       $rootScope.$broadcast('refresh');
     };
     };
 
 
-    p.start_scheduled_refresh = function (after_ms) {
-      this.cancel_scheduled_refresh();
-      this.refresh_timer = timer.register($timeout(function () {
-        this.start_scheduled_refresh(after_ms);
-        this.emit_refresh();
-      }.bind(this), after_ms));
-    };
-
-    p.cancel_scheduled_refresh = function () {
-      timer.cancel(this.refresh_timer);
-    };
-
-    p.set_interval = function (interval) {
-      this.refresh = interval;
-      if (interval) {
-        var _i = kbn.interval_to_ms(interval);
-        this.start_scheduled_refresh(_i);
-      } else {
-        this.cancel_scheduled_refresh();
-      }
-    };
-
     p.updateSchema = function(old) {
     p.updateSchema = function(old) {
       var oldVersion = this.version;
       var oldVersion = this.version;
       var panelUpgrades = [];
       var panelUpgrades = [];

+ 6 - 6
src/app/services/graphite/graphiteDatasource.js

@@ -11,7 +11,7 @@ function (angular, _, $, config, kbn, moment) {
 
 
   var module = angular.module('grafana.services');
   var module = angular.module('grafana.services');
 
 
-  module.factory('GraphiteDatasource', function($q, $http, timeSrv) {
+  module.factory('GraphiteDatasource', function($q, $http, templateSrv) {
 
 
     function GraphiteDatasource(datasource) {
     function GraphiteDatasource(datasource) {
       this.type = 'graphite';
       this.type = 'graphite';
@@ -63,7 +63,7 @@ function (angular, _, $, config, kbn, moment) {
     GraphiteDatasource.prototype.annotationQuery = function(annotation, rangeUnparsed) {
     GraphiteDatasource.prototype.annotationQuery = function(annotation, rangeUnparsed) {
       // Graphite metric as annotation
       // Graphite metric as annotation
       if (annotation.target) {
       if (annotation.target) {
-        var target = timeSrv.applyTemplateToTarget(annotation.target);
+        var target = templateSrv.replace(annotation.target);
         var graphiteQuery = {
         var graphiteQuery = {
           range: rangeUnparsed,
           range: rangeUnparsed,
           targets: [{ target: target }],
           targets: [{ target: target }],
@@ -71,7 +71,7 @@ function (angular, _, $, config, kbn, moment) {
           maxDataPoints: 100
           maxDataPoints: 100
         };
         };
 
 
-        return this.query(timeSrv, graphiteQuery)
+        return this.query(graphiteQuery)
           .then(function(result) {
           .then(function(result) {
             var list = [];
             var list = [];
 
 
@@ -95,7 +95,7 @@ function (angular, _, $, config, kbn, moment) {
       }
       }
       // Graphite event as annotation
       // Graphite event as annotation
       else {
       else {
-        var tags = timeSrv.applyTemplateToTarget(annotation.tags);
+        var tags = templateSrv.replace(annotation.tags);
         return this.events({ range: rangeUnparsed, tags: tags })
         return this.events({ range: rangeUnparsed, tags: tags })
           .then(function(results) {
           .then(function(results) {
             var list = [];
             var list = [];
@@ -169,7 +169,7 @@ function (angular, _, $, config, kbn, moment) {
     GraphiteDatasource.prototype.metricFindQuery = function(query) {
     GraphiteDatasource.prototype.metricFindQuery = function(query) {
       var interpolated;
       var interpolated;
       try {
       try {
-        interpolated = encodeURIComponent(timeSrv.applyTemplateToTarget(query));
+        interpolated = encodeURIComponent(templateSrv.replace(query));
       }
       }
       catch(err) {
       catch(err) {
         return $q.reject(err);
         return $q.reject(err);
@@ -226,7 +226,7 @@ function (angular, _, $, config, kbn, moment) {
         if (key === "targets") {
         if (key === "targets") {
           _.each(value, function (value) {
           _.each(value, function (value) {
             if (value.target && !value.hide) {
             if (value.target && !value.hide) {
-              var targetValue = timeSrv.applyTemplateToTarget(value.target);
+              var targetValue = templateSrv.replace(value.target);
               clean_options.push("target=" + encodeURIComponent(targetValue));
               clean_options.push("target=" + encodeURIComponent(targetValue));
             }
             }
           }, this);
           }, this);

+ 5 - 5
src/app/services/influxdb/influxdbDatasource.js

@@ -9,7 +9,7 @@ function (angular, _, kbn, InfluxSeries) {
 
 
   var module = angular.module('grafana.services');
   var module = angular.module('grafana.services');
 
 
-  module.factory('InfluxDatasource', function($q, $http, timeSrv) {
+  module.factory('InfluxDatasource', function($q, $http, templateSrv) {
 
 
     function InfluxDatasource(datasource) {
     function InfluxDatasource(datasource) {
       this.type = 'influxDB';
       this.type = 'influxDB';
@@ -73,7 +73,7 @@ function (angular, _, kbn, InfluxSeries) {
           }
           }
 
 
           query = queryElements.join(" ");
           query = queryElements.join(" ");
-          query = timeSrv.applyTemplateToTarget(query);
+          query = templateSrv.replace(query);
         }
         }
         else {
         else {
 
 
@@ -100,7 +100,7 @@ function (angular, _, kbn, InfluxSeries) {
           }
           }
 
 
           query = _.template(template, templateData, this.templateSettings);
           query = _.template(template, templateData, this.templateSettings);
-          query = timeSrv.applyTemplateToTarget(query);
+          query = templateSrv.replace(query);
 
 
           if (target.groupby_field_add) {
           if (target.groupby_field_add) {
             groupByField = target.groupby_field;
             groupByField = target.groupby_field;
@@ -110,7 +110,7 @@ function (angular, _, kbn, InfluxSeries) {
         }
         }
 
 
         if (target.alias) {
         if (target.alias) {
-          alias = filterSrv.applyTemplateToTarget(target.alias);
+          alias = templateSrv.replace(target.alias);
         }
         }
 
 
         var handleResponse = _.partial(handleInfluxQueryResponse, alias, groupByField);
         var handleResponse = _.partial(handleInfluxQueryResponse, alias, groupByField);
@@ -164,7 +164,7 @@ function (angular, _, kbn, InfluxSeries) {
     InfluxDatasource.prototype.metricFindQuery = function (filterSrv, query) {
     InfluxDatasource.prototype.metricFindQuery = function (filterSrv, query) {
       var interpolated;
       var interpolated;
       try {
       try {
-        interpolated = filterSrv.applyTemplateToTarget(query);
+        interpolated = templateSrv.replace(query);
       }
       }
       catch (err) {
       catch (err) {
         return $q.reject(err);
         return $q.reject(err);

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

@@ -129,13 +129,6 @@ function (angular, _) {
           $scope.get_data();
           $scope.get_data();
         }
         }
       }
       }
-
-      if ($rootScope.profilingEnabled) {
-        $rootScope.performance.panelsInitialized++;
-        if ($rootScope.performance.panelsInitialized === $scope.dashboard.rows.length) {
-          $rootScope.performance.allPanelsInitialized = new Date().getTime();
-        }
-      }
     };
     };
   });
   });
 
 

+ 34 - 2
src/app/services/templateSrv.js

@@ -4,16 +4,48 @@ define([
   'kbn',
   'kbn',
   'store'
   'store'
 ],
 ],
-function (angular) {
+function (angular, _) {
   'use strict';
   'use strict';
 
 
   var module = angular.module('grafana.services');
   var module = angular.module('grafana.services');
 
 
-  module.service('templateSrv', function() {
+  module.service('templateSrv', function($q, $routeParams) {
 
 
     this.init = function(dashboard) {
     this.init = function(dashboard) {
       this.dashboard = dashboard;
       this.dashboard = dashboard;
+      this.templateSettings = { interpolate : /\[\[([\s\S]+?)\]\]/g };
+      this.templateParameters = dashboard.templating.list;
+      this.updateTemplateData(true);
+    };
+
+    this.updateTemplateData = function(initial) {
+      var _templateData = {};
+      _.each(this.templateParameters, function(templateParameter) {
+        if (initial) {
+          var urlValue = $routeParams[ templateParameter.name ];
+          if (urlValue) {
+            templateParameter.current = { text: urlValue, value: urlValue };
+          }
+        }
+        if (!templateParameter.current || !templateParameter.current.value) {
+          return;
+        }
+        _templateData[templateParameter.name] = templateParameter.current.value;
+      });
+      this._templateData = _templateData;
+    };
+
+    this.addTemplateParameter = function(templateParameter) {
+      this.templateParameters.push(templateParameter);
+      this.updateTemplateData();
+    };
+
+    this.replace = function(target) {
+      if (!target || target.indexOf('[[') === -1) {
+        return target;
+      }
 
 
+      return _.template(target, this._templateData, this.templateSettings);
     };
     };
 
 
   });
   });

+ 72 - 0
src/app/services/templateValuesSrv.js

@@ -0,0 +1,72 @@
+define([
+  'angular',
+  'lodash',
+  'kbn',
+  'store'
+],
+function (angular, _) {
+  'use strict';
+
+  var module = angular.module('grafana.services');
+
+  module.service('templateValuesSrv', function($q, $rootScope, datasourceSrv, $routeParams, templateSrv) {
+    var self = this;
+
+    this.filterOptionSelected = function(templateParameter, option, recursive) {
+      templateParameter.current = option;
+
+      templateSrv.updateTemplateData();
+
+      return this.applyFilterToOtherFilters(templateParameter)
+        .then(function() {
+          if (!recursive) {
+            $rootScope.$broadcast('refresh');
+          }
+        });
+    };
+
+    this.applyFilterToOtherFilters = function(updatedTemplatedParam) {
+      var promises = _.map(self.templateParameters, function(templateParam) {
+        if (templateParam === updatedTemplatedParam) {
+          return;
+        }
+        if (templateParam.query.indexOf('[[' + updatedTemplatedParam.name + ']]') !== -1) {
+          return self.applyFilter(templateParam);
+        }
+      });
+
+      return $q.all(promises);
+    };
+
+    this.applyFilter = function(templateParam) {
+      return datasourceSrv.default.metricFindQuery(templateParam.query)
+        .then(function (results) {
+          templateParam.options = _.map(results, function(node) {
+            return { text: node.text, value: node.text };
+          });
+
+          if (templateParam.includeAll) {
+            var allExpr = '{';
+            _.each(templateParam.options, function(option) {
+              allExpr += option.text + ',';
+            });
+            allExpr = allExpr.substring(0, allExpr.length - 1) + '}';
+            templateParam.options.unshift({text: 'All', value: allExpr});
+          }
+
+          // if parameter has current value
+          // if it exists in options array keep value
+          if (templateParam.current) {
+            var currentExists = _.findWhere(templateParam.options, { value: templateParam.current.value });
+            if (currentExists) {
+              return self.filterOptionSelected(templateParam, templateParam.current, true);
+            }
+          }
+
+          return self.filterOptionSelected(templateParam, templateParam.options[0], true);
+        });
+    };
+
+  });
+
+});

+ 72 - 72
src/app/services/timeSrv.js

@@ -8,82 +8,82 @@ define([
 
 
   var module = angular.module('grafana.services');
   var module = angular.module('grafana.services');
 
 
-  module.service('timeSrv', function($rootScope, $timeout, $routeParams) {
+  module.service('timeSrv', function($rootScope, $timeout, timer) {
+    var self = this;
 
 
     this.init = function(dashboard) {
     this.init = function(dashboard) {
-        this.dashboard = dashboard;
-        this.templateSettings = { interpolate : /\[\[([\s\S]+?)\]\]/g };
-        this.time = dashboard.time;
-        this.templateParameters = dashboard.templating.list;
-        this.updateTemplateData(true);
+      timer.cancel_all();
+
+      this.dashboard = dashboard;
+      this.time = dashboard.time;
+
+      if(this.dashboard.refresh) {
+        this.set_interval(this.dashboard.refresh);
+      }
+    };
+
+    this.set_interval = function (interval) {
+      this.dashboard.refresh = interval;
+      if (interval) {
+        var _i = kbn.interval_to_ms(interval);
+        this.start_scheduled_refresh(_i);
+      } else {
+        this.cancel_scheduled_refresh();
+      }
+    };
+
+    this.refreshDashboard = function() {
+      $rootScope.$broadcast('refresh');
+    };
+
+    this.start_scheduled_refresh = function (after_ms) {
+      self.cancel_scheduled_refresh();
+      self.refresh_timer = timer.register($timeout(function () {
+        self.start_scheduled_refresh(after_ms);
+        self.refreshDashboard();
+      }, after_ms));
     };
     };
 
 
-     this.updateTemplateData = function(initial) {
-        var _templateData = {};
-        _.each(this.templateParameters, function(templateParameter) {
-          if (initial) {
-            var urlValue = $routeParams[ templateParameter.name ];
-            if (urlValue) {
-              templateParameter.current = { text: urlValue, value: urlValue };
-            }
-          }
-          if (!templateParameter.current || !templateParameter.current.value) {
-            return;
-          }
-          _templateData[templateParameter.name] = templateParameter.current.value;
-        });
-        this._templateData = _templateData;
-      };
-
-      this.addTemplateParameter = function(templateParameter) {
-        this.templateParameters.push(templateParameter);
-        this.updateTemplateData();
-      };
-
-      this.applyTemplateToTarget = function(target) {
-        if (!target || target.indexOf('[[') === -1) {
-          return target;
-        }
-
-        return _.template(target, this._templateData, this.templateSettings);
-      };
-
-      this.setTime = function(time) {
-        _.extend(this.time, time);
-
-        // disable refresh if we have an absolute time
-        if (time.to !== 'now') {
-          this.old_refresh = this.dashboard.refresh;
-          this.dashboard.set_interval(false);
-        }
-        else if (this.old_refresh && this.old_refresh !== this.dashboard.refresh) {
-          this.dashboard.set_interval(this.old_refresh);
-          this.old_refresh = null;
-        }
-
-        $timeout(this.dashboard.emit_refresh, 0);
-      };
-
-      this.timeRange = function(parse) {
-        var _t = this.time;
-        if(_.isUndefined(_t) || _.isUndefined(_t.from)) {
-          return false;
-        }
-        if(parse === false) {
-          return {
-            from: _t.from,
-            to: _t.to
-          };
-        } else {
-          var _from = _t.from;
-          var _to = _t.to || new Date();
-
-          return {
-            from : kbn.parseDate(_from),
-            to : kbn.parseDate(_to)
-          };
-        }
-      };
+    this.cancel_scheduled_refresh = function () {
+      timer.cancel(this.refresh_timer);
+    };
+
+    this.setTime = function(time) {
+      _.extend(this.time, time);
+
+      // disable refresh if we have an absolute time
+      if (time.to !== 'now') {
+        this.old_refresh = this.dashboard.refresh;
+        this.set_interval(false);
+      }
+      else if (this.old_refresh && this.old_refresh !== this.dashboard.refresh) {
+        this.set_interval(this.old_refresh);
+        this.old_refresh = null;
+      }
+
+      $timeout(this.refreshDashboard, 0);
+    };
+
+    this.timeRange = function(parse) {
+      var _t = this.time;
+      if(_.isUndefined(_t) || _.isUndefined(_t.from)) {
+        return false;
+      }
+      if(parse === false) {
+        return {
+          from: _t.from,
+          to: _t.to
+        };
+      } else {
+        var _from = _t.from;
+        var _to = _t.to || new Date();
+
+        return {
+          from: kbn.parseDate(_from),
+          to: kbn.parseDate(_to)
+        };
+      }
+    };
 
 
   });
   });
 
 

+ 2 - 5
src/test/mocks/dashboard-mock.js

@@ -5,9 +5,6 @@ define([],
   return {
   return {
     create: function() {
     create: function() {
       return {
       return {
-        emit_refresh: function() {},
-        set_interval: function(value) { this.refresh = value; },
-
         title: "",
         title: "",
         tags: [],
         tags: [],
         style: "dark",
         style: "dark",
@@ -18,11 +15,11 @@ define([],
         rows: [],
         rows: [],
         pulldowns: [ { type: 'templating' },  { type: 'annotations' } ],
         pulldowns: [ { type: 'templating' },  { type: 'annotations' } ],
         nav: [ { type: 'timepicker' } ],
         nav: [ { type: 'timepicker' } ],
-        time: {},
+        time: {from: '1h', to: 'now'},
         templating: {
         templating: {
           list: []
           list: []
         },
         },
-        refresh: true
+        refresh: '10s',
       };
       };
     }
     }
   };
   };

+ 1 - 1
src/test/specs/helpers.js

@@ -73,7 +73,7 @@ define([
       };
       };
     };
     };
 
 
-    this.applyTemplateToTarget = function(target) {
+    this.replace = function(target) {
       return target;
       return target;
     };
     };
   }
   }

+ 55 - 0
src/test/specs/templateSrv-specs.js

@@ -0,0 +1,55 @@
+define([
+  'mocks/dashboard-mock',
+  'lodash',
+  'services/templateSrv'
+], function(dashboardMock) {
+  'use strict';
+
+  describe('templateSrv', function() {
+    var _templateSrv;
+    var _dashboard;
+
+    beforeEach(module('grafana.services'));
+    beforeEach(module(function() {
+      _dashboard = dashboardMock.create();
+    }));
+
+    beforeEach(inject(function(templateSrv) {
+      _templateSrv = templateSrv;
+    }));
+
+    beforeEach(function() {
+      _templateSrv.init(_dashboard);
+    });
+
+    describe('init', function() {
+      beforeEach(function() {
+        _templateSrv.addTemplateParameter({ name: 'test', current: { value: 'oogle' } });
+      });
+
+      it('should initialize template data', function() {
+        var target = _templateSrv.replace('this.[[test]].filters');
+        expect(target).to.be('this.oogle.filters');
+      });
+    });
+
+    describe('updateTemplateData', function() {
+      beforeEach(function() {
+        _templateSrv.addTemplateParameter({
+          name: 'test',
+          value: 'muuu',
+          current: { value: 'muuuu' }
+        });
+
+        _templateSrv.updateTemplateData();
+      });
+
+      it('should set current value and update template data', function() {
+        var target = _templateSrv.replace('this.[[test]].filters');
+        expect(target).to.be('this.muuuu.filters');
+      });
+    });
+
+  });
+
+});

+ 4 - 34
src/test/specs/timeSrv-specs.js

@@ -10,45 +10,15 @@ define([
     var _dashboard;
     var _dashboard;
 
 
     beforeEach(module('grafana.services'));
     beforeEach(module('grafana.services'));
-    beforeEach(module(function() {
-      _dashboard = dashboardMock.create();
-    }));
-
     beforeEach(inject(function(timeSrv) {
     beforeEach(inject(function(timeSrv) {
       _timeSrv = timeSrv;
       _timeSrv = timeSrv;
+      _dashboard = dashboardMock.create();
     }));
     }));
 
 
     beforeEach(function() {
     beforeEach(function() {
       _timeSrv.init(_dashboard);
       _timeSrv.init(_dashboard);
     });
     });
 
 
-    describe('init', function() {
-      beforeEach(function() {
-        _timeSrv.addTemplateParameter({ name: 'test', current: { value: 'oogle' } });
-      });
-
-      it('should initialize template data', function() {
-        var target = _timeSrv.applyTemplateToTarget('this.[[test]].filters');
-        expect(target).to.be('this.oogle.filters');
-      });
-    });
-
-    describe('updateTemplateData', function() {
-      beforeEach(function() {
-        _timeSrv.addTemplateParameter({
-          name: 'test',
-          value: 'muuu',
-          current: { value: 'muuuu' }
-        });
-
-        _timeSrv.updateTemplateData();
-      });
-      it('should set current value and update template data', function() {
-        var target = _timeSrv.applyTemplateToTarget('this.[[test]].filters');
-        expect(target).to.be('this.muuuu.filters');
-      });
-    });
-
     describe('timeRange', function() {
     describe('timeRange', function() {
       it('should return unparsed when parse is false', function() {
       it('should return unparsed when parse is false', function() {
         _timeSrv.setTime({from: 'now', to: 'now-1h' });
         _timeSrv.setTime({from: 'now', to: 'now-1h' });
@@ -67,18 +37,18 @@ define([
 
 
     describe('setTime', function() {
     describe('setTime', function() {
       it('should return disable refresh for absolute times', function() {
       it('should return disable refresh for absolute times', function() {
-        _dashboard.refresh = true;
+        _dashboard.refresh = false;
 
 
         _timeSrv.setTime({from: '2011-01-01', to: '2015-01-01' });
         _timeSrv.setTime({from: '2011-01-01', to: '2015-01-01' });
         expect(_dashboard.refresh).to.be(false);
         expect(_dashboard.refresh).to.be(false);
       });
       });
 
 
       it('should restore refresh after relative time range is set', function() {
       it('should restore refresh after relative time range is set', function() {
-        _dashboard.refresh = true;
+        _dashboard.refresh = '10s';
         _timeSrv.setTime({from: '2011-01-01', to: '2015-01-01' });
         _timeSrv.setTime({from: '2011-01-01', to: '2015-01-01' });
         expect(_dashboard.refresh).to.be(false);
         expect(_dashboard.refresh).to.be(false);
         _timeSrv.setTime({from: '2011-01-01', to: 'now' });
         _timeSrv.setTime({from: '2011-01-01', to: 'now' });
-        expect(_dashboard.refresh).to.be(true);
+        expect(_dashboard.refresh).to.be('10s');
       });
       });
     });
     });
 
 

+ 1 - 0
src/test/test-main.js

@@ -126,6 +126,7 @@ require([
     'specs/grafanaGraph-specs',
     'specs/grafanaGraph-specs',
     'specs/seriesOverridesCtrl-specs',
     'specs/seriesOverridesCtrl-specs',
     'specs/timeSrv-specs',
     'specs/timeSrv-specs',
+    'specs/templateSrv-specs',
     'specs/kbn-format-specs',
     'specs/kbn-format-specs',
     'specs/dashboardSrv-specs',
     'specs/dashboardSrv-specs',
     'specs/dashboardViewStateSrv-specs',
     'specs/dashboardViewStateSrv-specs',