Compare commits
7
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f9037f831d | ||
|
|
9e0bd52c6a | ||
|
|
f1b017dc08 | ||
|
|
81dcbe294d | ||
|
|
e09a3d2e93 | ||
|
|
978a86bf12 | ||
|
|
0139a32213 |
No files matched your search
@@ -48,7 +48,7 @@ Check out these helpful links:
|
||||
-->
|
||||
|
||||
<!-- prettier-ignore-start -->
|
||||
[ohif-org]: https://www.ohif.org
|
||||
[ohif-org]: http://www.ohif.org
|
||||
[dicom-web]: https://en.wikipedia.org/wiki/DICOMweb
|
||||
[gh-issues]: https://github.com/OHIF/Viewers/issues
|
||||
<!-- prettier-ignore-end -->
|
||||
@@ -5,6 +5,7 @@
|
||||
- [Getting Started](development/getting-started.md)
|
||||
- [Contributing](development/contributing.md)
|
||||
- [Continuous Integration](development/continous-integration.md)
|
||||
- [Testing](development/testing.md)
|
||||
- [Configuring](configuring/index.md)
|
||||
- [Data Source](configuring/data-source.md)
|
||||
|
||||
|
||||
@@ -13,7 +13,6 @@ architected, and the role each of it's dependent libraries plays.
|
||||
- [Overview](#overview)
|
||||
- [Business Logic](#business-logic)
|
||||
- [Component Library](#react-component-library)
|
||||
- [Internationalization](#internationalization-i18n)
|
||||
- [Extensions & Configuration](#extensions--configuration)
|
||||
- [Common Questions](#common-questions)
|
||||
|
||||
@@ -74,10 +73,10 @@ This diagram is a conceptual illustration of how the Viewer is architected.
|
||||
The [`@ohif/core`][core-github] project offers pre-packaged solutions for
|
||||
features common to Web-based medical imaging viewers. For example:
|
||||
|
||||
- [Hotkeys](#)
|
||||
- Hotkeys
|
||||
- DICOM Web requests
|
||||
- Hanging Protocols
|
||||
- [Managing a study's measurements](../services/default/measurements.md)
|
||||
- Managing a study's measurements
|
||||
- Managing a study's DICOM metadata
|
||||
- [A flexible pattern for extensions](../extensions/index.md)
|
||||
- And many others
|
||||
@@ -99,10 +98,6 @@ application.
|
||||
|
||||
[Check out our component library!](https://react.ohif.org/)
|
||||
|
||||
## Internationalization (i18n)
|
||||
|
||||
...
|
||||
|
||||
## Extensions & Configuration
|
||||
|
||||
While OHIF maintains several high value and commonly requested features in its
|
||||
@@ -120,7 +115,7 @@ the viewer. Some common use cases include:
|
||||
We expose common integration points via [extensions](../extensions/index.md) to
|
||||
make this possible. The viewer and many of our own extensions also offer
|
||||
[configuration][configuration]. For a list of extensions maintained by OHIF,
|
||||
[check out this helpful table](../extensions/index.mdl#maintained-extensions).
|
||||
[check out this helpful table](../extensions/index.md#maintained-extensions).
|
||||
|
||||
If you find yourself thinking "I wish the Viewer could do X", and you can't
|
||||
accomplish it with an extension today, create a GitHub issue! We're actively
|
||||
@@ -147,12 +142,12 @@ you would need to recreate.
|
||||
-->
|
||||
|
||||
<!-- prettier-ignore-start -->
|
||||
[monorepo]: #
|
||||
[monorepo]: https://github.com/OHIF/Viewers/issues/768
|
||||
[viewers-project]: https://github.com/OHIF/Viewers
|
||||
[viewer-npm]: https://www.npmjs.com/package/@ohif/viewer
|
||||
[pwa]: https://developers.google.com/web/progressive-web-apps/
|
||||
[configuration]: ../configuring/index.md
|
||||
[extensions]: ../extensions/index.md
|
||||
[core-github]: https://github.com/OHIF/viewers/platform/core
|
||||
[ui-github]: https://github.com/OHIF/Viewers/platform/ui
|
||||
[ui-github]: https://github.com/OHIF/Viewers/tree/master/platform/ui
|
||||
<!-- prettier-ignore-end -->
|
||||
@@ -123,7 +123,7 @@ There are two important steps to making sure this setup works:
|
||||
Most image archives do not provide either of these features "out of the box".
|
||||
It's common to use IIS, Nginx, or Apache to route incoming requests and append
|
||||
appropriate headers. You can find an example of this setup in our
|
||||
[Nginx + Image Archive Deployment Recipe](deployment/recipes/nginx--image-archive.md).
|
||||
[Nginx + Image Archive Deployment Recipe](./recipes/nginx--image-archive.md).
|
||||
|
||||
#### What if my archive doesn't support DicomWeb?
|
||||
|
||||
@@ -166,7 +166,7 @@ window.config = {
|
||||
```
|
||||
|
||||
You can find an example of this setup in our
|
||||
[User Account Control Deployment Recipe](deployment/recipes/user-account-control.md).
|
||||
[User Account Control Deployment Recipe](./recipes/user-account-control.md).
|
||||
|
||||
#### Choosing a Flow for the Viewer
|
||||
|
||||
@@ -183,12 +183,12 @@ many possible configurations, so please don't feel limited to these setups.
|
||||
Please feel free to suggest or contribute your own recipes.
|
||||
|
||||
- Script Include
|
||||
- [Embedding the Viewer](deployment/recipes/embedded-viewer.md)
|
||||
- [Embedding the Viewer](./recipes/embedded-viewer.md)
|
||||
- Stand-Alone
|
||||
- [Build for Production](deployment/recipes/build-for-production.md)
|
||||
- [Static](deployment/recipes/static-assets.md)
|
||||
- [Nginx + Image Archive](deployment/recipes/nginx--image-archive.md)
|
||||
- [User Account Control](deployment/recipes/user-account-control.md)
|
||||
- [Build for Production](./recipes/build-for-production.md)
|
||||
- [Static](./recipes/static-assets.md)
|
||||
- [Nginx + Image Archive](./recipes/nginx--image-archive.md)
|
||||
- [User Account Control](./recipes/user-account-control.md)
|
||||
|
||||
<!--
|
||||
Links
|
||||
|
||||
@@ -50,7 +50,7 @@ window.config = {
|
||||
```
|
||||
|
||||
To learn more about how you can configure the OHIF Viewer, check out our
|
||||
[Configuration Guide](./index.md).
|
||||
[Configuration Guide](../../configuring/index.md).
|
||||
|
||||
<ol start="3"><li>
|
||||
Render the viewer in the web page's target <code>div</code>
|
||||
|
||||
@@ -49,9 +49,7 @@ We can solve this one of two ways:
|
||||
1. Have our Image Archive located at the same domain as our Web App
|
||||
2. Add appropriate `Access-Control-Allow-*` HTTP headers
|
||||
|
||||
This solution uses the first approach, but you can see an example of the second
|
||||
in the `docker-compose` bundled with this project for local development:
|
||||
[HERE](https://github.com/OHIF/Viewers/blob/master/platform/viewer/.recipes/Nginx-Orthanc/docker-compose.yml)
|
||||
**This solution uses the first approach.**
|
||||
|
||||
You can read more about CORS in this Medium article: [Understanding
|
||||
CORS][understanding-cors]
|
||||
@@ -121,7 +119,10 @@ likely want to update:
|
||||
|
||||
#### OHIF Viewer
|
||||
|
||||
The OHIF Viewer's configuration is imported from a static `.js` file. The configuration we use is set to a specific file when we build the viewer, and determined by the env variable: `APP_CONFIG`. You can see where we set its value in the `dockerfile` for this solution:
|
||||
The OHIF Viewer's configuration is imported from a static `.js` file. The
|
||||
configuration we use is set to a specific file when we build the viewer, and
|
||||
determined by the env variable: `APP_CONFIG`. You can see where we set its value
|
||||
in the `dockerfile` for this solution:
|
||||
|
||||
`ENV APP_CONFIG=config/docker_openresty-orthanc.js`
|
||||
|
||||
@@ -138,11 +139,11 @@ Viewer's configuration, you can run:
|
||||
|
||||
All other files are found in: `/docker/OpenResty-Orthanc/`
|
||||
|
||||
| Service | Configuration | Docs |
|
||||
| ----------------- | ---------------------------------------------- | ------------------------------------------- |
|
||||
| OHIF Viewer | [dockerfile][dockerfile] / [config.js][config] | You're reading them now! |
|
||||
| OpenResty (Nginx) | [`/nginx.conf`][config-nginx] | [lua-resty-openidc][lua-resty-openidc-docs] |
|
||||
| Orthanc | [`/orthanc.json`][config-orthanc] | [Here][orthanc-docs] |
|
||||
| Service | Configuration | Docs |
|
||||
| ----------------- | --------------------------------- | ------------------------------------------- |
|
||||
| OHIF Viewer | [dockerfile][dockerfile] | You're reading them now! |
|
||||
| OpenResty (Nginx) | [`/nginx.conf`][config-nginx] | [lua-resty-openidc][lua-resty-openidc-docs] |
|
||||
| Orthanc | [`/orthanc.json`][config-orthanc] | [Here][orthanc-docs] |
|
||||
|
||||
## Next Steps
|
||||
|
||||
@@ -218,10 +219,11 @@ following resources helpful:
|
||||
- [OpenResty Guide](http://www.staticshin.com/programming/definitely-an-open-resty-guide/)
|
||||
- [Lua Ngx API](https://openresty-reference.readthedocs.io/en/latest/Lua_Nginx_API/)
|
||||
|
||||
For a different take on this setup, check out the repository one of our
|
||||
community members put together:
|
||||
For a different take on this setup, check out the repositories our community
|
||||
members put together:
|
||||
|
||||
- [mjstealey/ohif-orthanc-dimse-docker](https://github.com/mjstealey/ohif-orthanc-dimse-docker)
|
||||
- [trypag/ohif-orthanc-postgres-docker](https://github.com/trypag/ohif-orthanc-postgres-docker)
|
||||
|
||||
<!--
|
||||
Links
|
||||
@@ -234,8 +236,7 @@ community members put together:
|
||||
[orthanc-docs]: http://book.orthanc-server.com/users/configuration.html#configuration
|
||||
[lua-resty-openidc-docs]: https://github.com/zmartzone/lua-resty-openidc
|
||||
<!-- SRC -->
|
||||
[config]: #
|
||||
[dockerfile]: #
|
||||
[config-nginx]: #
|
||||
[config-orthanc]: #
|
||||
[dockerfile]: https://github.com/OHIF/Viewers/blob/master/platform/viewer/.recipes/OpenResty-Orthanc/dockerfile
|
||||
[config-nginx]: https://github.com/OHIF/Viewers/blob/master/platform/viewer/.recipes/OpenResty-Orthanc/config/nginx.conf
|
||||
[config-orthanc]: https://github.com/OHIF/Viewers/blob/master/platform/viewer/.recipes/OpenResty-Orthanc/config/orthanc.json
|
||||
<!-- prettier-ignore-end -->
|
||||
@@ -122,7 +122,10 @@ likely want to update:
|
||||
|
||||
#### OHIF Viewer
|
||||
|
||||
The OHIF Viewer's configuration is imported from a static `.js` file. The configuration we use is set to a specific file when we build the viewer, and determined by the env variable: `APP_CONFIG`. You can see where we set its value in the `dockerfile` for this solution:
|
||||
The OHIF Viewer's configuration is imported from a static `.js` file. The
|
||||
configuration we use is set to a specific file when we build the viewer, and
|
||||
determined by the env variable: `APP_CONFIG`. You can see where we set its value
|
||||
in the `dockerfile` for this solution:
|
||||
|
||||
`ENV APP_CONFIG=config/docker_openresty-orthanc-keycloak.js`
|
||||
|
||||
@@ -146,8 +149,8 @@ All other files are found in: `/docker/OpenResty-Orthanc-Keycloak/`
|
||||
| Orthanc | [`/orthanc.json`][config-orthanc] | [Here][orthanc-docs] |
|
||||
| Keycloak | [`/ohif-keycloak-realm.json`][config-keycloak]\* | |
|
||||
|
||||
- \* These are the seed values for Keycloak. They can be manually updated at
|
||||
`http://127.0.0.1/auth/admin`
|
||||
\* These are the seed values for Keycloak. They can be manually updated at
|
||||
`http://127.0.0.1/auth/admin`
|
||||
|
||||
#### Keycloak Themeing
|
||||
|
||||
@@ -261,12 +264,12 @@ for OAuth:
|
||||
|
||||
- [Diagrams of OpenID Connect Flows](https://medium.com/@darutk/diagrams-of-all-the-openid-connect-flows-6968e3990660)
|
||||
- [KeyCloak: OpenID Connect Flows](https://www.keycloak.org/docs/latest/securing_apps/index.html#authorization-code)
|
||||
- [Good description on SSO Protocols](https://www.keycloak.org/docs/2.5/server_admin/topics/sso-protocols/oidc.html)
|
||||
|
||||
For a different take on this setup, check out the repository one of our
|
||||
community members put together:
|
||||
For a different take on this setup, check out the repositories our community
|
||||
members put together:
|
||||
|
||||
- [mjstealey/ohif-orthanc-dimse-docker](https://github.com/mjstealey/ohif-orthanc-dimse-docker)
|
||||
- [trypag/ohif-orthanc-postgres-docker](https://github.com/trypag/ohif-orthanc-postgres-docker)
|
||||
|
||||
<!--
|
||||
Links
|
||||
@@ -278,8 +281,8 @@ community members put together:
|
||||
[lua-resty-openidc-docs]: https://github.com/zmartzone/lua-resty-openidc
|
||||
<!-- SRC -->
|
||||
[config]: https://github.com/OHIF/Viewers/blob/master/platform/viewer/src/config.js
|
||||
[dockerfile]: https://github.com/OHIF/Viewers/tree/master/platform/viewer/.recipes
|
||||
[config-nginx]: https://github.com/OHIF/Viewers/tree/master/platform/viewer/.recipes
|
||||
[config-orthanc]: https://github.com/OHIF/Viewers/tree/master/platform/viewer/.recipes
|
||||
[config-keycloak]: https://github.com/OHIF/Viewers/tree/master/platform/viewer/.recipes
|
||||
[dockerfile]: https://github.com/OHIF/Viewers/blob/master/platform/viewer/.recipes/OpenResty-Orthanc-Keycloak/dockerfile
|
||||
[config-nginx]: https://github.com/OHIF/Viewers/blob/master/platform/viewer/.recipes/OpenResty-Orthanc-Keycloak/config/nginx.conf
|
||||
[config-orthanc]: https://github.com/OHIF/Viewers/blob/master/platform/viewer/.recipes/OpenResty-Orthanc-Keycloak/config/orthanc.json
|
||||
[config-keycloak]: https://github.com/OHIF/Viewers/blob/master/platform/viewer/.recipes/OpenResty-Orthanc-Keycloak/config/ohif-keycloak-realm.json
|
||||
<!-- prettier-ignore-end -->
|
||||
@@ -114,8 +114,8 @@ the tips above will help ensure your changes are reviewed.
|
||||
|
||||
## Testing contribution pull requests
|
||||
|
||||
OHIF uses [netlify](netlify.com) so that pull requests are autogenerated and
|
||||
available for testing.
|
||||
OHIF uses [netlify](https://www.netlify.com/) so that pull requests are
|
||||
autogenerated and available for testing.
|
||||
|
||||
For example, [this url][example-url] allows you to test [pull request 237, the
|
||||
request that created this FAQ entry,][pr-237] using data pulled from Amazon S3.
|
||||
|
||||
@@ -132,7 +132,7 @@ feature `X` or scenario `Y`? Open an issue and let's discuss.
|
||||
[flow-org]: https://flow.org/
|
||||
<!-- Talks -->
|
||||
[assert-js-talks]: https://www.youtube.com/playlist?list=PLZ66c9_z3umNSrKSb5cmpxdXZcIPNvKGw
|
||||
[kent-talk]: https://www.youtube.com/watch?list=PLV5CVI1eNcJgNqzNwcs4UKrlJdhfDjshf
|
||||
[kent-talk]: https://www.youtube.com/watch?v=Fha2bVoC8SE
|
||||
[gleb-talk]: https://www.youtube.com/watch?v=5FnalKRjpZk
|
||||
[kent-blog]: https://kentcdodds.com/blog/unit-vs-integration-vs-e2e-tests
|
||||
<!-- Images -->
|
||||
|
||||
@@ -31,6 +31,7 @@
|
||||
</td>
|
||||
<td>Viewport, Toolbar</td>
|
||||
</tr>
|
||||
<!-- dicom-html -->
|
||||
<tr>
|
||||
<td>
|
||||
<a href="https://www.npmjs.com/package/@ohif/extension-dicom-html">DICOM HTML</a>
|
||||
@@ -40,6 +41,7 @@
|
||||
</td>
|
||||
<td>Viewport, SopClassHandler</td>
|
||||
</tr>
|
||||
<!-- dicom-pdf -->
|
||||
<tr>
|
||||
<td>
|
||||
<a href="https://www.npmjs.com/package/@ohif/extension-dicom-pdf">DICOM PDF</a>
|
||||
@@ -49,6 +51,7 @@
|
||||
</td>
|
||||
<td>Viewport, SopClassHandler</td>
|
||||
</tr>
|
||||
<!-- dicom-microscopy -->
|
||||
<tr>
|
||||
<td>
|
||||
<a href="https://www.npmjs.com/package/@ohif/extension-dicom-microscopy">DICOM Microscopy</a>
|
||||
@@ -58,5 +61,15 @@
|
||||
</td>
|
||||
<td>Viewport, SopClassHandler</td>
|
||||
</tr>
|
||||
<!-- dicom-segmentation -->
|
||||
<tr>
|
||||
<td>
|
||||
<a href="https://www.npmjs.com/package/@ohif/extension-dicom-segmentation">DICOM Segmentation</a>
|
||||
</td>
|
||||
<td>
|
||||
Renders segmentation images for a <a href="https://github.com/OHIF/Viewers/blob/master/extensions/dicom-segmentation/src/OHIFDicomSegSopClassHandler.js#L5-L7">specific SopClassUID</a>.
|
||||
</td>
|
||||
<td>Panel, Toolbar</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
@@ -74,7 +74,8 @@ export default {
|
||||
### Registering an Extension
|
||||
|
||||
There are two different ways to register and configure extensions: At
|
||||
[runtime](#runtime-extensions) and at [build time](#bundled-extensions).
|
||||
[runtime](#registering-at-runtime) and at
|
||||
[build time](#registering-at-build-time).
|
||||
|
||||
You can leverage one or both strategies. Which one(s) you choose depend on your
|
||||
application's requirements. Each [module](#modules) defined by the extension
|
||||
@@ -82,9 +83,9 @@ becomes available to the core application via the `ExtensionManager`.
|
||||
|
||||
#### Registering at Runtime
|
||||
|
||||
The `@ohif/viewer` uses a [configuration file](#) at startup. The schema for
|
||||
that file includes an `Extensions` key that supports an array of extensions to
|
||||
register.
|
||||
The `@ohif/viewer` uses a [configuration file](../viewer/configuration.md) at
|
||||
startup. The schema for that file includes an `Extensions` key that supports an
|
||||
array of extensions to register.
|
||||
|
||||
```js
|
||||
// prettier-ignore
|
||||
@@ -193,8 +194,8 @@ today, create a GitHub issue!
|
||||
|
||||
The `ExtensionManager` is a class made available to us via the `@ohif/core`
|
||||
project (platform/core). Our application instantiates a single instance of it,
|
||||
and provides a `ServicesManager` and `CommandsManager` along with the application's
|
||||
configuration through the appConfig key (optional).
|
||||
and provides a `ServicesManager` and `CommandsManager` along with the
|
||||
application's configuration through the appConfig key (optional).
|
||||
|
||||
```js
|
||||
const commandsManager = new CommandsManager();
|
||||
@@ -202,7 +203,7 @@ const servicesManager = new ServicesManager();
|
||||
const extensionManager = new ExtensionManager({
|
||||
commandsManager,
|
||||
servicesManager,
|
||||
appConfig
|
||||
appConfig,
|
||||
});
|
||||
```
|
||||
|
||||
@@ -212,8 +213,9 @@ The `ExtensionManager` only has a few public members:
|
||||
- `registerExtensions` - Registers an array of extensions
|
||||
- `modules` - An object containing registered extensions by `MODULE_TYPE`
|
||||
|
||||
During registration, lifecycle hooks and modules have access to the extension's config,
|
||||
the application's config and `ExtensionManager`'s `ServicesManager` and `CommandsManager` instances.
|
||||
During registration, lifecycle hooks and modules have access to the extension's
|
||||
config, the application's config and `ExtensionManager`'s `ServicesManager` and
|
||||
`CommandsManager` instances.
|
||||
|
||||
Our `@ohif/viewer` uses the `modules` member to access registered extensions at
|
||||
appropriate places in our application.
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
# Module: SOP Class Handler
|
||||
|
||||
An extension can register a SOP Class Handler Module by defining a
|
||||
`getSopClassHandlerModule` method. The SOP Class Handler is a bit different from
|
||||
the other modules, as it doesn't provide a `1:1` schema for UI or provide it's
|
||||
own components. It instead defines:
|
||||
An extension can register a [SOP Class][sop-class-link] Handler Module by
|
||||
defining a `getSopClassHandlerModule` method. The [SOP Class][sop-class-link]
|
||||
Handler is a bit different from the other modules, as it doesn't provide a `1:1`
|
||||
schema for UI or provide it's own components. It instead defines:
|
||||
|
||||
- `sopClassUIDs`: an array of string SOP Class UIDs that the
|
||||
`getDisplaySetFromSeries` method should be applied to.
|
||||
@@ -76,6 +76,13 @@ getSopClassHandlerModule({ servicesManager, commandsManager }) {
|
||||
};
|
||||
```
|
||||
|
||||
### More examples :
|
||||
|
||||
- [Dicom-HTML SOP][dicom-html-sop]
|
||||
- [Dicom-PDF SOP][dicom-pdf-sop]
|
||||
- [Dicom-Microscopy SOP][dicom-micro-sop]
|
||||
- [Dicom-Segmentation SOP][dicom-seg-sop]
|
||||
|
||||
## `@ohif/viewer` usage
|
||||
|
||||
We use the `sopClassHandlerModule`s in three different places:
|
||||
@@ -88,3 +95,11 @@ Each time, it is used to map study and series data to `displaySets`. It does
|
||||
this by working alongside the `StudyMetadataManager` in `@ohif/core`. That
|
||||
manager has the method `createDisplaySets` that takes an array of
|
||||
`sopClassHandlerModules`.
|
||||
|
||||
<!-- prettier-ignore-start -->
|
||||
[sop-class-link]: http://dicom.nema.org/dicom/2013/output/chtml/part04/sect_B.5.html
|
||||
[dicom-html-sop]: https://github.com/OHIF/Viewers/blob/master/extensions/dicom-html/src/OHIFDicomHtmlSopClassHandler.js#L4-L12
|
||||
[dicom-pdf-sop]: https://github.com/OHIF/Viewers/blob/master/extensions/dicom-pdf/src/OHIFDicomPDFSopClassHandler.js#L4-L6
|
||||
[dicom-micro-sop]: https://github.com/OHIF/Viewers/blob/master/extensions/dicom-microscopy/src/DicomMicroscopySopClassHandler.js#L5-L7
|
||||
[dicom-seg-sop]: https://github.com/OHIF/Viewers/blob/master/extensions/dicom-segmentation/src/OHIFDicomSegSopClassHandler.js#L5-L7
|
||||
<!-- prettier-ignore-end -->
|
||||
@@ -75,7 +75,7 @@ items to our ["Active Development" GitHub Project Board][gh-board]. Items on
|
||||
this project board are either in active development by Core Team members, or
|
||||
queued up for development as in-progress items are completed.
|
||||
|
||||
> :pencil: Want to contribute but not sure where to start? Check out [Up for
|
||||
> 🖋 Want to contribute but not sure where to start? Check out [Up for
|
||||
> grabs][label-grabs] issues and our [Contributing
|
||||
> documentation][contributing-docs]
|
||||
|
||||
@@ -156,5 +156,5 @@ addressed and a Stable version is released.
|
||||
[ohif-prod]: https://viewer.ohif.org
|
||||
[gh-board]: https://github.com/OHIF/Viewers/projects/4
|
||||
[label-grabs]: https://github.com/OHIF/Viewers/issues?q=is%3Aissue+is%3Aopen+label%3A%22Up+For+Grabs+%3Araising_hand_woman%3A%22
|
||||
[contributing-docs]: https://docs.ohif.org/contributing/
|
||||
[contributing-docs]: ./development/contributing.md
|
||||
<!-- prettier-ignore-end -->
|
||||
@@ -62,7 +62,7 @@ able to fail or be removed. Related patterns that may reduce coupling include:
|
||||
-->
|
||||
|
||||
<!-- prettier-ignore-start -->
|
||||
[commands]: #/
|
||||
[commands]: ../extensions/modules/commands.md
|
||||
[core-services]: https://github.com/OHIF/Viewers/tree/master/platform/core/src/services
|
||||
[services-manager]: https://github.com/OHIF/Viewers/blob/master/platform/core/src/services/ServicesManager.js
|
||||
[cross-cutting-concerns]: https://en.wikipedia.org/wiki/Cross-cutting_concern
|
||||
|
||||
@@ -2,8 +2,8 @@
|
||||
|
||||
- [Overview](#overview)
|
||||
- [Example](#example)
|
||||
- [Tips & Tricks](#/)
|
||||
- [Maintained Services](#/)
|
||||
- [Tips & Tricks](#tips--tricks)
|
||||
- [Maintained Services](#maintained-services)
|
||||
|
||||
## Overview
|
||||
|
||||
|
||||
@@ -135,7 +135,7 @@ console.log(T('$t(Common:Play) my translated text'));
|
||||
|
||||
# Main Concepts While Translating
|
||||
|
||||
## - Namespaces
|
||||
## Namespaces
|
||||
|
||||
Namespaces are being used to organize translations in smaller portions, combined
|
||||
semantically or by use. Each `.json` file inside `@ohif/i18n` npm package
|
||||
@@ -157,7 +157,7 @@ NameSpace, like this following example getting data from `Common` NameSpace:
|
||||
$t(Common:Reset)
|
||||
```
|
||||
|
||||
## - Extending Languages in @ohif/i18n
|
||||
## Extending Languages in @ohif/i18n
|
||||
|
||||
Sometimes, even using the same language, some nouns or jargons can change
|
||||
according to the country, states or even from Hospital to Hospital.
|
||||
@@ -212,7 +212,7 @@ object like this:
|
||||
Please check the `index.js` files inside locales folder for an example of this
|
||||
exporting structure.
|
||||
|
||||
### - Extending languages dynamically
|
||||
### Extending languages dynamically
|
||||
|
||||
You have access to the i18next instance, so you can use the
|
||||
[addResourceBundle](https://www.i18next.com/how-to/add-or-load-translations#add-after-init)
|
||||
@@ -314,4 +314,4 @@ REACT_APP_I18N_DEBUG=true yarn run dev
|
||||
### Contributing with new languages
|
||||
|
||||
Contributions of any kind are welcome! Please check the
|
||||
[instructions](https://docs.ohif.org/contributing.html).
|
||||
[instructions](../development/contributing.md).
|
||||
@@ -3,6 +3,14 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
## [2.5.1](https://github.com/OHIF/Viewers/compare/@ohif/extension-cornerstone@2.5.0...@ohif/extension-cornerstone@2.5.1) (2020-04-02)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-cornerstone
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [2.5.0](https://github.com/OHIF/Viewers/compare/@ohif/extension-cornerstone@2.4.3...@ohif/extension-cornerstone@2.5.0) (2020-03-13)
|
||||
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@ohif/extension-cornerstone",
|
||||
"version": "2.5.0",
|
||||
"version": "2.5.1",
|
||||
"description": "OHIF extension for Cornerstone",
|
||||
"author": "OHIF",
|
||||
"license": "MIT",
|
||||
|
||||
@@ -1,37 +0,0 @@
|
||||
/**
|
||||
* We use this component to leverage "Code Splitting"
|
||||
*
|
||||
* Link: https://serverless-stack.com/chapters/code-splitting-in-create-react-app.html
|
||||
*/
|
||||
|
||||
import React, { Component } from 'react';
|
||||
|
||||
export default function asyncComponent(importComponent) {
|
||||
class AsyncComponent extends Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
|
||||
this.state = {
|
||||
component: null,
|
||||
};
|
||||
}
|
||||
|
||||
async componentDidMount() {
|
||||
// Add dynamically loaded component to state
|
||||
const { default: component } = await importComponent();
|
||||
|
||||
this.setState({
|
||||
component: component,
|
||||
});
|
||||
}
|
||||
|
||||
render() {
|
||||
const C = this.state.component;
|
||||
|
||||
// Render the loaded component, or null
|
||||
return C ? <C {...this.props} /> : null;
|
||||
}
|
||||
}
|
||||
|
||||
return AsyncComponent;
|
||||
}
|
||||
@@ -1,14 +1,20 @@
|
||||
import React from 'react';
|
||||
import init from './init.js';
|
||||
import asyncComponent from './asyncComponent.js';
|
||||
import commandsModule from './commandsModule.js';
|
||||
import toolbarModule from './toolbarModule.js';
|
||||
import CornerstoneViewportDownloadForm from './CornerstoneViewportDownloadForm';
|
||||
|
||||
const OHIFCornerstoneViewport = asyncComponent(() =>
|
||||
import(
|
||||
/* webpackChunkName: "OHIFCornerstoneViewport" */ './OHIFCornerstoneViewport.js'
|
||||
)
|
||||
);
|
||||
const Component = React.lazy(() => {
|
||||
return import('./OHIFCornerstoneViewport');
|
||||
});
|
||||
|
||||
const OHIFCornerstoneViewport = props => {
|
||||
return (
|
||||
<React.Suspense fallback={<div>Loading...</div>}>
|
||||
<Component {...props} />
|
||||
</React.Suspense>
|
||||
);
|
||||
};
|
||||
|
||||
/**
|
||||
*
|
||||
|
||||
@@ -3,6 +3,14 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
## [1.1.2](https://github.com/OHIF/Viewers/compare/@ohif/extension-dicom-html@1.1.1...@ohif/extension-dicom-html@1.1.2) (2020-04-02)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-dicom-html
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## [1.1.1](https://github.com/OHIF/Viewers/compare/@ohif/extension-dicom-html@1.1.0...@ohif/extension-dicom-html@1.1.1) (2020-03-09)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-dicom-html
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@ohif/extension-dicom-html",
|
||||
"version": "1.1.1",
|
||||
"version": "1.1.2",
|
||||
"description": "OHIF extension for rendering structured reports to HTML",
|
||||
"author": "OHIF",
|
||||
"license": "MIT",
|
||||
|
||||
@@ -1,37 +0,0 @@
|
||||
/**
|
||||
* We use this component to leverage "Code Splitting"
|
||||
*
|
||||
* Link: https://serverless-stack.com/chapters/code-splitting-in-create-react-app.html
|
||||
*/
|
||||
|
||||
import React, { Component } from 'react';
|
||||
|
||||
export default function asyncComponent(importComponent) {
|
||||
class AsyncComponent extends Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
|
||||
this.state = {
|
||||
component: null,
|
||||
};
|
||||
}
|
||||
|
||||
async componentDidMount() {
|
||||
// Add dynamically loaded component to state
|
||||
const { default: component } = await importComponent();
|
||||
|
||||
this.setState({
|
||||
component: component,
|
||||
});
|
||||
}
|
||||
|
||||
render() {
|
||||
const C = this.state.component;
|
||||
|
||||
// Render the loaded component, or null
|
||||
return C ? <C {...this.props} /> : null;
|
||||
}
|
||||
}
|
||||
|
||||
return AsyncComponent;
|
||||
}
|
||||
@@ -1,11 +1,17 @@
|
||||
import asyncComponent from './asyncComponent.js';
|
||||
import React from 'react';
|
||||
import OHIFDicomHtmlSopClassHandler from './OHIFDicomHtmlSopClassHandler.js';
|
||||
|
||||
const OHIFDicomHtmlViewport = asyncComponent(() =>
|
||||
import(
|
||||
/* webpackChunkName: "OHIFDicomHtmlViewport" */ './OHIFDicomHtmlViewport.js'
|
||||
)
|
||||
);
|
||||
const Component = React.lazy(() => {
|
||||
return import('./OHIFDicomHtmlViewport');
|
||||
});
|
||||
|
||||
const OHIFDicomHtmlViewport = props => {
|
||||
return (
|
||||
<React.Suspense fallback={<div>Loading...</div>}>
|
||||
<Component {...props} />
|
||||
</React.Suspense>
|
||||
);
|
||||
};
|
||||
|
||||
export default {
|
||||
/**
|
||||
|
||||
@@ -3,6 +3,14 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
## [0.50.9](https://github.com/OHIF/Viewers/compare/@ohif/extension-dicom-microscopy@0.50.8...@ohif/extension-dicom-microscopy@0.50.9) (2020-04-02)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-dicom-microscopy
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## [0.50.8](https://github.com/OHIF/Viewers/compare/@ohif/extension-dicom-microscopy@0.50.7...@ohif/extension-dicom-microscopy@0.50.8) (2020-03-31)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-dicom-microscopy
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@ohif/extension-dicom-microscopy",
|
||||
"version": "0.50.8",
|
||||
"version": "0.50.9",
|
||||
"description": "OHIF extension for Dicom Microscopy",
|
||||
"author": "OHIF",
|
||||
"license": "MIT",
|
||||
|
||||
@@ -1,37 +0,0 @@
|
||||
/**
|
||||
* We use this component to leverage "Code Splitting"
|
||||
*
|
||||
* Link: https://serverless-stack.com/chapters/code-splitting-in-create-react-app.html
|
||||
*/
|
||||
|
||||
import React, { Component } from 'react';
|
||||
|
||||
export default function asyncComponent(importComponent) {
|
||||
class AsyncComponent extends Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
|
||||
this.state = {
|
||||
component: null,
|
||||
};
|
||||
}
|
||||
|
||||
async componentDidMount() {
|
||||
// Add dynamically loaded component to state
|
||||
const { default: component } = await importComponent();
|
||||
|
||||
this.setState({
|
||||
component: component,
|
||||
});
|
||||
}
|
||||
|
||||
render() {
|
||||
const C = this.state.component;
|
||||
|
||||
// Render the loaded component, or null
|
||||
return C ? <C {...this.props} /> : null;
|
||||
}
|
||||
}
|
||||
|
||||
return AsyncComponent;
|
||||
}
|
||||
@@ -1,11 +1,17 @@
|
||||
import asyncComponent from './asyncComponent.js';
|
||||
import React from 'react';
|
||||
import DicomMicroscopySopClassHandler from './DicomMicroscopySopClassHandler.js';
|
||||
|
||||
const DicomMicroscopyViewport = asyncComponent(() =>
|
||||
import(
|
||||
/* webpackChunkName: "DicomMicroscopyViewport" */ './DicomMicroscopyViewport.js'
|
||||
)
|
||||
);
|
||||
const Component = React.lazy(() => {
|
||||
return import('./DicomMicroscopyViewport');
|
||||
});
|
||||
|
||||
const DicomMicroscopyViewport = props => {
|
||||
return (
|
||||
<React.Suspense fallback={<div>Loading...</div>}>
|
||||
<Component {...props} />
|
||||
</React.Suspense>
|
||||
);
|
||||
};
|
||||
|
||||
export default {
|
||||
/**
|
||||
|
||||
@@ -3,6 +3,14 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
## [1.0.3](https://github.com/OHIF/Viewers/compare/@ohif/extension-dicom-pdf@1.0.2...@ohif/extension-dicom-pdf@1.0.3) (2020-04-02)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-dicom-pdf
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## [1.0.2](https://github.com/OHIF/Viewers/compare/@ohif/extension-dicom-pdf@1.0.1...@ohif/extension-dicom-pdf@1.0.2) (2020-03-09)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-dicom-pdf
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@ohif/extension-dicom-pdf",
|
||||
"version": "1.0.2",
|
||||
"version": "1.0.3",
|
||||
"description": "OHIF extension for Dicom PDF",
|
||||
"author": "OHIF",
|
||||
"license": "MIT",
|
||||
|
||||
@@ -1,37 +0,0 @@
|
||||
/**
|
||||
* We use this component to leverage "Code Splitting"
|
||||
*
|
||||
* Link: https://serverless-stack.com/chapters/code-splitting-in-create-react-app.html
|
||||
*/
|
||||
|
||||
import React, { Component } from 'react';
|
||||
|
||||
export default function asyncComponent(importComponent) {
|
||||
class AsyncComponent extends Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
|
||||
this.state = {
|
||||
component: null,
|
||||
};
|
||||
}
|
||||
|
||||
async componentDidMount() {
|
||||
// Add dynamically loaded component to state
|
||||
const { default: component } = await importComponent();
|
||||
|
||||
this.setState({
|
||||
component: component,
|
||||
});
|
||||
}
|
||||
|
||||
render() {
|
||||
const C = this.state.component;
|
||||
|
||||
// Render the loaded component, or null
|
||||
return C ? <C {...this.props} /> : null;
|
||||
}
|
||||
}
|
||||
|
||||
return AsyncComponent;
|
||||
}
|
||||
@@ -1,11 +1,17 @@
|
||||
import asyncComponent from './asyncComponent.js';
|
||||
import React from 'react';
|
||||
import OHIFDicomPDFSopClassHandler from './OHIFDicomPDFSopClassHandler.js';
|
||||
|
||||
const ConnectedOHIFDicomPDFViewer = asyncComponent(() =>
|
||||
import(
|
||||
/* webpackChunkName: "ConnectedOHIFDicomPDFViewer" */ './ConnectedOHIFDicomPDFViewer'
|
||||
)
|
||||
);
|
||||
const Component = React.lazy(() => {
|
||||
return import('./ConnectedOHIFDicomPDFViewer');
|
||||
});
|
||||
|
||||
const ConnectedOHIFDicomPDFViewer = props => {
|
||||
return (
|
||||
<React.Suspense fallback={<div>Loading...</div>}>
|
||||
<Component {...props} />
|
||||
</React.Suspense>
|
||||
);
|
||||
};
|
||||
|
||||
export default {
|
||||
/**
|
||||
|
||||
@@ -3,6 +3,22 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
## [1.3.8](https://github.com/OHIF/Viewers/compare/@ohif/extension-vtk@1.3.7...@ohif/extension-vtk@1.3.8) (2020-04-02)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-vtk
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## [1.3.7](https://github.com/OHIF/Viewers/compare/@ohif/extension-vtk@1.3.6...@ohif/extension-vtk@1.3.7) (2020-04-02)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-vtk
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## [1.3.6](https://github.com/OHIF/Viewers/compare/@ohif/extension-vtk@1.3.5...@ohif/extension-vtk@1.3.6) (2020-04-01)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-vtk
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@ohif/extension-vtk",
|
||||
"version": "1.3.6",
|
||||
"version": "1.3.8",
|
||||
"description": "OHIF extension for VTK.js",
|
||||
"author": "OHIF",
|
||||
"license": "MIT",
|
||||
@@ -53,7 +53,7 @@
|
||||
"react-vtkjs-viewport": "^0.8.3"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@ohif/core": "^2.6.5",
|
||||
"@ohif/core": "^2.6.7",
|
||||
"@ohif/ui": "^1.4.1",
|
||||
"cornerstone-tools": "4.12.5",
|
||||
"cornerstone-wado-image-loader": "^3.0.0",
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import React, { Component } from 'react';
|
||||
import { getImageData, loadImageData } from 'react-vtkjs-viewport';
|
||||
import { getReactVtkjsViewport } from './utils/getReactVtkjsViewport';
|
||||
import ConnectedVTKViewport from './ConnectedVTKViewport';
|
||||
import LoadingIndicator from './LoadingIndicator.js';
|
||||
import OHIF from '@ohif/core';
|
||||
@@ -69,7 +69,7 @@ class OHIFVTKViewport extends Component {
|
||||
};
|
||||
|
||||
static defaultProps = {
|
||||
onScroll: () => {},
|
||||
onScroll: () => { },
|
||||
};
|
||||
|
||||
static id = 'OHIFVTKViewport';
|
||||
@@ -133,7 +133,8 @@ class OHIFVTKViewport extends Component {
|
||||
displaySetInstanceUID,
|
||||
SOPClassUID,
|
||||
SOPInstanceUID,
|
||||
frameIndex
|
||||
frameIndex,
|
||||
reactVtkjsViewport
|
||||
) => {
|
||||
const stack = OHIFVTKViewport.getCornerstoneStack(
|
||||
studies,
|
||||
@@ -144,7 +145,10 @@ class OHIFVTKViewport extends Component {
|
||||
frameIndex
|
||||
);
|
||||
|
||||
const imageDataObject = getImageData(stack.imageIds, displaySetInstanceUID);
|
||||
const imageDataObject = reactVtkjsViewport.getImageData(
|
||||
stack.imageIds,
|
||||
displaySetInstanceUID
|
||||
);
|
||||
let labelmapDataObject;
|
||||
let labelmapColorLUT;
|
||||
|
||||
@@ -257,7 +261,9 @@ class OHIFVTKViewport extends Component {
|
||||
return volumeActor;
|
||||
}
|
||||
|
||||
setStateFromProps() {
|
||||
async setStateFromProps() {
|
||||
const reactVtkjsViewport = await getReactVtkjsViewport();
|
||||
|
||||
const { studies, displaySet } = this.props.viewportData;
|
||||
const {
|
||||
StudyInstanceUID,
|
||||
@@ -295,8 +301,10 @@ class OHIFVTKViewport extends Component {
|
||||
studies,
|
||||
StudyInstanceUID,
|
||||
displaySetInstanceUID,
|
||||
sopClassUIDs[0],
|
||||
SOPInstanceUID,
|
||||
frameIndex
|
||||
frameIndex,
|
||||
reactVtkjsViewport
|
||||
);
|
||||
|
||||
this.imageDataObject = imageDataObject;
|
||||
@@ -317,7 +325,7 @@ class OHIFVTKViewport extends Component {
|
||||
dataDetails,
|
||||
},
|
||||
() => {
|
||||
this.loadProgressively(imageDataObject);
|
||||
this.loadProgressively(imageDataObject, reactVtkjsViewport);
|
||||
|
||||
// TODO: There must be a better way to do this.
|
||||
// We do this so that if all the data is available the react-vtkjs-viewport
|
||||
@@ -335,26 +343,26 @@ class OHIFVTKViewport extends Component {
|
||||
);
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
this.setStateFromProps();
|
||||
async componentDidMount() {
|
||||
await this.setStateFromProps();
|
||||
}
|
||||
|
||||
componentDidUpdate(prevProps) {
|
||||
async componentDidUpdate(prevProps) {
|
||||
const { displaySet } = this.props.viewportData;
|
||||
const prevDisplaySet = prevProps.viewportData.displaySet;
|
||||
|
||||
if (
|
||||
displaySet.displaySetInstanceUID !==
|
||||
prevDisplaySet.displaySetInstanceUID ||
|
||||
prevDisplaySet.displaySetInstanceUID ||
|
||||
displaySet.SOPInstanceUID !== prevDisplaySet.SOPInstanceUID ||
|
||||
displaySet.frameIndex !== prevDisplaySet.frameIndex
|
||||
) {
|
||||
this.setStateFromProps();
|
||||
await this.setStateFromProps();
|
||||
}
|
||||
}
|
||||
|
||||
loadProgressively(imageDataObject) {
|
||||
loadImageData(imageDataObject);
|
||||
loadProgressively(imageDataObject, reactVtkjsViewport) {
|
||||
reactVtkjsViewport.loadImageData(imageDataObject);
|
||||
|
||||
const { isLoading, insertPixelDataPromises } = imageDataObject;
|
||||
|
||||
|
||||
@@ -1,9 +1,16 @@
|
||||
import React, { useEffect, useCallback } from 'react';
|
||||
import { View2D } from 'react-vtkjs-viewport';
|
||||
// import { View2D } from 'react-vtkjs-viewport';
|
||||
import PropTypes from 'prop-types';
|
||||
import asyncComponent from './asyncComponent.js';
|
||||
import { getReactVtkjsViewport } from './utils/getReactVtkjsViewport';
|
||||
|
||||
import './VTKViewport.css';
|
||||
|
||||
const View2D = asyncComponent(async () => {
|
||||
const reactVtkjsViewport = await getReactVtkjsViewport();
|
||||
return { default: reactVtkjsViewport.View2D };
|
||||
});
|
||||
|
||||
const VTKViewport = props => {
|
||||
const style = { width: '100%', height: '100%', position: 'relative' };
|
||||
|
||||
@@ -52,7 +59,7 @@ VTKViewport.propTypes = {
|
||||
};
|
||||
|
||||
VTKViewport.defaultProps = {
|
||||
onScroll: () => {},
|
||||
onScroll: () => { },
|
||||
};
|
||||
|
||||
export default VTKViewport;
|
||||
@@ -1,10 +1,5 @@
|
||||
import throttle from 'lodash.throttle';
|
||||
import {
|
||||
vtkInteractorStyleMPRCrosshairs,
|
||||
vtkInteractorStyleMPRWindowLevel,
|
||||
vtkInteractorStyleMPRRotate,
|
||||
vtkSVGCrosshairsWidget,
|
||||
} from 'react-vtkjs-viewport';
|
||||
import { getReactVtkjsViewport } from './utils/getReactVtkjsViewport';
|
||||
|
||||
import setMPRLayout from './utils/setMPRLayout.js';
|
||||
import setViewportToVTK from './utils/setViewportToVTK.js';
|
||||
@@ -124,16 +119,18 @@ const commandsModule = ({ commandsManager }) => {
|
||||
|
||||
_setView(api, [0, 1, 0], [0, 0, 1]);
|
||||
},
|
||||
enableRotateTool: () => {
|
||||
enableRotateTool: async () => {
|
||||
const reactVtkjsViewport = await getReactVtkjsViewport();
|
||||
apis.forEach(api => {
|
||||
const istyle = vtkInteractorStyleMPRRotate.newInstance();
|
||||
const istyle = reactVtkjsViewport.vtkInteractorStyleMPRRotate.newInstance();
|
||||
|
||||
api.setInteractorStyle({ istyle });
|
||||
});
|
||||
},
|
||||
enableCrosshairsTool: () => {
|
||||
enableCrosshairsTool: async () => {
|
||||
const reactVtkjsViewport = await getReactVtkjsViewport();
|
||||
apis.forEach((api, apiIndex) => {
|
||||
const istyle = vtkInteractorStyleMPRCrosshairs.newInstance();
|
||||
const istyle = reactVtkjsViewport.vtkInteractorStyleMPRCrosshairs.newInstance();
|
||||
|
||||
api.setInteractorStyle({
|
||||
istyle,
|
||||
@@ -141,7 +138,7 @@ const commandsModule = ({ commandsManager }) => {
|
||||
});
|
||||
});
|
||||
},
|
||||
enableLevelTool: () => {
|
||||
enableLevelTool: async () => {
|
||||
function updateVOI(apis, windowWidth, windowCenter) {
|
||||
apis.forEach(api => {
|
||||
api.updateVOI(windowWidth, windowCenter);
|
||||
@@ -162,8 +159,9 @@ const commandsModule = ({ commandsManager }) => {
|
||||
},
|
||||
};
|
||||
|
||||
const reactVtkjsViewport = await getReactVtkjsViewport();
|
||||
apis.forEach(api => {
|
||||
const istyle = vtkInteractorStyleMPRWindowLevel.newInstance();
|
||||
const istyle = reactVtkjsViewport.vtkInteractorStyleMPRWindowLevel.newInstance();
|
||||
|
||||
api.setInteractorStyle({ istyle, callbacks });
|
||||
});
|
||||
@@ -260,14 +258,15 @@ const commandsModule = ({ commandsManager }) => {
|
||||
}
|
||||
|
||||
// Add widgets and set default interactorStyle of each viewport.
|
||||
const reactVtkjsViewport = await getReactVtkjsViewport();
|
||||
apis.forEach((api, apiIndex) => {
|
||||
api.addSVGWidget(
|
||||
vtkSVGCrosshairsWidget.newInstance(),
|
||||
reactVtkjsViewport.vtkSVGCrosshairsWidget.newInstance(),
|
||||
'crosshairsWidget'
|
||||
);
|
||||
|
||||
const uid = api.uid;
|
||||
const istyle = vtkInteractorStyleMPRCrosshairs.newInstance();
|
||||
const istyle = reactVtkjsViewport.vtkInteractorStyleMPRCrosshairs.newInstance();
|
||||
|
||||
api.setInteractorStyle({
|
||||
istyle,
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
export function getReactVtkjsViewport() {
|
||||
return import(
|
||||
/* webpackChunkName: "ReactVtkjsViewport" */ 'react-vtkjs-viewport'
|
||||
);
|
||||
}
|
||||
@@ -3,6 +3,25 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
## [2.6.7](https://github.com/OHIF/Viewers/compare/@ohif/core@2.6.6...@ohif/core@2.6.7) (2020-04-02)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* 🐛 Fix multiframe images ([#1595](https://github.com/OHIF/Viewers/issues/1595)) ([9e0bd52](https://github.com/OHIF/Viewers/commit/9e0bd52c6a86648eb6673344a8555ad787043e5c))
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## [2.6.6](https://github.com/OHIF/Viewers/compare/@ohif/core@2.6.5...@ohif/core@2.6.6) (2020-04-02)
|
||||
|
||||
**Note:** Version bump only for package @ohif/core
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## [2.6.5](https://github.com/OHIF/Viewers/compare/@ohif/core@2.6.4...@ohif/core@2.6.5) (2020-04-01)
|
||||
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@ohif/core",
|
||||
"version": "2.6.5",
|
||||
"version": "2.6.7",
|
||||
"description": "Generic business logic for web-based medical imaging applications",
|
||||
"author": "OHIF Core Team",
|
||||
"license": "MIT",
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
import cornerstone from 'cornerstone-core';
|
||||
import cornerstoneWADOImageLoader from 'cornerstone-wado-image-loader';
|
||||
import {
|
||||
clearStudyLoadingProgress,
|
||||
setStudyLoadingProgress,
|
||||
} from '../redux/actions';
|
||||
import StackManager from '../utils/StackManager';
|
||||
import { getCornerstoneWADOImageLoader } from '../utils/cornerstoneWADOImageLoader';
|
||||
|
||||
class BaseLoadingListener {
|
||||
constructor(stack, options = {}) {
|
||||
@@ -103,7 +103,8 @@ class DICOMFileLoadingListener extends BaseLoadingListener {
|
||||
this._checkCachedData();
|
||||
}
|
||||
|
||||
_checkCachedData() {
|
||||
async _checkCachedData() {
|
||||
const cornerstoneWADOImageLoader = await getCornerstoneWADOImageLoader();
|
||||
const dataSet = cornerstoneWADOImageLoader.wadouri.dataSetCacheManager.get(
|
||||
this._dataSetUrl
|
||||
);
|
||||
|
||||
@@ -78,7 +78,7 @@ export class StudyMetadata extends Metadata {
|
||||
Object.defineProperty(this, 'studyInstanceUID', {
|
||||
configurable: false,
|
||||
enumerable: false,
|
||||
get: function () {
|
||||
get: function() {
|
||||
return this.getStudyInstanceUID();
|
||||
},
|
||||
});
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import DICOMWeb from '../../../DICOMWeb';
|
||||
import metadataProvider from '../../../classes/MetadataProvider';
|
||||
import getWADORSImageId from '../../../utils/getWADORSImageId';
|
||||
import cornerstoneWADOImageLoader from 'cornerstone-wado-image-loader';
|
||||
import getReferencedSeriesSequence from './getReferencedSeriesSequence';
|
||||
import { getCornerstoneWADOImageLoader } from '../../../utils/cornerstoneWADOImageLoader';
|
||||
|
||||
/**
|
||||
* Create a plain JS object that describes a study (a study descriptor object)
|
||||
@@ -160,6 +160,7 @@ async function makeSOPInstance(server, study, instance) {
|
||||
|
||||
const wadoRSMetadata = Object.assign(instance);
|
||||
|
||||
const cornerstoneWADOImageLoader = await getCornerstoneWADOImageLoader();
|
||||
if (sopInstance.NumberOfFrames) {
|
||||
for (let i = 0; i < sopInstance.NumberOfFrames; i++) {
|
||||
const wadorsImageId = getWADORSImageId(sopInstance, i);
|
||||
|
||||
@@ -35,7 +35,8 @@ function createAndAddStack(stackMap, study, displaySet, stackUpdatedCallbacks) {
|
||||
imageIndex: imageIndex + 1,
|
||||
};
|
||||
|
||||
const NumberOfFrames = image.NumberOfFrames;
|
||||
const naturalizedInstance = instance.getData().metadata;
|
||||
const NumberOfFrames = naturalizedInstance.NumberOfFrames;
|
||||
|
||||
if (NumberOfFrames > 1) {
|
||||
for (let i = 0; i < NumberOfFrames; i++) {
|
||||
@@ -60,8 +61,6 @@ function createAndAddStack(stackMap, study, displaySet, stackUpdatedCallbacks) {
|
||||
imageId = getImageId(image);
|
||||
imageIds.push(imageId);
|
||||
|
||||
const naturalizedInstance = instance.getData().metadata;
|
||||
|
||||
const {
|
||||
StudyInstanceUID,
|
||||
SeriesInstanceUID,
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
export function getCornerstoneWADOImageLoader() {
|
||||
return import(
|
||||
/* webpackChunkName: "CornerstoneWADOImageLoader" */ 'cornerstone-wado-image-loader'
|
||||
);
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
import cornerstone from 'cornerstone-core';
|
||||
import cornerstoneWADOImageLoader from 'cornerstone-wado-image-loader';
|
||||
import { api } from 'dicomweb-client';
|
||||
import DICOMWeb from '../DICOMWeb';
|
||||
import { getCornerstoneWADOImageLoader } from './cornerstoneWADOImageLoader';
|
||||
|
||||
const getImageId = imageObj => {
|
||||
if (!imageObj) {
|
||||
@@ -86,7 +86,7 @@ const getImageLoaderType = imageId => {
|
||||
};
|
||||
|
||||
class DicomLoaderService {
|
||||
getLocalData(dataset, studies) {
|
||||
async getLocalData(dataset, studies) {
|
||||
if (dataset && dataset.localFile) {
|
||||
// Use referenced imageInstance
|
||||
const imageInstance = getImageInstance(dataset);
|
||||
@@ -98,6 +98,7 @@ class DicomLoaderService {
|
||||
}
|
||||
|
||||
if (!someInvalidStrings(imageId)) {
|
||||
const cornerstoneWADOImageLoader = await getCornerstoneWADOImageLoader();
|
||||
return cornerstoneWADOImageLoader.wadouri.loadFileRequest(imageId);
|
||||
}
|
||||
}
|
||||
@@ -176,16 +177,16 @@ class DicomLoaderService {
|
||||
}
|
||||
}
|
||||
|
||||
*getLoaderIterator(dataset, studies) {
|
||||
yield this.getLocalData(dataset, studies);
|
||||
async *getLoaderIterator(dataset, studies) {
|
||||
yield await this.getLocalData(dataset, studies);
|
||||
yield this.getDataByImageType(dataset);
|
||||
yield this.getDataByDatasetType(dataset);
|
||||
}
|
||||
|
||||
findDicomDataPromise(dataset, studies) {
|
||||
async findDicomDataPromise(dataset, studies) {
|
||||
const loaderIterator = this.getLoaderIterator(dataset, studies);
|
||||
// it returns first valid retriever method.
|
||||
for (const loader of loaderIterator) {
|
||||
for await (const loader of loaderIterator) {
|
||||
if (loader) {
|
||||
return loader;
|
||||
}
|
||||
|
||||
@@ -3,6 +3,30 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
## [3.8.16](https://github.com/OHIF/Viewers/compare/@ohif/viewer@3.8.15...@ohif/viewer@3.8.16) (2020-04-02)
|
||||
|
||||
**Note:** Version bump only for package @ohif/viewer
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## [3.8.15](https://github.com/OHIF/Viewers/compare/@ohif/viewer@3.8.14...@ohif/viewer@3.8.15) (2020-04-02)
|
||||
|
||||
**Note:** Version bump only for package @ohif/viewer
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## [3.8.14](https://github.com/OHIF/Viewers/compare/@ohif/viewer@3.8.13...@ohif/viewer@3.8.14) (2020-04-02)
|
||||
|
||||
**Note:** Version bump only for package @ohif/viewer
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## [3.8.13](https://github.com/OHIF/Viewers/compare/@ohif/viewer@3.8.12...@ohif/viewer@3.8.13) (2020-04-01)
|
||||
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@ohif/viewer",
|
||||
"version": "3.8.13",
|
||||
"version": "3.8.16",
|
||||
"description": "OHIF Viewer",
|
||||
"author": "OHIF Contributors",
|
||||
"license": "MIT",
|
||||
@@ -48,14 +48,14 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@babel/runtime": "^7.5.5",
|
||||
"@ohif/core": "^2.6.5",
|
||||
"@ohif/extension-cornerstone": "^2.5.0",
|
||||
"@ohif/extension-dicom-html": "^1.1.1",
|
||||
"@ohif/extension-dicom-microscopy": "^0.50.8",
|
||||
"@ohif/extension-dicom-pdf": "^1.0.2",
|
||||
"@ohif/core": "^2.6.7",
|
||||
"@ohif/extension-cornerstone": "^2.5.1",
|
||||
"@ohif/extension-dicom-html": "^1.1.2",
|
||||
"@ohif/extension-dicom-microscopy": "^0.50.9",
|
||||
"@ohif/extension-dicom-pdf": "^1.0.3",
|
||||
"@ohif/extension-dicom-segmentation": "^0.1.1",
|
||||
"@ohif/extension-lesion-tracker": "^0.2.0",
|
||||
"@ohif/extension-vtk": "^1.3.6",
|
||||
"@ohif/extension-vtk": "^1.3.8",
|
||||
"@ohif/i18n": "^0.52.7",
|
||||
"@ohif/ui": "^1.4.1",
|
||||
"@tanem/react-nprogress": "^1.1.25",
|
||||
|
||||
@@ -34,10 +34,7 @@ import i18n from '@ohif/i18n';
|
||||
import './config';
|
||||
|
||||
/** Utils */
|
||||
import {
|
||||
getUserManagerForOpenIdConnectClient,
|
||||
initWebWorkers,
|
||||
} from './utils/index.js';
|
||||
import { getUserManagerForOpenIdConnectClient } from './utils/index.js';
|
||||
|
||||
/** Extensions */
|
||||
import { GenericViewerCommands, MeasurementsPanel } from './appExtensions';
|
||||
@@ -140,7 +137,6 @@ class App extends Component {
|
||||
*/
|
||||
_initHotkeys(appConfigHotkeys);
|
||||
_initServers(servers);
|
||||
initWebWorkers();
|
||||
}
|
||||
|
||||
render() {
|
||||
|
||||
@@ -1,7 +1,4 @@
|
||||
import OHIF from '@ohif/core';
|
||||
import cornerstone from 'cornerstone-core';
|
||||
import cornerstoneWADOImageLoader from 'cornerstone-wado-image-loader';
|
||||
import dicomParser from 'dicom-parser';
|
||||
import version from './version.js';
|
||||
|
||||
let homepage;
|
||||
@@ -15,31 +12,4 @@ window.info = {
|
||||
homepage,
|
||||
};
|
||||
|
||||
// For debugging
|
||||
//if (process.env.node_env === 'development') {
|
||||
window.cornerstone = cornerstone;
|
||||
window.cornerstoneWADOImageLoader = cornerstoneWADOImageLoader;
|
||||
//}
|
||||
|
||||
cornerstoneWADOImageLoader.external.cornerstone = cornerstone;
|
||||
cornerstoneWADOImageLoader.external.dicomParser = dicomParser;
|
||||
|
||||
OHIF.user.getAccessToken = () => {
|
||||
// TODO: Get the Redux store from somewhere else
|
||||
const state = window.store.getState();
|
||||
if (!state.oidc || !state.oidc.user) {
|
||||
return;
|
||||
}
|
||||
|
||||
return state.oidc.user.access_token;
|
||||
};
|
||||
|
||||
cornerstoneWADOImageLoader.configure({
|
||||
beforeSend: function(xhr) {
|
||||
const headers = OHIF.DICOMWeb.getAuthorizationHeader();
|
||||
|
||||
if (headers.Authorization) {
|
||||
xhr.setRequestHeader('Authorization', headers.Authorization);
|
||||
}
|
||||
},
|
||||
});
|
||||
@@ -3,7 +3,7 @@ import FileLoaderService from './localFileLoaders/fileLoaderService';
|
||||
const processFile = async file => {
|
||||
try {
|
||||
const fileLoaderService = new FileLoaderService(file);
|
||||
const imageId = fileLoaderService.addFile(file);
|
||||
const imageId = await fileLoaderService.addFile(file);
|
||||
const image = await fileLoaderService.loadFile(file, imageId);
|
||||
const dataset = await fileLoaderService.getDataset(image, imageId);
|
||||
const studies = await fileLoaderService.getStudies(dataset, imageId);
|
||||
|
||||
@@ -1,13 +1,14 @@
|
||||
import * as dcmjs from 'dcmjs';
|
||||
import cornerstoneWADOImageLoader from 'cornerstone-wado-image-loader';
|
||||
import FileLoader from './fileLoader';
|
||||
import OHIF from '@ohif/core';
|
||||
import { getCornerstoneWADOImageLoader } from '../../utils/cornerstoneWADOImageLoader';
|
||||
|
||||
const metadataProvider = OHIF.cornerstone.metadataProvider;
|
||||
|
||||
const DICOMFileLoader = new (class extends FileLoader {
|
||||
fileType = 'application/dicom';
|
||||
loadFile(file, imageId) {
|
||||
async loadFile(file, imageId) {
|
||||
const cornerstoneWADOImageLoader = await getCornerstoneWADOImageLoader();
|
||||
return cornerstoneWADOImageLoader.wadouri.loadFileRequest(imageId);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import cornerstoneWADOImageLoader from 'cornerstone-wado-image-loader';
|
||||
import FileLoader from './fileLoader';
|
||||
import PDFFileLoader from './pdfFileLoader';
|
||||
import DICOMFileLoader from './dicomFileLoader';
|
||||
import { getCornerstoneWADOImageLoader } from '../../utils/cornerstoneWADOImageLoader';
|
||||
|
||||
class FileLoaderService extends FileLoader {
|
||||
fileType;
|
||||
@@ -53,7 +53,8 @@ class FileLoaderService extends FileLoader {
|
||||
return result;
|
||||
}
|
||||
|
||||
addFile(file) {
|
||||
async addFile(file) {
|
||||
const cornerstoneWADOImageLoader = await getCornerstoneWADOImageLoader();
|
||||
return cornerstoneWADOImageLoader.wadouri.fileManager.add(file);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
import cornerstoneWADOImageLoader from 'cornerstone-wado-image-loader';
|
||||
import FileLoader from './fileLoader';
|
||||
import { getCornerstoneWADOImageLoader } from '../../utils/cornerstoneWADOImageLoader';
|
||||
|
||||
const PDFFileLoader = new (class extends FileLoader {
|
||||
fileType = 'application/pdf';
|
||||
loadFile(file, imageId) {
|
||||
async loadFile(file, imageId) {
|
||||
const cornerstoneWADOImageLoader = await getCornerstoneWADOImageLoader();
|
||||
return cornerstoneWADOImageLoader.wadouri.loadFileRequest(imageId);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import asyncComponent from '../components/AsyncComponent.js';
|
||||
import { withCornerstone } from '../utils/cornerstoneWADOImageLoader';
|
||||
|
||||
import OHIF from '@ohif/core';
|
||||
const { urlUtil: UrlUtil } = OHIF.utils;
|
||||
@@ -9,8 +10,10 @@ const IHEInvokeImageDisplay = asyncComponent(() =>
|
||||
/* webpackChunkName: "IHEInvokeImageDisplay" */ './IHEInvokeImageDisplay.js'
|
||||
)
|
||||
);
|
||||
const ViewerRouting = asyncComponent(() =>
|
||||
import(/* webpackChunkName: "ViewerRouting" */ './ViewerRouting.js')
|
||||
const ViewerRouting = withCornerstone(
|
||||
asyncComponent(() =>
|
||||
import(/* webpackChunkName: "ViewerRouting" */ './ViewerRouting.js')
|
||||
)
|
||||
);
|
||||
|
||||
const StudyListRouting = asyncComponent(() =>
|
||||
@@ -18,12 +21,18 @@ const StudyListRouting = asyncComponent(() =>
|
||||
/* webpackChunkName: "StudyListRouting" */ '../studylist/StudyListRouting.js'
|
||||
)
|
||||
);
|
||||
const StandaloneRouting = asyncComponent(() =>
|
||||
import(/* webpackChunkName: "ConnectedStandaloneRouting" */ '../connectedComponents/ConnectedStandaloneRouting.js')
|
||||
const StandaloneRouting = withCornerstone(
|
||||
asyncComponent(() =>
|
||||
import(
|
||||
/* webpackChunkName: "ConnectedStandaloneRouting" */ '../connectedComponents/ConnectedStandaloneRouting.js'
|
||||
)
|
||||
)
|
||||
);
|
||||
const ViewerLocalFileData = asyncComponent(() =>
|
||||
import(
|
||||
/* webpackChunkName: "ViewerLocalFileData" */ '../connectedComponents/ViewerLocalFileData.js'
|
||||
const ViewerLocalFileData = withCornerstone(
|
||||
asyncComponent(() =>
|
||||
import(
|
||||
/* webpackChunkName: "ViewerLocalFileData" */ '../connectedComponents/ViewerLocalFileData.js'
|
||||
)
|
||||
)
|
||||
);
|
||||
|
||||
|
||||
@@ -0,0 +1,79 @@
|
||||
import OHIF from '@ohif/core';
|
||||
import cornerstone from 'cornerstone-core';
|
||||
import dicomParser from 'dicom-parser';
|
||||
import React from 'react';
|
||||
|
||||
export function getCornerstoneWADOImageLoader() {
|
||||
return import(
|
||||
/* webpackChunkName: "CornerstoneWADOImageLoader" */ 'cornerstone-wado-image-loader'
|
||||
);
|
||||
}
|
||||
|
||||
let initialized = false;
|
||||
export async function initCornerstoneWADOImageLoader() {
|
||||
if (initialized) return;
|
||||
const cornerstoneWADOImageLoader = await getCornerstoneWADOImageLoader();
|
||||
// For debugging
|
||||
//if (process.env.node_env === 'development') {
|
||||
window.cornerstoneWADOImageLoader = cornerstoneWADOImageLoader;
|
||||
//}
|
||||
|
||||
cornerstoneWADOImageLoader.external.cornerstone = cornerstone;
|
||||
cornerstoneWADOImageLoader.external.dicomParser = dicomParser;
|
||||
|
||||
OHIF.user.getAccessToken = () => {
|
||||
// TODO: Get the Redux store from somewhere else
|
||||
const state = window.store.getState();
|
||||
if (!state.oidc || !state.oidc.user) {
|
||||
return;
|
||||
}
|
||||
|
||||
return state.oidc.user.accesstoken;
|
||||
};
|
||||
|
||||
cornerstoneWADOImageLoader.configure({
|
||||
beforeSend: function (xhr) {
|
||||
const headers = OHIF.DICOMWeb.getAuthorizationHeader();
|
||||
|
||||
if (headers.Authorization) {
|
||||
xhr.setRequestHeader('Authorization', headers.Authorization);
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
const config = {
|
||||
maxWebWorkers: Math.max(navigator.hardwareConcurrency - 1, 1),
|
||||
startWebWorkersOnDemand: true,
|
||||
taskConfiguration: {
|
||||
decodeTask: {
|
||||
initializeCodecsOnStartup: false,
|
||||
usePDFJS: false,
|
||||
strict: false,
|
||||
},
|
||||
},
|
||||
};
|
||||
cornerstoneWADOImageLoader.webWorkerManager.initialize(config);
|
||||
|
||||
initialized = true;
|
||||
}
|
||||
|
||||
export function withCornerstone(Component) {
|
||||
// eslint-disable-next-line react/display-name
|
||||
return props => {
|
||||
const [
|
||||
cornerstoneWADOImageLoaderInitialized,
|
||||
setCornerstoneWADOImageLoaderInitialized,
|
||||
] = React.useState(false);
|
||||
|
||||
React.useEffect(() => {
|
||||
initCornerstoneWADOImageLoader().then(() =>
|
||||
setCornerstoneWADOImageLoaderInitialized(true)
|
||||
);
|
||||
}, []);
|
||||
|
||||
if (!cornerstoneWADOImageLoaderInitialized) {
|
||||
return null;
|
||||
}
|
||||
return <Component {...props} />;
|
||||
};
|
||||
}
|
||||
@@ -1,4 +1,3 @@
|
||||
import getUserManagerForOpenIdConnectClient from './getUserManagerForOpenIdConnectClient.js';
|
||||
import initWebWorkers from './initWebWorkers.js';
|
||||
|
||||
export { getUserManagerForOpenIdConnectClient, initWebWorkers };
|
||||
export { getUserManagerForOpenIdConnectClient };
|
||||
@@ -5,7 +5,7 @@ describe('utils', () => {
|
||||
const utilExports = Object.keys(utils).sort();
|
||||
|
||||
expect(utilExports).toEqual(
|
||||
['getUserManagerForOpenIdConnectClient', 'initWebWorkers'].sort()
|
||||
['getUserManagerForOpenIdConnectClient'].sort()
|
||||
);
|
||||
});
|
||||
});
|
||||
@@ -1,22 +0,0 @@
|
||||
import cornerstoneWADOImageLoader from 'cornerstone-wado-image-loader';
|
||||
|
||||
let initialized = false;
|
||||
|
||||
export default function initWebWorkers() {
|
||||
const config = {
|
||||
maxWebWorkers: Math.max(navigator.hardwareConcurrency - 1, 1),
|
||||
startWebWorkersOnDemand: true,
|
||||
taskConfiguration: {
|
||||
decodeTask: {
|
||||
initializeCodecsOnStartup: false,
|
||||
usePDFJS: false,
|
||||
strict: false,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
if (!initialized) {
|
||||
cornerstoneWADOImageLoader.webWorkerManager.initialize(config);
|
||||
initialized = true;
|
||||
}
|
||||
}
|
||||
@@ -1,23 +0,0 @@
|
||||
import initWebWorkers from './initWebWorkers.js';
|
||||
import cornerstoneWADOImageLoader from 'cornerstone-wado-image-loader';
|
||||
|
||||
describe('initWebWorkers', () => {
|
||||
it("initializes cornerstoneWADOImageLoader's web workers", () => {
|
||||
initWebWorkers();
|
||||
|
||||
expect(
|
||||
cornerstoneWADOImageLoader.webWorkerManager.initialize
|
||||
).toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
|
||||
describe('initWebWorkers', () => {
|
||||
it("initializes cornerstoneWADOImageLoader's web workers only once", () => {
|
||||
initWebWorkers();
|
||||
initWebWorkers();
|
||||
|
||||
expect(
|
||||
cornerstoneWADOImageLoader.webWorkerManager.initialize
|
||||
).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
});
|
||||
Reference in new issue
Block a user