Commit 3af4b1ff by Torkel Ödegaard

Merge pull request #4287 from grafana/raintank-issue4283

refactor how template vars are updated. fixes #4283
parents 17006b45 6fac4714
......@@ -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];
promises.push(this.processVariable(variable, queryParams));
}
return $q.all(promises);
};
this.processVariable = function(variable, queryParams) {
var dependencies = [];
var lock = self.variableLock[variable.name];
// 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) {
promises.push(this.setVariableFromUrl(variable, urlValue));
return self.setVariableFromUrl(variable, urlValue).then(lock.resolve);
}
else if (variable.refresh) {
promises.push(this.updateOptions(variable));
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') {
this.updateAutoInterval(variable);
self.updateAutoInterval(variable);
lock.resolve();
} else {
lock.resolve();
}
}
return $q.all(promises);
});
};
this.setVariableFromUrl = function(variable, urlValue) {
var option = _.findWhere(variable.options, { text: urlValue });
option = option || { text: urlValue, value: urlValue };
var promise = $q.when(true);
if (variable.refresh) {
promise = this.updateOptions(variable);
}
this.updateAutoInterval(variable);
return this.setVariableValue(variable, option);
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]);
......
......@@ -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() {
......
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