Commit 622246d5 by Hugo Häggmark Committed by GitHub

Templating: fixes so Textbox variables get value from url (#24623)

parent f97d021c
......@@ -2,13 +2,14 @@ import { variableAdapters } from '../adapters';
import { createTextBoxVariableAdapter } from './adapter';
import { reduxTester } from '../../../../test/core/redux/reduxTester';
import { TemplatingState } from 'app/features/variables/state/reducers';
import { updateTextBoxVariableOptions } from './actions';
import { setTextBoxVariableOptionsFromUrl, updateTextBoxVariableOptions } from './actions';
import { getRootReducer } from '../state/helpers';
import { TextBoxVariableModel, VariableHide, VariableOption } from '../../templating/types';
import { VariableOption } from '../../templating/types';
import { toVariablePayload } from '../state/types';
import { createTextBoxOptions } from './reducer';
import { setCurrentVariableValue, addVariable } from '../state/sharedReducer';
import { addVariable, changeVariableProp, setCurrentVariableValue } from '../state/sharedReducer';
import { updateLocation } from 'app/core/actions';
import { textboxBuilder } from '../shared/testing/builders';
describe('textbox actions', () => {
variableAdapters.setInit(() => [createTextBoxVariableAdapter()]);
......@@ -21,39 +22,45 @@ describe('textbox actions', () => {
selected: false,
};
const variable: TextBoxVariableModel = {
type: 'textbox',
id: '0',
global: false,
current: {
value: '',
text: '',
selected: false,
},
options: [],
query: 'A',
name: 'textbox',
label: '',
hide: VariableHide.dontHide,
skipUrlSync: false,
index: 0,
};
const variable = textboxBuilder()
.withId('textbox')
.withName('textbox')
.withCurrent('A')
.withQuery('A')
.build();
const tester = await reduxTester<{ templating: TemplatingState }>()
.givenRootReducer(getRootReducer())
.whenActionIsDispatched(addVariable(toVariablePayload(variable, { global: false, index: 0, model: variable })))
.whenAsyncActionIsDispatched(updateTextBoxVariableOptions(toVariablePayload(variable)), true);
tester.thenDispatchedActionsPredicateShouldEqual(actions => {
const [createAction, setCurrentAction, locationAction] = actions;
const expectedNumberOfActions = 3;
tester.thenDispatchedActionsShouldEqual(
createTextBoxOptions(toVariablePayload(variable)),
setCurrentVariableValue(toVariablePayload(variable, { option })),
updateLocation({ query: { 'var-textbox': 'A' } })
);
});
});
describe('when setTextBoxVariableOptionsFromUrl is dispatched', () => {
it('then correct actions are dispatched', async () => {
const urlValue = 'bB';
const variable = textboxBuilder()
.withId('textbox')
.withName('textbox')
.withCurrent('A')
.withQuery('A')
.build();
expect(createAction).toEqual(createTextBoxOptions(toVariablePayload(variable)));
expect(setCurrentAction).toEqual(setCurrentVariableValue(toVariablePayload(variable, { option })));
expect(locationAction).toEqual(updateLocation({ query: { 'var-textbox': 'A' } }));
const tester = await reduxTester<{ templating: TemplatingState }>()
.givenRootReducer(getRootReducer())
.whenActionIsDispatched(addVariable(toVariablePayload(variable, { global: false, index: 0, model: variable })))
.whenAsyncActionIsDispatched(setTextBoxVariableOptionsFromUrl(toVariablePayload(variable), urlValue), true);
return actions.length === expectedNumberOfActions;
});
tester.thenDispatchedActionsShouldEqual(
changeVariableProp(toVariablePayload(variable, { propName: 'query', propValue: 'bB' })),
setCurrentVariableValue(toVariablePayload(variable, { option: { text: 'bB', value: 'bB', selected: false } }))
);
});
});
});
......@@ -3,12 +3,27 @@ import { ThunkResult } from '../../../types';
import { getVariable } from '../state/selectors';
import { variableAdapters } from '../adapters';
import { createTextBoxOptions } from './reducer';
import { toVariablePayload, VariableIdentifier } from '../state/types';
import { toVariableIdentifier, toVariablePayload, VariableIdentifier } from '../state/types';
import { setOptionFromUrl } from '../state/actions';
import { UrlQueryValue } from '@grafana/data';
import { changeVariableProp } from '../state/sharedReducer';
export const updateTextBoxVariableOptions = (identifier: VariableIdentifier): ThunkResult<void> => {
return async (dispatch, getState) => {
await dispatch(createTextBoxOptions(toVariablePayload(identifier)));
const variableInState = getVariable<TextBoxVariableModel>(identifier.id!, getState());
await variableAdapters.get(identifier.type).setValue(variableInState, variableInState.options[0], true);
};
};
export const setTextBoxVariableOptionsFromUrl = (
identifier: VariableIdentifier,
urlValue: UrlQueryValue
): ThunkResult<void> => async (dispatch, getState) => {
const variableInState = getVariable<TextBoxVariableModel>(identifier.id!, getState());
dispatch(changeVariableProp(toVariablePayload(variableInState, { propName: 'query', propValue: urlValue })));
await dispatch(setOptionFromUrl(toVariableIdentifier(variableInState), urlValue));
};
......@@ -3,11 +3,11 @@ import cloneDeep from 'lodash/cloneDeep';
import { TextBoxVariableModel } from '../../templating/types';
import { initialTextBoxVariableModelState, textBoxVariableReducer } from './reducer';
import { dispatch } from '../../../store/store';
import { setOptionAsCurrent, setOptionFromUrl } from '../state/actions';
import { setOptionAsCurrent } from '../state/actions';
import { VariableAdapter } from '../adapters';
import { TextBoxVariablePicker } from './TextBoxVariablePicker';
import { TextBoxVariableEditor } from './TextBoxVariableEditor';
import { updateTextBoxVariableOptions } from './actions';
import { setTextBoxVariableOptionsFromUrl, updateTextBoxVariableOptions } from './actions';
import { toVariableIdentifier } from '../state/types';
export const createTextBoxVariableAdapter = (): VariableAdapter<TextBoxVariableModel> => {
......@@ -26,7 +26,7 @@ export const createTextBoxVariableAdapter = (): VariableAdapter<TextBoxVariableM
await dispatch(setOptionAsCurrent(toVariableIdentifier(variable), option, emitChanges));
},
setValueFromUrl: async (variable, urlValue) => {
await dispatch(setOptionFromUrl(toVariableIdentifier(variable), urlValue));
await dispatch(setTextBoxVariableOptionsFromUrl(toVariableIdentifier(variable), urlValue));
},
updateOptions: async variable => {
await dispatch(updateTextBoxVariableOptions(toVariableIdentifier(variable)));
......
......@@ -25,10 +25,9 @@ export const textBoxVariableSlice = createSlice({
reducers: {
createTextBoxOptions: (state: VariablesState, action: PayloadAction<VariablePayload>) => {
const instanceState = getInstanceState<TextBoxVariableModel>(state, action.payload.id!);
instanceState.options = [
{ text: instanceState.query.trim(), value: instanceState.query.trim(), selected: false },
];
instanceState.current = instanceState.options[0];
const option = { text: instanceState.query.trim(), value: instanceState.query.trim(), selected: false };
instanceState.options = [option];
instanceState.current = option;
},
},
});
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment