Commit dfe0f911 by Torkel Ödegaard

feat(adhoc): adhoc filters progress

parent 6e429b85
......@@ -18,7 +18,7 @@ export class AdhocVariable implements Variable {
};
/** @ngInject **/
constructor(private model, private timeSrv, private templateSrv, private variableSrv) {
constructor(private model) {
assignModelProperties(this, model, this.defaults);
}
......@@ -68,7 +68,7 @@ export class AdhocVariable implements Variable {
}
variableTypes['adhoc'] = {
name: 'Ad hoc',
name: 'Ad hoc filters',
ctor: AdhocVariable,
description: 'Ad hoc filters',
description: 'Add key/value filters on the fly',
};
import {describe, beforeEach, it, sinon, expect, angularMocks} from 'test/lib/common';
import {AdhocVariable} from '../adhoc_variable';
describe('AdhocVariable', function() {
describe('when serializing to url', function() {
it('should set return key value and op seperated by pipe', function() {
var variable = new AdhocVariable({
filters: [
{key: 'key1', operator: '=', value: 'value1'},
{key: 'key2', operator: '!=', value: 'value2'},
]
});
var urlValue = variable.getValueForUrl();
expect(urlValue).to.eql(["key1|=|value1", "key2|!=|value2"]);
});
});
describe('when deserializing from url', function() {
it('should restore filters', function() {
var variable = new AdhocVariable({});
variable.setValueFromUrl(["key1|=|value1", "key2|!=|value2"]);
expect(variable.filters[0].key).to.be('key1');
expect(variable.filters[0].operator).to.be('=');
expect(variable.filters[0].value).to.be('value1');
expect(variable.filters[1].key).to.be('key2');
expect(variable.filters[1].operator).to.be('!=');
expect(variable.filters[1].value).to.be('value2');
});
});
});
......@@ -15,6 +15,7 @@ function (angular, _, kbn) {
this._index = {};
this._texts = {};
this._grafanaVariables = {};
this._adhocVariables = {};
this.init = function(variables) {
this.variables = variables;
......@@ -23,16 +24,33 @@ function (angular, _, kbn) {
this.updateTemplateData = function() {
this._index = {};
this._filters = {};
for (var i = 0; i < this.variables.length; i++) {
var variable = this.variables[i];
// add adhoc filters to it's own index
if (variable.type === 'adhoc') {
this._adhocVariables[variable.datasource] = variable;
continue;
}
if (!variable.current || !variable.current.isNone && !variable.current.value) {
continue;
}
this._index[variable.name] = variable;
}
};
this.getAdhocFilters = function(datasourceName) {
var variable = this._adhocVariables[datasourceName];
if (variable) {
return variable.filters || [];
}
return []
};
function luceneEscape(value) {
return value.replace(/([\!\*\+\-\=<>\s\&\|\(\)\[\]\{\}\^\~\?\:\\/"])/g, "\\$1");
}
......
......@@ -44,36 +44,23 @@ export default class InfluxDatasource {
query(options) {
var timeFilter = this.getTimeFilter(options);
var scopedVars = _.extend({}, options.scopedVars);
var scopedVars = options.scopedVars ? _.cloneDeep(options.scopedVars) : {};
var targets = _.cloneDeep(options.targets);
var queryTargets = [];
var queryModel;
var i, y;
var allQueries = _.map(targets, target => {
if (target.hide) { return ""; }
if (!target.rawQuery) {
// apply add hoc filters
for (let variable of this.templateSrv.variables) {
if (variable.type === 'adhoc' && variable.datasource === this.name) {
for (let filter of variable.filters) {
if (filter.key !== undefined && filter.value !== undefined) {
target.tags.push({key: filter.key, value: filter.value, condition: filter.condition, operator: filter.operator});
}
}
}
}
}
queryTargets.push(target);
// build query
scopedVars.interval = {value: target.interval || options.interval};
var queryModel = new InfluxQuery(target, this.templateSrv, scopedVars);
var query = queryModel.render(true);
queryModel = new InfluxQuery(target, this.templateSrv, scopedVars);
return queryModel.render(true);
return query;
}).reduce((acc, current) => {
if (current !== "") {
acc += ";" + current;
......@@ -81,6 +68,16 @@ export default class InfluxDatasource {
return acc;
});
if (allQueries === '') {
return this.$q.when({data: []});
}
// add global adhoc filters to timeFilter
var adhocFilters = this.templateSrv.getAdhocFilters(this.name);
if (adhocFilters.length > 0 ) {
timeFilter += ' AND ' + queryModel.renderAdhocFilters(adhocFilters);
}
// replace grafana variables
scopedVars.timeFilter = {value: timeFilter};
......@@ -120,7 +117,7 @@ export default class InfluxDatasource {
}
}
return { data: seriesList };
return {data: seriesList};
});
};
......
......@@ -251,4 +251,11 @@ export default class InfluxQuery {
return query;
}
renderAdhocFilters(filters) {
var conditions = _.map(filters, (tag, index) => {
return this.renderTagCondition(tag, index, false);
});
return conditions.join(' ');
}
}
......@@ -237,6 +237,19 @@ describe('InfluxQuery', function() {
expect(query.target.select[0][2].type).to.be('math');
});
describe('when render adhoc filters', function() {
it('should generate correct query segment', function() {
var query = new InfluxQuery({measurement: 'cpu', }, templateSrv, {});
var queryText = query.renderAdhocFilters([
{key: 'key1', operator: '=', value: 'value1'},
{key: 'key2', operator: '!=', value: 'value2'},
]);
expect(queryText).to.be('"key1" = \'value1\' AND "key2" != \'value2\'');
});
});
});
});
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