Dashboard: Variable without a current value in json model causes crash on load (#24261)

* Variables: Fixes variable initilization and default values

* fixed failing tests.

Co-authored-by: Marcus Andersson <marcus.andersson@grafana.com>
This commit is contained in:
Torkel Ödegaard 2020-05-05 15:47:48 +02:00 committed by GitHub
parent a2363f4d0c
commit cdc5203d8a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 19 additions and 7 deletions

View File

@ -196,7 +196,7 @@ describe('shared actions', () => {
${['A', 'B', 'C']} | ${'B'} | ${'C'} | ${'B'}
${['A', 'B', 'C']} | ${'X'} | ${undefined} | ${'A'}
${['A', 'B', 'C']} | ${'X'} | ${'C'} | ${'C'}
${undefined} | ${'B'} | ${undefined} | ${'A'}
${undefined} | ${'B'} | ${undefined} | ${'should not dispatch setCurrentVariableValue'}
`('then correct actions are dispatched', async ({ withOptions, withCurrent, defaultValue, expected }) => {
let custom;

View File

@ -308,7 +308,9 @@ export const validateVariableSelectionState = (
// 3. use the first value
if (variableInState.options) {
const option = variableInState.options[0];
return setValue(variableInState, option);
if (option) {
return setValue(variableInState, option);
}
}
// 4... give up

View File

@ -1,4 +1,5 @@
import cloneDeep from 'lodash/cloneDeep';
import { default as lodashDefaults } from 'lodash/defaults';
import { reducerTester } from '../../../../test/core/redux/reducerTester';
import {
@ -29,15 +30,20 @@ variableAdapters.setInit(() => [createQueryVariableAdapter()]);
describe('sharedReducer', () => {
describe('when addVariable is dispatched', () => {
it('then state should be correct', () => {
const model = ({ name: 'name from model', type: 'type from model' } as unknown) as QueryVariableModel;
const model = ({
name: 'name from model',
type: 'type from model',
current: undefined,
} as unknown) as QueryVariableModel;
const payload = toVariablePayload({ id: '0', type: 'query' }, { global: true, index: 0, model });
reducerTester<VariablesState>()
.givenReducer(sharedReducer, { ...initialVariablesState })
.whenActionIsDispatched(addVariable(payload))
.thenStateShouldEqual({
[0]: {
...initialQueryVariableModelState,
...model,
...lodashDefaults({}, model, initialQueryVariableModelState),
id: '0',
global: true,
index: 0,

View File

@ -1,5 +1,6 @@
import { createSlice, PayloadAction } from '@reduxjs/toolkit';
import cloneDeep from 'lodash/cloneDeep';
import { default as lodashDefaults } from 'lodash/defaults';
import { VariableType } from '@grafana/data';
import { VariableModel, VariableOption, VariableWithOptions } from '../../templating/types';
@ -16,13 +17,16 @@ const sharedReducerSlice = createSlice({
reducers: {
addVariable: (state: VariablesState, action: PayloadAction<VariablePayload<AddVariable>>) => {
const id = action.payload.id ?? action.payload.data.model.name; // for testing purposes we can call this with an id
const initialState = cloneDeep(variableAdapters.get(action.payload.type).initialState);
const model = cloneDeep(action.payload.data.model);
const variable = {
...cloneDeep(variableAdapters.get(action.payload.type).initialState),
...action.payload.data.model,
...lodashDefaults({}, model, initialState),
id: id,
index: action.payload.data.index,
global: action.payload.data.global,
};
state[id] = variable;
},
addInitLock: (state: VariablesState, action: PayloadAction<VariablePayload>) => {