diff --git a/public/app/features/variables/adhoc/AdHocVariableEditor.test.tsx b/public/app/features/variables/adhoc/AdHocVariableEditor.test.tsx
new file mode 100644
index 00000000000..82944657f9e
--- /dev/null
+++ b/public/app/features/variables/adhoc/AdHocVariableEditor.test.tsx
@@ -0,0 +1,53 @@
+import React from 'react';
+import { render, screen } from '@testing-library/react';
+
+import { AdHocVariableEditorUnConnected as AdHocVariableEditor } from './AdHocVariableEditor';
+import { initialAdHocVariableModelState } from './reducer';
+import { selectOptionInTest } from '@grafana/ui';
+import { getSelectParent } from '@grafana/ui/src/components/Select/test-utils';
+
+const props = {
+ extended: {
+ dataSources: [
+ { text: 'Prometheus', value: null }, // default datasource
+ { text: 'Loki', value: { type: 'loki-ds', uid: 'abc' } },
+ ],
+ },
+ variable: { ...initialAdHocVariableModelState },
+ onPropChange: jest.fn(),
+
+ // connected actions
+ initAdHocVariableEditor: jest.fn(),
+ changeVariableDatasource: jest.fn(),
+};
+
+describe('AdHocVariableEditor', () => {
+ beforeEach(() => {
+ props.changeVariableDatasource.mockReset();
+ });
+
+ it('has a datasource select menu', async () => {
+ render();
+
+ const selectContainer = getSelectParent(screen.getByLabelText('Data source'));
+ expect(selectContainer).toHaveTextContent('Prometheus');
+ });
+
+ it('calls the callback when changing the datasource', async () => {
+ render();
+ await selectOptionInTest(screen.getByLabelText('Data source'), 'Loki');
+
+ expect(props.changeVariableDatasource).toBeCalledWith({ type: 'loki-ds', uid: 'abc' });
+ });
+
+ it('renders informational text', () => {
+ const extended = {
+ ...props.extended,
+ infoText: "Here's a message that should help you",
+ };
+ render();
+
+ const alert = screen.getByText("Here's a message that should help you");
+ expect(alert).toBeInTheDocument();
+ });
+});
diff --git a/public/app/features/variables/adhoc/AdHocVariableEditor.tsx b/public/app/features/variables/adhoc/AdHocVariableEditor.tsx
index 387de6bb027..f00a074c21d 100644
--- a/public/app/features/variables/adhoc/AdHocVariableEditor.tsx
+++ b/public/app/features/variables/adhoc/AdHocVariableEditor.tsx
@@ -5,15 +5,14 @@ import { DataSourceRef, SelectableValue } from '@grafana/data';
import { AdHocVariableModel } from '../types';
import { VariableEditorProps } from '../editor/types';
-import { VariableEditorState } from '../editor/reducer';
-import { AdHocVariableEditorState } from './reducer';
import { changeVariableDatasource, initAdHocVariableEditor } from './actions';
import { StoreState } from 'app/types';
import { VariableSectionHeader } from '../editor/VariableSectionHeader';
import { VariableSelectField } from '../editor/VariableSelectField';
+import { getAdhocVariableEditorState } from '../editor/selectors';
const mapStateToProps = (state: StoreState) => ({
- editor: state.templating.editor as VariableEditorState,
+ extended: getAdhocVariableEditorState(state.templating.editor),
});
const mapDispatchToProps = {
@@ -37,9 +36,9 @@ export class AdHocVariableEditorUnConnected extends PureComponent {
};
render() {
- const { variable, editor } = this.props;
- const dataSources = editor.extended?.dataSources ?? [];
- const infoText = editor.extended?.infoText ?? null;
+ const { variable, extended } = this.props;
+ const dataSources = extended?.dataSources ?? [];
+ const infoText = extended?.infoText ?? null;
const options = dataSources.map((ds) => ({ label: ds.text, value: ds.value }));
const value = options.find((o) => o.value?.uid === variable.datasource?.uid) ?? options[0];
@@ -56,6 +55,7 @@ export class AdHocVariableEditorUnConnected extends PureComponent {
labelWidth={10}
/>
+
{infoText ? : null}
diff --git a/public/app/features/variables/adhoc/reducer.ts b/public/app/features/variables/adhoc/reducer.ts
index 50cafae936a..3f5aa9f9222 100644
--- a/public/app/features/variables/adhoc/reducer.ts
+++ b/public/app/features/variables/adhoc/reducer.ts
@@ -1,5 +1,4 @@
import { createSlice, PayloadAction } from '@reduxjs/toolkit';
-import { DataSourceRef } from '@grafana/data';
import { AdHocVariableFilter, AdHocVariableModel, initialVariableModelState } from 'app/features/variables/types';
import { getInstanceState, initialVariablesState, VariablePayload, VariablesState } from '../state/types';
@@ -8,10 +7,6 @@ export interface AdHocVariabelFilterUpdate {
index: number;
filter: AdHocVariableFilter;
}
-export interface AdHocVariableEditorState {
- infoText: string;
- dataSources: Array<{ text: string; value: DataSourceRef | null }>;
-}
export const initialAdHocVariableModelState: AdHocVariableModel = {
...initialVariableModelState,
diff --git a/public/app/features/variables/datasource/DataSourceVariableEditor.test.tsx b/public/app/features/variables/datasource/DataSourceVariableEditor.test.tsx
new file mode 100644
index 00000000000..9bf77dec0c2
--- /dev/null
+++ b/public/app/features/variables/datasource/DataSourceVariableEditor.test.tsx
@@ -0,0 +1,55 @@
+import React from 'react';
+import { render, screen, fireEvent } from '@testing-library/react';
+
+import { DataSourceVariableEditorUnConnected as DataSourceVariableEditor } from './DataSourceVariableEditor';
+import { initialDataSourceVariableModelState } from './reducer';
+import { selectOptionInTest } from '@grafana/ui';
+import { getSelectParent } from '@grafana/ui/src/components/Select/test-utils';
+
+const props = {
+ extended: {
+ dataSourceTypes: [
+ { text: 'Prometheus', value: 'ds-prom' },
+ { text: 'Loki', value: 'ds-loki' },
+ ],
+ },
+ variable: { ...initialDataSourceVariableModelState },
+ onPropChange: jest.fn(),
+
+ // connected actions
+ initDataSourceVariableEditor: jest.fn(),
+ changeVariableMultiValue: jest.fn(),
+};
+
+describe('DataSourceVariableEditor', () => {
+ beforeEach(() => {
+ props.onPropChange.mockReset();
+ });
+
+ it('has a data source select menu', () => {
+ render();
+
+ const selectContainer = getSelectParent(screen.getByLabelText('Type'));
+ expect(selectContainer).toHaveTextContent('Prometheus');
+ });
+
+ it('calls the handler when the data source is changed', async () => {
+ render();
+ await selectOptionInTest(screen.getByLabelText('Type'), 'Loki');
+
+ expect(props.onPropChange).toBeCalledWith({ propName: 'query', propValue: 'ds-loki', updateOptions: true });
+ });
+
+ it('has a regex filter field', () => {
+ render();
+ const field = screen.getByLabelText('Instance name filter');
+ expect(field).toBeInTheDocument();
+ });
+
+ it('calls the handler when the regex filter is changed', () => {
+ render();
+ const field = screen.getByLabelText('Instance name filter');
+ fireEvent.change(field, { target: { value: '/prod/' } });
+ expect(props.onPropChange).toBeCalledWith({ propName: 'regex', propValue: '/prod/' });
+ });
+});
diff --git a/public/app/features/variables/datasource/DataSourceVariableEditor.tsx b/public/app/features/variables/datasource/DataSourceVariableEditor.tsx
index 73af0609cea..0be82c77056 100644
--- a/public/app/features/variables/datasource/DataSourceVariableEditor.tsx
+++ b/public/app/features/variables/datasource/DataSourceVariableEditor.tsx
@@ -1,34 +1,34 @@
import React, { FormEvent, PureComponent } from 'react';
-import { MapDispatchToProps, MapStateToProps } from 'react-redux';
+import { connect, ConnectedProps } from 'react-redux';
import { InlineFieldRow, VerticalGroup } from '@grafana/ui';
import { DataSourceVariableModel, VariableWithMultiSupport } from '../types';
import { OnPropChangeArguments, VariableEditorProps } from '../editor/types';
import { SelectionOptionsEditor } from '../editor/SelectionOptionsEditor';
-import { VariableEditorState } from '../editor/reducer';
-import { DataSourceVariableEditorState } from './reducer';
import { initDataSourceVariableEditor } from './actions';
import { StoreState } from '../../../types';
-import { connectWithStore } from '../../../core/utils/connectWithReduxStore';
import { changeVariableMultiValue } from '../state/actions';
import { VariableSectionHeader } from '../editor/VariableSectionHeader';
import { VariableSelectField } from '../editor/VariableSelectField';
import { SelectableValue } from '@grafana/data';
import { VariableTextField } from '../editor/VariableTextField';
import { selectors } from '@grafana/e2e-selectors';
+import { getDatasourceVariableEditorState } from '../editor/selectors';
+
+const mapStateToProps = (state: StoreState) => ({
+ extended: getDatasourceVariableEditorState(state.templating.editor),
+});
+
+const mapDispatchToProps = {
+ initDataSourceVariableEditor,
+ changeVariableMultiValue,
+};
+
+const connector = connect(mapStateToProps, mapDispatchToProps);
export interface OwnProps extends VariableEditorProps {}
-interface ConnectedProps {
- editor: VariableEditorState;
-}
-
-interface DispatchProps {
- initDataSourceVariableEditor: typeof initDataSourceVariableEditor;
- changeVariableMultiValue: typeof changeVariableMultiValue;
-}
-
-type Props = OwnProps & ConnectedProps & DispatchProps;
+type Props = OwnProps & ConnectedProps;
export class DataSourceVariableEditorUnConnected extends PureComponent {
componentDidMount() {
@@ -55,11 +55,14 @@ export class DataSourceVariableEditorUnConnected extends PureComponent {
};
getSelectedDataSourceTypeValue = (): string => {
- if (!this.props.editor.extended?.dataSourceTypes?.length) {
+ const { extended } = this.props;
+
+ if (!extended?.dataSourceTypes.length) {
return '';
}
- const foundItem = this.props.editor.extended?.dataSourceTypes.find((ds) => ds.value === this.props.variable.query);
- const value = foundItem ? foundItem.value : this.props.editor.extended?.dataSourceTypes[0].value;
+
+ const foundItem = extended.dataSourceTypes.find((ds) => ds.value === this.props.variable.query);
+ const value = foundItem ? foundItem.value : extended.dataSourceTypes[0].value;
return value ?? '';
};
@@ -68,10 +71,13 @@ export class DataSourceVariableEditorUnConnected extends PureComponent {
};
render() {
- const typeOptions = this.props.editor.extended?.dataSourceTypes?.length
- ? this.props.editor.extended?.dataSourceTypes?.map((ds) => ({ value: ds.value ?? '', label: ds.text }))
+ const { variable, extended, changeVariableMultiValue } = this.props;
+
+ const typeOptions = extended?.dataSourceTypes?.length
+ ? extended.dataSourceTypes?.map((ds) => ({ value: ds.value ?? '', label: ds.text }))
: [];
- const typeValue = typeOptions.find((o) => o.value === this.props.variable.query) ?? typeOptions[0];
+
+ const typeValue = typeOptions.find((o) => o.value === variable.query) ?? typeOptions[0];
return (
@@ -110,9 +116,9 @@ export class DataSourceVariableEditorUnConnected extends PureComponent {
@@ -120,17 +126,4 @@ export class DataSourceVariableEditorUnConnected extends PureComponent {
}
}
-const mapStateToProps: MapStateToProps = (state, ownProps) => ({
- editor: state.templating.editor as VariableEditorState,
-});
-
-const mapDispatchToProps: MapDispatchToProps = {
- initDataSourceVariableEditor,
- changeVariableMultiValue,
-};
-
-export const DataSourceVariableEditor = connectWithStore(
- DataSourceVariableEditorUnConnected,
- mapStateToProps,
- mapDispatchToProps
-);
+export const DataSourceVariableEditor = connector(DataSourceVariableEditorUnConnected);
diff --git a/public/app/features/variables/datasource/reducer.ts b/public/app/features/variables/datasource/reducer.ts
index d67a96d0689..1a6cb0619d3 100644
--- a/public/app/features/variables/datasource/reducer.ts
+++ b/public/app/features/variables/datasource/reducer.ts
@@ -5,10 +5,6 @@ import { DataSourceVariableModel, initialVariableModelState, VariableOption, Var
import { getInstanceState, initialVariablesState, VariablePayload, VariablesState } from '../state/types';
import { ALL_VARIABLE_TEXT, ALL_VARIABLE_VALUE } from '../constants';
-export interface DataSourceVariableEditorState {
- dataSourceTypes: Array<{ text: string; value: string }>;
-}
-
export const initialDataSourceVariableModelState: DataSourceVariableModel = {
...initialVariableModelState,
type: 'datasource',
diff --git a/public/app/features/variables/editor/reducer.test.ts b/public/app/features/variables/editor/reducer.test.ts
index c43e2345039..a50a42cb5f2 100644
--- a/public/app/features/variables/editor/reducer.test.ts
+++ b/public/app/features/variables/editor/reducer.test.ts
@@ -62,7 +62,7 @@ describe('variableEditorReducer', () => {
name: 'A name',
isValid: false,
errors: { update: 'Something wrong' },
- extended: { prop: 1000 },
+ extended: null,
};
const payload = toVariablePayload({ id: '0', type: 'textbox' });
reducerTester()
@@ -188,6 +188,7 @@ describe('variableEditorReducer', () => {
.thenStateShouldEqual({
...initialVariableEditorState,
extended: {
+ // @ts-ignore - temp ignoring this, we'll fix it soon
someProp: [{}],
},
});
diff --git a/public/app/features/variables/editor/reducer.ts b/public/app/features/variables/editor/reducer.ts
index e3caa2fd4cc..4a93f91dc02 100644
--- a/public/app/features/variables/editor/reducer.ts
+++ b/public/app/features/variables/editor/reducer.ts
@@ -1,13 +1,30 @@
+import { DataSourceApi, DataSourceRef } from '@grafana/data';
import { createSlice, PayloadAction } from '@reduxjs/toolkit';
import { VariablePayload } from '../state/types';
+import { VariableQueryEditorType } from '../types';
-type VariableEditorExtension = { [P in keyof ExtendedProps]: ExtendedProps[P] };
-export interface VariableEditorState {
+export interface AdHocVariableEditorState {
+ infoText?: string;
+ dataSources: Array<{ text: string; value: DataSourceRef | null }>;
+}
+
+export interface DataSourceVariableEditorState {
+ dataSourceTypes: Array<{ text: string; value: string }>;
+}
+
+export interface QueryVariableEditorState {
+ VariableQueryEditor: VariableQueryEditorType;
+ dataSource: DataSourceApi | null;
+}
+
+type VariableEditorExtension = AdHocVariableEditorState | DataSourceVariableEditorState | QueryVariableEditorState;
+
+export interface VariableEditorState {
id: string;
name: string;
errors: Record;
isValid: boolean;
- extended: VariableEditorExtension | null;
+ extended: VariableEditorExtension | null;
}
export const initialVariableEditorState: VariableEditorState = {
@@ -65,6 +82,7 @@ const variableEditorReducerSlice = createSlice({
state: VariableEditorState,
action: PayloadAction<{ propName: string; propValue: any }>
) => {
+ // @ts-ignore - temp ignoring the errors now the state type is more strict
state.extended = {
...state.extended,
[action.payload.propName]: action.payload.propValue,
diff --git a/public/app/features/variables/editor/selectors.test.ts b/public/app/features/variables/editor/selectors.test.ts
new file mode 100644
index 00000000000..6380d9153df
--- /dev/null
+++ b/public/app/features/variables/editor/selectors.test.ts
@@ -0,0 +1,89 @@
+import {
+ getAdhocVariableEditorState,
+ getDatasourceVariableEditorState,
+ getQueryVariableEditorState,
+} from './selectors';
+import {
+ AdHocVariableEditorState,
+ DataSourceVariableEditorState,
+ initialVariableEditorState,
+ QueryVariableEditorState,
+} from './reducer';
+import { LegacyVariableQueryEditor } from './LegacyVariableQueryEditor';
+import { DataSourceApi } from '@grafana/data';
+
+const adhocExtended: AdHocVariableEditorState = {
+ dataSources: [
+ { text: 'Prometheus', value: null }, // default datasource
+ { text: 'Loki', value: { type: 'loki-ds', uid: 'abc' } },
+ ],
+};
+
+const datasourceExtended: DataSourceVariableEditorState = {
+ dataSourceTypes: [
+ { text: 'Prometheus', value: 'ds-prom' },
+ { text: 'Loki', value: 'ds-loki' },
+ ],
+};
+
+const queryExtended: QueryVariableEditorState = {
+ VariableQueryEditor: LegacyVariableQueryEditor,
+ dataSource: {} as unknown as DataSourceApi,
+};
+
+const adhocVariableState = {
+ ...initialVariableEditorState,
+ extended: adhocExtended,
+};
+
+const datasourceVariableState = {
+ ...initialVariableEditorState,
+ extended: datasourceExtended,
+};
+
+const queryVariableState = {
+ ...initialVariableEditorState,
+ extended: queryExtended,
+};
+
+describe('getAdhocVariableEditorState', () => {
+ it('returns the extended properties for adhoc variable state', () => {
+ expect(getAdhocVariableEditorState(adhocVariableState)).toBe(adhocExtended);
+ });
+
+ it('returns null for datasource variable state', () => {
+ expect(getAdhocVariableEditorState(datasourceVariableState)).toBeNull();
+ });
+
+ it('returns null for query variable state', () => {
+ expect(getAdhocVariableEditorState(queryVariableState)).toBeNull();
+ });
+});
+
+describe('getDatasourceVariableEditorState', () => {
+ it('returns the extended properties for datasource variable state', () => {
+ expect(getDatasourceVariableEditorState(datasourceVariableState)).toBe(datasourceExtended);
+ });
+
+ it('returns null for adhoc variable state', () => {
+ expect(getDatasourceVariableEditorState(adhocVariableState)).toBeNull();
+ });
+
+ it('returns null for query variable state', () => {
+ expect(getDatasourceVariableEditorState(queryVariableState)).toBeNull();
+ });
+});
+
+describe('getQueryVariableEditorState', () => {
+ it('returns the extended properties for query variable state', () => {
+ expect(getQueryVariableEditorState(queryVariableState)).toBe(queryExtended);
+ });
+
+ it('returns null for adhoc variable state', () => {
+ expect(getQueryVariableEditorState(adhocVariableState)).toBeNull();
+ });
+
+ it('returns null for datasource variable state', () => {
+ expect(getQueryVariableEditorState(datasourceVariableState)).toBeNull();
+ });
+});
diff --git a/public/app/features/variables/editor/selectors.ts b/public/app/features/variables/editor/selectors.ts
new file mode 100644
index 00000000000..2152d4ed18f
--- /dev/null
+++ b/public/app/features/variables/editor/selectors.ts
@@ -0,0 +1,41 @@
+import {
+ AdHocVariableEditorState,
+ DataSourceVariableEditorState,
+ QueryVariableEditorState,
+ VariableEditorState,
+} from './reducer';
+
+/**
+ * Narrows generic variable editor state down to specific Adhoc variable extended editor state
+ */
+export function getAdhocVariableEditorState(editorState: VariableEditorState): AdHocVariableEditorState | null {
+ if (editorState.extended && 'dataSources' in editorState.extended) {
+ return editorState.extended;
+ }
+
+ return null;
+}
+
+/**
+ * Narrows generic variable editor state down to specific Datasource variable extended editor state
+ */
+export function getDatasourceVariableEditorState(
+ editorState: VariableEditorState
+): DataSourceVariableEditorState | null {
+ if (editorState.extended && 'dataSourceTypes' in editorState.extended) {
+ return editorState.extended;
+ }
+
+ return null;
+}
+
+/**
+ * Narrows generic variable editor state down to specific Query variable extended editor state
+ */
+export function getQueryVariableEditorState(editorState: VariableEditorState): QueryVariableEditorState | null {
+ if (editorState.extended && 'dataSource' in editorState.extended) {
+ return editorState.extended;
+ }
+
+ return null;
+}
diff --git a/public/app/features/variables/query/QueryVariableEditor.test.tsx b/public/app/features/variables/query/QueryVariableEditor.test.tsx
index d61344f5b46..69c4cd08810 100644
--- a/public/app/features/variables/query/QueryVariableEditor.test.tsx
+++ b/public/app/features/variables/query/QueryVariableEditor.test.tsx
@@ -5,7 +5,6 @@ import { DataSourceApi } from '@grafana/data';
import { Props, QueryVariableEditorUnConnected } from './QueryVariableEditor';
import { initialQueryVariableModelState } from './reducer';
-import { initialVariableEditorState } from '../editor/reducer';
import { describe, expect } from '../../../../test/lib/common';
import { LegacyVariableQueryEditor } from '../editor/LegacyVariableQueryEditor';
import { mockDataSource } from 'app/features/alerting/unified/mocks';
@@ -13,19 +12,17 @@ import { DataSourceType } from 'app/features/alerting/unified/utils/datasource';
import { NEW_VARIABLE_ID } from '../constants';
const setupTestContext = (options: Partial) => {
+ const extended = {
+ VariableQueryEditor: LegacyVariableQueryEditor,
+ dataSource: {} as unknown as DataSourceApi,
+ };
const defaults: Props = {
variable: { ...initialQueryVariableModelState },
initQueryVariableEditor: jest.fn(),
changeQueryVariableDataSource: jest.fn(),
changeQueryVariableQuery: jest.fn(),
changeVariableMultiValue: jest.fn(),
- editor: {
- ...initialVariableEditorState,
- extended: {
- VariableQueryEditor: LegacyVariableQueryEditor,
- dataSource: {} as unknown as DataSourceApi,
- },
- },
+ extended,
onPropChange: jest.fn(),
};
diff --git a/public/app/features/variables/query/QueryVariableEditor.tsx b/public/app/features/variables/query/QueryVariableEditor.tsx
index df4cdfe3ccf..521748f237f 100644
--- a/public/app/features/variables/query/QueryVariableEditor.tsx
+++ b/public/app/features/variables/query/QueryVariableEditor.tsx
@@ -8,9 +8,7 @@ import { DataSourceInstanceSettings, getDataSourceRef, LoadingState, SelectableV
import { SelectionOptionsEditor } from '../editor/SelectionOptionsEditor';
import { QueryVariableModel, VariableRefresh, VariableSort, VariableWithMultiSupport } from '../types';
-import { QueryVariableEditorState } from './reducer';
import { changeQueryVariableDataSource, changeQueryVariableQuery, initQueryVariableEditor } from './actions';
-import { VariableEditorState } from '../editor/reducer';
import { OnPropChangeArguments, VariableEditorProps } from '../editor/types';
import { StoreState } from '../../../types';
import { toVariableIdentifier } from '../state/types';
@@ -21,9 +19,10 @@ import { VariableSectionHeader } from '../editor/VariableSectionHeader';
import { VariableTextField } from '../editor/VariableTextField';
import { QueryVariableRefreshSelect } from './QueryVariableRefreshSelect';
import { QueryVariableSortSelect } from './QueryVariableSortSelect';
+import { getQueryVariableEditorState } from '../editor/selectors';
const mapStateToProps = (state: StoreState) => ({
- editor: state.templating.editor as VariableEditorState,
+ extended: getQueryVariableEditorState(state.templating.editor),
});
const mapDispatchToProps = {
@@ -114,14 +113,15 @@ export class QueryVariableEditorUnConnected extends PureComponent
};
renderQueryEditor = () => {
- const { editor, variable } = this.props;
- if (!editor.extended || !editor.extended.dataSource || !editor.extended.VariableQueryEditor) {
+ const { extended, variable } = this.props;
+
+ if (!extended || !extended.dataSource || !extended.VariableQueryEditor) {
return null;
}
const query = variable.query;
- const datasource = editor.extended.dataSource;
- const VariableQueryEditor = editor.extended.VariableQueryEditor;
+ const datasource = extended.dataSource;
+ const VariableQueryEditor = extended.VariableQueryEditor;
if (isLegacyQueryEditor(VariableQueryEditor, datasource)) {
return (
diff --git a/public/app/features/variables/query/actions.ts b/public/app/features/variables/query/actions.ts
index f88883cf6e6..58debe8d6db 100644
--- a/public/app/features/variables/query/actions.ts
+++ b/public/app/features/variables/query/actions.ts
@@ -6,19 +6,14 @@ import { updateOptions } from '../state/actions';
import { QueryVariableModel } from '../types';
import { ThunkResult } from '../../../types';
import { getVariable } from '../state/selectors';
-import {
- addVariableEditorError,
- changeVariableEditorExtended,
- removeVariableEditorError,
- VariableEditorState,
-} from '../editor/reducer';
+import { addVariableEditorError, changeVariableEditorExtended, removeVariableEditorError } from '../editor/reducer';
import { changeVariableProp } from '../state/sharedReducer';
import { toVariableIdentifier, toVariablePayload, VariableIdentifier } from '../state/types';
import { getVariableQueryEditor } from '../editor/getVariableQueryEditor';
import { getVariableQueryRunner } from './VariableQueryRunner';
import { variableQueryObserver } from './variableQueryObserver';
-import { QueryVariableEditorState } from './reducer';
import { hasOngoingTransaction } from '../utils';
+import { getQueryVariableEditorState } from '../editor/selectors';
export const updateQueryVariableOptions = (
identifier: VariableIdentifier,
@@ -71,8 +66,8 @@ export const changeQueryVariableDataSource = (
): ThunkResult => {
return async (dispatch, getState) => {
try {
- const editorState = getState().templating.editor as VariableEditorState;
- const previousDatasource = editorState.extended?.dataSource;
+ const extendedEditorState = getQueryVariableEditorState(getState().templating.editor);
+ const previousDatasource = extendedEditorState?.dataSource;
const dataSource = await getDataSourceSrv().get(name ?? '');
if (previousDatasource && previousDatasource.type !== dataSource?.type) {
dispatch(changeVariableProp(toVariablePayload(identifier, { propName: 'query', propValue: '' })));
diff --git a/public/app/features/variables/query/reducer.ts b/public/app/features/variables/query/reducer.ts
index 10edda1cec0..03e2e0d89e8 100644
--- a/public/app/features/variables/query/reducer.ts
+++ b/public/app/features/variables/query/reducer.ts
@@ -1,15 +1,8 @@
import { createSlice, PayloadAction } from '@reduxjs/toolkit';
import { isNumber, sortBy, toLower, uniqBy } from 'lodash';
-import { DataSourceApi, MetricFindValue, stringToJsRegex } from '@grafana/data';
+import { MetricFindValue, stringToJsRegex } from '@grafana/data';
-import {
- initialVariableModelState,
- QueryVariableModel,
- VariableOption,
- VariableQueryEditorType,
- VariableRefresh,
- VariableSort,
-} from '../types';
+import { initialVariableModelState, QueryVariableModel, VariableOption, VariableRefresh, VariableSort } from '../types';
import { getInstanceState, initialVariablesState, VariablePayload, VariablesState } from '../state/types';
import { ALL_VARIABLE_TEXT, ALL_VARIABLE_VALUE, NONE_VARIABLE_TEXT, NONE_VARIABLE_VALUE } from '../constants';
@@ -19,11 +12,6 @@ interface VariableOptionsUpdate {
results: MetricFindValue[];
}
-export interface QueryVariableEditorState {
- VariableQueryEditor: VariableQueryEditorType;
- dataSource: DataSourceApi | null;
-}
-
export const initialQueryVariableModelState: QueryVariableModel = {
...initialVariableModelState,
type: 'query',