diff --git a/src/App.tsx b/src/App.tsx index 4bb759e8..6fb8f95f 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -28,6 +28,7 @@ import NotificationMiddleware, { NotificationMiddlewareContext, } from './services/NotificationMiddleware' import { CustomError, errorTypes } from './utils/CustomError' +import { getProjectStorePath, isProjectsPath, RoutePaths } from './utils/routes' import { joinUrl, normalizeServerUrl } from './utils/url' function ParametrizedCaseViewer({ @@ -105,8 +106,8 @@ function _createClientMapping({ } }) } else { - if (window.location.pathname.includes('/projects/')) { - const pathname = window.location.pathname.split('/study/')[0] + if (isProjectsPath(window.location.pathname)) { + const pathname = getProjectStorePath(window.location.pathname) const pathUrl = `${gcpBaseUrl}${pathname}/dicomWeb` serverSettings.url = pathUrl } @@ -564,7 +565,7 @@ class App extends React.Component { @@ -586,7 +587,7 @@ class App extends React.Component { } /> @@ -615,7 +616,7 @@ class App extends React.Component { } /> @@ -644,7 +645,7 @@ class App extends React.Component { } /> diff --git a/src/auth/OidcManager.tsx b/src/auth/OidcManager.tsx index d1d4fedc..4dfd97fd 100644 --- a/src/auth/OidcManager.tsx +++ b/src/auth/OidcManager.tsx @@ -5,6 +5,7 @@ import NotificationMiddleware, { NotificationMiddlewareContext, } from '../services/NotificationMiddleware' import { CustomError, errorTypes } from '../utils/CustomError' +import { buildLogoutPath } from '../utils/routes' import { isAuthorizationCodeInUrl } from '../utils/url' import type { AuthManager, SignInCallback, User } from '.' @@ -63,7 +64,7 @@ export default class OidcManager implements AuthManager { loadUserInfo: true, automaticSilentRenew: true, revokeAccessTokenOnSignout: true, - post_logout_redirect_uri: `${baseUri}/logout`, + post_logout_redirect_uri: buildLogoutPath(baseUri), }) if ( settings.endSessionEndpoint !== null && @@ -95,7 +96,7 @@ export default class OidcManager implements AuthManager { loadUserInfo: true, automaticSilentRenew: true, revokeAccessTokenOnSignout: true, - post_logout_redirect_uri: `${baseUri}/logout`, + post_logout_redirect_uri: buildLogoutPath(baseUri), metadata, }) } diff --git a/src/components/CaseViewer.tsx b/src/components/CaseViewer.tsx index 8fbc6985..c8dbf033 100644 --- a/src/components/CaseViewer.tsx +++ b/src/components/CaseViewer.tsx @@ -22,6 +22,14 @@ import { seriesUidFromSlide, } from '../utils/recoverSeriesInstanceUID' import { type RouteComponentProps, withRouter } from '../utils/router' +import { + buildSeriesPath, + hasSeriesInPath, + isProjectsPath, + parseSeriesInstanceUID, + RoutePaths, + withSeriesInProjectPath, +} from '../utils/routes' import ClinicalTrial from './ClinicalTrial' import Patient from './Patient' import SlideList from './SlideList' @@ -262,22 +270,14 @@ function Viewer(props: ViewerProps): JSX.Element | null { seriesInstanceUID: string }): void => { console.info(`switch to series "${seriesInstanceUID}"`) - let urlPath = `/studies/${studyInstanceUID}/series/${seriesInstanceUID}` + let urlPath = buildSeriesPath(studyInstanceUID, seriesInstanceUID) - if (location.pathname.includes('/projects/')) { - urlPath = location.pathname - if (!location.pathname.includes('/series/')) { - urlPath += `/series/${seriesInstanceUID}` - } else { - urlPath = urlPath.replace( - /\/series\/[^/]+/, - `/series/${seriesInstanceUID}`, - ) - } + if (isProjectsPath(location.pathname)) { + urlPath = withSeriesInProjectPath(location.pathname, seriesInstanceUID) } if ( - location.pathname.includes('/series/') && + hasSeriesInPath(location.pathname) && location.search !== null && location.search !== undefined ) { @@ -307,11 +307,8 @@ function Viewer(props: ViewerProps): JSX.Element | null { * the first slide contained in the study. */ let selectedSeriesInstanceUID: string - if (location.pathname.includes('series/')) { - const seriesFragment = location.pathname.split('series/')[1] - const seriesFromPath = seriesFragment.includes('/') - ? seriesFragment.split('/')[0] - : seriesFragment + const seriesFromPath = parseSeriesInstanceUID(location.pathname) + if (seriesFromPath !== '') { const slideForPath = findSeriesSlide(slides, seriesFromPath) selectedSeriesInstanceUID = slideForPath !== undefined @@ -399,7 +396,7 @@ function Viewer(props: ViewerProps): JSX.Element | null { = { container: { textAlign: 'center', @@ -335,12 +338,7 @@ class Header extends React.Component { } } const pathNorm = trimmedUrl.startsWith('/') ? trimmedUrl : `/${trimmedUrl}` - return ( - pathNorm.includes('/projects/') && - pathNorm.includes('/locations/') && - pathNorm.includes('/datasets/') && - pathNorm.includes('/dicomStores/') - ) + return isGcpDicomStorePath(pathNorm) } static handleUserMenuButtonClick(e: React.SyntheticEvent): void { @@ -489,13 +487,9 @@ class Header extends React.Component { handleDicomTagBrowserButtonClick = (): void => { const width = window.innerWidth - 200 - let seriesInstanceUID = '' - if (this.props.location.pathname.includes('series/')) { - const seriesFragment = this.props.location.pathname.split('series/')[1] - seriesInstanceUID = seriesFragment.includes('/') - ? seriesFragment.split('/')[0] - : seriesFragment - } + const seriesInstanceUID = parseSeriesInstanceUID( + this.props.location.pathname, + ) Modal.info({ title: 'DICOM Tag Browser', @@ -753,9 +747,7 @@ class Header extends React.Component { ) - const showDicomTagBrowser = DICOM_TAG_BROWSER_PATHS.some((path) => - this.props.location.pathname.includes(path), - ) + const showDicomTagBrowser = isViewerPath(this.props.location.pathname) const dicomTagBrowserButton = showDicomTagBrowser ? (