From 3db328f516d61caaa3ea7f6a2338395c4624f3de Mon Sep 17 00:00:00 2001 From: Marcus Efraimsson Date: Thu, 1 Feb 2018 16:30:48 +0100 Subject: [PATCH] fix for dashboard/folder url's when having a sub path in root_url config --- .../ManageDashboards/FolderPermissions.tsx | 1 + public/app/core/services/bridge_srv.ts | 23 +++++-------------- public/app/core/specs/bridge_srv.jest.ts | 22 ------------------ public/app/core/specs/location_util.jest.ts | 16 +++++++++++++ public/app/core/utils/location_util.ts | 14 +++++++++++ .../dashboard/folder_dashboards_ctrl.ts | 7 ++++-- public/app/features/panel/solo_panel_ctrl.ts | 4 +++- public/app/routes/dashboard_loaders.ts | 12 ++++++---- 8 files changed, 53 insertions(+), 46 deletions(-) delete mode 100644 public/app/core/specs/bridge_srv.jest.ts create mode 100644 public/app/core/specs/location_util.jest.ts create mode 100644 public/app/core/utils/location_util.ts diff --git a/public/app/containers/ManageDashboards/FolderPermissions.tsx b/public/app/containers/ManageDashboards/FolderPermissions.tsx index e6e788b7585..07700923b54 100644 --- a/public/app/containers/ManageDashboards/FolderPermissions.tsx +++ b/public/app/containers/ManageDashboards/FolderPermissions.tsx @@ -17,6 +17,7 @@ export class FolderPermissions extends Component { loadStore() { const { nav, folder, view } = this.props; 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'); }); } diff --git a/public/app/core/services/bridge_srv.ts b/public/app/core/services/bridge_srv.ts index ed4abb9b894..4a5649a6c52 100644 --- a/public/app/core/services/bridge_srv.ts +++ b/public/app/core/services/bridge_srv.ts @@ -1,30 +1,18 @@ import coreModule from 'app/core/core_module'; -import config from 'app/core/config'; import appEvents from 'app/core/app_events'; import { store } from 'app/stores/store'; import { reaction } from 'mobx'; +import locationUtil from 'app/core/utils/location_util'; // Services that handles angular -> mobx store sync & other react <-> angular sync export class BridgeSrv { - private appSubUrl; private fullPageReloadRoutes; /** @ngInject */ constructor(private $location, private $timeout, private $window, private $rootScope, private $route) { - this.appSubUrl = config.appSubUrl; this.fullPageReloadRoutes = ['/logout']; } - // Angular's $location does not like 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() { this.$rootScope.$on('$routeUpdate', (evt, data) => { let angularUrl = this.$location.url(); @@ -41,17 +29,18 @@ export class BridgeSrv { () => store.view.currentUrl, currentUrl => { let angularUrl = this.$location.url(); - if (angularUrl !== currentUrl) { + const url = locationUtil.stripBaseFromUrl(currentUrl); + if (angularUrl !== url) { 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 => { - const urlWithoutBase = this.stripBaseFromUrl(payload.href); + const urlWithoutBase = locationUtil.stripBaseFromUrl(payload.href); if (this.fullPageReloadRoutes.indexOf(urlWithoutBase) > -1) { this.$window.location.href = payload.href; return; diff --git a/public/app/core/specs/bridge_srv.jest.ts b/public/app/core/specs/bridge_srv.jest.ts deleted file mode 100644 index 2e32f9bd600..00000000000 --- a/public/app/core/specs/bridge_srv.jest.ts +++ /dev/null @@ -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/'); - }); - }); -}); diff --git a/public/app/core/specs/location_util.jest.ts b/public/app/core/specs/location_util.jest.ts new file mode 100644 index 00000000000..c109ab7315a --- /dev/null +++ b/public/app/core/specs/location_util.jest.ts @@ -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/'); + }); + }); +}); diff --git a/public/app/core/utils/location_util.ts b/public/app/core/utils/location_util.ts new file mode 100644 index 00000000000..f8d6aa4ee5f --- /dev/null +++ b/public/app/core/utils/location_util.ts @@ -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, +}; diff --git a/public/app/features/dashboard/folder_dashboards_ctrl.ts b/public/app/features/dashboard/folder_dashboards_ctrl.ts index dd0bf7772d8..8ee942445ae 100644 --- a/public/app/features/dashboard/folder_dashboards_ctrl.ts +++ b/public/app/features/dashboard/folder_dashboards_ctrl.ts @@ -1,4 +1,5 @@ import { FolderPageLoader } from './folder_page_loader'; +import locationUtil from 'app/core/utils/location_util'; export class FolderDashboardsCtrl { navModel: any; @@ -13,8 +14,10 @@ export class FolderDashboardsCtrl { const loader = new FolderPageLoader(this.backendSrv); loader.load(this, this.uid, 'manage-folder-dashboards').then(folder => { - if ($location.path() !== folder.meta.url) { - $location.path(folder.meta.url).replace(); + const url = locationUtil.stripBaseFromUrl(folder.meta.url); + + if (url !== $location.path()) { + $location.path(url).replace(); } }); } diff --git a/public/app/features/panel/solo_panel_ctrl.ts b/public/app/features/panel/solo_panel_ctrl.ts index 575c9e4c3b9..6e1c8a4db65 100644 --- a/public/app/features/panel/solo_panel_ctrl.ts +++ b/public/app/features/panel/solo_panel_ctrl.ts @@ -1,4 +1,5 @@ import angular from 'angular'; +import locationUtil from 'app/core/utils/location_util'; export class SoloPanelCtrl { /** @ngInject */ @@ -17,7 +18,8 @@ export class SoloPanelCtrl { if (!($routeParams.type === 'script' || $routeParams.type === 'snapshot') && !$routeParams.uid) { backendSrv.get(`/api/dashboards/db/${$routeParams.slug}`).then(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; diff --git a/public/app/routes/dashboard_loaders.ts b/public/app/routes/dashboard_loaders.ts index 80e74819069..e17ca6fb054 100644 --- a/public/app/routes/dashboard_loaders.ts +++ b/public/app/routes/dashboard_loaders.ts @@ -1,8 +1,9 @@ import coreModule from 'app/core/core_module'; +import locationUtil from 'app/core/utils/location_util'; export class LoadDashboardCtrl { /** @ngInject */ - constructor($scope, $routeParams, dashboardLoaderSrv, backendSrv, $location) { + constructor($scope, $routeParams, dashboardLoaderSrv, backendSrv, $location, $browser) { $scope.appEvent('dashboard-fetch-start'); if (!$routeParams.uid && !$routeParams.slug) { @@ -22,15 +23,18 @@ export class LoadDashboardCtrl { if (!($routeParams.type === 'script' || $routeParams.type === 'snapshot') && !$routeParams.uid) { backendSrv.get(`/api/dashboards/db/${$routeParams.slug}`).then(res => { if (res) { - $location.path(res.meta.url).replace(); + const url = locationUtil.stripBaseFromUrl(res.meta.url); + $location.path(url).replace(); } }); return; } dashboardLoaderSrv.loadDashboard($routeParams.type, $routeParams.slug, $routeParams.uid).then(function(result) { - if ($location.path() !== result.meta.url) { - $location.path(result.meta.url).replace(); + const url = locationUtil.stripBaseFromUrl(result.meta.url); + + if (url !== $location.path()) { + $location.path(url).replace(); } if ($routeParams.keepRows) {