fix: routerBasename setting (#4891)

This commit is contained in:
Bill Wallace 2025-03-27 16:47:16 -04:00 committed by GitHub
parent c368d763b0
commit 459b0d223a
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
40 changed files with 299 additions and 229 deletions

View File

@ -7,7 +7,7 @@ server {
location / { location / {
root /usr/share/nginx/html; root /usr/share/nginx/html;
index index.html index.htm; index index.html index.htm;
try_files $uri $uri/ /index.html; try_files $uri $uri/ ${PUBLIC_URL}index.html;
add_header Cross-Origin-Resource-Policy same-origin; add_header Cross-Origin-Resource-Policy same-origin;
proxy_set_header Host $host; proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Real-IP $remote_addr;

View File

@ -2,12 +2,11 @@
if [ -n "$SSL_PORT" ] if [ -n "$SSL_PORT" ]
then then
envsubst '${SSL_PORT}:${PORT}' < /usr/src/default.ssl.conf.template > /etc/nginx/conf.d/default.conf envsubst '${SSL_PORT}:${PORT}' < /usr/src/default.ssl.conf.template | envsubst '${PUBLIC_URL}' > /etc/nginx/conf.d/default.conf
else else
envsubst '${PORT}' < /usr/src/default.conf.template > /etc/nginx/conf.d/default.conf envsubst '${PORT}:${PUBLIC_URL}' < /usr/src/default.conf.template > /etc/nginx/conf.d/default.conf
fi fi
if [ -n "$APP_CONFIG" ]; then if [ -n "$APP_CONFIG" ]; then
echo "$APP_CONFIG" > /usr/share/nginx/html${PUBLIC_URL}app-config.js echo "$APP_CONFIG" > /usr/share/nginx/html${PUBLIC_URL}app-config.js
echo "Using custom APP_CONFIG environment variable" echo "Using custom APP_CONFIG environment variable"

View File

@ -62,9 +62,6 @@ RUN bun pm cache rm
RUN bun install RUN bun install
# Copy the local directory # Copy the local directory
COPY --link --exclude=yarn.lock --exclude=package.json --exclude=Dockerfile . . COPY --link --exclude=yarn.lock --exclude=package.json --exclude=Dockerfile . .
# Do a second install to finalize things after the copy
RUN bun run show:config
RUN bun install
# Build here # Build here
# After install it should hopefully be stable until the local directory changes # After install it should hopefully be stable until the local directory changes
@ -72,6 +69,7 @@ ENV QUICK_BUILD true
# ENV GENERATE_SOURCEMAP=false # ENV GENERATE_SOURCEMAP=false
ARG APP_CONFIG=config/default.js ARG APP_CONFIG=config/default.js
ARG PUBLIC_URL=/ ARG PUBLIC_URL=/
ENV PUBLIC_URL=${PUBLIC_URL}
RUN bun run show:config RUN bun run show:config
RUN bun run build RUN bun run build
@ -84,16 +82,19 @@ RUN ./.docker/compressDist.sh
# which runs Nginx using Alpine Linux # which runs Nginx using Alpine Linux
FROM nginxinc/nginx-unprivileged:1.27-alpine as final FROM nginxinc/nginx-unprivileged:1.27-alpine as final
#RUN apk add --no-cache bash #RUN apk add --no-cache bash
ARG PORT=80
ENV PORT=${PORT}
ARG PUBLIC_URL=/ ARG PUBLIC_URL=/
ENV PUBLIC_URL=${PUBLIC_URL} ENV PUBLIC_URL=${PUBLIC_URL}
ARG PORT=80
ENV PORT=${PORT}
RUN rm /etc/nginx/conf.d/default.conf RUN rm /etc/nginx/conf.d/default.conf
USER nginx USER nginx
COPY --chown=nginx:nginx .docker/Viewer-v3.x /usr/src COPY --chown=nginx:nginx .docker/Viewer-v3.x /usr/src
RUN chmod 777 /usr/src/entrypoint.sh RUN chmod 777 /usr/src/entrypoint.sh
COPY --from=builder /usr/src/app/platform/app/dist /usr/share/nginx/html${PUBLIC_URL} COPY --from=builder /usr/src/app/platform/app/dist /usr/share/nginx/html${PUBLIC_URL}
COPY --from=builder /usr/src/app/platform/app/dist/index.html /usr/share/nginx/html # Copy paths that are renamed/redirected generally
# Microscopy libraries depend on root level include, so must be copied
COPY --from=builder /usr/src/app/platform/app/dist/dicom-microscopy-viewer /usr/share/nginx/html/dicom-microscopy-viewer
# In entrypoint.sh, app-config.js might be overwritten, so chmod it to be writeable. # In entrypoint.sh, app-config.js might be overwritten, so chmod it to be writeable.
# The nginx user cannot chmod it, so change to root. # The nginx user cannot chmod it, so change to root.
USER root USER root

268
bun.lock
View File

@ -33,7 +33,7 @@
}, },
"addOns/externals/devDependencies": { "addOns/externals/devDependencies": {
"name": "@externals/devDependencies", "name": "@externals/devDependencies",
"version": "3.10.0-beta.138", "version": "3.10.0-beta.139",
"dependencies": { "dependencies": {
"@babel/runtime": "^7.20.13", "@babel/runtime": "^7.20.13",
"@kitware/vtk.js": "32.12.0", "@kitware/vtk.js": "32.12.0",
@ -121,14 +121,14 @@
}, },
"addOns/externals/dicom-microscopy-viewer": { "addOns/externals/dicom-microscopy-viewer": {
"name": "@externals/dicom-microscopy-viewer", "name": "@externals/dicom-microscopy-viewer",
"version": "3.10.0-beta.138", "version": "3.10.0-beta.139",
"dependencies": { "dependencies": {
"dicom-microscopy-viewer": "^0.46.1", "dicom-microscopy-viewer": "^0.46.1",
}, },
}, },
"extensions/cornerstone": { "extensions/cornerstone": {
"name": "@ohif/extension-cornerstone", "name": "@ohif/extension-cornerstone",
"version": "3.10.0-beta.138", "version": "3.10.0-beta.139",
"dependencies": { "dependencies": {
"@babel/runtime": "^7.20.13", "@babel/runtime": "^7.20.13",
"@cornerstonejs/adapters": "^3.7.16", "@cornerstonejs/adapters": "^3.7.16",
@ -153,8 +153,8 @@
"@cornerstonejs/codec-openjpeg": "^1.2.4", "@cornerstonejs/codec-openjpeg": "^1.2.4",
"@cornerstonejs/codec-openjph": "^2.4.5", "@cornerstonejs/codec-openjph": "^2.4.5",
"@cornerstonejs/dicom-image-loader": "^3.7.16", "@cornerstonejs/dicom-image-loader": "^3.7.16",
"@ohif/core": "3.10.0-beta.138", "@ohif/core": "3.10.0-beta.139",
"@ohif/ui": "3.10.0-beta.138", "@ohif/ui": "3.10.0-beta.139",
"dcmjs": "*", "dcmjs": "*",
"dicom-parser": "^1.8.21", "dicom-parser": "^1.8.21",
"hammerjs": "^2.0.8", "hammerjs": "^2.0.8",
@ -166,7 +166,7 @@
}, },
"extensions/cornerstone-dicom-pmap": { "extensions/cornerstone-dicom-pmap": {
"name": "@ohif/extension-cornerstone-dicom-pmap", "name": "@ohif/extension-cornerstone-dicom-pmap",
"version": "3.10.0-beta.138", "version": "3.10.0-beta.139",
"dependencies": { "dependencies": {
"@babel/runtime": "^7.20.13", "@babel/runtime": "^7.20.13",
"@cornerstonejs/adapters": "^3.7.16", "@cornerstonejs/adapters": "^3.7.16",
@ -175,10 +175,10 @@
"react-color": "^2.19.3", "react-color": "^2.19.3",
}, },
"peerDependencies": { "peerDependencies": {
"@ohif/core": "3.10.0-beta.138", "@ohif/core": "3.10.0-beta.139",
"@ohif/extension-cornerstone": "3.10.0-beta.138", "@ohif/extension-cornerstone": "3.10.0-beta.139",
"@ohif/extension-default": "3.10.0-beta.138", "@ohif/extension-default": "3.10.0-beta.139",
"@ohif/i18n": "3.10.0-beta.138", "@ohif/i18n": "3.10.0-beta.139",
"prop-types": "^15.6.2", "prop-types": "^15.6.2",
"react": "^18.3.1", "react": "^18.3.1",
"react-dom": "^18.3.1", "react-dom": "^18.3.1",
@ -189,16 +189,16 @@
}, },
"extensions/cornerstone-dicom-rt": { "extensions/cornerstone-dicom-rt": {
"name": "@ohif/extension-cornerstone-dicom-rt", "name": "@ohif/extension-cornerstone-dicom-rt",
"version": "3.10.0-beta.138", "version": "3.10.0-beta.139",
"dependencies": { "dependencies": {
"@babel/runtime": "^7.20.13", "@babel/runtime": "^7.20.13",
"react-color": "^2.19.3", "react-color": "^2.19.3",
}, },
"peerDependencies": { "peerDependencies": {
"@ohif/core": "3.10.0-beta.138", "@ohif/core": "3.10.0-beta.139",
"@ohif/extension-cornerstone": "3.10.0-beta.138", "@ohif/extension-cornerstone": "3.10.0-beta.139",
"@ohif/extension-default": "3.10.0-beta.138", "@ohif/extension-default": "3.10.0-beta.139",
"@ohif/i18n": "3.10.0-beta.138", "@ohif/i18n": "3.10.0-beta.139",
"prop-types": "^15.6.2", "prop-types": "^15.6.2",
"react": "^18.3.1", "react": "^18.3.1",
"react-dom": "^18.3.1", "react-dom": "^18.3.1",
@ -209,7 +209,7 @@
}, },
"extensions/cornerstone-dicom-seg": { "extensions/cornerstone-dicom-seg": {
"name": "@ohif/extension-cornerstone-dicom-seg", "name": "@ohif/extension-cornerstone-dicom-seg",
"version": "3.10.0-beta.138", "version": "3.10.0-beta.139",
"dependencies": { "dependencies": {
"@babel/runtime": "^7.20.13", "@babel/runtime": "^7.20.13",
"@cornerstonejs/adapters": "^3.7.16", "@cornerstonejs/adapters": "^3.7.16",
@ -218,10 +218,10 @@
"react-color": "^2.19.3", "react-color": "^2.19.3",
}, },
"peerDependencies": { "peerDependencies": {
"@ohif/core": "3.10.0-beta.138", "@ohif/core": "3.10.0-beta.139",
"@ohif/extension-cornerstone": "3.10.0-beta.138", "@ohif/extension-cornerstone": "3.10.0-beta.139",
"@ohif/extension-default": "3.10.0-beta.138", "@ohif/extension-default": "3.10.0-beta.139",
"@ohif/i18n": "3.10.0-beta.138", "@ohif/i18n": "3.10.0-beta.139",
"prop-types": "^15.6.2", "prop-types": "^15.6.2",
"react": "^18.3.1", "react": "^18.3.1",
"react-dom": "^18.3.1", "react-dom": "^18.3.1",
@ -232,7 +232,7 @@
}, },
"extensions/cornerstone-dicom-sr": { "extensions/cornerstone-dicom-sr": {
"name": "@ohif/extension-cornerstone-dicom-sr", "name": "@ohif/extension-cornerstone-dicom-sr",
"version": "3.10.0-beta.138", "version": "3.10.0-beta.139",
"dependencies": { "dependencies": {
"@babel/runtime": "^7.20.13", "@babel/runtime": "^7.20.13",
"@cornerstonejs/adapters": "^3.7.16", "@cornerstonejs/adapters": "^3.7.16",
@ -241,10 +241,10 @@
"classnames": "^2.3.2", "classnames": "^2.3.2",
}, },
"peerDependencies": { "peerDependencies": {
"@ohif/core": "3.10.0-beta.138", "@ohif/core": "3.10.0-beta.139",
"@ohif/extension-cornerstone": "3.10.0-beta.138", "@ohif/extension-cornerstone": "3.10.0-beta.139",
"@ohif/extension-measurement-tracking": "3.10.0-beta.138", "@ohif/extension-measurement-tracking": "3.10.0-beta.139",
"@ohif/ui": "3.10.0-beta.138", "@ohif/ui": "3.10.0-beta.139",
"dcmjs": "*", "dcmjs": "*",
"dicom-parser": "^1.8.9", "dicom-parser": "^1.8.9",
"hammerjs": "^2.0.8", "hammerjs": "^2.0.8",
@ -254,7 +254,7 @@
}, },
"extensions/cornerstone-dynamic-volume": { "extensions/cornerstone-dynamic-volume": {
"name": "@ohif/extension-cornerstone-dynamic-volume", "name": "@ohif/extension-cornerstone-dynamic-volume",
"version": "3.10.0-beta.138", "version": "3.10.0-beta.139",
"dependencies": { "dependencies": {
"@babel/runtime": "^7.20.13", "@babel/runtime": "^7.20.13",
"@cornerstonejs/core": "^3.7.16", "@cornerstonejs/core": "^3.7.16",
@ -262,11 +262,11 @@
"classnames": "^2.3.2", "classnames": "^2.3.2",
}, },
"peerDependencies": { "peerDependencies": {
"@ohif/core": "3.10.0-beta.138", "@ohif/core": "3.10.0-beta.139",
"@ohif/extension-cornerstone": "3.10.0-beta.138", "@ohif/extension-cornerstone": "3.10.0-beta.139",
"@ohif/extension-default": "3.10.0-beta.138", "@ohif/extension-default": "3.10.0-beta.139",
"@ohif/i18n": "3.10.0-beta.138", "@ohif/i18n": "3.10.0-beta.139",
"@ohif/ui": "3.10.0-beta.138", "@ohif/ui": "3.10.0-beta.139",
"dcmjs": "*", "dcmjs": "*",
"dicom-parser": "^1.8.21", "dicom-parser": "^1.8.21",
"hammerjs": "^2.0.8", "hammerjs": "^2.0.8",
@ -276,7 +276,7 @@
}, },
"extensions/default": { "extensions/default": {
"name": "@ohif/extension-default", "name": "@ohif/extension-default",
"version": "3.10.0-beta.138", "version": "3.10.0-beta.139",
"dependencies": { "dependencies": {
"@babel/runtime": "^7.20.13", "@babel/runtime": "^7.20.13",
"@cornerstonejs/calculate-suv": "^1.1.0", "@cornerstonejs/calculate-suv": "^1.1.0",
@ -284,8 +284,8 @@
"lodash.uniqby": "^4.7.0", "lodash.uniqby": "^4.7.0",
}, },
"peerDependencies": { "peerDependencies": {
"@ohif/core": "3.10.0-beta.138", "@ohif/core": "3.10.0-beta.139",
"@ohif/i18n": "3.10.0-beta.138", "@ohif/i18n": "3.10.0-beta.139",
"dcmjs": "*", "dcmjs": "*",
"dicomweb-client": "^0.10.4", "dicomweb-client": "^0.10.4",
"prop-types": "^15.6.2", "prop-types": "^15.6.2",
@ -299,7 +299,7 @@
}, },
"extensions/dicom-microscopy": { "extensions/dicom-microscopy": {
"name": "@ohif/extension-dicom-microscopy", "name": "@ohif/extension-dicom-microscopy",
"version": "3.10.0-beta.138", "version": "3.10.0-beta.139",
"dependencies": { "dependencies": {
"@babel/runtime": "^7.20.13", "@babel/runtime": "^7.20.13",
"@cornerstonejs/codec-charls": "^1.2.3", "@cornerstonejs/codec-charls": "^1.2.3",
@ -310,10 +310,10 @@
"mathjs": "^12.4.2", "mathjs": "^12.4.2",
}, },
"peerDependencies": { "peerDependencies": {
"@ohif/core": "3.10.0-beta.138", "@ohif/core": "3.10.0-beta.139",
"@ohif/extension-default": "3.10.0-beta.138", "@ohif/extension-default": "3.10.0-beta.139",
"@ohif/i18n": "3.10.0-beta.138", "@ohif/i18n": "3.10.0-beta.139",
"@ohif/ui": "3.10.0-beta.138", "@ohif/ui": "3.10.0-beta.139",
"prop-types": "^15.6.2", "prop-types": "^15.6.2",
"react": "^18.3.1", "react": "^18.3.1",
"react-dom": "^18.3.1", "react-dom": "^18.3.1",
@ -324,14 +324,14 @@
}, },
"extensions/dicom-pdf": { "extensions/dicom-pdf": {
"name": "@ohif/extension-dicom-pdf", "name": "@ohif/extension-dicom-pdf",
"version": "3.10.0-beta.138", "version": "3.10.0-beta.139",
"dependencies": { "dependencies": {
"@babel/runtime": "^7.20.13", "@babel/runtime": "^7.20.13",
"classnames": "^2.3.2", "classnames": "^2.3.2",
}, },
"peerDependencies": { "peerDependencies": {
"@ohif/core": "3.10.0-beta.138", "@ohif/core": "3.10.0-beta.139",
"@ohif/ui": "3.10.0-beta.138", "@ohif/ui": "3.10.0-beta.139",
"dcmjs": "*", "dcmjs": "*",
"dicom-parser": "^1.8.9", "dicom-parser": "^1.8.9",
"hammerjs": "^2.0.8", "hammerjs": "^2.0.8",
@ -341,14 +341,14 @@
}, },
"extensions/dicom-video": { "extensions/dicom-video": {
"name": "@ohif/extension-dicom-video", "name": "@ohif/extension-dicom-video",
"version": "3.10.0-beta.138", "version": "3.10.0-beta.139",
"dependencies": { "dependencies": {
"@babel/runtime": "^7.20.13", "@babel/runtime": "^7.20.13",
"classnames": "^2.3.2", "classnames": "^2.3.2",
}, },
"peerDependencies": { "peerDependencies": {
"@ohif/core": "3.10.0-beta.138", "@ohif/core": "3.10.0-beta.139",
"@ohif/ui": "3.10.0-beta.138", "@ohif/ui": "3.10.0-beta.139",
"dcmjs": "*", "dcmjs": "*",
"dicom-parser": "^1.8.9", "dicom-parser": "^1.8.9",
"hammerjs": "^2.0.8", "hammerjs": "^2.0.8",
@ -358,20 +358,20 @@
}, },
"extensions/measurement-tracking": { "extensions/measurement-tracking": {
"name": "@ohif/extension-measurement-tracking", "name": "@ohif/extension-measurement-tracking",
"version": "3.10.0-beta.138", "version": "3.10.0-beta.139",
"dependencies": { "dependencies": {
"@babel/runtime": "^7.20.13", "@babel/runtime": "^7.20.13",
"@ohif/ui": "3.10.0-beta.138", "@ohif/ui": "3.10.0-beta.139",
"@xstate/react": "^3.2.2", "@xstate/react": "^3.2.2",
"xstate": "^4.10.0", "xstate": "^4.10.0",
}, },
"peerDependencies": { "peerDependencies": {
"@cornerstonejs/core": "^3.7.16", "@cornerstonejs/core": "^3.7.16",
"@cornerstonejs/tools": "^3.7.16", "@cornerstonejs/tools": "^3.7.16",
"@ohif/core": "3.10.0-beta.138", "@ohif/core": "3.10.0-beta.139",
"@ohif/extension-cornerstone-dicom-sr": "3.10.0-beta.138", "@ohif/extension-cornerstone-dicom-sr": "3.10.0-beta.139",
"@ohif/extension-default": "3.10.0-beta.138", "@ohif/extension-default": "3.10.0-beta.139",
"@ohif/ui": "3.10.0-beta.138", "@ohif/ui": "3.10.0-beta.139",
"classnames": "^2.3.2", "classnames": "^2.3.2",
"dcmjs": "*", "dcmjs": "*",
"lodash.debounce": "^4.0.8", "lodash.debounce": "^4.0.8",
@ -384,14 +384,14 @@
}, },
"extensions/test-extension": { "extensions/test-extension": {
"name": "@ohif/extension-test", "name": "@ohif/extension-test",
"version": "3.10.0-beta.138", "version": "3.10.0-beta.139",
"dependencies": { "dependencies": {
"@babel/runtime": "^7.20.13", "@babel/runtime": "^7.20.13",
"classnames": "^2.3.2", "classnames": "^2.3.2",
}, },
"peerDependencies": { "peerDependencies": {
"@ohif/core": "3.10.0-beta.138", "@ohif/core": "3.10.0-beta.139",
"@ohif/ui": "3.10.0-beta.138", "@ohif/ui": "3.10.0-beta.139",
"dcmjs": "0.38.0", "dcmjs": "0.38.0",
"dicom-parser": "^1.8.9", "dicom-parser": "^1.8.9",
"hammerjs": "^2.0.8", "hammerjs": "^2.0.8",
@ -401,14 +401,14 @@
}, },
"extensions/tmtv": { "extensions/tmtv": {
"name": "@ohif/extension-tmtv", "name": "@ohif/extension-tmtv",
"version": "3.10.0-beta.138", "version": "3.10.0-beta.139",
"dependencies": { "dependencies": {
"@babel/runtime": "^7.20.13", "@babel/runtime": "^7.20.13",
"classnames": "^2.3.2", "classnames": "^2.3.2",
}, },
"peerDependencies": { "peerDependencies": {
"@ohif/core": "3.10.0-beta.138", "@ohif/core": "3.10.0-beta.139",
"@ohif/ui": "3.10.0-beta.138", "@ohif/ui": "3.10.0-beta.139",
"dcmjs": "*", "dcmjs": "*",
"dicom-parser": "^1.8.9", "dicom-parser": "^1.8.9",
"hammerjs": "^2.0.8", "hammerjs": "^2.0.8",
@ -418,7 +418,7 @@
}, },
"modes/basic-dev-mode": { "modes/basic-dev-mode": {
"name": "@ohif/mode-basic-dev-mode", "name": "@ohif/mode-basic-dev-mode",
"version": "3.10.0-beta.138", "version": "3.10.0-beta.139",
"dependencies": { "dependencies": {
"@babel/runtime": "^7.20.13", "@babel/runtime": "^7.20.13",
"i18next": "^17.0.3", "i18next": "^17.0.3",
@ -428,17 +428,17 @@
"webpack-merge": "^5.7.3", "webpack-merge": "^5.7.3",
}, },
"peerDependencies": { "peerDependencies": {
"@ohif/core": "3.10.0-beta.138", "@ohif/core": "3.10.0-beta.139",
"@ohif/extension-cornerstone": "3.10.0-beta.138", "@ohif/extension-cornerstone": "3.10.0-beta.139",
"@ohif/extension-cornerstone-dicom-sr": "3.10.0-beta.138", "@ohif/extension-cornerstone-dicom-sr": "3.10.0-beta.139",
"@ohif/extension-default": "3.10.0-beta.138", "@ohif/extension-default": "3.10.0-beta.139",
"@ohif/extension-dicom-pdf": "3.10.0-beta.138", "@ohif/extension-dicom-pdf": "3.10.0-beta.139",
"@ohif/extension-dicom-video": "3.10.0-beta.138", "@ohif/extension-dicom-video": "3.10.0-beta.139",
}, },
}, },
"modes/basic-test-mode": { "modes/basic-test-mode": {
"name": "@ohif/mode-test", "name": "@ohif/mode-test",
"version": "3.10.0-beta.138", "version": "3.10.0-beta.139",
"dependencies": { "dependencies": {
"@babel/runtime": "^7.20.13", "@babel/runtime": "^7.20.13",
"i18next": "^17.0.3", "i18next": "^17.0.3",
@ -448,19 +448,19 @@
"webpack-merge": "^5.7.3", "webpack-merge": "^5.7.3",
}, },
"peerDependencies": { "peerDependencies": {
"@ohif/core": "3.10.0-beta.138", "@ohif/core": "3.10.0-beta.139",
"@ohif/extension-cornerstone": "3.10.0-beta.138", "@ohif/extension-cornerstone": "3.10.0-beta.139",
"@ohif/extension-cornerstone-dicom-sr": "3.10.0-beta.138", "@ohif/extension-cornerstone-dicom-sr": "3.10.0-beta.139",
"@ohif/extension-default": "3.10.0-beta.138", "@ohif/extension-default": "3.10.0-beta.139",
"@ohif/extension-dicom-pdf": "3.10.0-beta.138", "@ohif/extension-dicom-pdf": "3.10.0-beta.139",
"@ohif/extension-dicom-video": "3.10.0-beta.138", "@ohif/extension-dicom-video": "3.10.0-beta.139",
"@ohif/extension-measurement-tracking": "3.10.0-beta.138", "@ohif/extension-measurement-tracking": "3.10.0-beta.139",
"@ohif/extension-test": "3.10.0-beta.138", "@ohif/extension-test": "3.10.0-beta.139",
}, },
}, },
"modes/longitudinal": { "modes/longitudinal": {
"name": "@ohif/mode-longitudinal", "name": "@ohif/mode-longitudinal",
"version": "3.10.0-beta.138", "version": "3.10.0-beta.139",
"dependencies": { "dependencies": {
"@babel/runtime": "^7.20.13", "@babel/runtime": "^7.20.13",
"i18next": "^17.0.3", "i18next": "^17.0.3",
@ -470,32 +470,32 @@
"webpack-merge": "^5.7.3", "webpack-merge": "^5.7.3",
}, },
"peerDependencies": { "peerDependencies": {
"@ohif/core": "3.10.0-beta.138", "@ohif/core": "3.10.0-beta.139",
"@ohif/extension-cornerstone": "3.10.0-beta.138", "@ohif/extension-cornerstone": "3.10.0-beta.139",
"@ohif/extension-cornerstone-dicom-rt": "3.10.0-beta.138", "@ohif/extension-cornerstone-dicom-rt": "3.10.0-beta.139",
"@ohif/extension-cornerstone-dicom-seg": "3.10.0-beta.138", "@ohif/extension-cornerstone-dicom-seg": "3.10.0-beta.139",
"@ohif/extension-cornerstone-dicom-sr": "3.10.0-beta.138", "@ohif/extension-cornerstone-dicom-sr": "3.10.0-beta.139",
"@ohif/extension-default": "3.10.0-beta.138", "@ohif/extension-default": "3.10.0-beta.139",
"@ohif/extension-dicom-pdf": "3.10.0-beta.138", "@ohif/extension-dicom-pdf": "3.10.0-beta.139",
"@ohif/extension-dicom-video": "3.10.0-beta.138", "@ohif/extension-dicom-video": "3.10.0-beta.139",
"@ohif/extension-measurement-tracking": "3.10.0-beta.138", "@ohif/extension-measurement-tracking": "3.10.0-beta.139",
}, },
}, },
"modes/microscopy": { "modes/microscopy": {
"name": "@ohif/mode-microscopy", "name": "@ohif/mode-microscopy",
"version": "3.10.0-beta.138", "version": "3.10.0-beta.139",
"dependencies": { "dependencies": {
"@babel/runtime": "^7.20.13", "@babel/runtime": "^7.20.13",
"i18next": "^17.0.3", "i18next": "^17.0.3",
}, },
"peerDependencies": { "peerDependencies": {
"@ohif/core": "3.10.0-beta.138", "@ohif/core": "3.10.0-beta.139",
"@ohif/extension-dicom-microscopy": "3.10.0-beta.138", "@ohif/extension-dicom-microscopy": "3.10.0-beta.139",
}, },
}, },
"modes/preclinical-4d": { "modes/preclinical-4d": {
"name": "@ohif/mode-preclinical-4d", "name": "@ohif/mode-preclinical-4d",
"version": "3.10.0-beta.138", "version": "3.10.0-beta.139",
"dependencies": { "dependencies": {
"@babel/runtime": "^7.20.13", "@babel/runtime": "^7.20.13",
}, },
@ -504,17 +504,17 @@
"webpack-merge": "^5.7.3", "webpack-merge": "^5.7.3",
}, },
"peerDependencies": { "peerDependencies": {
"@ohif/core": "3.10.0-beta.138", "@ohif/core": "3.10.0-beta.139",
"@ohif/extension-cornerstone": "3.10.0-beta.138", "@ohif/extension-cornerstone": "3.10.0-beta.139",
"@ohif/extension-cornerstone-dicom-seg": "3.10.0-beta.138", "@ohif/extension-cornerstone-dicom-seg": "3.10.0-beta.139",
"@ohif/extension-cornerstone-dynamic-volume": "3.10.0-beta.138", "@ohif/extension-cornerstone-dynamic-volume": "3.10.0-beta.139",
"@ohif/extension-default": "3.10.0-beta.138", "@ohif/extension-default": "3.10.0-beta.139",
"@ohif/extension-tmtv": "3.10.0-beta.138", "@ohif/extension-tmtv": "3.10.0-beta.139",
}, },
}, },
"modes/segmentation": { "modes/segmentation": {
"name": "@ohif/mode-segmentation", "name": "@ohif/mode-segmentation",
"version": "3.10.0-beta.138", "version": "3.10.0-beta.139",
"dependencies": { "dependencies": {
"@babel/runtime": "^7.20.13", "@babel/runtime": "^7.20.13",
"i18next": "^17.0.3", "i18next": "^17.0.3",
@ -546,19 +546,19 @@
"webpack-merge": "^5.7.3", "webpack-merge": "^5.7.3",
}, },
"peerDependencies": { "peerDependencies": {
"@ohif/core": "3.10.0-beta.138", "@ohif/core": "3.10.0-beta.139",
"@ohif/extension-cornerstone": "3.10.0-beta.138", "@ohif/extension-cornerstone": "3.10.0-beta.139",
"@ohif/extension-cornerstone-dicom-rt": "3.10.0-beta.138", "@ohif/extension-cornerstone-dicom-rt": "3.10.0-beta.139",
"@ohif/extension-cornerstone-dicom-seg": "3.10.0-beta.138", "@ohif/extension-cornerstone-dicom-seg": "3.10.0-beta.139",
"@ohif/extension-cornerstone-dicom-sr": "3.10.0-beta.138", "@ohif/extension-cornerstone-dicom-sr": "3.10.0-beta.139",
"@ohif/extension-default": "3.10.0-beta.138", "@ohif/extension-default": "3.10.0-beta.139",
"@ohif/extension-dicom-pdf": "3.10.0-beta.138", "@ohif/extension-dicom-pdf": "3.10.0-beta.139",
"@ohif/extension-dicom-video": "3.10.0-beta.138", "@ohif/extension-dicom-video": "3.10.0-beta.139",
}, },
}, },
"modes/tmtv": { "modes/tmtv": {
"name": "@ohif/mode-tmtv", "name": "@ohif/mode-tmtv",
"version": "3.10.0-beta.138", "version": "3.10.0-beta.139",
"dependencies": { "dependencies": {
"@babel/runtime": "^7.20.13", "@babel/runtime": "^7.20.13",
"i18next": "^17.0.3", "i18next": "^17.0.3",
@ -568,18 +568,18 @@
"webpack-merge": "^5.7.3", "webpack-merge": "^5.7.3",
}, },
"peerDependencies": { "peerDependencies": {
"@ohif/core": "3.10.0-beta.138", "@ohif/core": "3.10.0-beta.139",
"@ohif/extension-cornerstone": "3.10.0-beta.138", "@ohif/extension-cornerstone": "3.10.0-beta.139",
"@ohif/extension-cornerstone-dicom-sr": "3.10.0-beta.138", "@ohif/extension-cornerstone-dicom-sr": "3.10.0-beta.139",
"@ohif/extension-default": "3.10.0-beta.138", "@ohif/extension-default": "3.10.0-beta.139",
"@ohif/extension-dicom-pdf": "3.10.0-beta.138", "@ohif/extension-dicom-pdf": "3.10.0-beta.139",
"@ohif/extension-dicom-video": "3.10.0-beta.138", "@ohif/extension-dicom-video": "3.10.0-beta.139",
"@ohif/extension-measurement-tracking": "3.10.0-beta.138", "@ohif/extension-measurement-tracking": "3.10.0-beta.139",
}, },
}, },
"platform/app": { "platform/app": {
"name": "@ohif/app", "name": "@ohif/app",
"version": "3.10.0-beta.138", "version": "3.10.0-beta.139",
"dependencies": { "dependencies": {
"@babel/runtime": "^7.20.13", "@babel/runtime": "^7.20.13",
"@cornerstonejs/codec-charls": "^1.2.3", "@cornerstonejs/codec-charls": "^1.2.3",
@ -588,23 +588,23 @@
"@cornerstonejs/codec-openjph": "^2.4.5", "@cornerstonejs/codec-openjph": "^2.4.5",
"@cornerstonejs/dicom-image-loader": "^3.7.16", "@cornerstonejs/dicom-image-loader": "^3.7.16",
"@emotion/serialize": "^1.1.3", "@emotion/serialize": "^1.1.3",
"@ohif/core": "3.10.0-beta.138", "@ohif/core": "3.10.0-beta.139",
"@ohif/extension-cornerstone": "3.10.0-beta.138", "@ohif/extension-cornerstone": "3.10.0-beta.139",
"@ohif/extension-cornerstone-dicom-rt": "3.10.0-beta.138", "@ohif/extension-cornerstone-dicom-rt": "3.10.0-beta.139",
"@ohif/extension-cornerstone-dicom-seg": "3.10.0-beta.138", "@ohif/extension-cornerstone-dicom-seg": "3.10.0-beta.139",
"@ohif/extension-cornerstone-dicom-sr": "3.10.0-beta.138", "@ohif/extension-cornerstone-dicom-sr": "3.10.0-beta.139",
"@ohif/extension-default": "3.10.0-beta.138", "@ohif/extension-default": "3.10.0-beta.139",
"@ohif/extension-dicom-microscopy": "3.10.0-beta.138", "@ohif/extension-dicom-microscopy": "3.10.0-beta.139",
"@ohif/extension-dicom-pdf": "3.10.0-beta.138", "@ohif/extension-dicom-pdf": "3.10.0-beta.139",
"@ohif/extension-dicom-video": "3.10.0-beta.138", "@ohif/extension-dicom-video": "3.10.0-beta.139",
"@ohif/extension-test": "3.10.0-beta.138", "@ohif/extension-test": "3.10.0-beta.139",
"@ohif/i18n": "3.10.0-beta.138", "@ohif/i18n": "3.10.0-beta.139",
"@ohif/mode-basic-dev-mode": "3.10.0-beta.138", "@ohif/mode-basic-dev-mode": "3.10.0-beta.139",
"@ohif/mode-longitudinal": "3.10.0-beta.138", "@ohif/mode-longitudinal": "3.10.0-beta.139",
"@ohif/mode-microscopy": "3.10.0-beta.138", "@ohif/mode-microscopy": "3.10.0-beta.139",
"@ohif/mode-test": "3.10.0-beta.138", "@ohif/mode-test": "3.10.0-beta.139",
"@ohif/ui": "3.10.0-beta.138", "@ohif/ui": "3.10.0-beta.139",
"@ohif/ui-next": "3.10.0-beta.138", "@ohif/ui-next": "3.10.0-beta.139",
"@svgr/webpack": "^8.1.0", "@svgr/webpack": "^8.1.0",
"@types/react": "^18.3.3", "@types/react": "^18.3.3",
"classnames": "^2.3.2", "classnames": "^2.3.2",
@ -645,7 +645,7 @@
}, },
"platform/cli": { "platform/cli": {
"name": "@ohif/cli", "name": "@ohif/cli",
"version": "3.10.0-beta.138", "version": "3.10.0-beta.139",
"bin": { "bin": {
"ohif-cli": "src/index.js", "ohif-cli": "src/index.js",
}, },
@ -669,7 +669,7 @@
}, },
"platform/core": { "platform/core": {
"name": "@ohif/core", "name": "@ohif/core",
"version": "3.10.0-beta.138", "version": "3.10.0-beta.139",
"dependencies": { "dependencies": {
"@babel/runtime": "^7.20.13", "@babel/runtime": "^7.20.13",
"dcmjs": "*", "dcmjs": "*",
@ -695,14 +695,14 @@
"@cornerstonejs/codec-openjpeg": "^1.2.4", "@cornerstonejs/codec-openjpeg": "^1.2.4",
"@cornerstonejs/codec-openjph": "^2.4.5", "@cornerstonejs/codec-openjph": "^2.4.5",
"@cornerstonejs/dicom-image-loader": "^3.7.16", "@cornerstonejs/dicom-image-loader": "^3.7.16",
"@ohif/ui": "3.10.0-beta.138", "@ohif/ui": "3.10.0-beta.139",
"cornerstone-math": "0.1.9", "cornerstone-math": "0.1.9",
"dicom-parser": "^1.8.21", "dicom-parser": "^1.8.21",
}, },
}, },
"platform/i18n": { "platform/i18n": {
"name": "@ohif/i18n", "name": "@ohif/i18n",
"version": "3.10.0-beta.138", "version": "3.10.0-beta.139",
"dependencies": { "dependencies": {
"@babel/runtime": "^7.20.13", "@babel/runtime": "^7.20.13",
"i18next-locize-backend": "^2.0.0", "i18next-locize-backend": "^2.0.0",
@ -727,7 +727,7 @@
}, },
"platform/ui": { "platform/ui": {
"name": "@ohif/ui", "name": "@ohif/ui",
"version": "3.10.0-beta.138", "version": "3.10.0-beta.139",
"dependencies": { "dependencies": {
"@testing-library/react": "^13.1.0", "@testing-library/react": "^13.1.0",
"browser-detect": "^0.2.28", "browser-detect": "^0.2.28",
@ -787,7 +787,7 @@
}, },
"platform/ui-next": { "platform/ui-next": {
"name": "@ohif/ui-next", "name": "@ohif/ui-next",
"version": "3.10.0-beta.138", "version": "3.10.0-beta.139",
"dependencies": { "dependencies": {
"@radix-ui/react-accordion": "^1.2.0", "@radix-ui/react-accordion": "^1.2.0",
"@radix-ui/react-checkbox": "^1.1.1", "@radix-ui/react-checkbox": "^1.1.1",

View File

@ -7,7 +7,7 @@ import { useSystem } from '@ohif/core';
import { Toolbar } from '../Toolbar/Toolbar'; import { Toolbar } from '../Toolbar/Toolbar';
import HeaderPatientInfo from './HeaderPatientInfo'; import HeaderPatientInfo from './HeaderPatientInfo';
import { PatientInfoVisibility } from './HeaderPatientInfo/HeaderPatientInfo'; import { PatientInfoVisibility } from './HeaderPatientInfo/HeaderPatientInfo';
import { preserveQueryParameters, publicUrl } from '@ohif/app'; import { preserveQueryParameters } from '@ohif/app';
function ViewerHeader({ appConfig }: withAppTypes<{ appConfig: AppTypes.Config }>) { function ViewerHeader({ appConfig }: withAppTypes<{ appConfig: AppTypes.Config }>) {
const { servicesManager, extensionManager, commandsManager } = useSystem(); const { servicesManager, extensionManager, commandsManager } = useSystem();
@ -30,7 +30,7 @@ function ViewerHeader({ appConfig }: withAppTypes<{ appConfig: AppTypes.Config }
preserveQueryParameters(searchQuery); preserveQueryParameters(searchQuery);
navigate({ navigate({
pathname: publicUrl, pathname: '/',
search: decodeURIComponent(searchQuery.toString()), search: decodeURIComponent(searchQuery.toString()),
}); });
}; };

View File

@ -153,6 +153,12 @@ module.exports = (env, argv) => {
}, },
proxy: { proxy: {
'/dicomweb': 'http://localhost:5000', '/dicomweb': 'http://localhost:5000',
'/dicom-microscopy-viewer': {
target: 'http://localhost:3000',
pathRewrite: {
'^/dicom-microscopy-viewer': `/${PUBLIC_URL}/dicom-microscopy-viewer`,
},
},
}, },
static: [ static: [
{ {

View File

@ -1,7 +1,6 @@
const pluginConfig = require('../pluginConfig.json'); const pluginConfig = require('../pluginConfig.json');
const fs = require('fs'); const fs = require('fs');
const os = require('os'); const os = require('os');
const glob = require('glob');
const autogenerationDisclaimer = ` const autogenerationDisclaimer = `
// THIS FILE IS AUTOGENERATED AS PART OF THE EXTENSION AND MODE PLUGIN PROCESS. // THIS FILE IS AUTOGENERATED AS PART OF THE EXTENSION AND MODE PLUGIN PROCESS.
@ -9,6 +8,12 @@ const autogenerationDisclaimer = `
const extractName = val => (typeof val === 'string' ? val : val.packageName); const extractName = val => (typeof val === 'string' ? val : val.packageName);
const publicURL = process.env.PUBLIC_URL || '/';
function isAbsolutePath(path) {
return path.startsWith('http') || path.startsWith('/');
}
function constructLines(input, categoryName) { function constructLines(input, categoryName) {
let pluginCount = 0; let pluginCount = 0;
@ -72,7 +77,7 @@ function getRuntimeLoadModesExtensions(modules) {
if (module.importPath) { if (module.importPath) {
dynamicLoad.push( dynamicLoad.push(
` if( module==="${packageName}") {`, ` if( module==="${packageName}") {`,
` const imported = await window.browserImportFunction('${module.importPath}');`, ` const imported = await window.browserImportFunction('${isAbsolutePath(module.importPath) ? '' : publicURL}${module.importPath}');`,
' return ' + ' return ' +
(module.globalName (module.globalName
? `window["${module.globalName}"];` ? `window["${module.globalName}"];`

View File

@ -1,7 +1,7 @@
/** @type {AppTypes.Config} */ /** @type {AppTypes.Config} */
window.config = { window.config = {
routerBasename: '/', routerBasename: null,
extensions: [], extensions: [],
modes: [], modes: [],
showStudyList: true, showStudyList: true,

View File

@ -1,6 +1,6 @@
/** @type {AppTypes.Config} */ /** @type {AppTypes.Config} */
window.config = { window.config = {
routerBasename: '/', routerBasename: null,
extensions: [], extensions: [],
modes: ['@ohif/mode-test'], modes: ['@ohif/mode-test'],
showStudyList: true, showStudyList: true,

View File

@ -2,7 +2,7 @@
window.config = { window.config = {
name: 'config/default.js', name: 'config/default.js',
routerBasename: '/', routerBasename: null,
// whiteLabeling: {}, // whiteLabeling: {},
extensions: [], extensions: [],
modes: [], modes: [],

View File

@ -1,6 +1,6 @@
/** @type {AppTypes.Config} */ /** @type {AppTypes.Config} */
window.config = { window.config = {
routerBasename: '/', routerBasename: null,
// whiteLabeling: {}, // whiteLabeling: {},
extensions: [], extensions: [],
modes: [], modes: [],

View File

@ -1,6 +1,6 @@
/** @type {AppTypes.Config} */ /** @type {AppTypes.Config} */
window.config = { window.config = {
routerBasename: '/', routerBasename: null,
modes: [], modes: [],
extensions: [], extensions: [],
showStudyList: true, showStudyList: true,

View File

@ -1,6 +1,6 @@
/** @type {AppTypes.Config} */ /** @type {AppTypes.Config} */
window.config = { window.config = {
routerBasename: '/', routerBasename: null,
showStudyList: true, showStudyList: true,
extensions: [], extensions: [],
modes: [], modes: [],

View File

@ -1,6 +1,6 @@
/** @type {AppTypes.Config} */ /** @type {AppTypes.Config} */
window.config = { window.config = {
routerBasename: '/', routerBasename: null,
showStudyList: true, showStudyList: true,
extensions: [], extensions: [],
modes: [], modes: [],

View File

@ -1,6 +1,6 @@
/** @type {AppTypes.Config} */ /** @type {AppTypes.Config} */
window.config = { window.config = {
routerBasename: '/', routerBasename: null,
extensions: [], extensions: [],
modes: [], modes: [],
showStudyList: true, showStudyList: true,

View File

@ -1,6 +1,6 @@
/** @type {AppTypes.Config} */ /** @type {AppTypes.Config} */
window.config = { window.config = {
routerBasename: '/', routerBasename: null,
extensions: [], extensions: [],
modes: [], modes: [],
showStudyList: true, showStudyList: true,

View File

@ -1,6 +1,6 @@
/** @type {AppTypes.Config} */ /** @type {AppTypes.Config} */
window.config = { window.config = {
routerBasename: '/', routerBasename: null,
showStudyList: true, showStudyList: true,
extensions: [], extensions: [],
modes: [], modes: [],

View File

@ -1,6 +1,6 @@
/** @type {AppTypes.Config} */ /** @type {AppTypes.Config} */
window.config = { window.config = {
routerBasename: '/', routerBasename: null,
showStudyList: true, showStudyList: true,
extensions: [], extensions: [],
modes: [], modes: [],

View File

@ -17,7 +17,7 @@ if (window.location.search === '?today') {
/** @type {AppTypes.Config} */ /** @type {AppTypes.Config} */
window.config = { window.config = {
routerBasename: '/', routerBasename: null,
extensions: [], extensions: [],
modes: ['@ohif/mode-test'], modes: ['@ohif/mode-test'],
showStudyList: true, showStudyList: true,

View File

@ -1,6 +1,6 @@
/** @type {AppTypes.Config} */ /** @type {AppTypes.Config} */
window.config = { window.config = {
routerBasename: '/', routerBasename: null,
enableGoogleCloudAdapter: false, enableGoogleCloudAdapter: false,
// below flag is for performance reasons, but it might not work for all servers // below flag is for performance reasons, but it might not work for all servers
showWarningMessageForCrossOrigin: true, showWarningMessageForCrossOrigin: true,

View File

@ -1,6 +1,6 @@
/** @type {AppTypes.Config} */ /** @type {AppTypes.Config} */
window.config = { window.config = {
routerBasename: '/', routerBasename: null,
enableGoogleCloudAdapter: true, enableGoogleCloudAdapter: true,
// below flag is for performance reasons, but it might not work for all servers // below flag is for performance reasons, but it might not work for all servers
showWarningMessageForCrossOrigin: true, showWarningMessageForCrossOrigin: true,

View File

@ -2,7 +2,7 @@
window.config = { window.config = {
name: 'config/kheops.js', name: 'config/kheops.js',
routerBasename: '/', routerBasename: null,
extensions: [], extensions: [],
modes: ['@ohif/mode-test'], modes: ['@ohif/mode-test'],
customizationService: {}, customizationService: {},

View File

@ -1,6 +1,6 @@
/** @type {AppTypes.Config} */ /** @type {AppTypes.Config} */
window.config = { window.config = {
routerBasename: '/', routerBasename: null,
showStudyList: true, showStudyList: true,
extensions: [], extensions: [],
modes: [], modes: [],

View File

@ -1,6 +1,6 @@
/** @type {AppTypes.Config} */ /** @type {AppTypes.Config} */
window.config = { window.config = {
routerBasename: '/', routerBasename: null,
extensions: [], extensions: [],
modes: [], modes: [],
showStudyList: true, showStudyList: true,

View File

@ -1,6 +1,6 @@
/** @type {AppTypes.Config} */ /** @type {AppTypes.Config} */
window.config = { window.config = {
routerBasename: '/', routerBasename: null,
customizationService: ['@ohif/extension-default.customizationModule.helloPage'], customizationService: ['@ohif/extension-default.customizationModule.helloPage'],
extensions: [], extensions: [],
modes: [], modes: [],

View File

@ -3,7 +3,7 @@ window.config = {
// Activate the new HP mode.... // Activate the new HP mode....
isNewHP: true, isNewHP: true,
routerBasename: '/', routerBasename: null,
customizationService: [ customizationService: [
'@ohif/extension-default.customizationModule.datasources', '@ohif/extension-default.customizationModule.datasources',
{ {

View File

@ -1,7 +1,7 @@
/** @type {AppTypes.Config} */ /** @type {AppTypes.Config} */
window.config = { window.config = {
routerBasename: '/', routerBasename: null,
extensions: [], extensions: [],
modes: [], modes: [],
showStudyList: true, showStudyList: true,

View File

@ -1,5 +1,5 @@
window.config = { window.config = {
routerBasename: '/', routerBasename: null,
showStudyList: true, showStudyList: true,
// below flag is for performance reasons, but it might not work for all servers // below flag is for performance reasons, but it might not work for all servers
showWarningMessageForCrossOrigin: true, showWarningMessageForCrossOrigin: true,

View File

@ -53,7 +53,7 @@ function App({
* Hosted at: https://ohif.org/where-i-host-the/viewer/ * Hosted at: https://ohif.org/where-i-host-the/viewer/
* Value: `/where-i-host-the/viewer/` * Value: `/where-i-host-the/viewer/`
* */ * */
routerBaseName: '/', routerBasename: '/',
/** /**
* *
*/ */

View File

@ -17,15 +17,16 @@ import React from 'react';
*/ */
import { modes as defaultModes, extensions as defaultExtensions } from './pluginImports'; import { modes as defaultModes, extensions as defaultExtensions } from './pluginImports';
import loadDynamicConfig from './loadDynamicConfig'; import loadDynamicConfig from './loadDynamicConfig';
import { publicUrl } from './utils/publicUrl';
export { history } from './utils/history'; export { history } from './utils/history';
export { preserveQueryParameters, preserveQueryStrings } from './utils/preserveQueryParameters'; export { preserveQueryParameters, preserveQueryStrings } from './utils/preserveQueryParameters';
export { publicUrl } from './utils/publicUrl';
loadDynamicConfig(window.config).then(config_json => { loadDynamicConfig(window.config).then(config_json => {
// Reset Dynamic config if defined // Reset Dynamic config if defined
if (config_json !== null) { if (config_json !== null) {
window.config = config_json; window.config = config_json;
} }
window.config.routerBasename ||= publicUrl;
/** /**
* Combine our appConfiguration with installed extensions and modes. * Combine our appConfiguration with installed extensions and modes.

View File

@ -11,7 +11,7 @@ import filtersMeta from './filtersMeta.js';
import { useAppConfig } from '@state'; import { useAppConfig } from '@state';
import { useDebounce, useSearchParams } from '@hooks'; import { useDebounce, useSearchParams } from '@hooks';
import { utils } from '@ohif/core'; import { utils } from '@ohif/core';
import publicUrl from '../../utils/publicUrl'; import { routerBasename } from '../../utils/publicUrl';
import { import {
StudyListExpandedRow, StudyListExpandedRow,
@ -209,7 +209,7 @@ function WorkList({
skipEmptyString: true, skipEmptyString: true,
}); });
navigate({ navigate({
pathname: publicUrl, pathname: '/',
search: search ? `?${search}` : undefined, search: search ? `?${search}` : undefined,
}); });
// eslint-disable-next-line react-hooks/exhaustive-deps // eslint-disable-next-line react-hooks/exhaustive-deps
@ -417,7 +417,7 @@ function WorkList({
<Link <Link
className={isValidMode ? '' : 'cursor-not-allowed'} className={isValidMode ? '' : 'cursor-not-allowed'}
key={i} key={i}
to={`${publicUrl}${mode.routeName}${dataPath || ''}?${query.toString()}`} to={`${mode.routeName}${dataPath || ''}?${query.toString()}`}
onClick={event => { onClick={event => {
// In case any event bubbles up for an invalid mode, prevent the navigation. // In case any event bubbles up for an invalid mode, prevent the navigation.
// For example, the event bubbles up when the icon embedded in the disabled button is clicked. // For example, the event bubbles up when the icon embedded in the disabled button is clicked.

View File

@ -1,6 +1,5 @@
import React from 'react'; import React from 'react';
import ModeRoute from '@routes/Mode'; import ModeRoute from '@routes/Mode';
import publicUrl from '../utils/publicUrl';
/* /*
Routes uniquely define an entry point to: Routes uniquely define an entry point to:
@ -43,7 +42,7 @@ export default function buildModeRoutes({
modes.forEach(mode => { modes.forEach(mode => {
// todo: for each route. add route to path. // todo: for each route. add route to path.
dataSourceNames.forEach(dataSourceName => { dataSourceNames.forEach(dataSourceName => {
const path = `${publicUrl}${mode.routeName}/${dataSourceName}`; const path = `${mode.routeName}/${dataSourceName}`;
// TODO move up. // TODO move up.
const children = () => ( const children = () => (
@ -66,7 +65,7 @@ export default function buildModeRoutes({
// Add active DataSource route. // Add active DataSource route.
// This is the DataSource route for the active data source defined in ExtensionManager.getActiveDataSource // This is the DataSource route for the active data source defined in ExtensionManager.getActiveDataSource
const path = `${publicUrl}${mode.routeName}`; const path = `${mode.routeName}`;
// TODO move up. // TODO move up.
const children = () => ( const children = () => (

View File

@ -11,7 +11,7 @@ import NotFound from './NotFound';
import buildModeRoutes from './buildModeRoutes'; import buildModeRoutes from './buildModeRoutes';
import PrivateRoute from './PrivateRoute'; import PrivateRoute from './PrivateRoute';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import publicUrl from '../utils/publicUrl'; import { routerBase, routerBasename } from '../utils/publicUrl';
const NotFoundServer = ({ const NotFoundServer = ({
message = 'Unable to query for studies at this time. Check your data source configuration or network connection', message = 'Unable to query for studies at this time. Check your data source configuration or network connection',
@ -55,23 +55,23 @@ NotFoundStudy.propTypes = {
// TODO: Include "routes" debug route if dev build // TODO: Include "routes" debug route if dev build
const bakedInRoutes = [ const bakedInRoutes = [
{ {
path: `${publicUrl}notfoundserver`, path: `/notfoundserver`,
children: NotFoundServer, children: NotFoundServer,
}, },
{ {
path: `${publicUrl}notfoundstudy`, path: `/notfoundstudy`,
children: NotFoundStudy, children: NotFoundStudy,
}, },
{ {
path: `${publicUrl}debug`, path: `/debug`,
children: Debug, children: Debug,
}, },
{ {
path: `${publicUrl}local`, path: `/local`,
children: Local.bind(null, { modePath: '' }), // navigate to the worklist children: Local.bind(null, { modePath: '' }), // navigate to the worklist
}, },
{ {
path: `${publicUrl}localbasic`, path: `/localbasic`,
children: Local.bind(null, { modePath: 'viewer/dicomlocal' }), children: Local.bind(null, { modePath: 'viewer/dicomlocal' }),
}, },
]; ];
@ -86,7 +86,6 @@ const createRoutes = ({
servicesManager, servicesManager,
commandsManager, commandsManager,
hotkeysManager, hotkeysManager,
routerBasename,
showStudyList, showStudyList,
}: withAppTypes) => { }: withAppTypes) => {
const routes = const routes =
@ -101,8 +100,15 @@ const createRoutes = ({
const { customizationService } = servicesManager.services; const { customizationService } = servicesManager.services;
const path =
routerBasename.length > 1 && routerBasename.endsWith('/')
? routerBasename.substring(0, routerBasename.length - 1)
: routerBasename;
console.log('Registering worklist route', routerBasename, path);
const WorkListRoute = { const WorkListRoute = {
path: publicUrl, path: '/',
children: DataSourceWrapper, children: DataSourceWrapper,
private: true, private: true,
props: { children: WorkList, servicesManager, extensionManager }, props: { children: WorkList, servicesManager, extensionManager },
@ -113,7 +119,6 @@ const createRoutes = ({
const allRoutes = [ const allRoutes = [
...routes, ...routes,
...(showStudyList ? [WorkListRoute] : []), ...(showStudyList ? [WorkListRoute] : []),
...(publicUrl !== '/' && showStudyList ? [{ ...WorkListRoute, path: publicUrl }] : []),
...(customRoutes?.routes || []), ...(customRoutes?.routes || []),
...bakedInRoutes, ...bakedInRoutes,
customRoutes?.notFoundRoute || notFoundRoute, customRoutes?.notFoundRoute || notFoundRoute,

View File

@ -5,7 +5,7 @@ function preserve(query, current, key) {
} }
} }
export const preserveKeys = ['configUrl', 'multimonitor', 'screenNumber']; export const preserveKeys = ['configUrl', 'multimonitor', 'screenNumber', 'hangingProtocolId'];
export function preserveQueryParameters( export function preserveQueryParameters(
query, query,

View File

@ -1,4 +1,6 @@
const publicUrl = (window as any).PUBLIC_URL || '/'; const publicUrl = (window as any).PUBLIC_URL || '/';
const routerBasename = (window as any).config?.routerBasename || publicUrl;
export { publicUrl, routerBasename };
export default publicUrl; export default publicUrl;
export { publicUrl };

View File

@ -28,7 +28,7 @@ The simplest way is to update the existing default config:
```js title="platform/app/public/config/default.js" ```js title="platform/app/public/config/default.js"
window.config = { window.config = {
routerBasename: '/', routerBasename: null,
extensions: [], extensions: [],
modes: [], modes: [],
showStudyList: true, showStudyList: true,
@ -81,7 +81,7 @@ window.config = ({ servicesManager } = {}) => {
} }
}, },
}, },
routerBasename: '/', routerBasename: null,
dataSources: [ dataSources: [
{ {
namespace: '@ohif/extension-default.dataSourcesModule.dicomweb', namespace: '@ohif/extension-default.dataSourcesModule.dicomweb',

View File

@ -123,7 +123,7 @@ configuration looks like:
```js ```js
window.config = { window.config = {
routerBasename: '/', routerBasename: null,
extensions: [], extensions: [],
modes: [], modes: [],
showStudyList: true, showStudyList: true,

View File

@ -4,62 +4,113 @@ title: Custom URL Access/Build
--- ---
## Build for non-root path # Hosting the Web Viewer on a Custom URL Path
Sometimes it is desired to access the viewer from a non-root path (e.g., `/my-awesome-viewer` instead of `/`). You can host the viewer on a subpath like `/abc` instead of the root `/`. There are **two levels** of customization depending on how you want to serve your static assets.
You can achieve so by using the `PUBLIC_URL` environment variable AND the `routerBasename` configuration option.
1. use a config (e.g. `config/myConfig.js`) file that is using the `routerBasename` of your choice `/my-awesome-viewer` (note there is only one / - it is not /my-awesome-viewer/).
2. build the viewer with `PUBLIC_URL=/my-awesome-viewer/` (note there are two / - it is not /my-awesome-viewer).
:::tip ## Simple Setup (Recommended for Most Use Cases)
The PUBLIC_URL tells the application where to find the static assets and the routerBasename will tell the application how to handle the routes
:::
If you want to make the viewer accessible from a custom path (e.g. `/abc`) and **dont care where the assets are loaded from** (theyll be fetched from the root `/`), this setup is for you.
### Testing in Development ### What You Get
For testing the build locally, you can use the following command:
- Viewer available at `https://yourdomain.com/abc`
- All assets (JS, WASM, etc.) still loaded from the root (`/app.js`, `/viewer.wasm`, etc.)
### How To Set It Up
1. Set `routerBasename` in your config file (e.g., `config/myConfig.js`) to `/abc`
2. Build the viewer with:
```bash ```bash
# we use default config file, so we assume you have already set the routerBasename to /my-awesome-viewer in the default config as an example APP_CONFIG=config/myConfig.js yarn build
PUBLIC_URL=/my-awesome-viewer/ APP_CONFIG=config/default.js yarn dev
``` ```
### Local Development
### Testing in Build (production)
You need to build the viewer with the following command:
```bash ```bash
PUBLIC_URL=/my-awesome-viewer/ APP_CONFIG=config/default.js yarn build APP_CONFIG=config/myConfig.js yarn dev
``` ```
We can use the `npx serve` to serve the build folder. There are two things you need to consider however, ---
1. You need to change the `public/serve.json` file to reflect the new routerBasename in the destination (see the example below)
## Advanced Setup (Custom Asset Path)
```json If you want to host the viewer at `/abc` **and** serve static assets from a different location (e.g. `/my-private-assets`), this is a more advanced scenario.
// final serve.json
{ ### What You Get
"rewrites": [{ "source": "*", "destination": "my-awesome-viewer/index.html" }],
- Viewer accessible from `https://yourdomain.com/abc`
- All assets loaded from `https://yourdomain.com/my-private-assets/`
### Why This is Tricky
Some libraries (especially ones using WASM) load assets using **relative paths**, which can break if not handled carefully. To solve this:
- Set `routerBasename` to `/abc`
- Set `PUBLIC_URL` to `/my-private-assets/`
- Webpack will load assets from the specified public URL.
### Local Development Notes
In development, use proxy rewrites to handle relative asset paths. Example for `dicom-microscopy-viewer`:
```js
proxy: {
'/dicom-microscopy-viewer': {
target: 'http://localhost:3000',
pathRewrite: {
'^/dicom-microscopy-viewer': `/${PUBLIC_URL}/dicom-microscopy-viewer`,
},
},
} }
``` ```
This ensures local development can find assets even when libraries expect them at certain paths.
### Building and Serving in Production
To build the viewer for production:
```bash ```bash
cd platform/app; PUBLIC_URL=/my-private-assets/ APP_CONFIG=config/myConfig.js yarn build
# rename the dist folder to my-awesome-viewer
mv dist my-awesome-viewer
# serve the folder with custom json, note that we are using ../public/serve.json and NOT public/serve.json
npx serve -c ./public/serve.json
``` ```
If you're using `npx serve`, make sure to update `serve.json`:
:::note ```json
When you want to authenticate against a sub path, there are a few things you should keep in mind: {
"rewrites": [{ "source": "*", "destination": "/abc/index.html" }]
}
```
1. Set the `routerBasename` to the sub path and also update the `PUBLIC_URL` to match the sub path. Serve the viewer like this:
2. Don't forget to modify the `serve.json` file as mentioned earlier.
3. Ensure that the sub path is included in the list of allowed callback URLs. For example, in the Google Cloud dashboard, you can set it in the `Authorized redirect URIs` field under the `Credentials` section of the `APIs & Services` menu. ```bash
::: cd platform/app
mv dist abc # Rename dist folder to match your viewer route
npx serve -c ./public/serve.json
```
---
### 🐳 Using Docker? You're Covered
If youre using our Dockerfile, youre all set — it already handles copying specific asset folders (like `dicom-microscopy-viewer`) to the root:
```Dockerfile
COPY --from=builder /usr/src/app/platform/app/dist/dicom-microscopy-viewer /usr/share/nginx/html/dicom-microscopy-viewer
```
Keep an eye on the browser network tab for any assets that might fail to load — if any other libraries require similar treatment, youll need to handle those as well.
---
## Summary
| Goal | routerBasename | PUBLIC_URL | Assets Load From |
|-----------------------------------|----------------|-----------------------|--------------------------|
| Viewer at `/abc`, assets from `/` | `/abc` | default | Root `/` |
| Viewer at `/abc`, assets from `/my-private-assets` | `/abc` | `/my-private-assets/` | `/my-private-assets/` |

View File

@ -12,6 +12,7 @@ NODE_ENV=< production | development >
DEBUG=< true | false > DEBUG=< true | false >
APP_CONFIG=< relative path to application configuration file > APP_CONFIG=< relative path to application configuration file >
PUBLIC_URL=< relative path to application root - default / > PUBLIC_URL=< relative path to application root - default / >
ROUTER_BASENAME=< relative path to application root - default PUBLIC_URL >
VERSION_NUMBER=<Set by CircleCI> VERSION_NUMBER=<Set by CircleCI>
BUILD_NUM=<Set by CircleCI> BUILD_NUM=<Set by CircleCI>
# i18n # i18n

View File

@ -172,7 +172,7 @@ Customizations can be declared at three different scopes, each with its own prio
```jsx ```jsx
window.config = { window.config = {
name: 'config/default.js', name: 'config/default.js',
routerBasename: '/', routerBasename: null,
customizationService: [ customizationService: [
{ {
'studyBrowser.sortFunctions': { 'studyBrowser.sortFunctions': {
@ -194,7 +194,7 @@ Customizations can be declared at three different scopes, each with its own prio
```jsx ```jsx
window.config = { window.config = {
name: 'config/default.js', name: 'config/default.js',
routerBasename: '/', routerBasename: null,
customizationService: [ customizationService: [
'@ohif/extension-cornerstone.customizationModule.newCustomization', '@ohif/extension-cornerstone.customizationModule.newCustomization',
], ],