From 3f27d3ea23f5a6911d6529b1e839b35ef0828175 Mon Sep 17 00:00:00 2001 From: Jeremy Doupe Date: Tue, 5 Mar 2019 15:51:16 -0600 Subject: [PATCH 1/3] Make datasource variables multiselect and dashboard repeatable closes #7492 (and #7030) --- .../app/features/panel/metrics_panel_ctrl.ts | 21 ++++++++++++++++++- public/app/features/plugins/datasource_srv.ts | 4 ++++ .../templating/datasource_variable.ts | 15 +++++++++++++ 3 files changed, 39 insertions(+), 1 deletion(-) diff --git a/public/app/features/panel/metrics_panel_ctrl.ts b/public/app/features/panel/metrics_panel_ctrl.ts index ceebfd82335..0d73d6211e4 100644 --- a/public/app/features/panel/metrics_panel_ctrl.ts +++ b/public/app/features/panel/metrics_panel_ctrl.ts @@ -79,9 +79,28 @@ class MetricsPanelCtrl extends PanelCtrl { delete this.error; this.loading = true; + // set "mydatasource" to whatever the panel has defined + let mydatasource = this.panel.datasource; + let datasourceVarName = ''; + + // look for data source variables + for (let i = 0; i < this.templateSrv.variables.length; i++) { + const variable = this.templateSrv.variables[i]; + if (variable.type !== 'datasource') { + continue; + } + + datasourceVarName = variable.name; + } + + // if a data source variable was found, use its value + if (datasourceVarName !== '' && this.panel.scopedVars && this.panel.scopedVars[datasourceVarName]) { + mydatasource = this.panel.scopedVars[datasourceVarName].value; + } + // load datasource service this.datasourceSrv - .get(this.panel.datasource) + .get(mydatasource) .then(this.updateTimeRange.bind(this)) .then(this.issueQueries.bind(this)) .then(this.handleQueryResult.bind(this)) diff --git a/public/app/features/plugins/datasource_srv.ts b/public/app/features/plugins/datasource_srv.ts index f7dc0da32c4..aca87d8c63b 100644 --- a/public/app/features/plugins/datasource_srv.ts +++ b/public/app/features/plugins/datasource_srv.ts @@ -40,6 +40,10 @@ export class DatasourceSrv { } loadDatasource(name: string): Promise { + // if there are multiple datasources provided, just use the first one + const re = /{([^,}]+).*/; + name = name.replace(re, '$1'); + const dsConfig = config.datasources[name]; if (!dsConfig) { return this.$q.reject({ message: 'Datasource named ' + name + ' was not found' }); diff --git a/public/app/features/templating/datasource_variable.ts b/public/app/features/templating/datasource_variable.ts index 4424720c7f8..37b9e707444 100644 --- a/public/app/features/templating/datasource_variable.ts +++ b/public/app/features/templating/datasource_variable.ts @@ -6,6 +6,8 @@ export class DatasourceVariable implements Variable { query: string; options: any; current: any; + multi: boolean; + includeAll: boolean; refresh: any; skipUrlSync: boolean; @@ -18,6 +20,8 @@ export class DatasourceVariable implements Variable { regex: '', options: [], query: '', + multi: false, + includeAll: false, refresh: 1, skipUrlSync: false, }; @@ -69,9 +73,16 @@ export class DatasourceVariable implements Variable { } this.options = options; + if (this.includeAll) { + this.addAllOption(); + } return this.variableSrv.validateVariableSelectionState(this); } + addAllOption() { + this.options.unshift({ text: 'All', value: '$__all' }); + } + dependsOn(variable) { if (this.regex) { return containsVariable(this.regex, variable.name); @@ -84,6 +95,9 @@ export class DatasourceVariable implements Variable { } getValueForUrl() { + if (this.current.text === 'All') { + return 'All'; + } return this.current.value; } } @@ -91,5 +105,6 @@ export class DatasourceVariable implements Variable { variableTypes['datasource'] = { name: 'Datasource', ctor: DatasourceVariable, + supportsMulti: true, description: 'Enabled you to dynamically switch the datasource for multiple panels', }; From bf72b26c2c854ef8c6b7dbf13dc71223d676a647 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Torkel=20=C3=96degaard?= Date: Mon, 11 Mar 2019 15:44:11 +0100 Subject: [PATCH 2/3] Refactoring of multi-value datasource PR #15812 --- .../app/features/panel/metrics_panel_ctrl.ts | 21 +------------------ public/app/features/plugins/datasource_srv.ts | 15 ++++++------- 2 files changed, 9 insertions(+), 27 deletions(-) diff --git a/public/app/features/panel/metrics_panel_ctrl.ts b/public/app/features/panel/metrics_panel_ctrl.ts index 92412263f73..3e217369b15 100644 --- a/public/app/features/panel/metrics_panel_ctrl.ts +++ b/public/app/features/panel/metrics_panel_ctrl.ts @@ -79,28 +79,9 @@ class MetricsPanelCtrl extends PanelCtrl { delete this.error; this.loading = true; - // set "mydatasource" to whatever the panel has defined - let mydatasource = this.panel.datasource; - let datasourceVarName = ''; - - // look for data source variables - for (let i = 0; i < this.templateSrv.variables.length; i++) { - const variable = this.templateSrv.variables[i]; - if (variable.type !== 'datasource') { - continue; - } - - datasourceVarName = variable.name; - } - - // if a data source variable was found, use its value - if (datasourceVarName !== '' && this.panel.scopedVars && this.panel.scopedVars[datasourceVarName]) { - mydatasource = this.panel.scopedVars[datasourceVarName].value; - } - // load datasource service this.datasourceSrv - .get(mydatasource) + .get(this.panel.datasource, this.panel.scopedVars) .then(this.updateTimeRange.bind(this)) .then(this.issueQueries.bind(this)) .then(this.handleQueryResult.bind(this)) diff --git a/public/app/features/plugins/datasource_srv.ts b/public/app/features/plugins/datasource_srv.ts index aca87d8c63b..a98ac99eaf1 100644 --- a/public/app/features/plugins/datasource_srv.ts +++ b/public/app/features/plugins/datasource_srv.ts @@ -7,7 +7,7 @@ import config from 'app/core/config'; import { importPluginModule } from './plugin_loader'; // Types -import { DataSourceApi, DataSourceSelectItem } from '@grafana/ui/src/types'; +import { DataSourceApi, DataSourceSelectItem, ScopedVars } from '@grafana/ui/src/types'; export class DatasourceSrv { datasources: { [name: string]: DataSourceApi }; @@ -21,12 +21,17 @@ export class DatasourceSrv { this.datasources = {}; } - get(name?: string): Promise { + get(name?: string, scopedVars?: ScopedVars): Promise { if (!name) { return this.get(config.defaultDatasource); } - name = this.templateSrv.replace(name); + name = this.templateSrv.replace(name, scopedVars, (value, variable) => { + if (Array.isArray(value)) { + return value[0]; + } + return value; + }); if (name === 'default') { return this.get(config.defaultDatasource); @@ -40,10 +45,6 @@ export class DatasourceSrv { } loadDatasource(name: string): Promise { - // if there are multiple datasources provided, just use the first one - const re = /{([^,}]+).*/; - name = name.replace(re, '$1'); - const dsConfig = config.datasources[name]; if (!dsConfig) { return this.$q.reject({ message: 'Datasource named ' + name + ' was not found' }); From aeb35534914faea3b39778dcf5ab36de514a2ca1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Torkel=20=C3=96degaard?= Date: Mon, 11 Mar 2019 18:36:49 +0100 Subject: [PATCH 3/3] Added scopedVars argument in datasourceSrv.get in DataPanel --- public/app/features/dashboard/dashgrid/DataPanel.tsx | 2 +- public/app/features/plugins/datasource_srv.ts | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/public/app/features/dashboard/dashgrid/DataPanel.tsx b/public/app/features/dashboard/dashgrid/DataPanel.tsx index 09864d85960..82d94669cd6 100644 --- a/public/app/features/dashboard/dashgrid/DataPanel.tsx +++ b/public/app/features/dashboard/dashgrid/DataPanel.tsx @@ -116,7 +116,7 @@ export class DataPanel extends Component { this.setState({ loading: LoadingState.Loading }); try { - const ds = await this.dataSourceSrv.get(datasource); + const ds = await this.dataSourceSrv.get(datasource, scopedVars); // TODO interpolate variables const minInterval = this.props.minInterval || ds.interval; diff --git a/public/app/features/plugins/datasource_srv.ts b/public/app/features/plugins/datasource_srv.ts index a98ac99eaf1..fde17ba8f48 100644 --- a/public/app/features/plugins/datasource_srv.ts +++ b/public/app/features/plugins/datasource_srv.ts @@ -26,6 +26,7 @@ export class DatasourceSrv { return this.get(config.defaultDatasource); } + // Interpolation here is to support template variable in data source selection name = this.templateSrv.replace(name, scopedVars, (value, variable) => { if (Array.isArray(value)) { return value[0];