diff --git a/packages/grafana-data/src/types/variables.ts b/packages/grafana-data/src/types/variables.ts index a7d3087d8ff..f8d8666c09e 100644 --- a/packages/grafana-data/src/types/variables.ts +++ b/packages/grafana-data/src/types/variables.ts @@ -35,6 +35,11 @@ export abstract class VariableSupportBase< TOptions extends DataSourceJsonData = DataSourceOptionsType > { abstract getType(): VariableSupportType; + + /** + * Define this method in the config if you want to pre-populate the editor with a default query. + */ + getDefaultQuery?(): Partial; } /** diff --git a/public/app/features/variables/query/QueryVariableEditor.test.tsx b/public/app/features/variables/query/QueryVariableEditor.test.tsx index 01c97505441..03a1884428e 100644 --- a/public/app/features/variables/query/QueryVariableEditor.test.tsx +++ b/public/app/features/variables/query/QueryVariableEditor.test.tsx @@ -2,7 +2,7 @@ import { render, screen } from '@testing-library/react'; import userEvent from '@testing-library/user-event'; import React from 'react'; -import { DataSourceApi } from '@grafana/data'; +import { DataSourceApi, VariableSupportType } from '@grafana/data'; import { mockDataSource } from 'app/features/alerting/unified/mocks'; import { DataSourceType } from 'app/features/alerting/unified/utils/datasource'; @@ -64,6 +64,42 @@ describe('QueryVariableEditor', () => { }); }); + describe('when the editor is rendered', () => { + const extendedCustom = { + extended: { + VariableQueryEditor: jest.fn().mockImplementation(LegacyVariableQueryEditor), + dataSource: { + variables: { + getType: () => VariableSupportType.Custom, + query: jest.fn(), + editor: jest.fn(), + }, + } as unknown as DataSourceApi, + }, + }; + it('should pass down the query with default values if the datasource config defines it', () => { + const extended = { ...extendedCustom }; + extended.extended.dataSource.variables!.getDefaultQuery = jest + .fn() + .mockImplementation(() => 'some default query'); + const { props } = setupTestContext(extended); + expect(props.extended?.dataSource?.variables?.getDefaultQuery).toBeDefined(); + expect(props.extended?.dataSource?.variables?.getDefaultQuery).toHaveBeenCalledTimes(1); + expect(props.extended?.VariableQueryEditor).toHaveBeenCalledWith( + expect.objectContaining({ query: 'some default query' }), + expect.anything() + ); + }); + it('should not pass down a default query if the datasource config doesnt define it', () => { + extendedCustom.extended.dataSource.variables!.getDefaultQuery = undefined; + const { props } = setupTestContext(extendedCustom); + expect(props.extended?.dataSource?.variables?.getDefaultQuery).not.toBeDefined(); + expect(props.extended?.VariableQueryEditor).toHaveBeenCalledWith( + expect.objectContaining({ query: '' }), + expect.anything() + ); + }); + }); describe('when the user changes', () => { it.each` fieldName | propName | expectedArgs diff --git a/public/app/features/variables/query/QueryVariableEditor.tsx b/public/app/features/variables/query/QueryVariableEditor.tsx index 9422038c2b0..49b239fac1c 100644 --- a/public/app/features/variables/query/QueryVariableEditor.tsx +++ b/public/app/features/variables/query/QueryVariableEditor.tsx @@ -134,10 +134,20 @@ export class QueryVariableEditorUnConnected extends PureComponent return null; } - const query = variable.query; const datasource = extended.dataSource; const VariableQueryEditor = extended.VariableQueryEditor; + let query = variable.query; + + if (typeof query === 'string') { + query = query || (datasource.variables?.getDefaultQuery?.() ?? ''); + } else { + query = { + ...datasource.variables?.getDefaultQuery?.(), + ...variable.query, + }; + } + if (isLegacyQueryEditor(VariableQueryEditor, datasource)) { return ( diff --git a/public/app/plugins/datasource/cloudwatch/defaultQueries.ts b/public/app/plugins/datasource/cloudwatch/defaultQueries.ts index e921f9d75cc..a3e804861ff 100644 --- a/public/app/plugins/datasource/cloudwatch/defaultQueries.ts +++ b/public/app/plugins/datasource/cloudwatch/defaultQueries.ts @@ -1,4 +1,12 @@ -import { CloudWatchLogsQuery, CloudWatchMetricsQuery, LogGroup, MetricEditorMode, MetricQueryType } from './types'; +import { + CloudWatchLogsQuery, + CloudWatchMetricsQuery, + LogGroup, + MetricEditorMode, + MetricQueryType, + VariableQuery, + VariableQueryType, +} from './types'; export const DEFAULT_METRICS_QUERY: Omit = { queryMode: 'Metrics', @@ -29,3 +37,8 @@ export const getDefaultLogsQuery = ( logGroupNames: legacyDefaultLogGroups, logGroups: defaultLogGroups ?? [], }); + +export const DEFAULT_VARIABLE_QUERY: Partial = { + queryType: VariableQueryType.Regions, + region: 'default', +}; diff --git a/public/app/plugins/datasource/cloudwatch/variables.ts b/public/app/plugins/datasource/cloudwatch/variables.ts index 0089878a150..9220ddf299e 100644 --- a/public/app/plugins/datasource/cloudwatch/variables.ts +++ b/public/app/plugins/datasource/cloudwatch/variables.ts @@ -12,6 +12,7 @@ import { import { ALL_ACCOUNTS_OPTION } from './components/Account'; import { VariableQueryEditor } from './components/VariableQueryEditor/VariableQueryEditor'; import { CloudWatchDatasource } from './datasource'; +import { DEFAULT_VARIABLE_QUERY } from './defaultQueries'; import { migrateVariableQuery } from './migrations/variableQueryMigrations'; import { ResourcesAPI } from './resources/ResourcesAPI'; import { standardStatistics } from './standardStatistics'; @@ -158,6 +159,10 @@ export class CloudWatchVariableSupport extends CustomVariableSupport { + return DEFAULT_VARIABLE_QUERY; + } } function selectableValueToMetricFindOption({ label, value }: SelectableValue): MetricFindValue {