Commit dd37d003 by Dominik Prokop Committed by GitHub

Links: Assure base url when single stat, panel and data links are built (#21956)

* Assure base url when single stat, panel and data links are built

* Update public/app/features/dashboard/dashgrid/PanelHeader/PanelHeaderCorner.tsx

* Update public/app/features/panel/panellinks/link_srv.ts

* Update public/app/features/panel/panellinks/link_srv.ts

* Update public/app/features/panel/panellinks/link_srv.ts

* Update public/app/features/panel/panellinks/link_srv.ts

* Review updates

* Remove unnecessary code
parent cd680968
......@@ -66,7 +66,7 @@
{
"targetBlank": false,
"title": "Drill it down",
"url": "http://localhost:3000/d/wfTJJL5Wz/datalinks-source?var-seriesName=${__series.name}&var-labelDatacenter=${__series.labels.datacenter}&var-labelDatacenterRegion=${__series.labels[\"datacenter.region\"]}&var-valueTime=${__value.time}&var-valueNumeric=${__value.numeric}&var-valueText=${__value.text}"
"url": "/d/wfTJJL5Wz/datalinks-source?var-seriesName=${__series.name}&var-labelDatacenter=${__series.labels.datacenter}&var-labelDatacenterRegion=${__series.labels[\"datacenter.region\"]}&var-valueTime=${__value.time}&var-valueNumeric=${__value.numeric}&var-valueText=${__value.text}"
}
]
},
......@@ -164,7 +164,7 @@
{
"targetBlank": false,
"title": "Drill it down",
"url": "http://localhost:3000/d/wfTJJL5Wz/datalinks-source?var-seriesName=${__series.name}&var-valueTime=${__value.time}&var-valueNumeric=${__value.numeric}&var-valueText=${__value.text}&var-fieldName=${__field.name}"
"url": "/d/wfTJJL5Wz/datalinks-source?var-seriesName=${__series.name}&var-valueTime=${__value.time}&var-valueNumeric=${__value.numeric}&var-valueText=${__value.text}&var-fieldName=${__field.name}"
}
]
},
......@@ -246,7 +246,7 @@
{
"targetBlank": true,
"title": "Drill it down!",
"url": "http://localhost:3000/d/wfTJJL5Wz/datalinks-source\n?var-fieldName=${__field.name}\n&var-labelDatacenter=${__series.labels.datacenter}\n&var-labelDatacenterRegion=${__series.labels[\"datacenter.region\"]}\n&var-valueNumeric=${__value.numeric}\n&var-valueText=${__value.text}\n&var-valueCalc=${__value.calc}"
"url": "/d/wfTJJL5Wz/datalinks-source\n?var-fieldName=${__field.name}\n&var-labelDatacenter=${__series.labels.datacenter}\n&var-labelDatacenterRegion=${__series.labels[\"datacenter.region\"]}\n&var-valueNumeric=${__value.numeric}\n&var-valueText=${__value.text}\n&var-valueCalc=${__value.calc}"
}
],
"mappings": [
......@@ -307,7 +307,7 @@
"links": [
{
"title": "Drill it down",
"url": "http://localhost:3000/d/wfTJJL5Wz/datalinks-source?var-fieldName=${__field.name}&var-labelDatacenter=${__series.labels.datacenter}&var-labelDatacenterRegion=${__series.labels[\"datacenter.region\"]}&var-valueNumeric=${__value.numeric}&var-valueText=${__value.text}&var-valueCalc=${__value.calc}"
"url": "/d/wfTJJL5Wz/datalinks-source?var-fieldName=${__field.name}&var-labelDatacenter=${__series.labels.datacenter}&var-labelDatacenterRegion=${__series.labels[\"datacenter.region\"]}&var-valueNumeric=${__value.numeric}&var-valueText=${__value.text}&var-valueCalc=${__value.calc}"
}
],
"mappings": [],
......
......@@ -2,7 +2,7 @@ import locationUtil from 'app/core/utils/location_util';
jest.mock('app/core/config', () => {
return {
appSubUrl: '/subUrl',
getConfig: () => ({ appSubUrl: '/subUrl' }),
};
});
......
import config from 'app/core/config';
import { getConfig } from 'app/core/config';
export const stripBaseFromUrl = (url: string): string => {
const appSubUrl = config.appSubUrl;
const appSubUrl = getConfig().appSubUrl;
const stripExtraChars = appSubUrl.endsWith('/') ? 1 : 0;
const urlWithoutBase =
url.length > 0 && url.indexOf(appSubUrl) === 0 ? url.slice(appSubUrl.length - stripExtraChars) : url;
......@@ -9,4 +9,11 @@ export const stripBaseFromUrl = (url: string): string => {
return urlWithoutBase;
};
export default { stripBaseFromUrl };
export const assureBaseUrl = (url: string) => {
if (url.startsWith('/')) {
return `${getConfig().appSubUrl}${stripBaseFromUrl(url)}`;
}
return url;
};
export default { stripBaseFromUrl, assureBaseUrl };
......@@ -2,11 +2,11 @@ import React, { Component } from 'react';
import { renderMarkdown, LinkModelSupplier, ScopedVars } from '@grafana/data';
import { Tooltip, PopoverContent } from '@grafana/ui';
import { getLocationSrv } from '@grafana/runtime';
import { PanelModel } from 'app/features/dashboard/state/PanelModel';
import templateSrv from 'app/features/templating/template_srv';
import { getTimeSrv, TimeSrv } from 'app/features/dashboard/services/TimeSrv';
import { getLocationSrv } from '@grafana/runtime';
import { InspectTab } from '../../components/Inspector/PanelInspector';
enum InfoMode {
......
......@@ -5,6 +5,7 @@ import coreModule from 'app/core/core_module';
import { appendQueryToUrl, toUrlParams } from 'app/core/utils/url';
import { sanitizeUrl } from 'app/core/utils/text';
import { getConfig } from 'app/core/config';
import locationUtil from 'app/core/utils/location_util';
import { VariableSuggestion, VariableOrigin, DataLinkBuiltInVars } from '@grafana/ui';
import {
DataLink,
......@@ -216,7 +217,7 @@ export class LinkSrv implements LinkService {
constructor(private templateSrv: TemplateSrv, private timeSrv: TimeSrv) {}
getLinkUrl(link: any) {
const url = this.templateSrv.replace(link.url || '');
let url = locationUtil.assureBaseUrl(this.templateSrv.replace(link.url || ''));
const params: { [key: string]: any } = {};
if (link.keepTime) {
......@@ -229,7 +230,8 @@ export class LinkSrv implements LinkService {
this.templateSrv.fillVariableValuesForUrl(params);
}
return appendQueryToUrl(url, toUrlParams(params));
url = appendQueryToUrl(url, toUrlParams(params));
return getConfig().disableSanitizeHtml ? url : sanitizeUrl(url);
}
getAnchorInfo(link: any) {
......@@ -266,7 +268,7 @@ export class LinkSrv implements LinkService {
}
const info: LinkModel<T> = {
href: href.replace(/\s|\n/g, ''),
href: locationUtil.assureBaseUrl(href.replace(/\s|\n/g, '')),
title: this.templateSrv.replace(link.title || '', scopedVars),
target: link.targetBlank ? '_blank' : '_self',
origin,
......
......@@ -175,4 +175,39 @@ describe('linkSrv', () => {
}
);
});
describe('Building links with root_url set', () => {
it.each`
url | appSubUrl | expected
${'/d/XXX'} | ${'/grafana'} | ${'/grafana/d/XXX'}
${'/grafana/d/XXX'} | ${'/grafana'} | ${'/grafana/d/XXX'}
${'d/whatever'} | ${'/grafana'} | ${'d/whatever'}
${'/d/XXX'} | ${''} | ${'/d/XXX'}
${'/grafana/d/XXX'} | ${''} | ${'/grafana/d/XXX'}
${'d/whatever'} | ${''} | ${'d/whatever'}
`(
"when link '$url' and config.appSubUrl set to '$appSubUrl' then result should be '$expected'",
({ url, appSubUrl, expected }) => {
updateConfig({
appSubUrl,
});
const link = linkSrv.getDataLinkUIModel(
{
title: 'Any title',
url,
},
{
__value: {
value: { time: dataPointMock.datapoint[0] },
text: 'Value',
},
},
{}
).href;
expect(link).toBe(expected);
}
);
});
});
......@@ -4,6 +4,7 @@ import $ from 'jquery';
import 'vendor/flot/jquery.flot';
import 'vendor/flot/jquery.flot.gauge';
import 'app/features/panel/panellinks/link_srv';
import locationUtil from 'app/core/utils/location_util';
import {
DataFrame,
......@@ -656,7 +657,7 @@ class SingleStatCtrl extends MetricsPanelCtrl {
window.location.href = linkInfo.href;
} else {
$timeout(() => {
$location.url(linkInfo.href);
$location.url(locationUtil.stripBaseFromUrl(linkInfo.href));
});
}
......
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