Commit cace879c by Torkel Ödegaard Committed by GitHub

Templating: Fixed recursive queries triggered when switching dashboard settings view (#26137)

* Templating: Fixed recursive queries triggered when going into dashboard settings

* Fixed unused import

* use locationUtil
parent 8ab5d2dd
......@@ -40,4 +40,14 @@ describe('when checking template variables', () => {
expect(findTemplateVarChanges(b, a)).toBeUndefined();
expect(findTemplateVarChanges(a, b)).toBeUndefined();
});
it('then should ignore empty array values', () => {
const a: UrlQueryMap = {
'var-adhoc': [],
};
const b: UrlQueryMap = {};
expect(findTemplateVarChanges(b, a)).toBeUndefined();
expect(findTemplateVarChanges(a, b)).toBeUndefined();
});
});
......@@ -8,6 +8,7 @@ import { GrafanaRootScope } from 'app/routes/GrafanaCtrl';
import { locationUtil, UrlQueryMap } from '@grafana/data';
import { getDashboardSrv } from 'app/features/dashboard/services/DashboardSrv';
import { templateVarsChangedInUrl } from 'app/features/variables/state/actions';
import { isArray, isEqual } from 'lodash';
// Services that handles angular -> redux store sync & other react <-> angular sync
export class BridgeSrv {
......@@ -15,6 +16,7 @@ export class BridgeSrv {
private lastQuery: UrlQueryMap = {};
private lastPath = '';
private angularUrl: string;
private lastUrl: string | null = null;
/** @ngInject */
constructor(
......@@ -62,6 +64,11 @@ export class BridgeSrv {
const state = store.getState();
const url = state.location.url;
// No url change ignore redux store change
if (url === this.lastUrl) {
return;
}
if (this.angularUrl !== url) {
// store angular url right away as otherwise we end up syncing multiple times
this.angularUrl = url;
......@@ -90,7 +97,9 @@ export class BridgeSrv {
} else {
this.lastQuery = {};
}
this.lastPath = state.location.path;
this.lastUrl = state.location.url;
});
appEvents.on(CoreEvents.locationChange, payload => {
......@@ -111,19 +120,45 @@ export class BridgeSrv {
export function findTemplateVarChanges(query: UrlQueryMap, old: UrlQueryMap): UrlQueryMap | undefined {
let count = 0;
const changes: UrlQueryMap = {};
for (const key in query) {
if (!key.startsWith('var-')) {
continue;
}
if (query[key] !== old[key]) {
changes[key] = query[key];
let oldValue = getUrlValueForComparison(old[key]);
let newValue = getUrlValueForComparison(query[key]);
if (!isEqual(newValue, oldValue)) {
changes[key] = newValue;
count++;
}
}
function getUrlValueForComparison(value: any): any {
if (isArray(value)) {
if (value.length === 0) {
value = undefined;
} else if (value.length === 1) {
value = value[0];
}
}
return value;
}
for (const key in old) {
if (!key.startsWith('var-')) {
continue;
}
const value = old[key];
// ignore empty array values
if (isArray(value) && value.length === 0) {
continue;
}
if (!query.hasOwnProperty(key)) {
changes[key] = ''; // removed
count++;
......
import $ from 'jquery';
import _ from 'lodash';
import angular, { ILocationService, IScope } from 'angular';
import { selectors } from '@grafana/e2e-selectors';
import { appEvents, contextSrv, coreModule } from 'app/core/core';
import { DashboardModel } from '../../state/DashboardModel';
import { getConfig } from 'app/core/config';
import { DashboardSrv } from '../../services/DashboardSrv';
import { CoreEvents } from 'app/types';
import { GrafanaRootScope } from 'app/routes/GrafanaCtrl';
import { AppEvents, locationUtil, TimeZone } from '@grafana/data';
import { AppEvents, locationUtil, TimeZone, urlUtil } from '@grafana/data';
import { promiseToDigest } from '../../../../core/utils/promiseToDigest';
import { deleteDashboard } from 'app/features/manage-dashboards/state/actions';
......@@ -121,8 +119,7 @@ export class SettingsCtrl {
const url = this.$location.path();
for (const section of this.sections) {
const sectionParams = _.defaults({ editview: section.id }, params);
section.url = getConfig().appSubUrl + url + '?' + $.param(sectionParams);
section.url = locationUtil.assureBaseUrl(urlUtil.renderUrl(url, { ...params, editview: section.id }));
}
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment