Skip to content

Commit

Permalink
Progress on template variable dropdown, lots of unit tests for select…
Browse files Browse the repository at this point in the history
…ion behavior,
  • Loading branch information
torkelo committed May 29, 2015
1 parent cc1e2eb commit be1a4a4
Show file tree
Hide file tree
Showing 4 changed files with 114 additions and 44 deletions.
78 changes: 38 additions & 40 deletions public/app/directives/variableValueSelect.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ function (angular, app, _) {

angular
.module('grafana.controllers')
.controller('SelectDropdownCtrl', function() {
.controller('SelectDropdownCtrl', function($q) {
var vm = this;

vm.show = function() {
Expand Down Expand Up @@ -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) {
Expand Down Expand Up @@ -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++) {
Expand All @@ -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
Expand Down Expand Up @@ -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',
Expand All @@ -209,35 +222,20 @@ 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');

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);
}

Expand All @@ -252,7 +250,7 @@ function (angular, app, _) {
scope.$watch('vm.dropdownVisible', function(newValue) {
if (newValue) {
openDropdown();
} {
} else {
switchToLink();
}
});
Expand Down
4 changes: 4 additions & 0 deletions public/app/features/dashboard/submenuCtrl.js
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
2 changes: 1 addition & 1 deletion public/app/partials/submenu.html
Original file line number Diff line number Diff line change
Expand Up @@ -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>

Expand Down
74 changes: 71 additions & 3 deletions public/test/specs/selectDropdownCtrl-specs.js
Original file line number Diff line number Diff line change
Expand Up @@ -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() {
Expand All @@ -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);
});
});
});
});
});
});

0 comments on commit be1a4a4

Please sign in to comment.