Variables: Fixes inconsistend selected states on dashboard load (#34197)

This commit is contained in:
Hugo Häggmark
2021-05-18 06:10:22 +02:00
committed by GitHub
parent de5cd4a7d3
commit 3339d13a45
2 changed files with 117 additions and 2 deletions

View File

@@ -12,6 +12,7 @@ import {
cancelVariables,
changeVariableMultiValue,
cleanUpVariables,
fixSelectedInconsistency,
initDashboardTemplating,
initVariablesTransaction,
processVariables,
@@ -686,4 +687,92 @@ describe('shared actions', () => {
});
});
});
describe('fixSelectedInconsistency', () => {
describe('when called for a single value variable', () => {
describe('and there is an inconsistency between current and selected in options', () => {
it('then it should set the correct selected', () => {
const variable = customBuilder().withId('custom').withCurrent('A').withOptions('A', 'B', 'C').build();
variable.options[1].selected = true;
expect(variable.options).toEqual([
{ text: 'A', value: 'A', selected: false },
{ text: 'B', value: 'B', selected: true },
{ text: 'C', value: 'C', selected: false },
]);
fixSelectedInconsistency(variable);
expect(variable.options).toEqual([
{ text: 'A', value: 'A', selected: true },
{ text: 'B', value: 'B', selected: false },
{ text: 'C', value: 'C', selected: false },
]);
});
});
describe('and there is no matching option in options', () => {
it('then the first option should be selected', () => {
const variable = customBuilder().withId('custom').withCurrent('A').withOptions('X', 'Y', 'Z').build();
expect(variable.options).toEqual([
{ text: 'X', value: 'X', selected: false },
{ text: 'Y', value: 'Y', selected: false },
{ text: 'Z', value: 'Z', selected: false },
]);
fixSelectedInconsistency(variable);
expect(variable.options).toEqual([
{ text: 'X', value: 'X', selected: true },
{ text: 'Y', value: 'Y', selected: false },
{ text: 'Z', value: 'Z', selected: false },
]);
});
});
});
describe('when called for a multi value variable', () => {
describe('and there is an inconsistency between current and selected in options', () => {
it('then it should set the correct selected', () => {
const variable = customBuilder().withId('custom').withCurrent(['A', 'C']).withOptions('A', 'B', 'C').build();
variable.options[1].selected = true;
expect(variable.options).toEqual([
{ text: 'A', value: 'A', selected: false },
{ text: 'B', value: 'B', selected: true },
{ text: 'C', value: 'C', selected: false },
]);
fixSelectedInconsistency(variable);
expect(variable.options).toEqual([
{ text: 'A', value: 'A', selected: true },
{ text: 'B', value: 'B', selected: false },
{ text: 'C', value: 'C', selected: true },
]);
});
});
describe('and there is no matching option in options', () => {
it('then the first option should be selected', () => {
const variable = customBuilder().withId('custom').withCurrent(['A', 'C']).withOptions('X', 'Y', 'Z').build();
expect(variable.options).toEqual([
{ text: 'X', value: 'X', selected: false },
{ text: 'Y', value: 'Y', selected: false },
{ text: 'Z', value: 'Z', selected: false },
]);
fixSelectedInconsistency(variable);
expect(variable.options).toEqual([
{ text: 'X', value: 'X', selected: true },
{ text: 'Y', value: 'Y', selected: false },
{ text: 'Z', value: 'Z', selected: false },
]);
});
});
});
});
});

View File

@@ -39,7 +39,7 @@ import {
import { contextSrv } from 'app/core/services/context_srv';
import { getTemplateSrv, TemplateSrv } from '../../templating/template_srv';
import { alignCurrentWithMulti } from '../shared/multiOptions';
import { hasLegacyVariableSupport, hasStandardVariableSupport, isMulti, isQuery } from '../guard';
import { hasLegacyVariableSupport, hasOptions, hasStandardVariableSupport, isMulti, isQuery } from '../guard';
import { getTimeSrv } from 'app/features/dashboard/services/TimeSrv';
import { DashboardModel } from 'app/features/dashboard/state';
import { createErrorNotification } from '../../../core/copy/appNotification';
@@ -92,7 +92,7 @@ export const initDashboardTemplating = (list: VariableModel[]): ThunkResult<void
return (dispatch, getState) => {
let orderIndex = 0;
for (let index = 0; index < list.length; index++) {
const model = list[index];
const model = fixSelectedInconsistency(list[index]);
if (!variableAdapters.getIfExists(model.type)) {
continue;
}
@@ -110,6 +110,32 @@ export const initDashboardTemplating = (list: VariableModel[]): ThunkResult<void
};
};
export function fixSelectedInconsistency(model: VariableModel): VariableModel | VariableWithOptions {
if (!hasOptions(model)) {
return model;
}
let found = false;
for (const option of model.options) {
option.selected = false;
if (Array.isArray(model.current.value)) {
for (const value of model.current.value) {
if (option.value === value) {
option.selected = found = true;
}
}
} else if (option.value === model.current.value) {
option.selected = found = true;
}
}
if (!found && model.options.length) {
model.options[0].selected = true;
}
return model;
}
export const addSystemTemplateVariables = (dashboard: DashboardModel): ThunkResult<void> => {
return (dispatch) => {
const dashboardModel: DashboardVariableModel = {