Commit 0f037454 by Ryan McKinley Committed by GitHub

Templating: update variables on location changed (#21480)

parent 5a31e485
import { UrlQueryMap } from '@grafana/runtime';
import { findTemplateVarChanges } from './bridge_srv';
describe('when checking template variables', () => {
it('detect adding/removing a variable', () => {
const a: UrlQueryMap = {};
const b: UrlQueryMap = {
'var-xyz': 'hello',
aaa: 'ignore me',
};
expect(findTemplateVarChanges(b, a)).toEqual({ 'var-xyz': 'hello' });
expect(findTemplateVarChanges(a, b)).toEqual({ 'var-xyz': '' });
});
});
...@@ -6,10 +6,15 @@ import { updateLocation } from 'app/core/actions'; ...@@ -6,10 +6,15 @@ import { updateLocation } from 'app/core/actions';
import { ITimeoutService, ILocationService, IWindowService } from 'angular'; import { ITimeoutService, ILocationService, IWindowService } from 'angular';
import { CoreEvents } from 'app/types'; import { CoreEvents } from 'app/types';
import { GrafanaRootScope } from 'app/routes/GrafanaCtrl'; import { GrafanaRootScope } from 'app/routes/GrafanaCtrl';
import { UrlQueryMap } from '@grafana/runtime';
import { getDashboardSrv } from 'app/features/dashboard/services/DashboardSrv';
import { VariableSrv } from 'app/features/templating/all';
// Services that handles angular -> redux store sync & other react <-> angular sync // Services that handles angular -> redux store sync & other react <-> angular sync
export class BridgeSrv { export class BridgeSrv {
private fullPageReloadRoutes: string[]; private fullPageReloadRoutes: string[];
private lastQuery: UrlQueryMap = {};
private lastPath = '';
/** @ngInject */ /** @ngInject */
constructor( constructor(
...@@ -17,7 +22,8 @@ export class BridgeSrv { ...@@ -17,7 +22,8 @@ export class BridgeSrv {
private $timeout: ITimeoutService, private $timeout: ITimeoutService,
private $window: IWindowService, private $window: IWindowService,
private $rootScope: GrafanaRootScope, private $rootScope: GrafanaRootScope,
private $route: any private $route: any,
private variableSrv: VariableSrv
) { ) {
this.fullPageReloadRoutes = ['/logout']; this.fullPageReloadRoutes = ['/logout'];
} }
...@@ -62,6 +68,21 @@ export class BridgeSrv { ...@@ -62,6 +68,21 @@ export class BridgeSrv {
}); });
console.log('store updating angular $location.url', url); console.log('store updating angular $location.url', url);
} }
// Check for template variable changes on a dashboard
if (state.location.path === this.lastPath) {
const changes = findTemplateVarChanges(state.location.query, this.lastQuery);
if (changes) {
const dash = getDashboardSrv().getCurrent();
if (dash) {
this.variableSrv.templateVarsChangedInUrl(changes);
}
}
this.lastQuery = state.location.query;
} else {
this.lastQuery = {};
}
this.lastPath = state.location.path;
}); });
appEvents.on(CoreEvents.locationChange, payload => { appEvents.on(CoreEvents.locationChange, payload => {
...@@ -79,4 +100,28 @@ export class BridgeSrv { ...@@ -79,4 +100,28 @@ 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];
count++;
}
}
for (const key in old) {
if (!key.startsWith('var-')) {
continue;
}
if (!query[key]) {
changes[key] = ''; // removed
count++;
}
}
return count ? changes : undefined;
}
coreModule.service('bridgeSrv', BridgeSrv); coreModule.service('bridgeSrv', BridgeSrv);
...@@ -13,6 +13,7 @@ import { DashboardModel } from 'app/features/dashboard/state/DashboardModel'; ...@@ -13,6 +13,7 @@ import { DashboardModel } from 'app/features/dashboard/state/DashboardModel';
// Types // Types
import { TimeRange } from '@grafana/data'; import { TimeRange } from '@grafana/data';
import { CoreEvents } from 'app/types'; import { CoreEvents } from 'app/types';
import { UrlQueryMap } from '@grafana/runtime';
export class VariableSrv { export class VariableSrv {
dashboard: DashboardModel; dashboard: DashboardModel;
...@@ -302,6 +303,22 @@ export class VariableSrv { ...@@ -302,6 +303,22 @@ export class VariableSrv {
return this.variableUpdated(variable); return this.variableUpdated(variable);
} }
templateVarsChangedInUrl(vars: UrlQueryMap) {
const update: Array<Promise<any>> = [];
for (const v of this.variables) {
const key = `var-${v.name}`;
if (vars.hasOwnProperty(key)) {
update.push(v.setValueFromUrl(vars[key]));
}
}
if (update.length) {
Promise.all(update).then(() => {
this.dashboard.templateVariableValueUpdated();
this.dashboard.startRefresh();
});
}
}
updateUrlParamsWithCurrentVariables() { updateUrlParamsWithCurrentVariables() {
// update url // update url
const params = this.$location.search(); const params = this.$location.search();
......
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