mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
fix for dashboard/folder url's when having a sub path in root_url config
This commit is contained in:
@@ -17,6 +17,7 @@ export class FolderPermissions extends Component<IContainerProps, any> {
|
|||||||
loadStore() {
|
loadStore() {
|
||||||
const { nav, folder, view } = this.props;
|
const { nav, folder, view } = this.props;
|
||||||
return folder.load(view.routeParams.get('uid') as string).then(res => {
|
return folder.load(view.routeParams.get('uid') as string).then(res => {
|
||||||
|
view.updatePathAndQuery(`${res.meta.url}/permissions`, {}, {});
|
||||||
return nav.initFolderNav(toJS(folder.folder), 'manage-folder-permissions');
|
return nav.initFolderNav(toJS(folder.folder), 'manage-folder-permissions');
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@@ -1,30 +1,18 @@
|
|||||||
import coreModule from 'app/core/core_module';
|
import coreModule from 'app/core/core_module';
|
||||||
import config from 'app/core/config';
|
|
||||||
import appEvents from 'app/core/app_events';
|
import appEvents from 'app/core/app_events';
|
||||||
import { store } from 'app/stores/store';
|
import { store } from 'app/stores/store';
|
||||||
import { reaction } from 'mobx';
|
import { reaction } from 'mobx';
|
||||||
|
import locationUtil from 'app/core/utils/location_util';
|
||||||
|
|
||||||
// Services that handles angular -> mobx store sync & other react <-> angular sync
|
// Services that handles angular -> mobx store sync & other react <-> angular sync
|
||||||
export class BridgeSrv {
|
export class BridgeSrv {
|
||||||
private appSubUrl;
|
|
||||||
private fullPageReloadRoutes;
|
private fullPageReloadRoutes;
|
||||||
|
|
||||||
/** @ngInject */
|
/** @ngInject */
|
||||||
constructor(private $location, private $timeout, private $window, private $rootScope, private $route) {
|
constructor(private $location, private $timeout, private $window, private $rootScope, private $route) {
|
||||||
this.appSubUrl = config.appSubUrl;
|
|
||||||
this.fullPageReloadRoutes = ['/logout'];
|
this.fullPageReloadRoutes = ['/logout'];
|
||||||
}
|
}
|
||||||
|
|
||||||
// Angular's $location does not like <base href...> and absolute urls
|
|
||||||
stripBaseFromUrl(url = '') {
|
|
||||||
const appSubUrl = this.appSubUrl;
|
|
||||||
const stripExtraChars = appSubUrl.endsWith('/') ? 1 : 0;
|
|
||||||
const urlWithoutBase =
|
|
||||||
url.length > 0 && url.indexOf(appSubUrl) === 0 ? url.slice(appSubUrl.length - stripExtraChars) : url;
|
|
||||||
|
|
||||||
return urlWithoutBase;
|
|
||||||
}
|
|
||||||
|
|
||||||
init() {
|
init() {
|
||||||
this.$rootScope.$on('$routeUpdate', (evt, data) => {
|
this.$rootScope.$on('$routeUpdate', (evt, data) => {
|
||||||
let angularUrl = this.$location.url();
|
let angularUrl = this.$location.url();
|
||||||
@@ -41,17 +29,18 @@ export class BridgeSrv {
|
|||||||
() => store.view.currentUrl,
|
() => store.view.currentUrl,
|
||||||
currentUrl => {
|
currentUrl => {
|
||||||
let angularUrl = this.$location.url();
|
let angularUrl = this.$location.url();
|
||||||
if (angularUrl !== currentUrl) {
|
const url = locationUtil.stripBaseFromUrl(currentUrl);
|
||||||
|
if (angularUrl !== url) {
|
||||||
this.$timeout(() => {
|
this.$timeout(() => {
|
||||||
this.$location.url(currentUrl);
|
this.$location.url(url);
|
||||||
});
|
});
|
||||||
console.log('store updating angular $location.url', currentUrl);
|
console.log('store updating angular $location.url', url);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
appEvents.on('location-change', payload => {
|
appEvents.on('location-change', payload => {
|
||||||
const urlWithoutBase = this.stripBaseFromUrl(payload.href);
|
const urlWithoutBase = locationUtil.stripBaseFromUrl(payload.href);
|
||||||
if (this.fullPageReloadRoutes.indexOf(urlWithoutBase) > -1) {
|
if (this.fullPageReloadRoutes.indexOf(urlWithoutBase) > -1) {
|
||||||
this.$window.location.href = payload.href;
|
this.$window.location.href = payload.href;
|
||||||
return;
|
return;
|
||||||
|
@@ -1,22 +0,0 @@
|
|||||||
import { BridgeSrv } from 'app/core/services/bridge_srv';
|
|
||||||
|
|
||||||
jest.mock('app/core/config', () => {
|
|
||||||
return {
|
|
||||||
appSubUrl: '/subUrl',
|
|
||||||
};
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('BridgeSrv', () => {
|
|
||||||
let searchSrv;
|
|
||||||
|
|
||||||
beforeEach(() => {
|
|
||||||
searchSrv = new BridgeSrv(null, null, null, null, null);
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('With /subUrl as appSubUrl', () => {
|
|
||||||
it('/subUrl should be stripped', () => {
|
|
||||||
const urlWithoutMaster = searchSrv.stripBaseFromUrl('/subUrl/grafana/');
|
|
||||||
expect(urlWithoutMaster).toBe('/grafana/');
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
16
public/app/core/specs/location_util.jest.ts
Normal file
16
public/app/core/specs/location_util.jest.ts
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
import locationUtil from 'app/core/utils/location_util';
|
||||||
|
|
||||||
|
jest.mock('app/core/config', () => {
|
||||||
|
return {
|
||||||
|
appSubUrl: '/subUrl',
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('locationUtil', () => {
|
||||||
|
describe('With /subUrl as appSubUrl', () => {
|
||||||
|
it('/subUrl should be stripped', () => {
|
||||||
|
const urlWithoutMaster = locationUtil.stripBaseFromUrl('/subUrl/grafana/');
|
||||||
|
expect(urlWithoutMaster).toBe('/grafana/');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
14
public/app/core/utils/location_util.ts
Normal file
14
public/app/core/utils/location_util.ts
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
import config from 'app/core/config';
|
||||||
|
|
||||||
|
const _stripBaseFromUrl = url => {
|
||||||
|
const appSubUrl = config.appSubUrl;
|
||||||
|
const stripExtraChars = appSubUrl.endsWith('/') ? 1 : 0;
|
||||||
|
const urlWithoutBase =
|
||||||
|
url.length > 0 && url.indexOf(appSubUrl) === 0 ? url.slice(appSubUrl.length - stripExtraChars) : url;
|
||||||
|
|
||||||
|
return urlWithoutBase;
|
||||||
|
};
|
||||||
|
|
||||||
|
export default {
|
||||||
|
stripBaseFromUrl: _stripBaseFromUrl,
|
||||||
|
};
|
@@ -1,4 +1,5 @@
|
|||||||
import { FolderPageLoader } from './folder_page_loader';
|
import { FolderPageLoader } from './folder_page_loader';
|
||||||
|
import locationUtil from 'app/core/utils/location_util';
|
||||||
|
|
||||||
export class FolderDashboardsCtrl {
|
export class FolderDashboardsCtrl {
|
||||||
navModel: any;
|
navModel: any;
|
||||||
@@ -13,8 +14,10 @@ export class FolderDashboardsCtrl {
|
|||||||
const loader = new FolderPageLoader(this.backendSrv);
|
const loader = new FolderPageLoader(this.backendSrv);
|
||||||
|
|
||||||
loader.load(this, this.uid, 'manage-folder-dashboards').then(folder => {
|
loader.load(this, this.uid, 'manage-folder-dashboards').then(folder => {
|
||||||
if ($location.path() !== folder.meta.url) {
|
const url = locationUtil.stripBaseFromUrl(folder.meta.url);
|
||||||
$location.path(folder.meta.url).replace();
|
|
||||||
|
if (url !== $location.path()) {
|
||||||
|
$location.path(url).replace();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@@ -1,4 +1,5 @@
|
|||||||
import angular from 'angular';
|
import angular from 'angular';
|
||||||
|
import locationUtil from 'app/core/utils/location_util';
|
||||||
|
|
||||||
export class SoloPanelCtrl {
|
export class SoloPanelCtrl {
|
||||||
/** @ngInject */
|
/** @ngInject */
|
||||||
@@ -17,7 +18,8 @@ export class SoloPanelCtrl {
|
|||||||
if (!($routeParams.type === 'script' || $routeParams.type === 'snapshot') && !$routeParams.uid) {
|
if (!($routeParams.type === 'script' || $routeParams.type === 'snapshot') && !$routeParams.uid) {
|
||||||
backendSrv.get(`/api/dashboards/db/${$routeParams.slug}`).then(res => {
|
backendSrv.get(`/api/dashboards/db/${$routeParams.slug}`).then(res => {
|
||||||
if (res) {
|
if (res) {
|
||||||
$location.path(res.meta.url.replace('/d/', '/d-solo/'));
|
const url = locationUtil.stripBaseFromUrl(res.meta.url.replace('/d/', '/d-solo/'));
|
||||||
|
$location.path(url).replace();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
return;
|
return;
|
||||||
|
@@ -1,8 +1,9 @@
|
|||||||
import coreModule from 'app/core/core_module';
|
import coreModule from 'app/core/core_module';
|
||||||
|
import locationUtil from 'app/core/utils/location_util';
|
||||||
|
|
||||||
export class LoadDashboardCtrl {
|
export class LoadDashboardCtrl {
|
||||||
/** @ngInject */
|
/** @ngInject */
|
||||||
constructor($scope, $routeParams, dashboardLoaderSrv, backendSrv, $location) {
|
constructor($scope, $routeParams, dashboardLoaderSrv, backendSrv, $location, $browser) {
|
||||||
$scope.appEvent('dashboard-fetch-start');
|
$scope.appEvent('dashboard-fetch-start');
|
||||||
|
|
||||||
if (!$routeParams.uid && !$routeParams.slug) {
|
if (!$routeParams.uid && !$routeParams.slug) {
|
||||||
@@ -22,15 +23,18 @@ export class LoadDashboardCtrl {
|
|||||||
if (!($routeParams.type === 'script' || $routeParams.type === 'snapshot') && !$routeParams.uid) {
|
if (!($routeParams.type === 'script' || $routeParams.type === 'snapshot') && !$routeParams.uid) {
|
||||||
backendSrv.get(`/api/dashboards/db/${$routeParams.slug}`).then(res => {
|
backendSrv.get(`/api/dashboards/db/${$routeParams.slug}`).then(res => {
|
||||||
if (res) {
|
if (res) {
|
||||||
$location.path(res.meta.url).replace();
|
const url = locationUtil.stripBaseFromUrl(res.meta.url);
|
||||||
|
$location.path(url).replace();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
dashboardLoaderSrv.loadDashboard($routeParams.type, $routeParams.slug, $routeParams.uid).then(function(result) {
|
dashboardLoaderSrv.loadDashboard($routeParams.type, $routeParams.slug, $routeParams.uid).then(function(result) {
|
||||||
if ($location.path() !== result.meta.url) {
|
const url = locationUtil.stripBaseFromUrl(result.meta.url);
|
||||||
$location.path(result.meta.url).replace();
|
|
||||||
|
if (url !== $location.path()) {
|
||||||
|
$location.path(url).replace();
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($routeParams.keepRows) {
|
if ($routeParams.keepRows) {
|
||||||
|
Reference in New Issue
Block a user