Compare commits
204
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
7b5beb8f98 | ||
|
|
97410e12b9 | ||
|
|
bdecbfeee3 | ||
|
|
5a970056ae | ||
|
|
8581405352 | ||
|
|
df8c4db2ed | ||
|
|
ea62bdaddf | ||
|
|
e983b02677 | ||
|
|
1e4b78d78d | ||
|
|
ee6131f98e | ||
|
|
a56bdd035b | ||
|
|
04901c296e | ||
|
|
59cadad98c | ||
|
|
14d6454eaf | ||
|
|
64f87d2c93 | ||
|
|
cfd66e5ef7 | ||
|
|
6480389778 | ||
|
|
0e736e7a56 | ||
|
|
d246cd9842 | ||
|
|
4fa1eb683d | ||
|
|
ea6842a276 | ||
|
|
d97270f995 | ||
|
|
0ef76f8b66 | ||
|
|
05b5a10af9 | ||
|
|
e1150acaf6 | ||
|
|
4abdbe0584 | ||
|
|
9223a52af9 | ||
|
|
06f58d18bf | ||
|
|
7c5f9c44b6 | ||
|
|
ef341d1518 | ||
|
|
d956963ef0 | ||
|
|
83b7d9e8b4 | ||
|
|
12e73228d1 | ||
|
|
4002401c66 | ||
|
|
18a8e059b6 | ||
|
|
f3582e514e | ||
|
|
c76bfd4a58 | ||
|
|
7f8cf5f5da | ||
|
|
5ef926477c | ||
|
|
87f5b97983 | ||
|
|
4c7b2b4ae0 | ||
|
|
d1e52dd6a6 | ||
|
|
cb147dfc69 | ||
|
|
a5fdeddfb4 | ||
|
|
e0e5f6000f | ||
|
|
cffb7d6f2f | ||
|
|
360616be13 | ||
|
|
d8fe8929b6 | ||
|
|
6b99a21227 | ||
|
|
16631e1fc4 | ||
|
|
587de94cea | ||
|
|
0ebe8a67d2 | ||
|
|
39a988dac7 | ||
|
|
f95928bcdd | ||
|
|
0f736bd294 | ||
|
|
6cbd9839c6 | ||
|
|
649bc5825a | ||
|
|
8038009afd | ||
|
|
f07f21117d | ||
|
|
77c7463c53 | ||
|
|
449e8f25f6 | ||
|
|
437c01511e | ||
|
|
00fddc1550 | ||
|
|
00b5cccae5 | ||
|
|
e545dd5b28 | ||
|
|
efde6ed20e | ||
|
|
32022f51f2 | ||
|
|
d282f72d75 | ||
|
|
29fceacee9 | ||
|
|
a7a5a359dc | ||
|
|
e362e895d4 | ||
|
|
45a07dfa19 | ||
|
|
7323e63608 | ||
|
|
0baf18dcb2 | ||
|
|
cca3d6bff2 | ||
|
|
f3cecf129b | ||
|
|
fe03fc6f55 | ||
|
|
b59187c74d | ||
|
|
5210c80369 | ||
|
|
f57725ac8b | ||
|
|
138e0fb3bf | ||
|
|
be494a7376 | ||
|
|
ab23feefbb | ||
|
|
4c079044f6 | ||
|
|
81fcfc7370 | ||
|
|
6ec6446787 | ||
|
|
4b5a43641a | ||
|
|
2fb0b01fe2 | ||
|
|
3632e5d495 | ||
|
|
dfe566e2aa | ||
|
|
6c5ad9e98d | ||
|
|
aeb7d5edcc | ||
|
|
d5b89748c9 | ||
|
|
b161016edb | ||
|
|
2fff2d511f | ||
|
|
cc92f91c1f | ||
|
|
d2e777bafc | ||
|
|
c0c3ab307d | ||
|
|
5121913ee6 | ||
|
|
6ef2b19925 | ||
|
|
f2450be255 | ||
|
|
04ca32a93e | ||
|
|
c92de6c647 | ||
|
|
5b302843d4 | ||
|
|
7eb8c4c641 | ||
|
|
619f361510 | ||
|
|
330eeaa216 | ||
|
|
d627dee3b2 | ||
|
|
d8714ea9c4 | ||
|
|
3c05920705 | ||
|
|
c6629bda75 | ||
|
|
588bcc9d17 | ||
|
|
c31f8f9d65 | ||
|
|
c0280e28ca | ||
|
|
7c3ac387ef | ||
|
|
d6f79d9ddf | ||
|
|
9448993cf0 | ||
|
|
1c556b4cc3 | ||
|
|
94a9067fe3 | ||
|
|
cfba4df70e | ||
|
|
11c1d12872 | ||
|
|
91364db882 | ||
|
|
bea31d5fec | ||
|
|
48ecbc261a | ||
|
|
8bc467fb07 | ||
|
|
cffc44f0f4 | ||
|
|
ea0fc07e30 | ||
|
|
b8d241fa33 | ||
|
|
ccdfcd4a85 | ||
|
|
6cf72d1757 | ||
|
|
bb1cdbda3a | ||
|
|
fab122dd8f | ||
|
|
42803b0ae8 | ||
|
|
5a78da8ff6 | ||
|
|
0ef88e88eb | ||
|
|
a7b5f1847a | ||
|
|
5cb6e63b88 | ||
|
|
48eb4a9ec3 | ||
|
|
d9231fd431 | ||
|
|
e5b578bd8e | ||
|
|
f38979037d | ||
|
|
45ca88f5b8 | ||
|
|
a1dee16a3d | ||
|
|
6a37a2a661 | ||
|
|
a8caf4bba4 | ||
|
|
29dcc82e28 | ||
|
|
dbf0501031 | ||
|
|
ef28fa2ac1 | ||
|
|
779a7e0976 | ||
|
|
7f3ca1fc23 | ||
|
|
59ab68b4ed | ||
|
|
248bc0a64a | ||
|
|
5fdace1432 | ||
|
|
71b6b454a3 | ||
|
|
3b02a06f5e | ||
|
|
ebdcde1c4d | ||
|
|
829ac2b410 | ||
|
|
09745a0349 | ||
|
|
cd73dd3027 | ||
|
|
ca511edeff | ||
|
|
bb5f30ce2a | ||
|
|
87d5c68e71 | ||
|
|
0e87ab37c2 | ||
|
|
756b005fe1 | ||
|
|
3d86b5f876 | ||
|
|
2a647fd618 | ||
|
|
f8fc31bcac | ||
|
|
b7ab88b0f1 | ||
|
|
57a30d7c34 | ||
|
|
cd90665b0e | ||
|
|
98c657231e | ||
|
|
14da247318 | ||
|
|
6a77d6c778 | ||
|
|
8f1785446b | ||
|
|
41225eefc0 | ||
|
|
7772fee21a | ||
|
|
d870ac914a | ||
|
|
451f7eab92 | ||
|
|
029f8af4c7 | ||
|
|
b1b4c8c861 | ||
|
|
cdde2af224 | ||
|
|
4a2922dda0 | ||
|
|
b6b5a8414f | ||
|
|
e7cc735c03 | ||
|
|
6121bdcf63 | ||
|
|
da70079675 | ||
|
|
9089875ca7 | ||
|
|
b4627ecfa3 | ||
|
|
4ede8a525a | ||
|
|
2c23818c86 | ||
|
|
fa4b03d62d | ||
|
|
698e900b85 | ||
|
|
b7d47383c5 | ||
|
|
6123741765 | ||
|
|
ab25be3520 | ||
|
|
950a54c704 | ||
|
|
4293c073f0 | ||
|
|
62a2cd5ff3 | ||
|
|
2d827c2a49 | ||
|
|
a8305772d0 | ||
|
|
eab115e70c | ||
|
|
c02b232b0c | ||
|
|
f01640d009 | ||
|
|
63fd65690c |
No files matched your search
@@ -0,0 +1,69 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Set directory to location of this script
|
||||
# https://stackoverflow.com/a/3355423/1867984
|
||||
cd "$(dirname "$0")"
|
||||
|
||||
yarn -v
|
||||
node -v
|
||||
|
||||
echo 'Installing Gitbook CLI'
|
||||
|
||||
yarn global bin
|
||||
yarn config get prefix
|
||||
yarn config set prefix ~/.yarn
|
||||
export PATH="$PATH:`yarn global bin`"
|
||||
|
||||
echo 'Running Gitbook installation'
|
||||
|
||||
# Generate all version's GitBook output
|
||||
# For each directory in /docs ...
|
||||
cd ./../docs/
|
||||
for D in *; do
|
||||
if [ -d "${D}" ]; then
|
||||
|
||||
echo "Generating output for: ${D}"
|
||||
cd "${D}"
|
||||
|
||||
# Clear previous output, generate new
|
||||
rm -rf _book
|
||||
gitbook install
|
||||
gitbook build
|
||||
|
||||
cd ..
|
||||
|
||||
fi
|
||||
done
|
||||
|
||||
# Move CNAME File into `latest`
|
||||
cp CNAME ./latest/_book/CNAME
|
||||
|
||||
# Create a history folder in our latest version's output
|
||||
mkdir ./latest/_book/history
|
||||
|
||||
# Move each version's files to latest's history folder
|
||||
for D in *; do
|
||||
if [ -d "${D}" ]; then
|
||||
if [ "${D}" == v* ] ; then
|
||||
|
||||
echo "Moving ${D} to the latest version's history folder"
|
||||
|
||||
mkdir "./latest/_book/history/${D}"
|
||||
cp -v -r "./${D}/_book"/* "./latest/_book/history/${D}"
|
||||
|
||||
fi
|
||||
fi
|
||||
done
|
||||
|
||||
# Back to repo root
|
||||
cd ..
|
||||
|
||||
echo "Done generating documentation output"
|
||||
echo 'STARTING PUBLISH'
|
||||
|
||||
# WILL ALWAYS FAIL IF INITIATED FROM PR BRANCH
|
||||
npx gh-pages \
|
||||
--silent \
|
||||
--repo https://$GITHUB_TOKEN@github.com/OHIF/Viewers.git \
|
||||
--message 'Autogenerated Message: [ci skip]' \
|
||||
--dist docs/latest/_book
|
||||
+227
-235
@@ -18,17 +18,18 @@ executors:
|
||||
# Custom executor to override Cypress config
|
||||
deploy-to-prod-executor:
|
||||
docker:
|
||||
- image: cimg/node:16.14
|
||||
- image: 'cypress/browsers:node14.15.0-chrome86-ff82'
|
||||
environment:
|
||||
CYPRESS_BASE_URL: https://ohif-staging.netlify.com/
|
||||
chrome-and-pacs:
|
||||
docker:
|
||||
# Primary container image where all steps run.
|
||||
- image: 'cypress/browsers:node16.14.2-slim-chrome103-ff102'
|
||||
- image: 'cypress/browsers:node14.15.0-chrome86-ff82'
|
||||
- image: 'ohif/viewer-testdata:0.1-test'
|
||||
|
||||
defaults: &defaults
|
||||
docker:
|
||||
- image: cimg/node:16.14-browsers
|
||||
- image: circleci/node:14.15.0
|
||||
environment:
|
||||
TERM: xterm # Enable colors in term
|
||||
QUICK_BUILD: true
|
||||
@@ -44,7 +45,9 @@ jobs:
|
||||
# Update yarn
|
||||
- run: yarn -v
|
||||
# Checkout code and ALL Git Tags
|
||||
- checkout
|
||||
- checkout:
|
||||
post:
|
||||
- git fetch --all
|
||||
- restore_cache:
|
||||
name: Restore Yarn and Cypress Package Cache
|
||||
keys:
|
||||
@@ -63,18 +66,18 @@ jobs:
|
||||
- run:
|
||||
name: 'JavaScript Test Suite'
|
||||
command: yarn run test:unit:ci
|
||||
# platform/app
|
||||
# PLATFORM/VIEWER
|
||||
- run:
|
||||
name: 'VIEWER: Combine report output'
|
||||
command: |
|
||||
viewerCov="/home/circleci/repo/platform/app/coverage"
|
||||
viewerCov="/home/circleci/repo/platform/viewer/coverage"
|
||||
touch "${viewerCov}/reports"
|
||||
cat "${viewerCov}/clover.xml" >> "${viewerCov}/reports"
|
||||
echo "\<<\<<\<< EOF" >> "${viewerCov}/reports"
|
||||
cat "${viewerCov}/lcov.info" >>"${viewerCov}/reports"
|
||||
echo "\<<\<<\<< EOF" >> "${viewerCov}/reports"
|
||||
- codecov/upload:
|
||||
file: '/home/circleci/repo/platform/app/coverage/reports'
|
||||
file: '/home/circleci/repo/platform/viewer/coverage/reports'
|
||||
flags: 'viewer'
|
||||
# PLATFORM/CORE
|
||||
- run:
|
||||
@@ -100,7 +103,10 @@ jobs:
|
||||
- run: yarn config set workspaces-experimental true
|
||||
|
||||
# Checkout code and ALL Git Tags
|
||||
- checkout
|
||||
- checkout:
|
||||
post:
|
||||
- git fetch --all
|
||||
|
||||
- restore_cache:
|
||||
name: Restore Yarn and Cypress Package Cache
|
||||
keys:
|
||||
@@ -123,9 +129,9 @@ jobs:
|
||||
# Set our version number using vars
|
||||
echo $CIRCLE_BUILD_NUM
|
||||
# Build our image, auth, and push
|
||||
docker build --tag ohif/app:PR_BUILD-$CIRCLE_BUILD_NUM .
|
||||
docker build --tag ohif/viewer:PR_BUILD-$CIRCLE_BUILD_NUM .
|
||||
echo $DOCKER_PWD | docker login -u $DOCKER_LOGIN --password-stdin
|
||||
docker push ohif/app:PR_BUILD-$CIRCLE_BUILD_NUM
|
||||
docker push ohif/viewer:PR_BUILD-$CIRCLE_BUILD_NUM
|
||||
|
||||
###
|
||||
# Workflow: DEPLOY
|
||||
@@ -134,7 +140,9 @@ jobs:
|
||||
<<: *defaults
|
||||
steps:
|
||||
# Checkout code and ALL Git Tags
|
||||
- checkout
|
||||
- checkout:
|
||||
post:
|
||||
- git fetch --all
|
||||
- restore_cache:
|
||||
name: Restore Yarn and Cypress Package Cache
|
||||
keys:
|
||||
@@ -150,89 +158,72 @@ jobs:
|
||||
- ~/.cache ## Cache yarn and Cypress
|
||||
key: yarn-packages-{{ checksum "yarn.lock" }}
|
||||
# Build & Test
|
||||
- run:
|
||||
name: 'Perform the versioning before build'
|
||||
command: node ./version.mjs
|
||||
- run:
|
||||
name: 'Build the OHIF Viewer'
|
||||
command: yarn run build
|
||||
no_output_timeout: 45m
|
||||
- run:
|
||||
name: 'Upload SourceMaps, Send Deploy Notification'
|
||||
command: |
|
||||
# export FILE_1=$(find ./build/static/js -type f -name "2.*.js" -exec basename {} \;)
|
||||
# export FILE_MAIN=$(find ./build/static/js -type f -name "main.*.js" -exec basename {} \;)
|
||||
# export FILE_RUNTIME_MAIN=$(find ./build/static/js -type f -name "runtime~main.*.js" -exec basename {} \;)
|
||||
# curl https://api.rollbar.com/api/1/sourcemap -F source_map=@build/static/js/$FILE_1.map -F access_token=$ROLLBAR_TOKEN -F version=$CIRCLE_SHA1 -F minified_url=https://$GOOGLE_STORAGE_BUCKET/static/js/$FILE_1
|
||||
# curl https://api.rollbar.com/api/1/sourcemap -F source_map=@build/static/js/$FILE_MAIN.map -F access_token=$ROLLBAR_TOKEN -F version=$CIRCLE_SHA1 -F minified_url=https://$GOOGLE_STORAGE_BUCKET/static/js/$FILE_MAIN
|
||||
# curl https://api.rollbar.com/api/1/sourcemap -F source_map=@build/static/js/$FILE_RUNTIME_MAIN.map -F access_token=$ROLLBAR_TOKEN -F version=$CIRCLE_SHA1 -F minified_url=https://$GOOGLE_STORAGE_BUCKET/static/js/$FILE_RUNTIME_MAIN
|
||||
curl --request POST https://api.rollbar.com/api/1/deploy/ -F access_token=$ROLLBAR_TOKEN -F environment=$GOOGLE_STORAGE_BUCKET -F revision=$CIRCLE_SHA1 -F local_username=CircleCI
|
||||
# - run:
|
||||
# name: 'Upload SourceMaps, Send Deploy Notification'
|
||||
# command: |
|
||||
# # export FILE_1=$(find ./build/static/js -type f -name "2.*.js" -exec basename {} \;)
|
||||
# # export FILE_MAIN=$(find ./build/static/js -type f -name "main.*.js" -exec basename {} \;)
|
||||
# # export FILE_RUNTIME_MAIN=$(find ./build/static/js -type f -name "runtime~main.*.js" -exec basename {} \;)
|
||||
# # curl https://api.rollbar.com/api/1/sourcemap -F source_map=@build/static/js/$FILE_1.map -F access_token=$ROLLBAR_TOKEN -F version=$CIRCLE_SHA1 -F minified_url=https://$GOOGLE_STORAGE_BUCKET/static/js/$FILE_1
|
||||
# # curl https://api.rollbar.com/api/1/sourcemap -F source_map=@build/static/js/$FILE_MAIN.map -F access_token=$ROLLBAR_TOKEN -F version=$CIRCLE_SHA1 -F minified_url=https://$GOOGLE_STORAGE_BUCKET/static/js/$FILE_MAIN
|
||||
# # curl https://api.rollbar.com/api/1/sourcemap -F source_map=@build/static/js/$FILE_RUNTIME_MAIN.map -F access_token=$ROLLBAR_TOKEN -F version=$CIRCLE_SHA1 -F minified_url=https://$GOOGLE_STORAGE_BUCKET/static/js/$FILE_RUNTIME_MAIN
|
||||
# curl --request POST https://api.rollbar.com/api/1/deploy/ -F access_token=$ROLLBAR_TOKEN -F environment=$GOOGLE_STORAGE_BUCKET -F revision=$CIRCLE_SHA1 -F local_username=CircleCI
|
||||
# Persist :+1:
|
||||
- persist_to_workspace:
|
||||
root: ~/repo
|
||||
paths:
|
||||
- platform/app/dist
|
||||
- Dockerfile
|
||||
- version.txt
|
||||
- commit.txt
|
||||
- version.json
|
||||
- platform/viewer/dist
|
||||
- netlify.toml
|
||||
- .netlify
|
||||
|
||||
# DEPLOY_TO_DEV:
|
||||
# docker:
|
||||
# - image: circleci/node:16.14.0
|
||||
# environment:
|
||||
# TERM: xterm
|
||||
# NETLIFY_SITE_ID: 32708787-c9b0-4634-b50f-7ca41952da77
|
||||
# working_directory: ~/repo
|
||||
# steps:
|
||||
# - attach_workspace:
|
||||
# at: ~/repo
|
||||
# - run: cd .netlify && npm install
|
||||
# - run: cp .netlify/deploy-workflow/_redirects platform/app/dist/_redirects
|
||||
# - run: cd .netlify && npm run deploy
|
||||
DEPLOY_TO_DEV:
|
||||
docker:
|
||||
- image: circleci/node:14.15.0
|
||||
environment:
|
||||
TERM: xterm
|
||||
NETLIFY_SITE_ID: 32708787-c9b0-4634-b50f-7ca41952da77
|
||||
working_directory: ~/repo
|
||||
steps:
|
||||
- attach_workspace:
|
||||
at: ~/repo
|
||||
- run: cd .netlify && npm install
|
||||
- run:
|
||||
cp .netlify/deploy-workflow/_redirects platform/viewer/dist/_redirects
|
||||
- run: cd .netlify && npm run deploy
|
||||
|
||||
# DEPLOY_TO_STAGING:
|
||||
# docker:
|
||||
# - image: circleci/node:16.14.0
|
||||
# environment:
|
||||
# TERM: xterm
|
||||
# NETLIFY_SITE_ID: c7502ae3-b150-493c-8422-05701e44a969
|
||||
# working_directory: ~/repo
|
||||
# steps:
|
||||
# - attach_workspace:
|
||||
# at: ~/repo
|
||||
# - run: cd .netlify && npm install
|
||||
# - run: cp .netlify/deploy-workflow/_redirects platform/app/dist/_redirects
|
||||
# - run: cd .netlify && npm run deploy
|
||||
DEPLOY_TO_STAGING:
|
||||
docker:
|
||||
- image: circleci/node:14.15.0
|
||||
environment:
|
||||
TERM: xterm
|
||||
NETLIFY_SITE_ID: c7502ae3-b150-493c-8422-05701e44a969
|
||||
working_directory: ~/repo
|
||||
steps:
|
||||
- attach_workspace:
|
||||
at: ~/repo
|
||||
- run: cd .netlify && npm install
|
||||
- run:
|
||||
cp .netlify/deploy-workflow/_redirects platform/viewer/dist/_redirects
|
||||
- run: cd .netlify && npm run deploy
|
||||
|
||||
# DEPLOY_TO_PRODUCTION:
|
||||
# docker:
|
||||
# - image: circleci/node:16.14.0
|
||||
# environment:
|
||||
# TERM: xterm
|
||||
# NETLIFY_SITE_ID: 79c4a5da-5c95-4dc9-84f7-45fd9dfe21b0
|
||||
# working_directory: ~/repo
|
||||
# steps:
|
||||
# - attach_workspace:
|
||||
# at: ~/repo
|
||||
# - run: cd .netlify && npm install
|
||||
# - run: cp .netlify/deploy-workflow/_redirects platform/app/dist/_redirects
|
||||
# - run: cd .netlify && npm run deploy
|
||||
|
||||
# DEPLOY_TO_RELEASE_DEV:
|
||||
# docker:
|
||||
# - image: circleci/node:16.14.0
|
||||
# environment:
|
||||
# TERM: xterm
|
||||
# NETLIFY_SITE_ID: 3270878-22
|
||||
# working_directory: ~/repo
|
||||
# steps:
|
||||
# - attach_workspace:
|
||||
# at: ~/repo
|
||||
# - run: cd .netlify && npm install
|
||||
# - run:
|
||||
# cp .netlify/deploy-workflow/_redirects platform/app/dist/_redirects
|
||||
# - run: cd .netlify && npm run deploy
|
||||
DEPLOY_TO_PRODUCTION:
|
||||
docker:
|
||||
- image: circleci/node:14.15.0
|
||||
environment:
|
||||
TERM: xterm
|
||||
NETLIFY_SITE_ID: 79c4a5da-5c95-4dc9-84f7-45fd9dfe21b0
|
||||
working_directory: ~/repo
|
||||
steps:
|
||||
- attach_workspace:
|
||||
at: ~/repo
|
||||
- run: cd .netlify && npm install
|
||||
- run:
|
||||
cp .netlify/deploy-workflow/_redirects platform/viewer/dist/_redirects
|
||||
- run: cd .netlify && npm run deploy
|
||||
|
||||
###
|
||||
# Workflow: RELEASE
|
||||
@@ -242,9 +233,9 @@ jobs:
|
||||
steps:
|
||||
- run: yarn -v
|
||||
# Checkout code and ALL Git Tags
|
||||
- checkout
|
||||
- attach_workspace:
|
||||
at: ~/repo
|
||||
- checkout:
|
||||
post:
|
||||
- git fetch --all
|
||||
# Use increasingly general patterns to restore cache
|
||||
- restore_cache:
|
||||
name: Restore Yarn and Cypress Package Cache
|
||||
@@ -271,36 +262,34 @@ jobs:
|
||||
name: Authenticate with NPM registry
|
||||
command:
|
||||
echo "//registry.npmjs.org/:_authToken=$NPM_TOKEN" > ~/repo/.npmrc
|
||||
- run:
|
||||
name: Increase the event emitter limit
|
||||
command: |
|
||||
node ./increaseEventEmitterLimit.mjs
|
||||
- run:
|
||||
name: build half of the packages (to avoid out of memory in circleci)
|
||||
command: |
|
||||
yarn run build:package-all
|
||||
- run:
|
||||
name: build the other half of the packages
|
||||
command: |
|
||||
yarn run build:package-all-1
|
||||
- run:
|
||||
name: publish package versions
|
||||
command: |
|
||||
node ./publish-version.mjs
|
||||
- run:
|
||||
name: Again set the NPM registry (was deleted in the version script)
|
||||
command:
|
||||
echo "//registry.npmjs.org/:_authToken=$NPM_TOKEN" > ~/repo/.npmrc
|
||||
- run:
|
||||
name: publish package dist
|
||||
command: |
|
||||
node ./publish-package.mjs
|
||||
- run: npx lerna version
|
||||
- run: npx lerna publish from-package
|
||||
- persist_to_workspace:
|
||||
root: ~/repo
|
||||
paths:
|
||||
- .
|
||||
paths: .
|
||||
|
||||
DOCKER_RELEASE_PUBLISH:
|
||||
DOCS_PUBLISH:
|
||||
docker:
|
||||
# Gitbook fails due to graceful-fs updates above this node version :-(
|
||||
- image: circleci/node:12.9.1
|
||||
environment:
|
||||
TERM: xterm # Enable colors in term
|
||||
working_directory: ~/repo
|
||||
steps:
|
||||
- checkout
|
||||
- run:
|
||||
name: Avoid hosts unknown for github
|
||||
command: |
|
||||
rm -rf ~/.ssh
|
||||
mkdir ~/.ssh/
|
||||
echo -e "Host github.com\n\tStrictHostKeyChecking no\n" > ~/.ssh/config
|
||||
git config --global user.email "danny.ri.brown+ohif-bot@gmail.com"
|
||||
git config --global user.name "ohif-bot"
|
||||
- run: yarn global add gitbook-cli gh-pages
|
||||
- run: chmod +x ~/repo/.circleci/build-and-publish-docs.sh
|
||||
- run: ~/repo/.circleci/build-and-publish-docs.sh
|
||||
|
||||
DOCKER_MASTER_PUBLISH:
|
||||
<<: *defaults
|
||||
steps:
|
||||
- attach_workspace:
|
||||
@@ -308,61 +297,26 @@ jobs:
|
||||
- setup_remote_docker:
|
||||
docker_layer_caching: false
|
||||
- run:
|
||||
name: Build and push Docker image from the release branch
|
||||
name: Build and push Docker image
|
||||
command: |
|
||||
# This file will exist if a new version was published by
|
||||
# our command in the previous job.
|
||||
if [[ ! -e version.txt ]]; then
|
||||
# our command in the previous job. Created in npm postpublish hook
|
||||
# in the `platform/viewer` project.
|
||||
if [[ ! -e platform/viewer/success_version.txt ]]; then
|
||||
exit 0
|
||||
else
|
||||
# Remove npm config
|
||||
rm -f ./.npmrc
|
||||
# Set our version number using vars
|
||||
export IMAGE_VERSION=$(cat version.txt)
|
||||
export IMAGE_VERSION_FULL=v$IMAGE_VERSION
|
||||
export IMAGE_VERSION=$(cat platform/viewer/success_version.txt)
|
||||
export IMAGE_VERSION_FULL=v$IMAGE_VERSION.${CIRCLE_BUILD_NUM}
|
||||
echo $IMAGE_VERSION
|
||||
echo $IMAGE_VERSION_FULL
|
||||
# Build our image, auth, and push
|
||||
docker build --tag ohif/app:$IMAGE_VERSION_FULL --tag ohif/app:latest .
|
||||
docker build --tag ohif/$IMAGE_NAME:$IMAGE_VERSION_FULL --tag ohif/$IMAGE_NAME:latest .
|
||||
echo $DOCKER_PWD | docker login -u $DOCKER_LOGIN --password-stdin
|
||||
docker push ohif/app:$IMAGE_VERSION_FULL
|
||||
docker push ohif/app:latest
|
||||
fi
|
||||
|
||||
DOCKER_BETA_PUBLISH:
|
||||
<<: *defaults
|
||||
steps:
|
||||
- attach_workspace:
|
||||
at: ~/repo
|
||||
- setup_remote_docker:
|
||||
docker_layer_caching: false
|
||||
- run:
|
||||
name:
|
||||
Build and push Docker image from the master branch (beta releases)
|
||||
command: |
|
||||
echo $(ls -l)
|
||||
|
||||
# This file will exist if a new version was published by
|
||||
# our command in the previous job.
|
||||
if [[ ! -e version.txt ]]; then
|
||||
echo "don't have version txt"
|
||||
exit 0
|
||||
else
|
||||
echo "Building and pushing Docker image from the master branch (beta releases)"
|
||||
rm -f ./.npmrc
|
||||
# Set our version number using vars
|
||||
export IMAGE_VERSION=$(cat version.txt)
|
||||
export IMAGE_VERSION_FULL=v$IMAGE_VERSION
|
||||
echo $IMAGE_VERSION
|
||||
echo $IMAGE_VERSION_FULL
|
||||
# Build our image, auth, and push
|
||||
|
||||
echo "starting docker build"
|
||||
docker build --tag ohif/app:$IMAGE_VERSION_FULL .
|
||||
echo $DOCKER_PWD | docker login -u $DOCKER_LOGIN --password-stdin
|
||||
|
||||
echo "starting docker push"
|
||||
docker push ohif/app:$IMAGE_VERSION_FULL
|
||||
docker push ohif/$IMAGE_NAME:$IMAGE_VERSION_FULL
|
||||
docker push ohif/$IMAGE_NAME:latest
|
||||
fi
|
||||
|
||||
workflows:
|
||||
@@ -370,8 +324,13 @@ workflows:
|
||||
|
||||
PR_CHECKS:
|
||||
jobs:
|
||||
- UNIT_TESTS
|
||||
|
||||
- UNIT_TESTS:
|
||||
filters:
|
||||
branches:
|
||||
ignore:
|
||||
- master
|
||||
- feature/*
|
||||
- hotfix/*
|
||||
# E2E: PWA
|
||||
- cypress/run:
|
||||
name: 'E2E: PWA'
|
||||
@@ -379,26 +338,53 @@ workflows:
|
||||
browser: chrome
|
||||
pre-steps:
|
||||
- run: |
|
||||
# Clear yarn cache; use yarn from image (update image to update yarn)
|
||||
# Clear yarn cache; update to latest
|
||||
rm -rf ~/.yarn
|
||||
npm i -g yarn
|
||||
yarn -v
|
||||
yarn: true
|
||||
record: true
|
||||
store_artifacts: true
|
||||
working_directory: platform/app
|
||||
build: yarn test:data
|
||||
working_directory: platform/viewer
|
||||
build: npx cross-env QUICK_BUILD=true APP_CONFIG=config/dicomweb-server.js yarn run build
|
||||
start: yarn run test:e2e:serve
|
||||
spec: 'cypress/integration/**/*'
|
||||
spec: 'cypress/integration/common/**/*,cypress/integration/pwa/**/*'
|
||||
wait-on: 'http://localhost:3000'
|
||||
cache-key: 'yarn-packages-{{ checksum "yarn.lock" }}'
|
||||
no-workspace: true # Don't persist workspace
|
||||
post-steps:
|
||||
- store_artifacts:
|
||||
path: platform/app/cypress/screenshots
|
||||
path: platform/viewer/cypress/screenshots
|
||||
- store_artifacts:
|
||||
path: platform/app/cypress/videos
|
||||
path: platform/viewer/cypress/videos
|
||||
- store_test_results:
|
||||
path: platform/app/cypress/results
|
||||
path: platform/viewer/cypress/results
|
||||
requires:
|
||||
- UNIT_TESTS
|
||||
# E2E: script-tag
|
||||
- cypress/run:
|
||||
name: 'E2E: Script Tag'
|
||||
executor: chrome-and-pacs
|
||||
browser: chrome
|
||||
pre-steps:
|
||||
- run: 'rm -rf ~/.yarn && npm i -g yarn && yarn -v' # Use yarn latest
|
||||
yarn: true
|
||||
record: true
|
||||
store_artifacts: true
|
||||
working_directory: platform/viewer
|
||||
build: npx cross-env QUICK_BUILD=true APP_CONFIG=config/dicomweb-server.js yarn run build:package
|
||||
start: yarn run test:e2e:serve
|
||||
spec: 'cypress/integration/common/**/*,cypress/integration/script-tag/**/*'
|
||||
wait-on: 'http://localhost:3000'
|
||||
cache-key: 'yarn-packages-{{ checksum "yarn.lock" }}'
|
||||
no-workspace: true # Don't persist workspace
|
||||
post-steps:
|
||||
- store_artifacts:
|
||||
path: platform/viewer/cypress/screenshots
|
||||
- store_artifacts:
|
||||
path: platform/viewer/cypress/videos
|
||||
- store_test_results:
|
||||
path: platform/viewer/cypress/results
|
||||
requires:
|
||||
- UNIT_TESTS
|
||||
|
||||
@@ -409,100 +395,106 @@ workflows:
|
||||
# Update hub.docker.org
|
||||
- cypress/run:
|
||||
name: 'Generate Percy Snapshots'
|
||||
executor: cypress/browsers-chrome76
|
||||
executor: chrome-and-pacs
|
||||
browser: chrome
|
||||
pre-steps:
|
||||
- run: 'rm -rf ~/.yarn && yarn -v && yarn global add wait-on'
|
||||
- run: 'rm -rf ~/.yarn && npm i -g yarn && yarn -v && yarn global
|
||||
add wait-on' # Use yarn latest
|
||||
yarn: true
|
||||
store_artifacts: false
|
||||
working_directory: platform/app
|
||||
build:
|
||||
yarn test:data && npx cross-env QUICK_BUILD=true
|
||||
APP_CONFIG=config/dicomweb-server.js yarn run build
|
||||
working_directory: platform/viewer
|
||||
build: npx cross-env QUICK_BUILD=true APP_CONFIG=config/dicomweb-server.js yarn run build
|
||||
# start server --> verify running --> percy + chrome + cypress
|
||||
command: yarn run test:e2e:dist
|
||||
cache-key: 'yarn-packages-{{ checksum "yarn.lock" }}'
|
||||
no-workspace: true # Don't persist workspace
|
||||
post-steps:
|
||||
- store_artifacts:
|
||||
path: platform/app/cypress/screenshots
|
||||
path: platform/viewer/cypress/screenshots
|
||||
- store_artifacts:
|
||||
path: platform/app/cypress/videos
|
||||
path: platform/viewer/cypress/videos
|
||||
requires:
|
||||
- AWAIT_APPROVAL
|
||||
|
||||
# Our master branch deploys to viewer-dev.ohif.org, the viewer.ohif.org is
|
||||
# deployed from the release branch which is more stable and less frequently updated.
|
||||
DEPLOY_MASTER:
|
||||
PR_OPTIONAL_DOCKER_PUBLISH:
|
||||
jobs:
|
||||
# https://circleci.com/docs/2.0/workflows/#holding-a-workflow-for-a-manual-approval
|
||||
- AWAIT_APPROVAL:
|
||||
type: approval
|
||||
# Update hub.docker.org
|
||||
- DOCKER_PR_PUBLISH:
|
||||
context: Docker Hub
|
||||
requires:
|
||||
- AWAIT_APPROVAL
|
||||
|
||||
###
|
||||
# Our workflow for building, deploying, and promoting builds across our
|
||||
# development, staging, and production environments.
|
||||
###
|
||||
DEPLOY:
|
||||
jobs:
|
||||
- BUILD:
|
||||
filters:
|
||||
branches:
|
||||
only: master
|
||||
- NPM_PUBLISH:
|
||||
- DEPLOY_TO_DEV:
|
||||
requires:
|
||||
- BUILD
|
||||
- DOCKER_BETA_PUBLISH:
|
||||
- PROMOTE_TO_STAGING:
|
||||
type: approval
|
||||
requires:
|
||||
- NPM_PUBLISH
|
||||
|
||||
# Our release branch deploys to viewer.ohif.org and is more stable and less
|
||||
# frequently updated after being tested in the staging environment.
|
||||
DEPLOY_RELEASE:
|
||||
jobs:
|
||||
- BUILD:
|
||||
filters:
|
||||
branches:
|
||||
only: release
|
||||
- NPM_PUBLISH:
|
||||
- DEPLOY_TO_DEV
|
||||
- DEPLOY_TO_STAGING:
|
||||
requires:
|
||||
- BUILD
|
||||
- DOCKER_RELEASE_PUBLISH:
|
||||
- PROMOTE_TO_STAGING
|
||||
- PROMOTE_TO_PRODUCTION:
|
||||
type: approval
|
||||
requires:
|
||||
- NPM_PUBLISH
|
||||
- DEPLOY_TO_STAGING
|
||||
- DEPLOY_TO_PRODUCTION:
|
||||
requires:
|
||||
- PROMOTE_TO_PRODUCTION
|
||||
###
|
||||
# Unit and E2E tests have already run for PR_CHECKS
|
||||
# Re-running should not gain us any confidence here
|
||||
###
|
||||
# RELEASE:
|
||||
# jobs:
|
||||
# - NPM_PUBLISH:
|
||||
# filters:
|
||||
# branches:
|
||||
# only: master
|
||||
# - DOCS_PUBLISH:
|
||||
# filters:
|
||||
# branches:
|
||||
# only: master
|
||||
# # Update base branch snapshots
|
||||
# # and record a Cypress dashboard test run
|
||||
# - cypress/run:
|
||||
# name: 'Generate Percy Snapshots'
|
||||
# executor: cypress/browsers-chrome76
|
||||
# browser: chrome
|
||||
# pre-steps:
|
||||
# - run: 'rm -rf ~/.yarn && npm i -g yarn && yarn -v && yarn global
|
||||
# add wait-on' # Use yarn latest
|
||||
# yarn: true
|
||||
# store_artifacts: false
|
||||
# working_directory: platform/app
|
||||
# build:
|
||||
# npx cross-env QUICK_BUILD=true APP_CONFIG=config/e2e.js yarn run
|
||||
# build
|
||||
# # start server --> verify running --> percy + chrome + cypress
|
||||
# command: yarn run test:e2e:dist
|
||||
# cache-key: 'yarn-packages-{{ checksum "yarn.lock" }}'
|
||||
# no-workspace: true # Don't persist workspace
|
||||
# post-steps:
|
||||
# - store_artifacts:
|
||||
# path: platform/app/cypress/screenshots
|
||||
# - store_artifacts:
|
||||
# path: platform/app/cypress/videos
|
||||
# - store_test_results:
|
||||
# path: platform/app/cypress/results
|
||||
# filters:
|
||||
# branches:
|
||||
# only: master
|
||||
# - DOCKER_MASTER_PUBLISH:
|
||||
# requires:
|
||||
# - NPM_PUBLISH
|
||||
RELEASE:
|
||||
jobs:
|
||||
- NPM_PUBLISH:
|
||||
filters:
|
||||
branches:
|
||||
only: master
|
||||
- DOCS_PUBLISH:
|
||||
filters:
|
||||
branches:
|
||||
only: master
|
||||
# Update base branch snapshots
|
||||
# and record a Cypress dashboard test run
|
||||
- cypress/run:
|
||||
name: 'Generate Percy Snapshots'
|
||||
executor: chrome-and-pacs
|
||||
browser: chrome
|
||||
pre-steps:
|
||||
- run: 'rm -rf ~/.yarn && npm i -g yarn && yarn -v && yarn global
|
||||
add wait-on' # Use yarn latest
|
||||
yarn: true
|
||||
store_artifacts: false
|
||||
working_directory: platform/viewer
|
||||
build: npx cross-env QUICK_BUILD=true APP_CONFIG=config/dicomweb-server.js yarn run build
|
||||
# start server --> verify running --> percy + chrome + cypress
|
||||
command: yarn run test:e2e:dist
|
||||
cache-key: 'yarn-packages-{{ checksum "yarn.lock" }}'
|
||||
no-workspace: true # Don't persist workspace
|
||||
post-steps:
|
||||
- store_artifacts:
|
||||
path: platform/viewer/cypress/screenshots
|
||||
- store_artifacts:
|
||||
path: platform/viewer/cypress/videos
|
||||
- store_test_results:
|
||||
path: platform/viewer/cypress/results
|
||||
filters:
|
||||
branches:
|
||||
only: master
|
||||
- DOCKER_MASTER_PUBLISH:
|
||||
requires:
|
||||
- NPM_PUBLISH
|
||||
+1
-1
@@ -22,4 +22,4 @@ flags:
|
||||
- platform/core
|
||||
viewer:
|
||||
paths:
|
||||
- platform/app
|
||||
- platform/viewer
|
||||
@@ -2,7 +2,7 @@ version: '3.5'
|
||||
|
||||
services:
|
||||
orthanc:
|
||||
image: jodogne/orthanc-plugins:1.11.0
|
||||
image: jodogne/orthanc-plugins:1.5.6
|
||||
hostname: orthanc
|
||||
volumes:
|
||||
# Config
|
||||
@@ -13,11 +13,3 @@ services:
|
||||
- '4242:4242' # DICOM
|
||||
- '8042:8042' # Web
|
||||
restart: unless-stopped
|
||||
nginx:
|
||||
image: nginx:latest
|
||||
volumes:
|
||||
- ./config/nginx.conf:/etc/nginx/nginx.conf
|
||||
ports:
|
||||
- '80:80' #ngnix proxy
|
||||
depends_on:
|
||||
- orthanc
|
||||
@@ -1,43 +0,0 @@
|
||||
# Docker compose files
|
||||
|
||||
This folder contains docker-compose files used to spin up OHIF-Viewer with
|
||||
different options such as locally or with any PAS you desire to
|
||||
|
||||
## Public Server
|
||||
|
||||
## Local Orthanc
|
||||
|
||||
### Build
|
||||
|
||||
`$ docker-compose -f docker-compose-orthanc.yml build`
|
||||
|
||||
### Run
|
||||
|
||||
Starts containers and leaves them running in the background.
|
||||
|
||||
`$ docker-compose -f docker-compose-orthanc.yml up -d`
|
||||
|
||||
then, access the application at [http://localhost](http://localhost)
|
||||
|
||||
**remember that you have to access orthanc application and include your studies
|
||||
there**
|
||||
|
||||
## Local Dcm4chee
|
||||
|
||||
#### build
|
||||
|
||||
`$ docker-compose -f docker-compose-dcm4chee.yml build`
|
||||
|
||||
#### run
|
||||
|
||||
`$ docker-compose -f docker-compose-dcm4chee.yml up -d`
|
||||
|
||||
then, access the application at [http://localhost](http://localhost)
|
||||
|
||||
**remember that you have to access dcm4chee application and include your studies
|
||||
there** You can use the following command to import your studies into dcm4che
|
||||
|
||||
`$ docker run -v {YOUR_STUDY_FOLDER}:/tmp --rm --network=docker_dcm4che_default dcm4che/dcm4che-tools:5.14.0 storescu -cDCM4CHEE@arc:11112 /tmp`
|
||||
|
||||
**make sure that your Docker network name is docker_dcm4chee_default or change
|
||||
it to the right one**
|
||||
@@ -0,0 +1,12 @@
|
||||
server {
|
||||
listen 80;
|
||||
location / {
|
||||
root /usr/share/nginx/html;
|
||||
index index.html index.htm;
|
||||
try_files $uri $uri/ /index.html;
|
||||
}
|
||||
error_page 500 502 503 504 /50x.html;
|
||||
location = /50x.html {
|
||||
root /usr/share/nginx/html;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
#!/bin/bash
|
||||
|
||||
if [ -n "$CLIENT_ID" ] || [ -n "$HEALTHCARE_API_ENDPOINT" ]
|
||||
then
|
||||
# If CLIENT_ID is specified, use the google.js configuration with the modified ID
|
||||
if [ -n "$CLIENT_ID" ]
|
||||
then
|
||||
echo "Google Cloud Healthcare \$CLIENT_ID has been provided: "
|
||||
echo "$CLIENT_ID"
|
||||
echo "Updating config..."
|
||||
|
||||
# - Use SED to replace the CLIENT_ID that is currently in google.js
|
||||
sed -i -e "s/YOURCLIENTID.apps.googleusercontent.com/$CLIENT_ID/g" /usr/share/nginx/html/google.js
|
||||
fi
|
||||
|
||||
# If HEALTHCARE_API_ENDPOINT is specified, use the google.js configuration with the modified endpoint
|
||||
if [ -n "$HEALTHCARE_API_ENDPOINT" ]
|
||||
then
|
||||
echo "Google Cloud Healthcare \$HEALTHCARE_API_ENDPOINT has been provided: "
|
||||
echo "$HEALTHCARE_API_ENDPOINT"
|
||||
echo "Updating config..."
|
||||
|
||||
# - Use SED to replace the HEALTHCARE_API_ENDPOINT that is currently in google.js
|
||||
sed -i -e "s+https://healthcare.googleapis.com/v1beta1+$HEALTHCARE_API_ENDPOINT+g" /usr/share/nginx/html/google.js
|
||||
fi
|
||||
|
||||
# - Copy google.js to overwrite app-config.js
|
||||
cp /usr/share/nginx/html/google.js /usr/share/nginx/html/app-config.js
|
||||
fi
|
||||
|
||||
if [ -n "${PORT}" ]
|
||||
then
|
||||
echo "Changing port to ${PORT}..."
|
||||
sed -i -e "s/listen 80/listen ${PORT}/g" /etc/nginx/conf.d/default.conf
|
||||
fi
|
||||
|
||||
echo "Starting Nginx to serve the OHIF Viewer..."
|
||||
|
||||
exec "$@"
|
||||
@@ -1,19 +0,0 @@
|
||||
server {
|
||||
listen ${PORT};
|
||||
location / {
|
||||
root /usr/share/nginx/html;
|
||||
index index.html index.htm;
|
||||
try_files $uri $uri/ /index.html;
|
||||
add_header Cross-Origin-Opener-Policy same-origin;
|
||||
add_header Cross-Origin-Embedder-Policy require-corp;
|
||||
add_header Cross-Origin-Resource-Policy same-origin;
|
||||
proxy_set_header Host $host;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
proxy_set_header X-Forwarded-Proto $http_x_forwarded_proto;
|
||||
}
|
||||
error_page 500 502 503 504 /50x.html;
|
||||
location = /50x.html {
|
||||
root /usr/share/nginx/html;
|
||||
}
|
||||
}
|
||||
@@ -1,35 +0,0 @@
|
||||
#!/bin/sh
|
||||
|
||||
envsubst '${PORT}' < /usr/src/default.conf.template > /etc/nginx/conf.d/default.conf
|
||||
|
||||
if [ -n "$CLIENT_ID" ] || [ -n "$HEALTHCARE_API_ENDPOINT" ]
|
||||
then
|
||||
# If CLIENT_ID is specified, use the google.js configuration with the modified ID
|
||||
if [ -n "$CLIENT_ID" ]
|
||||
then
|
||||
echo "Google Cloud Healthcare \$CLIENT_ID has been provided: "
|
||||
echo "$CLIENT_ID"
|
||||
echo "Updating config..."
|
||||
|
||||
# - Use SED to replace the CLIENT_ID that is currently in google.js
|
||||
sed -i -e "s/YOURCLIENTID.apps.googleusercontent.com/$CLIENT_ID/g" /usr/share/nginx/html/google.js
|
||||
fi
|
||||
|
||||
# If HEALTHCARE_API_ENDPOINT is specified, use the google.js configuration with the modified endpoint
|
||||
if [ -n "$HEALTHCARE_API_ENDPOINT" ]
|
||||
then
|
||||
echo "Google Cloud Healthcare \$HEALTHCARE_API_ENDPOINT has been provided: "
|
||||
echo "$HEALTHCARE_API_ENDPOINT"
|
||||
echo "Updating config..."
|
||||
|
||||
# - Use SED to replace the HEALTHCARE_API_ENDPOINT that is currently in google.js
|
||||
sed -i -e "s+https://healthcare.googleapis.com/v1+$HEALTHCARE_API_ENDPOINT+g" /usr/share/nginx/html/google.js
|
||||
fi
|
||||
|
||||
# - Copy google.js to overwrite app-config.js
|
||||
cp /usr/share/nginx/html/google.js /usr/share/nginx/html/app-config.js
|
||||
fi
|
||||
|
||||
echo "Starting Nginx to serve the OHIF Viewer..."
|
||||
|
||||
exec "$@"
|
||||
@@ -1,4 +0,0 @@
|
||||
config/**
|
||||
docs/**
|
||||
img/**
|
||||
node_modules
|
||||
+1
-8
@@ -1,18 +1,11 @@
|
||||
{
|
||||
"plugins": [
|
||||
"@typescript-eslint",
|
||||
"import",
|
||||
"eslint-plugin-tsdoc",
|
||||
"prettier"
|
||||
],
|
||||
"extends": [
|
||||
"react-app",
|
||||
"eslint:recommended",
|
||||
"plugin:react/recommended",
|
||||
"plugin:@typescript-eslint/recommended",
|
||||
"plugin:prettier/recommended"
|
||||
],
|
||||
"parser": "@typescript-eslint/parser",
|
||||
"parser": "babel-eslint",
|
||||
"env": {
|
||||
"jest": true
|
||||
},
|
||||
|
||||
@@ -1,5 +0,0 @@
|
||||
# Set the default behavior,
|
||||
# in case people don't have core.autocrlf set.
|
||||
* text=auto
|
||||
# Declares that files will always have CRLF line ends
|
||||
*.sh text eol=lf
|
||||
@@ -1 +0,0 @@
|
||||
custom: https://giving.massgeneral.org/ohif
|
||||
@@ -0,0 +1,33 @@
|
||||
---
|
||||
name: "\U0001F41B Bug report"
|
||||
about: Create a report to help us improve
|
||||
title: ''
|
||||
labels: 'Community: Report :bug:, Awaiting Reproduction, Triage :white_flag:'
|
||||
assignees: ''
|
||||
---
|
||||
|
||||
> **Before Creating an issue**
|
||||
>
|
||||
> - Are you running the latest version?
|
||||
> - Are you reporting to the correct repository?
|
||||
> - Did you search existing issues?
|
||||
|
||||
## Bug Report
|
||||
|
||||
### Describe the Bug
|
||||
|
||||
_A clear and concise description of what the bug is._
|
||||
|
||||
### What steps can we follow to reproduce the bug?
|
||||
|
||||
1. First step
|
||||
2. Second step
|
||||
3. ...
|
||||
|
||||
```js
|
||||
Please use code blocks to show formatted errors or code snippets
|
||||
```
|
||||
|
||||
> :warning: Reports we cannot reproduce are at risk of being marked stale and
|
||||
> closed. The more information you can provide, the more likely we are to look
|
||||
> into and address your issue.
|
||||
@@ -0,0 +1,25 @@
|
||||
---
|
||||
name: "\U0001F680 Feature request"
|
||||
about: Suggest an idea for this project
|
||||
title: ''
|
||||
labels: 'Community: Request :hand:, Triage :white_flag:'
|
||||
assignees: ''
|
||||
---
|
||||
|
||||
> :hand: Many people requests features. Tell us why yours is important to the
|
||||
> community. How does it add value? Why _this feature_?
|
||||
>
|
||||
> Is your request very specific to your needs? Consider
|
||||
> [contributing it](https://docs.ohif.org/contributing.html) yourself! Or reach
|
||||
> out to a community member that offers
|
||||
> [consulting services](https://docs.ohif.org/help.html#paid--commercial).
|
||||
|
||||
## Request
|
||||
|
||||
**What feature or change would you like to see made?**
|
||||
|
||||
...
|
||||
|
||||
**Why should we prioritize this feature?**
|
||||
|
||||
...
|
||||
@@ -0,0 +1,18 @@
|
||||
---
|
||||
name: "\U0001F917 Support Question"
|
||||
about: "I have a question \U0001F4AC"
|
||||
title: ''
|
||||
labels: 'Community: Question :question:, Triage :white_flag:'
|
||||
assignees: ''
|
||||
---
|
||||
|
||||
> :hand: We are a small team with limited resources. Your question is much more
|
||||
> likely to be answered if it is
|
||||
> [a good question](https://stackoverflow.com/help/how-to-ask)
|
||||
|
||||
**Description**
|
||||
|
||||
Questions can often be answered by our documentation. Unable to find an answer
|
||||
in our docs? We'll try to help. In the meantime, if you answer your own
|
||||
question, please respond with the answer here so that others may benefit as
|
||||
well. Better yet, open a PR to expand our docs ^\_^
|
||||
@@ -1,86 +0,0 @@
|
||||
name: 'Bug report'
|
||||
description: Create a report to help us improve
|
||||
title: '[Bug] '
|
||||
labels: ['Community: Report :bug:', 'Awaiting Reproduction']
|
||||
|
||||
body:
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: |
|
||||
👋 Hello, and thank you for contributing to our project! Your support is greatly appreciated.
|
||||
|
||||
🔍 Before proceeding, please make sure to read our [Rules of Conduct](https://github.com/OHIF/Viewers/blob/master/CODE_OF_CONDUCT.md) and familiarize yourself with our [development process](https:/docs.ohif.org/development/our-process).
|
||||
|
||||
❓ If you're here to seek general support or ask a question, we encourage you to visit our [community discussion board](https://community.ohif.org/)
|
||||
|
||||
🐞 For bug reports, please complete the following template in as much detail as possible. This will help us reproduce and address the issue efficiently.
|
||||
|
||||
🧪 Finally, ensure that you're using the latest version of the software and check if your issue has already been reported to avoid duplicates.
|
||||
|
||||
- type: textarea
|
||||
id: bug_description
|
||||
attributes:
|
||||
label: Describe the Bug
|
||||
description: 'A clear and concise description of what the bug is.'
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: textarea
|
||||
id: reproduction_steps
|
||||
attributes:
|
||||
label: Steps to Reproduce
|
||||
description: 'Please describe the steps to reproduce the issue.'
|
||||
placeholder: "1. First step\n2. Second step\n3. ..."
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: textarea
|
||||
id: current_behavior
|
||||
attributes:
|
||||
label: The current behavior
|
||||
description:
|
||||
'A clear and concise description of what happens instead of the expected
|
||||
behavior.'
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: textarea
|
||||
id: expected_behavior
|
||||
attributes:
|
||||
label: The expected behavior
|
||||
description:
|
||||
'A clear and concise description of what you expected to happen.'
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: input
|
||||
id: os
|
||||
attributes:
|
||||
label: 'OS'
|
||||
description: 'Your operating system.'
|
||||
placeholder: 'e.g., Windows 10, macOS 10.15.4'
|
||||
validations:
|
||||
required: true
|
||||
- type: input
|
||||
id: node-version
|
||||
attributes:
|
||||
label: 'Node version'
|
||||
description: 'Your Node.js version.'
|
||||
placeholder: 'e.g., 16.14.0'
|
||||
validations:
|
||||
required: true
|
||||
- type: input
|
||||
id: browser
|
||||
attributes:
|
||||
label: 'Browser'
|
||||
description: 'Your browser.'
|
||||
placeholder: 'e.g., Chrome 83.0.4103.116, Firefox 77.0.1, Safari 13.1.1'
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: >
|
||||
> :warning: Reports we cannot reproduce are at risk of being marked
|
||||
stale and > closed. The more information you can provide, the more
|
||||
likely we are to look > into and address your issue.
|
||||
@@ -1,5 +0,0 @@
|
||||
blank_issues_enabled: false
|
||||
contact_links:
|
||||
- name: 🤗 Support Question
|
||||
url: https://community.ohif.org/
|
||||
about: Please use our forum if you have questions or need help.
|
||||
@@ -1,36 +0,0 @@
|
||||
name: Feature request
|
||||
description: Create a feature request
|
||||
labels: ['Community: Request :hand:']
|
||||
title: '[Feature Request] '
|
||||
body:
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: |
|
||||
👋 Hello and thank you for your interest in our project!
|
||||
|
||||
🔍 Before you proceed, please read our [Rules of Conduct](https://github.com/OHIF/Viewers/blob/master/CODE_OF_CONDUCT.md).
|
||||
|
||||
🚀 If your request is specific to your needs, consider contributing it yourself! Read our [contributing guides](https://docs.ohif.org/development/contributing) to get started.
|
||||
|
||||
🖊️ Please provide as much detail as possible for your feature request. Mock-up screenshots, workflow or logic flow diagrams are very helpful. Discuss how your requested feature would interact with existing features.
|
||||
|
||||
⏱️ Lastly, tell us why we should prioritize your feature. What impact would it have?
|
||||
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: 'What feature or change would you like to see made?'
|
||||
description:
|
||||
'Please include as much detail as possible including possibly mock up
|
||||
screen shots, workflow or logic flow diagrams etc.'
|
||||
placeholder: '...'
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: 'Why should we prioritize this feature?'
|
||||
description:
|
||||
'Discuss if and how the requested feature interacts with existing
|
||||
features.'
|
||||
placeholder: '...'
|
||||
validations:
|
||||
required: true
|
||||
@@ -1,91 +1,14 @@
|
||||
<!-- Do Not Delete This! pr_template -->
|
||||
<!-- Please read our Rules of Conduct: https://github.com/OHIF/Viewers/blob/master/CODE_OF_CONDUCT.md -->
|
||||
<!-- 🕮 Read our guide about our Contributing Guide here https://docs.ohif.org/development/contributing -->
|
||||
<!-- :hand: Thank you for starting this amazing contribution! -->
|
||||
### PR Checklist
|
||||
|
||||
- [ ] Brief description of changes
|
||||
- [ ] Links to any relevant issues
|
||||
- [ ] Required status checks are passing
|
||||
- [ ] User cases if changes impact the user's experience
|
||||
- [ ] `@mention` a maintainer to request a review
|
||||
|
||||
<!--
|
||||
⚠️⚠️ Please make sure the checklist section below is complete before submitting your PR.
|
||||
To complete the checklist, add an 'x' to each item: [] -> [x]
|
||||
(PRs that do not have all the checkboxes marked will not be approved)
|
||||
-->
|
||||
|
||||
### Context
|
||||
|
||||
<!--
|
||||
Provide a clear explanation of the reasoning behind this change, such as:
|
||||
- A link to the issue being addressed, using the format "Fixes #ISSUE_NUMBER"
|
||||
- An image showing the issue or problem being addressed (if not already in the issue)
|
||||
- Error logs or callStacks to help with the understanding of the problem (if not already in the issue)
|
||||
-->
|
||||
|
||||
### Changes & Results
|
||||
|
||||
<!--
|
||||
List all the changes that have been done, such as:
|
||||
- Add new components
|
||||
- Remove old components
|
||||
- Update dependencies
|
||||
|
||||
What are the effects of this change?
|
||||
- Before vs After
|
||||
- Screenshots / GIFs / Videos
|
||||
-->
|
||||
|
||||
### Testing
|
||||
|
||||
<!--
|
||||
Describe how we can test your changes.
|
||||
- open a URL
|
||||
- visit a page
|
||||
- click on a button
|
||||
- etc.
|
||||
-->
|
||||
|
||||
### Checklist
|
||||
|
||||
#### PR
|
||||
|
||||
<!--
|
||||
https://semantic-release.gitbook.io/semantic-release/#how-does-it-work
|
||||
|
||||
Examples:
|
||||
Please note the letter casing in the provided examples (upper or lower).
|
||||
|
||||
- feat(MeasurementService): add ...
|
||||
- fix(Toolbar): fix ...
|
||||
- docs(Readme): update ...
|
||||
- style(Whitespace): fix ...
|
||||
- refactor(ExtensionManager): ...
|
||||
- test(HangingProtocol): Add test ...
|
||||
- chore(git): update ...
|
||||
- perf(VolumeLoader): ...
|
||||
|
||||
You don't need to have each commit within the Pull Request follow the rule,
|
||||
but the PR title must comply with it, as it will be used as the commit message
|
||||
after the commits are squashed.
|
||||
-->
|
||||
|
||||
- [] My Pull Request title is descriptive, accurate and follows the
|
||||
semantic-release format and guidelines.
|
||||
|
||||
#### Code
|
||||
|
||||
- [] My code has been well-documented (function documentation, inline comments,
|
||||
etc.)
|
||||
|
||||
#### Public Documentation Updates
|
||||
|
||||
<!-- https://docs.ohif.org/ -->
|
||||
|
||||
- [] The documentation page has been updated as necessary for any public API
|
||||
additions or removals.
|
||||
|
||||
#### Tested Environment
|
||||
|
||||
- [] OS: <!--[e.g. Windows 10, macOS 10.15.4]-->
|
||||
- [] Node version: <!--[e.g. 16.14.0]-->
|
||||
- [] Browser:
|
||||
<!--[e.g. Chrome 83.0.4103.116, Firefox 77.0.1, Safari 13.1.1]-->
|
||||
Links
|
||||
-->
|
||||
|
||||
<!-- prettier-ignore-start -->
|
||||
[blog]: https://circleci.com/blog/triggering-trusted-ci-jobs-on-untrusted-forks/
|
||||
|
||||
+9
-3
@@ -4,17 +4,23 @@
|
||||
# Number of days of inactivity before an issue becomes stale
|
||||
daysUntilStale: 180
|
||||
# Number of days of inactivity before a stale issue is closed
|
||||
daysUntilClose: 60
|
||||
daysUntilClose: 9000
|
||||
# Issues with these labels will never be considered stale
|
||||
exemptLabels:
|
||||
- 'Story :raised_hands:'
|
||||
- 'Bug: Verified :bug:'
|
||||
- 'Task: CI/Tooling :robot:'
|
||||
- 'Task: Docs 📖'
|
||||
- 'Task: Docs :book:'
|
||||
- 'Task: Refactor :hammer_and_wrench:'
|
||||
- 'Task: Tests :microscope:'
|
||||
- 'PR: Awaiting Review 👀'
|
||||
- 'Triage :white_flag:'
|
||||
- 'Extension: Discussion'
|
||||
- 'Announcement 🎉'
|
||||
- 'IDC:priority'
|
||||
- 'IDC:candidate'
|
||||
- 'IDC:collaboration'
|
||||
- 'Community: Request :hand:'
|
||||
- 'Community: Report :bug:'
|
||||
# Label to use when marking an issue as stale
|
||||
staleLabel: 'Stale :baguette_bread:'
|
||||
# Comment to post when marking an issue as stale. Set to `false` to disable
|
||||
|
||||
+1
-9
@@ -9,12 +9,11 @@ src/version.js
|
||||
junit.xml
|
||||
coverage/
|
||||
.docz/
|
||||
.yarn/
|
||||
|
||||
# YALC (for Erik)
|
||||
.yalc
|
||||
yalc.lock
|
||||
*.dcm
|
||||
|
||||
# Logging, System files, misc.
|
||||
.idea/
|
||||
.npm
|
||||
@@ -23,7 +22,6 @@ package-lock.json
|
||||
yarn-error.log
|
||||
.DS_Store
|
||||
.env
|
||||
*.code-workspace
|
||||
|
||||
# Common Example Data Directories
|
||||
sampledata/
|
||||
@@ -36,9 +34,3 @@ screenshots/
|
||||
|
||||
# Locize settings
|
||||
.locize
|
||||
|
||||
# autogenerated files
|
||||
platform/app/src/pluginImports.js
|
||||
/Viewers.iml
|
||||
platform/app/.recipes/Nginx-Dcm4Che/dcm4che/dcm4che-arc/*
|
||||
platform/app/.recipes/OpenResty-Orthanc/logs/*
|
||||
@@ -1,3 +0,0 @@
|
||||
[submodule "testdata"]
|
||||
path = testdata
|
||||
url = https://github.com/OHIF/viewer-testdata-dicomweb.git
|
||||
Executable → Regular
+18
-9
@@ -6,27 +6,36 @@ cd "$(dirname "$0")"
|
||||
cd .. # Up to project root
|
||||
|
||||
# Helpful to verify which versions we're using
|
||||
echo 'My yarn version is... '
|
||||
|
||||
yarn -v
|
||||
node -v
|
||||
|
||||
# Install build deps and all monorepo package dependencies. Yarn Workspaces
|
||||
# should also symlink all projects appropriately
|
||||
yarn run lerna:restore
|
||||
yarn install --no-ignore-optional --pure-lockfile
|
||||
|
||||
# Build && Move PWA Output
|
||||
yarn run build:ci
|
||||
mkdir -p ./.netlify/www/pwa
|
||||
mv platform/app/dist/* .netlify/www/pwa -v
|
||||
echo 'Web application built and copied'
|
||||
mv platform/viewer/dist/* .netlify/www/pwa -v
|
||||
|
||||
# Build && Move Docusaurus Output (for the docs themselves)
|
||||
cd platform/docs
|
||||
# Build && Move script output
|
||||
# yarn run build:package
|
||||
|
||||
# Build && Move Docz Output
|
||||
# Using local yarn install to prevent Gatsby from needing to access
|
||||
# node_modules above the platform/ui folder
|
||||
cd platform/ui
|
||||
yarn install
|
||||
yarn run build
|
||||
cd ../..
|
||||
mkdir -p ./.netlify/www/docs
|
||||
mv platform/docs/build/* .netlify/www/docs -v
|
||||
echo 'Docs built (docusaurus) and copied'
|
||||
mkdir -p ./.netlify/www/ui
|
||||
mv platform/ui/.docz/dist/* .netlify/www/ui -v
|
||||
|
||||
# Cache all of the node_module dependencies in
|
||||
# extensions, modules, and platform packages
|
||||
yarn run lerna:cache
|
||||
echo 'Nothing left to see here. Go home, folks.'
|
||||
|
||||
# Build using react-scripts
|
||||
# npx cross-env PUBLIC_URL=/demo APP_CONFIG=config/netlify.js react-scripts --max_old_space_size=4096 build
|
||||
@@ -2,12 +2,12 @@
|
||||
"name": "root",
|
||||
"private": true,
|
||||
"engines": {
|
||||
"node": ">=14",
|
||||
"node": ">=10",
|
||||
"npm": ">=6",
|
||||
"yarn": ">=1.16.0"
|
||||
},
|
||||
"scripts": {
|
||||
"deploy": "netlify deploy --prod --dir ./../platform/app/dist"
|
||||
"deploy": "netlify deploy --prod --dir ./../platform/viewer/dist"
|
||||
},
|
||||
"devDependencies": {
|
||||
"netlify-cli": "^2.21.0"
|
||||
|
||||
@@ -4,7 +4,3 @@
|
||||
|
||||
# PWA Demo
|
||||
/pwa/* /pwa/index.html 200
|
||||
# UI Demo
|
||||
/ui/* /ui/index.html 200
|
||||
# UI Demo
|
||||
/docs/* /docs/index.html 200
|
||||
+11
-20
@@ -1,23 +1,14 @@
|
||||
<html>
|
||||
<head>
|
||||
<title>OHIF Viewer: Deploy Preview</title>
|
||||
</head>
|
||||
<body>
|
||||
<h1>Index of Previews</h1>
|
||||
|
||||
<head>
|
||||
<title>OHIF Viewer: Deploy Preview</title>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<h1>Index of Previews</h1>
|
||||
|
||||
<ul>
|
||||
<li>
|
||||
<a href="/pwa">OHIF Viewer</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="/docs">Documentation</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="/ui">UI: Component Library</a>
|
||||
</li>
|
||||
</ul>
|
||||
</body>
|
||||
|
||||
<ul>
|
||||
<li>
|
||||
<a href="/pwa">Progressive Web App</a>
|
||||
</li>
|
||||
</ul>
|
||||
</body>
|
||||
</html>
|
||||
@@ -1 +0,0 @@
|
||||
16.14.0
|
||||
@@ -1 +0,0 @@
|
||||
*.md
|
||||
+1
-2
@@ -4,6 +4,5 @@
|
||||
"proseWrap": "always",
|
||||
"tabWidth": 2,
|
||||
"semi": true,
|
||||
"singleQuote": true,
|
||||
"arrowParens": "avoid"
|
||||
"singleQuote": true
|
||||
}
|
||||
Vendored
+2
-6
@@ -1,12 +1,8 @@
|
||||
{
|
||||
"recommendations": [
|
||||
"esbenp.prettier-vscode",
|
||||
"sysoev.language-stylus",
|
||||
"dbaeumer.vscode-eslint",
|
||||
"mikestead.dotenv",
|
||||
"bungcip.better-toml",
|
||||
"silvenon.mdx",
|
||||
"gruntfuggly.todo-tree",
|
||||
"wayou.vscode-todo-highlight",
|
||||
"bradlc.vscode-tailwindcss"
|
||||
"mikestead.dotenv"
|
||||
]
|
||||
}
|
||||
Vendored
-28
@@ -1,28 +0,0 @@
|
||||
{
|
||||
// Use IntelliSense to learn about possible attributes.
|
||||
// Hover to view descriptions of existing attributes.
|
||||
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
|
||||
"version": "0.2.0",
|
||||
"configurations": [
|
||||
{
|
||||
"type": "pwa-chrome",
|
||||
"request": "launch",
|
||||
"name": "Launch Chrome against localhost",
|
||||
"url": "http://localhost:3000",
|
||||
"webRoot": "${workspaceFolder}"
|
||||
}
|
||||
// {
|
||||
// "name": "Debug Jest Tests",
|
||||
// "type": "node",
|
||||
// "request": "launch",
|
||||
// "runtimeArgs": [
|
||||
// "--inspect-brk",
|
||||
// "${workspaceRoot}/node_modules/.bin/jest",
|
||||
// "--runInBand"
|
||||
// ],
|
||||
// "console": "integratedTerminal",
|
||||
// "internalConsoleOptions": "neverOpen",
|
||||
// "port": 9229
|
||||
// }
|
||||
]
|
||||
}
|
||||
Vendored
-1
@@ -26,7 +26,6 @@
|
||||
"autoFix": true
|
||||
}
|
||||
],
|
||||
"jest.autoRun": "off",
|
||||
"prettier.disableLanguages": ["html"],
|
||||
"prettier.endOfLine": "lf",
|
||||
"workbench.colorCustomizations": {},
|
||||
|
||||
@@ -1,28 +1,14 @@
|
||||
const autoprefixer = require('autoprefixer');
|
||||
const path = require('path');
|
||||
const tailwindcss = require('tailwindcss');
|
||||
const tailwindConfigPath = path.resolve(
|
||||
'../../platform/app/tailwind.config.js'
|
||||
);
|
||||
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
|
||||
const devMode = process.env.NODE_ENV !== 'production';
|
||||
|
||||
const cssToJavaScript = {
|
||||
test: /\.css$/,
|
||||
use: [
|
||||
//'style-loader',
|
||||
devMode ? 'style-loader' : MiniCssExtractPlugin.loader,
|
||||
'style-loader',
|
||||
{ loader: 'css-loader', options: { importLoaders: 1 } },
|
||||
{
|
||||
loader: 'postcss-loader',
|
||||
options: {
|
||||
postcssOptions: {
|
||||
verbose: true,
|
||||
plugins: [
|
||||
[tailwindcss(tailwindConfigPath)],
|
||||
[autoprefixer('last 2 version', 'ie >= 11')],
|
||||
],
|
||||
},
|
||||
plugins: () => [autoprefixer('last 2 version', 'ie >= 11')],
|
||||
},
|
||||
},
|
||||
],
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
const stylusToJavaScript = {
|
||||
test: /\.styl$/,
|
||||
use: [
|
||||
{ loader: 'style-loader' }, // 3. Style nodes from JS Strings
|
||||
{ loader: 'css-loader' }, // 2. CSS to CommonJS
|
||||
{ loader: 'stylus-loader' }, // 1. Stylus to CSS
|
||||
],
|
||||
};
|
||||
|
||||
module.exports = stylusToJavaScript;
|
||||
@@ -4,6 +4,7 @@ function transpileJavaScript(mode) {
|
||||
const exclude =
|
||||
mode === 'production'
|
||||
? excludeNodeModulesExcept([
|
||||
'vtk.js',
|
||||
// 'dicomweb-client',
|
||||
// https://github.com/react-dnd/react-dnd/blob/master/babel.config.js
|
||||
'react-dnd',
|
||||
@@ -20,20 +21,17 @@ function transpileJavaScript(mode) {
|
||||
: excludeNodeModulesExcept([]);
|
||||
|
||||
return {
|
||||
// Include mjs, ts, tsx, js, and jsx files.
|
||||
test: /\.(mjs|ts|js)x?$/,
|
||||
test: /\.jsx?$/,
|
||||
// These are packages that are not transpiled to our lowest supported
|
||||
// JS version (currently ES5). Most of these leverage ES6+ features,
|
||||
// that we need to transpile to a different syntax.
|
||||
exclude: [/(codecs)/, /(dicomicc)/, exclude],
|
||||
exclude,
|
||||
loader: 'babel-loader',
|
||||
options: {
|
||||
// Find babel.config.js in monorepo root
|
||||
// https://babeljs.io/docs/en/options#rootmode
|
||||
rootMode: 'upward',
|
||||
envName: mode,
|
||||
cacheCompression: false,
|
||||
cacheDirectory: true,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
+26
-93
@@ -2,40 +2,22 @@
|
||||
const dotenv = require('dotenv');
|
||||
//
|
||||
const path = require('path');
|
||||
const fs = require('fs');
|
||||
|
||||
const webpack = require('webpack');
|
||||
|
||||
// ~~ PLUGINS
|
||||
const BundleAnalyzerPlugin = require('webpack-bundle-analyzer')
|
||||
.BundleAnalyzerPlugin;
|
||||
const TerserJSPlugin = require('terser-webpack-plugin');
|
||||
|
||||
// ~~ PackageJSON
|
||||
// const vtkRules = require('vtk.js/Utilities/config/dependency.js').webpack.core
|
||||
// .rules;
|
||||
// ~~ RULES
|
||||
const loadShadersRule = require('./rules/loadShaders.js');
|
||||
const loadWebWorkersRule = require('./rules/loadWebWorkers.js');
|
||||
const transpileJavaScriptRule = require('./rules/transpileJavaScript.js');
|
||||
const cssToJavaScript = require('./rules/cssToJavaScript.js');
|
||||
|
||||
// ~~ PLUGINS
|
||||
const TerserJSPlugin = require('terser-webpack-plugin');
|
||||
// ~~ ENV VARS
|
||||
const NODE_ENV = process.env.NODE_ENV;
|
||||
const QUICK_BUILD = process.env.QUICK_BUILD;
|
||||
const BUILD_NUM = process.env.CIRCLE_BUILD_NUM || '0';
|
||||
|
||||
// read from ../version.txt
|
||||
const VERSION_NUMBER =
|
||||
fs.readFileSync(path.join(__dirname, '../version.txt'), 'utf8') || '';
|
||||
|
||||
const COMMIT_HASH =
|
||||
fs.readFileSync(path.join(__dirname, '../commit.txt'), 'utf8') || '';
|
||||
|
||||
//
|
||||
dotenv.config();
|
||||
|
||||
module.exports = (env, argv, { SRC_DIR, ENTRY }) => {
|
||||
module.exports = (env, argv, { SRC_DIR, DIST_DIR }) => {
|
||||
if (!process.env.NODE_ENV) {
|
||||
throw new Error('process.env.NODE_ENV not set');
|
||||
}
|
||||
@@ -46,20 +28,13 @@ module.exports = (env, argv, { SRC_DIR, ENTRY }) => {
|
||||
|
||||
const config = {
|
||||
mode: isProdBuild ? 'production' : 'development',
|
||||
devtool: isProdBuild ? 'source-map' : 'cheap-module-source-map',
|
||||
entry: ENTRY,
|
||||
optimization: {
|
||||
// splitChunks: {
|
||||
// // include all types of chunks
|
||||
// chunks: 'all',
|
||||
// },
|
||||
//runtimeChunk: 'single',
|
||||
minimize: isProdBuild,
|
||||
sideEffects: false,
|
||||
devtool: isProdBuild ? 'source-map' : 'cheap-module-eval-source-map',
|
||||
entry: {
|
||||
app: `${SRC_DIR}/index.js`,
|
||||
},
|
||||
output: {
|
||||
// clean: true,
|
||||
publicPath: '/',
|
||||
optimization: {
|
||||
minimize: isProdBuild,
|
||||
sideEffects: true,
|
||||
},
|
||||
context: SRC_DIR,
|
||||
stats: {
|
||||
@@ -73,69 +48,26 @@ module.exports = (env, argv, { SRC_DIR, ENTRY }) => {
|
||||
children: false,
|
||||
warnings: true,
|
||||
},
|
||||
devServer: {
|
||||
open: true,
|
||||
port: 3000,
|
||||
historyApiFallback: true,
|
||||
headers: {
|
||||
'Cross-Origin-Embedder-Policy': 'require-corp',
|
||||
'Cross-Origin-Opener-Policy': 'same-origin',
|
||||
},
|
||||
},
|
||||
cache: {
|
||||
type: 'filesystem',
|
||||
},
|
||||
module: {
|
||||
noParse: [/(codec)/, /(dicomicc)/],
|
||||
rules: [
|
||||
transpileJavaScriptRule(mode),
|
||||
loadWebWorkersRule,
|
||||
// loadShadersRule,
|
||||
{
|
||||
test: /\.m?js/,
|
||||
resolve: {
|
||||
fullySpecified: false,
|
||||
},
|
||||
},
|
||||
cssToJavaScript,
|
||||
{
|
||||
test: /\.wasm/,
|
||||
type: 'asset/resource',
|
||||
},
|
||||
], //.concat(vtkRules),
|
||||
loadShadersRule,
|
||||
],
|
||||
},
|
||||
resolve: {
|
||||
mainFields: ['module', 'browser', 'main'],
|
||||
alias: {
|
||||
// Viewer project
|
||||
'@': path.resolve(__dirname, '../platform/app/src'),
|
||||
'@components': path.resolve(
|
||||
__dirname,
|
||||
'../platform/app/src/components'
|
||||
),
|
||||
'@hooks': path.resolve(__dirname, '../platform/app/src/hooks'),
|
||||
'@routes': path.resolve(__dirname, '../platform/app/src/routes'),
|
||||
'@state': path.resolve(__dirname, '../platform/app/src/state'),
|
||||
'dicom-microscopy-viewer':
|
||||
'dicom-microscopy-viewer/dist/dynamic-import/dicomMicroscopyViewer.min.js',
|
||||
'@cornerstonejs/dicom-image-loader':
|
||||
'@cornerstonejs/dicom-image-loader/dist/dynamic-import/cornerstoneDICOMImageLoader.min.js',
|
||||
},
|
||||
// Which directories to search when resolving modules
|
||||
modules: [
|
||||
// Modules specific to this package
|
||||
path.resolve(__dirname, '../node_modules'),
|
||||
// Hoisted Yarn Workspace Modules
|
||||
path.resolve(__dirname, '../../../node_modules'),
|
||||
path.resolve(__dirname, '../platform/app/node_modules'),
|
||||
path.resolve(__dirname, '../platform/ui/node_modules'),
|
||||
SRC_DIR,
|
||||
],
|
||||
// Attempt to resolve these extensions in order.
|
||||
extensions: ['.js', '.jsx', '.json', '.ts', '.tsx', '*'],
|
||||
extensions: ['.js', '.jsx', '.json', '*'],
|
||||
// symlinked resources are resolved to their real path, not their symlinked location
|
||||
symlinks: true,
|
||||
fallback: { fs: false, path: false, zlib: false },
|
||||
},
|
||||
plugins: [
|
||||
new webpack.DefinePlugin({
|
||||
@@ -144,29 +76,30 @@ module.exports = (env, argv, { SRC_DIR, ENTRY }) => {
|
||||
'process.env.DEBUG': JSON.stringify(process.env.DEBUG),
|
||||
'process.env.APP_CONFIG': JSON.stringify(process.env.APP_CONFIG || ''),
|
||||
'process.env.PUBLIC_URL': JSON.stringify(process.env.PUBLIC_URL || '/'),
|
||||
'process.env.VERSION_NUMBER': webpack.DefinePlugin.runtimeValue(() => {
|
||||
const package = require('../platform/viewer/package.json');
|
||||
return JSON.stringify(package.version || '');
|
||||
}, ['../platform/viewer/package.json']),
|
||||
'process.env.BUILD_NUM': JSON.stringify(BUILD_NUM),
|
||||
'process.env.VERSION_NUMBER': JSON.stringify(VERSION_NUMBER),
|
||||
'process.env.COMMIT_HASH': JSON.stringify(COMMIT_HASH),
|
||||
/* i18n */
|
||||
'process.env.USE_LOCIZE': JSON.stringify(process.env.USE_LOCIZE || ''),
|
||||
'process.env.LOCIZE_PROJECTID': JSON.stringify(
|
||||
process.env.LOCIZE_PROJECTID || ''
|
||||
),
|
||||
'process.env.LOCIZE_API_KEY': JSON.stringify(
|
||||
process.env.LOCIZE_API_KEY || ''
|
||||
),
|
||||
'process.env.REACT_APP_I18N_DEBUG': JSON.stringify(
|
||||
process.env.REACT_APP_I18N_DEBUG || ''
|
||||
),
|
||||
'process.env.LOCIZE_PROJECTID': JSON.stringify(process.env.LOCIZE_PROJECTID || ''),
|
||||
'process.env.LOCIZE_API_KEY': JSON.stringify(process.env.LOCIZE_API_KEY || ''),
|
||||
}),
|
||||
// Uncomment to generate bundle analyzer
|
||||
// new BundleAnalyzerPlugin(),
|
||||
],
|
||||
// Fix: https://github.com/webpack-contrib/css-loader/issues/447#issuecomment-285598881
|
||||
// For issue in cornerstone-wado-image-loader
|
||||
node: {
|
||||
fs: 'empty',
|
||||
},
|
||||
};
|
||||
|
||||
if (isProdBuild) {
|
||||
config.optimization.minimizer = [
|
||||
new TerserJSPlugin({
|
||||
// Supports:
|
||||
// source-map and inline-source-map
|
||||
sourceMap: isProdBuild && !isQuickBuild,
|
||||
parallel: true,
|
||||
terserOptions: {},
|
||||
}),
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
const merge = require('webpack-merge');
|
||||
const webpackBase = require('./webpack.base.js');
|
||||
const cssToJavaScriptRule = require('./rules/cssToJavaScript.js');
|
||||
const stylusToJavaScriptRule = require('./rules/stylusToJavaScript.js');
|
||||
|
||||
/**
|
||||
* WebPack configuration for CommonJS Bundles. Extends rules of BaseConfig by making
|
||||
* sure we're bundling styles and other files that would normally be split in a
|
||||
* PWA.
|
||||
*/
|
||||
module.exports = (env, argv, { SRC_DIR, DIST_DIR }) => {
|
||||
const baseConfig = webpackBase(env, argv, { SRC_DIR, DIST_DIR });
|
||||
|
||||
return merge(baseConfig, {
|
||||
module: {
|
||||
rules: [cssToJavaScriptRule, stylusToJavaScriptRule],
|
||||
},
|
||||
});
|
||||
};
|
||||
-149
@@ -1,149 +0,0 @@
|
||||
# OHIF public demo data sets
|
||||
|
||||
The OHIF Viewer's public demo page, available at https://viewer.ohif.org/, uses publicly anonymized demo datasets.
|
||||
These datasets were mostly obtained from the [NIH NCI Imaging Data Commons](https://datacommons.cancer.gov/repository/imaging-data-commons)
|
||||
and [NIH NCI TCIA](https://www.cancerimagingarchive.net/). Before listing the datasets,
|
||||
we would like to extend a special thank you to all groups who have made their datasets publicly available.
|
||||
Without them, we would not have been able to create this demo page.
|
||||
|
||||
Please find below the list of datasets used on the demo page, along with their respective citations.
|
||||
|
||||
|
||||
## Platforms
|
||||
### NIH NCI IDC
|
||||
|
||||
- Fedorov, A., Longabaugh, W.J., Pot, D., Clunie, D.A., Pieper, S., Aerts, H.J., Homeyer, A., Lewis, R., Akbarzadeh, A., Bontempi, D. and Clifford, W., 2021. NCI imaging data commons. Cancer research, 81(16), p.4188.
|
||||
|
||||
### NIH NCI TCIA
|
||||
|
||||
- Clark, K., Vendt, B., Smith, K., Freymann, J., Kirby, J., Koppel, P., Moore, S., Phillips, S., Maffitt, D., Pringle, M., Tarbox, L., & Prior, F. (2013). The Cancer Imaging Archive (TCIA): Maintaining and Operating a Public Information Repository. Journal of Digital Imaging, 26(6), 1045–1057. https://doi.org/10.1007/s10278-013-9622-7
|
||||
|
||||
|
||||
|
||||
|
||||
## Datasets
|
||||
Below you can find the StudyInstanceUID of the studies that are used in the demo page along with their citations.
|
||||
|
||||
### 1.3.6.1.4.1.14519.5.2.1.267424821384663813780850856506829388886
|
||||
|
||||
Segmentation of Vestibular Schwannoma from Magnetic Resonance Imaging: An Open Annotated Dataset and Baseline Algorithm (Vestibular-Schwannoma-SEG)
|
||||
|
||||
- Shapey, J., Kujawa, A., Dorent, R., Wang, G., Bisdas, S., Dimitriadis, A., Grishchuck, D., Paddick, I., Kitchen, N., Bradford, R., Saeed, S., Ourselin, S., & Vercauteren, T. (2021). Segmentation of Vestibular Schwannoma from Magnetic Resonance Imaging: An Open Annotated Dataset and Baseline Algorithm [Data set]. The Cancer Imaging Archive. https://doi.org/10.7937/TCIA.9YTJ-5Q73
|
||||
|
||||
- Shapey, J., Kujawa, A., Dorent, R., Wang, G., Dimitriadis, A., Grishchuk, D., Paddick, I., Kitchen, N., Bradford, R., Saeed, S. R., Bisdas, S., Ourselin, S., & Vercauteren, T. (2021). Segmentation of vestibular schwannoma from MRI, an open annotated dataset and baseline algorithm. In Scientific Data (Vol. 8, Issue 1). Springer Science and Business Media LLC. https://doi.org/10.1038/s41597-021-01064-w
|
||||
|
||||
|
||||
### 1.3.6.1.4.1.14519.5.2.1.7009.2403.334240657131972136850343327463
|
||||
### 1.3.6.1.4.1.14519.5.2.1.7009.2403.871108593056125491804754960339
|
||||
|
||||
|
||||
ACRIN-NSCLC-FDG-PET (ACRIN 6668)
|
||||
|
||||
- Kinahan, P., Muzi, M., Bialecki, B., Herman, B., & Coombs, L. (2019). Data from the ACRIN 6668 Trial NSCLC-FDG-PET (Version 2) [Data set]. The Cancer Imaging Archive. https://doi.org/10.7937/tcia.2019.30ilqfcl
|
||||
|
||||
- Machtay, M., Duan, F., Siegel, B. A., Snyder, B. S., Gorelick, J. J., Reddin, J. S., Munden, R., Johnson, D. W., Wilf, L. H., DeNittis, A., Sherwin, N., Cho, K. H., Kim, S., Videtic, G., Neumann, D. R., Komaki, R., Macapinlac, H., Bradley, J. D., & Alavi, A. (2013). Prediction of Survival by [18F]Fluorodeoxyglucose Positron Emission Tomography in Patients With Locally Advanced Non–Small-Cell Lung Cancer Undergoing Definitive Chemoradiation Therapy: Results of the ACRIN 6668/RTOG 0235 Trial. In Journal of Clinical Oncology (Vol. 31, Issue 30, pp. 3823–3830). American Society of Clinical Oncology (ASCO). https://doi.org/10.1200/jco.2012.47.5947
|
||||
|
||||
|
||||
### 2.25.103659964951665749659160840573802789777
|
||||
|
||||
The Cancer Genome Atlas Glioblastoma Multiforme Collection (TCGA-GBM)
|
||||
|
||||
- Scarpace, L., Mikkelsen, T., Cha, S., Rao, S., Tekchandani, S., Gutman, D., Saltz, J. H., Erickson, B. J., Pedano, N., Flanders, A. E., Barnholtz-Sloan, J., Ostrom, Q., Barboriak, D., & Pierce, L. J. (2016). The Cancer Genome Atlas Glioblastoma Multiforme Collection (TCGA-GBM) (Version 4) [Data set]. The Cancer Imaging Archive. https://doi.org/10.7937/K9/TCIA.2016.RNYFUYE9
|
||||
|
||||
|
||||
### 1.3.6.1.4.1.14519.5.2.1.256467663913010332776401703474716742458
|
||||
|
||||
Abdominal or pelvic enhanced CT images within 10 days before surgery of 230 patients with stage II colorectal cancer (StageII-Colorectal-CT)
|
||||
|
||||
|
||||
- Tong T., Li M. (2022) Abdominal or pelvic enhanced CT images within 10 days before surgery of 230 patients with stage II colorectal cancer (StageII-Colorectal-CT) [Dataset]. The Cancer Imaging Archive. DOI: https://doi.org/10.7937/p5k5-tg43
|
||||
|
||||
- Li, M., Gong, J., Bao, Y., Huang, D., Peng, J., & Tong, T. (2022). Special issue “The advance of solid tumor research in China”: Prognosis prediction for stage II colorectal cancer by fusing computed tomography radiomics and deep‐learning features of primary lesions and peripheral lymph nodes. In International Journal of Cancer. Wiley. https://doi.org/10.1002/ijc.34053
|
||||
|
||||
|
||||
### 1.3.6.1.4.1.14519.5.2.1.3023.4024.215308722288168917637555384485
|
||||
|
||||
The Cancer Genome Atlas Sarcoma Collection (TCGA-SARC)
|
||||
|
||||
- Roche, C., Bonaccio, E., & Filippini, J. (2016). The Cancer Genome Atlas Sarcoma Collection (TCGA-SARC) (Version 3) [Data set]. The Cancer Imaging Archive. https://doi.org/10.7937/K9/TCIA.2016.CX6YLSUX
|
||||
|
||||
|
||||
|
||||
### 1.3.6.1.4.1.14519.5.2.1.4792.2001.105216574054253895819671475627
|
||||
|
||||
BREAST-DIAGNOSIS
|
||||
|
||||
|
||||
- Bloch, B. Nicolas, Jain, Ashali, & Jaffe, C. Carl. (2015). BREAST-DIAGNOSIS [Data set]. The Cancer Imaging Archive. http://doi.org/10.7937/K9/TCIA.2015.SDNRQXXR
|
||||
|
||||
|
||||
|
||||
|
||||
### 1.3.6.1.4.1.14519.5.2.1.1706.8374.643249677828306008300337414785
|
||||
|
||||
Multimodality annotated HCC cases with and without advanced imaging segmentation (HCC-TACE-Seg)
|
||||
|
||||
|
||||
- Moawad, A. W., Fuentes, D., Morshid, A., Khalaf, A. M., Elmohr, M. M., Abusaif, A., Hazle, J. D., Kaseb, A. O., Hassan, M., Mahvash, A., Szklaruk, J., Qayyom, A., & Elsayes, K. (2021). Multimodality annotated HCC cases with and without advanced imaging segmentation [Data set]. The Cancer Imaging Archive. https://doi.org/10.7937/TCIA.5FNA-0924
|
||||
|
||||
- Morshid, A., Elsayes, K. M., Khalaf, A. M., Elmohr, M. M., Yu, J., Kaseb, A. O., Hassan, M., Mahvash, A., Wang, Z., Hazle, J. D., & Fuentes, D. (2019). A Machine Learning Model to Predict Hepatocellular Carcinoma Response to Transcatheter Arterial Chemoembolization. Radiology: Artificial Intelligence, 1(5), e180021. https://doi.org/10.1148/ryai.2019180021
|
||||
|
||||
|
||||
|
||||
### 1.3.6.1.4.1.14519.5.2.1.1188.2803.137585363493444318569098508293
|
||||
|
||||
Ultrasound data of a variety of liver masses (B-mode-and-CEUS-Liver)
|
||||
|
||||
- Eisenbrey, J., Lyshchik, A., & Wessner, C. (2021). Ultrasound data of a variety of liver masses [Data set]. The Cancer Imaging Archive. DOI: https://doi.org/10.7937/TCIA.2021.v4z7-tc39
|
||||
|
||||
|
||||
|
||||
### 1.3.6.1.4.1.32722.99.99.62087908186665265759322018723889952421
|
||||
|
||||
NSCLC-Radiomics
|
||||
|
||||
- Aerts, H. J. W. L., Wee, L., Rios Velazquez, E., Leijenaar, R. T. H., Parmar, C., Grossmann, P., Carvalho, S., Bussink, J., Monshouwer, R., Haibe-Kains, B., Rietveld, D., Hoebers, F., Rietbergen, M. M., Leemans, C. R., Dekker, A., Quackenbush, J., Gillies, R. J., Lambin, P. (2019). Data From NSCLC-Radiomics (version 4) [Data set]. The Cancer Imaging Archive. https://doi.org/10.7937/K9/TCIA.2015.PF0M9REI
|
||||
|
||||
|
||||
- Aerts, H. J. W. L., Velazquez, E. R., Leijenaar, R. T. H., Parmar, C., Grossmann, P., Carvalho, S., Bussink, J., Monshouwer, R., Haibe-Kains, B., Rietveld, D., Hoebers, F., Rietbergen, M. M., Leemans, C. R., Dekker, A., Quackenbush, J., Gillies, R. J., Lambin, P. (2014, June 3). Decoding tumour phenotype by noninvasive imaging using a quantitative radiomics approach. Nature Communications. Nature Publishing Group. https://doi.org/10.1038/ncomms5006 (link)
|
||||
|
||||
|
||||
### 1.3.6.1.4.1.14519.5.2.1.3671.4754.298665348758363466150039312520
|
||||
|
||||
QIN-PROSTATE-Repeatability
|
||||
|
||||
- Fedorov, A; Schwier, M; Clunie, D; Herz, C; Pieper, S; Kikinis, R; Tempany, C; Fennessy, F. (2018). Data From QIN-PROSTATE-Repeatability. The Cancer Imaging Archive. DOI: 10.7937/K9/TCIA.2018.MR1CKGND
|
||||
|
||||
|
||||
- Fedorov A, Vangel MG, Tempany CM, Fennessy FM. Multiparametric Magnetic Resonance Imaging of the Prostate: Repeatability of Volume and Apparent Diffusion Coefficient Quantification. Investigative Radiology. 52, 538–546 (2017). DOI: 10.1097/RLI.0000000000000382
|
||||
|
||||
- Fedorov, A., Schwier, M., Clunie, D., Herz, C., Pieper, S., Kikinis,R., Tempany, C. & Fennessy, F. An annotated test-retest collection of prostate multiparametric MRI. Scientific Data 5, 180281 (2018). DOI:
|
||||
|
||||
### 2.25.141277760791347900862109212450152067508
|
||||
|
||||
The Clinical Proteomic Tumor Analysis Consortium Clear Cell Renal Cell Carcinoma Collection (CPTAC-CCRCC)
|
||||
|
||||
- National Cancer Institute Clinical Proteomic Tumor Analysis Consortium (CPTAC). (2018). The Clinical Proteomic Tumor Analysis Consortium Clear Cell Renal Cell Carcinoma Collection (CPTAC-CCRCC) (Version 10) [Data set]. The Cancer Imaging Archive. https://doi.org/10.7937/K9/TCIA.2018.OBLAMN27
|
||||
|
||||
- The CPTAC program requests that publications using data from this program include the following statement: “Data used in this publication were generated by the National Cancer Institute Clinical Proteomic Tumor Analysis Consortium (CPTAC).”
|
||||
|
||||
|
||||
### 2.25.275741864483510678566144889372061815320
|
||||
|
||||
National Lung Screening Trial
|
||||
|
||||
- National Lung Screening Trial Research Team. (2013). Data from the National Lung Screening Trial (NLST) [Data set]. The Cancer Imaging Archive. https://doi.org/10.7937/TCIA.HMQ8-J677
|
||||
|
||||
- National Lung Screening Trial Research Team*; Aberle DR, Adams AM, Berg CD, Black WC, Clapp JD, Fagerstrom RM, Gareen IF, Gatsonis C, Marcus PM, Sicks JD (2011). Reduced Lung-Cancer Mortality with Low-Dose Computed Tomographic Screening. New England Journal of Medicine, 365(5), 395–409. https://doi.org/10.1056/nejmoa1102873
|
||||
|
||||
|
||||
### 1.3.6.1.4.1.14519.5.2.1.99.1071.26968527900428638961173806140069
|
||||
|
||||
Stony Brook University COVID-19 Positive Cases (COVID-19-NY-SBU)
|
||||
|
||||
- Saltz, J., Saltz, M., Prasanna, P., Moffitt, R., Hajagos, J., Bremer, E., Balsamo, J., & Kurc, T. (2021). Stony Brook University COVID-19 Positive Cases [Data set]. The Cancer Imaging Archive. https://doi.org/10.7937/TCIA.BBAG-2923
|
||||
|
||||
|
||||
### 2.16.840.1.114362.1.11972228.22789312658.616067305.306.2
|
||||
|
||||
https://data.kitware.com/
|
||||
+23
-31
@@ -1,4 +1,4 @@
|
||||
# This dockerfile is used to publish the `ohif/app` image on dockerhub.
|
||||
# This dockerfile is used to publish the `ohif/viewer` image on dockerhub.
|
||||
#
|
||||
# It's a good example of how to build our static application and package it
|
||||
# with a web server capable of hosting it as static content.
|
||||
@@ -21,36 +21,27 @@
|
||||
|
||||
# Stage 1: Build the application
|
||||
# docker build -t ohif/viewer:latest .
|
||||
FROM node:16.15.0-slim as json-copier
|
||||
FROM node:10.16.3-slim as builder
|
||||
|
||||
RUN mkdir /usr/src/app
|
||||
WORKDIR /usr/src/app
|
||||
|
||||
COPY ["package.json", "yarn.lock", "preinstall.js", "./"]
|
||||
COPY extensions /usr/src/app/extensions
|
||||
COPY modes /usr/src/app/modes
|
||||
COPY platform /usr/src/app/platform
|
||||
|
||||
# Find and remove non-package.json files
|
||||
#RUN find extensions \! -name "package.json" -mindepth 2 -maxdepth 2 -print | xargs rm -rf
|
||||
#RUN find modes \! -name "package.json" -mindepth 2 -maxdepth 2 -print | xargs rm -rf
|
||||
#RUN find platform \! -name "package.json" -mindepth 2 -maxdepth 2 -print | xargs rm -rf
|
||||
|
||||
# Copy Files
|
||||
FROM node:16.15.0-slim as builder
|
||||
RUN mkdir /usr/src/app
|
||||
WORKDIR /usr/src/app
|
||||
|
||||
COPY --from=json-copier /usr/src/app .
|
||||
COPY .docker /usr/src/app/.docker
|
||||
COPY .webpack /usr/src/app/.webpack
|
||||
COPY extensions /usr/src/app/extensions
|
||||
COPY platform /usr/src/app/platform
|
||||
COPY .browserslistrc /usr/src/app/.browserslistrc
|
||||
COPY aliases.config.js /usr/src/app/aliases.config.js
|
||||
COPY babel.config.js /usr/src/app/babel.config.js
|
||||
COPY lerna.json /usr/src/app/lerna.json
|
||||
COPY package.json /usr/src/app/package.json
|
||||
COPY postcss.config.js /usr/src/app/postcss.config.js
|
||||
COPY yarn.lock /usr/src/app/yarn.lock
|
||||
|
||||
# Run the install before copying the rest of the files
|
||||
RUN yarn config set workspaces-experimental true
|
||||
RUN yarn install --frozen-lockfile --verbose
|
||||
|
||||
COPY . .
|
||||
|
||||
# To restore workspaces symlinks
|
||||
RUN yarn install --frozen-lockfile --verbose
|
||||
RUN yarn install
|
||||
|
||||
ENV PATH /usr/src/app/node_modules/.bin:$PATH
|
||||
ENV QUICK_BUILD true
|
||||
@@ -59,15 +50,16 @@ ENV QUICK_BUILD true
|
||||
|
||||
RUN yarn run build
|
||||
|
||||
# Stage 3: Bundle the built application into a Docker container
|
||||
# Stage 2: Bundle the built application into a Docker container
|
||||
# which runs Nginx using Alpine Linux
|
||||
FROM nginxinc/nginx-unprivileged:1.23.1-alpine as final
|
||||
#RUN apk add --no-cache bash
|
||||
ENV PORT=80
|
||||
RUN rm /etc/nginx/conf.d/default.conf
|
||||
USER nginx
|
||||
COPY --chown=nginx:nginx .docker/Viewer-v3.x /usr/src
|
||||
FROM nginx:1.15.5-alpine
|
||||
RUN apk add --no-cache bash
|
||||
RUN rm -rf /etc/nginx/conf.d
|
||||
COPY .docker/Viewer-v2.x /etc/nginx/conf.d
|
||||
COPY .docker/Viewer-v2.x/entrypoint.sh /usr/src/
|
||||
RUN chmod 777 /usr/src/entrypoint.sh
|
||||
COPY --from=builder /usr/src/app/platform/app/dist /usr/share/nginx/html
|
||||
COPY --from=builder /usr/src/app/platform/viewer/dist /usr/share/nginx/html
|
||||
EXPOSE 80
|
||||
EXPOSE 443
|
||||
ENTRYPOINT ["/usr/src/entrypoint.sh"]
|
||||
CMD ["nginx", "-g", "daemon off;"]
|
||||
@@ -2,40 +2,35 @@
|
||||
<!-- markdownlint-disable -->
|
||||
<div align="center">
|
||||
<h1>OHIF Medical Imaging Viewer</h1>
|
||||
<p><strong>The OHIF Viewer</strong> is a zero-footprint medical image viewer
|
||||
provided by the <a href="https://ohif.org/">Open Health Imaging Foundation (OHIF)</a>. It is a configurable and extensible progressive web application with out-of-the-box support for image archives which support <a href="https://www.dicomstandard.org/dicomweb/">DICOMweb</a>.</p>
|
||||
<p><strong>The OHIF Viewer</strong> is a zero-footprint medical image viewer provided by the <a href="http://ohif.org/">Open Health Imaging Foundation (OHIF)</a>. It is a configurable and extensible progressive web application with out-of-the-box support for image archives which support <a href="https://www.dicomstandard.org/dicomweb/">DICOMweb</a>.</p>
|
||||
</div>
|
||||
|
||||
|
||||
<div align="center">
|
||||
<a href="https://docs.ohif.org/"><strong>Read The Docs</strong></a>
|
||||
<a href="https://docs.ohif.org/"><strong>Read The Docs</strong></a> |
|
||||
<a href="https://github.com/OHIF/Viewers/tree/master/docs/latest">Edit the docs</a>
|
||||
</div>
|
||||
<div align="center">
|
||||
<a href="https://viewer.ohif.org/">Live Demo</a> |
|
||||
<a href="https://ui.ohif.org/">Component Library</a>
|
||||
</div>
|
||||
<div align="center">
|
||||
📰 <a href="https://ohif.org/news/"><strong>Join OHIF Newsletter</strong></a> 📰
|
||||
<a href="https://react.ohif.org/">Component Library</a>
|
||||
</div>
|
||||
|
||||
|
||||
<hr />
|
||||
|
||||
[![NPM version][npm-version-image]][npm-url]
|
||||
[![NPM downloads][npm-downloads-image]][npm-url]
|
||||
[![Pulls][docker-pulls-img]][docker-image-url]
|
||||
[![MIT License][license-image]][license-url]
|
||||
[](https://app.fossa.io/projects/git%2Bgithub.com%2FOHIF%2FViewers?ref=badge_shield)
|
||||
|
||||
[![Netlify Status][netlify-image]][netlify-url]
|
||||
[![CircleCI][circleci-image]][circleci-url]
|
||||
[![codecov][codecov-image]][codecov-url]
|
||||
[![This project is using Percy.io for visual regression testing.][percy-image]](percy-url)
|
||||
<!-- [![NPM downloads][npm-downloads-image]][npm-url] -->
|
||||
<!-- [![Pulls][docker-pulls-img]][docker-image-url] -->
|
||||
<!-- [](https://app.fossa.io/projects/git%2Bgithub.com%2FOHIF%2FViewers?ref=badge_shield) -->
|
||||
|
||||
<!-- [![Netlify Status][netlify-image]][netlify-url] -->
|
||||
<!-- [![CircleCI][circleci-image]][circleci-url] -->
|
||||
<!-- [![codecov][codecov-image]][codecov-url] -->
|
||||
<!-- [](#contributors) -->
|
||||
[](#contributors)
|
||||
<!-- prettier-ignore-end -->
|
||||
|
||||

|
||||
|
||||
## About
|
||||
|
||||
The OHIF Medical Imaging Viewer is for viewing medical images. It can retrieve
|
||||
@@ -59,7 +54,7 @@ contributions of individuals, research groups, and commercial organizations.
|
||||
|
||||
### Built to Adapt
|
||||
|
||||
After more than 8-years of integrating with many companies and organizations,
|
||||
After more than 5-years of integrating with many companies and organizations,
|
||||
The OHIF Viewer has been rebuilt from the ground up to better address the
|
||||
varying workflow and configuration needs of its many users. All of the Viewer's
|
||||
core features are built using it's own extension system. The same extensibility
|
||||
@@ -70,7 +65,6 @@ that allows us to offer:
|
||||
- Maximum Intensity Project (MIP)
|
||||
- Whole slide microscopy viewing
|
||||
- PDF and Dicom Structured Report rendering
|
||||
- Segmentation rendering as labelmaps and contours
|
||||
- User Access Control (UAC)
|
||||
- Context specific toolbar and side panel content
|
||||
- and many others
|
||||
@@ -84,53 +78,62 @@ forking).
|
||||
We offer support through
|
||||
[GitHub Issues](https://github.com/OHIF/Viewers/issues/new/choose). You can:
|
||||
|
||||
- [Report a Bug 🐛](https://github.com/OHIF/Viewers/issues/new?assignees=&labels=Community%3A+Report+%3Abug%3A%2CAwaiting+Reproduction&projects=&template=bug-report.yml&title=%5BBug%5D+)
|
||||
- [Request a Feature 🚀](https://github.com/OHIF/Viewers/issues/new?assignees=&labels=Community%3A+Request+%3Ahand%3A&projects=&template=feature-request.yml&title=%5BFeature+Request%5D+)
|
||||
- [Ask a Question 🤗](community.ohif.org)
|
||||
- [Slack Channel](https://join.slack.com/t/cornerstonejs/shared_invite/zt-1r8xb2zau-dOxlD6jit3TN0Uwf928w9Q)
|
||||
- [Report a Bug 🐛](https://github.com/OHIF/Viewers/issues/new?assignees=&labels=Community%3A+Report+%3Abug%3A&template=---bug-report.md)
|
||||
- [Request a Feature 🚀](https://github.com/OHIF/Viewers/issues/new?assignees=&labels=Community%3A+Request+%3Ahand%3A&template=---feature-request.md)
|
||||
- [Ask a Question 🤗](https://github.com/OHIF/Viewers/issues/new?assignees=&labels=Community%3A+Question+%3Aquestion%3A&template=---support-question.md)
|
||||
|
||||
For commercial support, academic collaborations, and answers to common
|
||||
For commercial support, academic collaberations, and answers to common
|
||||
questions; please read our
|
||||
[documented FAQ](https://docs.ohif.org/faq/index.html#does-ohif-offer-commercial-support).
|
||||
|
||||
## Quick Start Deployment
|
||||
|
||||
> This is only one of many ways to configure and deploy the OHIF Viewer. To
|
||||
> learn more about your options, and how to choose the best one for your
|
||||
> requirements, check out
|
||||
> [our deployment recipes and documentation](https://docs.ohif.org/deployment/).
|
||||
|
||||
The fastest and easiest way to get started is to include the OHIF Viewer with a
|
||||
script tag. In practice, this is as simple as:
|
||||
|
||||
- Including the following dependencies with script tags:
|
||||
- [React](https://unpkg.com/react@16/umd/react.production.min.js)
|
||||
- [React Dom](https://unpkg.com/react-dom@16/umd/react-dom.production.min.js)
|
||||
- The [OHIF Viewer](https://unpkg.com/@ohif/viewer)
|
||||
- Have an element with an ID of `root` on the page
|
||||
- Configure the OHIF Viewer at `window.config`:
|
||||
|
||||
```js
|
||||
window.config = {
|
||||
routerBasename: '/',
|
||||
servers: {
|
||||
dicomWeb: [
|
||||
{
|
||||
name: 'DCM4CHEE',
|
||||
qidoRoot: 'https://server.dcmjs.org/dcm4chee-arc/aets/DCM4CHEE/rs',
|
||||
wadoRoot: 'https://server.dcmjs.org/dcm4chee-arc/aets/DCM4CHEE/rs',
|
||||
qidoSupportsIncludeField: true,
|
||||
imageRendering: 'wadors',
|
||||
thumbnailRendering: 'wadors',
|
||||
},
|
||||
],
|
||||
},
|
||||
};
|
||||
```
|
||||
|
||||
- Install the viewer: `window.OHIFViewer.installViewer(window.config);`
|
||||
|
||||
This exact setup is demonstrated in this
|
||||
[CodeSandbox](https://codesandbox.io/s/viewer-script-tag-tprch) and in our
|
||||
[Embedding The Viewer](https://docs.ohif.org/deployment/recipes/embedded-viewer.html)
|
||||
deployment recipe.
|
||||
|
||||
## Developing
|
||||
|
||||
### Branches
|
||||
|
||||
#### `master` branch - The latest dev (beta) release
|
||||
|
||||
- `master` - The latest dev release
|
||||
|
||||
This is typically where the latest development happens. Code that is in the master branch has passed code reviews and automated tests, but it may not be deemed ready for production. This branch usually contains the most recent changes and features being worked on by the development team. It's often the starting point for creating feature branches (where new features are developed) and hotfix branches (for urgent fixes).
|
||||
|
||||
Each package is tagged with beta version numbers, and published to npm such as `@ohif/ui@3.6.0-beta.1`
|
||||
|
||||
### `release` branch - The latest stable release
|
||||
|
||||
This branch represents the latest stable version of the project that is considered ready for production. The code in this branch should be fully tested and vetted for release. Once the code in the master branch reaches a state where it's stable and ready to be released to users,
|
||||
we do a comprehensive code review and QA testing. Once the code is approved,
|
||||
we merge it into the release branch and tag a new release.
|
||||
|
||||
Each package is tagged with version numbers, and published to npm such as `@ohif/ui@3.5.0`
|
||||
|
||||
Note: `master` is always ahead of `release` branch. We publish both docker builds for beta and stable releases.
|
||||
|
||||
Here is a schematic representation of our development workflow:
|
||||
|
||||

|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
### Requirements
|
||||
|
||||
- [Yarn 1.17.3+](https://yarnpkg.com/en/docs/install)
|
||||
- [Node 16+](https://nodejs.org/en/)
|
||||
- [Node 10+](https://nodejs.org/en/)
|
||||
- Yarn Workspaces should be enabled on your machine:
|
||||
- `yarn config set workspaces-experimental true`
|
||||
|
||||
@@ -166,14 +169,17 @@ also supports a number of commands that can be found in their respective
|
||||
| ---------------------------- | ------------------------------------------------------------- |
|
||||
| **Develop** | |
|
||||
| `dev` or `start` | Default development experience for Viewer |
|
||||
| `dev:project <package-name>` | Replace with `core`, `ui`, `i18n`, `cornerstone`, `vtk`, etc. |
|
||||
| `test:unit` | Jest multi-project test runner; overall coverage |
|
||||
| **Deploy** | |
|
||||
| `build`\* | Builds production output for our PWA Viewer | |
|
||||
| `build`\* | Builds production output for our PWA Viewer |
|
||||
| `build:package`\* | Builds production `commonjs` output for our Viewer |
|
||||
| `build:package-all`\* | Builds commonjs bundles for all projects |
|
||||
|
||||
\* - For more information on our different builds, check out our [Deploy
|
||||
Docs][deployment-docs]
|
||||
|
||||
## Project
|
||||
## Projects
|
||||
|
||||
The OHIF Medical Image Viewing Platform is maintained as a
|
||||
[`monorepo`][monorepo]. This means that this repository, instead of containing a
|
||||
@@ -182,69 +188,58 @@ you'll see the following:
|
||||
|
||||
```bash
|
||||
.
|
||||
├── extensions #
|
||||
│ ├── _example # Skeleton of example extension
|
||||
│ ├── default # basic set of useful functionalities (datasources, panels, etc)
|
||||
│ ├── cornerstone # image rendering and tools w/ Cornerstone3D
|
||||
│ ├── cornerstone-dicom-sr # DICOM Structured Report rendering and export
|
||||
│ ├── cornerstone-dicom-sr # DICOM Structured Report rendering and export
|
||||
│ ├── cornerstone-dicom-seg # DICOM Segmentation rendering and export
|
||||
│ ├── cornerstone-dicom-rt # DICOM RTSTRUCT rendering
|
||||
│ ├── cornerstone-microscopy # Whole Slide Microscopy rendering
|
||||
│ ├── dicom-pdf # PDF rendering
|
||||
│ ├── dicom-video # DICOM RESTful Services
|
||||
│ ├── measurement-tracking # Longitudinal measurement tracking
|
||||
│ ├── tmtv # Total Metabolic Tumor Volume (TMTV) calculation
|
||||
|
|
||||
|
||||
├── extensions #
|
||||
│ ├── _example # Skeleton of example extension
|
||||
│ ├── cornerstone # 2D images w/ Cornerstone.js
|
||||
│ ├── dicom-html # Structured Reports as HTML in viewport
|
||||
│ ├── dicom-microscopy # Whole slide microscopy viewing
|
||||
│ ├── dicom-pdf # View DICOM wrapped PDFs in viewport
|
||||
│ └── vtk # MPR and Volume support w/ VTK.js
|
||||
│
|
||||
├── modes #
|
||||
│ ├── _example # Skeleton of example mode
|
||||
│ ├── basic-dev-mode # Basic development mode
|
||||
│ ├── longitudinal # Longitudinal mode (measurement tracking)
|
||||
│ ├── tmtv # Total Metabolic Tumor Volume (TMTV) calculation mode
|
||||
│ └── microscopy # Whole Slide Microscopy mode
|
||||
├── platform #
|
||||
│ ├── core # Business Logic
|
||||
│ ├── i18n # Internationalization Support
|
||||
│ ├── ui # React component library
|
||||
│ └── viewer # Connects platform and extension projects
|
||||
│
|
||||
├── platform #
|
||||
│ ├── core # Business Logic
|
||||
│ ├── i18n # Internationalization Support
|
||||
│ ├── ui # React component library
|
||||
│ ├── docs # Documentation
|
||||
│ └── viewer # Connects platform and extension projects
|
||||
│
|
||||
├── ... # misc. shared configuration
|
||||
├── lerna.json # MonoRepo (Lerna) settings
|
||||
├── package.json # Shared devDependencies and commands
|
||||
└── README.md # This file
|
||||
├── ... # misc. shared configuration
|
||||
├── lerna.json # MonoRepo (Lerna) settings
|
||||
├── package.json # Shared devDependencies and commands
|
||||
└── README.md # This file
|
||||
```
|
||||
|
||||
Want to better understand why and how we've structured this repository? Read
|
||||
more about it in our [Architecture Documentation][ohif-architecture].
|
||||
|
||||
### Platform
|
||||
|
||||
These projects comprise the
|
||||
|
||||
| Name | Description | Links |
|
||||
| ---------------------------------------------------- | ----------------------------------------------------- | ---------------------- |
|
||||
| [@ohif/extension-cornerstone][extension-cornerstone] | 2D image viewing, annotation, and segementation tools | [NPM][cornerstone-npm] |
|
||||
| Name | Description | Links |
|
||||
| ------------------------------- | ---------------------------------------------------------------------------------------------------- | ----------------- |
|
||||
| [@ohif/core][platform-core] | Business logic and classes that model the data, services, and extensions that are framework agnostic | [NPM][core-npm] |
|
||||
| [@ohif/i18n][platform-i18n] | Language files and small API for wrapping component/ui text for translations | [NPM][i18n-npm] |
|
||||
| [@ohif/viewer][platform-viewer] | The OHIF Viewer. Where we consume and configure all platform library's and extensions | [NPM][viewer-npm] |
|
||||
| [@ohif/ui][platform-ui] | Reusable React components we consume and compose to build our Viewer's UI | [NPM][ui-npm] |
|
||||
|
||||
### Extensions
|
||||
|
||||
This is a list of Extensions maintained by the OHIF Core team. It's possible to
|
||||
customize and configure these extensions, and you can even create your own. You
|
||||
can [read more about extensions here][ohif-extensions].
|
||||
|
||||
| Name | Description | Links |
|
||||
| -------------------------------------------------------------- | ------------------------------------------------------- | ---------------------- |
|
||||
| [@ohif/extension-cornestone][extension-cornerstone] | 2D image viewing, annotation, and segementation tools | [NPM][cornerstone-npm] |
|
||||
| [@ohif/extension-dicom-html][extension-dicom-html] | Support for viewing DICOM SR as rendered HTML | [NPM][html-npm] |
|
||||
| [@ohif/extension-dicom-microscopy][extension-dicom-microscopy] | Whole slide microscopy viewing | [NPM][microscopy-npm] |
|
||||
| [@ohif/extension-dicom-pdf][extension-dicom-pdf] | View DICOM wrapped PDFs in a viewport | [NPM][pdf-npm] |
|
||||
| [@ohif/extension-vtk][extension-vtk] | Volume rendering, reconstruction, and 3D visualizations | [NPM][vtk-npm] |
|
||||
|
||||
## Acknowledgments
|
||||
|
||||
To acknowledge the OHIF Viewer in an academic publication, please cite
|
||||
|
||||
> _Open Health Imaging Foundation Viewer: An Extensible Open-Source Framework
|
||||
> for Building Web-Based Imaging Applications to Support Cancer Research_
|
||||
>
|
||||
> Erik Ziegler, Trinity Urban, Danny Brown, James Petts, Steve D. Pieper, Rob
|
||||
> Lewis, Chris Hafey, and Gordon J. Harris
|
||||
>
|
||||
> _JCO Clinical Cancer Informatics_, no. 4 (2020), 336-345, DOI:
|
||||
> [10.1200/CCI.19.00131](https://www.doi.org/10.1200/CCI.19.00131)
|
||||
>
|
||||
> Open-Access on Pubmed Central:
|
||||
> https://www.ncbi.nlm.nih.gov/pmc/articles/PMC7259879/
|
||||
|
||||
or, for v1, please cite:
|
||||
|
||||
> _LesionTracker: Extensible Open-Source Zero-Footprint Web Viewer for Cancer
|
||||
> Imaging Research and Clinical Trials_
|
||||
>
|
||||
@@ -263,7 +258,21 @@ Cancer Institute, Informatics Technology for Cancer Research (ITCR) program,
|
||||
under a
|
||||
[grant to Dr. Gordon Harris at Massachusetts General Hospital (U24 CA199460)](https://projectreporter.nih.gov/project_info_description.cfm?aid=8971104).
|
||||
|
||||
This project is tested with BrowserStack. Thank you for supporting open source
|
||||
## Projects that contributed to OHIF Viewer
|
||||
|
||||
The following is a (partial) list of projects that contributed resources towards
|
||||
development of OHIF Viewer:
|
||||
|
||||
- [NCI Imaging Data Commons (IDC) project](https://imaging.datacommons.cancer.gov/)
|
||||
supported development of new features and bug fixes marked with
|
||||
["IDC:priority"](https://github.com/OHIF/Viewers/issues?q=is%3Aissue+is%3Aopen+label%3AIDC%3Apriority),
|
||||
["IDC:candidate"](https://github.com/OHIF/Viewers/issues?q=is%3Aissue+is%3Aopen+label%3AIDC%3Acandidate)
|
||||
or
|
||||
["IDC:collaboration"](https://github.com/OHIF/Viewers/issues?q=is%3Aissue+is%3Aopen+label%3AIDC%3Acollaboration).
|
||||
NCI Imaging Data Commons is supported by the contract number 19X037Q from
|
||||
Leidos Biomedical Research under Task Order HHSN26100071 from NCI.
|
||||
[IDC Viewer](https://learn.canceridc.dev/portal/visualization) is a customized
|
||||
version of the OHIF Viewer.
|
||||
|
||||
## License
|
||||
|
||||
@@ -289,11 +298,11 @@ MIT © [OHIF](https://github.com/OHIF)
|
||||
[semantic-image]: https://img.shields.io/badge/%20%20%F0%9F%93%A6%F0%9F%9A%80-semantic--release-e10079.svg
|
||||
[semantic-url]: https://github.com/semantic-release/semantic-release
|
||||
<!-- ROW -->
|
||||
[npm-url]: https://npmjs.org/package/@ohif/app
|
||||
[npm-downloads-image]: https://img.shields.io/npm/dm/@ohif/app.svg?style=flat-square
|
||||
[npm-version-image]: https://img.shields.io/npm/v/@ohif/app.svg?style=flat-square
|
||||
[npm-url]: https://npmjs.org/package/@ohif/viewer
|
||||
[npm-downloads-image]: https://img.shields.io/npm/dm/@ohif/viewer.svg?style=flat-square
|
||||
[npm-version-image]: https://img.shields.io/npm/v/@ohif/viewer.svg?style=flat-square
|
||||
[docker-pulls-img]: https://img.shields.io/docker/pulls/ohif/viewer.svg?style=flat-square
|
||||
[docker-image-url]: https://hub.docker.com/r/ohif/app
|
||||
[docker-image-url]: https://hub.docker.com/r/ohif/viewer
|
||||
[license-image]: https://img.shields.io/badge/license-MIT-blue.svg?style=flat-square
|
||||
[license-url]: LICENSE
|
||||
[percy-image]: https://percy.io/static/images/percy-badge.svg
|
||||
@@ -307,7 +316,7 @@ MIT © [OHIF](https://github.com/OHIF)
|
||||
[deployment-docs]: https://docs.ohif.org/deployment/
|
||||
[react-url]: https://reactjs.org/
|
||||
[pwa-url]: https://developers.google.com/web/progressive-web-apps/
|
||||
[ohif-viewer-url]: https://www.npmjs.com/package/@ohif/app
|
||||
[ohif-viewer-url]: https://www.npmjs.com/package/@ohif/viewer
|
||||
[configuration-url]: https://docs.ohif.org/configuring/
|
||||
[extensions-url]: https://docs.ohif.org/extensions/
|
||||
<!-- Platform -->
|
||||
@@ -317,8 +326,8 @@ MIT © [OHIF](https://github.com/OHIF)
|
||||
[i18n-npm]: https://www.npmjs.com/package/@ohif/i18n
|
||||
[platform-ui]: platform/ui/README.md
|
||||
[ui-npm]: https://www.npmjs.com/package/@ohif/ui
|
||||
[platform-viewer]: platform/app/README.md
|
||||
[viewer-npm]: https://www.npmjs.com/package/@ohif/app
|
||||
[platform-viewer]: platform/viewer/README.md
|
||||
[viewer-npm]: https://www.npmjs.com/package/@ohif/viewer
|
||||
<!-- Extensions -->
|
||||
[extension-cornerstone]: extensions/cornerstone/README.md
|
||||
[cornerstone-npm]: https://www.npmjs.com/package/@ohif/extension-cornerstone
|
||||
|
||||
+22
-31
@@ -1,32 +1,10 @@
|
||||
// https://babeljs.io/docs/en/options#babelrcroots
|
||||
const { extendDefaultPlugins } = require('svgo');
|
||||
const aliases = require('./aliases.config');
|
||||
const path = require('path');
|
||||
|
||||
// https://babeljs.io/docs/en/options#babelrcroots
|
||||
module.exports = {
|
||||
babelrcRoots: ['./platform/*', './extensions/*', './modes/*'],
|
||||
presets: [
|
||||
'@babel/preset-env',
|
||||
'@babel/preset-react',
|
||||
'@babel/preset-typescript',
|
||||
],
|
||||
plugins: [
|
||||
[
|
||||
'inline-react-svg',
|
||||
{
|
||||
svgo: {
|
||||
plugins: extendDefaultPlugins([
|
||||
{
|
||||
name: 'removeViewBox',
|
||||
active: false,
|
||||
},
|
||||
]),
|
||||
},
|
||||
},
|
||||
],
|
||||
['@babel/plugin-proposal-class-properties', { loose: true }],
|
||||
'@babel/plugin-transform-typescript',
|
||||
['@babel/plugin-proposal-private-property-in-object', { loose: true }],
|
||||
['@babel/plugin-proposal-private-methods', { loose: true }],
|
||||
],
|
||||
babelrcRoots: ['./platform/*', './extensions/*'],
|
||||
plugins: ['inline-react-svg', '@babel/plugin-proposal-class-properties'],
|
||||
env: {
|
||||
test: {
|
||||
presets: [
|
||||
@@ -39,14 +17,12 @@ module.exports = {
|
||||
},
|
||||
],
|
||||
'@babel/preset-react',
|
||||
'@babel/preset-typescript',
|
||||
],
|
||||
plugins: [
|
||||
'@babel/plugin-proposal-object-rest-spread',
|
||||
'@babel/plugin-syntax-dynamic-import',
|
||||
'@babel/plugin-transform-regenerator',
|
||||
'@babel/plugin-transform-runtime',
|
||||
'@babel/plugin-transform-typescript',
|
||||
],
|
||||
},
|
||||
production: {
|
||||
@@ -54,7 +30,6 @@ module.exports = {
|
||||
// WebPack handles ES6 --> Target Syntax
|
||||
['@babel/preset-env', { modules: false }],
|
||||
'@babel/preset-react',
|
||||
'@babel/preset-typescript',
|
||||
],
|
||||
ignore: ['**/*.test.jsx', '**/*.test.js', '__snapshots__', '__tests__'],
|
||||
},
|
||||
@@ -63,10 +38,26 @@ module.exports = {
|
||||
// WebPack handles ES6 --> Target Syntax
|
||||
['@babel/preset-env', { modules: false }],
|
||||
'@babel/preset-react',
|
||||
'@babel/preset-typescript',
|
||||
],
|
||||
plugins: ['react-hot-loader/babel'],
|
||||
ignore: ['**/*.test.jsx', '**/*.test.js', '__snapshots__', '__tests__'],
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
// TODO: Plugins; Aliases
|
||||
// We don't currently use aliases, but this is a nice snippet that would help
|
||||
// [
|
||||
// 'module-resolver',
|
||||
// {
|
||||
// // https://github.com/tleunen/babel-plugin-module-resolver/issues/338
|
||||
// // There seem to be a bug with module-resolver with a mono-repo setup:
|
||||
// // It doesn't resolve paths correctly when using root/alias combo, so we
|
||||
// // use this function instead.
|
||||
// resolvePath(sourcePath, currentFile, opts) {
|
||||
// // This will return undefined if aliases has no key for the sourcePath,
|
||||
// // in which case module-resolver will fallback on its default behaviour.
|
||||
// return aliases[sourcePath];
|
||||
// },
|
||||
// },
|
||||
// ],
|
||||
@@ -0,0 +1,64 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Set directory to location of this script
|
||||
# https://stackoverflow.com/a/3355423/1867984
|
||||
cd "$(dirname "$0")"
|
||||
|
||||
yarn -v
|
||||
node -v
|
||||
|
||||
echo 'Installing Gitbook CLI'
|
||||
yarn global add gitbook-cli
|
||||
|
||||
echo 'Running Gitbook installation'
|
||||
|
||||
# Generate all version's GitBook output
|
||||
# For each directory in /docs ...
|
||||
cd ./../docs/
|
||||
for D in *; do
|
||||
if [ -d "${D}" ]; then
|
||||
|
||||
echo "Generating output for: ${D}"
|
||||
cd "${D}"
|
||||
|
||||
# Clear previous output, generate new
|
||||
rm -rf _book
|
||||
gitbook install
|
||||
gitbook build
|
||||
|
||||
cd ..
|
||||
|
||||
fi
|
||||
done
|
||||
|
||||
# Move CNAME File into `latest`
|
||||
cp CNAME ./latest/_book/CNAME
|
||||
|
||||
# Create a history folder in our latest version's output
|
||||
mkdir ./latest/_book/history
|
||||
|
||||
# Move each version's files to latest's history folder
|
||||
for D in *; do
|
||||
if [ -d "${D}" ]; then
|
||||
if [ "${D}" == v* ] ; then
|
||||
|
||||
echo "Moving ${D} to the latest version's history folder"
|
||||
|
||||
mkdir "./latest/_book/history/${D}"
|
||||
cp -v -r "./${D}/_book"/* "./latest/_book/history/${D}"
|
||||
|
||||
fi
|
||||
fi
|
||||
done
|
||||
|
||||
# Back to repo root
|
||||
cd ..
|
||||
|
||||
echo "Done generating documentation output"
|
||||
echo 'PUBLISHING'
|
||||
|
||||
./node_modules/.bin/gh-pages \
|
||||
--silent \
|
||||
--repo https://$GITHUB_TOKEN@github.com/OHIF/Viewers.git \
|
||||
--message 'Autogenerated Message: [ci skip]' \
|
||||
--dist docs/latest/_book
|
||||
@@ -1 +0,0 @@
|
||||
3d8cc9801a8a0b2add8f2b57b5a8498d9f0522c4
|
||||
@@ -0,0 +1 @@
|
||||
_book/
|
||||
@@ -0,0 +1 @@
|
||||
docs.ohif.org
|
||||
@@ -0,0 +1,46 @@
|
||||
# How To: Documentation Step-by-Step
|
||||
|
||||
We use [GitBook](https://www.gitbook.com/) to create our documentation. It primarily uses markdown, html, css, js, misc. plugins, and configuration to generate high quality, easy to read, and easy to maintain documentation.
|
||||
|
||||
## Getting Started
|
||||
|
||||
_Requirements:_
|
||||
|
||||
Make sure you have the [`gitbook-cli`](https://www.npmjs.com/package/gitbook-cli) installed globally:
|
||||
|
||||
> `npm install -g gitbook-cli`
|
||||
|
||||
### Editing and Previewing Changes
|
||||
|
||||
Currently, you can only edit and preview a single "book" at a time. We maintain one "book" per API major version. You can find each version's book at:
|
||||
|
||||
_Past Versions:_
|
||||
|
||||
- Template:
|
||||
- `<project-root>/docs/v<versionNumber>`
|
||||
- Examples:
|
||||
- `/docs/v1`
|
||||
- `/docs/v2`
|
||||
|
||||
_Latest Version:_
|
||||
|
||||
The latest version will always be located in `/docs/latest`
|
||||
|
||||
_Live Preview:_
|
||||
|
||||
In your terminal / command prompt:
|
||||
|
||||
```bash
|
||||
cd /docs/latest
|
||||
gitbook install
|
||||
gitbook serve
|
||||
```
|
||||
|
||||
Which should generate output like:
|
||||
|
||||
> starting server...
|
||||
> serving book on http://localhost:4000
|
||||
|
||||
Navigating to the the provided URL will show a preview of what the generated book should look like. Any edits you make to the book's markdown files should automatically update in your browser.
|
||||
|
||||
### Publishing
|
||||
@@ -0,0 +1,3 @@
|
||||
# Netlify redirects
|
||||
# SPA rules for our docs
|
||||
/* /index.html 200
|
||||
File renamed without changes.
@@ -0,0 +1,54 @@
|
||||
<div class='row'>
|
||||
<div class='column' style='text-align: right; padding: 0 20px'>
|
||||
<strong>Looking for a Live Demo?</strong>
|
||||
<a href="http://viewer.ohif.org/">Preview The OHIF Viewer</a>
|
||||
</div>
|
||||
<div class='column' style='text-align: left; padding: 0 20px'>
|
||||
<a href="https://www.netlify.com">
|
||||
<img src="https://www.netlify.com/img/global/badges/netlify-color-bg.svg"/>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
> ATTENTION! You are looking at the docs for the `React` version of the OHIF
|
||||
> Viewer. If you're looking for the `Meteor` version's documentation (now
|
||||
> deprecated), select it's version from the dropdown box in the top left corner
|
||||
> of this page.
|
||||
|
||||
# Introduction
|
||||
|
||||
The [Open Health Imaging Foundation][ohif-org] (OHIF) Viewer is an open source,
|
||||
web-based, medical imaging viewer. It can be configured to connect to Image
|
||||
Archives that support [DicomWeb][dicom-web], and offers support for mapping to
|
||||
proprietary API formats. OHIF maintained extensions add support for viewing,
|
||||
annotating, and reporting on DICOM images in 2D (slices) and 3D (volumes).
|
||||
|
||||

|
||||
|
||||
<center><i>The <strong>OHIF Viewer</strong>: A general purpose DICOM Viewer (<a href="http://viewer.ohif.org/">Live Demo</a>)</center>
|
||||
|
||||
The Open Health Imaging Foundation intends to provide a simple general purpose
|
||||
DICOM Viewer which can be easily extended for specific uses. If you find
|
||||
yourself unable to extend the viewer for your purposes, please reach out via our
|
||||
[GitHub issues][gh-issues]. We are actively seeking feedback on ways to improve
|
||||
our integration and extension points.
|
||||
|
||||
## Where to next?
|
||||
|
||||
Check out these helpful links:
|
||||
|
||||
- Ready to dive into some code? Check out our
|
||||
[Getting Started Guide](./development/getting-started.md).
|
||||
- We're an active, vibrant community.
|
||||
[Learn how you can be more involved.](./development/contributing.md)
|
||||
- Feeling lost? Read our [help page](./help.md).
|
||||
|
||||
<!--
|
||||
Links
|
||||
-->
|
||||
|
||||
<!-- prettier-ignore-start -->
|
||||
[ohif-org]: http://www.ohif.org
|
||||
[dicom-web]: https://en.wikipedia.org/wiki/DICOMweb
|
||||
[gh-issues]: https://github.com/OHIF/Viewers/issues
|
||||
<!-- prettier-ignore-end -->
|
||||
@@ -0,0 +1,61 @@
|
||||
# OHIF Viewers
|
||||
|
||||
- [Our Process](our-process.md)
|
||||
- Development
|
||||
- [Getting Started](development/getting-started.md)
|
||||
- [Contributing](development/contributing.md)
|
||||
- [Continuous Integration](development/continous-integration.md)
|
||||
- [Testing](development/testing.md)
|
||||
- [Configuring](configuring/index.md)
|
||||
- [Data Source](configuring/data-source.md)
|
||||
|
||||
---
|
||||
|
||||
- [Architecture](architecture/index.md)
|
||||
- [Viewer](viewer/index.md)
|
||||
- [Configuration](viewer/configuration.md)
|
||||
- [Themeing](viewer/themeing.md)
|
||||
- [Internationalization](viewer/internationalization.md)
|
||||
- [Extensions](extensions/index.md)
|
||||
- [Registering](extensions/index.md#registering-an-extension)
|
||||
- [Lifecycle Hooks](extensions/index.md#lifecycle-hooks)
|
||||
- [preRegistration](extensions/lifecycle/pre-registration.md)
|
||||
- [Modules](extensions/index.md#modules)
|
||||
- [Commands](extensions/modules/commands.md)
|
||||
- [Panel](extensions/modules/panel.md)
|
||||
- [SOP Class Handler](extensions/modules/sop-class-handler.md)
|
||||
- [Toolbar](extensions/modules/toolbar.md)
|
||||
- [Viewport](extensions/modules/viewport.md)
|
||||
- [Contexts](extensions/index.md#contexts)
|
||||
- [ExtensionManager](extensions/index.md#extensionmanager)
|
||||
- [OHIF Maintained](extensions/index.md#maintained-extensions)
|
||||
- [Services](services/index.md)
|
||||
- [Default](services/default/index.md)
|
||||
- [UI](services/ui/index.md)
|
||||
- [Dialog Service](services/ui/ui-dialog-service.md)
|
||||
- [Modal Service](services/ui/ui-modal-service.md)
|
||||
- [Notification Service](services/ui/ui-notification-service.md)
|
||||
|
||||
---
|
||||
|
||||
- [Deployment](deployment/index.md)
|
||||
- [Embedded](deployment/index.md#embedded-viewer)
|
||||
- [Stand-alone](deployment/index.md#stand-alone-viewer)
|
||||
- [Data](deployment/index.md#data)
|
||||
- Recipes
|
||||
- Script Include
|
||||
- [Embedding the Viewer](deployment/recipes/embedded-viewer.md)
|
||||
- Stand-Alone
|
||||
- [Build for Production](deployment/recipes/build-for-production.md)
|
||||
- [Static](deployment/recipes/static-assets.md)
|
||||
- [Nginx + Image Archive](deployment/recipes/nginx--image-archive.md)
|
||||
- [User Account Control](deployment/recipes/user-account-control.md)
|
||||
- [Google Cloud Healthcare](connecting-to-image-archives/google-cloud-healthcare.md)
|
||||
|
||||
---
|
||||
|
||||
- [FAQ](faq/index.md)
|
||||
- [Scope of Project](faq/scope-of-project.md)
|
||||
- [Browser Support](faq/browser-support.md)
|
||||
- [PWA vs Packaged](faq/pwa-vs-packaged.md)
|
||||
- [Help](help.md)
|
||||
@@ -0,0 +1,153 @@
|
||||
# Architecture
|
||||
|
||||
Looking to extend your instance of the OHIF Viewer? Want learn how to reuse _a
|
||||
portion_ of the Viewer in your own application? Or maybe you want to get
|
||||
involved and draft or suggest a new feature? Regardless, you're in the right
|
||||
place!
|
||||
|
||||
The OHIF Viewer aims to be decoupled, configurable, and extensible; while this
|
||||
allows our code to be used in more ways, it also increases complexity. Below, we
|
||||
aim to demistify that complexity by providing insight into how our Viewer is
|
||||
architected, and the role each of it's dependent libraries plays.
|
||||
|
||||
- [Overview](#overview)
|
||||
- [Business Logic](#business-logic)
|
||||
- [Component Library](#react-component-library)
|
||||
- [Extensions & Configuration](#extensions--configuration)
|
||||
- [Common Questions](#common-questions)
|
||||
|
||||
## Overview
|
||||
|
||||
The [OHIF Medical Image Viewing Platform][viewers-project] is maintained as a
|
||||
[`monorepo`][monorepo]. This means that this repository, instead of containing a
|
||||
single project, contains many projects. If you explore our project structure,
|
||||
you'll see the following:
|
||||
|
||||
```bash
|
||||
.
|
||||
├── extensions
|
||||
│ ├── _example # Skeleton of example extension
|
||||
│ ├── cornerstone # 2D images w/ Cornerstone.js
|
||||
│ ├── dicom-html # Structured Reports as HTML in viewport
|
||||
│ ├── dicom-microscopy # Whole slide microscopy viewing
|
||||
│ ├── dicom-pdf # View DICOM wrapped PDFs in viewport
|
||||
│ └── vtk # MPR and Volume support w/ VTK.js
|
||||
│
|
||||
├── platform
|
||||
│ ├── core # Business Logic
|
||||
│ ├── i18n # Internationalization Support
|
||||
│ ├── ui # React component library
|
||||
│ └── viewer # Connects platform and extension projects
|
||||
│
|
||||
├── ... # misc. shared configuration
|
||||
├── lerna.json # MonoRepo (Lerna) settings
|
||||
├── package.json # Shared devDependencies and commands
|
||||
└── README.md
|
||||
```
|
||||
|
||||
The `platform` directory contains the business logic library, component library,
|
||||
and the application library that combines them to create a powerful medical
|
||||
imaging viewer.
|
||||
|
||||
The `extensions` directory contains many packages that can be registered with
|
||||
`@ohif/core`'s `ExtensionManager` to expand an application's supported features
|
||||
and functionality.
|
||||
|
||||

|
||||
|
||||
<center><i>architecture diagram</i></center>
|
||||
|
||||
This diagram is a conceptual illustration of how the Viewer is architected.
|
||||
|
||||
1. (optional) `extensions` can be registered with `@ohif/core`'s
|
||||
`ExtensionManager`
|
||||
2. `@ohif/core` provides bussiness logic and a way for `@ohif/viewer` to access
|
||||
registered extensions
|
||||
3. The `@ohif/viewer` composes and provides data to components from our
|
||||
component library (`@ohif/ui`)
|
||||
4. The `@ohif/viewer` can be built and served as a stand-alone PWA, or as an
|
||||
embeddable package ([`@ohif/viewer`][viewer-npm])
|
||||
|
||||
## Business Logic
|
||||
|
||||
The [`@ohif/core`][core-github] project offers pre-packaged solutions for
|
||||
features common to Web-based medical imaging viewers. For example:
|
||||
|
||||
- Hotkeys
|
||||
- DICOM Web requests
|
||||
- Hanging Protocols
|
||||
- Managing a study's measurements
|
||||
- Managing a study's DICOM metadata
|
||||
- [A flexible pattern for extensions](../extensions/index.md)
|
||||
- And many others
|
||||
|
||||
It does this while remaining decoupled from any particular view library or
|
||||
rendering logic. While we use it to power our React Viewer, it can be used with
|
||||
Vue, React, Vanilla JS, or any number of other frameworks.
|
||||
|
||||
## React Component Library
|
||||
|
||||
[`@ohif/ui`][ui-github] is a React Component library that contains the reusable
|
||||
components that power the OHIF Viewer. It allows us to build, compose, and test
|
||||
components in isolation; easing the development process by reducing the need to
|
||||
stand-up a local PACS with test case data.
|
||||
|
||||
Extension authors can also use these same components when building their
|
||||
extension's UI; allowing for a consistent look and feel with the rest of the
|
||||
application.
|
||||
|
||||
[Check out our component library!](https://react.ohif.org/)
|
||||
|
||||
## Extensions & Configuration
|
||||
|
||||
While OHIF maintains several high value and commonly requested features in its
|
||||
own extensions, there are many instances where one may wish to further extend
|
||||
the viewer. Some common use cases include:
|
||||
|
||||
- Adding AI/ML tools and insights
|
||||
- Custom workflows for guided diagnosis
|
||||
- Collecting specific annotations for training data or reports
|
||||
- Authentication and granular permissions
|
||||
- Teleconsultation workflow, image comments, and tracking
|
||||
- Adding surgical templating tools and reports
|
||||
- and many others
|
||||
|
||||
We expose common integration points via [extensions](../extensions/index.md) to
|
||||
make this possible. The viewer and many of our own extensions also offer
|
||||
[configuration][configuration]. For a list of extensions maintained by OHIF,
|
||||
[check out this helpful table](../extensions/index.md#maintained-extensions).
|
||||
|
||||
If you find yourself thinking "I wish the Viewer could do X", and you can't
|
||||
accomplish it with an extension today, create a GitHub issue! We're actively
|
||||
looking for ways to improve our extensibility ^\_^
|
||||
|
||||
[Click here to read more about extensions!](../extensions/index.md)
|
||||
|
||||
## Common Questions
|
||||
|
||||
> When should I use the packaged source `@ohif/viewer` versus building a PWA
|
||||
> from the source?
|
||||
|
||||
...
|
||||
|
||||
> Can I create my own Viewer using Vue.js or Angular.js?
|
||||
|
||||
You can, but you will not be able to leverage as much of the existing code and
|
||||
components. `@ohif/core` could still be used for business logic, and to provide
|
||||
a model for extensions. `@ohif/ui` would then become a guide for the components
|
||||
you would need to recreate.
|
||||
|
||||
<!--
|
||||
Links
|
||||
-->
|
||||
|
||||
<!-- prettier-ignore-start -->
|
||||
[monorepo]: https://github.com/OHIF/Viewers/issues/768
|
||||
[viewers-project]: https://github.com/OHIF/Viewers
|
||||
[viewer-npm]: https://www.npmjs.com/package/@ohif/viewer
|
||||
[pwa]: https://developers.google.com/web/progressive-web-apps/
|
||||
[configuration]: ../configuring/index.md
|
||||
[extensions]: ../extensions/index.md
|
||||
[core-github]: https://github.com/OHIF/viewers/platform/core
|
||||
[ui-github]: https://github.com/OHIF/Viewers/tree/master/platform/ui
|
||||
<!-- prettier-ignore-end -->
|
||||
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
Binary file not shown.
|
After Width: | Height: | Size: 20 MiB |
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
@@ -0,0 +1,50 @@
|
||||
{
|
||||
"title": "OHIF",
|
||||
"description": "Documentation for the OHIF framework",
|
||||
"gitbook": ">3.0.0",
|
||||
"plugins": [
|
||||
"edit-link",
|
||||
"theme-cornerstone",
|
||||
"-fontsettings",
|
||||
"github",
|
||||
"ga",
|
||||
"sitemap",
|
||||
"anchors",
|
||||
"versions"
|
||||
],
|
||||
"pluginsConfig": {
|
||||
"edit-link": {
|
||||
"base": "https://github.com/OHIF/Viewers/edit/master/docs",
|
||||
"label": "Edit This Page"
|
||||
},
|
||||
"github": {
|
||||
"url": "https://github.com/OHIF/Viewers"
|
||||
},
|
||||
"ga": {
|
||||
"token": "UA-110573590-2"
|
||||
},
|
||||
"sitemap": {
|
||||
"hostname": "https://docs.ohif.org"
|
||||
},
|
||||
"versions": {
|
||||
"gitbookConfigURL": "https://raw.githubusercontent.com/OHIF/Viewers/master/docs/book.json",
|
||||
"options": [
|
||||
{
|
||||
"value": "https://docs.ohif.org/history/v1/",
|
||||
"text": "Version 1.0.0 (Meteor)"
|
||||
},
|
||||
{
|
||||
"value": "https://docs.ohif.org/",
|
||||
"text": "Version 2.0.0",
|
||||
"selected": true
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"links": {
|
||||
"sharing": {
|
||||
"facebook": false,
|
||||
"twitter": false
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,170 @@
|
||||
# Data Source
|
||||
|
||||
After following the steps outlined in
|
||||
[Getting Started](./../development/getting-started.md), you'll notice that the
|
||||
OHIF Viewer has data for several studies and their images. You didn't add this
|
||||
data, so where is it coming from?
|
||||
|
||||
By default, the viewer is configured to connect to a remote server hosted by the
|
||||
nice folks over at [dcmjs.org][dcmjs-org]. While convenient for getting started,
|
||||
the time may come when you want to develop using your own data either locally or
|
||||
remotely.
|
||||
|
||||
## Set up a local DICOM server
|
||||
|
||||
> ATTENTION! Already have a remote or local server? Skip to the
|
||||
> [configuration section](#configuration-learn-more) below.
|
||||
|
||||
While the OHIF Viewer can work with any data source, the easiest to configure
|
||||
are the ones that follow the [DICOMWeb][dicom-web] spec.
|
||||
|
||||
1. Choose and install an Image Archive
|
||||
2. Upload data to your archive (e.g. with DCMTK's [storescu][storescu] or your
|
||||
archive's web interface)
|
||||
3. Keep the server running
|
||||
|
||||
For our purposes, we will be using `Orthanc`, but you can see a list of
|
||||
[other Open Source options](#open-source-dicom-image-archives) below.
|
||||
|
||||
### Requirements
|
||||
|
||||
- Docker
|
||||
- [Docker for Mac](https://docs.docker.com/docker-for-mac/)
|
||||
- [Docker for Windows (recommended)](https://docs.docker.com/docker-for-windows/)
|
||||
- [Docker Toolbox for Windows](https://docs.docker.com/toolbox/toolbox_install_windows/)
|
||||
|
||||
_Not sure if you have `docker` installed already? Try running `docker --version`
|
||||
in command prompt or terminal_
|
||||
|
||||
> If you are using `Docker Toolbox` you need to change the _PROXY_DOMAIN_
|
||||
> parameter in _platform/viewer/package.json_ to http://192.168.99.100:8042 or
|
||||
> the ip docker-machine ip throws. This is the value [`WebPack`][webpack-proxy]
|
||||
> uses to proxy requests
|
||||
|
||||
### Running Orthanc
|
||||
|
||||
_Start Orthanc:_
|
||||
|
||||
```bash
|
||||
# Runs orthanc so long as window remains open
|
||||
yarn run orthanc:up
|
||||
```
|
||||
|
||||
_Upload your first Study:_
|
||||
|
||||
1. Navigate to
|
||||
[Orthanc's web interface](http://localhost:8042/app/explorer.html) at
|
||||
`http://localhost:8042/app/explorer.html` in a web browser.
|
||||
2. In the top right corner, click "Upload"
|
||||
3. Click "Select files to upload..." and select one or more DICOM files
|
||||
4. Click "Start the upload"
|
||||
|
||||
#### Orthanc: Learn More
|
||||
|
||||
You can see the `docker-compose.yml` file this command runs at
|
||||
[`<project-root>/.docker/Nginx-Orthanc/`][orthanc-docker-compose], and more on
|
||||
Orthanc for Docker in [Orthanc's documentation][orthanc-docker].
|
||||
|
||||
### Connecting to Orthanc
|
||||
|
||||
Now that we have a local Orthanc instance up and running, we need to configure
|
||||
our web application to connect to it. Open a new terminal window, navigate to
|
||||
this repository's root directory, and run:
|
||||
|
||||
```bash
|
||||
# If you haven't already, enable yarn workspaces
|
||||
yarn config set workspaces-experimental true
|
||||
|
||||
# Restore dependencies
|
||||
yarn install
|
||||
|
||||
# Run our dev command, but with the local orthanc config
|
||||
yarn run dev:orthanc
|
||||
```
|
||||
|
||||
#### Configuration: Learn More
|
||||
|
||||
> For more configuration fun, check out the
|
||||
> [Essentials Configuration](./index.md) guide.
|
||||
|
||||
Let's take a look at what's going on under the hood here. `yarn run dev:orthanc`
|
||||
is running the `dev:orthanc` script in our project's `package.json`. That script
|
||||
is:
|
||||
|
||||
```js
|
||||
cross-env NODE_ENV=development PROXY_TARGET=/dicom-web PROXY_DOMAIN=http://localhost:8042 APP_CONFIG=config/docker_nginx-orthanc.js webpack-dev-server --config .webpack/webpack.pwa.js -w
|
||||
```
|
||||
|
||||
- `cross-env` sets three environment variables
|
||||
- PROXY_TARGET: `/dicom-web`
|
||||
- PROXY_DOMAIN: `http://localhost:8042`
|
||||
- APP_CONFIG: `config/docker_nginx-orthanc.js`
|
||||
- `webpack-dev-server` runs using the `.webpack/webpack.pwa.js` configuration
|
||||
file. It will watch for changes and update as we develop.
|
||||
|
||||
`PROXY_TARGET` and `PROXY_DOMAIN` tell our development server to proxy requests
|
||||
to `Orthanc`. This allows us to bypass CORS issues that normally occur when
|
||||
requesting resources that live at a different domain.
|
||||
|
||||
The `APP_CONFIG` value tells our app which file to load on to `window.config`.
|
||||
By default, our app uses the file at
|
||||
`<project-root>/platform/viewer/public/config/default.js`. Here is what that
|
||||
configuration looks like:
|
||||
|
||||
```js
|
||||
window.config = {
|
||||
routerBasename: '/',
|
||||
servers: {
|
||||
dicomWeb: [
|
||||
{
|
||||
name: 'Orthanc',
|
||||
wadoUriRoot: 'http://localhost:8899/wado',
|
||||
qidoRoot: 'http://localhost:8899/dicom-web',
|
||||
wadoRoot: 'http://localhost:8899/dicom-web',
|
||||
qidoSupportsIncludeField: false,
|
||||
imageRendering: 'wadors',
|
||||
thumbnailRendering: 'wadors',
|
||||
},
|
||||
],
|
||||
},
|
||||
};
|
||||
```
|
||||
|
||||
To learn more about how you can configure the OHIF Viewer, check out our
|
||||
[Configuration Guide](./index.md).
|
||||
|
||||
## Open Source DICOM Image Archives
|
||||
|
||||
Our example uses `Orthanc`, but there are a lot of options available to you.
|
||||
Here are some of the more popular ones:
|
||||
|
||||
| Archive | Installation |
|
||||
| --------------------------------------------- | ---------------------------------- |
|
||||
| [DCM4CHEE Archive 5.x][dcm4chee] | [W/ Docker][dcm4chee-docker] |
|
||||
| [Orthanc][orthanc] | [W/ Docker][orthanc-docker] |
|
||||
| [DICOMcloud][dicomcloud] (**DICOM Web only**) | [Installation][dicomcloud-install] |
|
||||
| [OsiriX][osirix] (**Mac OSX only**) | Desktop Client |
|
||||
| [Horos][horos] (**Mac OSX only**) | Desktop Client |
|
||||
|
||||
_Feel free to make a Pull Request if you want to add to this list._
|
||||
|
||||
<!--
|
||||
Links
|
||||
-->
|
||||
|
||||
<!-- prettier-ignore-start -->
|
||||
[dcmjs-org]: https://server.dcmjs.org/dcm4chee-arc/aets/DCM4CHEE/wado
|
||||
[dicom-web]: https://en.wikipedia.org/wiki/DICOMweb
|
||||
[storescu]: http://support.dcmtk.org/docs/storescu.html
|
||||
[webpack-proxy]: https://webpack.js.org/configuration/dev-server/#devserverproxy
|
||||
[orthanc-docker-compose]: https://github.com/OHIF/Viewers/tree/master/.docker/Nginx-Orthanc
|
||||
<!-- Archives -->
|
||||
[dcm4chee]: https://github.com/dcm4che/dcm4chee-arc-light
|
||||
[dcm4chee-docker]: https://github.com/dcm4che/dcm4chee-arc-light/wiki/Running-on-Docker
|
||||
[orthanc]: https://www.orthanc-server.com/
|
||||
[orthanc-docker]: http://book.orthanc-server.com/users/docker.html
|
||||
[dicomcloud]: https://github.com/DICOMcloud/DICOMcloud
|
||||
[dicomcloud-install]: https://github.com/DICOMcloud/DICOMcloud#running-the-code
|
||||
[osirix]: http://www.osirix-viewer.com/
|
||||
[horos]: https://www.horosproject.org/
|
||||
<!-- prettier-ignore-end -->
|
||||
@@ -0,0 +1,126 @@
|
||||
# Configuration
|
||||
|
||||
> This step assumes you have an imaging archive. If you need assistance setting
|
||||
> one up, check out the [`Data Source` Guide](./data-source.md) or a deployment
|
||||
> recipe that contains an open Image Archive
|
||||
|
||||
- [Overview](#overview)
|
||||
- [Configuration Files](#configuration-files)
|
||||
- [Environment Variables](#environment-variables)
|
||||
- [How do I configure my project?](#how-do-i-configure-my-project)
|
||||
|
||||
## Overview
|
||||
|
||||
### Configuration Files
|
||||
|
||||
The configuration for our viewer is in the `<root>platform/viewer/public/config`
|
||||
directory. Our build process knows which configuration file to use based on the
|
||||
`APP_CONFIG` environment variable. By default, its value is
|
||||
[`config/default.js`][default-config]. The majority of the viewer's features,
|
||||
and registered extension's features, are configured using this file.
|
||||
|
||||
**Embedded Use Note:**
|
||||
|
||||
Alternatively, when using the `umd` bundle for embedded use cases, these same
|
||||
values are what you'll pass to `installViewer` method:
|
||||
|
||||
`OHIFStandaloneViewer.installViewer(window.config)`
|
||||
|
||||
### Environment Variables
|
||||
|
||||
We use environment variables at build and dev time to change the Viewer's
|
||||
behavior. We can update the `HTML_TEMPLATE` to easily change which extensions
|
||||
are registered, and specify a different `APP_CONFIG` to connect to an
|
||||
alternative data source (or even specify different default hotkeys).
|
||||
|
||||
| Environment Variable | Description | Default |
|
||||
| -------------------- | -------------------------------------------------------------------------------------------------- | ------------------- |
|
||||
| `HTML_TEMPLATE` | Which [HTML template][html-templates] to use as our web app's entry point. Specific to PWA builds. | `index.html` |
|
||||
| `PUBLIC_URL` | The route relative to the host that the app will be served from. Specific to PWA builds. | `/` |
|
||||
| `APP_CONFIG` | Which [configuration file][config-file] to copy to output as `app-config.js` | `config/default.js` |
|
||||
| `PROXY_TARGET` | When developing, proxy requests that match this pattern to `PROXY_DOMAIN` | `undefined` |
|
||||
| `PROXY_DOMAIN` | When developing, proxy requests from `PROXY_TARGET` to `PROXY_DOMAIN` | `undefined` |
|
||||
|
||||
## How do I configure my project?
|
||||
|
||||
The simplest way is to update the existing default config:
|
||||
|
||||
_/platform/viewer/public/config/default.js_
|
||||
|
||||
```js
|
||||
window.config = {
|
||||
routerBasename: '/',
|
||||
servers: {
|
||||
dicomWeb: [
|
||||
{
|
||||
name: 'DCM4CHEE',
|
||||
wadoUriRoot: 'https://server.dcmjs.org/dcm4chee-arc/aets/DCM4CHEE/wado',
|
||||
qidoRoot: 'https://server.dcmjs.org/dcm4chee-arc/aets/DCM4CHEE/rs',
|
||||
wadoRoot: 'https://server.dcmjs.org/dcm4chee-arc/aets/DCM4CHEE/rs',
|
||||
qidoSupportsIncludeField: true,
|
||||
imageRendering: 'wadors',
|
||||
thumbnailRendering: 'wadors',
|
||||
},
|
||||
],
|
||||
},
|
||||
};
|
||||
```
|
||||
|
||||
The configuration can also be written as a JS Function in case you need to inject dependencies like external services:
|
||||
|
||||
```js
|
||||
window.config = ({ servicesManager } = {}) => {
|
||||
const { UIDialogService } = servicesManager.services;
|
||||
return {
|
||||
cornerstoneExtensionConfig: {
|
||||
tools: {
|
||||
ArrowAnnotate: {
|
||||
configuration: {
|
||||
getTextCallback: (callback, eventDetails) => UIDialogService.create({...
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
routerBasename: '/',
|
||||
servers: {
|
||||
dicomWeb: [
|
||||
{
|
||||
name: 'DCM4CHEE',
|
||||
wadoUriRoot: 'https://server.dcmjs.org/dcm4chee-arc/aets/DCM4CHEE/wado',
|
||||
qidoRoot: 'https://server.dcmjs.org/dcm4chee-arc/aets/DCM4CHEE/rs',
|
||||
wadoRoot: 'https://server.dcmjs.org/dcm4chee-arc/aets/DCM4CHEE/rs',
|
||||
qidoSupportsIncludeField: true,
|
||||
imageRendering: 'wadors',
|
||||
thumbnailRendering: 'wadors',
|
||||
},
|
||||
],
|
||||
},
|
||||
};
|
||||
};
|
||||
```
|
||||
|
||||
You can also create a new config file and specify its path relative to the build
|
||||
output's root by setting the `APP_CONFIG` environment variable. You can set the
|
||||
value of this environment variable a few different ways:
|
||||
|
||||
- ~[Add a temporary environment variable in your shell](https://facebook.github.io/create-react-app/docs/adding-custom-environment-variables#adding-temporary-environment-variables-in-your-shell)~
|
||||
- Previous `react-scripts` functionality that we need to duplicate with
|
||||
`dotenv-webpack`
|
||||
- ~[Add environment specific variables in `.env` file(s)](https://facebook.github.io/create-react-app/docs/adding-custom-environment-variables#adding-development-environment-variables-in-env)~
|
||||
- Previous `react-scripts` functionality that we need to duplicate with
|
||||
`dotenv-webpack`
|
||||
- Using the `cross-env` package in an npm script:
|
||||
- `"build": "cross-env APP_CONFIG=config/my-config.js react-scripts build"`
|
||||
|
||||
After updating the configuration, `yarn run build` to generate updated build
|
||||
output.
|
||||
|
||||
<!--
|
||||
Links
|
||||
-->
|
||||
|
||||
<!-- prettier-ignore-start -->
|
||||
[default-config]: https://github.com/OHIF/Viewers/blob/master/platform/viewer/public/config/default.js
|
||||
[html-templates]: https://github.com/OHIF/Viewers/tree/master/platform/viewer/public/html-templates
|
||||
[config-files]: https://github.com/OHIF/Viewers/tree/master/platform/viewer/public/config
|
||||
<!-- prettier-ignore-end -->
|
||||
@@ -0,0 +1,71 @@
|
||||
# Google Cloud Healthcare
|
||||
|
||||
> The [Google Cloud Healthcare API](https://cloud.google.com/healthcare/) is a
|
||||
> powerful option for storing medical imaging data in the cloud.
|
||||
|
||||
An alternative to deploying your own PACS is to use a software-as-a-service
|
||||
provider such as Google Cloud. The Cloud Healthcare API promises to be a
|
||||
scalable, secure, cost effective image storage solution for those willing to
|
||||
store their data in the cloud. It offers an
|
||||
[almost-entirely complete DICOMWeb API](https://cloud.google.com/healthcare/docs/dicom)
|
||||
which requires tokens generated via the
|
||||
[OAuth 2.0 Sign In flow](https://developers.google.com/identity/sign-in/web/sign-in).
|
||||
Images can even be transcoded on the fly if this is desired.
|
||||
|
||||
## Setup a Google Cloud Healthcare Project
|
||||
|
||||
- Create a Google Cloud account
|
||||
- Create a project in Google Cloud
|
||||
- Enable the [Cloud Healthcare API](https://cloud.google.com/healthcare/) for
|
||||
your project.
|
||||
- (Optional): Create a Dataset and Data Store for storing your DICOM data
|
||||
- Enable the
|
||||
[Cloud Resource Manager API](https://cloud.google.com/resource-manager/) for
|
||||
your project.
|
||||
- _Note:_ If you are having trouble finding the APIs, use the search box at
|
||||
the top of the Cloud console.
|
||||
- Go to APIs & Services > Credentials to create an OAuth Consent screen and fill
|
||||
in your application details.
|
||||
- Under Scopes for Google APIs, click "manually paste scopes".
|
||||
- Add the following scopes:
|
||||
- `https://www.googleapis.com/auth/cloudplatformprojects.readonly`
|
||||
- `https://www.googleapis.com/auth/cloud-healthcare`
|
||||
- Go to APIs & Services > Credentials to create a new set of credentials:
|
||||
|
||||
- Choose the "Web Application" type
|
||||
- Set up an
|
||||
[OAuth 2.0 Client ID](https://support.google.com/cloud/answer/6158849?hl=en)
|
||||
- Add your domain (e.g. `http://localhost:3000`) to Authorized JavaScript
|
||||
origins.
|
||||
- Add your domain, plus `callback` (e.g. `http://localhost:3000/callback`) to
|
||||
Authorized Redirect URIs.
|
||||
- Save your Client ID for later.
|
||||
|
||||
- (Optional): Enable Public Datasets that are being hosted by Google:
|
||||
https://cloud.google.com/healthcare/docs/resources/public-datasets/
|
||||
|
||||
## Run the viewer with your OAuth Client ID
|
||||
|
||||
1. Open the `config/google.js` file and change `YOURCLIENTID` to your Client ID
|
||||
value.
|
||||
1. Run the OHIF Viewer using the config/google.js configuration file
|
||||
|
||||
```bash
|
||||
cd OHIFViewer
|
||||
yarn install
|
||||
APP_CONFIG=config/google.js yarn run dev
|
||||
```
|
||||
|
||||
## Running via Docker
|
||||
|
||||
The OHIF Viewer Docker container can be connected to Google Cloud Healthcare by
|
||||
providing a Client ID at runtime. This is a very simple method to get up and
|
||||
running.
|
||||
|
||||
1. Install Docker (https://www.docker.com/)
|
||||
1. Run the Docker container, providing a Client ID as an environment variable.
|
||||
Client IDs look like `xyz.apps.googleusercontent.com`.
|
||||
|
||||
```bash
|
||||
docker run --env CLIENT_ID=$CLIENT_ID --publish 5000:80 ohif/viewer:latest
|
||||
```
|
||||
@@ -0,0 +1,4 @@
|
||||
<div style="text-align: center;">
|
||||
<img src="/assets/img/embedded-viewer-diagram.png" alt="Embedded Viewer Diagram" style="margin: 0 auto;" />
|
||||
<div><i>embedded viewer diagram</i></div>
|
||||
</div>
|
||||
@@ -0,0 +1,4 @@
|
||||
<div style="text-align: center;">
|
||||
<img src="/assets/img/nginx-image-archive.png" alt="request flow example" style="margin: 0 auto;" />
|
||||
<div><i>simplified request flow diagram</i></div>
|
||||
</div>
|
||||
@@ -0,0 +1,4 @@
|
||||
<div style="text-align: center;">
|
||||
<img src="/assets/img/user-access-control-request-flow.png" alt="request flow example" style="margin: 0 auto;" />
|
||||
<div><i>simplified request flow diagram</i></div>
|
||||
</div>
|
||||
@@ -0,0 +1,305 @@
|
||||
# Deployment
|
||||
|
||||
The OHIF Viewer can be embedded in other web applications via it's [packaged
|
||||
script source][viewer-npm], or served up as a stand-alone PWA ([progressive web
|
||||
application][pwa-url]) by building and hosting a collection of static assets. In
|
||||
either case, you will need to configure your instance of the Viewer so that it
|
||||
can connect to your data source (the database or PACS that provides the data
|
||||
your Viewer will display).
|
||||
|
||||
## Overview
|
||||
|
||||
Our goal is to make deployment as simple and painless as possible; however,
|
||||
there is an inherent amount of complexity in configuring and deploying web
|
||||
applications. If you find yourself a little lost, please don't hesitate to
|
||||
[reach out for help](/help.md)
|
||||
|
||||
## Deployment Scenarios
|
||||
|
||||
### Embedded Viewer
|
||||
|
||||
The quickest and easiest way to get the OHIF Viewer up and running is to embed
|
||||
it into an existing web application. It allows us to forego a "build step", and
|
||||
add a powerful medical imaging viewer to an existing web page using only a few
|
||||
include tags.
|
||||
|
||||
- Read more about it here: [Embedded Viewer](./recipes/embedded-viewer.md)
|
||||
- And check out our [live demo on CodeSandbox][code-sandbox]
|
||||
|
||||
{% include "./_embedded-viewer-diagram.md" %}
|
||||
|
||||
### Stand-alone Viewer
|
||||
|
||||
Deploying the OHIF Viewer as a stand-alone web application provides many
|
||||
benefits, but comes at the cost of time and complexity. Some benefits include:
|
||||
|
||||
_Today:_
|
||||
|
||||
- Leverage [extensions](/extensions/index.md) to drop-in powerful new features
|
||||
- Add routes and customize the viewer's workflow
|
||||
- Finer control over styling and whitelabeling
|
||||
|
||||
_In the future:_
|
||||
|
||||
- The ability to package the viewer for [App Store distribution][app-store]
|
||||
- Leverage `service-workers` for offline support and speed benefits from caching
|
||||
|
||||
#### Hosted Static Assets
|
||||
|
||||
At the end of the day, a production OHIF Viewer instance is a collection of
|
||||
HTML, CSS, JS, Font Files, and Images. We "build" those files from our
|
||||
`source code` with configuration specific to our project. We then make those
|
||||
files publicly accessible by hosting them on a Web Server.
|
||||
|
||||
If you have not deployed a web application before, this may be a good time to
|
||||
[reach out for help](/help.md), as these steps assume prior web development and
|
||||
deployment experience.
|
||||
|
||||
##### Part 1 - Build Production Assets
|
||||
|
||||
"Building", or creating, the files you will need is the same regardless of the
|
||||
web host you choose. You can find detailed instructions on how to configure and
|
||||
build the OHIF Viewer in our
|
||||
["Build for Production" guide](./recipes/build-for-production.md).
|
||||
|
||||
##### Part 2 - Host Your App
|
||||
|
||||
There are a lot of [benefits to hosting static assets][host-static-assets] over
|
||||
dynamic content. You can find instructions on how to host your build's output
|
||||
via one of these guides:
|
||||
|
||||
_Drag-n-drop_
|
||||
|
||||
- [Netlify: Drop](/deployment/recipes/static-assets.md#netlify-drop)
|
||||
|
||||
_Easy_
|
||||
|
||||
- [Surge.sh](/deployment/recipes/static-assets.md#surgesh)
|
||||
- [GitHub Pages](/deployment/recipes/static-assets.md#github-pages)
|
||||
|
||||
_Advanced_
|
||||
|
||||
- [AWS S3 + Cloudfront](/deployment/recipes/static-assets.md#aws-s3--cloudfront)
|
||||
- [GCP + Cloudflare](/deployment/recipes/static-assets.md#gcp--cloudflare)
|
||||
- [Azure](/deployment/recipes/static-assets.md#azure)
|
||||
|
||||
## Data
|
||||
|
||||
The OHIF Viewer is able to connect to any data source that implements the [DICOM
|
||||
Web Standard][dicom-web-standard]. [DICOM Web][dicom-web] refers to RESTful
|
||||
DICOM Services -- a recently standardized set of guidelines for exchanging
|
||||
medical images and imaging metadata over the internet. Not all archives fully
|
||||
support it yet, but it is gaining wider adoption.
|
||||
|
||||
### Configure Connection
|
||||
|
||||
If you have an existing archive and intend to host the OHIF Viewer at the same
|
||||
domain name as your archive, then connecting the two is as simple as following
|
||||
the steps layed out in our
|
||||
[Configuration Essentials Guide](./../configuring/index.md).
|
||||
|
||||
#### What if I don't have an imaging archive?
|
||||
|
||||
We provide some guidance on configuring a local image archive in our
|
||||
[Data Source Essentials](./../configuring/data-source.md) guide. Hosting an
|
||||
archive remotely is a little trickier. You can check out some of our
|
||||
[advanced recipes](#recipes) for modeled setups that may work for you.
|
||||
|
||||
#### What if I intend to host the OHIF Viewer at a different domain?
|
||||
|
||||
There are two important steps to making sure this setup works:
|
||||
|
||||
1. Your Image Archive needs to be exposed, in some way, to the open web. This
|
||||
can be directly, or through a `reverse proxy`, but the Viewer needs _some
|
||||
way_ to request it's data.
|
||||
2. \* Your Image Archive needs to have appropriate CORS (Cross-Origin Resource
|
||||
Sharing) Headers
|
||||
|
||||
> \* Cross-Origin Resource Sharing (CORS) is a mechanism that uses additional
|
||||
> HTTP headers to tell a browser to let a web application running at one origin
|
||||
> (domain) have permission to access selected resources from a server at a
|
||||
> different origin. - [MDN Web Docs: Web - Http - CORS][cors]
|
||||
|
||||
Most image archives do not provide either of these features "out of the box".
|
||||
It's common to use IIS, Nginx, or Apache to route incoming requests and append
|
||||
appropriate headers. You can find an example of this setup in our
|
||||
[Nginx + Image Archive Deployment Recipe](./recipes/nginx--image-archive.md).
|
||||
|
||||
#### What if my archive doesn't support DicomWeb?
|
||||
|
||||
It's possible to supply all Study data via JSON format, in the event you do not have a DicomWeb endpoint.
|
||||
You can host all of the relevant files on any web accessible server (Amazon S3, Azure Blob Storage, Local file server etc.)
|
||||
|
||||
This JSON is supplied via the '?url=' query parameter.
|
||||
It should reference an endpoint that returns **application/json** formatted text.
|
||||
|
||||
If you do not have an API, you can simply return a text file containing the JSON from any web server.
|
||||
|
||||
|
||||
You tell the OHIF viewer to use JSON by appending the `'?url='` query to the `/Viewer` route:
|
||||
|
||||
eg. `https://my-test-ohif-server/viewer?url=https://my-json-server/study-uid.json`
|
||||
|
||||
The returned JSON object must contain a single root object with a 'studies' array.
|
||||
|
||||
|
||||
*Sample JSON format:*
|
||||
```JSON
|
||||
{
|
||||
"studies": [
|
||||
{
|
||||
"StudyInstanceUID": "1.2.840.113619.2.5.1762583153.215519.978957063.78",
|
||||
"StudyDescription": "BRAIN SELLA",
|
||||
"StudyDate": "20010108",
|
||||
"StudyTime": "120022",
|
||||
"PatientName": "MISTER^MR",
|
||||
"PatientId": "832040",
|
||||
"series": [
|
||||
{
|
||||
"SeriesDescription": "SAG T-1",
|
||||
"SeriesInstanceUID": "1.2.840.113619.2.5.1762583153.215519.978957063.121",
|
||||
"SeriesNumber": 2,
|
||||
"SeriesDate": "20010108",
|
||||
"SeriesTime": "120318",
|
||||
"Modality": "MR",
|
||||
"instances": [
|
||||
{
|
||||
"metadata": {
|
||||
"Columns": 512,
|
||||
"Rows": 512,
|
||||
"InstanceNumber": 3,
|
||||
"AcquisitionNumber": 0,
|
||||
"PhotometricInterpretation": "MONOCHROME2",
|
||||
"BitsAllocated": 16,
|
||||
"BitsStored": 16,
|
||||
"PixelRepresentation": 1,
|
||||
"SamplesPerPixel": 1,
|
||||
"PixelSpacing": [0.390625, 0.390625],
|
||||
"HighBit": 15,
|
||||
"ImageOrientationPatient": [0,1,0,0,0,-1],
|
||||
"ImagePositionPatient": [11.600000,-92.500000, 98.099998],
|
||||
"FrameOfReferenceUID": "1.2.840.113619.2.5.1762583153.223134.978956938.470",
|
||||
"ImageType": ["ORIGINAL","PRIMARY","OTHER"],
|
||||
"Modality": "MR",
|
||||
"SOPInstanceUID": "1.2.840.113619.2.5.1762583153.215519.978957063.124",
|
||||
"SeriesInstanceUID": "1.2.840.113619.2.5.1762583153.215519.978957063.121",
|
||||
"StudyInstanceUID": "1.2.840.113619.2.5.1762583153.215519.978957063.78"
|
||||
},
|
||||
"url": "dicomweb://s3.amazonaws.com/lury/MRStudy/1.2.840.113619.2.5.1762583153.215519.978957063.124.dcm"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
More info on this JSON format can be found here [Issue #1500](https://github.com/OHIF/Viewers/issues/1500)
|
||||
|
||||
|
||||
**Implementation Notes:**
|
||||
|
||||
1. When hosting the viewer, you will also need to host a /viewer route on the server - or the browser may not be able to find the route.
|
||||
2. For each instance url (dicom object) in the returned JSON, you must prefix the `url` with `dicomweb:` in order for the cornerstone image loader to retrieve it correctly.
|
||||
eg. `https://image-server/my-image.dcm` ---> `dicomweb:https://image-server/my-image.dcm`
|
||||
3. The JSON format above is compatible with >= v3.7.8 of the application. Older versions of the viewer used a different JSON format. As of 20/04/20 the public [https://viewer.ohif.org/] is a pre 3.0 version that does not support this format yet.
|
||||
4. The JSON format is case-sensitive. Please ensure you have matched casing with the naturalised Dicom format referenced in [Issue #1500](https://github.com/OHIF/Viewers/issues/1500).
|
||||
|
||||
*CORS Issues (Cross-Origin Resource Sharing)*
|
||||
|
||||
If you host a JSON API or Images on a different domain from the the app itself, you will likely have CORS issues. This will also happen when testing from Localhost and reaching out to remote servers.
|
||||
Even if the domain is the same, different ports, subdomains or protocols (https vs http) will also cause CORS errors.
|
||||
You will to need add a configuration on each server hosting these assets to allow your App server origin.
|
||||
|
||||
For example:
|
||||
|
||||
Lets assume your application is hosted on `https://my-ohif-server.com`.
|
||||
|
||||
Your JSON API is hosted on `https://my-json-api.aws.com`
|
||||
|
||||
And your images are stored on Amazon S3 at `https://my-s3-bucket.aws.com`
|
||||
|
||||
When you first start your application, browsing to `https://my-ohif-server.com/viewer?url=https://my-json-api.aws.com/api/my-json-study-info.json`, you will likely get a CORS error in the browser console as it tries to connect to `https://my-json-api.aws.com`.
|
||||
|
||||
Adding a setting on the JSON server to allow the CORS origin = `https://my-ohif-server.com` should solve this.
|
||||
|
||||
Next, you will likely get a similar CORS error, as the browser tries to go to `https://my-s3-bucket.aws.com`.
|
||||
You will need to go to the S3 bucket configuration, and add a CORS setting to allow origin = `https://my-ohif-server.com`.
|
||||
|
||||
Essentially, whenever the application connects to a remote resource, you will need to add the applications url to the allowed CORS Origins on that resource. Adding an origin similar to https://localhost:3000 will also allow for local testing.
|
||||
|
||||
|
||||
### Securing Your Data
|
||||
|
||||
> Feeling lost? Securing your data is important, and it can be hard to tell if
|
||||
> you've gotten it right. Don't hesitate to work with professional auditors, or
|
||||
> [enlist help from experts](./../help.md).
|
||||
|
||||
The OHIF Viewer can be configured to work with authorization servers that
|
||||
support one or more of the OpenID-Connect authorization flows. The Viewer finds
|
||||
it's OpenID-Connect settings on the `oidc` configuration key. You can set these
|
||||
values following the instructions laid out in the
|
||||
[Configuration Essentials Guide](./../configuring/index.md).
|
||||
|
||||
_Example OpenID-Connect Settings:_
|
||||
|
||||
```js
|
||||
window.config = {
|
||||
...
|
||||
oidc: [
|
||||
{
|
||||
// ~ REQUIRED
|
||||
// Authorization Server URL
|
||||
authority: 'http://127.0.0.1/auth/realms/ohif',
|
||||
client_id: 'ohif-viewer',
|
||||
redirect_uri: 'http://127.0.0.1/callback', // `OHIFStandaloneViewer.js`
|
||||
response_type: 'code', // "Authorization Code Flow"
|
||||
scope: 'openid', // email profile openid
|
||||
// ~ OPTIONAL
|
||||
post_logout_redirect_uri: '/logout-redirect.html',
|
||||
},
|
||||
],
|
||||
}
|
||||
```
|
||||
|
||||
You can find an example of this setup in our
|
||||
[User Account Control Deployment Recipe](./recipes/user-account-control.md).
|
||||
|
||||
#### Choosing a Flow for the Viewer
|
||||
|
||||
In general, we recommend using the "Authorization Code Flow" ( [see
|
||||
`response_type=code` here][code-flows]); however, the "Implicit Flow" ( [see
|
||||
`response_type=token` here][code-flows]) can work if additonal precautions are
|
||||
taken. If the flow you've chosen produces a JWT Token, it's validity can be used
|
||||
to secure access to your Image Archive as well.
|
||||
|
||||
### Recipes
|
||||
|
||||
We've included a few recipes for common deployment scenarios. There are many,
|
||||
many possible configurations, so please don't feel limited to these setups.
|
||||
Please feel free to suggest or contribute your own recipes.
|
||||
|
||||
- Script Include
|
||||
- [Embedding the Viewer](./recipes/embedded-viewer.md)
|
||||
- Stand-Alone
|
||||
- [Build for Production](./recipes/build-for-production.md)
|
||||
- [Static](./recipes/static-assets.md)
|
||||
- [Nginx + Image Archive](./recipes/nginx--image-archive.md)
|
||||
- [User Account Control](./recipes/user-account-control.md)
|
||||
|
||||
<!--
|
||||
Links
|
||||
-->
|
||||
|
||||
<!-- prettier-ignore-start -->
|
||||
[viewer-npm]: https://www.npmjs.com/package/@ohif/viewer
|
||||
[pwa-url]: https://developers.google.com/web/progressive-web-apps/
|
||||
[static-assets-url]: https://www.maxcdn.com/one/visual-glossary/static-content/
|
||||
[app-store]: https://medium.freecodecamp.org/i-built-a-pwa-and-published-it-in-3-app-stores-heres-what-i-learned-7cb3f56daf9b
|
||||
[dicom-web-standard]: https://www.dicomstandard.org/dicomweb/
|
||||
[dicom-web]: https://en.wikipedia.org/wiki/DICOMweb
|
||||
[host-static-assets]: https://www.netlify.com/blog/2016/05/18/9-reasons-your-site-should-be-static/
|
||||
[cors]: https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS
|
||||
[code-flows]: https://medium.com/@darutk/diagrams-of-all-the-openid-connect-flows-6968e3990660
|
||||
[code-sandbox]: https://codesandbox.io/s/viewer-script-tag-tprch
|
||||
<!-- prettier-ignore-end -->
|
||||
Loaded 100 of 2891 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user