From 56903582cece021c00068b70199b2caab6edc28c Mon Sep 17 00:00:00 2001 From: Tobias Skarhed <1438972+tskarhed@users.noreply.github.com> Date: Fri, 9 Jul 2021 12:55:56 +0200 Subject: [PATCH] QueryVariable: Default to first option when none is set (#36521) * TemplateVariables: Default to first option when none is set * Add test * Add tests and rewrite logic --- .../variables/state/sharedReducer.test.ts | 52 +++++++++++++++++++ .../features/variables/state/sharedReducer.ts | 9 ++++ 2 files changed, 61 insertions(+) diff --git a/public/app/features/variables/state/sharedReducer.test.ts b/public/app/features/variables/state/sharedReducer.test.ts index 4cbbf1a9e5a..bf3a7300152 100644 --- a/public/app/features/variables/state/sharedReducer.test.ts +++ b/public/app/features/variables/state/sharedReducer.test.ts @@ -343,6 +343,58 @@ describe('sharedReducer', () => { }); }); + describe('when setCurrentVariableValue is dispatched and current.value has no value', () => { + it('then the first available option should be selected', () => { + const adapter = createQueryVariableAdapter(); + const { initialState } = getVariableTestContext(adapter, { + options: [ + { text: 'A', value: 'A', selected: false }, + { text: 'B', value: 'B', selected: false }, + { text: 'C', value: 'C', selected: false }, + ], + }); + const current = { text: '', value: '', selected: false }; + const payload = toVariablePayload({ id: '0', type: 'query' }, { option: current }); + reducerTester() + .givenReducer(sharedReducer, cloneDeep(initialState)) + .whenActionIsDispatched(setCurrentVariableValue(payload)) + .thenStateShouldEqual({ + ...initialState, + '0': ({ + ...initialState[0], + options: [ + { selected: true, text: 'A', value: 'A' }, + { selected: false, text: 'B', value: 'B' }, + { selected: false, text: 'C', value: 'C' }, + ], + current: { selected: true, text: 'A', value: 'A' }, + } as unknown) as QueryVariableModel, + }); + }); + }); + + describe('when setCurrentVariableValue is dispatched and current.value has no value and there are no options', () => { + it('then no option should be selected', () => { + const adapter = createQueryVariableAdapter(); + const { initialState } = getVariableTestContext(adapter, { + options: [], + }); + const current = { text: '', value: '', selected: false }; + const payload = toVariablePayload({ id: '0', type: 'query' }, { option: current }); + reducerTester() + .givenReducer(sharedReducer, cloneDeep(initialState)) + .whenActionIsDispatched(setCurrentVariableValue(payload)) + .thenStateShouldEqual({ + ...initialState, + '0': ({ + ...initialState[0], + options: [], + current: { selected: false, text: '', value: '' }, + } as unknown) as QueryVariableModel, + }); + }); + }); + describe('when setCurrentVariableValue is dispatched and current.value is an Array with values containing All value', () => { it('then state should be correct', () => { const adapter = createQueryVariableAdapter(); diff --git a/public/app/features/variables/state/sharedReducer.ts b/public/app/features/variables/state/sharedReducer.ts index b6fb2a5b25a..9ed2956aba2 100644 --- a/public/app/features/variables/state/sharedReducer.ts +++ b/public/app/features/variables/state/sharedReducer.ts @@ -121,6 +121,15 @@ const sharedReducerSlice = createSlice({ const { option } = action.payload.data; const current = { ...option, text: ensureStringValues(option?.text), value: ensureStringValues(option?.value) }; + // If no value is set, default to the first avilable + if (!current.value && instanceState.options.length) { + instanceState.options.forEach((option, index) => { + option.selected = !Boolean(index); + }); + instanceState.current = instanceState.options[0]; + return; + } + instanceState.current = current; instanceState.options = instanceState.options.map((option) => { option.value = ensureStringValues(option.value);