Commit 9dc42648 by Torkel Ödegaard

fix(templating): fixed issue with experimental feature template variable value…

fix(templating): fixed issue with experimental feature template variable value groups tags, fixes #6752
parent 2e7d222f
...@@ -6,6 +6,7 @@ ...@@ -6,6 +6,7 @@
* **Server side PNG rendering**: Fixed issue with y-axis label rotation in phantomjs rendered images [#6924](https://github.com/grafana/grafana/issues/6924) * **Server side PNG rendering**: Fixed issue with y-axis label rotation in phantomjs rendered images [#6924](https://github.com/grafana/grafana/issues/6924)
* **Graph**: Fixed centering of y-axis label [#7099](https://github.com/grafana/grafana/issues/7099) * **Graph**: Fixed centering of y-axis label [#7099](https://github.com/grafana/grafana/issues/7099)
* **Graph**: Fixed graph legend table mode and always visible scrollbar [#6828](https://github.com/grafana/grafana/issues/6828) * **Graph**: Fixed graph legend table mode and always visible scrollbar [#6828](https://github.com/grafana/grafana/issues/6828)
* **Templating**: Fixed template variable value groups/tags feature [#6752](https://github.com/grafana/grafana/issues/6752)
# 4.1-beta1 (2016-12-21) # 4.1-beta1 (2016-12-21)
......
...@@ -75,7 +75,7 @@ function (angular, _, coreModule) { ...@@ -75,7 +75,7 @@ function (angular, _, coreModule) {
tag.selected = !tag.selected; tag.selected = !tag.selected;
var tagValuesPromise; var tagValuesPromise;
if (!tag.values) { if (!tag.values) {
tagValuesPromise = vm.getValuesForTag({tagKey: tag.text}); tagValuesPromise = vm.variable.getValuesForTag(tag.text);
} else { } else {
tagValuesPromise = $q.when(tag.values); tagValuesPromise = $q.when(tag.values);
} }
...@@ -225,7 +225,7 @@ function (angular, _, coreModule) { ...@@ -225,7 +225,7 @@ function (angular, _, coreModule) {
coreModule.default.directive('valueSelectDropdown', function($compile, $window, $timeout, $rootScope) { coreModule.default.directive('valueSelectDropdown', function($compile, $window, $timeout, $rootScope) {
return { return {
scope: { variable: "=", onUpdated: "&", getValuesForTag: "&" }, scope: { variable: "=", onUpdated: "&"},
templateUrl: 'public/app/partials/valueSelectDropdown.html', templateUrl: 'public/app/partials/valueSelectDropdown.html',
controller: 'ValueSelectDropdownCtrl', controller: 'ValueSelectDropdownCtrl',
controllerAs: 'vm', controllerAs: 'vm',
......
export function assignModelProperties(target, source, defaults) { export function assignModelProperties(target, source, defaults, removeDefaults?) {
for (var key in defaults) { for (var key in defaults) {
if (!defaults.hasOwnProperty(key)) { if (!defaults.hasOwnProperty(key)) {
continue; continue;
......
...@@ -5,7 +5,7 @@ ...@@ -5,7 +5,7 @@
<label class="gf-form-label template-variable" ng-hide="variable.hide === 1"> <label class="gf-form-label template-variable" ng-hide="variable.hide === 1">
{{variable.label || variable.name}} {{variable.label || variable.name}}
</label> </label>
<value-select-dropdown ng-if="variable.type !== 'adhoc'" variable="variable" on-updated="ctrl.variableUpdated(variable)" get-values-for-tag="ctrl.getValuesForTag(variable, tagKey)"></value-select-dropdown> <value-select-dropdown ng-if="variable.type !== 'adhoc'" variable="variable" on-updated="ctrl.variableUpdated(variable)"></value-select-dropdown>
</div> </div>
<ad-hoc-filters ng-if="variable.type === 'adhoc'" variable="variable"></ad-hoc-filters> <ad-hoc-filters ng-if="variable.type === 'adhoc'" variable="variable"></ad-hoc-filters>
</div> </div>
......
...@@ -21,10 +21,6 @@ export class SubmenuCtrl { ...@@ -21,10 +21,6 @@ export class SubmenuCtrl {
this.$rootScope.$broadcast('refresh'); this.$rootScope.$broadcast('refresh');
} }
getValuesForTag(variable, tagKey) {
return this.variableSrv.getValuesForTag(variable, tagKey);
}
variableUpdated(variable) { variableUpdated(variable) {
this.variableSrv.variableUpdated(variable).then(() => { this.variableSrv.variableUpdated(variable).then(() => {
this.$rootScope.$emit('template-variable-value-updated'); this.$rootScope.$emit('template-variable-value-updated');
......
...@@ -111,14 +111,14 @@ ...@@ -111,14 +111,14 @@
<span class="gf-form-label width-9">Values</span> <span class="gf-form-label width-9">Values</span>
<input type="text" class="gf-form-input" placeholder="name" ng-model='current.query' placeholder="1m,10m,1h,6h,1d,7d" ng-model-onblur ng-change="runQuery()" required></input> <input type="text" class="gf-form-input" placeholder="name" ng-model='current.query' placeholder="1m,10m,1h,6h,1d,7d" ng-model-onblur ng-change="runQuery()" required></input>
</div> </div>
<div class="gf-form">
<span class="gf-form-label width-9">Auto option</span>
<editor-checkbox text="Enable" model="current.auto" change="runQuery()"></editor-checkbox>
</div>
<div class="gf-form-inline"> <div class="gf-form-inline">
<gf-form-switch class="gf-form" label="Auto Option" label-class="width-9" checked="current.auto" on-change="runQuery()">
</gf-form-switch>
<div class="gf-form"> <div class="gf-form">
<span class="gf-form-label width-9" ng-show="current.auto"> <span class="gf-form-label width-9" ng-show="current.auto">
Auto steps <tip>How many times should the current time range be divided to calculate the value</tip> Step count <tip>How many times should the current time range be divided to calculate the value</tip>
</span> </span>
<div class="gf-form-select-wrapper max-width-10" ng-show="current.auto"> <div class="gf-form-select-wrapper max-width-10" ng-show="current.auto">
<select class="gf-form-input" ng-model="current.auto_count" ng-options="f for f in [2,3,4,5,10,20,30,40,50,100,200,300,400,500]" ng-change="runQuery()"></select> <select class="gf-form-input" ng-model="current.auto_count" ng-options="f for f in [2,3,4,5,10,20,30,40,50,100,200,300,400,500]" ng-change="runQuery()"></select>
...@@ -257,27 +257,26 @@ ...@@ -257,27 +257,26 @@
<div class="gf-form-group" ng-if="current.type === 'query'"> <div class="gf-form-group" ng-if="current.type === 'query'">
<h5>Value groups/tags (Experimental feature)</h5> <h5>Value groups/tags (Experimental feature)</h5>
<div class="gf-form"> <gf-form-switch class="gf-form" label="Enabled" label-class="width-10" checked="current.useTags" on-change="runQuery()">
<editor-checkbox text="Enable" model="current.useTags" change="runQuery()"></editor-checkbox> </gf-form-switch>
</div> <div class="gf-form last" ng-if="current.useTags">
<div class="gf-form last" ng-if="current.useTags"> <span class="gf-form-label width-10">Tags query</span>
<span class="gf-form-label width-10">Tags query</span> <input type="text" class="gf-form-input" ng-model='current.tagsQuery' placeholder="metric name or tags query" ng-model-onblur></input>
<input type="text" class="gf-form-input" ng-model='current.tagsQuery' placeholder="metric name or tags query" ng-model-onblur></input> </div>
</div> <div class="gf-form" ng-if="current.useTags">
<div class="gf-form" ng-if="current.useTags"> <li class="gf-form-label width-10">Tag values query</li>
<li class="gf-form-label width-10">Tag values query</li> <input type="text" class="gf-form-input" ng-model='current.tagValuesQuery' placeholder="apps.$tag.*" ng-model-onblur></input>
<input type="text" class="gf-form-input" ng-model='current.tagValuesQuery' placeholder="apps.$tag.*" ng-model-onblur></input> </div>
</div> </div>
</div>
<div class="gf-form-group" ng-show="current.options.length"> <div class="gf-form-group" ng-show="current.options.length">
<h5>Preview of values (shows max 20)</h5> <h5>Preview of values (shows max 20)</h5>
<div class="gf-form-inline"> <div class="gf-form-inline">
<div class="gf-form" ng-repeat="option in current.options | limitTo: 20"> <div class="gf-form" ng-repeat="option in current.options | limitTo: 20">
<span class="gf-form-label">{{option.text}}</span> <span class="gf-form-label">{{option.text}}</span>
</div> </div>
</div> </div>
</div> </div>
<div class="alert alert-info gf-form-group" ng-if="infoText"> <div class="alert alert-info gf-form-group" ng-if="infoText">
{{infoText}} {{infoText}}
......
...@@ -21,6 +21,10 @@ export class QueryVariable implements Variable { ...@@ -21,6 +21,10 @@ export class QueryVariable implements Variable {
name: string; name: string;
multi: boolean; multi: boolean;
includeAll: boolean; includeAll: boolean;
useTags: boolean;
tagsQuery: string;
tagValuesQuery: string;
tags: any[];
defaults = { defaults = {
type: 'query', type: 'query',
...@@ -37,8 +41,10 @@ export class QueryVariable implements Variable { ...@@ -37,8 +41,10 @@ export class QueryVariable implements Variable {
allValue: null, allValue: null,
options: [], options: [],
current: {}, current: {},
tagsQuery: null, tags: [],
tagValuesQuery: null, useTags: false,
tagsQuery: "",
tagValuesQuery: "",
}; };
/** @ngInject **/ /** @ngInject **/
...@@ -77,9 +83,37 @@ export class QueryVariable implements Variable { ...@@ -77,9 +83,37 @@ export class QueryVariable implements Variable {
updateOptions() { updateOptions() {
return this.datasourceSrv.get(this.datasource) return this.datasourceSrv.get(this.datasource)
.then(this.updateOptionsFromMetricFindQuery.bind(this)) .then(this.updateOptionsFromMetricFindQuery.bind(this))
.then(this.updateTags.bind(this))
.then(this.variableSrv.validateVariableSelectionState.bind(this.variableSrv, this)); .then(this.variableSrv.validateVariableSelectionState.bind(this.variableSrv, this));
} }
updateTags(datasource) {
if (this.useTags) {
return datasource.metricFindQuery(this.tagsQuery).then(results => {
this.tags = [];
for (var i = 0; i < results.length; i++) {
this.tags.push(results[i].text);
}
return datasource;
});
} else {
delete this.tags;
}
return datasource;
}
getValuesForTag(tagKey) {
return this.datasourceSrv.get(this.datasource).then(datasource => {
var query = this.tagValuesQuery.replace('$tag', tagKey);
return datasource.metricFindQuery(query).then(function (results) {
return _.map(results, function(value) {
return value.text;
});
});
});
}
updateOptionsFromMetricFindQuery(datasource) { updateOptionsFromMetricFindQuery(datasource) {
return datasource.metricFindQuery(this.query).then(results => { return datasource.metricFindQuery(this.query).then(results => {
this.options = this.metricNamesToVariableValues(results); this.options = this.metricNamesToVariableValues(results);
...@@ -147,11 +181,11 @@ export class QueryVariable implements Variable { ...@@ -147,11 +181,11 @@ export class QueryVariable implements Variable {
} else if (sortType === 2) { } else if (sortType === 2) {
options = _.sortBy(options, function(opt) { options = _.sortBy(options, function(opt) {
var matches = opt.text.match(/.*?(\d+).*/); var matches = opt.text.match(/.*?(\d+).*/);
if (!matches) { if (!matches) {
return 0; return 0;
} else { } else {
return parseInt(matches[1], 10); return parseInt(matches[1], 10);
} }
}); });
} }
......
...@@ -9,22 +9,26 @@ function () { ...@@ -9,22 +9,26 @@ function () {
var ctrl; var ctrl;
var tagValuesMap = {}; var tagValuesMap = {};
var rootScope; var rootScope;
var q;
beforeEach(module('grafana.core')); beforeEach(module('grafana.core'));
beforeEach(inject(function($controller, $rootScope, $q, $httpBackend) { beforeEach(inject(function($controller, $rootScope, $q, $httpBackend) {
rootScope = $rootScope; rootScope = $rootScope;
q = $q;
scope = $rootScope.$new(); scope = $rootScope.$new();
ctrl = $controller('ValueSelectDropdownCtrl', {$scope: scope}); ctrl = $controller('ValueSelectDropdownCtrl', {$scope: scope});
ctrl.getValuesForTag = function(obj) {
return $q.when(tagValuesMap[obj.tagKey]);
};
ctrl.onUpdated = sinon.spy(); ctrl.onUpdated = sinon.spy();
$httpBackend.when('GET', /\.html$/).respond(''); $httpBackend.when('GET', /\.html$/).respond('');
})); }));
describe("Given simple variable", function() { describe("Given simple variable", function() {
beforeEach(function() { beforeEach(function() {
ctrl.variable = {current: {text: 'hej', value: 'hej' }}; ctrl.variable = {
current: {text: 'hej', value: 'hej' },
getValuesForTag: function(key) {
return q.when(tagValuesMap[key]);
},
};
ctrl.init(); ctrl.init();
}); });
...@@ -43,6 +47,9 @@ function () { ...@@ -43,6 +47,9 @@ function () {
{text: 'server-3', value: 'server-3'}, {text: 'server-3', value: 'server-3'},
], ],
tags: ["key1", "key2", "key3"], tags: ["key1", "key2", "key3"],
getValuesForTag: function(key) {
return q.when(tagValuesMap[key]);
},
multi: true multi: true
}; };
tagValuesMap.key1 = ['server-1', 'server-3']; tagValuesMap.key1 = ['server-1', 'server-3'];
...@@ -145,6 +152,9 @@ function () { ...@@ -145,6 +152,9 @@ function () {
{text: 'server-3', value: 'server-3'}, {text: 'server-3', value: 'server-3'},
], ],
tags: ["key1", "key2", "key3"], tags: ["key1", "key2", "key3"],
getValuesForTag: function(key) {
return q.when(tagValuesMap[key]);
},
multi: true multi: true
}; };
ctrl.init(); ctrl.init();
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment