Merge pull request #4287 from grafana/raintank-issue4283

refactor how template vars are updated. fixes #4283
This commit is contained in:
Torkel Ödegaard 2016-03-08 11:33:37 +01:00
commit 3af4b1ff98
2 changed files with 73 additions and 23 deletions

View File

@ -27,29 +27,71 @@ function (angular, _, kbn) {
var queryParams = $location.search();
var promises = [];
// use promises to delay processing variables that
// depend on other variables.
this.variableLock = {};
_.forEach(this.variables, function(variable) {
self.variableLock[variable.name] = $q.defer();
});
for (var i = 0; i < this.variables.length; i++) {
var variable = this.variables[i];
var urlValue = queryParams['var-' + variable.name];
if (urlValue !== void 0) {
promises.push(this.setVariableFromUrl(variable, urlValue));
}
else if (variable.refresh) {
promises.push(this.updateOptions(variable));
}
else if (variable.type === 'interval') {
this.updateAutoInterval(variable);
}
promises.push(this.processVariable(variable, queryParams));
}
return $q.all(promises);
};
this.setVariableFromUrl = function(variable, urlValue) {
var option = _.findWhere(variable.options, { text: urlValue });
option = option || { text: urlValue, value: urlValue };
this.processVariable = function(variable, queryParams) {
var dependencies = [];
var lock = self.variableLock[variable.name];
this.updateAutoInterval(variable);
return this.setVariableValue(variable, option);
// determine our dependencies.
if (variable.type === "query") {
_.forEach(this.variables, function(v) {
if (templateSrv.containsVariable(variable.query, v.name)) {
dependencies.push(self.variableLock[v.name].promise);
}
});
}
return $q.all(dependencies).then(function() {
var urlValue = queryParams['var-' + variable.name];
if (urlValue !== void 0) {
return self.setVariableFromUrl(variable, urlValue).then(lock.resolve);
}
else if (variable.refresh) {
return self.updateOptions(variable).then(function() {
if (_.isEmpty(variable.current) && variable.options.length) {
console.log("setting current for %s", variable.name);
self.setVariableValue(variable, variable.options[0]);
}
lock.resolve();
});
}
else if (variable.type === 'interval') {
self.updateAutoInterval(variable);
lock.resolve();
} else {
lock.resolve();
}
});
};
this.setVariableFromUrl = function(variable, urlValue) {
var promise = $q.when(true);
if (variable.refresh) {
promise = this.updateOptions(variable);
}
return promise.then(function() {
var option = _.findWhere(variable.options, { text: urlValue });
option = option || { text: urlValue, value: urlValue };
self.updateAutoInterval(variable);
return self.setVariableValue(variable, option, true);
});
};
this.updateAutoInterval = function(variable) {
@ -64,7 +106,7 @@ function (angular, _, kbn) {
templateSrv.setGrafanaVariable('$__auto_interval', interval);
};
this.setVariableValue = function(variable, option) {
this.setVariableValue = function(variable, option, initPhase) {
variable.current = angular.copy(option);
if (_.isArray(variable.current.value)) {
@ -72,8 +114,14 @@ function (angular, _, kbn) {
}
self.selectOptionsForCurrentValue(variable);
templateSrv.updateTemplateData();
// on first load, variable loading is ordered to ensure
// that parents are updated before children.
if (initPhase) {
return $q.when();
}
return self.updateOptionsInChildVariables(variable);
};
@ -145,7 +193,7 @@ function (angular, _, kbn) {
this.validateVariableSelectionState = function(variable) {
if (!variable.current) {
if (!variable.options.length) { return; }
return self.setVariableValue(variable, variable.options[0]);
return self.setVariableValue(variable, variable.options[0], true);
}
if (_.isArray(variable.current.value)) {
@ -153,7 +201,7 @@ function (angular, _, kbn) {
} else {
var currentOption = _.findWhere(variable.options, { text: variable.current.text });
if (currentOption) {
return self.setVariableValue(variable, currentOption);
return self.setVariableValue(variable, currentOption, true);
} else {
if (!variable.options.length) { return; }
return self.setVariableValue(variable, variable.options[0]);

View File

@ -34,12 +34,13 @@ define([
options: [{text: "test", value: "test"}]
};
beforeEach(function() {
beforeEach(function(done) {
var dashboard = { templating: { list: [variable] } };
var urlParams = {};
urlParams["var-apps"] = "new";
ctx.$location.search = sinon.stub().returns(urlParams);
ctx.service.init(dashboard);
ctx.service.init(dashboard).then(function() { done(); });
ctx.$rootScope.$digest();
});
it('should update current value', function() {
@ -56,12 +57,13 @@ define([
options: [{text: "val1", value: "val1"}, {text: 'val2', value: 'val2'}, {text: 'val3', value: 'val3', selected: true}]
};
beforeEach(function() {
beforeEach(function(done) {
var dashboard = { templating: { list: [variable] } };
var urlParams = {};
urlParams["var-apps"] = ["val2", "val1"];
ctx.$location.search = sinon.stub().returns(urlParams);
ctx.service.init(dashboard);
ctx.service.init(dashboard).then(function() { done(); });
ctx.$rootScope.$digest();
});
it('should update current value', function() {