Commit 0992b6a6 by Torkel Ödegaard

Progress on template variable dropdown, lots of unit tests for selection behavior,

parent 53ed4074
......@@ -9,7 +9,7 @@ function (angular, app, _) {
angular
.module('grafana.controllers')
.controller('SelectDropdownCtrl', function() {
.controller('SelectDropdownCtrl', function($q) {
var vm = this;
vm.show = function() {
......@@ -56,23 +56,29 @@ function (angular, app, _) {
vm.selectTag = function(tag) {
tag.selected = !tag.selected;
var tagValuesPromise;
if (!tag.values) {
if (tag.text === 'backend') {
tag.values = ['backend_01', 'backend_02', 'backend_03', 'backend_04'];
} else {
tag.values = ['web_server_01', 'web_server_02', 'web_server_03', 'web_server_04'];
}
console.log('querying for tag values');
tagValuesPromise = vm.getValuesForTag({tagKey: tag.text});
// if (tag.text === 'backend') {
// tag.values = ['backend_01', 'backend_02', 'backend_03', 'backend_04'];
// } else {
// tag.values = ['web_server_01', 'web_server_02', 'web_server_03', 'web_server_04'];
// }
} else {
tagValuesPromise = $q.when(tag.values);
}
_.each(vm.options, function(option) {
if (_.indexOf(tag.values, option.value) !== -1) {
option.selected = tag.selected;
}
});
tagValuesPromise.then(function(values) {
tag.values = values;
_.each(vm.options, function(option) {
if (_.indexOf(tag.values, option.value) !== -1) {
option.selected = tag.selected;
}
});
vm.selectedTags = _.filter(vm.tags, {selected: true});
vm.selectionsChanged(false);
vm.selectedTags = _.filter(vm.tags, {selected: true});
vm.selectionsChanged(false);
});
};
vm.keyDown = function (evt) {
......@@ -141,10 +147,16 @@ function (angular, app, _) {
}
}
vm.variable.current = {
text: _.pluck(selected, 'text').join(', '),
value: _.pluck(selected, 'value'),
};
// validate selected tags
_.each(vm.selectedTags, function(tag) {
_.each(tag.values, function(value) {
if (!_.findWhere(selected, {value: value})) {
tag.selected = false;
}
});
});
vm.selectedTags = _.filter(vm.tags, {selected: true});
var valuesNotInTag = _.filter(selected, function(test) {
for (var i = 0; i < vm.selectedTags.length; i++) {
......@@ -156,8 +168,9 @@ function (angular, app, _) {
return true;
});
vm.variable.current = {};
vm.variable.current.value = _.pluck(selected, 'value');
vm.variable.current.text = _.pluck(valuesNotInTag, 'text').join(', ');
vm.selectedValuesCount = vm.variable.current.value.length;
// only single value
......@@ -195,12 +208,12 @@ function (angular, app, _) {
});
angular
angular
.module('grafana.directives')
.directive('variableValueSelect', function($compile, $window, $timeout) {
return {
scope: { variable: "=", onUpdated: "&" },
scope: { variable: "=", onUpdated: "&", getValuesForTag: "&" },
templateUrl: 'app/features/dashboard/partials/variableValueSelect.html',
controller: 'SelectDropdownCtrl',
controllerAs: 'vm',
......@@ -209,7 +222,6 @@ function (angular, app, _) {
var bodyEl = angular.element($window.document.body);
var linkEl = elem.find('.variable-value-link');
var inputEl = elem.find('input');
var cancelBlur = null;
function openDropdown() {
inputEl.css('width', Math.max(linkEl.width(), 30) + 'px');
......@@ -217,27 +229,13 @@ function (angular, app, _) {
inputEl.show();
linkEl.hide();
linkEl.hide();
inputEl.show();
inputEl.focus();
$timeout(function() { bodyEl.on('click', bodyOnClick); }, 0, false);
}
function switchToLink(now) {
if (now === true || cancelBlur) {
clearTimeout(cancelBlur);
cancelBlur = null;
inputEl.hide();
linkEl.show();
}
else {
// need to have long delay because the blur
// happens long before the click event on the typeahead options
cancelBlur = setTimeout(scope.switchToLink, 50);
}
function switchToLink() {
inputEl.hide();
linkEl.show();
bodyEl.off('click', bodyOnClick);
}
......@@ -252,7 +250,7 @@ function (angular, app, _) {
scope.$watch('vm.dropdownVisible', function(newValue) {
if (newValue) {
openDropdown();
} {
} else {
switchToLink();
}
});
......
......@@ -28,6 +28,10 @@ function (angular, _) {
$rootScope.$broadcast('refresh');
};
$scope.getValuesForTag = function() {
return $q.when(['backend_01', 'backend_02']);
};
$scope.variableUpdated = function(variable) {
templateValuesSrv.variableUpdated(variable).then(function() {
dynamicDashboardSrv.update($scope.dashboard);
......
......@@ -6,7 +6,7 @@
<span class="template-variable tight-form-item" ng-show="!variable.hideLabel" style="padding-right: 5px">
{{variable.label || variable.name}}:
</span>
<variable-value-select variable="variable" on-updated="variableUpdated(variable)"></variable-value-select>
<variable-value-select variable="variable" on-updated="variableUpdated(variable)" get-values-for-tag="getValuesForTag(tagKey)"></variable-value-select>
</li>
</ul>
......
......@@ -8,11 +8,17 @@ function () {
describe("SelectDropdownCtrl", function() {
var scope;
var ctrl;
var tagValuesMap = {};
var rootScope;
beforeEach(module('grafana.controllers'));
beforeEach(inject(function($controller, $rootScope) {
beforeEach(inject(function($controller, $rootScope, $q) {
rootScope = $rootScope;
scope = $rootScope.$new();
ctrl = $controller('SelectDropdownCtrl', {$scope: scope});
ctrl.getValuesForTag = function(obj) {
return $q.when(tagValuesMap[obj.tagKey]);
};
}));
describe("Given simple variable", function() {
......@@ -24,9 +30,71 @@ function () {
it("Should init labelText and linkText", function() {
expect(ctrl.linkText).to.be("hej");
});
});
});
describe("Given variable with tags and dropdown is opened", function() {
beforeEach(function() {
ctrl.variable = {
current: {text: 'hej', value: 'hej'},
options: [
{text: 'server-1', value: 'server-1'},
{text: 'server-2', value: 'server-2'},
{text: 'server-3', value: 'server-3'},
],
tags: ["key1", "key2", "key3"]
};
tagValuesMap.key1 = ['server-1', 'server-3'];
tagValuesMap.key2 = ['server-2', 'server-3'];
tagValuesMap.key3 = ['server-1', 'server-2', 'server-3'];
ctrl.init();
ctrl.show();
});
it("should init tags model", function() {
expect(ctrl.tags.length).to.be(3);
expect(ctrl.tags[0].text).to.be("key1");
});
it("should init options model", function() {
expect(ctrl.options.length).to.be(3);
});
describe('When tag is selected', function() {
beforeEach(function() {
ctrl.selectTag(ctrl.tags[0]);
rootScope.$digest();
});
it("should select tag", function() {
expect(ctrl.selectedTags.length).to.be(1);
});
it("should select values", function() {
expect(ctrl.options[0].selected).to.be(true);
expect(ctrl.options[2].selected).to.be(true);
});
describe('and then unselected', function() {
beforeEach(function() {
ctrl.selectTag(ctrl.tags[0]);
rootScope.$digest();
});
it("should deselect tag", function() {
expect(ctrl.selectedTags.length).to.be(0);
});
});
describe('and then value is unselected', function() {
beforeEach(function() {
ctrl.optionSelected(ctrl.options[0]);
});
it("should deselect tag", function() {
expect(ctrl.selectedTags.length).to.be(0);
});
});
});
});
});
});
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