mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
Merge branch 'variable-value-formatting-rethink'
This commit is contained in:
commit
2cf1193b56
@ -4,7 +4,7 @@
|
|||||||
"bitwise":false,
|
"bitwise":false,
|
||||||
"curly": true,
|
"curly": true,
|
||||||
"eqnull": true,
|
"eqnull": true,
|
||||||
"globalstrict": true,
|
"strict": true,
|
||||||
"devel": true,
|
"devel": true,
|
||||||
"eqeqeq": true,
|
"eqeqeq": true,
|
||||||
"forin": false,
|
"forin": false,
|
||||||
@ -12,7 +12,7 @@
|
|||||||
"supernew": true,
|
"supernew": true,
|
||||||
"expr": true,
|
"expr": true,
|
||||||
"indent": 2,
|
"indent": 2,
|
||||||
"latedef": true,
|
"latedef": false,
|
||||||
"newcap": true,
|
"newcap": true,
|
||||||
"noarg": true,
|
"noarg": true,
|
||||||
"noempty": true,
|
"noempty": true,
|
||||||
|
@ -23,4 +23,4 @@ scrape_configs:
|
|||||||
# scheme defaults to 'http'.
|
# scheme defaults to 'http'.
|
||||||
|
|
||||||
target_groups:
|
target_groups:
|
||||||
- targets: ['localhost:9090', '172.17.42.1:9091']
|
- targets: ['localhost:9090', '172.17.0.1:9091']
|
||||||
|
@ -24,7 +24,7 @@
|
|||||||
"grunt-contrib-copy": "~0.8.2",
|
"grunt-contrib-copy": "~0.8.2",
|
||||||
"grunt-contrib-cssmin": "~0.14.0",
|
"grunt-contrib-cssmin": "~0.14.0",
|
||||||
"grunt-contrib-htmlmin": "~0.6.0",
|
"grunt-contrib-htmlmin": "~0.6.0",
|
||||||
"grunt-contrib-jshint": "~0.11.3",
|
"grunt-contrib-jshint": "~1.0.0",
|
||||||
"grunt-contrib-less": "~0.7.0",
|
"grunt-contrib-less": "~0.7.0",
|
||||||
"grunt-contrib-uglify": "~0.11.0",
|
"grunt-contrib-uglify": "~0.11.0",
|
||||||
"grunt-contrib-watch": "^0.6.1",
|
"grunt-contrib-watch": "^0.6.1",
|
||||||
@ -39,7 +39,7 @@
|
|||||||
"grunt-tslint": "^3.0.2",
|
"grunt-tslint": "^3.0.2",
|
||||||
"grunt-typescript": "^0.8.0",
|
"grunt-typescript": "^0.8.0",
|
||||||
"grunt-usemin": "3.0.0",
|
"grunt-usemin": "3.0.0",
|
||||||
"jshint-stylish": "~0.1.5",
|
"jshint-stylish": "~2.1.0",
|
||||||
"karma": "~0.13.15",
|
"karma": "~0.13.15",
|
||||||
"karma-chrome-launcher": "~0.2.2",
|
"karma-chrome-launcher": "~0.2.2",
|
||||||
"karma-coverage": "0.5.3",
|
"karma-coverage": "0.5.3",
|
||||||
|
@ -179,8 +179,7 @@ function (angular, _, coreModule) {
|
|||||||
vm.variable.current.text = _.pluck(vm.selectedValues, 'text').join(' + ');
|
vm.variable.current.text = _.pluck(vm.selectedValues, 'text').join(' + ');
|
||||||
vm.variable.current.tags = vm.selectedTags;
|
vm.variable.current.tags = vm.selectedTags;
|
||||||
|
|
||||||
// only single value
|
if (!vm.variable.multi) {
|
||||||
if (vm.selectedValues.length === 1) {
|
|
||||||
vm.variable.current.value = vm.selectedValues[0].value;
|
vm.variable.current.value = vm.selectedValues[0].value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -15,26 +15,24 @@
|
|||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<h5 class="page-heading">
|
<h5 class="section-heading">
|
||||||
Migrate dashboards
|
Migrate dashboards
|
||||||
<em style="font-size: 14px;padding-left: 10px;"><i class="fa fa-info-circle"></i> Import dashboards from Elasticsearch or InfluxDB</em>
|
<em style="font-size: 14px;padding-left: 10px;"><i class="fa fa-info-circle"></i> Import dashboards from Elasticsearch or InfluxDB</em>
|
||||||
</h5>
|
</h5>
|
||||||
|
|
||||||
<div class="gf-form-group last">
|
<div class="gf-form-inline gf-form-group">
|
||||||
<div class="gf-form">
|
<div class="gf-form">
|
||||||
<div class="gf-form-label">Dashboard source</div>
|
<div class="gf-form-label">Dashboard source</div>
|
||||||
<div>
|
<div class="gf-form-select-wrapper">
|
||||||
<div class="gf-form-select-wrapper">
|
<select class="gf-form-input gf-size-auto" ng-model="sourceName" ng-options="f for f in datasources"></select>
|
||||||
<select class="gf-form-input gf-size-auto" ng-model="sourceName" ng-options="f for f in datasources"></select>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="gf-form-btn">
|
|
||||||
<button class="btn btn-success" ng-click="startImport()">Import</button>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="gf-form">
|
||||||
|
<button class="btn btn-success gf-form-btn" ng-click="startImport()">Import</button>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<h5 class="page-heading" ng-if="importing">{{infoText}}</h5>
|
<h5 class="section-heading" ng-if="importing">{{infoText}}</h5>
|
||||||
<div class="editor-row" ng-if="importing">
|
<div class="editor-row" ng-if="importing">
|
||||||
<div class="editor-row row">
|
<div class="editor-row row">
|
||||||
<table class="grafana-options-table span5">
|
<table class="grafana-options-table span5">
|
||||||
|
@ -136,22 +136,23 @@
|
|||||||
<button class="btn btn-inverse btn-large" data-clipboard-text="{{snapshotUrl}}" clipboard-button><i class="fa fa-clipboard"></i> Copy Link</button>
|
<button class="btn btn-inverse btn-large" data-clipboard-text="{{snapshotUrl}}" clipboard-button><i class="fa fa-clipboard"></i> Copy Link</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div ng-if="step === 1" class="gf-form-buttons-row">
|
|
||||||
<button class="btn btn-success btn-large" ng-click="createSnapshot()" ng-disabled="loading">
|
|
||||||
<i class="fa fa-save"></i>
|
|
||||||
Local Snapshot
|
|
||||||
</button>
|
|
||||||
<button class="btn btn-primary btn-large" ng-if="externalEnabled" ng-click="createSnapshot(true)" ng-disabled="loading">
|
|
||||||
<i class="fa fa-cloud-upload"></i>
|
|
||||||
{{sharingButtonText}}
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="pull-right" ng-if="step === 2" style="padding: 5px">
|
|
||||||
Did you make a mistake? <a class="pointer" ng-click="deleteSnapshot()" target="_blank">delete snapshot.</a>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div ng-if="step === 1" class="gf-form-buttons-row">
|
||||||
|
<button class="btn btn-success btn-large" ng-click="createSnapshot()" ng-disabled="loading">
|
||||||
|
<i class="fa fa-save"></i>
|
||||||
|
Local Snapshot
|
||||||
|
</button>
|
||||||
|
<button class="btn btn-primary btn-large" ng-if="externalEnabled" ng-click="createSnapshot(true)" ng-disabled="loading">
|
||||||
|
<i class="fa fa-cloud-upload"></i>
|
||||||
|
{{sharingButtonText}}
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="pull-right" ng-if="step === 2" style="padding: 5px">
|
||||||
|
Did you make a mistake? <a class="pointer" ng-click="deleteSnapshot()" target="_blank">delete snapshot.</a>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
</script>
|
</script>
|
||||||
|
@ -12,7 +12,7 @@
|
|||||||
</li>
|
</li>
|
||||||
<li class="gf-tabs-item" ng-show="mode === 'edit'">
|
<li class="gf-tabs-item" ng-show="mode === 'edit'">
|
||||||
<a class="gf-tabs-link" ng-class="{active: mode === 'edit'}">
|
<a class="gf-tabs-link" ng-class="{active: mode === 'edit'}">
|
||||||
{{current.name}}
|
Edit
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
<li class="gf-tabs-item" ng-show="mode === 'new'">
|
<li class="gf-tabs-item" ng-show="mode === 'new'">
|
||||||
@ -79,7 +79,7 @@
|
|||||||
<input type="text" class="gf-form-input max-width-14" placeholder="name" ng-model='current.name'></input>
|
<input type="text" class="gf-form-input max-width-14" placeholder="name" ng-model='current.name'></input>
|
||||||
</div>
|
</div>
|
||||||
<div class="gf-form">
|
<div class="gf-form">
|
||||||
<span class="gf-form-label width-7">Type</span>
|
<span class="gf-form-label width-4">Type</span>
|
||||||
<div class="gf-form-select-wrapper max-width-10">
|
<div class="gf-form-select-wrapper max-width-10">
|
||||||
<select class="gf-form-input max-width-10" ng-model="current.type" ng-options="f for f in ['query', 'interval', 'custom']" ng-change="typeChanged()"></select>
|
<select class="gf-form-input max-width-10" ng-model="current.type" ng-options="f for f in ['query', 'interval', 'custom']" ng-change="typeChanged()"></select>
|
||||||
</div>
|
</div>
|
||||||
@ -97,8 +97,9 @@
|
|||||||
<input type="text" class="gf-form-input max-width-14" ng-model='current.label' placeholder="optional display name"></input>
|
<input type="text" class="gf-form-input max-width-14" ng-model='current.label' placeholder="optional display name"></input>
|
||||||
</div>
|
</div>
|
||||||
<div class="gf-form">
|
<div class="gf-form">
|
||||||
<editor-checkbox class="width-10" text="Hide label" model="current.hideLabel" change="runQuery()"></editor-checkbox>
|
<span class="gf-form-label width-4">Hide</span>
|
||||||
<editor-checkbox class="width-11" text="Hide variable" model="current.hideVariable" change="runQuery()"></editor-checkbox>
|
<editor-checkbox text="Label" model="current.hideLabel" change="runQuery()"></editor-checkbox>
|
||||||
|
<editor-checkbox text="Variable" model="current.hideVariable" change="runQuery()"></editor-checkbox>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@ -107,40 +108,35 @@
|
|||||||
<h5 class="section-heading">Value Options</h5>
|
<h5 class="section-heading">Value Options</h5>
|
||||||
<div ng-show="current.type === 'interval'" class="gf-form-group">
|
<div ng-show="current.type === 'interval'" class="gf-form-group">
|
||||||
<div class="gf-form">
|
<div class="gf-form">
|
||||||
<span class="gf-form-label width-7">Values</span>
|
<span class="gf-form-label width-9">Values</span>
|
||||||
<input type="text" class="gf-form-input max-width-28" placeholder="name" ng-model='current.query' placeholder="1m,10m,1h,6h,1d,7d" ng-model-onblur ng-change="runQuery()"></input>
|
<input type="text" class="gf-form-input" placeholder="name" ng-model='current.query' placeholder="1m,10m,1h,6h,1d,7d" ng-model-onblur ng-change="runQuery()"></input>
|
||||||
</div>
|
</div>
|
||||||
<div class="gf-form">
|
<div class="gf-form">
|
||||||
<editor-checkbox text="Include auto interval" model="current.auto" change="runQuery()"></editor-checkbox>
|
<span class="gf-form-label width-9">Auto option</span>
|
||||||
<span class="gf-form-label" ng-show="current.auto">
|
<editor-checkbox text="Enable" model="current.auto" change="runQuery()"></editor-checkbox>
|
||||||
Auto interval steps <tip>How many times should the current time range be divided to calculate the value</tip>
|
</div>
|
||||||
</span>
|
<div class="gf-form-inline">
|
||||||
<div class="gf-form-select-wrapper max-width-10" ng-show="current.auto">
|
<div class="gf-form">
|
||||||
<select class="gf-form-input" ng-model="current.auto_count" ng-options="f for f in [2,3,4,5,10,20,30,40,50,100,200,300,400,500]" ng-change="runQuery()"></select>
|
<span class="gf-form-label width-9" ng-show="current.auto">
|
||||||
|
Auto steps <tip>How many times should the current time range be divided to calculate the value</tip>
|
||||||
|
</span>
|
||||||
|
<div class="gf-form-select-wrapper max-width-10" ng-show="current.auto">
|
||||||
|
<select class="gf-form-input" ng-model="current.auto_count" ng-options="f for f in [2,3,4,5,10,20,30,40,50,100,200,300,400,500]" ng-change="runQuery()"></select>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="gf-form">
|
||||||
|
<span class="gf-form-label" ng-show="current.auto">
|
||||||
|
Min interval <tip>The calculated value will not go below this threshold</tip>
|
||||||
|
</span>
|
||||||
|
<input type="text" class="gf-form-input max-width-10" ng-show="current.auto" ng-model="current.auto_min" ng-change="runQuery()" placeholder="10s"></input>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
<div class="gf-form">
|
|
||||||
<span class="gf-form-label" ng-show="current.auto">
|
|
||||||
Auto interval min value <tip>The calculated value will not go below this threshold</tip>
|
|
||||||
</span>
|
|
||||||
<input type="text" class="gf-form-input max-width-10" ng-show="current.auto" ng-model="current.auto_min" ng-change="runQuery()"></input>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div ng-show="current.type === 'custom'" class="gf-form-group">
|
<div ng-show="current.type === 'custom'" class="gf-form-group">
|
||||||
<div class="gf-form">
|
<div class="gf-form">
|
||||||
<span class="gf-form-label width-13">Values seperated by comma</span>
|
<span class="gf-form-label width-13">Values seperated by comma</span>
|
||||||
<input type="text" class="gf-form-input max-width-22" ng-model='current.query' ng-blur="runQuery()" placeholder="1, 10, 20, myvalue"></input>
|
<input type="text" class="gf-form-input" ng-model='current.query' ng-blur="runQuery()" placeholder="1, 10, 20, myvalue"></input>
|
||||||
</div>
|
|
||||||
<div class="gf-form ">
|
|
||||||
<editor-checkbox class="width-13" text="All value" model="current.includeAll" change="runQuery()"></editor-checkbox>
|
|
||||||
<input ng-show="current.includeAll" type="text" class="gf-form-input max-width-22" ng-model='current.options[0].value' style="margin-left: 4px;"></input>
|
|
||||||
</div>
|
|
||||||
<div class="gf-form">
|
|
||||||
<span class="gf-form-label width-13" ng-show="current.includeAll">All format</span>
|
|
||||||
<div class="gf-form-select-wrapper max-width-10" ng-show="current.includeAll">
|
|
||||||
<select class="gf-form-input" ng-model="current.allFormat" ng-change="runQuery()" ng-options="f for f in ['glob', 'wildcard', 'regex wildcard', 'regex values', 'lucene', 'pipe']"></select>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@ -156,22 +152,6 @@
|
|||||||
</span>
|
</span>
|
||||||
<input type="text" class="gf-form-input" ng-model='current.regex' placeholder="/.*-(.*)-.*/" ng-model-onblur ng-change="runQuery()"></input>
|
<input type="text" class="gf-form-input" ng-model='current.regex' placeholder="/.*-(.*)-.*/" ng-model-onblur ng-change="runQuery()"></input>
|
||||||
</div>
|
</div>
|
||||||
<div class="gf-form">
|
|
||||||
<span class="gf-form-label width-7">All value</span>
|
|
||||||
<editor-checkbox class="width-13" text="Enable" model="current.includeAll" change="runQuery()"></editor-checkbox>
|
|
||||||
</div>
|
|
||||||
<div class="gf-form-inline" ng-show="current.includeAll">
|
|
||||||
<div class="gf-form">
|
|
||||||
<span class="gf-form-label width-7">All format</span>
|
|
||||||
<div class="gf-form-select-wrapper">
|
|
||||||
<select class="gf-form-input" ng-model="current.allFormat" ng-change="runQuery()" ng-options="f for f in ['glob', 'wildcard', 'regex wildcard', 'regex values', 'lucene', 'pipe']"></select>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="gf-form max-width-30">
|
|
||||||
<span class="gf-form-label width-7">All value</span>
|
|
||||||
<input type="text" class="gf-form-input" ng-model='current.options[0].value'></input>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="gf-form">
|
<div class="gf-form">
|
||||||
<span class="gf-form-label width-7">Update</span>
|
<span class="gf-form-label width-7">Update</span>
|
||||||
<editor-checkbox text="On Dashboard Load" model="current.refresh"></editor-checkbox>
|
<editor-checkbox text="On Dashboard Load" model="current.refresh"></editor-checkbox>
|
||||||
@ -180,13 +160,19 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="gf-form-group" >
|
<div class="gf-form-group" >
|
||||||
<h5 class="section-heading">Multi-value selection <tip>Enables multiple values to be selected at the same time</tip></h5>
|
<h5 class="section-heading">Selection Options</h5>
|
||||||
<div class="gf-form">
|
<div class="gf-form">
|
||||||
|
<span class="gf-form-label width-10">Multi-value</span>
|
||||||
<editor-checkbox text="Enable" model="current.multi" change="runQuery()"></editor-checkbox>
|
<editor-checkbox text="Enable" model="current.multi" change="runQuery()"></editor-checkbox>
|
||||||
<span class="gf-form-label" ng-show="current.multi">Multi format</span>
|
<tip>Enables multiple values to be selected at the same time</tip>
|
||||||
<div class="gf-form-select-wrapper max-width-10" ng-show="current.multi">
|
</div>
|
||||||
<select class="gf-form-input" ng-model="current.multiFormat" ng-change="runQuery()" ng-options="f for f in ['glob', 'regex values', 'lucene', 'pipe']"></select>
|
<div class="gf-form">
|
||||||
</div>
|
<span class="gf-form-label width-10">Include All option</span>
|
||||||
|
<editor-checkbox class="width-13" text="Enable" model="current.includeAll" change="runQuery()"></editor-checkbox>
|
||||||
|
</div>
|
||||||
|
<div class="gf-form" ng-if="current.includeAll">
|
||||||
|
<span class="gf-form-label width-10">Custom all value</span>
|
||||||
|
<input type="text" class="gf-form-input max-width-15" g-model='current.allValue' placeholder="blank = auto"></input>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@ -13,7 +13,7 @@ function (angular, _) {
|
|||||||
var self = this;
|
var self = this;
|
||||||
|
|
||||||
this._regex = /\$(\w+)|\[\[([\s\S]+?)\]\]/g;
|
this._regex = /\$(\w+)|\[\[([\s\S]+?)\]\]/g;
|
||||||
this._values = {};
|
this._index = {};
|
||||||
this._texts = {};
|
this._texts = {};
|
||||||
this._grafanaVariables = {};
|
this._grafanaVariables = {};
|
||||||
|
|
||||||
@ -23,38 +23,52 @@ function (angular, _) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
this.updateTemplateData = function() {
|
this.updateTemplateData = function() {
|
||||||
this._values = {};
|
this._index = {};
|
||||||
this._texts = {};
|
|
||||||
|
|
||||||
_.each(this.variables, function(variable) {
|
for (var i = 0; i < this.variables.length; i++) {
|
||||||
if (!variable.current || !variable.current.isNone && !variable.current.value) { return; }
|
var variable = this.variables[i];
|
||||||
|
if (!variable.current || !variable.current.isNone && !variable.current.value) {
|
||||||
this._values[variable.name] = this.renderVariableValue(variable);
|
continue;
|
||||||
this._texts[variable.name] = variable.current.text;
|
}
|
||||||
}, this);
|
this._index[variable.name] = variable;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
this.renderVariableValue = function(variable) {
|
function regexEscape(value) {
|
||||||
var value = variable.current.value;
|
return value.replace(/[-[\]{}()*+!<=:?.\/\\^$|#\s,]/g, '\\$&');
|
||||||
if (_.isString(value)) {
|
}
|
||||||
return value;
|
|
||||||
} else {
|
function luceneEscape(value) {
|
||||||
switch(variable.multiFormat) {
|
return value.replace(/([\!\*\+\-\=<>\s\&\|\(\)\[\]\{\}\^\~\?\:\\/"])/g, "\\$1");
|
||||||
case "regex values": {
|
}
|
||||||
return '(' + value.join('|') + ')';
|
|
||||||
|
this.formatValue = function(value, format) {
|
||||||
|
switch(format) {
|
||||||
|
case "regex": {
|
||||||
|
if (typeof value === 'string') {
|
||||||
|
return regexEscape(value);
|
||||||
}
|
}
|
||||||
case "lucene": {
|
|
||||||
var quotedValues = _.map(value, function(val) {
|
var escapedValues = _.map(value, regexEscape);
|
||||||
return '\\\"' + val + '\\\"';
|
return escapedValues.join('|');
|
||||||
});
|
}
|
||||||
return '(' + quotedValues.join(' OR ') + ')';
|
case "lucene": {
|
||||||
|
if (typeof value === 'string') {
|
||||||
|
return luceneEscape(value);
|
||||||
}
|
}
|
||||||
case "pipe": {
|
var quotedValues = _.map(value, function(val) {
|
||||||
return value.join('|');
|
return '\"' + luceneEscape(val) + '\"';
|
||||||
}
|
});
|
||||||
default: {
|
return '(' + quotedValues.join(' OR ') + ')';
|
||||||
return '{' + value.join(',') + '}';
|
}
|
||||||
|
case "pipe": {
|
||||||
|
return value.join('|');
|
||||||
|
}
|
||||||
|
default: {
|
||||||
|
if (typeof value === 'string') {
|
||||||
|
return value;
|
||||||
}
|
}
|
||||||
|
return '{' + value.join(',') + '}';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -66,7 +80,7 @@ function (angular, _) {
|
|||||||
this.variableExists = function(expression) {
|
this.variableExists = function(expression) {
|
||||||
this._regex.lastIndex = 0;
|
this._regex.lastIndex = 0;
|
||||||
var match = this._regex.exec(expression);
|
var match = this._regex.exec(expression);
|
||||||
return match && (self._values[match[1] || match[2]] !== void 0);
|
return match && (self._index[match[1] || match[2]] !== void 0);
|
||||||
};
|
};
|
||||||
|
|
||||||
this.containsVariable = function(str, variableName) {
|
this.containsVariable = function(str, variableName) {
|
||||||
@ -82,37 +96,66 @@ function (angular, _) {
|
|||||||
str = _.escape(str);
|
str = _.escape(str);
|
||||||
this._regex.lastIndex = 0;
|
this._regex.lastIndex = 0;
|
||||||
return str.replace(this._regex, function(match, g1, g2) {
|
return str.replace(this._regex, function(match, g1, g2) {
|
||||||
if (self._values[g1 || g2]) {
|
if (self._index[g1 || g2]) {
|
||||||
return '<span class="template-variable">' + match + '</span>';
|
return '<span class="template-variable">' + match + '</span>';
|
||||||
}
|
}
|
||||||
return match;
|
return match;
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
this.replace = function(target, scopedVars) {
|
this.getAllValue = function(variable) {
|
||||||
|
if (variable.allValue) {
|
||||||
|
return variable.allValue;
|
||||||
|
}
|
||||||
|
var values = [];
|
||||||
|
for (var i = 1; i < variable.options.length; i++) {
|
||||||
|
values.push(variable.options[i].value);
|
||||||
|
}
|
||||||
|
return values;
|
||||||
|
};
|
||||||
|
|
||||||
|
this.replace = function(target, scopedVars, format) {
|
||||||
if (!target) { return target; }
|
if (!target) { return target; }
|
||||||
|
|
||||||
var value;
|
var variable, systemValue, value;
|
||||||
this._regex.lastIndex = 0;
|
this._regex.lastIndex = 0;
|
||||||
|
|
||||||
return target.replace(this._regex, function(match, g1, g2) {
|
return target.replace(this._regex, function(match, g1, g2) {
|
||||||
if (scopedVars) {
|
if (scopedVars) {
|
||||||
value = scopedVars[g1 || g2];
|
value = scopedVars[g1 || g2];
|
||||||
if (value) { return value.value; }
|
if (value) {
|
||||||
|
return self.formatValue(value.value);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
value = self._values[g1 || g2];
|
variable = self._index[g1 || g2];
|
||||||
if (!value) { return match; }
|
if (!variable) {
|
||||||
|
return match;
|
||||||
|
}
|
||||||
|
|
||||||
return self._grafanaVariables[value] || value;
|
systemValue = self._grafanaVariables[variable.current.value];
|
||||||
|
if (systemValue) {
|
||||||
|
return self.formatValue(systemValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
value = variable.current.value;
|
||||||
|
if (self.isAllValue(value)) {
|
||||||
|
value = self.getAllValue(variable);
|
||||||
|
}
|
||||||
|
|
||||||
|
var res = self.formatValue(value, format);
|
||||||
|
return res;
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
this.isAllValue = function(value) {
|
||||||
|
return value === '$__all' || Array.isArray(value) && value[0] === '$__all';
|
||||||
|
};
|
||||||
|
|
||||||
this.replaceWithText = function(target, scopedVars) {
|
this.replaceWithText = function(target, scopedVars) {
|
||||||
if (!target) { return target; }
|
if (!target) { return target; }
|
||||||
|
|
||||||
var value;
|
var variable;
|
||||||
var text;
|
|
||||||
this._regex.lastIndex = 0;
|
this._regex.lastIndex = 0;
|
||||||
|
|
||||||
return target.replace(this._regex, function(match, g1, g2) {
|
return target.replace(this._regex, function(match, g1, g2) {
|
||||||
@ -121,11 +164,10 @@ function (angular, _) {
|
|||||||
if (option) { return option.text; }
|
if (option) { return option.text; }
|
||||||
}
|
}
|
||||||
|
|
||||||
value = self._values[g1 || g2];
|
variable = self._index[g1 || g2];
|
||||||
text = self._texts[g1 || g2];
|
if (!variable) { return match; }
|
||||||
if (!value) { return match; }
|
|
||||||
|
|
||||||
return self._grafanaVariables[value] || text;
|
return self._grafanaVariables[variable.current.value] || variable.current.text;
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -108,7 +108,6 @@ function (angular, _, kbn) {
|
|||||||
if (variable.type === 'custom' && variable.includeAll) {
|
if (variable.type === 'custom' && variable.includeAll) {
|
||||||
self.addAllOption(variable);
|
self.addAllOption(variable);
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
this.updateOptions = function(variable) {
|
this.updateOptions = function(variable) {
|
||||||
@ -226,60 +225,17 @@ function (angular, _, kbn) {
|
|||||||
|
|
||||||
return _.map(_.keys(options).sort(), function(key) {
|
return _.map(_.keys(options).sort(), function(key) {
|
||||||
var option = { text: key, value: key };
|
var option = { text: key, value: key };
|
||||||
|
|
||||||
// check if values need to be regex escaped
|
|
||||||
if (self.shouldRegexEscape(variable)) {
|
|
||||||
option.value = self.regexEscape(option.value);
|
|
||||||
}
|
|
||||||
|
|
||||||
return option;
|
return option;
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
this.shouldRegexEscape = function(variable) {
|
|
||||||
return (variable.includeAll || variable.multi) && variable.allFormat.indexOf('regex') !== -1;
|
|
||||||
};
|
|
||||||
|
|
||||||
this.regexEscape = function(value) {
|
|
||||||
return value.replace(/[-[\]{}()*+!<=:?.\/\\^$|#\s,]/g, '\\$&');
|
|
||||||
};
|
|
||||||
|
|
||||||
this.addAllOption = function(variable) {
|
this.addAllOption = function(variable) {
|
||||||
var allValue = '';
|
if (variable.allValue) {
|
||||||
switch(variable.allFormat) {
|
variable.options.unshift({text: 'All', value: variable.allValue});
|
||||||
case 'wildcard': {
|
return;
|
||||||
allValue = '*';
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case 'regex wildcard': {
|
|
||||||
allValue = '.*';
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case 'lucene': {
|
|
||||||
var quotedValues = _.map(variable.options, function(val) {
|
|
||||||
return '\\\"' + val.text + '\\\"';
|
|
||||||
});
|
|
||||||
allValue = '(' + quotedValues.join(' OR ') + ')';
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case 'regex values': {
|
|
||||||
allValue = '(' + _.map(variable.options, function(option) {
|
|
||||||
return self.regexEscape(option.text);
|
|
||||||
}).join('|') + ')';
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case 'pipe': {
|
|
||||||
allValue = _.pluck(variable.options, 'text').join('|');
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
default: {
|
|
||||||
allValue = '{';
|
|
||||||
allValue += _.pluck(variable.options, 'text').join(',');
|
|
||||||
allValue += '}';
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
variable.options.unshift({text: 'All', value: allValue});
|
variable.options.unshift({text: 'All', value: "$__all"});
|
||||||
};
|
};
|
||||||
|
|
||||||
});
|
});
|
||||||
|
@ -47,15 +47,15 @@ function (angular, _, moment, kbn, ElasticQueryBuilder, IndexPattern, ElasticRes
|
|||||||
};
|
};
|
||||||
|
|
||||||
this._get = function(url) {
|
this._get = function(url) {
|
||||||
return this._request('GET', this.indexPattern.getIndexForToday() + url)
|
return this._request('GET', this.indexPattern.getIndexForToday() + url).then(function(results) {
|
||||||
.then(function(results) {
|
results.data.$$config = results.config;
|
||||||
return results.data;
|
return results.data;
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
this._post = function(url, data) {
|
this._post = function(url, data) {
|
||||||
return this._request('POST', url, data)
|
return this._request('POST', url, data).then(function(results) {
|
||||||
.then(function(results) {
|
results.data.$$config = results.config;
|
||||||
return results.data;
|
return results.data;
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
@ -170,7 +170,10 @@ function (angular, _, moment, kbn, ElasticQueryBuilder, IndexPattern, ElasticRes
|
|||||||
|
|
||||||
var queryObj = this.queryBuilder.build(target);
|
var queryObj = this.queryBuilder.build(target);
|
||||||
var esQuery = angular.toJson(queryObj);
|
var esQuery = angular.toJson(queryObj);
|
||||||
var luceneQuery = angular.toJson(target.query || '*');
|
var luceneQuery = target.query || '*';
|
||||||
|
luceneQuery = templateSrv.replace(luceneQuery, options.scopedVars, 'lucene');
|
||||||
|
luceneQuery = angular.toJson(luceneQuery);
|
||||||
|
|
||||||
// remove inner quotes
|
// remove inner quotes
|
||||||
luceneQuery = luceneQuery.substr(1, luceneQuery.length - 2);
|
luceneQuery = luceneQuery.substr(1, luceneQuery.length - 2);
|
||||||
esQuery = esQuery.replace("$lucene_query", luceneQuery);
|
esQuery = esQuery.replace("$lucene_query", luceneQuery);
|
||||||
|
@ -284,13 +284,29 @@ function (_, queryDef) {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
ElasticResponse.prototype.getErrorFromElasticResponse = function(response, err) {
|
||||||
|
var result = {};
|
||||||
|
result.data = JSON.stringify(err, null, 4);
|
||||||
|
if (err.root_cause && err.root_cause.length > 0 && err.root_cause[0].reason) {
|
||||||
|
result.message = err.root_cause[0].reason;
|
||||||
|
} else {
|
||||||
|
result.message = err.reason || 'Unkown elatic error response';
|
||||||
|
}
|
||||||
|
|
||||||
|
if (response.$$config) {
|
||||||
|
result.config = response.$$config;
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
};
|
||||||
|
|
||||||
ElasticResponse.prototype.getTimeSeries = function() {
|
ElasticResponse.prototype.getTimeSeries = function() {
|
||||||
var seriesList = [];
|
var seriesList = [];
|
||||||
|
|
||||||
for (var i = 0; i < this.response.responses.length; i++) {
|
for (var i = 0; i < this.response.responses.length; i++) {
|
||||||
var response = this.response.responses[i];
|
var response = this.response.responses[i];
|
||||||
if (response.error) {
|
if (response.error) {
|
||||||
throw { message: response.error };
|
throw this.getErrorFromElasticResponse(this.response, response.error);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (response.hits && response.hits.hits.length > 0) {
|
if (response.hits && response.hits.hits.length > 0) {
|
||||||
|
@ -33,7 +33,7 @@ describe('ElasticDatasource', function() {
|
|||||||
var requestOptions;
|
var requestOptions;
|
||||||
ctx.backendSrv.datasourceRequest = function(options) {
|
ctx.backendSrv.datasourceRequest = function(options) {
|
||||||
requestOptions = options;
|
requestOptions = options;
|
||||||
return ctx.$q.when({});
|
return ctx.$q.when({data: {}});
|
||||||
};
|
};
|
||||||
|
|
||||||
ctx.ds.testDatasource();
|
ctx.ds.testDatasource();
|
||||||
|
@ -34,8 +34,8 @@ export function InfluxDatasource(instanceSettings, $q, backendSrv, templateSrv)
|
|||||||
queryTargets.push(target);
|
queryTargets.push(target);
|
||||||
|
|
||||||
// build query
|
// build query
|
||||||
var queryModel = new InfluxQuery(target);
|
var queryModel = new InfluxQuery(target, templateSrv, options.scopedVars);
|
||||||
var query = queryModel.render();
|
var query = queryModel.render(true);
|
||||||
query = query.replace(/\$interval/g, (target.interval || options.interval));
|
query = query.replace(/\$interval/g, (target.interval || options.interval));
|
||||||
return query;
|
return query;
|
||||||
|
|
||||||
|
@ -8,9 +8,13 @@ export default class InfluxQuery {
|
|||||||
selectModels: any[];
|
selectModels: any[];
|
||||||
queryBuilder: any;
|
queryBuilder: any;
|
||||||
groupByParts: any;
|
groupByParts: any;
|
||||||
|
templateSrv: any;
|
||||||
|
scopedVars: any;
|
||||||
|
|
||||||
constructor(target) {
|
constructor(target, templateSrv?, scopedVars?) {
|
||||||
this.target = target;
|
this.target = target;
|
||||||
|
this.templateSrv = templateSrv;
|
||||||
|
this.scopedVars = scopedVars;
|
||||||
|
|
||||||
target.policy = target.policy || 'default';
|
target.policy = target.policy || 'default';
|
||||||
target.dsType = 'influxdb';
|
target.dsType = 'influxdb';
|
||||||
@ -126,7 +130,7 @@ export default class InfluxQuery {
|
|||||||
this.updatePersistedParts();
|
this.updatePersistedParts();
|
||||||
}
|
}
|
||||||
|
|
||||||
private renderTagCondition(tag, index) {
|
private renderTagCondition(tag, index, interpolate) {
|
||||||
var str = "";
|
var str = "";
|
||||||
var operator = tag.operator;
|
var operator = tag.operator;
|
||||||
var value = tag.value;
|
var value = tag.value;
|
||||||
@ -135,7 +139,7 @@ export default class InfluxQuery {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!operator) {
|
if (!operator) {
|
||||||
if (/^\/.*\/$/.test(tag.value)) {
|
if (/^\/.*\/$/.test(value)) {
|
||||||
operator = '=~';
|
operator = '=~';
|
||||||
} else {
|
} else {
|
||||||
operator = '=';
|
operator = '=';
|
||||||
@ -144,7 +148,12 @@ export default class InfluxQuery {
|
|||||||
|
|
||||||
// quote value unless regex
|
// quote value unless regex
|
||||||
if (operator !== '=~' && operator !== '!~') {
|
if (operator !== '=~' && operator !== '!~') {
|
||||||
|
if (interpolate) {
|
||||||
|
value = this.templateSrv.replace(value, this.scopedVars);
|
||||||
|
}
|
||||||
value = "'" + value.replace('\\', '\\\\') + "'";
|
value = "'" + value.replace('\\', '\\\\') + "'";
|
||||||
|
} else if (interpolate){
|
||||||
|
value = this.templateSrv.replace(value, this.scopedVars, 'regex');
|
||||||
}
|
}
|
||||||
|
|
||||||
return str + '"' + tag.key + '" ' + operator + ' ' + value;
|
return str + '"' + tag.key + '" ' + operator + ' ' + value;
|
||||||
@ -167,11 +176,15 @@ export default class InfluxQuery {
|
|||||||
return policy + measurement;
|
return policy + measurement;
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render(interpolate?) {
|
||||||
var target = this.target;
|
var target = this.target;
|
||||||
|
|
||||||
if (target.rawQuery) {
|
if (target.rawQuery) {
|
||||||
return target.query;
|
if (interpolate) {
|
||||||
|
return this.templateSrv.replace(target.query, this.scopedVars, 'regex');
|
||||||
|
} else {
|
||||||
|
return target.query;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!target.measurement) {
|
if (!target.measurement) {
|
||||||
@ -196,7 +209,7 @@ export default class InfluxQuery {
|
|||||||
|
|
||||||
query += ' FROM ' + this.getMeasurementAndPolicy() + ' WHERE ';
|
query += ' FROM ' + this.getMeasurementAndPolicy() + ' WHERE ';
|
||||||
var conditions = _.map(target.tags, (tag, index) => {
|
var conditions = _.map(target.tags, (tag, index) => {
|
||||||
return this.renderTagCondition(tag, index);
|
return this.renderTagCondition(tag, index, interpolate);
|
||||||
});
|
});
|
||||||
|
|
||||||
query += conditions.join(' ');
|
query += conditions.join(' ');
|
||||||
@ -220,8 +233,6 @@ export default class InfluxQuery {
|
|||||||
query += ' fill(' + target.fill + ')';
|
query += ' fill(' + target.fill + ')';
|
||||||
}
|
}
|
||||||
|
|
||||||
target.query = query;
|
|
||||||
|
|
||||||
return query;
|
return query;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -28,7 +28,7 @@ export class InfluxQueryCtrl extends QueryCtrl {
|
|||||||
super($scope, $injector);
|
super($scope, $injector);
|
||||||
|
|
||||||
this.target = this.target;
|
this.target = this.target;
|
||||||
this.queryModel = new InfluxQuery(this.target);
|
this.queryModel = new InfluxQuery(this.target, templateSrv, this.panel.scopedVars);
|
||||||
this.queryBuilder = new InfluxQueryBuilder(this.target, this.datasource.database);
|
this.queryBuilder = new InfluxQueryBuilder(this.target, this.datasource.database);
|
||||||
this.groupBySegment = this.uiSegmentSrv.newPlusButton();
|
this.groupBySegment = this.uiSegmentSrv.newPlusButton();
|
||||||
this.resultFormats = [
|
this.resultFormats = [
|
||||||
@ -154,6 +154,7 @@ export class InfluxQueryCtrl extends QueryCtrl {
|
|||||||
}
|
}
|
||||||
|
|
||||||
toggleEditorMode() {
|
toggleEditorMode() {
|
||||||
|
this.target.query = this.queryModel.render(false);
|
||||||
this.target.rawQuery = !this.target.rawQuery;
|
this.target.rawQuery = !this.target.rawQuery;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3,12 +3,13 @@ import {describe, beforeEach, it, sinon, expect} from 'test/lib/common';
|
|||||||
import InfluxQuery from '../influx_query';
|
import InfluxQuery from '../influx_query';
|
||||||
|
|
||||||
describe('InfluxQuery', function() {
|
describe('InfluxQuery', function() {
|
||||||
|
var templateSrv = {replace: val => val};
|
||||||
|
|
||||||
describe('render series with mesurement only', function() {
|
describe('render series with mesurement only', function() {
|
||||||
it('should generate correct query', function() {
|
it('should generate correct query', function() {
|
||||||
var query = new InfluxQuery({
|
var query = new InfluxQuery({
|
||||||
measurement: 'cpu',
|
measurement: 'cpu',
|
||||||
});
|
}, templateSrv, {});
|
||||||
|
|
||||||
var queryText = query.render();
|
var queryText = query.render();
|
||||||
expect(queryText).to.be('SELECT mean("value") FROM "cpu" WHERE $timeFilter GROUP BY time($interval) fill(null)');
|
expect(queryText).to.be('SELECT mean("value") FROM "cpu" WHERE $timeFilter GROUP BY time($interval) fill(null)');
|
||||||
@ -20,7 +21,7 @@ describe('InfluxQuery', function() {
|
|||||||
var query = new InfluxQuery({
|
var query = new InfluxQuery({
|
||||||
measurement: 'cpu',
|
measurement: 'cpu',
|
||||||
policy: '5m_avg'
|
policy: '5m_avg'
|
||||||
});
|
}, templateSrv, {});
|
||||||
|
|
||||||
var queryText = query.render();
|
var queryText = query.render();
|
||||||
expect(queryText).to.be('SELECT mean("value") FROM "5m_avg"."cpu" WHERE $timeFilter GROUP BY time($interval) fill(null)');
|
expect(queryText).to.be('SELECT mean("value") FROM "5m_avg"."cpu" WHERE $timeFilter GROUP BY time($interval) fill(null)');
|
||||||
@ -39,7 +40,7 @@ describe('InfluxQuery', function() {
|
|||||||
{type: 'alias', params: ['text']},
|
{type: 'alias', params: ['text']},
|
||||||
]
|
]
|
||||||
]
|
]
|
||||||
});
|
}, templateSrv, {});
|
||||||
|
|
||||||
var queryText = query.render();
|
var queryText = query.render();
|
||||||
expect(queryText).to.be('SELECT mean("value") /100 AS "text" FROM "cpu" WHERE $timeFilter GROUP BY time($interval) fill(null)');
|
expect(queryText).to.be('SELECT mean("value") /100 AS "text" FROM "cpu" WHERE $timeFilter GROUP BY time($interval) fill(null)');
|
||||||
@ -52,7 +53,7 @@ describe('InfluxQuery', function() {
|
|||||||
measurement: 'cpu',
|
measurement: 'cpu',
|
||||||
groupBy: [{type: 'time', params: ['auto']}],
|
groupBy: [{type: 'time', params: ['auto']}],
|
||||||
tags: [{key: 'hostname', value: 'server\\1'}]
|
tags: [{key: 'hostname', value: 'server\\1'}]
|
||||||
});
|
}, templateSrv, {});
|
||||||
|
|
||||||
var queryText = query.render();
|
var queryText = query.render();
|
||||||
|
|
||||||
@ -65,7 +66,7 @@ describe('InfluxQuery', function() {
|
|||||||
measurement: 'cpu',
|
measurement: 'cpu',
|
||||||
groupBy: [{type: 'time', params: ['auto']}],
|
groupBy: [{type: 'time', params: ['auto']}],
|
||||||
tags: [{key: 'app', value: '/e.*/'}]
|
tags: [{key: 'app', value: '/e.*/'}]
|
||||||
});
|
}, templateSrv, {});
|
||||||
|
|
||||||
var queryText = query.render();
|
var queryText = query.render();
|
||||||
expect(queryText).to.be('SELECT mean("value") FROM "cpu" WHERE "app" =~ /e.*/ AND $timeFilter GROUP BY time($interval)');
|
expect(queryText).to.be('SELECT mean("value") FROM "cpu" WHERE "app" =~ /e.*/ AND $timeFilter GROUP BY time($interval)');
|
||||||
@ -78,7 +79,7 @@ describe('InfluxQuery', function() {
|
|||||||
measurement: 'cpu',
|
measurement: 'cpu',
|
||||||
groupBy: [{type: 'time', params: ['auto']}],
|
groupBy: [{type: 'time', params: ['auto']}],
|
||||||
tags: [{key: 'hostname', value: 'server1'}, {key: 'app', value: 'email', condition: "AND"}]
|
tags: [{key: 'hostname', value: 'server1'}, {key: 'app', value: 'email', condition: "AND"}]
|
||||||
});
|
}, templateSrv, {});
|
||||||
|
|
||||||
var queryText = query.render();
|
var queryText = query.render();
|
||||||
expect(queryText).to.be('SELECT mean("value") FROM "cpu" WHERE "hostname" = \'server1\' AND "app" = \'email\' AND ' +
|
expect(queryText).to.be('SELECT mean("value") FROM "cpu" WHERE "hostname" = \'server1\' AND "app" = \'email\' AND ' +
|
||||||
@ -92,7 +93,7 @@ describe('InfluxQuery', function() {
|
|||||||
measurement: 'cpu',
|
measurement: 'cpu',
|
||||||
groupBy: [{type: 'time', params: ['auto']}],
|
groupBy: [{type: 'time', params: ['auto']}],
|
||||||
tags: [{key: 'hostname', value: 'server1'}, {key: 'hostname', value: 'server2', condition: "OR"}]
|
tags: [{key: 'hostname', value: 'server1'}, {key: 'hostname', value: 'server2', condition: "OR"}]
|
||||||
});
|
}, templateSrv, {});
|
||||||
|
|
||||||
var queryText = query.render();
|
var queryText = query.render();
|
||||||
expect(queryText).to.be('SELECT mean("value") FROM "cpu" WHERE "hostname" = \'server1\' OR "hostname" = \'server2\' AND ' +
|
expect(queryText).to.be('SELECT mean("value") FROM "cpu" WHERE "hostname" = \'server1\' OR "hostname" = \'server2\' AND ' +
|
||||||
@ -106,7 +107,7 @@ describe('InfluxQuery', function() {
|
|||||||
measurement: 'cpu',
|
measurement: 'cpu',
|
||||||
tags: [],
|
tags: [],
|
||||||
groupBy: [{type: 'time', interval: 'auto'}, {type: 'tag', params: ['host']}],
|
groupBy: [{type: 'time', interval: 'auto'}, {type: 'tag', params: ['host']}],
|
||||||
});
|
}, templateSrv, {});
|
||||||
|
|
||||||
var queryText = query.render();
|
var queryText = query.render();
|
||||||
expect(queryText).to.be('SELECT mean("value") FROM "cpu" WHERE $timeFilter ' +
|
expect(queryText).to.be('SELECT mean("value") FROM "cpu" WHERE $timeFilter ' +
|
||||||
@ -120,7 +121,7 @@ describe('InfluxQuery', function() {
|
|||||||
measurement: 'cpu',
|
measurement: 'cpu',
|
||||||
select: [[{type: 'field', params: ['value']}]],
|
select: [[{type: 'field', params: ['value']}]],
|
||||||
groupBy: [],
|
groupBy: [],
|
||||||
});
|
}, templateSrv, {});
|
||||||
var queryText = query.render();
|
var queryText = query.render();
|
||||||
expect(queryText).to.be('SELECT "value" FROM "cpu" WHERE $timeFilter');
|
expect(queryText).to.be('SELECT "value" FROM "cpu" WHERE $timeFilter');
|
||||||
});
|
});
|
||||||
@ -132,7 +133,7 @@ describe('InfluxQuery', function() {
|
|||||||
measurement: 'cpu',
|
measurement: 'cpu',
|
||||||
select: [[{type: 'field', params: ['value']}]],
|
select: [[{type: 'field', params: ['value']}]],
|
||||||
groupBy: [{type: 'time'}, {type: 'fill', params: ['0']}],
|
groupBy: [{type: 'time'}, {type: 'fill', params: ['0']}],
|
||||||
});
|
}, templateSrv, {});
|
||||||
var queryText = query.render();
|
var queryText = query.render();
|
||||||
expect(queryText).to.be('SELECT "value" FROM "cpu" WHERE $timeFilter GROUP BY time($interval) fill(0)');
|
expect(queryText).to.be('SELECT "value" FROM "cpu" WHERE $timeFilter GROUP BY time($interval) fill(0)');
|
||||||
});
|
});
|
||||||
@ -144,7 +145,7 @@ describe('InfluxQuery', function() {
|
|||||||
var query = new InfluxQuery({
|
var query = new InfluxQuery({
|
||||||
measurement: 'cpu',
|
measurement: 'cpu',
|
||||||
groupBy: [{type: 'time'}, {type: 'fill'}]
|
groupBy: [{type: 'time'}, {type: 'fill'}]
|
||||||
});
|
}, templateSrv, {});
|
||||||
|
|
||||||
query.addGroupBy('tag(host)');
|
query.addGroupBy('tag(host)');
|
||||||
expect(query.target.groupBy.length).to.be(3);
|
expect(query.target.groupBy.length).to.be(3);
|
||||||
@ -157,7 +158,7 @@ describe('InfluxQuery', function() {
|
|||||||
var query = new InfluxQuery({
|
var query = new InfluxQuery({
|
||||||
measurement: 'cpu',
|
measurement: 'cpu',
|
||||||
groupBy: []
|
groupBy: []
|
||||||
});
|
}, templateSrv, {});
|
||||||
|
|
||||||
query.addGroupBy('tag(host)');
|
query.addGroupBy('tag(host)');
|
||||||
expect(query.target.groupBy.length).to.be(1);
|
expect(query.target.groupBy.length).to.be(1);
|
||||||
@ -172,7 +173,7 @@ describe('InfluxQuery', function() {
|
|||||||
var query = new InfluxQuery({
|
var query = new InfluxQuery({
|
||||||
measurement: 'cpu',
|
measurement: 'cpu',
|
||||||
select: [[{type: 'field', params: ['value']}]]
|
select: [[{type: 'field', params: ['value']}]]
|
||||||
});
|
}, templateSrv, {});
|
||||||
|
|
||||||
query.addSelectPart(query.selectModels[0], 'mean');
|
query.addSelectPart(query.selectModels[0], 'mean');
|
||||||
expect(query.target.select[0].length).to.be(2);
|
expect(query.target.select[0].length).to.be(2);
|
||||||
@ -183,7 +184,7 @@ describe('InfluxQuery', function() {
|
|||||||
var query = new InfluxQuery({
|
var query = new InfluxQuery({
|
||||||
measurement: 'cpu',
|
measurement: 'cpu',
|
||||||
select: [[{type: 'field', params: ['value']}, {type: 'mean'}]]
|
select: [[{type: 'field', params: ['value']}, {type: 'mean'}]]
|
||||||
});
|
}, templateSrv, {});
|
||||||
|
|
||||||
query.addSelectPart(query.selectModels[0], 'sum');
|
query.addSelectPart(query.selectModels[0], 'sum');
|
||||||
expect(query.target.select[0].length).to.be(2);
|
expect(query.target.select[0].length).to.be(2);
|
||||||
@ -194,7 +195,7 @@ describe('InfluxQuery', function() {
|
|||||||
var query = new InfluxQuery({
|
var query = new InfluxQuery({
|
||||||
measurement: 'cpu',
|
measurement: 'cpu',
|
||||||
select: [[{type: 'field', params: ['value']}, {type: 'mean'}, {type: 'alias'}]]
|
select: [[{type: 'field', params: ['value']}, {type: 'mean'}, {type: 'alias'}]]
|
||||||
});
|
}, templateSrv, {});
|
||||||
|
|
||||||
query.addSelectPart(query.selectModels[0], 'math');
|
query.addSelectPart(query.selectModels[0], 'math');
|
||||||
expect(query.target.select[0].length).to.be(4);
|
expect(query.target.select[0].length).to.be(4);
|
||||||
@ -205,7 +206,7 @@ describe('InfluxQuery', function() {
|
|||||||
var query = new InfluxQuery({
|
var query = new InfluxQuery({
|
||||||
measurement: 'cpu',
|
measurement: 'cpu',
|
||||||
select: [[{type: 'field', params: ['value']}, {type: 'mean'}]]
|
select: [[{type: 'field', params: ['value']}, {type: 'mean'}]]
|
||||||
});
|
}, templateSrv, {});
|
||||||
|
|
||||||
query.addSelectPart(query.selectModels[0], 'math');
|
query.addSelectPart(query.selectModels[0], 'math');
|
||||||
expect(query.target.select[0].length).to.be(3);
|
expect(query.target.select[0].length).to.be(3);
|
||||||
@ -216,7 +217,7 @@ describe('InfluxQuery', function() {
|
|||||||
var query = new InfluxQuery({
|
var query = new InfluxQuery({
|
||||||
measurement: 'cpu',
|
measurement: 'cpu',
|
||||||
select: [[{type: 'field', params: ['value']}, {type: 'mean'}, {type: 'math'}]]
|
select: [[{type: 'field', params: ['value']}, {type: 'mean'}, {type: 'math'}]]
|
||||||
});
|
}, templateSrv, {});
|
||||||
|
|
||||||
query.addSelectPart(query.selectModels[0], 'math');
|
query.addSelectPart(query.selectModels[0], 'math');
|
||||||
expect(query.target.select[0].length).to.be(3);
|
expect(query.target.select[0].length).to.be(3);
|
||||||
|
@ -335,7 +335,7 @@ function (angular, _, dateMath) {
|
|||||||
query.tags = angular.copy(target.tags);
|
query.tags = angular.copy(target.tags);
|
||||||
if(query.tags){
|
if(query.tags){
|
||||||
for(var key in query.tags){
|
for(var key in query.tags){
|
||||||
query.tags[key] = templateSrv.replace(query.tags[key], options.scopedVars);
|
query.tags[key] = templateSrv.replace(query.tags[key], options.scopedVars, 'pipe');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -355,7 +355,7 @@ function (angular, _, dateMath) {
|
|||||||
} else {
|
} else {
|
||||||
return target.metric === metricData.metric &&
|
return target.metric === metricData.metric &&
|
||||||
_.all(target.tags, function(tagV, tagK) {
|
_.all(target.tags, function(tagV, tagK) {
|
||||||
interpolatedTagValue = templateSrv.replace(tagV, options.scopedVars);
|
interpolatedTagValue = templateSrv.replace(tagV, options.scopedVars, 'pipe');
|
||||||
return metricData.tags[tagK] === interpolatedTagValue || interpolatedTagValue === "*";
|
return metricData.tags[tagK] === interpolatedTagValue || interpolatedTagValue === "*";
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -52,7 +52,7 @@ export function PrometheusDatasource(instanceSettings, $q, backendSrv, templateS
|
|||||||
}
|
}
|
||||||
|
|
||||||
var query: any = {};
|
var query: any = {};
|
||||||
query.expr = templateSrv.replace(target.expr, options.scopedVars);
|
query.expr = templateSrv.replace(target.expr, options.scopedVars, 'regex');
|
||||||
|
|
||||||
var interval = target.interval || options.interval;
|
var interval = target.interval || options.interval;
|
||||||
var intervalFactor = target.intervalFactor || 1;
|
var intervalFactor = target.intervalFactor || 1;
|
||||||
|
@ -4,6 +4,5 @@
|
|||||||
"id": "prometheus",
|
"id": "prometheus",
|
||||||
|
|
||||||
"metrics": true,
|
"metrics": true,
|
||||||
"annotations": true,
|
"annotations": true
|
||||||
"defaultMatchFormat": "pipe"
|
|
||||||
}
|
}
|
||||||
|
@ -131,7 +131,6 @@ mark,
|
|||||||
// Unordered and Ordered lists
|
// Unordered and Ordered lists
|
||||||
ul, ol {
|
ul, ol {
|
||||||
padding: 0;
|
padding: 0;
|
||||||
padding-left: $spacer;
|
|
||||||
}
|
}
|
||||||
ul ul,
|
ul ul,
|
||||||
ul ol,
|
ul ol,
|
||||||
|
@ -16,5 +16,8 @@
|
|||||||
h5 {
|
h5 {
|
||||||
margin-top: 5px;
|
margin-top: 5px;
|
||||||
}
|
}
|
||||||
|
ul {
|
||||||
|
padding-left: $spacer;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -13,10 +13,6 @@
|
|||||||
color: $variable;
|
color: $variable;
|
||||||
}
|
}
|
||||||
|
|
||||||
.grafana-row {
|
|
||||||
margin-bottom: 5px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.row-tab {
|
.row-tab {
|
||||||
.dropdown-menu-right {
|
.dropdown-menu-right {
|
||||||
top: 0;
|
top: 0;
|
||||||
@ -121,7 +117,7 @@ div.flot-text {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.panel-margin {
|
.panel-margin {
|
||||||
margin: 0 0.4rem 0.4rem 0.4rem;
|
margin: 0 0.4rem 0.8rem 0.4rem;
|
||||||
display: block;
|
display: block;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
"bitwise":false,
|
"bitwise":false,
|
||||||
"curly": true,
|
"curly": true,
|
||||||
"eqnull": true,
|
"eqnull": true,
|
||||||
"globalstrict": true,
|
"strict": true,
|
||||||
"devel": true,
|
"devel": true,
|
||||||
"eqeqeq": true,
|
"eqeqeq": true,
|
||||||
"forin": false,
|
"forin": false,
|
||||||
@ -11,7 +11,7 @@
|
|||||||
"supernew": true,
|
"supernew": true,
|
||||||
"expr": true,
|
"expr": true,
|
||||||
"indent": 2,
|
"indent": 2,
|
||||||
"latedef": true,
|
"latedef": false,
|
||||||
"newcap": true,
|
"newcap": true,
|
||||||
"noarg": true,
|
"noarg": true,
|
||||||
"noempty": true,
|
"noempty": true,
|
||||||
|
@ -45,49 +45,93 @@ define([
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('render variable to string values', function() {
|
describe('replace can pass multi / all format', function() {
|
||||||
|
beforeEach(function() {
|
||||||
|
_templateSrv.init([{name: 'test', current: {value: ['value1', 'value2'] }}]);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should replace $test with globbed value', function() {
|
||||||
|
var target = _templateSrv.replace('this.$test.filters', {}, 'glob');
|
||||||
|
expect(target).to.be('this.{value1,value2}.filters');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should replace $test with piped value', function() {
|
||||||
|
var target = _templateSrv.replace('this=$test', {}, 'pipe');
|
||||||
|
expect(target).to.be('this=value1|value2');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should replace $test with piped value', function() {
|
||||||
|
var target = _templateSrv.replace('this=$test', {}, 'pipe');
|
||||||
|
expect(target).to.be('this=value1|value2');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('variable with all option', function() {
|
||||||
|
beforeEach(function() {
|
||||||
|
_templateSrv.init([{
|
||||||
|
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).to.be('this.{value1,value2}.filters');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('variable with all option and custom value', function() {
|
||||||
|
beforeEach(function() {
|
||||||
|
_templateSrv.init([{
|
||||||
|
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).to.be('this.*.filters');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('lucene format', function() {
|
||||||
|
it('should properly escape $test with lucene escape sequences', function() {
|
||||||
|
_templateSrv.init([{name: 'test', current: {value: 'value/4' }}]);
|
||||||
|
var target = _templateSrv.replace('this:$test', {}, 'lucene');
|
||||||
|
expect(target).to.be("this:value\\\/4");
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('format variable to string values', function() {
|
||||||
it('single value should return value', function() {
|
it('single value should return value', function() {
|
||||||
var result = _templateSrv.renderVariableValue({current: {value: 'test'}});
|
var result = _templateSrv.formatValue('test');
|
||||||
expect(result).to.be('test');
|
expect(result).to.be('test');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('multi value and glob format should render glob string', function() {
|
it('multi value and glob format should render glob string', function() {
|
||||||
var result = _templateSrv.renderVariableValue({
|
var result = _templateSrv.formatValue(['test','test2'], 'glob');
|
||||||
multiFormat: 'glob',
|
|
||||||
current: {
|
|
||||||
value: ['test','test2'],
|
|
||||||
}
|
|
||||||
});
|
|
||||||
expect(result).to.be('{test,test2}');
|
expect(result).to.be('{test,test2}');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('multi value and lucene should render as lucene expr', function() {
|
it('multi value and lucene should render as lucene expr', function() {
|
||||||
var result = _templateSrv.renderVariableValue({
|
var result = _templateSrv.formatValue(['test','test2'], 'lucene');
|
||||||
multiFormat: 'lucene',
|
expect(result).to.be('("test" OR "test2")');
|
||||||
current: {
|
|
||||||
value: ['test','test2'],
|
|
||||||
}
|
|
||||||
});
|
|
||||||
expect(result).to.be('(\\\"test\\\" OR \\\"test2\\\")');
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('multi value and regex format should render regex string', function() {
|
it('multi value and regex format should render regex string', function() {
|
||||||
var result = _templateSrv.renderVariableValue({
|
var result = _templateSrv.formatValue(['test.','test2'], 'regex');
|
||||||
multiFormat: 'regex values',
|
expect(result).to.be('test\\.|test2');
|
||||||
current: {
|
|
||||||
value: ['test','test2'],
|
|
||||||
}
|
|
||||||
});
|
|
||||||
expect(result).to.be('(test|test2)');
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('multi value and pipe should render pipe string', function() {
|
it('multi value and pipe should render pipe string', function() {
|
||||||
var result = _templateSrv.renderVariableValue({
|
var result = _templateSrv.formatValue(['test','test2'], 'pipe');
|
||||||
multiFormat: 'pipe',
|
|
||||||
current: {
|
|
||||||
value: ['test','test2'],
|
|
||||||
}
|
|
||||||
});
|
|
||||||
expect(result).to.be('test|test2');
|
expect(result).to.be('test|test2');
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -194,7 +238,6 @@ define([
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
});
|
});
|
||||||
|
@ -247,7 +247,7 @@ define([
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describeUpdateVariable('regex pattern remove duplicates', function(scenario) {
|
describeUpdateVariable('regex pattern remove duplicates', function(scenario) {
|
||||||
scenario.setup(function() {
|
scenario.setup(function() {
|
||||||
scenario.variable = { type: 'query', query: 'apps.*', name: 'test' };
|
scenario.variable = { type: 'query', query: 'apps.*', name: 'test' };
|
||||||
scenario.variable.regex = 'backend_01';
|
scenario.variable.regex = 'backend_01';
|
||||||
@ -259,107 +259,29 @@ define([
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describeUpdateVariable('with include All glob syntax', function(scenario) {
|
describeUpdateVariable('with include All', function(scenario) {
|
||||||
scenario.setup(function() {
|
scenario.setup(function() {
|
||||||
scenario.variable = { type: 'query', query: 'apps.*', name: 'test', includeAll: true, allFormat: 'glob' };
|
scenario.variable = {type: 'query', query: 'apps.*', name: 'test', includeAll: true};
|
||||||
scenario.queryResult = [{text: 'backend1'}, {text: 'backend2'}, { text: 'backend3'}];
|
scenario.queryResult = [{text: 'backend1'}, {text: 'backend2'}, { text: 'backend3'}];
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should add All Glob option', function() {
|
it('should add All option', function() {
|
||||||
expect(scenario.variable.options[0].value).to.be('{backend1,backend2,backend3}');
|
expect(scenario.variable.options[0].text).to.be('All');
|
||||||
|
expect(scenario.variable.options[0].value).to.be('$__all');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describeUpdateVariable('with include all wildcard', function(scenario) {
|
describeUpdateVariable('with include all and custom value', function(scenario) {
|
||||||
scenario.setup(function() {
|
scenario.setup(function() {
|
||||||
scenario.variable = { type: 'query', query: 'apps.*', name: 'test', includeAll: true, allFormat: 'wildcard' };
|
scenario.variable = { type: 'query', query: 'apps.*', name: 'test', includeAll: true, allValue: '*' };
|
||||||
scenario.queryResult = [{text: 'backend1'}, {text: 'backend2'}, { text: 'backend3'}];
|
scenario.queryResult = [{text: 'backend1'}, {text: 'backend2'}, { text: 'backend3'}];
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should add All wildcard option', function() {
|
it('should add All option with custom value', function() {
|
||||||
expect(scenario.variable.options[0].value).to.be('*');
|
expect(scenario.variable.options[0].value).to.be('*');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describeUpdateVariable('with include all wildcard', function(scenario) {
|
|
||||||
scenario.setup(function() {
|
|
||||||
scenario.variable = { type: 'query', query: 'apps.*', name: 'test', includeAll: true, allFormat: 'regex wildcard' };
|
|
||||||
scenario.queryResult = [{text: 'backend1'}, {text: 'backend2'}, { text: 'backend3'}];
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should add All wildcard option', function() {
|
|
||||||
expect(scenario.variable.options[0].value).to.be('.*');
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describeUpdateVariable('with include all regex values', function(scenario) {
|
|
||||||
scenario.setup(function() {
|
|
||||||
scenario.variable = { type: 'query', query: 'apps.*', name: 'test', includeAll: true, allFormat: 'wildcard' };
|
|
||||||
scenario.queryResult = [{text: 'backend1'}, {text: 'backend2'}, { text: 'backend3'}];
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should add All wildcard option', function() {
|
|
||||||
expect(scenario.variable.options[0].value).to.be('*');
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describeUpdateVariable('with include all glob no values', function(scenario) {
|
|
||||||
scenario.setup(function() {
|
|
||||||
scenario.variable = { type: 'query', query: 'apps.*', name: 'test', includeAll: true, allFormat: 'glob' };
|
|
||||||
scenario.queryResult = [];
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should add empty glob', function() {
|
|
||||||
expect(scenario.variable.options[0].value).to.be('{}');
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describeUpdateVariable('with include all lucene and values', function(scenario) {
|
|
||||||
scenario.setup(function() {
|
|
||||||
scenario.variable = { type: 'query', query: 'apps.*', name: 'test', includeAll: true, allFormat: 'lucene' };
|
|
||||||
scenario.queryResult = [{text: 'backend1'}, { text: 'backend2'}];
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should add lucene glob', function() {
|
|
||||||
expect(scenario.variable.options[0].value).to.be('(\\\"backend1\\\" OR \\\"backend2\\\")');
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describeUpdateVariable('with include all regex all values', function(scenario) {
|
|
||||||
scenario.setup(function() {
|
|
||||||
scenario.variable = { type: 'query', query: 'apps.*', name: 'test', includeAll: true, allFormat: 'regex values' };
|
|
||||||
scenario.queryResult = [{text: 'backend1'}, {text: 'backend2'}, { text: 'backend3'}];
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should add empty glob', function() {
|
|
||||||
expect(scenario.variable.options[0].value).to.be('(backend1|backend2|backend3)');
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describeUpdateVariable('with include all regex values and values require escaping', function(scenario) {
|
|
||||||
scenario.setup(function() {
|
|
||||||
scenario.variable = { type: 'query', query: 'apps.*', name: 'test', includeAll: true, allFormat: 'regex values' };
|
|
||||||
scenario.queryResult = [{text: '/root'}, {text: '/var'}, { text: '/lib'}];
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should regex escape options', function() {
|
|
||||||
expect(scenario.variable.options[0].value).to.be('(\\/lib|\\/root|\\/var)');
|
|
||||||
expect(scenario.variable.options[1].value).to.be('\\/lib');
|
|
||||||
expect(scenario.variable.options[1].text).to.be('/lib');
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describeUpdateVariable('with include all pipe all values', function(scenario) {
|
|
||||||
scenario.setup(function() {
|
|
||||||
scenario.variable = { type: 'query', query: 'apps.*', name: 'test', includeAll: true, allFormat: 'pipe' };
|
|
||||||
scenario.queryResult = [{text: 'backend1'}, {text: 'backend2'}, { text: 'backend3'}];
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should add pipe delimited string', function() {
|
|
||||||
expect(scenario.variable.options[0].value).to.be('backend1|backend2|backend3');
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
});
|
});
|
||||||
|
Loading…
Reference in New Issue
Block a user