mirror of
https://github.com/grafana/grafana.git
synced 2024-12-01 04:59:15 -06:00
feat(templating): progress on variable system refactoring, #6048
This commit is contained in:
parent
945b5ee3cf
commit
9d6ecc6361
@ -87,6 +87,7 @@ export class DashboardCtrl {
|
||||
};
|
||||
|
||||
$scope.templateVariableUpdated = function() {
|
||||
dynamicDashboardSrv.update($scope.dashboard);
|
||||
};
|
||||
|
||||
$scope.updateSubmenuVisibility = function() {
|
||||
|
@ -23,13 +23,15 @@ export class CustomVariable implements Variable {
|
||||
multi: false,
|
||||
};
|
||||
|
||||
supportsMulti = true;
|
||||
|
||||
/** @ngInject */
|
||||
constructor(private model, private timeSrv, private templateSrv, private variableSrv) {
|
||||
assignModelProperties(this, model, this.defaults);
|
||||
}
|
||||
|
||||
setValue(option) {
|
||||
this.variableSrv.setOptionAsCurrent(this, option);
|
||||
return this.variableSrv.setOptionAsCurrent(this, option);
|
||||
}
|
||||
|
||||
getModel() {
|
||||
@ -47,7 +49,7 @@ export class CustomVariable implements Variable {
|
||||
this.addAllOption();
|
||||
}
|
||||
|
||||
return Promise.resolve();
|
||||
return this.variableSrv.validateVariableSelectionState(this);
|
||||
}
|
||||
|
||||
addAllOption() {
|
||||
|
@ -15,7 +15,7 @@ export class DatasourceVariable implements Variable {
|
||||
name: '',
|
||||
hide: 0,
|
||||
label: '',
|
||||
current: {text: '', value: ''}
|
||||
current: {text: '', value: ''},
|
||||
regex: '',
|
||||
options: [],
|
||||
query: '',
|
||||
@ -32,7 +32,7 @@ export class DatasourceVariable implements Variable {
|
||||
}
|
||||
|
||||
setValue(option) {
|
||||
this.variableSrv.setOptionAsCurrent(this, option);
|
||||
return this.variableSrv.setOptionAsCurrent(this, option);
|
||||
}
|
||||
|
||||
updateOptions() {
|
||||
@ -63,6 +63,7 @@ export class DatasourceVariable implements Variable {
|
||||
}
|
||||
|
||||
this.options = options;
|
||||
return this.variableSrv.validateVariableSelectionState(this);
|
||||
}
|
||||
|
||||
dependsOn(variable) {
|
||||
|
@ -10,7 +10,7 @@ import appEvents from 'app/core/app_events';
|
||||
export class VariableEditorCtrl {
|
||||
|
||||
/** @ngInject */
|
||||
constructor(private $scope, private datasourceSrv, private variableSrv) {
|
||||
constructor(private $scope, private datasourceSrv, private variableSrv, templateSrv) {
|
||||
$scope.variableTypes = [
|
||||
{value: "query", text: "Query"},
|
||||
{value: "adhoc", text: "Ad hoc filters"},
|
||||
@ -27,7 +27,7 @@ export class VariableEditorCtrl {
|
||||
];
|
||||
|
||||
$scope.sortOptions = [
|
||||
{value: 0, text: "Query sort"},
|
||||
{value: 0, text: "Disabled"},
|
||||
{value: 1, text: "Alphabetical (asc)"},
|
||||
{value: 2, text: "Alphabetical (desc)"},
|
||||
{value: 3, text: "Numerical (asc)"},
|
||||
@ -115,6 +115,7 @@ export class VariableEditorCtrl {
|
||||
$scope.runQuery().then(function() {
|
||||
$scope.reset();
|
||||
$scope.mode = 'list';
|
||||
templateSrv.updateTemplateData();
|
||||
});
|
||||
}
|
||||
};
|
||||
@ -124,18 +125,6 @@ export class VariableEditorCtrl {
|
||||
$scope.current = variableSrv.createVariableFromModel({type: 'query'});
|
||||
};
|
||||
|
||||
$scope.showSelectionOptions = function() {
|
||||
if ($scope.current) {
|
||||
if ($scope.current.type === 'query') {
|
||||
return true;
|
||||
}
|
||||
if ($scope.current.type === 'custom') {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
$scope.typeChanged = function() {
|
||||
var old = $scope.current;
|
||||
$scope.current = variableSrv.createVariableFromModel({type: $scope.current.type});
|
||||
@ -147,27 +136,6 @@ export class VariableEditorCtrl {
|
||||
if (oldIndex !== -1) {
|
||||
this.variables[oldIndex] = $scope.current;
|
||||
}
|
||||
|
||||
// if ($scope.current.type === 'interval') {
|
||||
// $scope.current.query = '1m,10m,30m,1h,6h,12h,1d,7d,14d,30d';
|
||||
// $scope.current.refresh = 0;
|
||||
// }
|
||||
//
|
||||
// if ($scope.current.type === 'query') {
|
||||
// $scope.current.query = '';
|
||||
// }
|
||||
//
|
||||
// if ($scope.current.type === 'constant') {
|
||||
// $scope.current.query = '';
|
||||
// $scope.current.refresh = 0;
|
||||
// $scope.current.hide = 2;
|
||||
// }
|
||||
//
|
||||
// if ($scope.current.type === 'datasource') {
|
||||
// $scope.current.query = $scope.datasourceTypes[0].value;
|
||||
// $scope.current.regex = '';
|
||||
// $scope.current.refresh = 1;
|
||||
// }
|
||||
};
|
||||
|
||||
$scope.removeVariable = function(variable) {
|
||||
|
@ -11,12 +11,14 @@ export class IntervalVariable implements Variable {
|
||||
options: any;
|
||||
auto: boolean;
|
||||
query: string;
|
||||
refresh: number;
|
||||
|
||||
defaults = {
|
||||
type: 'interval',
|
||||
name: '',
|
||||
hide: 0,
|
||||
label: '',
|
||||
refresh: 2,
|
||||
options: [],
|
||||
current: {text: '', value: ''},
|
||||
query: '1m,10m,30m,1h,6h,12h,1d,7d,14d,30d',
|
||||
@ -28,6 +30,7 @@ export class IntervalVariable implements Variable {
|
||||
/** @ngInject */
|
||||
constructor(private model, private timeSrv, private templateSrv, private variableSrv) {
|
||||
assignModelProperties(this, model, this.defaults);
|
||||
this.refresh = 2;
|
||||
}
|
||||
|
||||
getModel() {
|
||||
@ -37,7 +40,7 @@ export class IntervalVariable implements Variable {
|
||||
|
||||
setValue(option) {
|
||||
this.updateAutoValue();
|
||||
this.variableSrv.setOptionAsCurrent(this, option);
|
||||
return this.variableSrv.setOptionAsCurrent(this, option);
|
||||
}
|
||||
|
||||
updateAutoValue() {
|
||||
@ -61,6 +64,7 @@ export class IntervalVariable implements Variable {
|
||||
});
|
||||
|
||||
this.updateAutoValue();
|
||||
return this.variableSrv.validateVariableSelectionState(this);
|
||||
}
|
||||
|
||||
dependsOn(variable) {
|
||||
|
@ -181,19 +181,8 @@
|
||||
<select class="gf-form-input" ng-model="current.refresh" ng-options="f.value as f.text for f in refreshOptions"></select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="gf-form max-width-21">
|
||||
<span class="gf-form-label width-7">
|
||||
Sort
|
||||
<info-popover mode="right-normal">
|
||||
How to sort the values of this variable.
|
||||
</info-popover>
|
||||
</span>
|
||||
<div class="gf-form-select-wrapper max-width-14">
|
||||
<select class="gf-form-input" ng-model="current.sort" ng-options="f.value as f.text for f in sortOptions" ng-change="runQuery()"></select>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="gf-form">
|
||||
</div>
|
||||
<div class="gf-form">
|
||||
<span class="gf-form-label width-7">Query</span>
|
||||
<input type="text" class="gf-form-input" ng-model='current.query' placeholder="metric name or tags query" ng-model-onblur ng-change="runQuery()"></input>
|
||||
</div>
|
||||
@ -206,35 +195,46 @@
|
||||
</span>
|
||||
<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 max-width-21">
|
||||
<span class="gf-form-label width-7">
|
||||
Sort
|
||||
<info-popover mode="right-normal">
|
||||
How to sort the values of this variable.
|
||||
</info-popover>
|
||||
</span>
|
||||
<div class="gf-form-select-wrapper max-width-14">
|
||||
<select class="gf-form-input" ng-model="current.sort" ng-options="f.value as f.text for f in sortOptions" ng-change="runQuery()"></select>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div ng-show="current.type === 'datasource'" class="gf-form-group">
|
||||
<h5 class="section-heading">Data source options</h5>
|
||||
<div ng-show="current.type === 'datasource'" class="gf-form-group">
|
||||
<h5 class="section-heading">Data source options</h5>
|
||||
|
||||
<div class="gf-form">
|
||||
<label class="gf-form-label width-12">Type</label>
|
||||
<div class="gf-form-select-wrapper max-width-18">
|
||||
<select class="gf-form-input" ng-model="current.query" ng-options="f.value as f.text for f in datasourceTypes" ng-change="runQuery()"></select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="gf-form">
|
||||
<label class="gf-form-label width-12">Type</label>
|
||||
<div class="gf-form-select-wrapper max-width-18">
|
||||
<select class="gf-form-input" ng-model="current.query" ng-options="f.value as f.text for f in datasourceTypes" ng-change="runQuery()"></select>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="gf-form">
|
||||
<label class="gf-form-label width-12">
|
||||
Instance name filter
|
||||
<info-popover mode="right-normal">
|
||||
Regex filter for which data source instances to choose from in
|
||||
the variable value dropdown. Leave empty for all.
|
||||
<br><br>
|
||||
Example: <code>/^prod/</code>
|
||||
<div class="gf-form">
|
||||
<label class="gf-form-label width-12">
|
||||
Instance name filter
|
||||
<info-popover mode="right-normal">
|
||||
Regex filter for which data source instances to choose from in
|
||||
the variable value dropdown. Leave empty for all.
|
||||
<br><br>
|
||||
Example: <code>/^prod/</code>
|
||||
|
||||
</info-popover>
|
||||
</label>
|
||||
<input type="text" class="gf-form-input max-width-18" ng-model='current.regex' placeholder="/.*-(.*)-.*/" ng-model-onblur ng-change="runQuery()"></input>
|
||||
</div>
|
||||
</div>
|
||||
</info-popover>
|
||||
</label>
|
||||
<input type="text" class="gf-form-input max-width-18" ng-model='current.regex' placeholder="/.*-(.*)-.*/" ng-model-onblur ng-change="runQuery()"></input>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div ng-show="current.type === 'adhoc'" class="gf-form-group">
|
||||
<h5 class="section-heading">Options</h5>
|
||||
<h5 class="section-heading">Options</h5>
|
||||
|
||||
<div class="gf-form max-width-21">
|
||||
<span class="gf-form-label width-8">Data source</span>
|
||||
@ -242,58 +242,58 @@
|
||||
<select class="gf-form-input" ng-model="current.datasource" ng-options="f.value as f.name for f in datasources"></select>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="section gf-form-group" ng-show="showSelectionOptions()">
|
||||
<h5 class="section-heading">Selection Options</h5>
|
||||
<div class="section">
|
||||
<gf-form-switch class="gf-form"
|
||||
label="Multi-value"
|
||||
label-class="width-10"
|
||||
tooltip="Enables multiple values to be selected at the same time"
|
||||
checked="current.multi"
|
||||
on-change="runQuery()">
|
||||
</gf-form-switch>
|
||||
<gf-form-switch class="gf-form"
|
||||
label="Include All option"
|
||||
label-class="width-10"
|
||||
checked="current.includeAll"
|
||||
on-change="runQuery()">
|
||||
</gf-form-switch>
|
||||
</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" ng-model='current.allValue' placeholder="blank = auto"></input>
|
||||
</div>
|
||||
</div>
|
||||
<div class="section gf-form-group" ng-show="current.supportsMulti">
|
||||
<h5 class="section-heading">Selection Options</h5>
|
||||
<div class="section">
|
||||
<gf-form-switch class="gf-form"
|
||||
label="Multi-value"
|
||||
label-class="width-10"
|
||||
tooltip="Enables multiple values to be selected at the same time"
|
||||
checked="current.multi"
|
||||
on-change="runQuery()">
|
||||
</gf-form-switch>
|
||||
<gf-form-switch class="gf-form"
|
||||
label="Include All option"
|
||||
label-class="width-10"
|
||||
checked="current.includeAll"
|
||||
on-change="runQuery()">
|
||||
</gf-form-switch>
|
||||
</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" ng-model='current.allValue' placeholder="blank = auto"></input>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="gf-form-group" ng-if="current.type === 'query'">
|
||||
<h5>Value groups/tags (Experimental feature)</h5>
|
||||
<div class="gf-form">
|
||||
<editor-checkbox text="Enable" model="current.useTags" change="runQuery()"></editor-checkbox>
|
||||
</div>
|
||||
<div class="gf-form last" ng-if="current.useTags">
|
||||
<span class="gf-form-label width-10">Tags query</span>
|
||||
<input type="text" class="gf-form-input" ng-model='current.tagsQuery' placeholder="metric name or tags query" ng-model-onblur></input>
|
||||
</div>
|
||||
<div class="gf-form" ng-if="current.useTags">
|
||||
<li class="gf-form-label width-10">Tag values query</li>
|
||||
<input type="text" class="gf-form-input" ng-model='current.tagValuesQuery' placeholder="apps.$tag.*" ng-model-onblur></input>
|
||||
</div>
|
||||
</div>
|
||||
<div class="gf-form-group" ng-if="current.type === 'query'">
|
||||
<h5>Value groups/tags (Experimental feature)</h5>
|
||||
<div class="gf-form">
|
||||
<editor-checkbox text="Enable" model="current.useTags" change="runQuery()"></editor-checkbox>
|
||||
</div>
|
||||
<div class="gf-form last" ng-if="current.useTags">
|
||||
<span class="gf-form-label width-10">Tags query</span>
|
||||
<input type="text" class="gf-form-input" ng-model='current.tagsQuery' placeholder="metric name or tags query" ng-model-onblur></input>
|
||||
</div>
|
||||
<div class="gf-form" ng-if="current.useTags">
|
||||
<li class="gf-form-label width-10">Tag values query</li>
|
||||
<input type="text" class="gf-form-input" ng-model='current.tagValuesQuery' placeholder="apps.$tag.*" ng-model-onblur></input>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="gf-form-group">
|
||||
<h5>Preview of values (shows max 20)</h5>
|
||||
<div class="gf-form-inline">
|
||||
<div class="gf-form" ng-repeat="option in current.options | limitTo: 20">
|
||||
<span class="gf-form-label">{{option.text}}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="gf-form-group">
|
||||
<h5>Preview of values (shows max 20)</h5>
|
||||
<div class="gf-form-inline">
|
||||
<div class="gf-form" ng-repeat="option in current.options | limitTo: 20">
|
||||
<span class="gf-form-label">{{option.text}}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="gf-form-button-row p-y-0">
|
||||
<button type="button" class="btn btn-success" ng-show="mode === 'edit'" ng-click="update();">Update</button>
|
||||
<div class="gf-form-button-row p-y-0">
|
||||
<button type="button" class="btn btn-success" ng-show="mode === 'edit'" ng-click="update();">Update</button>
|
||||
<button type="button" class="btn btn-success" ng-show="mode === 'new'" ng-click="add();">Add</button>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -37,6 +37,8 @@ export class QueryVariable implements Variable {
|
||||
current: {text: '', value: ''},
|
||||
};
|
||||
|
||||
supportsMulti = true;
|
||||
|
||||
constructor(private model, private datasourceSrv, private templateSrv, private variableSrv, private $q) {
|
||||
// copy model properties to this instance
|
||||
assignModelProperties(this, model, this.defaults);
|
||||
@ -49,7 +51,7 @@ export class QueryVariable implements Variable {
|
||||
}
|
||||
|
||||
setValue(option){
|
||||
this.variableSrv.setOptionAsCurrent(this, option);
|
||||
return this.variableSrv.setOptionAsCurrent(this, option);
|
||||
}
|
||||
|
||||
setValueFromUrl(urlValue) {
|
||||
@ -59,9 +61,7 @@ export class QueryVariable implements Variable {
|
||||
updateOptions() {
|
||||
return this.datasourceSrv.get(this.datasource)
|
||||
.then(this.updateOptionsFromMetricFindQuery.bind(this))
|
||||
.then(() => {
|
||||
this.variableSrv.validateVariableSelectionState(this);
|
||||
});
|
||||
.then(this.variableSrv.validateVariableSelectionState.bind(this.variableSrv, this));
|
||||
}
|
||||
|
||||
updateOptionsFromMetricFindQuery(datasource) {
|
||||
|
@ -15,7 +15,7 @@ export class VariableSrv {
|
||||
/** @ngInject */
|
||||
constructor(private $rootScope, private $q, private $location, private $injector, private templateSrv) {
|
||||
// update time variant variables
|
||||
// $rootScope.onAppEvent('refresh', this.onDashboardRefresh.bind(this), $rootScope);
|
||||
$rootScope.$on('refresh', this.onDashboardRefresh.bind(this), $rootScope);
|
||||
}
|
||||
|
||||
init(dashboard) {
|
||||
@ -41,22 +41,21 @@ export class VariableSrv {
|
||||
}
|
||||
|
||||
onDashboardRefresh() {
|
||||
// var promises = this.variables
|
||||
// .filter(variable => variable.refresh === 2)
|
||||
// .map(variable => {
|
||||
// var previousOptions = variable.options.slice();
|
||||
//
|
||||
// return self.updateOptions(variable).then(function () {
|
||||
// return self.variableUpdated(variable).then(function () {
|
||||
// // check if current options changed due to refresh
|
||||
// if (angular.toJson(previousOptions) !== angular.toJson(variable.options)) {
|
||||
// $rootScope.appEvent('template-variable-value-updated');
|
||||
// }
|
||||
// });
|
||||
// });
|
||||
// });
|
||||
//
|
||||
// return this.$q.all(promises);
|
||||
var promises = this.variables
|
||||
.filter(variable => variable.refresh === 2)
|
||||
.map(variable => {
|
||||
var previousOptions = variable.options.slice();
|
||||
|
||||
return variable.updateOptions()
|
||||
.then(this.variableUpdated.bind(this, variable))
|
||||
.then(() => {
|
||||
if (angular.toJson(previousOptions) !== angular.toJson(variable.options)) {
|
||||
this.$rootScope.$emit('template-variable-value-updated');
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
return this.$q.all(promises);
|
||||
}
|
||||
|
||||
processVariable(variable, queryParams) {
|
||||
|
@ -257,6 +257,10 @@ function (angular, _, moment, kbn, ElasticQueryBuilder, IndexPattern, ElasticRes
|
||||
esQuery = header + '\n' + esQuery + '\n';
|
||||
|
||||
return this._post('_msearch?search_type=count', esQuery).then(function(res) {
|
||||
if (!res.responses[0].aggregations) {
|
||||
return [];
|
||||
}
|
||||
|
||||
var buckets = res.responses[0].aggregations["1"].buckets;
|
||||
return _.map(buckets, function(bucket) {
|
||||
return {text: bucket.key, value: bucket.key};
|
||||
|
Loading…
Reference in New Issue
Block a user