diff --git a/CHANGELOG.md b/CHANGELOG.md index f00957dc9a8..6b8cd4f7128 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,7 @@ ### Enhancements * **Singlestat**: Support for gauges in singlestat panel. closes [#3688](https://github.com/grafana/grafana/pull/3688) +* **Templating**: Support for data source as variable, closes [#816](https://github.com/grafana/grafana/pull/816) ### Bug fixes * **InfluxDB 0.12**: Fixed issue templating and `show tag values` query only returning tags for first measurement, fixes [#4726](https://github.com/grafana/grafana/issues/4726) diff --git a/public/app/core/components/info_popover.ts b/public/app/core/components/info_popover.ts index b221c8577fa..d370aab9d6d 100644 --- a/public/app/core/components/info_popover.ts +++ b/public/app/core/components/info_popover.ts @@ -11,7 +11,6 @@ export function infoPopover() { template: '', transclude: true, link: function(scope, elem, attrs, ctrl, transclude) { - var offset = attrs.offset || '0 -10px'; var position = attrs.position || 'right middle'; var classes = 'drop-help drop-hide-out-of-bounds'; @@ -39,6 +38,7 @@ export function infoPopover() { position: position, classes: classes, openOn: openOn, + hoverOpenDelay: 400, tetherOptions: { offset: offset } diff --git a/public/app/core/services/datasource_srv.js b/public/app/core/services/datasource_srv.js index 07e3f004d45..2c3a043ac6c 100644 --- a/public/app/core/services/datasource_srv.js +++ b/public/app/core/services/datasource_srv.js @@ -7,36 +7,11 @@ define([ function (angular, _, coreModule, config) { 'use strict'; - coreModule.default.service('datasourceSrv', function($q, $injector, $rootScope) { + coreModule.default.service('datasourceSrv', function($q, $injector, $rootScope, templateSrv) { var self = this; this.init = function() { this.datasources = {}; - this.metricSources = []; - this.annotationSources = []; - - _.each(config.datasources, function(value, key) { - if (value.meta && value.meta.metrics) { - self.metricSources.push({ - value: key === config.defaultDatasource ? null : key, - name: key, - meta: value.meta, - }); - } - if (value.meta && value.meta.annotations) { - self.annotationSources.push(value); - } - }); - - this.metricSources.sort(function(a, b) { - if (a.meta.builtIn || a.name > b.name) { - return 1; - } - if (a.name < b.name) { - return -1; - } - return 0; - }); }; this.get = function(name) { @@ -44,6 +19,8 @@ function (angular, _, coreModule, config) { return this.get(config.defaultDatasource); } + name = templateSrv.replace(name); + if (this.datasources[name]) { return $q.when(this.datasources[name]); } @@ -89,11 +66,61 @@ function (angular, _, coreModule, config) { }; this.getAnnotationSources = function() { - return this.annotationSources; + return _.reduce(config.datasources, function(memo, key, value) { + + if (value.meta && value.meta.annotations) { + memo.push(value); + } + + return memo; + }, []); }; - this.getMetricSources = function() { - return this.metricSources; + this.getMetricSources = function(options) { + var metricSources = []; + + _.each(config.datasources, function(value, key) { + if (value.meta && value.meta.metrics) { + metricSources.push({ + value: key === config.defaultDatasource ? null : key, + name: key, + meta: value.meta, + }); + } + }); + + if (!options || !options.skipVariables) { + // look for data source variables + for (var i = 0; i < templateSrv.variables.length; i++) { + var variable = templateSrv.variables[i]; + if (variable.type !== 'datasource') { + continue; + } + + var first = variable.current.value; + var ds = config.datasources[first]; + + if (ds) { + metricSources.push({ + name: '$' + variable.name, + value: '$' + variable.name, + meta: ds.meta, + }); + } + } + } + + metricSources.sort(function(a, b) { + if (a.meta.builtIn || a.name > b.name) { + return 1; + } + if (a.name < b.name) { + return -1; + } + return 0; + }); + + return metricSources; }; this.init(); diff --git a/public/app/core/services/segment_srv.js b/public/app/core/services/segment_srv.js index a0b85a8bfb2..d05a2bb011f 100644 --- a/public/app/core/services/segment_srv.js +++ b/public/app/core/services/segment_srv.js @@ -19,7 +19,7 @@ function (angular, _, coreModule) { if (_.isString(options)) { this.value = options; - this.html = $sce.trustAsHtml(this.value); + this.html = $sce.trustAsHtml(templateSrv.highlightVariablesAsHtml(this.value)); return; } diff --git a/public/app/features/panel/metrics_ds_selector.ts b/public/app/features/panel/metrics_ds_selector.ts index 0c3c61955e3..b281c43048b 100644 --- a/public/app/features/panel/metrics_ds_selector.ts +++ b/public/app/features/panel/metrics_ds_selector.ts @@ -63,6 +63,10 @@ export class MetricsDsSelectorCtrl { } } + if (!this.current) { + this.current = {name: dsValue + ' not found', value: null}; + } + this.dsSegment = uiSegmentSrv.newSegment(this.current.name); } diff --git a/public/app/features/panel/metrics_panel_ctrl.ts b/public/app/features/panel/metrics_panel_ctrl.ts index 9ff63785273..0bccee8ff35 100644 --- a/public/app/features/panel/metrics_panel_ctrl.ts +++ b/public/app/features/panel/metrics_panel_ctrl.ts @@ -15,6 +15,7 @@ class MetricsPanelCtrl extends PanelCtrl { error: boolean; loading: boolean; datasource: any; + datasourceName: any; $q: any; $timeout: any; datasourceSrv: any; @@ -244,6 +245,7 @@ class MetricsPanelCtrl extends PanelCtrl { } this.panel.datasource = datasource.value; + this.datasourceName = datasource.name; this.datasource = null; this.refresh(); } diff --git a/public/app/features/templating/editorCtrl.js b/public/app/features/templating/editorCtrl.js index 291915ee99f..9ec4f57eb20 100644 --- a/public/app/features/templating/editorCtrl.js +++ b/public/app/features/templating/editorCtrl.js @@ -20,6 +20,13 @@ function (angular, _) { multi: false, }; + $scope.variableTypes = [ + {value: "query", text: "Query"}, + {value: "interval", text: "Interval"}, + {value: "datasource", text: "Datasource"}, + {value: "custom", text: "Custom"}, + ]; + $scope.refreshOptions = [ {value: 0, text: "Never"}, {value: 1, text: "On Dashboard Load"}, @@ -35,10 +42,16 @@ function (angular, _) { $scope.init = function() { $scope.mode = 'list'; + $scope.datasourceTypes = {}; $scope.datasources = _.filter(datasourceSrv.getMetricSources(), function(ds) { + $scope.datasourceTypes[ds.meta.id] = {text: ds.meta.name, value: ds.meta.id}; return !ds.meta.builtIn; }); + $scope.datasourceTypes = _.map($scope.datasourceTypes, function(value) { + return value; + }); + $scope.variables = templateSrv.variables; $scope.reset(); @@ -132,9 +145,16 @@ function (angular, _) { if ($scope.current.type === 'interval') { $scope.current.query = '1m,10m,30m,1h,6h,12h,1d,7d,14d,30d'; } + if ($scope.current.type === 'query') { $scope.current.query = ''; } + + if ($scope.current.type === 'datasource') { + $scope.current.query = $scope.datasourceTypes[0].value; + $scope.current.regex = ''; + $scope.current.refresh = 1; + } }; $scope.removeVariable = function(variable) { diff --git a/public/app/features/templating/partials/editor.html b/public/app/features/templating/partials/editor.html index c7dfe61f2b4..3e8ecb4f3c5 100644 --- a/public/app/features/templating/partials/editor.html +++ b/public/app/features/templating/partials/editor.html @@ -75,39 +75,49 @@