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 +
Strategy: | 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 {