mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
More work on filter/templating overhaul
This commit is contained in:
parent
9ee4fcb36c
commit
b761aad903
@ -15,7 +15,7 @@ function (angular, $, config, _) {
|
|||||||
$rootScope,
|
$rootScope,
|
||||||
dashboardKeybindings,
|
dashboardKeybindings,
|
||||||
timeSrv,
|
timeSrv,
|
||||||
templateSrv,
|
templateValuesSrv,
|
||||||
dashboardSrv,
|
dashboardSrv,
|
||||||
dashboardViewStateSrv,
|
dashboardViewStateSrv,
|
||||||
panelMoveSrv,
|
panelMoveSrv,
|
||||||
@ -51,7 +51,7 @@ function (angular, $, config, _) {
|
|||||||
$scope.grafana.style = $scope.dashboard.style;
|
$scope.grafana.style = $scope.dashboard.style;
|
||||||
|
|
||||||
timeSrv.init($scope.dashboard);
|
timeSrv.init($scope.dashboard);
|
||||||
templateSrv.init($scope.dashboard);
|
templateValuesSrv.init($scope.dashboard);
|
||||||
|
|
||||||
$scope.submenuEnabled = $scope.dashboard.templating.enable || $scope.dashboard.annotations.enable;
|
$scope.submenuEnabled = $scope.dashboard.templating.enable || $scope.dashboard.annotations.enable;
|
||||||
|
|
||||||
|
@ -13,7 +13,6 @@ function (angular, _, config) {
|
|||||||
$scope.init = function() {
|
$scope.init = function() {
|
||||||
$scope.timespan = config.playlist_timespan;
|
$scope.timespan = config.playlist_timespan;
|
||||||
$scope.loadFavorites();
|
$scope.loadFavorites();
|
||||||
$scope.$on('modal-opened', $scope.loadFavorites);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
$scope.loadFavorites = function() {
|
$scope.loadFavorites = function() {
|
||||||
|
@ -7,7 +7,7 @@ function (angular, _) {
|
|||||||
|
|
||||||
var module = angular.module('grafana.controllers');
|
var module = angular.module('grafana.controllers');
|
||||||
|
|
||||||
module.controller('TemplateEditorCtrl', function($scope, datasourceSrv) {
|
module.controller('TemplateEditorCtrl', function($scope, datasourceSrv, templateSrv, templateValuesSrv) {
|
||||||
|
|
||||||
var replacementDefaults = {
|
var replacementDefaults = {
|
||||||
type: 'query',
|
type: 'query',
|
||||||
@ -21,7 +21,7 @@ function (angular, _) {
|
|||||||
$scope.editor = { index: 0 };
|
$scope.editor = { index: 0 };
|
||||||
$scope.datasources = datasourceSrv.getMetricSources();
|
$scope.datasources = datasourceSrv.getMetricSources();
|
||||||
$scope.currentDatasource = _.findWhere($scope.datasources, { default: true });
|
$scope.currentDatasource = _.findWhere($scope.datasources, { default: true });
|
||||||
$scope.templateParameters = $scope.filter.templateParameters;
|
$scope.templateParameters = templateSrv.templateParameters;
|
||||||
$scope.reset();
|
$scope.reset();
|
||||||
|
|
||||||
_.each($scope.templateParameters, function(param) {
|
_.each($scope.templateParameters, function(param) {
|
||||||
@ -46,7 +46,7 @@ function (angular, _) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
$scope.runQuery = function() {
|
$scope.runQuery = function() {
|
||||||
$scope.filter.refreshTemplateParameter($scope.current);
|
templateValuesSrv.updateValuesFor($scope.current);
|
||||||
};
|
};
|
||||||
|
|
||||||
$scope.edit = function(param) {
|
$scope.edit = function(param) {
|
||||||
@ -71,6 +71,13 @@ function (angular, _) {
|
|||||||
$scope.current = angular.copy(replacementDefaults);
|
$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) {
|
$scope.removeTemplateParam = function(templateParam) {
|
||||||
var index = _.indexOf($scope.templateParameters, templateParam);
|
var index = _.indexOf($scope.templateParameters, templateParam);
|
||||||
$scope.templateParameters.splice(index, 1);
|
$scope.templateParameters.splice(index, 1);
|
||||||
|
96
src/app/dashboards/scripted_templated.js
Normal file
96
src/app/dashboards/scripted_templated.js
Normal file
@ -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;
|
@ -54,38 +54,61 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="editor-option">
|
<div class="editor-option">
|
||||||
<label class="small">Type</label>
|
<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>
|
||||||
<div class="editor-option">
|
<div class="editor-option" ng-show="current.type === 'query'">
|
||||||
<label class="small">Datasource</label>
|
<label class="small">Datasource</label>
|
||||||
<select ng-model="current.datasource" ng-options="f.value as f.name for f in datasources"></select>
|
<select ng-model="current.datasource" ng-options="f.value as f.name for f in datasources"></select>
|
||||||
</div>
|
</div>
|
||||||
</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>
|
||||||
<div class="editor-row">
|
<input type="checkbox" ng-model="current.refresh" ng-checked="refresh">
|
||||||
<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>
|
</div>
|
||||||
|
|
||||||
<div class="editor-row" style="margin-top: 10px;">
|
<div ng-show="current.type === 'time period'">
|
||||||
<div class="editor-option form-inline">
|
<div class="editor-option">
|
||||||
<label class="small">Regex (optional, if you want to extract part of a series name or metric node segment)</label>
|
<label class="small">Values</label>
|
||||||
<input type="text" class="input-xxlarge" ng-model='current.regex' placeholder="/.*-(.*)-.*/"></input>
|
<input type="text" class="input-xxlarge" array-join ng-model='current.options' ng-change="csvValuesChanged()" ng-model-onblur placeholder="name"></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-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>
|
||||||
|
|
||||||
<div class="editor-row" style="margin-top: 10px;">
|
<div ng-show="current.type === 'query'">
|
||||||
<div class="editor-option form-inline">
|
<div class="editor-row">
|
||||||
<label class="small">Current replacement values</label>
|
<div class="editor-option form-inline">
|
||||||
<ul>
|
<label class="small">Metric name query</label>
|
||||||
<li ng-repeat="option in current.options">
|
<input type="text" class="input-xxlarge" ng-model='current.query' placeholder="apps.servers.*"></input>
|
||||||
{{option.text}}
|
<button class="btn btn-small btn-success" ng-click="runQuery()" bs-tooltip="'Execute query'" data-placement="right"><i class="icon-play"></i></button>
|
||||||
</li>
|
</div>
|
||||||
</ul>
|
</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 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>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@ -111,7 +111,6 @@ function (angular, _) {
|
|||||||
|
|
||||||
$scope.datasources = datasourceSrv.getMetricSources();
|
$scope.datasources = datasourceSrv.getMetricSources();
|
||||||
$scope.setDatasource($scope.panel.datasource);
|
$scope.setDatasource($scope.panel.datasource);
|
||||||
|
|
||||||
$scope.dashboardViewState.registerPanel($scope);
|
$scope.dashboardViewState.registerPanel($scope);
|
||||||
|
|
||||||
if ($scope.get_data) {
|
if ($scope.get_data) {
|
||||||
|
@ -11,10 +11,9 @@ function (angular, _) {
|
|||||||
|
|
||||||
module.service('templateSrv', function($q, $routeParams) {
|
module.service('templateSrv', function($q, $routeParams) {
|
||||||
|
|
||||||
this.init = function(dashboard) {
|
this.init = function(templateParameters) {
|
||||||
this.dashboard = dashboard;
|
|
||||||
this.templateSettings = { interpolate : /\[\[([\s\S]+?)\]\]/g };
|
this.templateSettings = { interpolate : /\[\[([\s\S]+?)\]\]/g };
|
||||||
this.templateParameters = dashboard.templating.list;
|
this.templateParameters = templateParameters;
|
||||||
this.updateTemplateData(true);
|
this.updateTemplateData(true);
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -35,11 +34,6 @@ function (angular, _) {
|
|||||||
this._templateData = _templateData;
|
this._templateData = _templateData;
|
||||||
};
|
};
|
||||||
|
|
||||||
this.addTemplateParameter = function(templateParameter) {
|
|
||||||
this.templateParameters.push(templateParameter);
|
|
||||||
this.updateTemplateData();
|
|
||||||
};
|
|
||||||
|
|
||||||
this.replace = function(target) {
|
this.replace = function(target) {
|
||||||
if (!target || target.indexOf('[[') === -1) {
|
if (!target || target.indexOf('[[') === -1) {
|
||||||
return target;
|
return target;
|
||||||
|
@ -12,6 +12,19 @@ function (angular, _) {
|
|||||||
module.service('templateValuesSrv', function($q, $rootScope, datasourceSrv, $routeParams, templateSrv) {
|
module.service('templateValuesSrv', function($q, $rootScope, datasourceSrv, $routeParams, templateSrv) {
|
||||||
var self = this;
|
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) {
|
this.filterOptionSelected = function(templateParameter, option, recursive) {
|
||||||
templateParameter.current = option;
|
templateParameter.current = option;
|
||||||
|
|
||||||
@ -38,8 +51,9 @@ function (angular, _) {
|
|||||||
return $q.all(promises);
|
return $q.all(promises);
|
||||||
};
|
};
|
||||||
|
|
||||||
this.applyFilter = function(templateParam) {
|
this.updateValuesFor = function(templateParam) {
|
||||||
return datasourceSrv.default.metricFindQuery(templateParam.query)
|
var datasource = datasourceSrv.get(templateParam.datasource);
|
||||||
|
return datasource.metricFindQuery(templateParam.query)
|
||||||
.then(function (results) {
|
.then(function (results) {
|
||||||
templateParam.options = _.map(results, function(node) {
|
templateParam.options = _.map(results, function(node) {
|
||||||
return { text: node.text, value: node.text };
|
return { text: node.text, value: node.text };
|
||||||
|
@ -142,11 +142,13 @@ div.editor-row div.section {
|
|||||||
vertical-align: top;
|
vertical-align: top;
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
}
|
}
|
||||||
|
|
||||||
div.editor-option {
|
div.editor-option {
|
||||||
vertical-align: top;
|
vertical-align: top;
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
margin-right: 10px;
|
margin-right: 10px;
|
||||||
}
|
}
|
||||||
|
|
||||||
div.editor-option label {
|
div.editor-option label {
|
||||||
display: block;
|
display: block;
|
||||||
}
|
}
|
||||||
|
@ -18,13 +18,9 @@ define([
|
|||||||
_templateSrv = templateSrv;
|
_templateSrv = templateSrv;
|
||||||
}));
|
}));
|
||||||
|
|
||||||
beforeEach(function() {
|
|
||||||
_templateSrv.init(_dashboard);
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('init', function() {
|
describe('init', function() {
|
||||||
beforeEach(function() {
|
beforeEach(function() {
|
||||||
_templateSrv.addTemplateParameter({ name: 'test', current: { value: 'oogle' } });
|
_templateSrv.init([{ name: 'test', current: { value: 'oogle' } }]);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should initialize template data', function() {
|
it('should initialize template data', function() {
|
||||||
@ -35,11 +31,11 @@ define([
|
|||||||
|
|
||||||
describe('updateTemplateData', function() {
|
describe('updateTemplateData', function() {
|
||||||
beforeEach(function() {
|
beforeEach(function() {
|
||||||
_templateSrv.addTemplateParameter({
|
_templateSrv.init([{
|
||||||
name: 'test',
|
name: 'test',
|
||||||
value: 'muuu',
|
value: 'muuu',
|
||||||
current: { value: 'muuuu' }
|
current: { value: 'muuuu' }
|
||||||
});
|
}]);
|
||||||
|
|
||||||
_templateSrv.updateTemplateData();
|
_templateSrv.updateTemplateData();
|
||||||
});
|
});
|
||||||
|
Loading…
Reference in New Issue
Block a user