Variables: Clear query when data source type changes (#33924)

This commit is contained in:
Hugo Häggmark 2021-05-11 14:09:19 +02:00 committed by GitHub
parent dc3e17ba5b
commit b55b3307c1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 65 additions and 33 deletions

View File

@ -1,6 +1,6 @@
import React, { FormEvent, PureComponent } from 'react';
import { connect, ConnectedProps } from 'react-redux';
import { css } from '@emotion/css';
import { MapDispatchToProps, MapStateToProps } from 'react-redux';
import { InlineField, InlineFieldRow, VerticalGroup } from '@grafana/ui';
import { selectors } from '@grafana/e2e-selectors';
import { DataSourcePicker, getTemplateSrv } from '@grafana/runtime';
@ -13,7 +13,6 @@ import { changeQueryVariableDataSource, changeQueryVariableQuery, initQueryVaria
import { VariableEditorState } from '../editor/reducer';
import { OnPropChangeArguments, VariableEditorProps } from '../editor/types';
import { StoreState } from '../../../types';
import { connectWithStore } from '../../../core/utils/connectWithReduxStore';
import { toVariableIdentifier } from '../state/types';
import { changeVariableMultiValue } from '../state/actions';
import { getTimeSrv } from '../../dashboard/services/TimeSrv';
@ -23,20 +22,22 @@ import { VariableTextField } from '../editor/VariableTextField';
import { QueryVariableRefreshSelect } from './QueryVariableRefreshSelect';
import { QueryVariableSortSelect } from './QueryVariableSortSelect';
const mapStateToProps = (state: StoreState) => ({
editor: state.templating.editor as VariableEditorState<QueryVariableEditorState>,
});
const mapDispatchToProps = {
initQueryVariableEditor,
changeQueryVariableDataSource,
changeQueryVariableQuery,
changeVariableMultiValue,
};
const connector = connect(mapStateToProps, mapDispatchToProps);
export interface OwnProps extends VariableEditorProps<QueryVariableModel> {}
interface ConnectedProps {
editor: VariableEditorState<QueryVariableEditorState>;
}
interface DispatchProps {
initQueryVariableEditor: typeof initQueryVariableEditor;
changeQueryVariableDataSource: typeof changeQueryVariableDataSource;
changeQueryVariableQuery: typeof changeQueryVariableQuery;
changeVariableMultiValue: typeof changeVariableMultiValue;
}
export type Props = OwnProps & ConnectedProps & DispatchProps;
export type Props = OwnProps & ConnectedProps<typeof connector>;
export interface State {
regex: string | null;
@ -65,7 +66,6 @@ export class QueryVariableEditorUnConnected extends PureComponent<Props, State>
}
onDataSourceChange = (dsSettings: DataSourceInstanceSettings) => {
this.props.onPropChange({ propName: 'query', propValue: '' });
this.props.onPropChange({
propName: 'datasource',
propValue: dsSettings.isDefault ? null : dsSettings.name,
@ -215,19 +215,4 @@ export class QueryVariableEditorUnConnected extends PureComponent<Props, State>
}
}
const mapStateToProps: MapStateToProps<ConnectedProps, OwnProps, StoreState> = (state, ownProps) => ({
editor: state.templating.editor as VariableEditorState<QueryVariableEditorState>,
});
const mapDispatchToProps: MapDispatchToProps<DispatchProps, OwnProps> = {
initQueryVariableEditor,
changeQueryVariableDataSource,
changeQueryVariableQuery,
changeVariableMultiValue,
};
export const QueryVariableEditor = connectWithStore(
QueryVariableEditorUnConnected,
mapStateToProps,
mapDispatchToProps
);
export const QueryVariableEditor = connector(QueryVariableEditorUnConnected);

View File

@ -346,6 +346,42 @@ describe('query actions', () => {
return actions.length === expectedNumberOfActions;
});
});
describe('and data source type changed', () => {
it('then correct actions are dispatched', async () => {
const variable = createVariable({ datasource: 'other' });
const editor = {};
const preloadedState: any = { templating: { editor: { extended: { dataSource: { type: 'previous' } } } } };
mocks.pluginLoader.importDataSourcePlugin = jest.fn().mockResolvedValue({
components: { VariableQueryEditor: editor },
});
const tester = await reduxTester<RootReducerType>({ preloadedState })
.givenRootReducer(getRootReducer())
.whenActionIsDispatched(
addVariable(toVariablePayload(variable, { global: false, index: 0, model: variable }))
)
.whenAsyncActionIsDispatched(changeQueryVariableDataSource(toVariablePayload(variable), 'datasource'), true);
tester.thenDispatchedActionsPredicateShouldEqual((actions) => {
const [changeVariable, updateDatasource, updateEditor] = actions;
const expectedNumberOfActions = 3;
expect(changeVariable).toEqual(
changeVariableProp(toVariablePayload(variable, { propName: 'query', propValue: '' }))
);
expect(updateDatasource).toEqual(
changeVariableEditorExtended({ propName: 'dataSource', propValue: mocks.datasource })
);
expect(updateEditor).toEqual(
changeVariableEditorExtended({ propName: 'VariableQueryEditor', propValue: editor })
);
return actions.length === expectedNumberOfActions;
});
});
});
});
describe('when changeQueryVariableDataSource is dispatched and editor is not configured', () => {

View File

@ -1,15 +1,21 @@
import { toDataQueryError, getDataSourceSrv } from '@grafana/runtime';
import { getDataSourceSrv, toDataQueryError } from '@grafana/runtime';
import { updateOptions } from '../state/actions';
import { QueryVariableModel } from '../types';
import { ThunkResult } from '../../../types';
import { getVariable } from '../state/selectors';
import { addVariableEditorError, changeVariableEditorExtended, removeVariableEditorError } from '../editor/reducer';
import {
addVariableEditorError,
changeVariableEditorExtended,
removeVariableEditorError,
VariableEditorState,
} from '../editor/reducer';
import { changeVariableProp } from '../state/sharedReducer';
import { toVariableIdentifier, toVariablePayload, VariableIdentifier } from '../state/types';
import { getVariableQueryEditor } from '../editor/getVariableQueryEditor';
import { Subscription } from 'rxjs';
import { getVariableQueryRunner } from './VariableQueryRunner';
import { variableQueryObserver } from './variableQueryObserver';
import { QueryVariableEditorState } from './reducer';
export const updateQueryVariableOptions = (
identifier: VariableIdentifier,
@ -58,7 +64,12 @@ export const changeQueryVariableDataSource = (
): ThunkResult<void> => {
return async (dispatch, getState) => {
try {
const editorState = getState().templating.editor as VariableEditorState<QueryVariableEditorState>;
const previousDatasource = editorState.extended?.dataSource;
const dataSource = await getDataSourceSrv().get(name ?? '');
if (previousDatasource && previousDatasource.type !== dataSource?.type) {
dispatch(changeVariableProp(toVariablePayload(identifier, { propName: 'query', propValue: '' })));
}
dispatch(changeVariableEditorExtended({ propName: 'dataSource', propValue: dataSource }));
const VariableQueryEditor = await getVariableQueryEditor(dataSource);