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

More work on filter/templating overhaul

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

+ 2 - 2
src/app/controllers/dashboardCtrl.js

@@ -15,7 +15,7 @@ function (angular, $, config, _) {
       $rootScope,
       dashboardKeybindings,
       timeSrv,
-      templateSrv,
+      templateValuesSrv,
       dashboardSrv,
       dashboardViewStateSrv,
       panelMoveSrv,
@@ -51,7 +51,7 @@ function (angular, $, config, _) {
       $scope.grafana.style = $scope.dashboard.style;
 
       timeSrv.init($scope.dashboard);
-      templateSrv.init($scope.dashboard);
+      templateValuesSrv.init($scope.dashboard);
 
       $scope.submenuEnabled = $scope.dashboard.templating.enable || $scope.dashboard.annotations.enable;
 

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

@@ -13,7 +13,6 @@ function (angular, _, config) {
     $scope.init = function() {
       $scope.timespan = config.playlist_timespan;
       $scope.loadFavorites();
-      $scope.$on('modal-opened', $scope.loadFavorites);
     };
 
     $scope.loadFavorites = function() {

+ 10 - 3
src/app/controllers/templateEditorCtrl.js

@@ -7,7 +7,7 @@ function (angular, _) {
 
   var module = angular.module('grafana.controllers');
 
-  module.controller('TemplateEditorCtrl', function($scope, datasourceSrv) {
+  module.controller('TemplateEditorCtrl', function($scope, datasourceSrv, templateSrv, templateValuesSrv) {
 
     var replacementDefaults = {
       type: 'query',
@@ -21,7 +21,7 @@ function (angular, _) {
       $scope.editor = { index: 0 };
       $scope.datasources = datasourceSrv.getMetricSources();
       $scope.currentDatasource = _.findWhere($scope.datasources, { default: true });
-      $scope.templateParameters = $scope.filter.templateParameters;
+      $scope.templateParameters = templateSrv.templateParameters;
       $scope.reset();
 
       _.each($scope.templateParameters, function(param) {
@@ -46,7 +46,7 @@ function (angular, _) {
     };
 
     $scope.runQuery = function() {
-      $scope.filter.refreshTemplateParameter($scope.current);
+      templateValuesSrv.updateValuesFor($scope.current);
     };
 
     $scope.edit = function(param) {
@@ -71,6 +71,13 @@ function (angular, _) {
       $scope.current = angular.copy(replacementDefaults);
     };
 
+    $scope.typeChanged = function () {
+      if ($scope.current.type === 'time period') {
+        $scope.current.options = ['auto', '1m', '10m', '30m', '1h', '6h', '12h', '1d', '7d', '14d', '30d'];
+        $scope.current.auto_count = 10;
+      }
+    };
+
     $scope.removeTemplateParam = function(templateParam) {
       var index = _.indexOf($scope.templateParameters, templateParam);
       $scope.templateParameters.splice(index, 1);

+ 96 - 0
src/app/dashboards/scripted_templated.js

@@ -0,0 +1,96 @@
+/* global _ */
+
+/*
+ * Complex scripted dashboard
+ * This script generates a dashboard object that Grafana can load. It also takes a number of user
+ * supplied URL parameters (int ARGS variable)
+ *
+ * Return a dashboard object, or a function
+ *
+ * For async scripts, return a function, this function must take a single callback function as argument,
+ * call this callback function with the dashboard object (look at scripted_async.js for an example)
+ */
+
+'use strict';
+
+// accessable variables in this scope
+var window, document, ARGS, $, jQuery, moment, kbn;
+
+// Setup some variables
+var dashboard, timspan;
+
+// All url parameters are available via the ARGS object
+var ARGS;
+
+// Set a default timespan if one isn't specified
+timspan = '1d';
+
+// Intialize a skeleton with nothing but a rows array and service object
+dashboard = {
+  rows : [],
+};
+
+// Set a title
+dashboard.title = 'Scripted dash';
+dashboard.time = {
+  from: "now-" + (ARGS.from || timspan),
+  to: "now"
+};
+dashboard.templating = {
+  enable: true,
+  list: [
+    {
+      name: 'test',
+      query: 'apps.backend.*',
+      refresh: true,
+      options: [],
+      current: null,
+    },
+    {
+      name: 'test2',
+      query: '*',
+      refresh: true,
+      options: [],
+      current: null,
+    }
+  ]
+};
+
+var rows = 1;
+var seriesName = 'argName';
+
+if(!_.isUndefined(ARGS.rows)) {
+  rows = parseInt(ARGS.rows, 10);
+}
+
+if(!_.isUndefined(ARGS.name)) {
+  seriesName = ARGS.name;
+}
+
+for (var i = 0; i < rows; i++) {
+
+  dashboard.rows.push({
+    title: 'Chart',
+    height: '300px',
+    panels: [
+      {
+        title: 'Events',
+        type: 'graph',
+        span: 12,
+        fill: 1,
+        linewidth: 2,
+        targets: [
+          {
+            'target': "randomWalk('" + seriesName + "')"
+          },
+          {
+            'target': "randomWalk('[[test2]]')"
+          }
+        ],
+      }
+    ]
+  });
+}
+
+
+return dashboard;

+ 44 - 21
src/app/partials/templating_editor.html

@@ -54,38 +54,61 @@
 				</div>
 				<div class="editor-option">
 					<label class="small">Type</label>
-					<select class="input-medium" ng-model="current.type" ng-options="f for f in ['query', 'custom']"></select>
+					<select class="input-medium" ng-model="current.type" ng-options="f for f in ['query', 'time period']" ng-change="typeChanged()"></select>
 				</div>
-				<div class="editor-option">
+				<div class="editor-option" ng-show="current.type === 'query'">
 					<label class="small">Datasource</label>
 					<select ng-model="current.datasource" ng-options="f.value as f.name for f in datasources"></select>
 				</div>
+				<div class="editor-option text-center" ng-show="current.type === 'query'">
+					<label class="small">Refresh on load <tip>Check if you want values to be updated on dashboard load, will slow down dashboard load time.</tip></label>
+					<input type="checkbox" ng-model="current.refresh" ng-checked="refresh">
+				</div>
 			</div>
 
-			<div class="editor-row">
-				<div class="editor-option form-inline">
-					<label class="small">Metric name query</label>
-					<input type="text" class="input-xxlarge" ng-model='current.query' placeholder="apps.servers.*"></input>
-					<button class="btn btn-small btn-success" ng-click="runQuery()" bs-tooltip="'Execute query'" data-placement="right"><i class="icon-play"></i></button>
+			<div ng-show="current.type === 'time period'">
+				<div class="editor-option">
+					<label class="small">Values</label>
+					<input type="text" class="input-xxlarge" array-join ng-model='current.options' ng-change="csvValuesChanged()" ng-model-onblur placeholder="name"></input>
+				</div>
+				<div class="editor-option">
+					<label class="small">Auto period count <tip>The number you want to divide the time range in</tip></label>
+					<select class="input-small" ng-model="current.auto_count" ng-options="f for f in [5,6,7,8,9,10,15,20,30,40,50,70,90,100]"></select>
 				</div>
+				<p class="small">
+					<br>
+					<i class="icon-info-sign"></i>
+					This special type of template replacement is useful as the auto word will be calculated depending on the time range divided by
+					the number of periods you wish.
+				</p>
 			</div>
 
-			<div class="editor-row" style="margin-top: 10px;">
-				<div class="editor-option form-inline">
-					<label class="small">Regex (optional, if you want to extract part of a series name or metric node segment)</label>
-					<input type="text" class="input-xxlarge" ng-model='current.regex' placeholder="/.*-(.*)-.*/"></input>
-					<button class="btn btn-small btn-success" ng-click="runQuery()" bs-tooltip="'Execute query'" data-placement="right"><i class="icon-play"></i></button>
+			<div ng-show="current.type === 'query'">
+				<div class="editor-row">
+					<div class="editor-option form-inline">
+						<label class="small">Metric name query</label>
+						<input type="text" class="input-xxlarge" ng-model='current.query' placeholder="apps.servers.*"></input>
+						<button class="btn btn-small btn-success" ng-click="runQuery()" bs-tooltip="'Execute query'" data-placement="right"><i class="icon-play"></i></button>
+					</div>
+				</div>
+
+				<div class="editor-row" style="margin-top: 10px;">
+					<div class="editor-option form-inline">
+						<label class="small">Regex (optional, if you want to extract part of a series name or metric node segment)</label>
+						<input type="text" class="input-xxlarge" ng-model='current.regex' placeholder="/.*-(.*)-.*/"></input>
+						<button class="btn btn-small btn-success" ng-click="runQuery()" bs-tooltip="'Execute query'" data-placement="right"><i class="icon-play"></i></button>
+					</div>
 				</div>
-			</div>
 
-			<div class="editor-row" style="margin-top: 10px;">
-				<div class="editor-option form-inline">
-					<label class="small">Current replacement values</label>
-					<ul>
-						<li ng-repeat="option in current.options">
-							{{option.text}}
-						</li>
-					</ul>
+				<div class="editor-row" style="margin-top: 10px;">
+					<div class="editor-option form-inline">
+						<label class="small">Current replacement values</label>
+						<ul>
+							<li ng-repeat="option in current.options">
+								{{option.text}}
+							</li>
+						</ul>
+					</div>
 				</div>
 			</div>
 

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

@@ -111,7 +111,6 @@ function (angular, _) {
 
       $scope.datasources = datasourceSrv.getMetricSources();
       $scope.setDatasource($scope.panel.datasource);
-
       $scope.dashboardViewState.registerPanel($scope);
 
       if ($scope.get_data) {

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

@@ -11,10 +11,9 @@ function (angular, _) {
 
   module.service('templateSrv', function($q, $routeParams) {
 
-    this.init = function(dashboard) {
-      this.dashboard = dashboard;
+    this.init = function(templateParameters) {
       this.templateSettings = { interpolate : /\[\[([\s\S]+?)\]\]/g };
-      this.templateParameters = dashboard.templating.list;
+      this.templateParameters = templateParameters;
       this.updateTemplateData(true);
     };
 
@@ -35,11 +34,6 @@ function (angular, _) {
       this._templateData = _templateData;
     };
 
-    this.addTemplateParameter = function(templateParameter) {
-      this.templateParameters.push(templateParameter);
-      this.updateTemplateData();
-    };
-
     this.replace = function(target) {
       if (!target || target.indexOf('[[') === -1) {
         return target;

+ 16 - 2
src/app/services/templateValuesSrv.js

@@ -12,6 +12,19 @@ function (angular, _) {
   module.service('templateValuesSrv', function($q, $rootScope, datasourceSrv, $routeParams, templateSrv) {
     var self = this;
 
+    this.init = function(dashboard) {
+      this.templateParameters = dashboard.templating.list;
+
+      templateSrv.init(this.templateParameters);
+
+      for (var i = 0; i < this.templateParameters.length; i++) {
+        var param = this.templateParameters[i];
+        if (param.refresh) {
+          this.updateValuesFor(param);
+        }
+      }
+    };
+
     this.filterOptionSelected = function(templateParameter, option, recursive) {
       templateParameter.current = option;
 
@@ -38,8 +51,9 @@ function (angular, _) {
       return $q.all(promises);
     };
 
-    this.applyFilter = function(templateParam) {
-      return datasourceSrv.default.metricFindQuery(templateParam.query)
+    this.updateValuesFor = function(templateParam) {
+      var datasource = datasourceSrv.get(templateParam.datasource);
+      return datasource.metricFindQuery(templateParam.query)
         .then(function (results) {
           templateParam.options = _.map(results, function(node) {
             return { text: node.text, value: node.text };

+ 2 - 0
src/css/less/overrides.less

@@ -142,11 +142,13 @@ div.editor-row div.section {
   vertical-align: top;
   display: inline-block;
 }
+
 div.editor-option {
   vertical-align: top;
   display: inline-block;
   margin-right: 10px;
 }
+
 div.editor-option label {
   display: block;
 }

+ 3 - 7
src/test/specs/templateSrv-specs.js

@@ -18,13 +18,9 @@ define([
       _templateSrv = templateSrv;
     }));
 
-    beforeEach(function() {
-      _templateSrv.init(_dashboard);
-    });
-
     describe('init', function() {
       beforeEach(function() {
-        _templateSrv.addTemplateParameter({ name: 'test', current: { value: 'oogle' } });
+        _templateSrv.init([{ name: 'test', current: { value: 'oogle' } }]);
       });
 
       it('should initialize template data', function() {
@@ -35,11 +31,11 @@ define([
 
     describe('updateTemplateData', function() {
       beforeEach(function() {
-        _templateSrv.addTemplateParameter({
+        _templateSrv.init([{
           name: 'test',
           value: 'muuu',
           current: { value: 'muuuu' }
-        });
+        }]);
 
         _templateSrv.updateTemplateData();
       });