mirror of
https://github.com/grafana/grafana.git
synced 2024-11-24 09:50:29 -06:00
Variables: Selectively reload panels on URL update (#51003)
This commit is contained in:
parent
7e1667ce87
commit
342344bb03
@ -4900,12 +4900,12 @@ exports[`no explicit any`] = {
|
||||
[270, 29, 3, "Unexpected any. Specify a different type.", "193409811"],
|
||||
[754, 26, 3, "Unexpected any. Specify a different type.", "193409811"]
|
||||
],
|
||||
"public/app/features/variables/state/actions.ts:2709491277": [
|
||||
"public/app/features/variables/state/actions.ts:443730774": [
|
||||
[601, 32, 3, "Unexpected any. Specify a different type.", "193409811"],
|
||||
[678, 32, 3, "Unexpected any. Specify a different type.", "193409811"],
|
||||
[716, 90, 3, "Unexpected any. Specify a different type.", "193409811"],
|
||||
[860, 9, 3, "Unexpected any. Specify a different type.", "193409811"],
|
||||
[934, 32, 3, "Unexpected any. Specify a different type.", "193409811"]
|
||||
[731, 90, 3, "Unexpected any. Specify a different type.", "193409811"],
|
||||
[875, 9, 3, "Unexpected any. Specify a different type.", "193409811"],
|
||||
[949, 32, 3, "Unexpected any. Specify a different type.", "193409811"]
|
||||
],
|
||||
"public/app/features/variables/state/initVariableTransaction.test.ts:1177248976": [
|
||||
[55, 29, 3, "Unexpected any. Specify a different type.", "193409811"],
|
||||
|
@ -678,7 +678,9 @@ export const templateVarsChangedInUrl =
|
||||
async (dispatch, getState) => {
|
||||
const update: Array<Promise<any>> = [];
|
||||
const dashboard = getState().dashboard.getModel();
|
||||
for (const variable of getVariablesByKey(key, getState())) {
|
||||
const panelIds = new Set<number>();
|
||||
const variables = getVariablesByKey(key, getState());
|
||||
for (const variable of variables) {
|
||||
const key = `var-${variable.name}`;
|
||||
if (!vars.hasOwnProperty(key)) {
|
||||
// key not found quick exit
|
||||
@ -704,13 +706,26 @@ export const templateVarsChangedInUrl =
|
||||
}
|
||||
}
|
||||
|
||||
// for adhoc variables we don't know which panels that will be impacted
|
||||
if (!isAdHoc(variable)) {
|
||||
getAllAffectedPanelIdsForVariableChange(variable.id, variables, dashboard?.panels ?? []).forEach((id) =>
|
||||
panelIds.add(id)
|
||||
);
|
||||
}
|
||||
|
||||
const promise = variableAdapters.get(variable.type).setValueFromUrl(variable, value);
|
||||
update.push(promise);
|
||||
}
|
||||
|
||||
if (update.length) {
|
||||
await Promise.all(update);
|
||||
events.publish(new VariablesChangedInUrl({ panelIds: [], refreshAll: true }));
|
||||
|
||||
events.publish(
|
||||
new VariablesChangedInUrl({
|
||||
refreshAll: panelIds.size === 0,
|
||||
panelIds: Array.from(panelIds),
|
||||
})
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
import { DashboardState, StoreState } from '../../../types';
|
||||
import { DashboardModel } from '../../dashboard/state';
|
||||
import { DashboardModel, PanelModel } from '../../dashboard/state';
|
||||
import { initialState } from '../../dashboard/state/reducers';
|
||||
import { variableAdapters } from '../adapters';
|
||||
import { createConstantVariableAdapter } from '../constant/adapter';
|
||||
@ -30,9 +30,62 @@ async function getTestContext(urlQueryMap: ExtendedUrlQueryMap = {}, variable: V
|
||||
.build();
|
||||
}
|
||||
|
||||
const variableB = customBuilder()
|
||||
.withId('variableB')
|
||||
.withRootStateKey(key)
|
||||
.withName('variableB')
|
||||
.withCurrent(['B'])
|
||||
.withOptions('A', 'B', 'C')
|
||||
.build();
|
||||
|
||||
const setValueFromUrlMock = jest.fn();
|
||||
variableAdapters.get(variable.type).setValueFromUrl = setValueFromUrlMock;
|
||||
|
||||
const modelJson = {
|
||||
id: 1,
|
||||
type: 'table',
|
||||
maxDataPoints: 100,
|
||||
interval: '5m',
|
||||
showColumns: true,
|
||||
targets: [{ refId: 'A', queryType: '${variable}' }, { noRefId: true }],
|
||||
options: null,
|
||||
fieldConfig: {
|
||||
defaults: {
|
||||
unit: 'mpg',
|
||||
thresholds: {
|
||||
mode: 'absolute',
|
||||
steps: [
|
||||
{ color: 'green', value: null },
|
||||
{ color: 'red', value: 80 },
|
||||
],
|
||||
},
|
||||
},
|
||||
overrides: [
|
||||
{
|
||||
matcher: {
|
||||
id: '1',
|
||||
options: {},
|
||||
},
|
||||
properties: [
|
||||
{
|
||||
id: 'thresholds',
|
||||
value: {
|
||||
mode: 'absolute',
|
||||
steps: [
|
||||
{ color: 'green', value: null },
|
||||
{ color: 'red', value: 80 },
|
||||
],
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
};
|
||||
|
||||
const panelModelA = new PanelModel(modelJson);
|
||||
const panelModelB = new PanelModel({ ...modelJson, id: 2, targets: [{ refId: 'B', queryType: '${variableB}' }] });
|
||||
|
||||
const templateVariableValueUpdatedMock = jest.fn();
|
||||
const startRefreshMock = jest.fn();
|
||||
const dashboard: DashboardState = {
|
||||
@ -41,11 +94,12 @@ async function getTestContext(urlQueryMap: ExtendedUrlQueryMap = {}, variable: V
|
||||
dashboardModel.templateVariableValueUpdated = templateVariableValueUpdatedMock;
|
||||
dashboardModel.startRefresh = startRefreshMock;
|
||||
dashboardModel.templating = { list: [variable] };
|
||||
dashboardModel.panels = [panelModelA, panelModelB];
|
||||
return dashboardModel;
|
||||
},
|
||||
};
|
||||
|
||||
const variables: VariablesState = { variable };
|
||||
const variables: VariablesState = { variable, variableB };
|
||||
const state: Partial<StoreState> = {
|
||||
dashboard,
|
||||
...getPreloadedState(key, { variables }),
|
||||
@ -57,7 +111,7 @@ async function getTestContext(urlQueryMap: ExtendedUrlQueryMap = {}, variable: V
|
||||
|
||||
await thunk(dispatch, getState, undefined);
|
||||
|
||||
return { setValueFromUrlMock, templateVariableValueUpdatedMock, startRefreshMock, variable };
|
||||
return { setValueFromUrlMock, templateVariableValueUpdatedMock, startRefreshMock, variable, variableB };
|
||||
}
|
||||
|
||||
describe('templateVarsChangedInUrl', () => {
|
||||
@ -107,6 +161,20 @@ describe('templateVarsChangedInUrl', () => {
|
||||
expect(setValueFromUrlMock).toHaveBeenCalledWith(variable, 'B');
|
||||
expect(templateVariableValueUpdatedMock).toHaveBeenCalledTimes(1);
|
||||
expect(startRefreshMock).toHaveBeenCalledTimes(1);
|
||||
expect(startRefreshMock).toHaveBeenCalledWith({ refreshAll: false, panelIds: [1] });
|
||||
});
|
||||
|
||||
it('should update URL value and only refresh panels with variableB dependency', async () => {
|
||||
const { setValueFromUrlMock, templateVariableValueUpdatedMock, startRefreshMock, variableB } =
|
||||
await getTestContext({
|
||||
'var-variableB': { value: 'A' },
|
||||
});
|
||||
|
||||
expect(setValueFromUrlMock).toHaveBeenCalledTimes(1);
|
||||
expect(setValueFromUrlMock).toHaveBeenCalledWith(variableB, 'A');
|
||||
expect(templateVariableValueUpdatedMock).toHaveBeenCalledTimes(1);
|
||||
expect(startRefreshMock).toHaveBeenCalledTimes(1);
|
||||
expect(startRefreshMock).toHaveBeenCalledWith({ refreshAll: false, panelIds: [2] });
|
||||
});
|
||||
|
||||
describe('but the values in url query map were removed', () => {
|
||||
|
Loading…
Reference in New Issue
Block a user