diff --git a/monailabel/endpoints/proxy.py b/monailabel/endpoints/proxy.py index 8b2529832..7800f2fca 100644 --- a/monailabel/endpoints/proxy.py +++ b/monailabel/endpoints/proxy.py @@ -10,11 +10,12 @@ # limitations under the License. import logging +import time import google.auth import google.auth.transport.requests -import httpx -from fastapi import APIRouter, Depends +import requests +from fastapi import APIRouter, Depends, Request from fastapi.responses import Response from monailabel.config import settings @@ -29,103 +30,106 @@ ) -class GoogleAuth(httpx.Auth): - def __init__(self, token): - self.token = token - - def auth_flow(self, request): - # Send the request, with a custom `Authorization` header. - request.headers["Authorization"] = "Bearer %s" % self.token - yield request - - -async def proxy_dicom(op: str, path: str, response: Response): +async def proxy_dicom(request: Request, op: str, path: str): auth = ( (settings.MONAI_LABEL_DICOMWEB_USERNAME, settings.MONAI_LABEL_DICOMWEB_PASSWORD) if settings.MONAI_LABEL_DICOMWEB_USERNAME and settings.MONAI_LABEL_DICOMWEB_PASSWORD else None ) + + headers = {} if "googleapis.com" in settings.MONAI_LABEL_STUDIES: google_credentials, _ = google.auth.default(scopes=["https://www.googleapis.com/auth/cloud-platform"]) auth_req = google.auth.transport.requests.Request() google_credentials.refresh(auth_req) token = google_credentials.token - auth = GoogleAuth(token) - - async with httpx.AsyncClient(auth=auth) as client: - server = f"{settings.MONAI_LABEL_STUDIES.rstrip('/')}" - prefix = ( - settings.MONAI_LABEL_WADO_PREFIX - if op == "wado" - else settings.MONAI_LABEL_QIDO_PREFIX - if op == "qido" - else settings.MONAI_LABEL_STOW_PREFIX - if op == "stow" - else "" - ) + headers["Authorization"] = "Bearer %s" % token + auth = None + + server = f"{settings.MONAI_LABEL_STUDIES.rstrip('/')}" + prefix = ( + settings.MONAI_LABEL_WADO_PREFIX + if op == "wado" + else settings.MONAI_LABEL_QIDO_PREFIX + if op == "qido" + else settings.MONAI_LABEL_STOW_PREFIX + if op == "stow" + else "" + ) - # some version of ohif requests metadata using qido so change it to wado - print( - f"This is the server {server} - This is the op {op} - This is the prefix {prefix} - This is the path {path}" + # some version of ohif requests metadata using qido so change it to wado + # print(f"Server {server}; Op: {op}; Prefix: {prefix}; Path: {path}") + if path.endswith("metadata") and op == "qido": + prefix = settings.MONAI_LABEL_WADO_PREFIX + + if prefix: + proxy_path = f"{prefix}/{path}" + else: + proxy_path = f"{path}" + + logger.debug(f"Proxy connecting to /dicom/{op}/{path} => {proxy_path}") + start = time.time() + if request.method == "POST": + headers.update(request.headers) + rp_resp = requests.post( + f"{server}/{proxy_path}", + auth=auth, + stream=True, + headers=headers, + data=await request.body(), ) - if path.endswith("metadata") and op == "qido": - prefix = settings.MONAI_LABEL_WADO_PREFIX - - if prefix: - proxy_path = f"{server}/{prefix}/{path}" - else: - proxy_path = f"{server}/{path}" - - logger.debug(f"Proxy connecting to /dicom/{op}/{path} => {proxy_path}") - timeout = httpx.Timeout( - settings.MONAI_LABEL_DICOMWEB_PROXY_TIMEOUT, - read=settings.MONAI_LABEL_DICOMWEB_READ_TIMEOUT, + else: + rp_resp = requests.get( + f"{server}/{proxy_path}", + auth=auth, + stream=True, + headers=headers, ) + logger.debug(f"Proxy Time: {time.time() - start:.4f} => Path: {proxy_path}") - print(f"This is the proxy path: {proxy_path}") - proxy = await client.get(proxy_path, timeout=timeout) - - response.body = proxy.content - response.status_code = proxy.status_code - # response.headers["Cross-Origin-Opener-Policy"] = "same-origin" - # response.headers["Cross-Origin-Embedder-Policy"] = "require-corp" - # response.headers["Cross-Origin-Resource-Policy"] = "same-site" - # response.headers["Cross-Origin-Resource-Policy"] = "cross-origin" - return response + return Response( + content=rp_resp.raw.read(), + status_code=rp_resp.status_code, + headers=rp_resp.headers, + ) @router.get("/dicom/wado/{path:path}", include_in_schema=False) +@router.post("/dicom/wado/{path:path}", include_in_schema=False) async def proxy_wado( + request: Request, path: str, - response: Response, user: User = Depends(RBAC(settings.MONAI_LABEL_AUTH_ROLE_USER)), ): - return await proxy_dicom("wado", path, response) + return await proxy_dicom(request, "wado", path) @router.get("/dicom/qido/{path:path}", include_in_schema=False) +@router.post("/dicom/qido/{path:path}", include_in_schema=False) async def proxy_qido( + request: Request, path: str, - response: Response, user: User = Depends(RBAC(settings.MONAI_LABEL_AUTH_ROLE_USER)), ): - return await proxy_dicom("qido", path, response) + return await proxy_dicom(request, "qido", path) @router.get("/dicom/stow/{path:path}", include_in_schema=False) +@router.post("/dicom/stow/{path:path}", include_in_schema=False) async def proxy_stow( + request: Request, path: str, - response: Response, user: User = Depends(RBAC(settings.MONAI_LABEL_AUTH_ROLE_USER)), ): - return await proxy_dicom("stow", path, response) + return await proxy_dicom(request, "stow", path) # https://fastapi.tiangolo.com/tutorial/path-params/#order-matters @router.get("/dicom/{path:path}", include_in_schema=False) +@router.post("/dicom/{path:path}", include_in_schema=False) async def proxy( + request: Request, path: str, - response: Response, user: User = Depends(RBAC(settings.MONAI_LABEL_AUTH_ROLE_USER)), ): - return await proxy_dicom("", path, response) + return await proxy_dicom(request, "", path) diff --git a/plugins/ohifv3/.gitignore b/plugins/ohifv3/.gitignore new file mode 100644 index 000000000..a120fafbd --- /dev/null +++ b/plugins/ohifv3/.gitignore @@ -0,0 +1,14 @@ +# Copyright (c) MONAI Consortium +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# http://www.apache.org/licenses/LICENSE-2.0 +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +logs +Viewers +www diff --git a/plugins/ohifv3/README.md b/plugins/ohifv3/README.md index f7b1920d7..7e5cacd95 100644 --- a/plugins/ohifv3/README.md +++ b/plugins/ohifv3/README.md @@ -14,7 +14,7 @@ limitations under the License. ## MONAI Label Plugin for OHIF Viewer The Open Health Imaging Foundation (OHIF) Viewer is an open-source, web-based platform for medical imaging. OHIF Viewer provides a framework for building complex imaging applications with user-friendly interfaces. MONAI Label supports the web-based OHIF viewer with connectivity to a remote DICOM server via DICOMweb. - + ### Table of Contents - [Supported Applications](#supported-applications) @@ -33,20 +33,16 @@ When installing MONAI Label with `pip install monailabel`, a version of OHIF tha #### Development setup To build the OHIF plugin for development, follow these steps: - ```bash - sudo sh requirements.sh # installs yarn - sh build.sh - ``` - -To run Orthanc from the submodule and avoid building the OHIF package for every code change, use the following commands: ```bash -cd plugins/ohif/Viewers - -yarn run dev:orthanc +sudo sh requirements.sh # installs yarn/ngnix +sh build.sh +``` -# OHIF will run at http://127.0.0.1:3000/ +To run the OHIF plugin, update DICOM and MONAI Server Endpoints in configs/nginx.conf +```bash +sh run.sh ``` -You can then visit http://127.0.0.1:3000/ on your browser to see the running OHIF. +You can then visit http://127.0.0.1:3000/ohif/ on your browser to see the running OHIF. ### Installing Orthanc (DICOMWeb) diff --git a/plugins/ohifv3/build.sh b/plugins/ohifv3/build.sh index a47134569..d84297b84 100755 --- a/plugins/ohifv3/build.sh +++ b/plugins/ohifv3/build.sh @@ -25,51 +25,31 @@ echo "Installing OHIF at: ${install_dir}" cd ${my_dir} rm -rf Viewers -git clone https://github.com/OHIF/Viewers.git +cp -r ~/Projects/Viewers . +#git clone https://github.com/OHIF/Viewers.git cd Viewers -git checkout feat/monai-label +git checkout 33f125940863607f8dba82c71b27a43f35431dd5 +#cp -r ../extensions/monai-label extensions/ +#cp -r ../modes/monai-label modes/monai-label +cd extensions +ln -s ../../extensions/monai-label monai-label +cd .. -sed -i "s|routerBasename: '/'|routerBasename: '/ohif/'|g" ./platform/app/public/config/default.js -sed -i "s|name: 'aws'|name: 'Orthanc'|g" ./platform/app/public/config/default.js -sed -i "s|wadoUriRoot: 'https://d33do7qe4w26qo.cloudfront.net/dicomweb'|wadoUriRoot: 'http://localhost/dicom-web'|g" ./platform/app/public/config/default.js -sed -i "s|wadoRoot: 'https://d33do7qe4w26qo.cloudfront.net/dicomweb'|wadoRoot: 'http://localhost/dicom-web'|g" ./platform/app/public/config/default.js -sed -i "s|qidoRoot: 'https://d33do7qe4w26qo.cloudfront.net/dicomweb'|qidoRoot: 'http://localhost/dicom-web'|g" ./platform/app/public/config/default.js +cd modes +ln -s ../../modes/monai-label monai-label +cd .. -sed -i "s|PUBLIC_URL=/|PUBLIC_URL=/ohif/|g" ./platform/app/.env +git apply ../extensions.patch +cp ../config/monai_label.js platform/app/public/config/monai_label.js +yarn config set workspaces-experimental true yarn install - -# Link the mode and extension HERE -echo "Linking extension and mode at: $(pwd)" -yarn run cli link-extension ../extension-monai-label -yarn run cli link-mode ../mode-monai-label - -cd ../extension-monai-label - -echo "Running install again at: $(pwd)" - -yarn install - -echo "Moving nrrd-js and itk node modules to Viewersnode_modules/" - -cp -r ./node_modules/nrrd-js ../Viewers/node_modules/ - -cp -r ./node_modules/itk ../Viewers/node_modules/ - -echo "Moving to Viewers folder to build OHIF" - -cd ../Viewers - -echo "Viewers folder before building OHIF $(pwd)" - -QUICK_BUILD=true yarn run build +APP_CONFIG=config/monai_label.js PUBLIC_URL=/ohif/ QUICK_BUILD=true yarn run build rm -rf ${install_dir} -mv ./platform/app/dist/ ${install_dir} +cp -r platform/app/dist/ ${install_dir} echo "Copied OHIF to ${install_dir}" -rm -rf ../Viewers - cd ${curr_dir} diff --git a/plugins/ohifv3/config/mime.types b/plugins/ohifv3/config/mime.types new file mode 100644 index 000000000..1c00d701a --- /dev/null +++ b/plugins/ohifv3/config/mime.types @@ -0,0 +1,99 @@ + +types { + text/html html htm shtml; + text/css css; + text/xml xml; + image/gif gif; + image/jpeg jpeg jpg; + application/javascript js; + application/atom+xml atom; + application/rss+xml rss; + + text/mathml mml; + text/plain txt; + text/vnd.sun.j2me.app-descriptor jad; + text/vnd.wap.wml wml; + text/x-component htc; + + image/avif avif; + image/png png; + image/svg+xml svg svgz; + image/tiff tif tiff; + image/vnd.wap.wbmp wbmp; + image/webp webp; + image/x-icon ico; + image/x-jng jng; + image/x-ms-bmp bmp; + + font/woff woff; + font/woff2 woff2; + + application/java-archive jar war ear; + application/json json; + application/mac-binhex40 hqx; + application/msword doc; + application/pdf pdf; + application/postscript ps eps ai; + application/rtf rtf; + application/vnd.apple.mpegurl m3u8; + application/vnd.google-earth.kml+xml kml; + application/vnd.google-earth.kmz kmz; + application/vnd.ms-excel xls; + application/vnd.ms-fontobject eot; + application/vnd.ms-powerpoint ppt; + application/vnd.oasis.opendocument.graphics odg; + application/vnd.oasis.opendocument.presentation odp; + application/vnd.oasis.opendocument.spreadsheet ods; + application/vnd.oasis.opendocument.text odt; + application/vnd.openxmlformats-officedocument.presentationml.presentation + pptx; + application/vnd.openxmlformats-officedocument.spreadsheetml.sheet + xlsx; + application/vnd.openxmlformats-officedocument.wordprocessingml.document + docx; + application/vnd.wap.wmlc wmlc; + application/wasm wasm; + application/x-7z-compressed 7z; + application/x-cocoa cco; + application/x-java-archive-diff jardiff; + application/x-java-jnlp-file jnlp; + application/x-makeself run; + application/x-perl pl pm; + application/x-pilot prc pdb; + application/x-rar-compressed rar; + application/x-redhat-package-manager rpm; + application/x-sea sea; + application/x-shockwave-flash swf; + application/x-stuffit sit; + application/x-tcl tcl tk; + application/x-x509-ca-cert der pem crt; + application/x-xpinstall xpi; + application/xhtml+xml xhtml; + application/xspf+xml xspf; + application/zip zip; + + application/octet-stream bin exe dll; + application/octet-stream deb; + application/octet-stream dmg; + application/octet-stream iso img; + application/octet-stream msi msp msm; + + audio/midi mid midi kar; + audio/mpeg mp3; + audio/ogg ogg; + audio/x-m4a m4a; + audio/x-realaudio ra; + + video/3gpp 3gpp 3gp; + video/mp2t ts; + video/mp4 mp4; + video/mpeg mpeg mpg; + video/quicktime mov; + video/webm webm; + video/x-flv flv; + video/x-m4v m4v; + video/x-mng mng; + video/x-ms-asf asx asf; + video/x-ms-wmv wmv; + video/x-msvideo avi; +} diff --git a/plugins/ohifv3/config/monai_label.js b/plugins/ohifv3/config/monai_label.js new file mode 100644 index 000000000..529f44725 --- /dev/null +++ b/plugins/ohifv3/config/monai_label.js @@ -0,0 +1,38 @@ +window.config = { + routerBasename: '/ohif/', + showStudyList: true, + extensions: [], + modes: [], + // below flag is for performance reasons, but it might not work for all servers + + showWarningMessageForCrossOrigin: true, + showCPUFallbackMessage: true, + showLoadingIndicator: true, + strictZSpacingForVolumeViewport: true, + defaultDataSourceName: 'dicomweb', + useSharedArrayBuffer: 'FALSE', + dataSources: [ + { + namespace: '@ohif/extension-default.dataSourcesModule.dicomweb', + sourceName: 'dicomweb', + configuration: { + friendlyName: 'Orthanc Server', + name: 'Orthanc', + wadoUriRoot: '/proxy/dicom/wado', + qidoRoot: '/proxy/dicom/qido', + wadoRoot: '/proxy/dicom/wado', + qidoSupportsIncludeField: true, + supportsReject: true, + imageRendering: 'wadors', + thumbnailRendering: 'wadors', + enableStudyLazyLoad: false, + supportsFuzzyMatching: true, + supportsWildcard: true, + dicomUploadEnabled: true, + bulkDataURI: { + enabled: true, + }, + }, + }, + ], +}; diff --git a/plugins/ohifv3/config/nginx.conf b/plugins/ohifv3/config/nginx.conf new file mode 100644 index 000000000..702ccc8de --- /dev/null +++ b/plugins/ohifv3/config/nginx.conf @@ -0,0 +1,62 @@ +# worker_processes auto; +worker_processes 1; +error_log stderr; +daemon off; +pid logs/nginx.pid; + +events { + worker_connections 4096; ## Default: 1024 +} +http { + client_max_body_size 0; + client_body_temp_path logs/temp; + + server { + listen 3000; + server_name localhost; + access_log logs/access.log; + + include mime.types; + default_type application/octet-stream; + sendfile on; + keepalive_timeout 65; + + location /proxy/dicom/qido/ { + proxy_http_version 1.1; + 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 $scheme; + + expires 0; + add_header Cache-Control private; + proxy_pass http://127.0.0.1:8042/dicom-web/; + proxy_buffering off; + # proxy_set_header Authorization "Basic dXNlcjpwYXNzd29yZA=="; # echo -n 'user:password' | base64 + } + + location /proxy/dicom/wado/ { + proxy_http_version 1.1; + 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 $scheme; + + expires 0; + add_header Cache-Control private; + proxy_pass http://127.0.0.1:8042/dicom-web/; + proxy_buffering off; + # proxy_set_header Authorization "Basic dXNlcjpwYXNzd29yZA=="; # echo -n 'user:password' | base64 + } + + location / { + root www/html; + index index.html; + try_files $uri $uri/ /index.html; + + add_header Cache-Control "no-store, no-cache, must-revalidate"; + add_header 'Cross-Origin-Opener-Policy' 'same-origin' always; + add_header 'Cross-Origin-Embedder-Policy' 'require-corp' always; + } + } +} diff --git a/plugins/ohifv3/extension-monai-label/.webpack/webpack.prod.js b/plugins/ohifv3/extension-monai-label/.webpack/webpack.prod.js deleted file mode 100644 index 070a723e3..000000000 --- a/plugins/ohifv3/extension-monai-label/.webpack/webpack.prod.js +++ /dev/null @@ -1,63 +0,0 @@ -const path = require('path'); -const pkg = require('../package.json'); - -const outputFile = 'index.umd.js'; -const rootDir = path.resolve(__dirname, '../'); -const outputFolder = path.join(__dirname, `../dist/umd/${pkg.name}/`); - -// Todo: add ESM build for the extension in addition to umd build - -const config = { - mode: 'production', - entry: rootDir + '/' + pkg.module, - devtool: 'source-map', - output: { - path: outputFolder, - filename: outputFile, - library: pkg.name, - libraryTarget: 'umd', - chunkFilename: '[name].chunk.js', - umdNamedDefine: true, - globalObject: "typeof self !== 'undefined' ? self : this", - }, - externals: [ - { - react: { - root: 'React', - commonjs2: 'react', - commonjs: 'react', - amd: 'react', - }, - '@ohif/core': { - commonjs2: '@ohif/core', - commonjs: '@ohif/core', - amd: '@ohif/core', - root: '@ohif/core', - }, - '@ohif/ui': { - commonjs2: '@ohif/ui', - commonjs: '@ohif/ui', - amd: '@ohif/ui', - root: '@ohif/ui', - }, - }, - ], - module: { - rules: [ - { - test: /(\.jsx|\.js|\.tsx|\.ts)$/, - loader: 'babel-loader', - exclude: /(node_modules|bower_components)/, - resolve: { - extensions: ['.js', '.jsx', '.ts', '.tsx'], - }, - }, - ], - }, - resolve: { - modules: [path.resolve('./node_modules'), path.resolve('./src')], - extensions: ['.json', '.js', '.jsx', '.tsx', '.ts'], - }, -}; - -module.exports = config; diff --git a/plugins/ohifv3/extension-monai-label/src/components/ModelSelector.styl b/plugins/ohifv3/extension-monai-label/src/components/ModelSelector.styl deleted file mode 100644 index ec1dbeccc..000000000 --- a/plugins/ohifv3/extension-monai-label/src/components/ModelSelector.styl +++ /dev/null @@ -1,33 +0,0 @@ - -.modelSelector - .table - border-collapse: collapse; - border: 0 solid; - width: 100%; - - .table tr td - border: 0 solid; - - .selectBox - width: 100% - - .actionButton - border: 2px solid black - border-radius: 15px - background-color: lightblue - color: var(--ui-gray-dark) - line-height: 25px - padding: 0 15px - outline: none - cursor: pointer - - &:hover, &:active - background-color: var(--ui-sky-blue) - - &:disabled - background-color: var(--ui-sky-blue) - - svg - margin-right: 4px - position: relative - top: 2px diff --git a/plugins/ohifv3/extension-monai-label/src/components/MonaiLabelPanel.styl b/plugins/ohifv3/extension-monai-label/src/components/MonaiLabelPanel.styl deleted file mode 100644 index 5069ab8dc..000000000 --- a/plugins/ohifv3/extension-monai-label/src/components/MonaiLabelPanel.styl +++ /dev/null @@ -1,146 +0,0 @@ - -@import url("https://www.w3schools.com/w3css/4/w3.css") - -.monaiLabelPanel - background-color: lightslategray - height: 100% - width: 100% - display: flex - flex-direction: column - color: var(--text-primary-color) - padding: 2px - overflow-y: scroll; /* Make the panel scrollable vertically */ - - .subtitle - font-size: 14px - text-decoration: underline - font-weight 500 - color black - margin 1px - text-align center - - /* Accordion styles */ - .tabs { - border-radius: 4px; - overflow: auto; - box-shadow: 0 4px 4px -2px rgba(0, 0, 0, 0.5); - background: black - margin: 1rem 0; - } - - .tab { - width: 100%; - color: white; - overflow: hidden; - } - .tab-switch { - position: absolute; - opacity: 0; - z-index: -1; - } - .tab-label { - display: flex; - justify-content: space-between; - padding: 0.4em; - background: #16202b; - border-right: 1px dotted #3c5d80; - color: #fff; - font-size: 12px; - font-weight: normal; - cursor: pointer; - /* Icon */ - } - .tab-label:hover { - background: #3e5975; - } - .tab-label::after { - content: "❯"; - width: 1em; - height: 1em; - text-align: center; - transition: all 0.35s; - } - .tab-content { - max-height: 0; - padding: 0 1em; - background: gray; - transition: all 0.35s; - width: 100%; - font-size: small - color: black - } - .tab-close { - display: flex; - justify-content: flex-end; - padding: 1em; - font-size: 0.75em; - background: #2c3e50; - cursor: pointer; - } - .tab-close:hover { - background: #1a252f; - } - - input:checked + .tab-label { - background: black; - } - input:checked + .tab-label::after { - transform: rotate(90deg); - } - input:checked ~ .tab-content { - max-height: 100vh; - padding: 1em; - } - - .separator - border: 0.01em solid #44626f - width: 100% - margin-top: 3px - margin-bottom: 3px - - .actionInput - width: 100% - padding: 1px - border: 1px solid black - color: black - - // Theming has changed: https://docs.ohif.org/platform/themeing/ - .actionButton - // https://github.com/OHIF/Viewers/blob/58d38495f097afc6333937b6fbaf60ae473957c0/platform/docs/versioned_docs/version-2.0-deprecated/viewer/themeing.md?plain=1#L5 - border: 1px solid black - border-radius: 15px - background-color: lightblue - color: black - line-height: 25px - padding: 10px - outline: none - cursor: pointer - - &:hover, &:active - background-color: var(--ui-sky-blue) - - &:disabled - background-color: var(--ui-sky-blue) - - svg - margin-right: 4px - position: relative - top: 2px - -.scrollbar { - overflow-y: scroll; -} - -#style-3::-webkit-scrollbar-track { - -webkit-box-shadow: inset 0 0 6px rgba(0, 0, 0, 0.3); - background-color: #000000; -} - -#style-3::-webkit-scrollbar { - width: 6px; - background-color: #000000; -} - -#style-3::-webkit-scrollbar-thumb { - background-color: #f5f5f5; -} diff --git a/plugins/ohifv3/extension-monai-label/src/components/actions/ActiveLearning.styl b/plugins/ohifv3/extension-monai-label/src/components/actions/ActiveLearning.styl deleted file mode 100644 index b0bf58765..000000000 --- a/plugins/ohifv3/extension-monai-label/src/components/actions/ActiveLearning.styl +++ /dev/null @@ -1,14 +0,0 @@ -/* -Copyright (c) MONAI Consortium -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -@import "BaseTab.styl" diff --git a/plugins/ohifv3/extension-monai-label/src/components/actions/BaseTab.styl b/plugins/ohifv3/extension-monai-label/src/components/actions/BaseTab.styl deleted file mode 100644 index bbbd02694..000000000 --- a/plugins/ohifv3/extension-monai-label/src/components/actions/BaseTab.styl +++ /dev/null @@ -1,14 +0,0 @@ -/* -Copyright (c) MONAI Consortium -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -@import "../ModelSelector.styl" diff --git a/plugins/ohifv3/extension-monai-label/src/components/actions/NextSampleForm.styl b/plugins/ohifv3/extension-monai-label/src/components/actions/NextSampleForm.styl deleted file mode 100644 index 0dce82fbc..000000000 --- a/plugins/ohifv3/extension-monai-label/src/components/actions/NextSampleForm.styl +++ /dev/null @@ -1,54 +0,0 @@ -/* -Copyright (c) MONAI Consortium -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -.nextSampleForm - width: 750px - - .actionButton - border: 1px solid var(--ui-border-color-active) - border-radius: 15px - background-color: var(--active-color) - color: var(--ui-gray-dark) - line-height: 25px - padding: 0 15px - outline: none - cursor: pointer - - &:hover, &:active - background-color: var(--ui-sky-blue) - - &:disabled - background-color: var(--ui-sky-blue) - - svg - margin-right: 4px - position: relative - top: 2px - - .optionsTable { - font-family: arial, sans-serif; - border-collapse: collapse; - width: 100%; - font-size: smaller; - } - - .optionsTable th { - border: 1px solid #dddddd; - text-align: left; - background-color: lightslategray; - } - - .optionsTable td { - border: 1px solid #dddddd; - text-align: left; - } diff --git a/plugins/ohifv3/extension-monai-label/src/components/actions/SmartEdit.styl b/plugins/ohifv3/extension-monai-label/src/components/actions/SmartEdit.styl deleted file mode 100644 index b0bf58765..000000000 --- a/plugins/ohifv3/extension-monai-label/src/components/actions/SmartEdit.styl +++ /dev/null @@ -1,14 +0,0 @@ -/* -Copyright (c) MONAI Consortium -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -@import "BaseTab.styl" diff --git a/plugins/ohifv3/extensions.patch b/plugins/ohifv3/extensions.patch new file mode 100644 index 000000000..83d3be2bc --- /dev/null +++ b/plugins/ohifv3/extensions.patch @@ -0,0 +1,26 @@ +diff --git a/platform/app/pluginConfig.json b/platform/app/pluginConfig.json +index 08a42deb0..69e5aa005 100644 +--- a/platform/app/pluginConfig.json ++++ b/platform/app/pluginConfig.json +@@ -22,6 +22,11 @@ + "default": false, + "version": "3.0.0" + }, ++ { ++ "packageName": "@ohif/extension-monai-label", ++ "default": false, ++ "version": "0.0.1" ++ }, + { + "packageName": "@ohif/extension-dicom-microscopy", + "default": false, +@@ -60,6 +65,9 @@ + { + "packageName": "@ohif/mode-segmentation" + }, ++ { ++ "packageName": "@ohif/mode-monai-label" ++ }, + { + "packageName": "@ohif/mode-tmtv" + }, diff --git a/plugins/ohifv3/extension-monai-label/.gitignore b/plugins/ohifv3/extensions/monai-label/.gitignore similarity index 100% rename from plugins/ohifv3/extension-monai-label/.gitignore rename to plugins/ohifv3/extensions/monai-label/.gitignore diff --git a/plugins/ohifv3/extension-monai-label/.prettierrc b/plugins/ohifv3/extensions/monai-label/.prettierrc similarity index 100% rename from plugins/ohifv3/extension-monai-label/.prettierrc rename to plugins/ohifv3/extensions/monai-label/.prettierrc diff --git a/plugins/ohifv3/extensions/monai-label/.webpack/webpack.prod.js b/plugins/ohifv3/extensions/monai-label/.webpack/webpack.prod.js new file mode 100644 index 000000000..2398e36fb --- /dev/null +++ b/plugins/ohifv3/extensions/monai-label/.webpack/webpack.prod.js @@ -0,0 +1,48 @@ +const webpack = require('webpack'); +const { merge } = require('webpack-merge'); +const path = require('path'); +const webpackCommon = require('./../../../.webpack/webpack.base.js'); +const pkg = require('./../package.json'); + +const ROOT_DIR = path.join(__dirname, './..'); +const SRC_DIR = path.join(__dirname, '../src'); +const DIST_DIR = path.join(__dirname, '../dist'); + +const ENTRY = { + app: `${SRC_DIR}/index.tsx`, +}; + +module.exports = (env, argv) => { + const commonConfig = webpackCommon(env, argv, { SRC_DIR, DIST_DIR, ENTRY }); + + return merge(commonConfig, { + stats: { + colors: true, + hash: true, + timings: true, + assets: true, + chunks: false, + chunkModules: false, + modules: false, + children: false, + warnings: true, + }, + optimization: { + minimize: true, + sideEffects: false, + }, + output: { + path: ROOT_DIR, + library: 'ohif-extension-monai-label', + libraryTarget: 'umd', + libraryExport: 'default', + filename: pkg.main, + }, + externals: [/\b(vtk.js)/, /\b(dcmjs)/, /\b(gl-matrix)/, /^@ohif/, /^@cornerstonejs/], + plugins: [ + new webpack.optimize.LimitChunkCountPlugin({ + maxChunks: 1, + }), + ], + }); +}; diff --git a/plugins/ohifv3/extension-monai-label/LICENSE b/plugins/ohifv3/extensions/monai-label/LICENSE similarity index 100% rename from plugins/ohifv3/extension-monai-label/LICENSE rename to plugins/ohifv3/extensions/monai-label/LICENSE diff --git a/plugins/ohifv3/extension-monai-label/README.md b/plugins/ohifv3/extensions/monai-label/README.md similarity index 100% rename from plugins/ohifv3/extension-monai-label/README.md rename to plugins/ohifv3/extensions/monai-label/README.md diff --git a/plugins/ohifv3/extension-monai-label/babel.config.js b/plugins/ohifv3/extensions/monai-label/babel.config.js similarity index 100% rename from plugins/ohifv3/extension-monai-label/babel.config.js rename to plugins/ohifv3/extensions/monai-label/babel.config.js diff --git a/plugins/ohifv3/extension-monai-label/package.json b/plugins/ohifv3/extensions/monai-label/package.json similarity index 51% rename from plugins/ohifv3/extension-monai-label/package.json rename to plugins/ohifv3/extensions/monai-label/package.json index 6b82ff88c..753bfafff 100644 --- a/plugins/ohifv3/extension-monai-label/package.json +++ b/plugins/ohifv3/extensions/monai-label/package.json @@ -31,18 +31,16 @@ "start": "yarn run dev" }, "peerDependencies": { - "@ohif/core": "^3.0.0", - "@ohif/extension-default": "^3.0.0", - "@ohif/extension-cornerstone": "^3.0.0", - "@ohif/i18n": "^1.0.0", + "@ohif/core": "^3.7.0-beta.80", + "@ohif/extension-default": "^3.7.0-beta.80", + "@ohif/extension-cornerstone": "^3.7.0-beta.80", + "@ohif/i18n": "^3.7.0-beta.80", "prop-types": "^15.6.2", "react": "^17.0.2", "react-dom": "^17.0.2", "react-i18next": "^12.2.2", "react-router": "^6.8.1", - "react-router-dom": "^6.8.1", - "webpack": "^5.50.0", - "webpack-merge": "^5.7.3" + "react-router-dom": "^6.8.1" }, "dependencies": { "@babel/runtime": "^7.20.13", @@ -52,37 +50,15 @@ "ndarray": "^1.0.19", "nrrd-js": "^0.2.1", "pako": "^2.0.3", - "itk": "^14.1.1", "react-color": "^2.19.3", "bootstrap": "^5.0.2", "react-select": "^4.3.1", - "chroma-js": "^2.1.2" + "chroma-js": "^2.1.2", + "itk": "^14.1.1" }, "devDependencies": { - "@babel/core": "^7.21.4", - "@babel/plugin-proposal-class-properties": "^7.16.7", - "@babel/plugin-proposal-object-rest-spread": "^7.17.3", - "@babel/plugin-proposal-private-methods": "^7.18.6", - "@babel/plugin-syntax-dynamic-import": "^7.8.3", - "@babel/plugin-transform-arrow-functions": "^7.16.7", - "@babel/plugin-transform-regenerator": "^7.16.7", - "@babel/plugin-transform-runtime": "^7.17.0", - "@babel/plugin-transform-typescript": "^7.13.0", - "@babel/preset-env": "^7.16.11", - "@babel/preset-react": "^7.16.7", - "@babel/preset-typescript": "^7.13.0", - "babel-eslint": "9.x", - "babel-loader": "^8.2.4", - "babel-plugin-inline-react-svg": "^2.0.2", - "babel-plugin-module-resolver": "^5.0.0", - "clean-webpack-plugin": "^4.0.0", - "copy-webpack-plugin": "^10.2.0", - "cross-env": "^7.0.3", - "dotenv": "^14.1.0", - "eslint": "^5.0.1", - "eslint-loader": "^2.0.0", - "webpack": "^5.50.0", - "webpack-merge": "^5.7.3", - "webpack-cli": "^4.7.2" + "@babel/runtime": "^7.20.13", + "@cornerstonejs/tools": "^1.16.4", + "react-color": "^2.19.3" } } diff --git a/plugins/ohifv3/extensions/monai-label/src/components/ModelSelector.css b/plugins/ohifv3/extensions/monai-label/src/components/ModelSelector.css new file mode 100644 index 000000000..153d01263 --- /dev/null +++ b/plugins/ohifv3/extensions/monai-label/src/components/ModelSelector.css @@ -0,0 +1,33 @@ +.modelSelector .table { + border-collapse: collapse; + border: 0 solid; + width: 100%; +} +.modelSelector .table tr td { + border: 0 solid; +} +.modelSelector .selectBox { + width: 100%; +} +.modelSelector .actionButton { + border: 2px solid #000; + border-radius: 15px; + background-color: #add8e6; + color: var(--ui-gray-dark); + line-height: 25px; + padding: 0 15px; + outline: none; + cursor: pointer; +} +.modelSelector .actionButton:hover, +.modelSelector .actionButton:active { + background-color: var(--ui-sky-blue); +} +.modelSelector .actionButton:disabled { + background-color: var(--ui-sky-blue); +} +.modelSelector .actionButton svg { + margin-right: 4px; + position: relative; + top: 2px; +} diff --git a/plugins/ohifv3/extension-monai-label/src/components/ModelSelector.tsx b/plugins/ohifv3/extensions/monai-label/src/components/ModelSelector.tsx similarity index 98% rename from plugins/ohifv3/extension-monai-label/src/components/ModelSelector.tsx rename to plugins/ohifv3/extensions/monai-label/src/components/ModelSelector.tsx index e9c582a6a..c2371f336 100644 --- a/plugins/ohifv3/extension-monai-label/src/components/ModelSelector.tsx +++ b/plugins/ohifv3/extensions/monai-label/src/components/ModelSelector.tsx @@ -2,7 +2,7 @@ import React, { Component } from 'react'; import PropTypes from 'prop-types'; -import './ModelSelector.styl'; +import './ModelSelector.css'; export default class ModelSelector extends Component { static propTypes = { diff --git a/plugins/ohifv3/extensions/monai-label/src/components/MonaiLabelPanel.css b/plugins/ohifv3/extensions/monai-label/src/components/MonaiLabelPanel.css new file mode 100644 index 000000000..6c069c0ed --- /dev/null +++ b/plugins/ohifv3/extensions/monai-label/src/components/MonaiLabelPanel.css @@ -0,0 +1,139 @@ +@import url("w3.css"); + +.monaiLabelPanel { + background-color: #789; + height: 100%; + width: 100%; + display: flex; + flex-direction: column; + color: var(--text-primary-color); + padding: 2px; + overflow-y: scroll; /* Make the panel scrollable vertically */ +/* Accordion styles */ +} +.monaiLabelPanel .subtitle { + font-size: 14px; + text-decoration: underline; + font-weight: 500; + color: #000; + margin: 1px; + text-align: center; +} +.monaiLabelPanel .tabs { + border-radius: 4px; + overflow: auto; + box-shadow: 0 4px 4px -2px rgba(0,0,0,0.5); + background: #000; + margin: 1rem 0; +} +.monaiLabelPanel .tab { + width: 100%; + color: #fff; + overflow: hidden; +} +.monaiLabelPanel .tab-switch { + position: absolute; + opacity: 0; + z-index: -1; +} +.monaiLabelPanel .tab-label { + display: flex; + justify-content: space-between; + padding: 0.4em; + background: #16202b; + border-right: 1px dotted #3c5d80; + color: #fff; + font-size: 12px; + font-weight: normal; + cursor: pointer; +/* Icon */ +} +.monaiLabelPanel .tab-label:hover { + background: #3e5975; +} +.monaiLabelPanel .tab-label::after { + content: "❯"; + width: 1em; + height: 1em; + text-align: center; + transition: all 0.35s; +} +.monaiLabelPanel .tab-content { + max-height: 0; + padding: 0 1em; + background: #808080; + transition: all 0.35s; + width: 90%; + font-size: small; + color: #000; +} +.monaiLabelPanel .tab-close { + display: flex; + justify-content: flex-end; + padding: 1em; + font-size: 0.75em; + background: #2c3e50; + cursor: pointer; +} +.monaiLabelPanel .tab-close:hover { + background: #1a252f; +} +.monaiLabelPanel input:checked + .tab-label { + background: #000; +} +.monaiLabelPanel input:checked + .tab-label::after { + transform: rotate(90deg); +} +.monaiLabelPanel input:checked ~ .tab-content { + max-height: 100vh; + padding: 1em; +} +.monaiLabelPanel .separator { + border: 0.01em solid #44626f; + width: 100%; + margin-top: 3px; + margin-bottom: 3px; +} +.monaiLabelPanel .actionInput { + width: 100%; + padding: 1px; + border: 1px solid #000; + border-radius: 5px; + color: #000; +} +.monaiLabelPanel .actionButton { + border: 1px solid #000; + border-radius: 15px; + background-color: #add8e6; + color: #000; + line-height: 25px; + padding: 10px; + outline: none; + cursor: pointer; +} +.monaiLabelPanel .actionButton:hover, +.monaiLabelPanel .actionButton:active { + background-color: var(--ui-sky-blue); +} +.monaiLabelPanel .actionButton:disabled { + background-color: var(--ui-sky-blue); +} +.monaiLabelPanel .actionButton svg { + margin-right: 4px; + position: relative; + top: 2px; +} +.scrollbar { + overflow-y: scroll; +} +#style-3::-webkit-scrollbar-track { + -webkit-box-shadow: inset 0 0 6px rgba(0,0,0,0.3); + background-color: #000; +} +#style-3::-webkit-scrollbar { + width: 6px; + background-color: #000; +} +#style-3::-webkit-scrollbar-thumb { + background-color: #f5f5f5; +} diff --git a/plugins/ohifv3/extension-monai-label/src/components/MonaiLabelPanel.tsx b/plugins/ohifv3/extensions/monai-label/src/components/MonaiLabelPanel.tsx similarity index 99% rename from plugins/ohifv3/extension-monai-label/src/components/MonaiLabelPanel.tsx rename to plugins/ohifv3/extensions/monai-label/src/components/MonaiLabelPanel.tsx index 19a407f13..f62e3f5d6 100644 --- a/plugins/ohifv3/extension-monai-label/src/components/MonaiLabelPanel.tsx +++ b/plugins/ohifv3/extensions/monai-label/src/components/MonaiLabelPanel.tsx @@ -2,7 +2,7 @@ import React, { Component } from 'react'; import PropTypes from 'prop-types'; import { cache, triggerEvent, eventTarget } from '@cornerstonejs/core'; import { Enums } from '@cornerstonejs/tools'; -import './MonaiLabelPanel.styl'; +import './MonaiLabelPanel.css'; import SettingsTable from './SettingsTable'; import AutoSegmentation from './actions/AutoSegmentation'; import SmartEdit from './actions/SmartEdit'; diff --git a/plugins/ohifv3/extension-monai-label/src/components/MonaiSegmentation.tsx b/plugins/ohifv3/extensions/monai-label/src/components/MonaiSegmentation.tsx similarity index 98% rename from plugins/ohifv3/extension-monai-label/src/components/MonaiSegmentation.tsx rename to plugins/ohifv3/extensions/monai-label/src/components/MonaiSegmentation.tsx index d24d198d6..f112a84c8 100644 --- a/plugins/ohifv3/extension-monai-label/src/components/MonaiSegmentation.tsx +++ b/plugins/ohifv3/extensions/monai-label/src/components/MonaiSegmentation.tsx @@ -202,6 +202,8 @@ export default function MonaiSegmentation({ }); }; + const onSegmentationDownloadRTSS = (segmentationId) => {}; + const storeSegmentation = (segmentationId) => { const datasources = extensionManager.getActiveDataSource(); @@ -243,6 +245,7 @@ export default function MonaiSegmentation({ onToggleSegmentationVisibility={onToggleSegmentationVisibility} showDeleteSegment={true} segmentationConfig={{ initialConfig: segmentationConfiguration }} + onSegmentationDownloadRTSS={onSegmentationDownloadRTSS} setRenderOutline={(value) => _setSegmentationConfiguration( selectedSegmentationId, diff --git a/plugins/ohifv3/extension-monai-label/src/components/SegmentationToolbox.tsx b/plugins/ohifv3/extensions/monai-label/src/components/SegmentationToolbox.tsx similarity index 100% rename from plugins/ohifv3/extension-monai-label/src/components/SegmentationToolbox.tsx rename to plugins/ohifv3/extensions/monai-label/src/components/SegmentationToolbox.tsx diff --git a/plugins/ohifv3/extension-monai-label/src/components/SettingsTable.styl b/plugins/ohifv3/extensions/monai-label/src/components/SettingsTable.css similarity index 78% rename from plugins/ohifv3/extension-monai-label/src/components/SettingsTable.styl rename to plugins/ohifv3/extensions/monai-label/src/components/SettingsTable.css index 9416781ea..4cd128a74 100644 --- a/plugins/ohifv3/extension-monai-label/src/components/SettingsTable.styl +++ b/plugins/ohifv3/extensions/monai-label/src/components/SettingsTable.css @@ -1,17 +1,16 @@ - -.settingsTable +.settingsTable { border-collapse: collapse; border: 0 solid; width: 100%; - font-size: small - -.settingsTable tr td + font-size: small; +} +.settingsTable tr td { border: 0 solid; - +} .settings_active, .settings_header { - background-color: black; - color: white; + background-color: #000; + color: #fff; cursor: pointer; padding: 5px; width: 100%; @@ -19,35 +18,30 @@ text-align: left; outline: none; } - .settings_active { background-color: #403f3d; } - .settings_header:hover { background-color: #2b2a28; } - .settings_header:after { content: '\002B'; - color: white; + color: #fff; font-weight: bold; float: right; margin-left: 5px; } - .settings_active:after { content: '\2212'; - color: white; + color: #fff; font-weight: bold; float: right; margin-left: 5px; } - .settings_content { cursor: pointer; color: #fff; background-color: #2b2a28; - padding: 10px - font-size: smaller + padding: 10px; + font-size: smaller; } diff --git a/plugins/ohifv3/extension-monai-label/src/components/SettingsTable.tsx b/plugins/ohifv3/extensions/monai-label/src/components/SettingsTable.tsx similarity index 98% rename from plugins/ohifv3/extension-monai-label/src/components/SettingsTable.tsx rename to plugins/ohifv3/extensions/monai-label/src/components/SettingsTable.tsx index 967c0baf9..d5db4bc9a 100644 --- a/plugins/ohifv3/extension-monai-label/src/components/SettingsTable.tsx +++ b/plugins/ohifv3/extensions/monai-label/src/components/SettingsTable.tsx @@ -1,6 +1,6 @@ import React, { Component } from 'react'; -import './MonaiLabelPanel.styl'; +import './SettingsTable.css'; import { Icon } from '@ohif/ui'; import { CookieUtils } from '../utils/GenericUtils'; diff --git a/plugins/ohifv3/extension-monai-label/src/components/Toolbox/ThresholdSettingsPreset.tsx b/plugins/ohifv3/extensions/monai-label/src/components/Toolbox/ThresholdSettingsPreset.tsx similarity index 100% rename from plugins/ohifv3/extension-monai-label/src/components/Toolbox/ThresholdSettingsPreset.tsx rename to plugins/ohifv3/extensions/monai-label/src/components/Toolbox/ThresholdSettingsPreset.tsx diff --git a/plugins/ohifv3/extension-monai-label/src/components/actions/AutoSegmentation.styl b/plugins/ohifv3/extensions/monai-label/src/components/actions/ActiveLearning.css similarity index 63% rename from plugins/ohifv3/extension-monai-label/src/components/actions/AutoSegmentation.styl rename to plugins/ohifv3/extensions/monai-label/src/components/actions/ActiveLearning.css index b0bf58765..c69d56a48 100644 --- a/plugins/ohifv3/extension-monai-label/src/components/actions/AutoSegmentation.styl +++ b/plugins/ohifv3/extensions/monai-label/src/components/actions/ActiveLearning.css @@ -10,5 +10,21 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ - -@import "BaseTab.styl" +.optionsTable { + font-family: arial, sans-serif; + border-collapse: collapse; + width: 100%; + font-size: smaller; +} +.optionsTable th { + border: 0px solid #070303; + text-align: left; + background-color: #789; +} +.optionsTable td { + border: 0px solid #070202; + text-align: left; +} +.optionsInput { + width: 100%; +} diff --git a/plugins/ohifv3/extension-monai-label/src/components/actions/ActiveLearning.tsx b/plugins/ohifv3/extensions/monai-label/src/components/actions/ActiveLearning.tsx similarity index 94% rename from plugins/ohifv3/extension-monai-label/src/components/actions/ActiveLearning.tsx rename to plugins/ohifv3/extensions/monai-label/src/components/actions/ActiveLearning.tsx index eb7ebb0bc..dd0bd2fc4 100644 --- a/plugins/ohifv3/extension-monai-label/src/components/actions/ActiveLearning.tsx +++ b/plugins/ohifv3/extensions/monai-label/src/components/actions/ActiveLearning.tsx @@ -13,7 +13,7 @@ limitations under the License. import React from 'react'; -import './OptionTable.styl'; +import './ActiveLearning.css'; import BaseTab from './BaseTab'; import NextSampleForm from './NextSampleForm'; import { @@ -237,6 +237,7 @@ export default class OptionTable extends BaseTab { Next Sample +   - + {/* */} + {/**/} + {/* */} + {/* Submit Label*/} + {/* */} + {/**/}
- +
diff --git a/plugins/ohifv3/extension-monai-label/src/components/actions/AutoSegmentation.tsx b/plugins/ohifv3/extensions/monai-label/src/components/actions/AutoSegmentation.tsx similarity index 98% rename from plugins/ohifv3/extension-monai-label/src/components/actions/AutoSegmentation.tsx rename to plugins/ohifv3/extensions/monai-label/src/components/actions/AutoSegmentation.tsx index 100777113..6192ec063 100644 --- a/plugins/ohifv3/extension-monai-label/src/components/actions/AutoSegmentation.tsx +++ b/plugins/ohifv3/extensions/monai-label/src/components/actions/AutoSegmentation.tsx @@ -1,5 +1,4 @@ import React from 'react'; -import './AutoSegmentation.styl'; import ModelSelector from '../ModelSelector'; import BaseTab from './BaseTab'; diff --git a/plugins/ohifv3/extension-monai-label/src/components/actions/BaseTab.tsx b/plugins/ohifv3/extensions/monai-label/src/components/actions/BaseTab.tsx similarity index 97% rename from plugins/ohifv3/extension-monai-label/src/components/actions/BaseTab.tsx rename to plugins/ohifv3/extensions/monai-label/src/components/actions/BaseTab.tsx index f40f1276e..cec16e8b3 100644 --- a/plugins/ohifv3/extension-monai-label/src/components/actions/BaseTab.tsx +++ b/plugins/ohifv3/extensions/monai-label/src/components/actions/BaseTab.tsx @@ -2,7 +2,6 @@ import { Component } from 'react'; import PropTypes from 'prop-types'; -import './BaseTab.styl'; import { UIModalService, UINotificationService } from '@ohif/core'; export default class BaseTab extends Component { diff --git a/plugins/ohifv3/extensions/monai-label/src/components/actions/NextSampleForm.css b/plugins/ohifv3/extensions/monai-label/src/components/actions/NextSampleForm.css new file mode 100644 index 000000000..b381c3607 --- /dev/null +++ b/plugins/ohifv3/extensions/monai-label/src/components/actions/NextSampleForm.css @@ -0,0 +1,52 @@ +/* +Copyright (c) MONAI Consortium +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ +.nextSampleForm { + width: 750px; +} +.nextSampleForm .actionButton { + border: 1px solid var(--ui-border-color-active); + border-radius: 15px; + background-color: var(--active-color); + color: var(--ui-gray-dark); + line-height: 25px; + padding: 0 15px; + outline: none; + cursor: pointer; +} +.nextSampleForm .actionButton:hover, +.nextSampleForm .actionButton:active { + background-color: var(--ui-sky-blue); +} +.nextSampleForm .actionButton:disabled { + background-color: var(--ui-sky-blue); +} +.nextSampleForm .actionButton svg { + margin-right: 4px; + position: relative; + top: 2px; +} +.nextSampleForm .optionsTable { + font-family: arial, sans-serif; + border-collapse: collapse; + width: 100%; + font-size: smaller; +} +.nextSampleForm .optionsTable th { + border: 1px solid #ddd; + text-align: left; + background-color: #789; +} +.nextSampleForm .optionsTable td { + border: 1px solid #ddd; + text-align: left; +} diff --git a/plugins/ohifv3/extension-monai-label/src/components/actions/NextSampleForm.tsx b/plugins/ohifv3/extensions/monai-label/src/components/actions/NextSampleForm.tsx similarity index 98% rename from plugins/ohifv3/extension-monai-label/src/components/actions/NextSampleForm.tsx rename to plugins/ohifv3/extensions/monai-label/src/components/actions/NextSampleForm.tsx index 3112fec5f..643ad524c 100644 --- a/plugins/ohifv3/extension-monai-label/src/components/actions/NextSampleForm.tsx +++ b/plugins/ohifv3/extensions/monai-label/src/components/actions/NextSampleForm.tsx @@ -13,7 +13,7 @@ limitations under the License. import React, { Component } from 'react'; -import './NextSampleForm.styl'; +import './NextSampleForm.css'; import PropTypes from 'prop-types'; export default class NextSampleForm extends Component { diff --git a/plugins/ohifv3/extension-monai-label/src/components/actions/OptionTable.styl b/plugins/ohifv3/extensions/monai-label/src/components/actions/OptionTable.css similarity index 89% rename from plugins/ohifv3/extension-monai-label/src/components/actions/OptionTable.styl rename to plugins/ohifv3/extensions/monai-label/src/components/actions/OptionTable.css index ed32a4c5a..c02744028 100644 --- a/plugins/ohifv3/extension-monai-label/src/components/actions/OptionTable.styl +++ b/plugins/ohifv3/extensions/monai-label/src/components/actions/OptionTable.css @@ -10,26 +10,21 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ - -@import "BaseTab.styl" - .optionsTable { font-family: arial, sans-serif; border-collapse: collapse; width: 100%; font-size: smaller; } - .optionsTable th { border: 1px solid #070303; text-align: left; - background-color: lightslategray; + background-color: #789; } - .optionsTable td { border: 1px solid #070202; text-align: left; } - -.optionsInput - width: 100% +.optionsInput { + width: 100%; +} diff --git a/plugins/ohifv3/extension-monai-label/src/components/actions/OptionTable.tsx b/plugins/ohifv3/extensions/monai-label/src/components/actions/OptionTable.tsx similarity index 99% rename from plugins/ohifv3/extension-monai-label/src/components/actions/OptionTable.tsx rename to plugins/ohifv3/extensions/monai-label/src/components/actions/OptionTable.tsx index 8e41765d7..4a2a86f05 100644 --- a/plugins/ohifv3/extension-monai-label/src/components/actions/OptionTable.tsx +++ b/plugins/ohifv3/extensions/monai-label/src/components/actions/OptionTable.tsx @@ -13,7 +13,7 @@ limitations under the License. import React from 'react'; -import './OptionTable.styl'; +import './OptionTable.css'; import BaseTab from './BaseTab'; export default class OptionTable extends BaseTab { @@ -147,7 +147,7 @@ export default class OptionTable extends BaseTab {
Strategy:
- +
diff --git a/plugins/ohifv3/extension-monai-label/src/components/actions/SmartEdit.tsx b/plugins/ohifv3/extensions/monai-label/src/components/actions/SmartEdit.tsx similarity index 99% rename from plugins/ohifv3/extension-monai-label/src/components/actions/SmartEdit.tsx rename to plugins/ohifv3/extensions/monai-label/src/components/actions/SmartEdit.tsx index d71ae4156..ba607d19a 100644 --- a/plugins/ohifv3/extension-monai-label/src/components/actions/SmartEdit.tsx +++ b/plugins/ohifv3/extensions/monai-label/src/components/actions/SmartEdit.tsx @@ -12,7 +12,6 @@ limitations under the License. */ import React from 'react'; -import './SmartEdit.styl'; import ModelSelector from '../ModelSelector'; import BaseTab from './BaseTab'; import * as cornerstoneTools from '@cornerstonejs/tools'; diff --git a/plugins/ohifv3/extension-monai-label/src/components/callInputDialog.tsx b/plugins/ohifv3/extensions/monai-label/src/components/callInputDialog.tsx similarity index 100% rename from plugins/ohifv3/extension-monai-label/src/components/callInputDialog.tsx rename to plugins/ohifv3/extensions/monai-label/src/components/callInputDialog.tsx diff --git a/plugins/ohifv3/extension-monai-label/src/components/colorPickerDialog.css b/plugins/ohifv3/extensions/monai-label/src/components/colorPickerDialog.css similarity index 100% rename from plugins/ohifv3/extension-monai-label/src/components/colorPickerDialog.css rename to plugins/ohifv3/extensions/monai-label/src/components/colorPickerDialog.css diff --git a/plugins/ohifv3/extension-monai-label/src/components/colorPickerDialog.tsx b/plugins/ohifv3/extensions/monai-label/src/components/colorPickerDialog.tsx similarity index 100% rename from plugins/ohifv3/extension-monai-label/src/components/colorPickerDialog.tsx rename to plugins/ohifv3/extensions/monai-label/src/components/colorPickerDialog.tsx diff --git a/plugins/ohifv3/extensions/monai-label/src/components/w3.css b/plugins/ohifv3/extensions/monai-label/src/components/w3.css new file mode 100644 index 000000000..3e78e3b2c --- /dev/null +++ b/plugins/ohifv3/extensions/monai-label/src/components/w3.css @@ -0,0 +1,235 @@ +/* W3.CSS 4.15 December 2020 by Jan Egil and Borge Refsnes */ +html{box-sizing:border-box}*,*:before,*:after{box-sizing:inherit} +/* Extract from normalize.css by Nicolas Gallagher and Jonathan Neal git.io/normalize */ +html{-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%}body{margin:0} +article,aside,details,figcaption,figure,footer,header,main,menu,nav,section{display:block}summary{display:list-item} +audio,canvas,progress,video{display:inline-block}progress{vertical-align:baseline} +audio:not([controls]){display:none;height:0}[hidden],template{display:none} +a{background-color:transparent}a:active,a:hover{outline-width:0} +abbr[title]{border-bottom:none;text-decoration:underline;text-decoration:underline dotted} +b,strong{font-weight:bolder}dfn{font-style:italic}mark{background:#ff0;color:#000} +small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline} +sub{bottom:-0.25em}sup{top:-0.5em}figure{margin:1em 40px}img{border-style:none} +code,kbd,pre,samp{font-family:monospace,monospace;font-size:1em}hr{box-sizing:content-box;height:0;overflow:visible} +button,input,select,textarea,optgroup{font:inherit;margin:0}optgroup{font-weight:bold} +button,input{overflow:visible}button,select{text-transform:none} +button,[type=button],[type=reset],[type=submit]{-webkit-appearance:button} +button::-moz-focus-inner,[type=button]::-moz-focus-inner,[type=reset]::-moz-focus-inner,[type=submit]::-moz-focus-inner{border-style:none;padding:0} +button:-moz-focusring,[type=button]:-moz-focusring,[type=reset]:-moz-focusring,[type=submit]:-moz-focusring{outline:1px dotted ButtonText} +fieldset{border:1px solid #c0c0c0;margin:0 2px;padding:.35em .625em .75em} +legend{color:inherit;display:table;max-width:100%;padding:0;white-space:normal}textarea{overflow:auto} +[type=checkbox],[type=radio]{padding:0} +[type=number]::-webkit-inner-spin-button,[type=number]::-webkit-outer-spin-button{height:auto} +[type=search]{-webkit-appearance:textfield;outline-offset:-2px} +[type=search]::-webkit-search-decoration{-webkit-appearance:none} +::-webkit-file-upload-button{-webkit-appearance:button;font:inherit} +/* End extract */ +html,body{font-family:Verdana,sans-serif;font-size:15px;line-height:1.5}html{overflow-x:hidden} +h1{font-size:36px}h2{font-size:30px}h3{font-size:24px}h4{font-size:20px}h5{font-size:18px}h6{font-size:16px} +.w3-serif{font-family:serif}.w3-sans-serif{font-family:sans-serif}.w3-cursive{font-family:cursive}.w3-monospace{font-family:monospace} +h1,h2,h3,h4,h5,h6{font-family:"Segoe UI",Arial,sans-serif;font-weight:400;margin:10px 0}.w3-wide{letter-spacing:4px} +hr{border:0;border-top:1px solid #eee;margin:20px 0} +.w3-image{max-width:100%;height:auto}img{vertical-align:middle}a{color:inherit} +.w3-table,.w3-table-all{border-collapse:collapse;border-spacing:0;width:100%;display:table}.w3-table-all{border:1px solid #ccc} +.w3-bordered tr,.w3-table-all tr{border-bottom:1px solid #ddd}.w3-striped tbody tr:nth-child(even){background-color:#f1f1f1} +.w3-table-all tr:nth-child(odd){background-color:#fff}.w3-table-all tr:nth-child(even){background-color:#f1f1f1} +.w3-hoverable tbody tr:hover,.w3-ul.w3-hoverable li:hover{background-color:#ccc}.w3-centered tr th,.w3-centered tr td{text-align:center} +.w3-table td,.w3-table th,.w3-table-all td,.w3-table-all th{padding:8px 8px;display:table-cell;text-align:left;vertical-align:top} +.w3-table th:first-child,.w3-table td:first-child,.w3-table-all th:first-child,.w3-table-all td:first-child{padding-left:16px} +.w3-btn,.w3-button{border:none;display:inline-block;padding:8px 16px;vertical-align:middle;overflow:hidden;text-decoration:none;color:inherit;background-color:inherit;text-align:center;cursor:pointer;white-space:nowrap} +.w3-btn:hover{box-shadow:0 8px 16px 0 rgba(0,0,0,0.2),0 6px 20px 0 rgba(0,0,0,0.19)} +.w3-btn,.w3-button{-webkit-touch-callout:none;-webkit-user-select:none;-khtml-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none} +.w3-disabled,.w3-btn:disabled,.w3-button:disabled{cursor:not-allowed;opacity:0.3}.w3-disabled *,:disabled *{pointer-events:none} +.w3-btn.w3-disabled:hover,.w3-btn:disabled:hover{box-shadow:none} +.w3-badge,.w3-tag{background-color:#000;color:#fff;display:inline-block;padding-left:8px;padding-right:8px;text-align:center}.w3-badge{border-radius:50%} +.w3-ul{list-style-type:none;padding:0;margin:0}.w3-ul li{padding:8px 16px;border-bottom:1px solid #ddd}.w3-ul li:last-child{border-bottom:none} +.w3-tooltip,.w3-display-container{position:relative}.w3-tooltip .w3-text{display:none}.w3-tooltip:hover .w3-text{display:inline-block} +.w3-ripple:active{opacity:0.5}.w3-ripple{transition:opacity 0s} +.w3-input{padding:8px;display:block;border:none;border-bottom:1px solid #ccc;width:100%} +.w3-select{padding:9px 0;width:100%;border:none;border-bottom:1px solid #ccc} +.w3-dropdown-click,.w3-dropdown-hover{position:relative;display:inline-block;cursor:pointer} +.w3-dropdown-hover:hover .w3-dropdown-content{display:block} +.w3-dropdown-hover:first-child,.w3-dropdown-click:hover{background-color:#ccc;color:#000} +.w3-dropdown-hover:hover > .w3-button:first-child,.w3-dropdown-click:hover > .w3-button:first-child{background-color:#ccc;color:#000} +.w3-dropdown-content{cursor:auto;color:#000;background-color:#fff;display:none;position:absolute;min-width:160px;margin:0;padding:0;z-index:1} +.w3-check,.w3-radio{width:24px;height:24px;position:relative;top:6px} +.w3-sidebar{height:100%;width:200px;background-color:#fff;position:fixed!important;z-index:1;overflow:auto} +.w3-bar-block .w3-dropdown-hover,.w3-bar-block .w3-dropdown-click{width:100%} +.w3-bar-block .w3-dropdown-hover .w3-dropdown-content,.w3-bar-block .w3-dropdown-click .w3-dropdown-content{min-width:100%} +.w3-bar-block .w3-dropdown-hover .w3-button,.w3-bar-block .w3-dropdown-click .w3-button{width:100%;text-align:left;padding:8px 16px} +.w3-main,#main{transition:margin-left .4s} +.w3-modal{z-index:3;display:none;padding-top:100px;position:fixed;left:0;top:0;width:100%;height:100%;overflow:auto;background-color:rgb(0,0,0);background-color:rgba(0,0,0,0.4)} +.w3-modal-content{margin:auto;background-color:#fff;position:relative;padding:0;outline:0;width:600px} +.w3-bar{width:100%;overflow:hidden}.w3-center .w3-bar{display:inline-block;width:auto} +.w3-bar .w3-bar-item{padding:8px 16px;float:left;width:auto;border:none;display:block;outline:0} +.w3-bar .w3-dropdown-hover,.w3-bar .w3-dropdown-click{position:static;float:left} +.w3-bar .w3-button{white-space:normal} +.w3-bar-block .w3-bar-item{width:100%;display:block;padding:8px 16px;text-align:left;border:none;white-space:normal;float:none;outline:0} +.w3-bar-block.w3-center .w3-bar-item{text-align:center}.w3-block{display:block;width:100%} +.w3-responsive{display:block;overflow-x:auto} +.w3-container:after,.w3-container:before,.w3-panel:after,.w3-panel:before,.w3-row:after,.w3-row:before,.w3-row-padding:after,.w3-row-padding:before, +.w3-cell-row:before,.w3-cell-row:after,.w3-clear:after,.w3-clear:before,.w3-bar:before,.w3-bar:after{content:"";display:table;clear:both} +.w3-col,.w3-half,.w3-third,.w3-twothird,.w3-threequarter,.w3-quarter{float:left;width:100%} +.w3-col.s1{width:8.33333%}.w3-col.s2{width:16.66666%}.w3-col.s3{width:24.99999%}.w3-col.s4{width:33.33333%} +.w3-col.s5{width:41.66666%}.w3-col.s6{width:49.99999%}.w3-col.s7{width:58.33333%}.w3-col.s8{width:66.66666%} +.w3-col.s9{width:74.99999%}.w3-col.s10{width:83.33333%}.w3-col.s11{width:91.66666%}.w3-col.s12{width:99.99999%} +@media (min-width:601px){.w3-col.m1{width:8.33333%}.w3-col.m2{width:16.66666%}.w3-col.m3,.w3-quarter{width:24.99999%}.w3-col.m4,.w3-third{width:33.33333%} +.w3-col.m5{width:41.66666%}.w3-col.m6,.w3-half{width:49.99999%}.w3-col.m7{width:58.33333%}.w3-col.m8,.w3-twothird{width:66.66666%} +.w3-col.m9,.w3-threequarter{width:74.99999%}.w3-col.m10{width:83.33333%}.w3-col.m11{width:91.66666%}.w3-col.m12{width:99.99999%}} +@media (min-width:993px){.w3-col.l1{width:8.33333%}.w3-col.l2{width:16.66666%}.w3-col.l3{width:24.99999%}.w3-col.l4{width:33.33333%} +.w3-col.l5{width:41.66666%}.w3-col.l6{width:49.99999%}.w3-col.l7{width:58.33333%}.w3-col.l8{width:66.66666%} +.w3-col.l9{width:74.99999%}.w3-col.l10{width:83.33333%}.w3-col.l11{width:91.66666%}.w3-col.l12{width:99.99999%}} +.w3-rest{overflow:hidden}.w3-stretch{margin-left:-16px;margin-right:-16px} +.w3-content,.w3-auto{margin-left:auto;margin-right:auto}.w3-content{max-width:980px}.w3-auto{max-width:1140px} +.w3-cell-row{display:table;width:100%}.w3-cell{display:table-cell} +.w3-cell-top{vertical-align:top}.w3-cell-middle{vertical-align:middle}.w3-cell-bottom{vertical-align:bottom} +.w3-hide{display:none!important}.w3-show-block,.w3-show{display:block!important}.w3-show-inline-block{display:inline-block!important} +@media (max-width:1205px){.w3-auto{max-width:95%}} +@media (max-width:600px){.w3-modal-content{margin:0 10px;width:auto!important}.w3-modal{padding-top:30px} +.w3-dropdown-hover.w3-mobile .w3-dropdown-content,.w3-dropdown-click.w3-mobile .w3-dropdown-content{position:relative} +.w3-hide-small{display:none!important}.w3-mobile{display:block;width:100%!important}.w3-bar-item.w3-mobile,.w3-dropdown-hover.w3-mobile,.w3-dropdown-click.w3-mobile{text-align:center} +.w3-dropdown-hover.w3-mobile,.w3-dropdown-hover.w3-mobile .w3-btn,.w3-dropdown-hover.w3-mobile .w3-button,.w3-dropdown-click.w3-mobile,.w3-dropdown-click.w3-mobile .w3-btn,.w3-dropdown-click.w3-mobile .w3-button{width:100%}} +@media (max-width:768px){.w3-modal-content{width:500px}.w3-modal{padding-top:50px}} +@media (min-width:993px){.w3-modal-content{width:900px}.w3-hide-large{display:none!important}.w3-sidebar.w3-collapse{display:block!important}} +@media (max-width:992px) and (min-width:601px){.w3-hide-medium{display:none!important}} +@media (max-width:992px){.w3-sidebar.w3-collapse{display:none}.w3-main{margin-left:0!important;margin-right:0!important}.w3-auto{max-width:100%}} +.w3-top,.w3-bottom{position:fixed;width:100%;z-index:1}.w3-top{top:0}.w3-bottom{bottom:0} +.w3-overlay{position:fixed;display:none;width:100%;height:100%;top:0;left:0;right:0;bottom:0;background-color:rgba(0,0,0,0.5);z-index:2} +.w3-display-topleft{position:absolute;left:0;top:0}.w3-display-topright{position:absolute;right:0;top:0} +.w3-display-bottomleft{position:absolute;left:0;bottom:0}.w3-display-bottomright{position:absolute;right:0;bottom:0} +.w3-display-middle{position:absolute;top:50%;left:50%;transform:translate(-50%,-50%);-ms-transform:translate(-50%,-50%)} +.w3-display-left{position:absolute;top:50%;left:0%;transform:translate(0%,-50%);-ms-transform:translate(-0%,-50%)} +.w3-display-right{position:absolute;top:50%;right:0%;transform:translate(0%,-50%);-ms-transform:translate(0%,-50%)} +.w3-display-topmiddle{position:absolute;left:50%;top:0;transform:translate(-50%,0%);-ms-transform:translate(-50%,0%)} +.w3-display-bottommiddle{position:absolute;left:50%;bottom:0;transform:translate(-50%,0%);-ms-transform:translate(-50%,0%)} +.w3-display-container:hover .w3-display-hover{display:block}.w3-display-container:hover span.w3-display-hover{display:inline-block}.w3-display-hover{display:none} +.w3-display-position{position:absolute} +.w3-circle{border-radius:50%} +.w3-round-small{border-radius:2px}.w3-round,.w3-round-medium{border-radius:4px}.w3-round-large{border-radius:8px}.w3-round-xlarge{border-radius:16px}.w3-round-xxlarge{border-radius:32px} +.w3-row-padding,.w3-row-padding>.w3-half,.w3-row-padding>.w3-third,.w3-row-padding>.w3-twothird,.w3-row-padding>.w3-threequarter,.w3-row-padding>.w3-quarter,.w3-row-padding>.w3-col{padding:0 8px} +.w3-container,.w3-panel{padding:0.01em 16px}.w3-panel{margin-top:16px;margin-bottom:16px} +.w3-code,.w3-codespan{font-family:Consolas,"courier new";font-size:16px} +.w3-code{width:auto;background-color:#fff;padding:8px 12px;border-left:4px solid #4CAF50;word-wrap:break-word} +.w3-codespan{color:crimson;background-color:#f1f1f1;padding-left:4px;padding-right:4px;font-size:110%} +.w3-card,.w3-card-2{box-shadow:0 2px 5px 0 rgba(0,0,0,0.16),0 2px 10px 0 rgba(0,0,0,0.12)} +.w3-card-4,.w3-hover-shadow:hover{box-shadow:0 4px 10px 0 rgba(0,0,0,0.2),0 4px 20px 0 rgba(0,0,0,0.19)} +.w3-spin{animation:w3-spin 2s infinite linear}@keyframes w3-spin{0%{transform:rotate(0deg)}100%{transform:rotate(359deg)}} +.w3-animate-fading{animation:fading 10s infinite}@keyframes fading{0%{opacity:0}50%{opacity:1}100%{opacity:0}} +.w3-animate-opacity{animation:opac 0.8s}@keyframes opac{from{opacity:0} to{opacity:1}} +.w3-animate-top{position:relative;animation:animatetop 0.4s}@keyframes animatetop{from{top:-300px;opacity:0} to{top:0;opacity:1}} +.w3-animate-left{position:relative;animation:animateleft 0.4s}@keyframes animateleft{from{left:-300px;opacity:0} to{left:0;opacity:1}} +.w3-animate-right{position:relative;animation:animateright 0.4s}@keyframes animateright{from{right:-300px;opacity:0} to{right:0;opacity:1}} +.w3-animate-bottom{position:relative;animation:animatebottom 0.4s}@keyframes animatebottom{from{bottom:-300px;opacity:0} to{bottom:0;opacity:1}} +.w3-animate-zoom {animation:animatezoom 0.6s}@keyframes animatezoom{from{transform:scale(0)} to{transform:scale(1)}} +.w3-animate-input{transition:width 0.4s ease-in-out}.w3-animate-input:focus{width:100%!important} +.w3-opacity,.w3-hover-opacity:hover{opacity:0.60}.w3-opacity-off,.w3-hover-opacity-off:hover{opacity:1} +.w3-opacity-max{opacity:0.25}.w3-opacity-min{opacity:0.75} +.w3-greyscale-max,.w3-grayscale-max,.w3-hover-greyscale:hover,.w3-hover-grayscale:hover{filter:grayscale(100%)} +.w3-greyscale,.w3-grayscale{filter:grayscale(75%)}.w3-greyscale-min,.w3-grayscale-min{filter:grayscale(50%)} +.w3-sepia{filter:sepia(75%)}.w3-sepia-max,.w3-hover-sepia:hover{filter:sepia(100%)}.w3-sepia-min{filter:sepia(50%)} +.w3-tiny{font-size:10px!important}.w3-small{font-size:12px!important}.w3-medium{font-size:15px!important}.w3-large{font-size:18px!important} +.w3-xlarge{font-size:24px!important}.w3-xxlarge{font-size:36px!important}.w3-xxxlarge{font-size:48px!important}.w3-jumbo{font-size:64px!important} +.w3-left-align{text-align:left!important}.w3-right-align{text-align:right!important}.w3-justify{text-align:justify!important}.w3-center{text-align:center!important} +.w3-border-0{border:0!important}.w3-border{border:1px solid #ccc!important} +.w3-border-top{border-top:1px solid #ccc!important}.w3-border-bottom{border-bottom:1px solid #ccc!important} +.w3-border-left{border-left:1px solid #ccc!important}.w3-border-right{border-right:1px solid #ccc!important} +.w3-topbar{border-top:6px solid #ccc!important}.w3-bottombar{border-bottom:6px solid #ccc!important} +.w3-leftbar{border-left:6px solid #ccc!important}.w3-rightbar{border-right:6px solid #ccc!important} +.w3-section,.w3-code{margin-top:16px!important;margin-bottom:16px!important} +.w3-margin{margin:16px!important}.w3-margin-top{margin-top:16px!important}.w3-margin-bottom{margin-bottom:16px!important} +.w3-margin-left{margin-left:16px!important}.w3-margin-right{margin-right:16px!important} +.w3-padding-small{padding:4px 8px!important}.w3-padding{padding:8px 16px!important}.w3-padding-large{padding:12px 24px!important} +.w3-padding-16{padding-top:16px!important;padding-bottom:16px!important}.w3-padding-24{padding-top:24px!important;padding-bottom:24px!important} +.w3-padding-32{padding-top:32px!important;padding-bottom:32px!important}.w3-padding-48{padding-top:48px!important;padding-bottom:48px!important} +.w3-padding-64{padding-top:64px!important;padding-bottom:64px!important} +.w3-padding-top-64{padding-top:64px!important}.w3-padding-top-48{padding-top:48px!important} +.w3-padding-top-32{padding-top:32px!important}.w3-padding-top-24{padding-top:24px!important} +.w3-left{float:left!important}.w3-right{float:right!important} +.w3-button:hover{color:#000!important;background-color:#ccc!important} +.w3-transparent,.w3-hover-none:hover{background-color:transparent!important} +.w3-hover-none:hover{box-shadow:none!important} +/* Colors */ +.w3-amber,.w3-hover-amber:hover{color:#000!important;background-color:#ffc107!important} +.w3-aqua,.w3-hover-aqua:hover{color:#000!important;background-color:#00ffff!important} +.w3-blue,.w3-hover-blue:hover{color:#fff!important;background-color:#2196F3!important} +.w3-light-blue,.w3-hover-light-blue:hover{color:#000!important;background-color:#87CEEB!important} +.w3-brown,.w3-hover-brown:hover{color:#fff!important;background-color:#795548!important} +.w3-cyan,.w3-hover-cyan:hover{color:#000!important;background-color:#00bcd4!important} +.w3-blue-grey,.w3-hover-blue-grey:hover,.w3-blue-gray,.w3-hover-blue-gray:hover{color:#fff!important;background-color:#607d8b!important} +.w3-green,.w3-hover-green:hover{color:#fff!important;background-color:#4CAF50!important} +.w3-light-green,.w3-hover-light-green:hover{color:#000!important;background-color:#8bc34a!important} +.w3-indigo,.w3-hover-indigo:hover{color:#fff!important;background-color:#3f51b5!important} +.w3-khaki,.w3-hover-khaki:hover{color:#000!important;background-color:#f0e68c!important} +.w3-lime,.w3-hover-lime:hover{color:#000!important;background-color:#cddc39!important} +.w3-orange,.w3-hover-orange:hover{color:#000!important;background-color:#ff9800!important} +.w3-deep-orange,.w3-hover-deep-orange:hover{color:#fff!important;background-color:#ff5722!important} +.w3-pink,.w3-hover-pink:hover{color:#fff!important;background-color:#e91e63!important} +.w3-purple,.w3-hover-purple:hover{color:#fff!important;background-color:#9c27b0!important} +.w3-deep-purple,.w3-hover-deep-purple:hover{color:#fff!important;background-color:#673ab7!important} +.w3-red,.w3-hover-red:hover{color:#fff!important;background-color:#f44336!important} +.w3-sand,.w3-hover-sand:hover{color:#000!important;background-color:#fdf5e6!important} +.w3-teal,.w3-hover-teal:hover{color:#fff!important;background-color:#009688!important} +.w3-yellow,.w3-hover-yellow:hover{color:#000!important;background-color:#ffeb3b!important} +.w3-white,.w3-hover-white:hover{color:#000!important;background-color:#fff!important} +.w3-black,.w3-hover-black:hover{color:#fff!important;background-color:#000!important} +.w3-grey,.w3-hover-grey:hover,.w3-gray,.w3-hover-gray:hover{color:#000!important;background-color:#9e9e9e!important} +.w3-light-grey,.w3-hover-light-grey:hover,.w3-light-gray,.w3-hover-light-gray:hover{color:#000!important;background-color:#f1f1f1!important} +.w3-dark-grey,.w3-hover-dark-grey:hover,.w3-dark-gray,.w3-hover-dark-gray:hover{color:#fff!important;background-color:#616161!important} +.w3-pale-red,.w3-hover-pale-red:hover{color:#000!important;background-color:#ffdddd!important} +.w3-pale-green,.w3-hover-pale-green:hover{color:#000!important;background-color:#ddffdd!important} +.w3-pale-yellow,.w3-hover-pale-yellow:hover{color:#000!important;background-color:#ffffcc!important} +.w3-pale-blue,.w3-hover-pale-blue:hover{color:#000!important;background-color:#ddffff!important} +.w3-text-amber,.w3-hover-text-amber:hover{color:#ffc107!important} +.w3-text-aqua,.w3-hover-text-aqua:hover{color:#00ffff!important} +.w3-text-blue,.w3-hover-text-blue:hover{color:#2196F3!important} +.w3-text-light-blue,.w3-hover-text-light-blue:hover{color:#87CEEB!important} +.w3-text-brown,.w3-hover-text-brown:hover{color:#795548!important} +.w3-text-cyan,.w3-hover-text-cyan:hover{color:#00bcd4!important} +.w3-text-blue-grey,.w3-hover-text-blue-grey:hover,.w3-text-blue-gray,.w3-hover-text-blue-gray:hover{color:#607d8b!important} +.w3-text-green,.w3-hover-text-green:hover{color:#4CAF50!important} +.w3-text-light-green,.w3-hover-text-light-green:hover{color:#8bc34a!important} +.w3-text-indigo,.w3-hover-text-indigo:hover{color:#3f51b5!important} +.w3-text-khaki,.w3-hover-text-khaki:hover{color:#b4aa50!important} +.w3-text-lime,.w3-hover-text-lime:hover{color:#cddc39!important} +.w3-text-orange,.w3-hover-text-orange:hover{color:#ff9800!important} +.w3-text-deep-orange,.w3-hover-text-deep-orange:hover{color:#ff5722!important} +.w3-text-pink,.w3-hover-text-pink:hover{color:#e91e63!important} +.w3-text-purple,.w3-hover-text-purple:hover{color:#9c27b0!important} +.w3-text-deep-purple,.w3-hover-text-deep-purple:hover{color:#673ab7!important} +.w3-text-red,.w3-hover-text-red:hover{color:#f44336!important} +.w3-text-sand,.w3-hover-text-sand:hover{color:#fdf5e6!important} +.w3-text-teal,.w3-hover-text-teal:hover{color:#009688!important} +.w3-text-yellow,.w3-hover-text-yellow:hover{color:#d2be0e!important} +.w3-text-white,.w3-hover-text-white:hover{color:#fff!important} +.w3-text-black,.w3-hover-text-black:hover{color:#000!important} +.w3-text-grey,.w3-hover-text-grey:hover,.w3-text-gray,.w3-hover-text-gray:hover{color:#757575!important} +.w3-text-light-grey,.w3-hover-text-light-grey:hover,.w3-text-light-gray,.w3-hover-text-light-gray:hover{color:#f1f1f1!important} +.w3-text-dark-grey,.w3-hover-text-dark-grey:hover,.w3-text-dark-gray,.w3-hover-text-dark-gray:hover{color:#3a3a3a!important} +.w3-border-amber,.w3-hover-border-amber:hover{border-color:#ffc107!important} +.w3-border-aqua,.w3-hover-border-aqua:hover{border-color:#00ffff!important} +.w3-border-blue,.w3-hover-border-blue:hover{border-color:#2196F3!important} +.w3-border-light-blue,.w3-hover-border-light-blue:hover{border-color:#87CEEB!important} +.w3-border-brown,.w3-hover-border-brown:hover{border-color:#795548!important} +.w3-border-cyan,.w3-hover-border-cyan:hover{border-color:#00bcd4!important} +.w3-border-blue-grey,.w3-hover-border-blue-grey:hover,.w3-border-blue-gray,.w3-hover-border-blue-gray:hover{border-color:#607d8b!important} +.w3-border-green,.w3-hover-border-green:hover{border-color:#4CAF50!important} +.w3-border-light-green,.w3-hover-border-light-green:hover{border-color:#8bc34a!important} +.w3-border-indigo,.w3-hover-border-indigo:hover{border-color:#3f51b5!important} +.w3-border-khaki,.w3-hover-border-khaki:hover{border-color:#f0e68c!important} +.w3-border-lime,.w3-hover-border-lime:hover{border-color:#cddc39!important} +.w3-border-orange,.w3-hover-border-orange:hover{border-color:#ff9800!important} +.w3-border-deep-orange,.w3-hover-border-deep-orange:hover{border-color:#ff5722!important} +.w3-border-pink,.w3-hover-border-pink:hover{border-color:#e91e63!important} +.w3-border-purple,.w3-hover-border-purple:hover{border-color:#9c27b0!important} +.w3-border-deep-purple,.w3-hover-border-deep-purple:hover{border-color:#673ab7!important} +.w3-border-red,.w3-hover-border-red:hover{border-color:#f44336!important} +.w3-border-sand,.w3-hover-border-sand:hover{border-color:#fdf5e6!important} +.w3-border-teal,.w3-hover-border-teal:hover{border-color:#009688!important} +.w3-border-yellow,.w3-hover-border-yellow:hover{border-color:#ffeb3b!important} +.w3-border-white,.w3-hover-border-white:hover{border-color:#fff!important} +.w3-border-black,.w3-hover-border-black:hover{border-color:#000!important} +.w3-border-grey,.w3-hover-border-grey:hover,.w3-border-gray,.w3-hover-border-gray:hover{border-color:#9e9e9e!important} +.w3-border-light-grey,.w3-hover-border-light-grey:hover,.w3-border-light-gray,.w3-hover-border-light-gray:hover{border-color:#f1f1f1!important} +.w3-border-dark-grey,.w3-hover-border-dark-grey:hover,.w3-border-dark-gray,.w3-hover-border-dark-gray:hover{border-color:#616161!important} +.w3-border-pale-red,.w3-hover-border-pale-red:hover{border-color:#ffe7e7!important}.w3-border-pale-green,.w3-hover-border-pale-green:hover{border-color:#e7ffe7!important} +.w3-border-pale-yellow,.w3-hover-border-pale-yellow:hover{border-color:#ffffcc!important}.w3-border-pale-blue,.w3-hover-border-pale-blue:hover{border-color:#e7ffff!important} diff --git a/plugins/ohifv3/extension-monai-label/src/getCommandsModule.ts b/plugins/ohifv3/extensions/monai-label/src/getCommandsModule.ts similarity index 100% rename from plugins/ohifv3/extension-monai-label/src/getCommandsModule.ts rename to plugins/ohifv3/extensions/monai-label/src/getCommandsModule.ts diff --git a/plugins/ohifv3/extension-monai-label/src/getPanelModule.tsx b/plugins/ohifv3/extensions/monai-label/src/getPanelModule.tsx similarity index 100% rename from plugins/ohifv3/extension-monai-label/src/getPanelModule.tsx rename to plugins/ohifv3/extensions/monai-label/src/getPanelModule.tsx diff --git a/plugins/ohifv3/extension-monai-label/src/id.js b/plugins/ohifv3/extensions/monai-label/src/id.js similarity index 100% rename from plugins/ohifv3/extension-monai-label/src/id.js rename to plugins/ohifv3/extensions/monai-label/src/id.js diff --git a/plugins/ohifv3/extension-monai-label/src/index.tsx b/plugins/ohifv3/extensions/monai-label/src/index.tsx similarity index 100% rename from plugins/ohifv3/extension-monai-label/src/index.tsx rename to plugins/ohifv3/extensions/monai-label/src/index.tsx diff --git a/plugins/ohifv3/extension-monai-label/src/init.ts b/plugins/ohifv3/extensions/monai-label/src/init.ts similarity index 100% rename from plugins/ohifv3/extension-monai-label/src/init.ts rename to plugins/ohifv3/extensions/monai-label/src/init.ts diff --git a/plugins/ohifv3/extension-monai-label/src/services/MonaiLabelClient.js b/plugins/ohifv3/extensions/monai-label/src/services/MonaiLabelClient.js similarity index 100% rename from plugins/ohifv3/extension-monai-label/src/services/MonaiLabelClient.js rename to plugins/ohifv3/extensions/monai-label/src/services/MonaiLabelClient.js diff --git a/plugins/ohifv3/extension-monai-label/src/tools/ProbeMONAILabelTool.ts b/plugins/ohifv3/extensions/monai-label/src/tools/ProbeMONAILabelTool.ts similarity index 100% rename from plugins/ohifv3/extension-monai-label/src/tools/ProbeMONAILabelTool.ts rename to plugins/ohifv3/extensions/monai-label/src/tools/ProbeMONAILabelTool.ts diff --git a/plugins/ohifv3/extension-monai-label/src/utils/GenericAnatomyColors.js b/plugins/ohifv3/extensions/monai-label/src/utils/GenericAnatomyColors.js similarity index 100% rename from plugins/ohifv3/extension-monai-label/src/utils/GenericAnatomyColors.js rename to plugins/ohifv3/extensions/monai-label/src/utils/GenericAnatomyColors.js diff --git a/plugins/ohifv3/extension-monai-label/src/utils/GenericUtils.js b/plugins/ohifv3/extensions/monai-label/src/utils/GenericUtils.js similarity index 100% rename from plugins/ohifv3/extension-monai-label/src/utils/GenericUtils.js rename to plugins/ohifv3/extensions/monai-label/src/utils/GenericUtils.js diff --git a/plugins/ohifv3/extension-monai-label/src/utils/SegmentationReader.js b/plugins/ohifv3/extensions/monai-label/src/utils/SegmentationReader.js similarity index 100% rename from plugins/ohifv3/extension-monai-label/src/utils/SegmentationReader.js rename to plugins/ohifv3/extensions/monai-label/src/utils/SegmentationReader.js diff --git a/plugins/ohifv3/extension-monai-label/src/utils/SegmentationUtils.tsx b/plugins/ohifv3/extensions/monai-label/src/utils/SegmentationUtils.tsx similarity index 100% rename from plugins/ohifv3/extension-monai-label/src/utils/SegmentationUtils.tsx rename to plugins/ohifv3/extensions/monai-label/src/utils/SegmentationUtils.tsx diff --git a/plugins/ohifv3/extension-monai-label/src/utils/addToolInstance.ts b/plugins/ohifv3/extensions/monai-label/src/utils/addToolInstance.ts similarity index 100% rename from plugins/ohifv3/extension-monai-label/src/utils/addToolInstance.ts rename to plugins/ohifv3/extensions/monai-label/src/utils/addToolInstance.ts diff --git a/plugins/ohifv3/images/ohifv3.jpg b/plugins/ohifv3/images/ohifv3.jpg new file mode 100644 index 000000000..4c56ba9d3 Binary files /dev/null and b/plugins/ohifv3/images/ohifv3.jpg differ diff --git a/plugins/ohifv3/images/ohifv3.png b/plugins/ohifv3/images/ohifv3.png deleted file mode 100644 index 0679559e5..000000000 Binary files a/plugins/ohifv3/images/ohifv3.png and /dev/null differ diff --git a/plugins/ohifv3/mode-monai-label/.gitignore b/plugins/ohifv3/modes/monai-label/.gitignore similarity index 100% rename from plugins/ohifv3/mode-monai-label/.gitignore rename to plugins/ohifv3/modes/monai-label/.gitignore diff --git a/plugins/ohifv3/mode-monai-label/.prettierrc b/plugins/ohifv3/modes/monai-label/.prettierrc similarity index 100% rename from plugins/ohifv3/mode-monai-label/.prettierrc rename to plugins/ohifv3/modes/monai-label/.prettierrc diff --git a/plugins/ohifv3/mode-monai-label/.webpack/webpack.prod.js b/plugins/ohifv3/modes/monai-label/.webpack/webpack.prod.js similarity index 100% rename from plugins/ohifv3/mode-monai-label/.webpack/webpack.prod.js rename to plugins/ohifv3/modes/monai-label/.webpack/webpack.prod.js diff --git a/plugins/ohifv3/mode-monai-label/LICENSE b/plugins/ohifv3/modes/monai-label/LICENSE similarity index 100% rename from plugins/ohifv3/mode-monai-label/LICENSE rename to plugins/ohifv3/modes/monai-label/LICENSE diff --git a/plugins/ohifv3/mode-monai-label/README.md b/plugins/ohifv3/modes/monai-label/README.md similarity index 100% rename from plugins/ohifv3/mode-monai-label/README.md rename to plugins/ohifv3/modes/monai-label/README.md diff --git a/plugins/ohifv3/mode-monai-label/babel.config.js b/plugins/ohifv3/modes/monai-label/babel.config.js similarity index 100% rename from plugins/ohifv3/mode-monai-label/babel.config.js rename to plugins/ohifv3/modes/monai-label/babel.config.js diff --git a/plugins/ohifv3/mode-monai-label/package.json b/plugins/ohifv3/modes/monai-label/package.json similarity index 100% rename from plugins/ohifv3/mode-monai-label/package.json rename to plugins/ohifv3/modes/monai-label/package.json diff --git a/plugins/ohifv3/mode-monai-label/src/id.js b/plugins/ohifv3/modes/monai-label/src/id.js similarity index 100% rename from plugins/ohifv3/mode-monai-label/src/id.js rename to plugins/ohifv3/modes/monai-label/src/id.js diff --git a/plugins/ohifv3/mode-monai-label/src/index.tsx b/plugins/ohifv3/modes/monai-label/src/index.tsx similarity index 100% rename from plugins/ohifv3/mode-monai-label/src/index.tsx rename to plugins/ohifv3/modes/monai-label/src/index.tsx diff --git a/plugins/ohifv3/mode-monai-label/src/initToolGroups.js b/plugins/ohifv3/modes/monai-label/src/initToolGroups.js similarity index 100% rename from plugins/ohifv3/mode-monai-label/src/initToolGroups.js rename to plugins/ohifv3/modes/monai-label/src/initToolGroups.js diff --git a/plugins/ohifv3/mode-monai-label/src/toolbarButtons.js b/plugins/ohifv3/modes/monai-label/src/toolbarButtons.js similarity index 100% rename from plugins/ohifv3/mode-monai-label/src/toolbarButtons.js rename to plugins/ohifv3/modes/monai-label/src/toolbarButtons.js diff --git a/plugins/ohifv3/requirements.sh b/plugins/ohifv3/requirements.sh index 064952153..e748b6211 100755 --- a/plugins/ohifv3/requirements.sh +++ b/plugins/ohifv3/requirements.sh @@ -20,3 +20,9 @@ else apt update apt-get install yarn -y fi + +if which nginx >/dev/null; then + echo "nginx is already installed" +else + apt-get install nginx -y +fi diff --git a/plugins/ohifv3/run.sh b/plugins/ohifv3/run.sh new file mode 100755 index 000000000..e8a3776d4 --- /dev/null +++ b/plugins/ohifv3/run.sh @@ -0,0 +1,21 @@ +#!/bin/bash + +# Copyright (c) MONAI Consortium +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# http://www.apache.org/licenses/LICENSE-2.0 +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +mkdir -p logs + +rm -rf www +mkdir -p www/html +cp -r Viewers/platform/app/dist www/html/ohif +cp -f config/monai_label.js www/html/ohif/app-config.js + +nginx -p `pwd` -c config/nginx.conf -e logs/error.log diff --git a/setup.py b/setup.py index 9c7cea04a..9189ff7ab 100755 --- a/setup.py +++ b/setup.py @@ -41,7 +41,7 @@ def recursive_files(directory, prefix): if build_ohif: print("Building OHIF...") script = "build.bat" if any(platform.win32_ver()) else "build.sh" - command = os.path.realpath(os.path.join(os.path.dirname(__file__), "plugins", "ohif", script)) + command = os.path.realpath(os.path.join(os.path.dirname(__file__), "plugins", "ohifv3", script)) if os.path.exists(command): subprocess.call(["sh", command]) else: diff --git a/tests/unit/endpoints/test_proxy.py b/tests/unit/endpoints/test_proxy.py index 61bdfee67..2bb2a6d92 100644 --- a/tests/unit/endpoints/test_proxy.py +++ b/tests/unit/endpoints/test_proxy.py @@ -10,32 +10,23 @@ # limitations under the License. import unittest from types import SimpleNamespace -from unittest.mock import MagicMock, patch +from unittest.mock import patch from .context import BasicEndpointTestSuite -class MockHttpClient(MagicMock): - def __init__(self, auth): - pass +class RawData: + def read(self): + return b"xyz" - async def get(self, url, **kwargs): - return SimpleNamespace(content=b"xyz", status_code=400) - async def __aenter__(self): - return self +def mocked_requests_get(*args, **kwargs): + return SimpleNamespace(content=b"xyz", raw=RawData(), status_code=400, headers={}) - async def __aexit__(self, *args): - pass - -def mock_http_client(auth): - return MockHttpClient(auth) - - -@patch("httpx.AsyncClient", new=mock_http_client) +@patch("requests.get", side_effect=mocked_requests_get) class TestEndPointLogs(BasicEndpointTestSuite): - def test_proxy(self): + def test_proxy(self, mock_get): self.client.get("/proxy/dicom/studies")