diff --git a/public/app/features/templating/editorCtrl.js b/public/app/features/templating/editorCtrl.js
index 5efebc21e30..95f3bd2e9dd 100644
--- a/public/app/features/templating/editorCtrl.js
+++ b/public/app/features/templating/editorCtrl.js
@@ -13,6 +13,7 @@ function (angular, _) {
type: 'query',
datasource: null,
refresh: 0,
+ sort: 1,
name: '',
hide: 0,
options: [],
@@ -34,6 +35,14 @@ function (angular, _) {
{value: 2, text: "On Time Range Change"},
];
+ $scope.sortOptions = [
+ {value: 0, text: "Without Sort"},
+ {value: 1, text: "Alphabetical (asc)"},
+ {value: 2, text: "Alphabetical (desc)"},
+ {value: 3, text: "Numerical (asc)"},
+ {value: 4, text: "Numerical (desc)"},
+ ];
+
$scope.hideOptions = [
{value: 0, text: ""},
{value: 1, text: "Label"},
@@ -114,6 +123,7 @@ function (angular, _) {
$scope.currentIsNew = false;
$scope.mode = 'edit';
+ $scope.current.sort = $scope.current.sort || replacementDefaults.sort;
if ($scope.current.datasource === void 0) {
$scope.current.datasource = null;
$scope.current.type = 'query';
diff --git a/public/app/features/templating/partials/editor.html b/public/app/features/templating/partials/editor.html
index 247945c2342..80ea870dfc4 100644
--- a/public/app/features/templating/partials/editor.html
+++ b/public/app/features/templating/partials/editor.html
@@ -181,6 +181,17 @@
+
Query
diff --git a/public/app/features/templating/templateValuesSrv.js b/public/app/features/templating/templateValuesSrv.js
index 44904b07fad..6125a4b44a9 100644
--- a/public/app/features/templating/templateValuesSrv.js
+++ b/public/app/features/templating/templateValuesSrv.js
@@ -342,7 +342,7 @@ function (angular, _, $, kbn) {
this.metricNamesToVariableValues = function(variable, metricNames) {
var regex, options, i, matches;
- options = {}; // use object hash to remove duplicates
+ options = [];
if (variable.regex) {
regex = kbn.stringToJsRegex(templateSrv.replace(variable.regex));
@@ -370,16 +370,43 @@ function (angular, _, $, kbn) {
}
}
- options[value] = {text: text, value: value};
+ options.push({text: text, value: value});
}
+ options = _.uniq(options, 'value');
- return _.sortBy(options, 'text');
+ return this.sortVariableValues(options, variable.sort);
};
this.addAllOption = function(variable) {
variable.options.unshift({text: 'All', value: "$__all"});
};
+ this.sortVariableValues = function(options, sortOrder) {
+ if (sortOrder === 0) {
+ return options;
+ }
+
+ var sortType = Math.ceil(sortOrder / 2);
+ var reverseSort = (sortOrder % 2 === 0);
+ if (sortType === 1) {
+ options = _.sortBy(options, 'text');
+ } else if (sortType === 2) {
+ options = _.sortBy(options, function(opt) {
+ var matches = opt.text.match(/.*?(\d+).*/);
+ if (!matches) {
+ return 0;
+ } else {
+ return parseInt(matches[1], 10);
+ }
+ });
+ }
+ if (reverseSort) {
+ options = options.reverse();
+ }
+
+ return options;
+ };
+
});
});
diff --git a/public/test/specs/templateValuesSrv-specs.js b/public/test/specs/templateValuesSrv-specs.js
index 7a8d8c1fccb..1742f5739c3 100644
--- a/public/test/specs/templateValuesSrv-specs.js
+++ b/public/test/specs/templateValuesSrv-specs.js
@@ -386,5 +386,69 @@ define([
});
});
+ describeUpdateVariable('without sort', function(scenario) {
+ scenario.setup(function() {
+ scenario.variable = {type: 'query', query: 'apps.*', name: 'test', sort: 0};
+ scenario.queryResult = [{text: 'bbb2'}, {text: 'aaa10'}, { text: 'ccc3'}];
+ });
+
+ it('should return options without sort', function() {
+ expect(scenario.variable.options[0].text).to.be('bbb2');
+ expect(scenario.variable.options[1].text).to.be('aaa10');
+ expect(scenario.variable.options[2].text).to.be('ccc3');
+ });
+ });
+
+ describeUpdateVariable('with alphabetical sort (asc)', function(scenario) {
+ scenario.setup(function() {
+ scenario.variable = {type: 'query', query: 'apps.*', name: 'test', sort: 1};
+ scenario.queryResult = [{text: 'bbb2'}, {text: 'aaa10'}, { text: 'ccc3'}];
+ });
+
+ it('should return options with alphabetical sort', function() {
+ expect(scenario.variable.options[0].text).to.be('aaa10');
+ expect(scenario.variable.options[1].text).to.be('bbb2');
+ expect(scenario.variable.options[2].text).to.be('ccc3');
+ });
+ });
+
+ describeUpdateVariable('with alphabetical sort (desc)', function(scenario) {
+ scenario.setup(function() {
+ scenario.variable = {type: 'query', query: 'apps.*', name: 'test', sort: 2};
+ scenario.queryResult = [{text: 'bbb2'}, {text: 'aaa10'}, { text: 'ccc3'}];
+ });
+
+ it('should return options with alphabetical sort', function() {
+ expect(scenario.variable.options[0].text).to.be('ccc3');
+ expect(scenario.variable.options[1].text).to.be('bbb2');
+ expect(scenario.variable.options[2].text).to.be('aaa10');
+ });
+ });
+
+ describeUpdateVariable('with numerical sort (asc)', function(scenario) {
+ scenario.setup(function() {
+ scenario.variable = {type: 'query', query: 'apps.*', name: 'test', sort: 3};
+ scenario.queryResult = [{text: 'bbb2'}, {text: 'aaa10'}, { text: 'ccc3'}];
+ });
+
+ it('should return options with numerical sort', function() {
+ expect(scenario.variable.options[0].text).to.be('bbb2');
+ expect(scenario.variable.options[1].text).to.be('ccc3');
+ expect(scenario.variable.options[2].text).to.be('aaa10');
+ });
+ });
+
+ describeUpdateVariable('with numerical sort (desc)', function(scenario) {
+ scenario.setup(function() {
+ scenario.variable = {type: 'query', query: 'apps.*', name: 'test', sort: 4};
+ scenario.queryResult = [{text: 'bbb2'}, {text: 'aaa10'}, { text: 'ccc3'}];
+ });
+
+ it('should return options with numerical sort', function() {
+ expect(scenario.variable.options[0].text).to.be('aaa10');
+ expect(scenario.variable.options[1].text).to.be('ccc3');
+ expect(scenario.variable.options[2].text).to.be('bbb2');
+ });
+ });
});
});