tech: ran pretttier on all typescript files

This commit is contained in:
Torkel Ödegaard
2017-12-19 16:06:54 +01:00
parent b1621e1e8f
commit fadfc665e4
355 changed files with 20624 additions and 14931 deletions

View File

@@ -1,16 +1,16 @@
import _ from 'lodash';
import {Variable, assignModelProperties, variableTypes} from './variable';
import _ from "lodash";
import { Variable, assignModelProperties, variableTypes } from "./variable";
export class AdhocVariable implements Variable {
filters: any[];
defaults = {
type: 'adhoc',
name: '',
label: '',
type: "adhoc",
name: "",
label: "",
hide: 0,
datasource: null,
filters: [],
filters: []
};
/** @ngInject **/
@@ -41,13 +41,13 @@ export class AdhocVariable implements Variable {
}
this.filters = urlValue.map(item => {
var values = item.split('|').map(value => {
var values = item.split("|").map(value => {
return this.unescapeDelimiter(value);
});
return {
key: values[0],
operator: values[1],
value: values[2],
value: values[2]
};
});
@@ -56,18 +56,20 @@ export class AdhocVariable implements Variable {
getValueForUrl() {
return this.filters.map(filter => {
return [filter.key, filter.operator, filter.value].map(value => {
return this.escapeDelimiter(value);
}).join('|');
return [filter.key, filter.operator, filter.value]
.map(value => {
return this.escapeDelimiter(value);
})
.join("|");
});
}
escapeDelimiter(value) {
return value.replace(/\|/g, '__gfp__');
return value.replace(/\|/g, "__gfp__");
}
unescapeDelimiter(value) {
return value.replace(/__gfp__/g, '|');
return value.replace(/__gfp__/g, "|");
}
setFilters(filters: any[]) {
@@ -75,8 +77,8 @@ export class AdhocVariable implements Variable {
}
}
variableTypes['adhoc'] = {
name: 'Ad hoc filters',
variableTypes["adhoc"] = {
name: "Ad hoc filters",
ctor: AdhocVariable,
description: 'Add key/value filters on the fly',
description: "Add key/value filters on the fly"
};

View File

@@ -1,6 +1,6 @@
///<reference path="../../headers/common.d.ts" />
import {Variable, assignModelProperties, variableTypes} from './variable';
import { Variable, assignModelProperties, variableTypes } from "./variable";
export class ConstantVariable implements Variable {
query: string;
@@ -8,13 +8,13 @@ export class ConstantVariable implements Variable {
current: any;
defaults = {
type: 'constant',
name: '',
type: "constant",
name: "",
hide: 2,
label: '',
query: '',
label: "",
query: "",
current: {},
options: [],
options: []
};
/** @ngInject **/
@@ -32,7 +32,7 @@ export class ConstantVariable implements Variable {
}
updateOptions() {
this.options = [{text: this.query.trim(), value: this.query.trim()}];
this.options = [{ text: this.query.trim(), value: this.query.trim() }];
this.setValue(this.options[0]);
return Promise.resolve();
}
@@ -48,11 +48,11 @@ export class ConstantVariable implements Variable {
getValueForUrl() {
return this.current.value;
}
}
variableTypes['constant'] = {
name: 'Constant',
variableTypes["constant"] = {
name: "Constant",
ctor: ConstantVariable,
description: 'Define a hidden constant variable, useful for metric prefixes in dashboards you want to share' ,
description:
"Define a hidden constant variable, useful for metric prefixes in dashboards you want to share"
};

View File

@@ -1,7 +1,7 @@
///<reference path="../../headers/common.d.ts" />
import _ from 'lodash';
import {Variable, assignModelProperties, variableTypes} from './variable';
import _ from "lodash";
import { Variable, assignModelProperties, variableTypes } from "./variable";
export class CustomVariable implements Variable {
query: string;
@@ -11,16 +11,16 @@ export class CustomVariable implements Variable {
current: any;
defaults = {
type: 'custom',
name: '',
label: '',
type: "custom",
name: "",
label: "",
hide: 0,
options: [],
current: {},
query: '',
query: "",
includeAll: false,
multi: false,
allValue: null,
allValue: null
};
/** @ngInject **/
@@ -51,7 +51,7 @@ export class CustomVariable implements Variable {
}
addAllOption() {
this.options.unshift({text: 'All', value: "$__all"});
this.options.unshift({ text: "All", value: "$__all" });
}
dependsOn(variable) {
@@ -63,16 +63,16 @@ export class CustomVariable implements Variable {
}
getValueForUrl() {
if (this.current.text === 'All') {
return 'All';
if (this.current.text === "All") {
return "All";
}
return this.current.value;
}
}
variableTypes['custom'] = {
name: 'Custom',
variableTypes["custom"] = {
name: "Custom",
ctor: CustomVariable,
description: 'Define variable values manually' ,
supportsMulti: true,
description: "Define variable values manually",
supportsMulti: true
};

View File

@@ -1,7 +1,12 @@
///<reference path="../../headers/common.d.ts" />
import kbn from 'app/core/utils/kbn';
import {Variable, containsVariable, assignModelProperties, variableTypes} from './variable';
import kbn from "app/core/utils/kbn";
import {
Variable,
containsVariable,
assignModelProperties,
variableTypes
} from "./variable";
export class DatasourceVariable implements Variable {
regex: any;
@@ -10,20 +15,25 @@ export class DatasourceVariable implements Variable {
current: any;
refresh: any;
defaults = {
type: 'datasource',
name: '',
defaults = {
type: "datasource",
name: "",
hide: 0,
label: '',
label: "",
current: {},
regex: '',
regex: "",
options: [],
query: '',
refresh: 1,
query: "",
refresh: 1
};
/** @ngInject **/
constructor(private model, private datasourceSrv, private variableSrv, private templateSrv) {
constructor(
private model,
private datasourceSrv,
private variableSrv,
private templateSrv
) {
assignModelProperties(this, model, this.defaults);
this.refresh = 1;
}
@@ -42,11 +52,11 @@ export class DatasourceVariable implements Variable {
updateOptions() {
var options = [];
var sources = this.datasourceSrv.getMetricSources({skipVariables: true});
var sources = this.datasourceSrv.getMetricSources({ skipVariables: true });
var regex;
if (this.regex) {
regex = this.templateSrv.replace(this.regex, null, 'regex');
regex = this.templateSrv.replace(this.regex, null, "regex");
regex = kbn.stringToJsRegex(regex);
}
@@ -61,11 +71,11 @@ export class DatasourceVariable implements Variable {
continue;
}
options.push({text: source.name, value: source.name});
options.push({ text: source.name, value: source.name });
}
if (options.length === 0) {
options.push({text: 'No data sources found', value: ''});
options.push({ text: "No data sources found", value: "" });
}
this.options = options;
@@ -88,8 +98,9 @@ export class DatasourceVariable implements Variable {
}
}
variableTypes['datasource'] = {
name: 'Datasource',
variableTypes["datasource"] = {
name: "Datasource",
ctor: DatasourceVariable,
description: 'Enabled you to dynamically switch the datasource for multiple panels',
description:
"Enabled you to dynamically switch the datasource for multiple panels"
};

View File

@@ -1,9 +1,8 @@
import _ from 'lodash';
import coreModule from 'app/core/core_module';
import {variableTypes} from './variable';
import _ from "lodash";
import coreModule from "app/core/core_module";
import { variableTypes } from "./variable";
export class VariableEditorCtrl {
/** @ngInject **/
constructor($scope, datasourceSrv, variableSrv, templateSrv) {
$scope.variableTypes = variableTypes;
@@ -11,33 +10,33 @@ export class VariableEditorCtrl {
$scope.namePattern = /^(?!__).*$/;
$scope.refreshOptions = [
{value: 0, text: "Never"},
{value: 1, text: "On Dashboard Load"},
{value: 2, text: "On Time Range Change"},
{ value: 0, text: "Never" },
{ value: 1, text: "On Dashboard Load" },
{ value: 2, text: "On Time Range Change" }
];
$scope.sortOptions = [
{value: 0, text: "Disabled"},
{value: 1, text: "Alphabetical (asc)"},
{value: 2, text: "Alphabetical (desc)"},
{value: 3, text: "Numerical (asc)"},
{value: 4, text: "Numerical (desc)"},
{ value: 0, text: "Disabled" },
{ value: 1, text: "Alphabetical (asc)" },
{ value: 2, text: "Alphabetical (desc)" },
{ value: 3, text: "Numerical (asc)" },
{ value: 4, text: "Numerical (desc)" }
];
$scope.hideOptions = [
{value: 0, text: ""},
{value: 1, text: "Label"},
{value: 2, text: "Variable"},
{ value: 0, text: "" },
{ value: 1, text: "Label" },
{ value: 2, text: "Variable" }
];
$scope.init = function() {
$scope.mode = 'list';
$scope.mode = "list";
$scope.variables = variableSrv.variables;
$scope.reset();
$scope.$watch('mode', function(val) {
if (val === 'new') {
$scope.$watch("mode", function(val) {
if (val === "new") {
$scope.reset();
}
});
@@ -60,18 +59,33 @@ export class VariableEditorCtrl {
}
if (!$scope.current.name.match(/^\w+$/)) {
$scope.appEvent('alert-warning', ['Validation', 'Only word and digit characters are allowed in variable names']);
$scope.appEvent("alert-warning", [
"Validation",
"Only word and digit characters are allowed in variable names"
]);
return false;
}
var sameName = _.find($scope.variables, { name: $scope.current.name });
if (sameName && sameName !== $scope.current) {
$scope.appEvent('alert-warning', ['Validation', 'Variable with the same name already exists']);
$scope.appEvent("alert-warning", [
"Validation",
"Variable with the same name already exists"
]);
return false;
}
if ($scope.current.type === 'query' && $scope.current.query.match(new RegExp('\\$' + $scope.current.name + '(/| |$)'))) {
$scope.appEvent('alert-warning', ['Validation', 'Query cannot contain a reference to itself. Variable: $' + $scope.current.name]);
if (
$scope.current.type === "query" &&
$scope.current.query.match(
new RegExp("\\$" + $scope.current.name + "(/| |$)")
)
) {
$scope.appEvent("alert-warning", [
"Validation",
"Query cannot contain a reference to itself. Variable: $" +
$scope.current.name
]);
return false;
}
@@ -79,35 +93,47 @@ export class VariableEditorCtrl {
};
$scope.validate = function() {
$scope.infoText = '';
if ($scope.current.type === 'adhoc' && $scope.current.datasource !== null) {
$scope.infoText = 'Adhoc filters are applied automatically to all queries that target this datasource';
$scope.infoText = "";
if (
$scope.current.type === "adhoc" &&
$scope.current.datasource !== null
) {
$scope.infoText =
"Adhoc filters are applied automatically to all queries that target this datasource";
datasourceSrv.get($scope.current.datasource).then(ds => {
if (!ds.getTagKeys) {
$scope.infoText = 'This datasource does not support adhoc filters yet.';
$scope.infoText =
"This datasource does not support adhoc filters yet.";
}
});
}
};
$scope.runQuery = function() {
return variableSrv.updateOptions($scope.current).then(null, function(err) {
if (err.data && err.data.message) { err.message = err.data.message; }
$scope.appEvent("alert-error", ['Templating', 'Template variables could not be initialized: ' + err.message]);
});
return variableSrv
.updateOptions($scope.current)
.then(null, function(err) {
if (err.data && err.data.message) {
err.message = err.data.message;
}
$scope.appEvent("alert-error", [
"Templating",
"Template variables could not be initialized: " + err.message
]);
});
};
$scope.edit = function(variable) {
$scope.current = variable;
$scope.currentIsNew = false;
$scope.mode = 'edit';
$scope.mode = "edit";
$scope.validate();
};
$scope.duplicate = function(variable) {
var clone = _.cloneDeep(variable.getSaveModel());
$scope.current = variableSrv.createVariableFromModel(clone);
$scope.current.name = 'copy_of_'+variable.name;
$scope.current.name = "copy_of_" + variable.name;
variableSrv.addVariable($scope.current);
};
@@ -115,7 +141,7 @@ export class VariableEditorCtrl {
if ($scope.isValid()) {
$scope.runQuery().then(function() {
$scope.reset();
$scope.mode = 'list';
$scope.mode = "list";
templateSrv.updateTemplateData();
});
}
@@ -123,21 +149,28 @@ export class VariableEditorCtrl {
$scope.reset = function() {
$scope.currentIsNew = true;
$scope.current = variableSrv.createVariableFromModel({type: 'query'});
$scope.current = variableSrv.createVariableFromModel({ type: "query" });
// this is done here in case a new data source type variable was added
$scope.datasources = _.filter(datasourceSrv.getMetricSources(), function(ds) {
$scope.datasources = _.filter(datasourceSrv.getMetricSources(), function(
ds
) {
return !ds.meta.mixed && ds.value !== null;
});
$scope.datasourceTypes = _($scope.datasources).uniqBy('meta.id').map(function(ds) {
return {text: ds.meta.name, value: ds.meta.id};
}).value();
$scope.datasourceTypes = _($scope.datasources)
.uniqBy("meta.id")
.map(function(ds) {
return { text: ds.meta.name, value: ds.meta.id };
})
.value();
};
$scope.typeChanged = function() {
var old = $scope.current;
$scope.current = variableSrv.createVariableFromModel({type: $scope.current.type});
$scope.current = variableSrv.createVariableFromModel({
type: $scope.current.type
});
$scope.current.name = old.name;
$scope.current.hide = old.hide;
$scope.current.label = old.label;
@@ -156,5 +189,4 @@ export class VariableEditorCtrl {
}
}
coreModule.controller('VariableEditorCtrl', VariableEditorCtrl);
coreModule.controller("VariableEditorCtrl", VariableEditorCtrl);

View File

@@ -1,8 +1,8 @@
///<reference path="../../headers/common.d.ts" />
import _ from 'lodash';
import kbn from 'app/core/utils/kbn';
import {Variable, assignModelProperties, variableTypes} from './variable';
import _ from "lodash";
import kbn from "app/core/utils/kbn";
import { Variable, assignModelProperties, variableTypes } from "./variable";
export class IntervalVariable implements Variable {
name: string;
@@ -15,21 +15,26 @@ export class IntervalVariable implements Variable {
current: any;
defaults = {
type: 'interval',
name: '',
type: "interval",
name: "",
hide: 0,
label: '',
label: "",
refresh: 2,
options: [],
current: {},
query: '1m,10m,30m,1h,6h,12h,1d,7d,14d,30d',
query: "1m,10m,30m,1h,6h,12h,1d,7d,14d,30d",
auto: false,
auto_min: '10s',
auto_count: 30,
auto_min: "10s",
auto_count: 30
};
/** @ngInject **/
constructor(private model, private timeSrv, private templateSrv, private variableSrv) {
constructor(
private model,
private timeSrv,
private templateSrv,
private variableSrv
) {
assignModelProperties(this, model, this.defaults);
this.refresh = 2;
}
@@ -50,21 +55,33 @@ export class IntervalVariable implements Variable {
}
// add auto option if missing
if (this.options.length && this.options[0].text !== 'auto') {
this.options.unshift({ text: 'auto', value: '$__auto_interval_' + this.name });
if (this.options.length && this.options[0].text !== "auto") {
this.options.unshift({
text: "auto",
value: "$__auto_interval_" + this.name
});
}
var res = kbn.calculateInterval(this.timeSrv.timeRange(), this.auto_count, this.auto_min);
this.templateSrv.setGrafanaVariable('$__auto_interval_' + this.name, res.interval);
var res = kbn.calculateInterval(
this.timeSrv.timeRange(),
this.auto_count,
this.auto_min
);
this.templateSrv.setGrafanaVariable(
"$__auto_interval_" + this.name,
res.interval
);
// for backward compatibility, to be removed eventually
this.templateSrv.setGrafanaVariable('$__auto_interval', res.interval);
this.templateSrv.setGrafanaVariable("$__auto_interval", res.interval);
}
updateOptions() {
// extract options between quotes and/or comma
this.options = _.map(this.query.match(/(["'])(.*?)\1|\w+/g), function(text) {
text = text.replace(/["']+/g, '');
return {text: text.trim(), value: text.trim()};
this.options = _.map(this.query.match(/(["'])(.*?)\1|\w+/g), function(
text
) {
text = text.replace(/["']+/g, "");
return { text: text.trim(), value: text.trim() };
});
this.updateAutoValue();
@@ -85,8 +102,8 @@ export class IntervalVariable implements Variable {
}
}
variableTypes['interval'] = {
name: 'Interval',
variableTypes["interval"] = {
name: "Interval",
ctor: IntervalVariable,
description: 'Define a timespan interval (ex 1m, 1h, 1d)',
description: "Define a timespan interval (ex 1m, 1h, 1d)"
};

View File

@@ -1,9 +1,14 @@
import _ from 'lodash';
import kbn from 'app/core/utils/kbn';
import {Variable, containsVariable, assignModelProperties, variableTypes} from './variable';
import _ from "lodash";
import kbn from "app/core/utils/kbn";
import {
Variable,
containsVariable,
assignModelProperties,
variableTypes
} from "./variable";
function getNoneOption() {
return { text: 'None', value: '', isNone: true };
return { text: "None", value: "", isNone: true };
}
export class QueryVariable implements Variable {
@@ -24,15 +29,15 @@ export class QueryVariable implements Variable {
tags: any[];
defaults = {
type: 'query',
type: "query",
label: null,
query: '',
regex: '',
query: "",
regex: "",
sort: 0,
datasource: null,
refresh: 0,
hide: 0,
name: '',
name: "",
multi: false,
includeAll: false,
allValue: null,
@@ -41,11 +46,17 @@ export class QueryVariable implements Variable {
tags: [],
useTags: false,
tagsQuery: "",
tagValuesQuery: "",
tagValuesQuery: ""
};
/** @ngInject **/
constructor(private model, private datasourceSrv, private templateSrv, private variableSrv, private timeSrv) {
constructor(
private model,
private datasourceSrv,
private templateSrv,
private variableSrv,
private timeSrv
) {
// copy model properties to this instance
assignModelProperties(this, model, this.defaults);
}
@@ -71,17 +82,23 @@ export class QueryVariable implements Variable {
}
getValueForUrl() {
if (this.current.text === 'All') {
return 'All';
if (this.current.text === "All") {
return "All";
}
return this.current.value;
}
updateOptions() {
return this.datasourceSrv.get(this.datasource)
.then(this.updateOptionsFromMetricFindQuery.bind(this))
.then(this.updateTags.bind(this))
.then(this.variableSrv.validateVariableSelectionState.bind(this.variableSrv, this));
return this.datasourceSrv
.get(this.datasource)
.then(this.updateOptionsFromMetricFindQuery.bind(this))
.then(this.updateTags.bind(this))
.then(
this.variableSrv.validateVariableSelectionState.bind(
this.variableSrv,
this
)
);
}
updateTags(datasource) {
@@ -102,8 +119,8 @@ export class QueryVariable implements Variable {
getValuesForTag(tagKey) {
return this.datasourceSrv.get(this.datasource).then(datasource => {
var query = this.tagValuesQuery.replace('$tag', tagKey);
return this.metricFindQuery(datasource, query).then(function (results) {
var query = this.tagValuesQuery.replace("$tag", tagKey);
return this.metricFindQuery(datasource, query).then(function(results) {
return _.map(results, function(value) {
return value.text;
});
@@ -125,7 +142,7 @@ export class QueryVariable implements Variable {
}
metricFindQuery(datasource, query) {
var options = {range: undefined, variable: this};
var options = { range: undefined, variable: this };
if (this.refresh === 2) {
options.range = this.timeSrv.timeRange();
@@ -135,7 +152,7 @@ export class QueryVariable implements Variable {
}
addAllOption() {
this.options.unshift({text: 'All', value: "$__all"});
this.options.unshift({ text: "All", value: "$__all" });
}
metricNamesToVariableValues(metricNames) {
@@ -143,17 +160,19 @@ export class QueryVariable implements Variable {
options = [];
if (this.regex) {
regex = kbn.stringToJsRegex(this.templateSrv.replace(this.regex, {}, 'regex'));
regex = kbn.stringToJsRegex(
this.templateSrv.replace(this.regex, {}, "regex")
);
}
for (i = 0; i < metricNames.length; i++) {
var item = metricNames[i];
var text = item.text === undefined || item.text === null
? item.value
: item.text;
var text =
item.text === undefined || item.text === null ? item.value : item.text;
var value = item.value === undefined || item.value === null
? item.text
: item.value;
var value =
item.value === undefined || item.value === null
? item.text
: item.value;
if (_.isNumber(value)) {
value = value.toString();
@@ -165,17 +184,19 @@ export class QueryVariable implements Variable {
if (regex) {
matches = regex.exec(value);
if (!matches) { continue; }
if (!matches) {
continue;
}
if (matches.length > 1) {
value = matches[1];
text = matches[1];
}
}
options.push({text: text, value: value});
options.push({ text: text, value: value });
}
options = _.uniqBy(options, 'value');
options = _.uniqBy(options, "value");
return this.sortVariableValues(options, this.sort);
}
@@ -185,12 +206,12 @@ export class QueryVariable implements Variable {
}
var sortType = Math.ceil(sortOrder / 2);
var reverseSort = (sortOrder % 2 === 0);
var reverseSort = sortOrder % 2 === 0;
if (sortType === 1) {
options = _.sortBy(options, 'text');
options = _.sortBy(options, "text");
} else if (sortType === 2) {
options = _.sortBy(options, (opt) => {
options = _.sortBy(options, opt => {
var matches = opt.text.match(/.*?(\d+).*/);
if (!matches || matches.length < 2) {
return -1;
@@ -212,9 +233,9 @@ export class QueryVariable implements Variable {
}
}
variableTypes['query'] = {
name: 'Query',
variableTypes["query"] = {
name: "Query",
ctor: QueryVariable,
description: 'Variable values are fetched from a datasource query',
supportsMulti: true,
description: "Variable values are fetched from a datasource query",
supportsMulti: true
};

View File

@@ -1,43 +1,44 @@
import {AdhocVariable} from '../adhoc_variable';
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() {
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'},
{key: 'key3', operator: '=', value: 'value3a|value3b|value3c'},
{ key: "key1", operator: "=", value: "value1" },
{ key: "key2", operator: "!=", value: "value2" },
{ key: "key3", operator: "=", value: "value3a|value3b|value3c" }
]
});
var urlValue = variable.getValueForUrl();
expect(urlValue).toMatchObject(["key1|=|value1", "key2|!=|value2", "key3|=|value3a__gfp__value3b__gfp__value3c"]);
expect(urlValue).toMatchObject([
"key1|=|value1",
"key2|!=|value2",
"key3|=|value3a__gfp__value3b__gfp__value3c"
]);
});
});
describe('when deserializing from url', function() {
it('should restore filters', function() {
describe("when deserializing from url", function() {
it("should restore filters", function() {
var variable = new AdhocVariable({});
variable.setValueFromUrl(["key1|=|value1", "key2|!=|value2", "key3|=|value3a__gfp__value3b__gfp__value3c"]);
variable.setValueFromUrl([
"key1|=|value1",
"key2|!=|value2",
"key3|=|value3a__gfp__value3b__gfp__value3c"
]);
expect(variable.filters[0].key).toBe('key1');
expect(variable.filters[0].operator).toBe('=');
expect(variable.filters[0].value).toBe('value1');
expect(variable.filters[0].key).toBe("key1");
expect(variable.filters[0].operator).toBe("=");
expect(variable.filters[0].value).toBe("value1");
expect(variable.filters[1].key).toBe('key2');
expect(variable.filters[1].operator).toBe('!=');
expect(variable.filters[1].value).toBe('value2');
expect(variable.filters[1].key).toBe("key2");
expect(variable.filters[1].operator).toBe("!=");
expect(variable.filters[1].value).toBe("value2");
expect(variable.filters[2].key).toBe('key3');
expect(variable.filters[2].operator).toBe('=');
expect(variable.filters[2].value).toBe('value3a|value3b|value3c');
expect(variable.filters[2].key).toBe("key3");
expect(variable.filters[2].operator).toBe("=");
expect(variable.filters[2].value).toBe("value3a|value3b|value3c");
});
});
});

View File

@@ -1,39 +1,37 @@
import {QueryVariable} from '../query_variable';
import { QueryVariable } from "../query_variable";
describe('QueryVariable', () => {
describe('when creating from model', () => {
it('should set defaults', () => {
describe("QueryVariable", () => {
describe("when creating from model", () => {
it("should set defaults", () => {
var variable = new QueryVariable({}, null, null, null, null);
expect(variable.datasource).toBe(null);
expect(variable.refresh).toBe(0);
expect(variable.sort).toBe(0);
expect(variable.name).toBe('');
expect(variable.name).toBe("");
expect(variable.hide).toBe(0);
expect(variable.options.length).toBe(0);
expect(variable.multi).toBe(false);
expect(variable.includeAll).toBe(false);
});
it('get model should copy changes back to model', () => {
it("get model should copy changes back to model", () => {
var variable = new QueryVariable({}, null, null, null, null);
variable.options = [{text: 'test'}];
variable.datasource = 'google';
variable.regex = 'asd';
variable.options = [{ text: "test" }];
variable.datasource = "google";
variable.regex = "asd";
variable.sort = 50;
var model = variable.getSaveModel();
expect(model.options.length).toBe(1);
expect(model.options[0].text).toBe('test');
expect(model.datasource).toBe('google');
expect(model.regex).toBe('asd');
expect(model.options[0].text).toBe("test");
expect(model.datasource).toBe("google");
expect(model.regex).toBe("asd");
expect(model.sort).toBe(50);
});
it('if refresh != 0 then remove options in presisted mode', () => {
it("if refresh != 0 then remove options in presisted mode", () => {
var variable = new QueryVariable({}, null, null, null, null);
variable.options = [{text: 'test'}];
variable.options = [{ text: "test" }];
variable.refresh = 1;
var model = variable.getSaveModel();
@@ -41,38 +39,38 @@ describe('QueryVariable', () => {
});
});
describe('can convert and sort metric names',() => {
describe("can convert and sort metric names", () => {
var variable = new QueryVariable({}, null, null, null, null);
variable.sort = 3; // Numerical (asc)
describe('can sort a mixed array of metric variables', () => {
describe("can sort a mixed array of metric variables", () => {
var input = [
{text: '0', value: '0'},
{text: '1', value: '1'},
{text: null, value: 3},
{text: undefined, value: 4},
{text: '5', value: null},
{text: '6', value: undefined},
{text: null, value: '7'},
{text: undefined, value: '8'},
{text: 9, value: null},
{text: 10, value: undefined},
{text: '', value: undefined},
{text: undefined, value: ''},
{ text: "0", value: "0" },
{ text: "1", value: "1" },
{ text: null, value: 3 },
{ text: undefined, value: 4 },
{ text: "5", value: null },
{ text: "6", value: undefined },
{ text: null, value: "7" },
{ text: undefined, value: "8" },
{ text: 9, value: null },
{ text: 10, value: undefined },
{ text: "", value: undefined },
{ text: undefined, value: "" }
];
var result = variable.metricNamesToVariableValues(input);
it('should return in same order', () => {
it("should return in same order", () => {
var i = 0;
expect(result.length).toBe(11);
expect(result[i++].text).toBe('');
expect(result[i++].text).toBe('0');
expect(result[i++].text).toBe('1');
expect(result[i++].text).toBe('3');
expect(result[i++].text).toBe('4');
expect(result[i++].text).toBe('5');
expect(result[i++].text).toBe('6');
expect(result[i++].text).toBe("");
expect(result[i++].text).toBe("0");
expect(result[i++].text).toBe("1");
expect(result[i++].text).toBe("3");
expect(result[i++].text).toBe("4");
expect(result[i++].text).toBe("5");
expect(result[i++].text).toBe("6");
});
});
});

View File

@@ -1,6 +1,6 @@
import { TemplateSrv } from '../template_srv';
import { TemplateSrv } from "../template_srv";
describe('templateSrv', function() {
describe("templateSrv", function() {
var _templateSrv;
function initTemplateSrv(variables) {
@@ -8,222 +8,257 @@ describe('templateSrv', function() {
_templateSrv.init(variables);
}
describe('init', function() {
beforeEach(function() {
initTemplateSrv([{type: 'query', name: 'test', current: {value: 'oogle'}}]);
});
it('should initialize template data', function() {
var target = _templateSrv.replace('this.[[test]].filters');
expect(target).toBe('this.oogle.filters');
});
});
describe('replace can pass scoped vars', function() {
beforeEach(function() {
initTemplateSrv([{type: 'query', name: 'test', current: {value: 'oogle' }}]);
});
it('should replace $test with scoped value', function() {
var target = _templateSrv.replace('this.$test.filters', {'test': {value: 'mupp', text: 'asd'}});
expect(target).toBe('this.mupp.filters');
});
it('should replace $test with scoped text', function() {
var target = _templateSrv.replaceWithText('this.$test.filters', {'test': {value: 'mupp', text: 'asd'}});
expect(target).toBe('this.asd.filters');
});
});
describe('getAdhocFilters', function() {
describe("init", function() {
beforeEach(function() {
initTemplateSrv([
{type: 'datasource', name: 'ds', current: {value: 'logstash', text: 'logstash'}},
{type: 'adhoc', name: 'test', datasource: 'oogle', filters: [1]},
{type: 'adhoc', name: 'test2', datasource: '$ds', filters: [2]},
{ type: "query", name: "test", current: { value: "oogle" } }
]);
});
it('should return filters if datasourceName match', function() {
var filters = _templateSrv.getAdhocFilters('oogle');
it("should initialize template data", function() {
var target = _templateSrv.replace("this.[[test]].filters");
expect(target).toBe("this.oogle.filters");
});
});
describe("replace can pass scoped vars", function() {
beforeEach(function() {
initTemplateSrv([
{ type: "query", name: "test", current: { value: "oogle" } }
]);
});
it("should replace $test with scoped value", function() {
var target = _templateSrv.replace("this.$test.filters", {
test: { value: "mupp", text: "asd" }
});
expect(target).toBe("this.mupp.filters");
});
it("should replace $test with scoped text", function() {
var target = _templateSrv.replaceWithText("this.$test.filters", {
test: { value: "mupp", text: "asd" }
});
expect(target).toBe("this.asd.filters");
});
});
describe("getAdhocFilters", function() {
beforeEach(function() {
initTemplateSrv([
{
type: "datasource",
name: "ds",
current: { value: "logstash", text: "logstash" }
},
{ type: "adhoc", name: "test", datasource: "oogle", filters: [1] },
{ type: "adhoc", name: "test2", datasource: "$ds", filters: [2] }
]);
});
it("should return filters if datasourceName match", function() {
var filters = _templateSrv.getAdhocFilters("oogle");
expect(filters).toMatchObject([1]);
});
it('should return empty array if datasourceName does not match', function() {
var filters = _templateSrv.getAdhocFilters('oogleasdasd');
it("should return empty array if datasourceName does not match", function() {
var filters = _templateSrv.getAdhocFilters("oogleasdasd");
expect(filters).toMatchObject([]);
});
it('should return filters when datasourceName match via data source variable', function() {
var filters = _templateSrv.getAdhocFilters('logstash');
it("should return filters when datasourceName match via data source variable", function() {
var filters = _templateSrv.getAdhocFilters("logstash");
expect(filters).toMatchObject([2]);
});
});
describe('replace can pass multi / all format', function() {
describe("replace can pass multi / all format", function() {
beforeEach(function() {
initTemplateSrv([{type: 'query', name: 'test', current: {value: ['value1', 'value2'] }}]);
initTemplateSrv([
{
type: "query",
name: "test",
current: { value: ["value1", "value2"] }
}
]);
});
it('should replace $test with globbed value', function() {
var target = _templateSrv.replace('this.$test.filters', {}, 'glob');
expect(target).toBe('this.{value1,value2}.filters');
it("should replace $test with globbed value", function() {
var target = _templateSrv.replace("this.$test.filters", {}, "glob");
expect(target).toBe("this.{value1,value2}.filters");
});
it('should replace $test with piped value', function() {
var target = _templateSrv.replace('this=$test', {}, 'pipe');
expect(target).toBe('this=value1|value2');
it("should replace $test with piped value", function() {
var target = _templateSrv.replace("this=$test", {}, "pipe");
expect(target).toBe("this=value1|value2");
});
it('should replace $test with piped value', function() {
var target = _templateSrv.replace('this=$test', {}, 'pipe');
expect(target).toBe('this=value1|value2');
it("should replace $test with piped value", function() {
var target = _templateSrv.replace("this=$test", {}, "pipe");
expect(target).toBe("this=value1|value2");
});
});
describe('variable with all option', function() {
describe("variable with all option", function() {
beforeEach(function() {
initTemplateSrv([{
type: 'query',
name: 'test',
current: {value: '$__all' },
options: [
{value: '$__all'}, {value: 'value1'}, {value: 'value2'}
]
}]);
initTemplateSrv([
{
type: "query",
name: "test",
current: { value: "$__all" },
options: [
{ value: "$__all" },
{ value: "value1" },
{ value: "value2" }
]
}
]);
});
it('should replace $test with formatted all value', function() {
var target = _templateSrv.replace('this.$test.filters', {}, 'glob');
expect(target).toBe('this.{value1,value2}.filters');
it("should replace $test with formatted all value", function() {
var target = _templateSrv.replace("this.$test.filters", {}, "glob");
expect(target).toBe("this.{value1,value2}.filters");
});
});
describe('variable with all option and custom value', function() {
describe("variable with all option and custom value", function() {
beforeEach(function() {
initTemplateSrv([{
type: 'query',
name: 'test',
current: {value: '$__all' },
allValue: '*',
options: [
{value: 'value1'}, {value: 'value2'}
]
}]);
initTemplateSrv([
{
type: "query",
name: "test",
current: { value: "$__all" },
allValue: "*",
options: [{ value: "value1" }, { value: "value2" }]
}
]);
});
it('should replace $test with formatted all value', function() {
var target = _templateSrv.replace('this.$test.filters', {}, 'glob');
expect(target).toBe('this.*.filters');
it("should replace $test with formatted all value", function() {
var target = _templateSrv.replace("this.$test.filters", {}, "glob");
expect(target).toBe("this.*.filters");
});
it('should not escape custom all value', function() {
var target = _templateSrv.replace('this.$test', {}, 'regex');
expect(target).toBe('this.*');
it("should not escape custom all value", function() {
var target = _templateSrv.replace("this.$test", {}, "regex");
expect(target).toBe("this.*");
});
});
describe('lucene format', function() {
it('should properly escape $test with lucene escape sequences', function() {
initTemplateSrv([{type: 'query', name: 'test', current: {value: 'value/4' }}]);
var target = _templateSrv.replace('this:$test', {}, 'lucene');
expect(target).toBe("this:value\\\/4");
describe("lucene format", function() {
it("should properly escape $test with lucene escape sequences", function() {
initTemplateSrv([
{ type: "query", name: "test", current: { value: "value/4" } }
]);
var target = _templateSrv.replace("this:$test", {}, "lucene");
expect(target).toBe("this:value\\/4");
});
});
describe('format variable to string values', function() {
it('single value should return value', function() {
var result = _templateSrv.formatValue('test');
expect(result).toBe('test');
describe("format variable to string values", function() {
it("single value should return value", function() {
var result = _templateSrv.formatValue("test");
expect(result).toBe("test");
});
it('multi value and glob format should render glob string', function() {
var result = _templateSrv.formatValue(['test','test2'], 'glob');
expect(result).toBe('{test,test2}');
it("multi value and glob format should render glob string", function() {
var result = _templateSrv.formatValue(["test", "test2"], "glob");
expect(result).toBe("{test,test2}");
});
it('multi value and lucene should render as lucene expr', function() {
var result = _templateSrv.formatValue(['test','test2'], 'lucene');
it("multi value and lucene should render as lucene expr", function() {
var result = _templateSrv.formatValue(["test", "test2"], "lucene");
expect(result).toBe('("test" OR "test2")');
});
it('multi value and regex format should render regex string', function() {
var result = _templateSrv.formatValue(['test.','test2'], 'regex');
expect(result).toBe('(test\\.|test2)');
it("multi value and regex format should render regex string", function() {
var result = _templateSrv.formatValue(["test.", "test2"], "regex");
expect(result).toBe("(test\\.|test2)");
});
it('multi value and pipe should render pipe string', function() {
var result = _templateSrv.formatValue(['test','test2'], 'pipe');
expect(result).toBe('test|test2');
it("multi value and pipe should render pipe string", function() {
var result = _templateSrv.formatValue(["test", "test2"], "pipe");
expect(result).toBe("test|test2");
});
it('multi value and distributed should render distributed string', function() {
var result = _templateSrv.formatValue(['test','test2'], 'distributed', { name: 'build' });
expect(result).toBe('test,build=test2');
it("multi value and distributed should render distributed string", function() {
var result = _templateSrv.formatValue(["test", "test2"], "distributed", {
name: "build"
});
expect(result).toBe("test,build=test2");
});
it('multi value and distributed should render when not string', function() {
var result = _templateSrv.formatValue(['test'], 'distributed', { name: 'build' });
expect(result).toBe('test');
it("multi value and distributed should render when not string", function() {
var result = _templateSrv.formatValue(["test"], "distributed", {
name: "build"
});
expect(result).toBe("test");
});
it('slash should be properly escaped in regex format', function() {
var result = _templateSrv.formatValue('Gi3/14', 'regex');
expect(result).toBe('Gi3\\/14');
it("slash should be properly escaped in regex format", function() {
var result = _templateSrv.formatValue("Gi3/14", "regex");
expect(result).toBe("Gi3\\/14");
});
});
describe('can check if variable exists', function() {
describe("can check if variable exists", function() {
beforeEach(function() {
initTemplateSrv([{type: 'query', name: 'test', current: { value: 'oogle' } }]);
initTemplateSrv([
{ type: "query", name: "test", current: { value: "oogle" } }
]);
});
it('should return true if exists', function() {
var result = _templateSrv.variableExists('$test');
it("should return true if exists", function() {
var result = _templateSrv.variableExists("$test");
expect(result).toBe(true);
});
});
describe('can hightlight variables in string', function() {
describe("can hightlight variables in string", function() {
beforeEach(function() {
initTemplateSrv([{type: 'query', name: 'test', current: { value: 'oogle' } }]);
initTemplateSrv([
{ type: "query", name: "test", current: { value: "oogle" } }
]);
});
it('should insert html', function() {
var result = _templateSrv.highlightVariablesAsHtml('$test');
it("should insert html", function() {
var result = _templateSrv.highlightVariablesAsHtml("$test");
expect(result).toBe('<span class="template-variable">$test</span>');
});
it('should insert html anywhere in string', function() {
var result = _templateSrv.highlightVariablesAsHtml('this $test ok');
expect(result).toBe('this <span class="template-variable">$test</span> ok');
it("should insert html anywhere in string", function() {
var result = _templateSrv.highlightVariablesAsHtml("this $test ok");
expect(result).toBe(
'this <span class="template-variable">$test</span> ok'
);
});
it('should ignore if variables does not exist', function() {
var result = _templateSrv.highlightVariablesAsHtml('this $google ok');
expect(result).toBe('this $google ok');
it("should ignore if variables does not exist", function() {
var result = _templateSrv.highlightVariablesAsHtml("this $google ok");
expect(result).toBe("this $google ok");
});
});
describe('updateTemplateData with simple value', function() {
describe("updateTemplateData with simple value", function() {
beforeEach(function() {
initTemplateSrv([{type: 'query', name: 'test', current: { value: 'muuuu' } }]);
initTemplateSrv([
{ type: "query", name: "test", current: { value: "muuuu" } }
]);
});
it('should set current value and update template data', function() {
var target = _templateSrv.replace('this.[[test]].filters');
expect(target).toBe('this.muuuu.filters');
it("should set current value and update template data", function() {
var target = _templateSrv.replace("this.[[test]].filters");
expect(target).toBe("this.muuuu.filters");
});
});
describe('fillVariableValuesForUrl with multi value', function() {
describe("fillVariableValuesForUrl with multi value", function() {
beforeEach(function() {
initTemplateSrv([
{
type: 'query',
name: 'test',
current: { value: ['val1', 'val2'] },
type: "query",
name: "test",
current: { value: ["val1", "val2"] },
getValueForUrl: function() {
return this.current.value;
}
@@ -231,50 +266,65 @@ describe('templateSrv', function() {
]);
});
it('should set multiple url params', function() {
it("should set multiple url params", function() {
var params = {};
_templateSrv.fillVariableValuesForUrl(params);
expect(params['var-test']).toMatchObject(['val1', 'val2']);
expect(params["var-test"]).toMatchObject(["val1", "val2"]);
});
});
describe('fillVariableValuesForUrl with multi value and scopedVars', function() {
beforeEach(function() {
initTemplateSrv([{type: 'query', name: 'test', current: { value: ['val1', 'val2'] }}]);
});
it('should set scoped value as url params', function() {
var params = {};
_templateSrv.fillVariableValuesForUrl(params, {'test': {value: 'val1'}});
expect(params['var-test']).toBe('val1');
});
});
describe('replaceWithText', function() {
describe("fillVariableValuesForUrl with multi value and scopedVars", function() {
beforeEach(function() {
initTemplateSrv([
{type: 'query', name: 'server', current: { value: '{asd,asd2}', text: 'All' } },
{type: 'interval', name: 'period', current: { value: '$__auto_interval_interval', text: 'auto' } }
{ type: "query", name: "test", current: { value: ["val1", "val2"] } }
]);
_templateSrv.setGrafanaVariable('$__auto_interval_interval', '13m');
});
it("should set scoped value as url params", function() {
var params = {};
_templateSrv.fillVariableValuesForUrl(params, {
test: { value: "val1" }
});
expect(params["var-test"]).toBe("val1");
});
});
describe("replaceWithText", function() {
beforeEach(function() {
initTemplateSrv([
{
type: "query",
name: "server",
current: { value: "{asd,asd2}", text: "All" }
},
{
type: "interval",
name: "period",
current: { value: "$__auto_interval_interval", text: "auto" }
}
]);
_templateSrv.setGrafanaVariable("$__auto_interval_interval", "13m");
_templateSrv.updateTemplateData();
});
it('should replace with text except for grafanaVariables', function() {
var target = _templateSrv.replaceWithText('Server: $server, period: $period');
expect(target).toBe('Server: All, period: 13m');
it("should replace with text except for grafanaVariables", function() {
var target = _templateSrv.replaceWithText(
"Server: $server, period: $period"
);
expect(target).toBe("Server: All, period: 13m");
});
});
describe('built in interval variables', function() {
describe("built in interval variables", function() {
beforeEach(function() {
initTemplateSrv([]);
});
it('should replace $__interval_ms with interval milliseconds', function() {
var target = _templateSrv.replace('10 * $__interval_ms', {"__interval_ms": {text: "100", value: "100"}});
expect(target).toBe('10 * 100');
it("should replace $__interval_ms with interval milliseconds", function() {
var target = _templateSrv.replace("10 * $__interval_ms", {
__interval_ms: { text: "100", value: "100" }
});
expect(target).toBe("10 * 100");
});
});
});

View File

@@ -1,62 +1,59 @@
import {containsVariable, assignModelProperties} from '../variable';
import { containsVariable, assignModelProperties } from "../variable";
describe('containsVariable', function() {
describe('when checking if a string contains a variable', function() {
it('should find it with $var syntax', function() {
var contains = containsVariable('this.$test.filters', 'test');
describe("containsVariable", function() {
describe("when checking if a string contains a variable", function() {
it("should find it with $var syntax", function() {
var contains = containsVariable("this.$test.filters", "test");
expect(contains).toBe(true);
});
it('should not find it if only part matches with $var syntax', function() {
var contains = containsVariable('this.$serverDomain.filters', 'server');
it("should not find it if only part matches with $var syntax", function() {
var contains = containsVariable("this.$serverDomain.filters", "server");
expect(contains).toBe(false);
});
it('should find it if it ends with variable and passing multiple test strings', function() {
var contains = containsVariable('show field keys from $pgmetric', 'test string2', 'pgmetric');
it("should find it if it ends with variable and passing multiple test strings", function() {
var contains = containsVariable(
"show field keys from $pgmetric",
"test string2",
"pgmetric"
);
expect(contains).toBe(true);
});
it('should find it with [[var]] syntax', function() {
var contains = containsVariable('this.[[test]].filters', 'test');
it("should find it with [[var]] syntax", function() {
var contains = containsVariable("this.[[test]].filters", "test");
expect(contains).toBe(true);
});
it('should find it when part of segment', function() {
var contains = containsVariable('metrics.$env.$group-*', 'group');
it("should find it when part of segment", function() {
var contains = containsVariable("metrics.$env.$group-*", "group");
expect(contains).toBe(true);
});
it('should find it its the only thing', function() {
var contains = containsVariable('$env', 'env');
it("should find it its the only thing", function() {
var contains = containsVariable("$env", "env");
expect(contains).toBe(true);
});
it('should be able to pass in multiple test strings', function() {
var contains = containsVariable('asd','asd2.$env', 'env');
it("should be able to pass in multiple test strings", function() {
var contains = containsVariable("asd", "asd2.$env", "env");
expect(contains).toBe(true);
});
});
});
describe('assignModelProperties', function() {
it('only set properties defined in defaults', function() {
var target: any = {test: 'asd'};
assignModelProperties(target, {propA: 1, propB: 2}, {propB: 0});
describe("assignModelProperties", function() {
it("only set properties defined in defaults", function() {
var target: any = { test: "asd" };
assignModelProperties(target, { propA: 1, propB: 2 }, { propB: 0 });
expect(target.propB).toBe(2);
expect(target.test).toBe('asd');
expect(target.test).toBe("asd");
});
it('use default value if not found on source', function() {
var target: any = {test: 'asd'};
assignModelProperties(target, {propA: 1, propB: 2}, {propC: 10});
it("use default value if not found on source", function() {
var target: any = { test: "asd" };
assignModelProperties(target, { propA: 1, propB: 2 }, { propC: 10 });
expect(target.propC).toBe(10);
});
});

View File

@@ -1,29 +1,42 @@
import {describe, beforeEach, it, sinon, expect, angularMocks} from 'test/lib/common';
import {
describe,
beforeEach,
it,
sinon,
expect,
angularMocks
} from "test/lib/common";
import '../all';
import "../all";
import _ from 'lodash';
import helpers from 'test/specs/helpers';
import {Emitter} from 'app/core/core';
import _ from "lodash";
import helpers from "test/specs/helpers";
import { Emitter } from "app/core/core";
describe('VariableSrv init', function() {
describe("VariableSrv init", function() {
var ctx = new helpers.ControllerTestContext();
beforeEach(angularMocks.module('grafana.core'));
beforeEach(angularMocks.module('grafana.controllers'));
beforeEach(angularMocks.module('grafana.services'));
beforeEach(angularMocks.module(function($compileProvider) {
$compileProvider.preAssignBindingsEnabled(true);
}));
beforeEach(angularMocks.module("grafana.core"));
beforeEach(angularMocks.module("grafana.controllers"));
beforeEach(angularMocks.module("grafana.services"));
beforeEach(
angularMocks.module(function($compileProvider) {
$compileProvider.preAssignBindingsEnabled(true);
})
);
beforeEach(ctx.providePhase(['datasourceSrv', 'timeSrv', 'templateSrv', '$location']));
beforeEach(angularMocks.inject(($rootScope, $q, $location, $injector) => {
ctx.$q = $q;
ctx.$rootScope = $rootScope;
ctx.$location = $location;
ctx.variableSrv = $injector.get('variableSrv');
ctx.$rootScope.$digest();
}));
beforeEach(
ctx.providePhase(["datasourceSrv", "timeSrv", "templateSrv", "$location"])
);
beforeEach(
angularMocks.inject(($rootScope, $q, $location, $injector) => {
ctx.$q = $q;
ctx.$rootScope = $rootScope;
ctx.$location = $location;
ctx.variableSrv = $injector.get("variableSrv");
ctx.$rootScope.$digest();
})
);
function describeInitScenario(desc, fn) {
describe(desc, function() {
@@ -37,13 +50,22 @@ describe('VariableSrv init', function() {
beforeEach(function() {
scenario.setupFn();
ctx.datasource = {};
ctx.datasource.metricFindQuery = sinon.stub().returns(ctx.$q.when(scenario.queryResult));
ctx.datasource.metricFindQuery = sinon
.stub()
.returns(ctx.$q.when(scenario.queryResult));
ctx.datasourceSrv.get = sinon.stub().returns(ctx.$q.when(ctx.datasource));
ctx.datasourceSrv.getMetricSources = sinon.stub().returns(scenario.metricSources);
ctx.datasourceSrv.get = sinon
.stub()
.returns(ctx.$q.when(ctx.datasource));
ctx.datasourceSrv.getMetricSources = sinon
.stub()
.returns(scenario.metricSources);
ctx.$location.search = sinon.stub().returns(scenario.urlParams);
ctx.dashboard = {templating: {list: scenario.variables}, events: new Emitter()};
ctx.dashboard = {
templating: { list: scenario.variables },
events: new Emitter()
};
ctx.variableSrv.init(ctx.dashboard);
ctx.$rootScope.$digest();
@@ -55,116 +77,130 @@ describe('VariableSrv init', function() {
});
}
['query', 'interval', 'custom', 'datasource'].forEach(type => {
describeInitScenario('when setting ' + type + ' variable via url', scenario => {
scenario.setup(() => {
scenario.variables = [{
name: 'apps',
type: type,
current: {text: "test", value: "test"},
options: [{text: "test", value: "test"}]
}];
scenario.urlParams["var-apps"] = "new";
scenario.metricSources = [];
});
it('should update current value', () => {
expect(scenario.variables[0].current.value).to.be("new");
expect(scenario.variables[0].current.text).to.be("new");
});
});
["query", "interval", "custom", "datasource"].forEach(type => {
describeInitScenario(
"when setting " + type + " variable via url",
scenario => {
scenario.setup(() => {
scenario.variables = [
{
name: "apps",
type: type,
current: { text: "test", value: "test" },
options: [{ text: "test", value: "test" }]
}
];
scenario.urlParams["var-apps"] = "new";
scenario.metricSources = [];
});
it("should update current value", () => {
expect(scenario.variables[0].current.value).to.be("new");
expect(scenario.variables[0].current.text).to.be("new");
});
}
);
});
describe('given dependent variables', () => {
describe("given dependent variables", () => {
var variableList = [
{
name: 'app',
type: 'query',
query: '',
current: {text: "app1", value: "app1"},
options: [{text: "app1", value: "app1"}]
name: "app",
type: "query",
query: "",
current: { text: "app1", value: "app1" },
options: [{ text: "app1", value: "app1" }]
},
{
name: 'server',
type: 'query',
name: "server",
type: "query",
refresh: 1,
query: '$app.*',
current: {text: "server1", value: "server1"},
options: [{text: "server1", value: "server1"}]
},
query: "$app.*",
current: { text: "server1", value: "server1" },
options: [{ text: "server1", value: "server1" }]
}
];
describeInitScenario('when setting parent var from url', scenario => {
describeInitScenario("when setting parent var from url", scenario => {
scenario.setup(() => {
scenario.variables = _.cloneDeep(variableList);
scenario.urlParams["var-app"] = "google";
scenario.queryResult = [{text: 'google-server1'}, {text: 'google-server2'}];
scenario.queryResult = [
{ text: "google-server1" },
{ text: "google-server2" }
];
});
it('should update child variable', () => {
it("should update child variable", () => {
expect(scenario.variables[1].options.length).to.be(2);
expect(scenario.variables[1].current.text).to.be("google-server1");
});
it('should only update it once', () => {
it("should only update it once", () => {
expect(ctx.datasource.metricFindQuery.callCount).to.be(1);
});
});
});
describeInitScenario('when datasource variable is initialized', scenario => {
describeInitScenario("when datasource variable is initialized", scenario => {
scenario.setup(() => {
scenario.variables = [{
type: 'datasource',
query: 'graphite',
name: 'test',
current: {value: 'backend4_pee', text: 'backend4_pee'},
regex: '/pee$/'
scenario.variables = [
{
type: "datasource",
query: "graphite",
name: "test",
current: { value: "backend4_pee", text: "backend4_pee" },
regex: "/pee$/"
}
];
scenario.metricSources = [
{name: 'backend1', meta: {id: 'influx'}},
{name: 'backend2_pee', meta: {id: 'graphite'}},
{name: 'backend3', meta: {id: 'graphite'}},
{name: 'backend4_pee', meta: {id: 'graphite'}},
{ name: "backend1", meta: { id: "influx" } },
{ name: "backend2_pee", meta: { id: "graphite" } },
{ name: "backend3", meta: { id: "graphite" } },
{ name: "backend4_pee", meta: { id: "graphite" } }
];
});
it('should update current value', function() {
it("should update current value", function() {
var variable = ctx.variableSrv.variables[0];
expect(variable.options.length).to.be(2);
});
});
describeInitScenario('when template variable is present in url multiple times', scenario => {
scenario.setup(() => {
scenario.variables = [{
name: 'apps',
type: 'query',
multi: true,
current: {text: "val1", value: "val1"},
options: [{text: "val1", value: "val1"}, {text: 'val2', value: 'val2'}, {text: 'val3', value: 'val3', selected: true}]
}];
scenario.urlParams["var-apps"] = ["val2", "val1"];
});
describeInitScenario(
"when template variable is present in url multiple times",
scenario => {
scenario.setup(() => {
scenario.variables = [
{
name: "apps",
type: "query",
multi: true,
current: { text: "val1", value: "val1" },
options: [
{ text: "val1", value: "val1" },
{ text: "val2", value: "val2" },
{ text: "val3", value: "val3", selected: true }
]
}
];
scenario.urlParams["var-apps"] = ["val2", "val1"];
});
it('should update current value', function() {
var variable = ctx.variableSrv.variables[0];
expect(variable.current.value.length).to.be(2);
expect(variable.current.value[0]).to.be("val2");
expect(variable.current.value[1]).to.be("val1");
expect(variable.current.text).to.be("val2 + val1");
expect(variable.options[0].selected).to.be(true);
expect(variable.options[1].selected).to.be(true);
});
it('should set options that are not in value to selected false', function() {
var variable = ctx.variableSrv.variables[0];
expect(variable.options[2].selected).to.be(false);
});
});
it("should update current value", function() {
var variable = ctx.variableSrv.variables[0];
expect(variable.current.value.length).to.be(2);
expect(variable.current.value[0]).to.be("val2");
expect(variable.current.value[1]).to.be("val1");
expect(variable.current.text).to.be("val2 + val1");
expect(variable.options[0].selected).to.be(true);
expect(variable.options[1].selected).to.be(true);
});
it("should set options that are not in value to selected false", function() {
var variable = ctx.variableSrv.variables[0];
expect(variable.options[2].selected).to.be(false);
});
}
);
});

View File

@@ -1,31 +1,42 @@
import {describe, beforeEach, it, sinon, expect, angularMocks} from 'test/lib/common';
import {
describe,
beforeEach,
it,
sinon,
expect,
angularMocks
} from "test/lib/common";
import '../all';
import "../all";
import moment from 'moment';
import helpers from 'test/specs/helpers';
import {Emitter} from 'app/core/core';
import moment from "moment";
import helpers from "test/specs/helpers";
import { Emitter } from "app/core/core";
describe('VariableSrv', function() {
describe("VariableSrv", function() {
var ctx = new helpers.ControllerTestContext();
beforeEach(angularMocks.module('grafana.core'));
beforeEach(angularMocks.module('grafana.controllers'));
beforeEach(angularMocks.module('grafana.services'));
beforeEach(angularMocks.module("grafana.core"));
beforeEach(angularMocks.module("grafana.controllers"));
beforeEach(angularMocks.module("grafana.services"));
beforeEach(ctx.providePhase(['datasourceSrv', 'timeSrv', 'templateSrv', '$location']));
beforeEach(angularMocks.inject(($rootScope, $q, $location, $injector) => {
ctx.$q = $q;
ctx.$rootScope = $rootScope;
ctx.$location = $location;
ctx.variableSrv = $injector.get('variableSrv');
ctx.variableSrv.init({
templating: {list: []},
events: new Emitter(),
updateSubmenuVisibility: sinon.stub(),
});
ctx.$rootScope.$digest();
}));
beforeEach(
ctx.providePhase(["datasourceSrv", "timeSrv", "templateSrv", "$location"])
);
beforeEach(
angularMocks.inject(($rootScope, $q, $location, $injector) => {
ctx.$q = $q;
ctx.$rootScope = $rootScope;
ctx.$location = $location;
ctx.variableSrv = $injector.get("variableSrv");
ctx.variableSrv.init({
templating: { list: [] },
events: new Emitter(),
updateSubmenuVisibility: sinon.stub()
});
ctx.$rootScope.$digest();
})
);
function describeUpdateVariable(desc, fn) {
describe(desc, function() {
@@ -37,12 +48,17 @@ describe('VariableSrv', function() {
beforeEach(function() {
scenario.setupFn();
var ds: any = {};
ds.metricFindQuery = sinon.stub().returns(ctx.$q.when(scenario.queryResult));
ds.metricFindQuery = sinon
.stub()
.returns(ctx.$q.when(scenario.queryResult));
ctx.datasourceSrv.get = sinon.stub().returns(ctx.$q.when(ds));
ctx.datasourceSrv.getMetricSources = sinon.stub().returns(scenario.metricSources);
ctx.datasourceSrv.getMetricSources = sinon
.stub()
.returns(scenario.metricSources);
scenario.variable = ctx.variableSrv.createVariableFromModel(scenario.variableModel);
scenario.variable = ctx.variableSrv.createVariableFromModel(
scenario.variableModel
);
ctx.variableSrv.addVariable(scenario.variable);
ctx.variableSrv.updateOptions(scenario.variable);
@@ -53,27 +69,39 @@ describe('VariableSrv', function() {
});
}
describeUpdateVariable('interval variable without auto', scenario => {
describeUpdateVariable("interval variable without auto", scenario => {
scenario.setup(() => {
scenario.variableModel = {type: 'interval', query: '1s,2h,5h,1d', name: 'test'};
scenario.variableModel = {
type: "interval",
query: "1s,2h,5h,1d",
name: "test"
};
});
it('should update options array', () => {
it("should update options array", () => {
expect(scenario.variable.options.length).to.be(4);
expect(scenario.variable.options[0].text).to.be('1s');
expect(scenario.variable.options[0].value).to.be('1s');
expect(scenario.variable.options[0].text).to.be("1s");
expect(scenario.variable.options[0].value).to.be("1s");
});
});
//
// Interval variable update
//
describeUpdateVariable('interval variable with auto', scenario => {
describeUpdateVariable("interval variable with auto", scenario => {
scenario.setup(() => {
scenario.variableModel = {type: 'interval', query: '1s,2h,5h,1d', name: 'test', auto: true, auto_count: 10 };
scenario.variableModel = {
type: "interval",
query: "1s,2h,5h,1d",
name: "test",
auto: true,
auto_count: 10
};
var range = {
from: moment(new Date()).subtract(7, 'days').toDate(),
from: moment(new Date())
.subtract(7, "days")
.toDate(),
to: new Date()
};
@@ -81,390 +109,519 @@ describe('VariableSrv', function() {
ctx.templateSrv.setGrafanaVariable = sinon.spy();
});
it('should update options array', function() {
it("should update options array", function() {
expect(scenario.variable.options.length).to.be(5);
expect(scenario.variable.options[0].text).to.be('auto');
expect(scenario.variable.options[0].value).to.be('$__auto_interval_test');
expect(scenario.variable.options[0].text).to.be("auto");
expect(scenario.variable.options[0].value).to.be("$__auto_interval_test");
});
it('should set $__auto_interval_test', function() {
it("should set $__auto_interval_test", function() {
var call = ctx.templateSrv.setGrafanaVariable.firstCall;
expect(call.args[0]).to.be('$__auto_interval_test');
expect(call.args[1]).to.be('12h');
expect(call.args[0]).to.be("$__auto_interval_test");
expect(call.args[1]).to.be("12h");
});
// updateAutoValue() gets called twice: once directly once via VariableSrv.validateVariableSelectionState()
// So use lastCall instead of a specific call number
it('should set $__auto_interval', function() {
it("should set $__auto_interval", function() {
var call = ctx.templateSrv.setGrafanaVariable.lastCall;
expect(call.args[0]).to.be('$__auto_interval');
expect(call.args[1]).to.be('12h');
expect(call.args[0]).to.be("$__auto_interval");
expect(call.args[1]).to.be("12h");
});
});
//
// Query variable update
//
describeUpdateVariable('query variable with empty current object and refresh', function(scenario) {
describeUpdateVariable(
"query variable with empty current object and refresh",
function(scenario) {
scenario.setup(function() {
scenario.variableModel = {
type: "query",
query: "",
name: "test",
current: {}
};
scenario.queryResult = [{ text: "backend1" }, { text: "backend2" }];
});
it("should set current value to first option", function() {
expect(scenario.variable.options.length).to.be(2);
expect(scenario.variable.current.value).to.be("backend1");
});
}
);
describeUpdateVariable(
"query variable with multi select and new options does not contain some selected values",
function(scenario) {
scenario.setup(function() {
scenario.variableModel = {
type: "query",
query: "",
name: "test",
current: {
value: ["val1", "val2", "val3"],
text: "val1 + val2 + val3"
}
};
scenario.queryResult = [{ text: "val2" }, { text: "val3" }];
});
it("should update current value", function() {
expect(scenario.variable.current.value).to.eql(["val2", "val3"]);
expect(scenario.variable.current.text).to.eql("val2 + val3");
});
}
);
describeUpdateVariable(
"query variable with multi select and new options does not contain any selected values",
function(scenario) {
scenario.setup(function() {
scenario.variableModel = {
type: "query",
query: "",
name: "test",
current: {
value: ["val1", "val2", "val3"],
text: "val1 + val2 + val3"
}
};
scenario.queryResult = [{ text: "val5" }, { text: "val6" }];
});
it("should update current value with first one", function() {
expect(scenario.variable.current.value).to.eql("val5");
expect(scenario.variable.current.text).to.eql("val5");
});
}
);
describeUpdateVariable(
"query variable with multi select and $__all selected",
function(scenario) {
scenario.setup(function() {
scenario.variableModel = {
type: "query",
query: "",
name: "test",
includeAll: true,
current: {
value: ["$__all"],
text: "All"
}
};
scenario.queryResult = [{ text: "val5" }, { text: "val6" }];
});
it("should keep current All value", function() {
expect(scenario.variable.current.value).to.eql(["$__all"]);
expect(scenario.variable.current.text).to.eql("All");
});
}
);
describeUpdateVariable("query variable with numeric results", function(
scenario
) {
scenario.setup(function() {
scenario.variableModel = {type: 'query', query: '', name: 'test', current: {}};
scenario.queryResult = [{text: 'backend1'}, {text: 'backend2'}];
scenario.variableModel = {
type: "query",
query: "",
name: "test",
current: {}
};
scenario.queryResult = [{ text: 12, value: 12 }];
});
it('should set current value to first option', function() {
expect(scenario.variable.options.length).to.be(2);
expect(scenario.variable.current.value).to.be('backend1');
it("should set current value to first option", function() {
expect(scenario.variable.current.value).to.be("12");
expect(scenario.variable.options[0].value).to.be("12");
expect(scenario.variable.options[0].text).to.be("12");
});
});
describeUpdateVariable('query variable with multi select and new options does not contain some selected values', function(scenario) {
scenario.setup(function() {
scenario.variableModel = {
type: 'query',
query: '',
name: 'test',
current: {
value: ['val1', 'val2', 'val3'],
text: 'val1 + val2 + val3'
}
};
scenario.queryResult = [{text: 'val2'}, {text: 'val3'}];
});
it('should update current value', function() {
expect(scenario.variable.current.value).to.eql(['val2', 'val3']);
expect(scenario.variable.current.text).to.eql('val2 + val3');
});
describeUpdateVariable("basic query variable", function(scenario) {
scenario.setup(function() {
scenario.variableModel = { type: "query", query: "apps.*", name: "test" };
scenario.queryResult = [{ text: "backend1" }, { text: "backend2" }];
});
describeUpdateVariable('query variable with multi select and new options does not contain any selected values', function(scenario) {
scenario.setup(function() {
scenario.variableModel = {
type: 'query',
query: '',
name: 'test',
current: {
value: ['val1', 'val2', 'val3'],
text: 'val1 + val2 + val3'
}
};
scenario.queryResult = [{text: 'val5'}, {text: 'val6'}];
});
it('should update current value with first one', function() {
expect(scenario.variable.current.value).to.eql('val5');
expect(scenario.variable.current.text).to.eql('val5');
});
it("should update options array", function() {
expect(scenario.variable.options.length).to.be(2);
expect(scenario.variable.options[0].text).to.be("backend1");
expect(scenario.variable.options[0].value).to.be("backend1");
expect(scenario.variable.options[1].value).to.be("backend2");
});
describeUpdateVariable('query variable with multi select and $__all selected', function(scenario) {
scenario.setup(function() {
scenario.variableModel = {
type: 'query',
query: '',
name: 'test',
includeAll: true,
current: {
value: ['$__all'],
text: 'All'
}
};
scenario.queryResult = [{text: 'val5'}, {text: 'val6'}];
});
it("should select first option as value", function() {
expect(scenario.variable.current.value).to.be("backend1");
});
});
it('should keep current All value', function() {
expect(scenario.variable.current.value).to.eql(['$__all']);
expect(scenario.variable.current.text).to.eql('All');
});
describeUpdateVariable("and existing value still exists in options", function(
scenario
) {
scenario.setup(function() {
scenario.variableModel = { type: "query", query: "apps.*", name: "test" };
scenario.variableModel.current = { value: "backend2", text: "backend2" };
scenario.queryResult = [{ text: "backend1" }, { text: "backend2" }];
});
describeUpdateVariable('query variable with numeric results', function(scenario) {
scenario.setup(function() {
scenario.variableModel = { type: 'query', query: '', name: 'test', current: {} };
scenario.queryResult = [{text: 12, value: 12}];
});
it("should keep variable value", function() {
expect(scenario.variable.current.text).to.be("backend2");
});
});
it('should set current value to first option', function() {
expect(scenario.variable.current.value).to.be('12');
expect(scenario.variable.options[0].value).to.be('12');
expect(scenario.variable.options[0].text).to.be('12');
});
describeUpdateVariable("and regex pattern exists", function(scenario) {
scenario.setup(function() {
scenario.variableModel = { type: "query", query: "apps.*", name: "test" };
scenario.variableModel.regex = "/apps.*(backend_[0-9]+)/";
scenario.queryResult = [
{ text: "apps.backend.backend_01.counters.req" },
{ text: "apps.backend.backend_02.counters.req" }
];
});
describeUpdateVariable('basic query variable', function(scenario) {
scenario.setup(function() {
scenario.variableModel = { type: 'query', query: 'apps.*', name: 'test' };
scenario.queryResult = [{text: 'backend1'}, {text: 'backend2'}];
});
it("should extract and use match group", function() {
expect(scenario.variable.options[0].value).to.be("backend_01");
});
});
it('should update options array', function() {
expect(scenario.variable.options.length).to.be(2);
expect(scenario.variable.options[0].text).to.be('backend1');
expect(scenario.variable.options[0].value).to.be('backend1');
expect(scenario.variable.options[1].value).to.be('backend2');
});
it('should select first option as value', function() {
expect(scenario.variable.current.value).to.be('backend1');
});
describeUpdateVariable("and regex pattern exists and no match", function(
scenario
) {
scenario.setup(function() {
scenario.variableModel = { type: "query", query: "apps.*", name: "test" };
scenario.variableModel.regex = "/apps.*(backendasd[0-9]+)/";
scenario.queryResult = [
{ text: "apps.backend.backend_01.counters.req" },
{ text: "apps.backend.backend_02.counters.req" }
];
});
describeUpdateVariable('and existing value still exists in options', function(scenario) {
scenario.setup(function() {
scenario.variableModel = {type: 'query', query: 'apps.*', name: 'test'};
scenario.variableModel.current = { value: 'backend2', text: 'backend2'};
scenario.queryResult = [{text: 'backend1'}, {text: 'backend2'}];
});
it("should not add non matching items, None option should be added instead", function() {
expect(scenario.variable.options.length).to.be(1);
expect(scenario.variable.options[0].isNone).to.be(true);
});
});
it('should keep variable value', function() {
expect(scenario.variable.current.text).to.be('backend2');
});
describeUpdateVariable("regex pattern without slashes", function(scenario) {
scenario.setup(function() {
scenario.variableModel = { type: "query", query: "apps.*", name: "test" };
scenario.variableModel.regex = "backend_01";
scenario.queryResult = [
{ text: "apps.backend.backend_01.counters.req" },
{ text: "apps.backend.backend_02.counters.req" }
];
});
describeUpdateVariable('and regex pattern exists', function(scenario) {
scenario.setup(function() {
scenario.variableModel = {type: 'query', query: 'apps.*', name: 'test'};
scenario.variableModel.regex = '/apps.*(backend_[0-9]+)/';
scenario.queryResult = [{text: 'apps.backend.backend_01.counters.req'}, {text: 'apps.backend.backend_02.counters.req'}];
});
it("should return matches options", function() {
expect(scenario.variable.options.length).to.be(1);
});
});
it('should extract and use match group', function() {
expect(scenario.variable.options[0].value).to.be('backend_01');
});
describeUpdateVariable("regex pattern remove duplicates", function(scenario) {
scenario.setup(function() {
scenario.variableModel = { type: "query", query: "apps.*", name: "test" };
scenario.variableModel.regex = "/backend_01/";
scenario.queryResult = [
{ text: "apps.backend.backend_01.counters.req" },
{ text: "apps.backend.backend_01.counters.req" }
];
});
describeUpdateVariable('and regex pattern exists and no match', function(scenario) {
scenario.setup(function() {
scenario.variableModel = {type: 'query', query: 'apps.*', name: 'test'};
scenario.variableModel.regex = '/apps.*(backendasd[0-9]+)/';
scenario.queryResult = [{text: 'apps.backend.backend_01.counters.req'}, {text: 'apps.backend.backend_02.counters.req'}];
});
it("should return matches options", function() {
expect(scenario.variable.options.length).to.be(1);
});
});
it('should not add non matching items, None option should be added instead', function() {
expect(scenario.variable.options.length).to.be(1);
expect(scenario.variable.options[0].isNone).to.be(true);
});
describeUpdateVariable("with include All", function(scenario) {
scenario.setup(function() {
scenario.variableModel = {
type: "query",
query: "apps.*",
name: "test",
includeAll: true
};
scenario.queryResult = [
{ text: "backend1" },
{ text: "backend2" },
{ text: "backend3" }
];
});
describeUpdateVariable('regex pattern without slashes', function(scenario) {
scenario.setup(function() {
scenario.variableModel = {type: 'query', query: 'apps.*', name: 'test'};
scenario.variableModel.regex = 'backend_01';
scenario.queryResult = [{text: 'apps.backend.backend_01.counters.req'}, {text: 'apps.backend.backend_02.counters.req'}];
});
it("should add All option", function() {
expect(scenario.variable.options[0].text).to.be("All");
expect(scenario.variable.options[0].value).to.be("$__all");
});
});
it('should return matches options', function() {
expect(scenario.variable.options.length).to.be(1);
});
describeUpdateVariable("with include all and custom value", function(
scenario
) {
scenario.setup(function() {
scenario.variableModel = {
type: "query",
query: "apps.*",
name: "test",
includeAll: true,
allValue: "*"
};
scenario.queryResult = [
{ text: "backend1" },
{ text: "backend2" },
{ text: "backend3" }
];
});
describeUpdateVariable('regex pattern remove duplicates', function(scenario) {
scenario.setup(function() {
scenario.variableModel = {type: 'query', query: 'apps.*', name: 'test'};
scenario.variableModel.regex = '/backend_01/';
scenario.queryResult = [{text: 'apps.backend.backend_01.counters.req'}, {text: 'apps.backend.backend_01.counters.req'}];
});
it("should add All option with custom value", function() {
expect(scenario.variable.options[0].value).to.be("$__all");
});
});
it('should return matches options', function() {
expect(scenario.variable.options.length).to.be(1);
});
describeUpdateVariable("without sort", function(scenario) {
scenario.setup(function() {
scenario.variableModel = {
type: "query",
query: "apps.*",
name: "test",
sort: 0
};
scenario.queryResult = [
{ text: "bbb2" },
{ text: "aaa10" },
{ text: "ccc3" }
];
});
describeUpdateVariable('with include All', function(scenario) {
scenario.setup(function() {
scenario.variableModel = {type: 'query', query: 'apps.*', name: 'test', includeAll: true};
scenario.queryResult = [{text: 'backend1'}, {text: 'backend2'}, { text: 'backend3'}];
});
it("should return options without sort", function() {
expect(scenario.variable.options[0].text).to.be("bbb2");
expect(scenario.variable.options[1].text).to.be("aaa10");
expect(scenario.variable.options[2].text).to.be("ccc3");
});
});
it('should add All option', function() {
expect(scenario.variable.options[0].text).to.be('All');
expect(scenario.variable.options[0].value).to.be('$__all');
});
describeUpdateVariable("with alphabetical sort (asc)", function(scenario) {
scenario.setup(function() {
scenario.variableModel = {
type: "query",
query: "apps.*",
name: "test",
sort: 1
};
scenario.queryResult = [
{ text: "bbb2" },
{ text: "aaa10" },
{ text: "ccc3" }
];
});
describeUpdateVariable('with include all and custom value', function(scenario) {
scenario.setup(function() {
scenario.variableModel = {type: 'query', query: 'apps.*', name: 'test', includeAll: true, allValue: '*'};
scenario.queryResult = [{text: 'backend1'}, {text: 'backend2'}, { text: 'backend3'}];
});
it("should return options with alphabetical sort", function() {
expect(scenario.variable.options[0].text).to.be("aaa10");
expect(scenario.variable.options[1].text).to.be("bbb2");
expect(scenario.variable.options[2].text).to.be("ccc3");
});
});
it('should add All option with custom value', function() {
expect(scenario.variable.options[0].value).to.be('$__all');
});
describeUpdateVariable("with alphabetical sort (desc)", function(scenario) {
scenario.setup(function() {
scenario.variableModel = {
type: "query",
query: "apps.*",
name: "test",
sort: 2
};
scenario.queryResult = [
{ text: "bbb2" },
{ text: "aaa10" },
{ text: "ccc3" }
];
});
describeUpdateVariable('without sort', function(scenario) {
scenario.setup(function() {
scenario.variableModel = {type: 'query', query: 'apps.*', name: 'test', sort: 0};
scenario.queryResult = [{text: 'bbb2'}, {text: 'aaa10'}, { text: 'ccc3'}];
});
it("should return options with alphabetical sort", function() {
expect(scenario.variable.options[0].text).to.be("ccc3");
expect(scenario.variable.options[1].text).to.be("bbb2");
expect(scenario.variable.options[2].text).to.be("aaa10");
});
});
it('should return options without sort', function() {
expect(scenario.variable.options[0].text).to.be('bbb2');
expect(scenario.variable.options[1].text).to.be('aaa10');
expect(scenario.variable.options[2].text).to.be('ccc3');
});
describeUpdateVariable("with numerical sort (asc)", function(scenario) {
scenario.setup(function() {
scenario.variableModel = {
type: "query",
query: "apps.*",
name: "test",
sort: 3
};
scenario.queryResult = [
{ text: "bbb2" },
{ text: "aaa10" },
{ text: "ccc3" }
];
});
describeUpdateVariable('with alphabetical sort (asc)', function(scenario) {
scenario.setup(function() {
scenario.variableModel = {type: 'query', query: 'apps.*', name: 'test', sort: 1};
scenario.queryResult = [{text: 'bbb2'}, {text: 'aaa10'}, { text: 'ccc3'}];
});
it("should return options with numerical sort", function() {
expect(scenario.variable.options[0].text).to.be("bbb2");
expect(scenario.variable.options[1].text).to.be("ccc3");
expect(scenario.variable.options[2].text).to.be("aaa10");
});
});
it('should return options with alphabetical sort', function() {
expect(scenario.variable.options[0].text).to.be('aaa10');
expect(scenario.variable.options[1].text).to.be('bbb2');
expect(scenario.variable.options[2].text).to.be('ccc3');
});
describeUpdateVariable("with numerical sort (desc)", function(scenario) {
scenario.setup(function() {
scenario.variableModel = {
type: "query",
query: "apps.*",
name: "test",
sort: 4
};
scenario.queryResult = [
{ text: "bbb2" },
{ text: "aaa10" },
{ text: "ccc3" }
];
});
describeUpdateVariable('with alphabetical sort (desc)', function(scenario) {
scenario.setup(function() {
scenario.variableModel = {type: 'query', query: 'apps.*', name: 'test', sort: 2};
scenario.queryResult = [{text: 'bbb2'}, {text: 'aaa10'}, { text: 'ccc3'}];
});
it("should return options with numerical sort", function() {
expect(scenario.variable.options[0].text).to.be("aaa10");
expect(scenario.variable.options[1].text).to.be("ccc3");
expect(scenario.variable.options[2].text).to.be("bbb2");
});
});
it('should return options with alphabetical sort', function() {
expect(scenario.variable.options[0].text).to.be('ccc3');
expect(scenario.variable.options[1].text).to.be('bbb2');
expect(scenario.variable.options[2].text).to.be('aaa10');
});
//
// datasource variable update
//
describeUpdateVariable("datasource variable with regex filter", function(
scenario
) {
scenario.setup(function() {
scenario.variableModel = {
type: "datasource",
query: "graphite",
name: "test",
current: { value: "backend4_pee", text: "backend4_pee" },
regex: "/pee$/"
};
scenario.metricSources = [
{ name: "backend1", meta: { id: "influx" } },
{ name: "backend2_pee", meta: { id: "graphite" } },
{ name: "backend3", meta: { id: "graphite" } },
{ name: "backend4_pee", meta: { id: "graphite" } }
];
});
describeUpdateVariable('with numerical sort (asc)', function(scenario) {
scenario.setup(function() {
scenario.variableModel = {type: 'query', query: 'apps.*', name: 'test', sort: 3};
scenario.queryResult = [{text: 'bbb2'}, {text: 'aaa10'}, { text: 'ccc3'}];
});
it('should return options with numerical sort', function() {
expect(scenario.variable.options[0].text).to.be('bbb2');
expect(scenario.variable.options[1].text).to.be('ccc3');
expect(scenario.variable.options[2].text).to.be('aaa10');
});
it("should set only contain graphite ds and filtered using regex", function() {
expect(scenario.variable.options.length).to.be(2);
expect(scenario.variable.options[0].value).to.be("backend2_pee");
expect(scenario.variable.options[1].value).to.be("backend4_pee");
});
describeUpdateVariable('with numerical sort (desc)', function(scenario) {
scenario.setup(function() {
scenario.variableModel = {type: 'query', query: 'apps.*', name: 'test', sort: 4};
scenario.queryResult = [{text: 'bbb2'}, {text: 'aaa10'}, { text: 'ccc3'}];
});
it("should keep current value if available", function() {
expect(scenario.variable.current.value).to.be("backend4_pee");
});
});
it('should return options with numerical sort', function() {
expect(scenario.variable.options[0].text).to.be('aaa10');
expect(scenario.variable.options[1].text).to.be('ccc3');
expect(scenario.variable.options[2].text).to.be('bbb2');
});
//
// Custom variable update
//
describeUpdateVariable("update custom variable", function(scenario) {
scenario.setup(function() {
scenario.variableModel = {
type: "custom",
query: "hej, hop, asd",
name: "test"
};
});
//
// datasource variable update
//
describeUpdateVariable('datasource variable with regex filter', function(scenario) {
scenario.setup(function() {
scenario.variableModel = {
type: 'datasource',
query: 'graphite',
name: 'test',
current: {value: 'backend4_pee', text: 'backend4_pee'},
regex: '/pee$/'
};
scenario.metricSources = [
{name: 'backend1', meta: {id: 'influx'}},
{name: 'backend2_pee', meta: {id: 'graphite'}},
{name: 'backend3', meta: {id: 'graphite'}},
{name: 'backend4_pee', meta: {id: 'graphite'}},
];
});
it("should update options array", function() {
expect(scenario.variable.options.length).to.be(3);
expect(scenario.variable.options[0].text).to.be("hej");
expect(scenario.variable.options[1].value).to.be("hop");
});
});
it('should set only contain graphite ds and filtered using regex', function() {
expect(scenario.variable.options.length).to.be(2);
expect(scenario.variable.options[0].value).to.be('backend2_pee');
expect(scenario.variable.options[1].value).to.be('backend4_pee');
});
describe("multiple interval variables with auto", function() {
var variable1, variable2;
it('should keep current value if available', function() {
expect(scenario.variable.current.value).to.be('backend4_pee');
});
beforeEach(function() {
var range = {
from: moment(new Date())
.subtract(7, "days")
.toDate(),
to: new Date()
};
ctx.timeSrv.timeRange = sinon.stub().returns(range);
ctx.templateSrv.setGrafanaVariable = sinon.spy();
var variableModel1 = {
type: "interval",
query: "1s,2h,5h,1d",
name: "variable1",
auto: true,
auto_count: 10
};
variable1 = ctx.variableSrv.createVariableFromModel(variableModel1);
ctx.variableSrv.addVariable(variable1);
var variableModel2 = {
type: "interval",
query: "1s,2h,5h",
name: "variable2",
auto: true,
auto_count: 1000
};
variable2 = ctx.variableSrv.createVariableFromModel(variableModel2);
ctx.variableSrv.addVariable(variable2);
ctx.variableSrv.updateOptions(variable1);
ctx.variableSrv.updateOptions(variable2);
ctx.$rootScope.$digest();
});
//
// Custom variable update
//
describeUpdateVariable('update custom variable', function(scenario) {
scenario.setup(function() {
scenario.variableModel = {type: 'custom', query: 'hej, hop, asd', name: 'test'};
});
it('should update options array', function() {
expect(scenario.variable.options.length).to.be(3);
expect(scenario.variable.options[0].text).to.be('hej');
expect(scenario.variable.options[1].value).to.be('hop');
});
it("should update options array", function() {
expect(variable1.options.length).to.be(5);
expect(variable1.options[0].text).to.be("auto");
expect(variable1.options[0].value).to.be("$__auto_interval_variable1");
expect(variable2.options.length).to.be(4);
expect(variable2.options[0].text).to.be("auto");
expect(variable2.options[0].value).to.be("$__auto_interval_variable2");
});
describe('multiple interval variables with auto', function() {
var variable1, variable2;
beforeEach(function() {
var range = {
from: moment(new Date()).subtract(7, 'days').toDate(),
to: new Date()
};
ctx.timeSrv.timeRange = sinon.stub().returns(range);
ctx.templateSrv.setGrafanaVariable = sinon.spy();
var variableModel1 = {type: 'interval', query: '1s,2h,5h,1d', name: 'variable1', auto: true, auto_count: 10 };
variable1 = ctx.variableSrv.createVariableFromModel(variableModel1);
ctx.variableSrv.addVariable(variable1);
var variableModel2 = {type: 'interval', query: '1s,2h,5h', name: 'variable2', auto: true, auto_count: 1000 };
variable2 = ctx.variableSrv.createVariableFromModel(variableModel2);
ctx.variableSrv.addVariable(variable2);
ctx.variableSrv.updateOptions(variable1);
ctx.variableSrv.updateOptions(variable2);
ctx.$rootScope.$digest();
});
it('should update options array', function() {
expect(variable1.options.length).to.be(5);
expect(variable1.options[0].text).to.be('auto');
expect(variable1.options[0].value).to.be('$__auto_interval_variable1');
expect(variable2.options.length).to.be(4);
expect(variable2.options[0].text).to.be('auto');
expect(variable2.options[0].value).to.be('$__auto_interval_variable2');
});
it('should correctly set $__auto_interval_variableX', function() {
var variable1Set, variable2Set, legacySet, unknownSet = false;
// updateAutoValue() gets called repeatedly: once directly once via VariableSrv.validateVariableSelectionState()
// So check that all calls are valid rather than expect a specific number and/or ordering of calls
for (var i = 0; i < ctx.templateSrv.setGrafanaVariable.callCount; i++) {
var call = ctx.templateSrv.setGrafanaVariable.getCall(i);
switch (call.args[0]) {
case '$__auto_interval_variable1':
expect(call.args[1]).to.be('12h');
variable1Set = true;
break;
case '$__auto_interval_variable2':
expect(call.args[1]).to.be('10m');
variable2Set = true;
break;
case '$__auto_interval':
expect(call.args[1]).to.match(/^(12h|10m)$/);
legacySet = true;
break;
default:
unknownSet = true;
break;
}
it("should correctly set $__auto_interval_variableX", function() {
var variable1Set,
variable2Set,
legacySet,
unknownSet = false;
// updateAutoValue() gets called repeatedly: once directly once via VariableSrv.validateVariableSelectionState()
// So check that all calls are valid rather than expect a specific number and/or ordering of calls
for (var i = 0; i < ctx.templateSrv.setGrafanaVariable.callCount; i++) {
var call = ctx.templateSrv.setGrafanaVariable.getCall(i);
switch (call.args[0]) {
case "$__auto_interval_variable1":
expect(call.args[1]).to.be("12h");
variable1Set = true;
break;
case "$__auto_interval_variable2":
expect(call.args[1]).to.be("10m");
variable2Set = true;
break;
case "$__auto_interval":
expect(call.args[1]).to.match(/^(12h|10m)$/);
legacySet = true;
break;
default:
unknownSet = true;
break;
}
expect(variable1Set).to.be.equal(true);
expect(variable2Set).to.be.equal(true);
expect(legacySet).to.be.equal(true);
expect(unknownSet).to.be.equal(false);
});
}
expect(variable1Set).to.be.equal(true);
expect(variable2Set).to.be.equal(true);
expect(legacySet).to.be.equal(true);
expect(unknownSet).to.be.equal(false);
});
});
});

View File

@@ -1,8 +1,11 @@
import kbn from 'app/core/utils/kbn';
import _ from 'lodash';
import kbn from "app/core/utils/kbn";
import _ from "lodash";
function luceneEscape(value) {
return value.replace(/([\!\*\+\-\=<>\s\&\|\(\)\[\]\{\}\^\~\?\:\\/"])/g, "\\$1");
return value.replace(
/([\!\*\+\-\=<>\s\&\|\(\)\[\]\{\}\^\~\?\:\\/"])/g,
"\\$1"
);
}
export class TemplateSrv {
@@ -14,8 +17,8 @@ export class TemplateSrv {
private builtIns = {};
constructor() {
this.builtIns['__interval'] = {text: '1s', value: '1s'};
this.builtIns['__interval_ms'] = {text: '100', value: '100'};
this.builtIns["__interval"] = { text: "1s", value: "1s" };
this.builtIns["__interval_ms"] = { text: "100", value: "100" };
}
init(variables) {
@@ -29,7 +32,10 @@ export class TemplateSrv {
for (var i = 0; i < this.variables.length; i++) {
var variable = this.variables[i];
if (!variable.current || !variable.current.isNone && !variable.current.value) {
if (
!variable.current ||
(!variable.current.isNone && !variable.current.value)
) {
continue;
}
@@ -46,7 +52,7 @@ export class TemplateSrv {
for (var i = 0; i < this.variables.length; i++) {
var variable = this.variables[i];
if (variable.type !== 'adhoc') {
if (variable.type !== "adhoc") {
continue;
}
@@ -54,7 +60,7 @@ export class TemplateSrv {
filters = filters.concat(variable.filters);
}
if (variable.datasource.indexOf('$') === 0) {
if (variable.datasource.indexOf("$") === 0) {
if (this.replace(variable.datasource) === datasourceName) {
filters = filters.concat(variable.filters);
}
@@ -65,50 +71,50 @@ export class TemplateSrv {
}
luceneFormat(value) {
if (typeof value === 'string') {
if (typeof value === "string") {
return luceneEscape(value);
}
var quotedValues = _.map(value, function(val) {
return '\"' + luceneEscape(val) + '\"';
return '"' + luceneEscape(val) + '"';
});
return '(' + quotedValues.join(' OR ') + ')';
return "(" + quotedValues.join(" OR ") + ")";
}
formatValue(value, format, variable) {
// for some scopedVars there is no variable
variable = variable || {};
if (typeof format === 'function') {
if (typeof format === "function") {
return format(value, variable, this.formatValue);
}
switch (format) {
case "regex": {
if (typeof value === 'string') {
if (typeof value === "string") {
return kbn.regexEscape(value);
}
var escapedValues = _.map(value, kbn.regexEscape);
return '(' + escapedValues.join('|') + ')';
return "(" + escapedValues.join("|") + ")";
}
case "lucene": {
return this.luceneFormat(value);
}
case "pipe": {
if (typeof value === 'string') {
if (typeof value === "string") {
return value;
}
return value.join('|');
return value.join("|");
}
case "distributed": {
if (typeof value === 'string') {
if (typeof value === "string") {
return value;
}
return this.distributeVariable(value, variable.name);
}
default: {
default: {
if (_.isArray(value)) {
return '{' + value.join(',') + '}';
return "{" + value.join(",") + "}";
}
return value;
}
@@ -130,17 +136,19 @@ export class TemplateSrv {
variableExists(expression) {
var name = this.getVariableName(expression);
return name && (this.index[name] !== void 0);
return name && this.index[name] !== void 0;
}
highlightVariablesAsHtml(str) {
if (!str || !_.isString(str)) { return str; }
if (!str || !_.isString(str)) {
return str;
}
str = _.escape(str);
this.regex.lastIndex = 0;
return str.replace(this.regex, (match, g1, g2) => {
if (this.index[g1 || g2] || this.builtIns[g1 || g2]) {
return '<span class="template-variable">' + match + '</span>';
return '<span class="template-variable">' + match + "</span>";
}
return match;
});
@@ -158,7 +166,9 @@ export class TemplateSrv {
}
replace(target, scopedVars?, format?) {
if (!target) { return target; }
if (!target) {
return target;
}
var variable, systemValue, value;
this.regex.lastIndex = 0;
@@ -197,11 +207,15 @@ export class TemplateSrv {
}
isAllValue(value) {
return value === '$__all' || Array.isArray(value) && value[0] === '$__all';
return (
value === "$__all" || (Array.isArray(value) && value[0] === "$__all")
);
}
replaceWithText(target, scopedVars) {
if (!target) { return target; }
if (!target) {
return target;
}
var variable;
this.regex.lastIndex = 0;
@@ -209,22 +223,28 @@ export class TemplateSrv {
return target.replace(this.regex, (match, g1, g2) => {
if (scopedVars) {
var option = scopedVars[g1 || g2];
if (option) { return option.text; }
if (option) {
return option.text;
}
}
variable = this.index[g1 || g2];
if (!variable) { return match; }
if (!variable) {
return match;
}
return this.grafanaVariables[variable.current.value] || variable.current.text;
return (
this.grafanaVariables[variable.current.value] || variable.current.text
);
});
}
fillVariableValuesForUrl(params, scopedVars) {
_.each(this.variables, function(variable) {
if (scopedVars && scopedVars[variable.name] !== void 0) {
params['var-' + variable.name] = scopedVars[variable.name].value;
params["var-" + variable.name] = scopedVars[variable.name].value;
} else {
params['var-' + variable.name] = variable.getValueForUrl();
params["var-" + variable.name] = variable.getValueForUrl();
}
});
}
@@ -237,7 +257,7 @@ export class TemplateSrv {
return val;
}
});
return value.join(',');
return value.join(",");
}
}

View File

@@ -1,5 +1,5 @@
import kbn from 'app/core/utils/kbn';
import {assignModelProperties} from 'app/core/utils/model_utils';
import kbn from "app/core/utils/kbn";
import { assignModelProperties } from "app/core/utils/model_utils";
export interface Variable {
setValue(option);
@@ -11,25 +11,21 @@ export interface Variable {
}
export var variableTypes = {};
export {
assignModelProperties
};
export { assignModelProperties };
export function containsVariable(...args: any[]) {
var variableName = args[args.length-1];
var str = args[0] || '';
var variableName = args[args.length - 1];
var str = args[0] || "";
for (var i = 1; i < args.length-1; i++) {
str += ' ' + args[i] || '';
for (var i = 1; i < args.length - 1; i++) {
str += " " + args[i] || "";
}
variableName = kbn.regexEscape(variableName);
var findVarRegex = new RegExp('\\$(' + variableName + ')(?:\\W|$)|\\[\\[(' + variableName + ')\\]\\]', 'g');
var findVarRegex = new RegExp(
"\\$(" + variableName + ")(?:\\W|$)|\\[\\[(" + variableName + ")\\]\\]",
"g"
);
var match = findVarRegex.exec(str);
return match !== null;
}

View File

@@ -1,26 +1,38 @@
///<reference path="../../headers/common.d.ts" />
import angular from 'angular';
import _ from 'lodash';
import coreModule from 'app/core/core_module';
import {variableTypes} from './variable';
import angular from "angular";
import _ from "lodash";
import coreModule from "app/core/core_module";
import { variableTypes } from "./variable";
export class VariableSrv {
dashboard: any;
variables: any;
/** @ngInject */
constructor(private $rootScope, private $q, private $location, private $injector, private templateSrv) {
constructor(
private $rootScope,
private $q,
private $location,
private $injector,
private templateSrv
) {
// update time variant variables
$rootScope.$on('refresh', this.onDashboardRefresh.bind(this), $rootScope);
$rootScope.$on('template-variable-value-updated', this.updateUrlParamsWithCurrentVariables.bind(this), $rootScope);
$rootScope.$on("refresh", this.onDashboardRefresh.bind(this), $rootScope);
$rootScope.$on(
"template-variable-value-updated",
this.updateUrlParamsWithCurrentVariables.bind(this),
$rootScope
);
}
init(dashboard) {
this.dashboard = dashboard;
// create working class models representing variables
this.variables = dashboard.templating.list = dashboard.templating.list.map(this.createVariableFromModel.bind(this));
this.variables = dashboard.templating.list = dashboard.templating.list.map(
this.createVariableFromModel.bind(this)
);
this.templateSrv.init(this.variables);
// init variables
@@ -29,26 +41,31 @@ export class VariableSrv {
}
var queryParams = this.$location.search();
return this.$q.all(this.variables.map(variable => {
return this.processVariable(variable, queryParams);
})).then(() => {
this.templateSrv.updateTemplateData();
});
return this.$q
.all(
this.variables.map(variable => {
return this.processVariable(variable, queryParams);
})
)
.then(() => {
this.templateSrv.updateTemplateData();
});
}
onDashboardRefresh() {
var promises = this.variables
.filter(variable => variable.refresh === 2)
.map(variable => {
var previousOptions = variable.options.slice();
.filter(variable => variable.refresh === 2)
.map(variable => {
var previousOptions = variable.options.slice();
return variable.updateOptions()
.then(() => {
if (angular.toJson(previousOptions) !== angular.toJson(variable.options)) {
this.$rootScope.$emit('template-variable-value-updated');
}
return variable.updateOptions().then(() => {
if (
angular.toJson(previousOptions) !== angular.toJson(variable.options)
) {
this.$rootScope.$emit("template-variable-value-updated");
}
});
});
});
return this.$q.all(promises);
}
@@ -62,30 +79,37 @@ export class VariableSrv {
}
}
return this.$q.all(dependencies).then(() => {
var urlValue = queryParams['var-' + variable.name];
if (urlValue !== void 0) {
return variable.setValueFromUrl(urlValue).then(variable.initLock.resolve);
}
return this.$q
.all(dependencies)
.then(() => {
var urlValue = queryParams["var-" + variable.name];
if (urlValue !== void 0) {
return variable
.setValueFromUrl(urlValue)
.then(variable.initLock.resolve);
}
if (variable.refresh === 1 || variable.refresh === 2) {
return variable.updateOptions().then(variable.initLock.resolve);
}
if (variable.refresh === 1 || variable.refresh === 2) {
return variable.updateOptions().then(variable.initLock.resolve);
}
variable.initLock.resolve();
}).finally(() => {
this.templateSrv.variableInitialized(variable);
delete variable.initLock;
});
variable.initLock.resolve();
})
.finally(() => {
this.templateSrv.variableInitialized(variable);
delete variable.initLock;
});
}
createVariableFromModel(model) {
var ctor = variableTypes[model.type].ctor;
if (!ctor) {
throw {message: "Unable to find variable constructor for " + model.type};
throw {
message: "Unable to find variable constructor for " + model.type
};
}
var variable = this.$injector.instantiate(ctor, {model: model});
var variable = this.$injector.instantiate(ctor, { model: model });
return variable;
}
@@ -125,8 +149,8 @@ export class VariableSrv {
return this.$q.all(promises).then(() => {
if (emitChangeEvents) {
this.$rootScope.$emit('template-variable-value-updated');
this.$rootScope.$broadcast('refresh');
this.$rootScope.$emit("template-variable-value-updated");
this.$rootScope.$broadcast("refresh");
}
});
}
@@ -168,18 +192,26 @@ export class VariableSrv {
selected = variable.options[0];
} else {
selected = {
value: _.map(selected, function(val) {return val.value;}),
text: _.map(selected, function(val) {return val.text;}).join(' + '),
value: _.map(selected, function(val) {
return val.value;
}),
text: _.map(selected, function(val) {
return val.text;
}).join(" + ")
};
}
return variable.setValue(selected);
} else {
var currentOption = _.find(variable.options, {text: variable.current.text});
var currentOption = _.find(variable.options, {
text: variable.current.text
});
if (currentOption) {
return variable.setValue(currentOption);
} else {
if (!variable.options.length) { return Promise.resolve(); }
if (!variable.options.length) {
return Promise.resolve();
}
return variable.setValue(variable.options[0]);
}
}
@@ -197,7 +229,7 @@ export class VariableSrv {
return op.text === urlValue || op.value === urlValue;
});
option = option || {text: urlValue, value: urlValue};
option = option || { text: urlValue, value: urlValue };
return variable.setValue(option);
});
}
@@ -206,7 +238,7 @@ export class VariableSrv {
variable.current = _.cloneDeep(option);
if (_.isArray(variable.current.text)) {
variable.current.text = variable.current.text.join(' + ');
variable.current.text = variable.current.text.join(" + ");
}
this.selectOptionsForCurrentValue(variable);
@@ -219,7 +251,7 @@ export class VariableSrv {
// remove variable params
_.each(params, function(value, key) {
if (key.indexOf('var-') === 0) {
if (key.indexOf("var-") === 0) {
delete params[key];
}
});
@@ -231,24 +263,30 @@ export class VariableSrv {
}
setAdhocFilter(options) {
var variable = _.find(this.variables, {type: 'adhoc', datasource: options.datasource});
var variable = _.find(this.variables, {
type: "adhoc",
datasource: options.datasource
});
if (!variable) {
variable = this.createVariableFromModel({name: 'Filters', type: 'adhoc', datasource: options.datasource});
variable = this.createVariableFromModel({
name: "Filters",
type: "adhoc",
datasource: options.datasource
});
this.addVariable(variable);
}
let filters = variable.filters;
let filter = _.find(filters, {key: options.key, value: options.value});
let filter = _.find(filters, { key: options.key, value: options.value });
if (!filter) {
filter = {key: options.key, value: options.value};
filter = { key: options.key, value: options.value };
filters.push(filter);
}
filter.operator = options.operator;
this.variableUpdated(variable, true);
}
}
coreModule.service('variableSrv', VariableSrv);
coreModule.service("variableSrv", VariableSrv);