mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
Variables: Fixes inconsistend selected states on dashboard load (#34197)
This commit is contained in:
@@ -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 },
|
||||
]);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -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 = {
|
||||
|
||||
Reference in New Issue
Block a user