docs: Remove UI components for now, we will use Storybook instead later. Clean up links and introduction. (#2520)
This commit is contained in:
parent
2327b4ae12
commit
00d7192423
@ -17,20 +17,6 @@ mkdir -p ./.netlify/www/pwa
|
||||
mv platform/viewer/dist/* .netlify/www/pwa -v
|
||||
echo 'Web application built and copied'
|
||||
|
||||
# Build && Move script output
|
||||
# yarn run build:package
|
||||
|
||||
# Build && Move Docz Output (for the UI Component Library)
|
||||
# Using local yarn install to prevent Gatsby from needing to access
|
||||
# node_modules above the platform/ui folder
|
||||
cd platform/ui
|
||||
yarn install
|
||||
yarn run build
|
||||
cd ../..
|
||||
mkdir -p ./.netlify/www/ui
|
||||
mv platform/ui/.docz/dist/* .netlify/www/ui -v
|
||||
echo 'UI Component docs (docz) built and copied'
|
||||
|
||||
# Build && Move Docusaurus Output (for the docs themselves)
|
||||
cd platform/docs
|
||||
yarn install
|
||||
|
||||
@ -103,7 +103,7 @@ module.exports = (env, argv, { SRC_DIR, DIST_DIR }) => {
|
||||
'process.env.APP_CONFIG': JSON.stringify(process.env.APP_CONFIG || ''),
|
||||
'process.env.PUBLIC_URL': JSON.stringify(process.env.PUBLIC_URL || '/'),
|
||||
'process.env.VERSION_NUMBER': JSON.stringify(
|
||||
process.env.VERSION_NUMBER || PACKAGE.version || ''
|
||||
process.env.VERSION_NUMBER || PACKAGE.productVersion || ''
|
||||
),
|
||||
'process.env.BUILD_NUM': JSON.stringify(BUILD_NUM),
|
||||
/* i18n */
|
||||
|
||||
32
README.md
32
README.md
@ -82,7 +82,7 @@ We offer support through
|
||||
- [Request a Feature 🚀](https://github.com/OHIF/Viewers/issues/new?assignees=&labels=Community%3A+Request+%3Ahand%3A&template=---feature-request.md)
|
||||
- [Ask a Question 🤗](https://github.com/OHIF/Viewers/issues/new?assignees=&labels=Community%3A+Question+%3Aquestion%3A&template=---support-question.md)
|
||||
|
||||
For commercial support, academic collaberations, and answers to common
|
||||
For commercial support, academic collaborations, and answers to common
|
||||
questions; please read our
|
||||
[documented FAQ](https://docs.ohif.org/faq/index.html#does-ohif-offer-commercial-support).
|
||||
|
||||
@ -173,7 +173,7 @@ also supports a number of commands that can be found in their respective
|
||||
| `dev:project <package-name>` | Replace with `core`, `ui`, `i18n`, `cornerstone`, `vtk`, etc. |
|
||||
| `test:unit` | Jest multi-project test runner; overall coverage |
|
||||
| **Deploy** | |
|
||||
| `build`\* | Builds production output for our PWA Viewer | |
|
||||
| `build`\* | Builds production output for our PWA Viewer | |
|
||||
|
||||
\* - For more information on our different builds, check out our [Deploy
|
||||
Docs][deployment-docs]
|
||||
@ -189,14 +189,14 @@ you'll see the following:
|
||||
.
|
||||
├── extensions #
|
||||
│ ├── _example # Skeleton of example extension
|
||||
│ ├── default #
|
||||
│ ├── default #
|
||||
│ ├── cornerstone # 2D images w/ Cornerstone.js
|
||||
│ ├── dicom-sr #
|
||||
│ └── measurement-tracking #
|
||||
│ ├── dicom-sr #
|
||||
│ └── measurement-tracking #
|
||||
│
|
||||
├── modes #
|
||||
│ ├── _example # Skeleton of example mode
|
||||
│ └── longitudinal #
|
||||
│ └── longitudinal #
|
||||
│
|
||||
├── platform #
|
||||
│ ├── core # Business Logic
|
||||
@ -230,14 +230,28 @@ This is a list of Extensions maintained by the OHIF Core team. It's possible to
|
||||
customize and configure these extensions, and you can even create your own. You
|
||||
can [read more about extensions here][ohif-extensions].
|
||||
|
||||
| Name | Description | Links |
|
||||
| -------------------------------------------------------------- | ------------------------------------------------------- | ---------------------- |
|
||||
| [@ohif/extension-cornerstone][extension-cornerstone] | 2D image viewing, annotation, and segementation tools | [NPM][cornerstone-npm] |
|
||||
| Name | Description | Links |
|
||||
| ---------------------------------------------------- | ----------------------------------------------------- | ---------------------- |
|
||||
| [@ohif/extension-cornerstone][extension-cornerstone] | 2D image viewing, annotation, and segementation tools | [NPM][cornerstone-npm] |
|
||||
|
||||
## Acknowledgments
|
||||
|
||||
To acknowledge the OHIF Viewer in an academic publication, please cite
|
||||
|
||||
> _Open Health Imaging Foundation Viewer: An Extensible Open-Source Framework
|
||||
> for Building Web-Based Imaging Applications to Support Cancer Research_
|
||||
>
|
||||
> Erik Ziegler, Trinity Urban, Danny Brown, James Petts, Steve D. Pieper, Rob
|
||||
> Lewis, Chris Hafey, and Gordon J. Harris
|
||||
>
|
||||
> _JCO Clinical Cancer Informatics_, no. 4 (2020), 336-345, DOI:
|
||||
> [10.1200/CCI.19.00131](https://www.doi.org/10.1200/CCI.19.00131)
|
||||
>
|
||||
> Open-Access on Pubmed Central:
|
||||
> https://www.ncbi.nlm.nih.gov/pmc/articles/PMC7259879/
|
||||
|
||||
or, for v1, please cite:
|
||||
|
||||
> _LesionTracker: Extensible Open-Source Zero-Footprint Web Viewer for Cancer
|
||||
> Imaging Research and Clinical Trials_
|
||||
>
|
||||
|
||||
@ -13,7 +13,7 @@
|
||||
"engines": {
|
||||
"node": ">=10",
|
||||
"npm": ">=6",
|
||||
"yarn": ">=1.19.1"
|
||||
"yarn": ">=1.18.0"
|
||||
},
|
||||
"files": [
|
||||
"dist",
|
||||
|
||||
@ -101,11 +101,14 @@ function ViewerLayout({
|
||||
const { show, hide } = useModal();
|
||||
|
||||
const { hotkeyDefinitions, hotkeyDefaults } = hotkeysManager;
|
||||
const versionNumber = process.env.VERSION_NUMBER;
|
||||
const buildNumber = process.env.BUILD_NUM;
|
||||
|
||||
const menuOptions = [
|
||||
{
|
||||
title: t('Header:About'),
|
||||
icon: 'info',
|
||||
onClick: () => show({ content: AboutModal, title: 'About OHIF Viewer' }),
|
||||
onClick: () => show({ content: AboutModal, title: 'About OHIF Viewer', contentProps: { versionNumber, buildNumber } }),
|
||||
},
|
||||
{
|
||||
title: t('Header:Preferences'),
|
||||
|
||||
@ -13,7 +13,7 @@
|
||||
"engines": {
|
||||
"node": ">=10",
|
||||
"npm": ">=6",
|
||||
"yarn": ">=1.19.1"
|
||||
"yarn": ">=1.18.0"
|
||||
},
|
||||
"files": [
|
||||
"dist",
|
||||
|
||||
@ -4,167 +4,41 @@ slug: /
|
||||
sidebar_position: 1
|
||||
---
|
||||
|
||||
<div className="text--center">
|
||||
<a style={{marginRight:'10px'}} href="http://viewer.ohif.org/">Preview The OHIF Viewer</a>
|
||||
<a href="https://www.netlify.com"/>
|
||||
<img style={{width:'70px'}} src="https://www.netlify.com/img/global/badges/netlify-color-bg.svg" />
|
||||
</div>
|
||||
|
||||
> ATTENTION! You are looking at the docs for the `OHIF-v3` Viewer (third time is
|
||||
> always a charm). If you're looking for the our `OHIF-v2` (React stable
|
||||
> version) or OHIF-v1 (deprecated `Meteor` version) select it's version from the
|
||||
> dropdown box in the top left corner of this page.
|
||||
|
||||
The [Open Health Imaging Foundation][ohif-org] (OHIF) Viewer is an open source,
|
||||
web-based, medical imaging viewer. It can be configured to connect to Image
|
||||
Archives that support [DicomWeb][dicom-web], and offers support for mapping to
|
||||
proprietary API formats. OHIF maintained extensions add support for viewing,
|
||||
annotating, and reporting on DICOM images in 2D (slices) and 3D (volumes).
|
||||
web-based, medical imaging platform. It aims to provide a core framework for
|
||||
building complex imaging applications.
|
||||
|
||||
Key features:
|
||||
|
||||
- Designed to load large radiology studies as quickly as possible. Retrieves
|
||||
metadata ahead of time and streams in imaging pixel data as needed.
|
||||
- Leverages [Cornerstone.js](https://cornerstonejs.org/) for decoding,
|
||||
rendering, and annotating medical images.
|
||||
- Works out-of-the-box with Image Archives that support [DICOMWeb][dicom-web].
|
||||
Offers a Data Source API for communicating with archives over proprietary API
|
||||
formats.
|
||||
- Provides a plugin framework for creating task-based workflow modes which can
|
||||
re-use core functionality.
|
||||
- Beautiful user interface (UI) designed with extensibility in mind. UI
|
||||
components available in a reusable component library built with React.js and
|
||||
Tailwind CSS
|
||||
|
||||

|
||||
|
||||
<!-- <center><i>The <strong>OHIF Viewer v3</strong>: A general purpose DICOM Viewer (<a href="http://viewer.ohif.org/">Live Demo</a>)</center> -->
|
||||
|
||||
|
||||
|
||||
## What's new in `OHIF-v3`
|
||||
|
||||
`OHIF-v3` is our second try for a React-based viewer, and is the third version
|
||||
of our medical image web viewers from the start. The summary of changes include:
|
||||
|
||||
- Addition of workflow modes
|
||||
- Often, medical imaging use cases involves lots of specific workflows that
|
||||
re-use functionalities. We have added the capability of workflow modes, that
|
||||
enable people to customize user interface and configure application for
|
||||
specific workflow.
|
||||
- The idea is to re-use the functionalities that extensions provide and create
|
||||
a workflow. Brain segmentation workflow is different from prostate
|
||||
segmentation in UI for sure; however, they share the segmentation tools that
|
||||
can be re-used.
|
||||
- Our vision is that technical people focus of developing extensions which
|
||||
provides core functionalities, and experts to build modes by picking the
|
||||
appropriate functionalities from each extension.
|
||||
|
||||
* Redux store has been removed from the viewer, and a cleaner, more powerful
|
||||
* Tailwind CSS
|
||||
* End-to-end test suite
|
||||
|
||||
Below, you can find the gap analysis between the `OHIF-v2` and `OHIF-v3`:
|
||||
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th align="left" width="50%">OHIF-v2 functionalities</th>
|
||||
<th align="center">OHIF-v3</th>
|
||||
<th align="center">Comment</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td align="left">Rendering of 2D images via Cornerstone</td>
|
||||
<td align="center">✅</td>
|
||||
<td align="center"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="left">Study List</td>
|
||||
<td align="center">✅</td>
|
||||
<td align="center"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="left">Series Browser</td>
|
||||
<td align="center">✅</td>
|
||||
<td align="center"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="left">DICOM JSON</td>
|
||||
<td align="center">✅</td>
|
||||
<td align="center"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="left">2D Tools via CornerstoneTools</td>
|
||||
<td align="center">✅</td>
|
||||
<td align="center"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="left">OpenID Connect standard authentication flow for connecting to identity providers</td>
|
||||
<td align="center">✅</td>
|
||||
<td align="center"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="left">Internationalization</td>
|
||||
<td align="center">✅</td>
|
||||
<td align="center"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="left">Drag/drop DICOM data into the viewer (see https://viewer.ohif.org/local)</td>
|
||||
<td align="center">✅</td>
|
||||
<td align="center"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="left">White-labelling: Easily replace the OHIF Logo with your logo</td>
|
||||
<td align="center">✅</td>
|
||||
<td align="center"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="left">DICOM Whole-slide imaging viewport</td>
|
||||
<td align="center">🔜</td>
|
||||
<td align="center">In Progress</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="left">IHE Invoke Image Display - Standard-compliant launching of the viewer (e.g. from PACS or RIS)</td>
|
||||
<td align="center">🔜</td>
|
||||
<td align="center">Not Started</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="left">DICOM PDF support</td>
|
||||
<td align="center">🔜</td>
|
||||
<td align="center">Not Started</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="left">Displaying non-renderable DICOM as HTML</td>
|
||||
<td align="center">🔜</td>
|
||||
<td align="center">Not Started</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="left">Segmentation support</td>
|
||||
<td align="center">🔜</td>
|
||||
<td align="center">Not Started</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="left">RT STRUCT support</td>
|
||||
<td align="center">🔜</td>
|
||||
<td align="center">Not Started</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="left">DICOM upload to PACS</td>
|
||||
<td align="center">🔜</td>
|
||||
<td align="center">Not Started</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="left">Google Cloud adapter</td>
|
||||
<td align="center">🔜</td>
|
||||
<td align="center">Not Started</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="left">VTK Extension + MIP / MPR layout</td>
|
||||
<td align="center">❌</td>
|
||||
<td align="center">Other plans that involves amazing news soon!</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="left">UMD Build (Embedded Viewer). </td>
|
||||
<td align="center">❌</td>
|
||||
<td align="center">The problem is that this breaks a bunch of extensions that rely on third party scripts (e.g. VTK) which have their own web worker loaders.</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<div className="text--center">
|
||||
<div className="button-group">
|
||||
<a className='button button--primary' href="https://v3-demo.ohif.org/">Try the demo</a>
|
||||
<a className='button button--primary' href="./release-notes">Release Notes</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
## Where to next?
|
||||
|
||||
The Open Health Imaging Foundation intends to provide a simple general purpose
|
||||
DICOM Viewer which can be easily extended for specific uses. If you find
|
||||
yourself unable to extend the viewer for your purposes, please reach out via our
|
||||
[GitHub issues][gh-issues]. We are actively seeking feedback on ways to improve
|
||||
our integration and extension points.
|
||||
The Open Health Imaging Foundation intends to provide an imaging viewer
|
||||
framework which can be easily extended for specific uses. If you find yourself
|
||||
unable to extend the viewer for your purposes, please reach out via our [GitHub
|
||||
issues][gh-issues]. We are actively seeking feedback on ways to improve our
|
||||
integration and extension points.
|
||||
|
||||
Check out these helpful links:
|
||||
|
||||
@ -172,7 +46,47 @@ Check out these helpful links:
|
||||
[Getting Started Guide](./development/getting-started.md).
|
||||
- We're an active, vibrant community.
|
||||
[Learn how you can be more involved.](./development/contributing.md)
|
||||
- Feeling lost? Read our [help page](./help.md).
|
||||
- Feeling lost? Read our [help page](/help).
|
||||
|
||||
## Citing OHIF
|
||||
|
||||
To cite the OHIF Viewer in an academic publication, please cite
|
||||
|
||||
> _Open Health Imaging Foundation Viewer: An Extensible Open-Source Framework
|
||||
> for Building Web-Based Imaging Applications to Support Cancer Research_
|
||||
|
||||
> Erik Ziegler, Trinity Urban, Danny Brown, James Petts, Steve D. Pieper, Rob
|
||||
> Lewis, Chris Hafey, and Gordon J. Harris
|
||||
|
||||
> _JCO Clinical Cancer Informatics_, no. 4 (2020), 336-345, DOI:
|
||||
> [10.1200/CCI.19.00131](https://www.doi.org/10.1200/CCI.19.00131)
|
||||
|
||||
This article is freely available on Pubmed Central:
|
||||
https://www.ncbi.nlm.nih.gov/pmc/articles/PMC7259879/
|
||||
|
||||
or, for Lesion Tracker of OHIF v1, please cite:
|
||||
|
||||
> _LesionTracker: Extensible Open-Source Zero-Footprint Web Viewer for Cancer
|
||||
> Imaging Research and Clinical Trials_
|
||||
>
|
||||
> Trinity Urban, Erik Ziegler, Rob Lewis, Chris Hafey, Cheryl Sadow, Annick D.
|
||||
> Van den Abbeele and Gordon J. Harris
|
||||
>
|
||||
> _Cancer Research_, November 1 2017 (77) (21) e119-e122 DOI:
|
||||
> [10.1158/0008-5472.CAN-17-0334](https://www.doi.org/10.1158/0008-5472.CAN-17-0334)
|
||||
|
||||
This article is freely available on Pubmed Central:
|
||||
https://pubmed.ncbi.nlm.nih.gov/29092955/
|
||||
|
||||
**Note:** If you use or find this repository helpful, please take the time to
|
||||
star this repository on Github. This is an easy way for us to assess adoption
|
||||
and it can help us obtain future funding for the project.
|
||||
|
||||
## License
|
||||
|
||||
MIT © [OHIF](https://github.com/OHIF)
|
||||
|
||||
|
||||
|
||||
<!--
|
||||
Links
|
||||
@ -180,7 +94,7 @@ Check out these helpful links:
|
||||
|
||||
<!-- prettier-ignore-start -->
|
||||
[ohif-org]: https://www.ohif.org
|
||||
[ohif-demo]: http://viewer.ohif.org/
|
||||
[ohif-demo]: http://v3-demo.ohif.org/
|
||||
[dicom-web]: https://en.wikipedia.org/wiki/DICOMweb
|
||||
[gh-issues]: https://github.com/OHIF/Viewers/issues
|
||||
<!-- prettier-ignore-end -->
|
||||
|
||||
@ -17,7 +17,7 @@ your Viewer will display).
|
||||
Our goal is to make deployment as simple and painless as possible; however,
|
||||
there is an inherent amount of complexity in configuring and deploying web
|
||||
applications. If you find yourself a little lost, please don't hesitate to
|
||||
[reach out for help](/help.md)
|
||||
[reach out for help](/help)
|
||||
|
||||
## Deployment Scenarios
|
||||
|
||||
@ -53,7 +53,7 @@ HTML, CSS, JS, Font Files, and Images. We "build" those files from our
|
||||
files publicly accessible by hosting them on a Web Server.
|
||||
|
||||
If you have not deployed a web application before, this may be a good time to
|
||||
[reach out for help](/help.md), as these steps assume prior web development and
|
||||
[reach out for help](/help), as these steps assume prior web development and
|
||||
deployment experience.
|
||||
|
||||
##### Part 1 - Build Production Assets
|
||||
@ -264,7 +264,7 @@ Coming soon
|
||||
<!--
|
||||
> Feeling lost? Securing your data is important, and it can be hard to tell if
|
||||
> you've gotten it right. Don't hesitate to work with professional auditors, or
|
||||
> [enlist help from experts](./../help.md).
|
||||
> [enlist help from experts](../help).
|
||||
|
||||
The OHIF Viewer can be configured to work with authorization servers that
|
||||
support one or more of the OpenID-Connect authorization flows. The Viewer finds
|
||||
|
||||
@ -87,9 +87,6 @@ You should see the following output:
|
||||
```bash
|
||||
# Build static assets to host a PWA
|
||||
yarn run build
|
||||
|
||||
# Build packaged output (script-tag use)
|
||||
yarn run build:package
|
||||
```
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
@ -40,13 +40,8 @@ proposed collaboration has an impact on cancer research.
|
||||
### Does OHIF offer commercial support?
|
||||
|
||||
The Open Health Imaging Foundation does not offer commercial support, however,
|
||||
some community members do offer consulting services. The following contacts may
|
||||
be useful:
|
||||
|
||||
- Rob Lewis ([Radical Imaging](https://radicalimaging.com/))
|
||||
|
||||
**Please file a Pull Request if you wish to add your name or organization to
|
||||
this list.**
|
||||
some community members do offer consulting services. You can search our
|
||||
[Community Forum](https://community.ohif.org/) for more information.
|
||||
|
||||
### Does The OHIF Viewer have [510(k) Clearance][501k-clearance] from the U.S. F.D.A or [CE Marking][ce-marking] from the European Commission?
|
||||
|
||||
|
||||
@ -1,7 +0,0 @@
|
||||
---
|
||||
sidebar_position: 9
|
||||
sidebar_label: Migration to v3
|
||||
---
|
||||
|
||||
> New `OHIF-v3` architecture has made OHIF a general purpose extensible medical
|
||||
> imaging **platform**, as opposed to a configurable viewer.
|
||||
@ -1,82 +0,0 @@
|
||||
---
|
||||
sidebar_position: 2
|
||||
sidebar_label: Colors
|
||||
---
|
||||
|
||||
import { BackgroundColor } from '@ohif/ui';
|
||||
|
||||
# Color System
|
||||
|
||||
`@ohif/ui` offers a color system with a handful of color utility classes.
|
||||
|
||||
As `@ohif/ui` uses Tailwind as a base styling library, you will be able to use
|
||||
all the default colors from Tailwind, besides our custom colors too.
|
||||
|
||||
# How to use
|
||||
|
||||
To apply color in your element, you will use the same way Tailwind does.
|
||||
|
||||
- Background - `bg-primary-main`
|
||||
- Border - `border-primary-main`
|
||||
- Text - `text-primary-main`
|
||||
- Placeholder - `placeholder-primary-main`
|
||||
|
||||
Check [Tailwind's documentation](https://tailwindcss.com/docs) to see more
|
||||
details about color classes.
|
||||
|
||||
# Examples
|
||||
|
||||
## Text
|
||||
|
||||
```jsx live
|
||||
<div className="p-8">
|
||||
<p className="text-common-bright">text-common-bright</p>
|
||||
<p className="text-common-light">text-common-light</p>
|
||||
<p className="text-common-main">text-common-main</p>
|
||||
<p className="text-common-dark">text-common-dark</p>
|
||||
<p className="text-common-active">text-common-active</p>
|
||||
</div>
|
||||
```
|
||||
|
||||
## Background
|
||||
|
||||
<div className="flex">
|
||||
<div className="mr-8">
|
||||
<BackgroundColor color="primary-light" />
|
||||
<BackgroundColor color="primary-main" />
|
||||
<BackgroundColor color="primary-dark" />
|
||||
<BackgroundColor color="primary-active" />
|
||||
</div>
|
||||
<div>
|
||||
<BackgroundColor color="secondary-light" />
|
||||
<BackgroundColor color="secondary-main" />
|
||||
<BackgroundColor color="secondary-dark" />
|
||||
<BackgroundColor color="secondary-active" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
# Color palette
|
||||
|
||||
```javascript
|
||||
primary: {
|
||||
light: '#5acce6',
|
||||
main: '#0944b3',
|
||||
dark: '#090c29',
|
||||
active: '#348cfd',
|
||||
},
|
||||
|
||||
secondary: {
|
||||
light: '#3a3f99',
|
||||
main: '#2b166b',
|
||||
dark: '#041c4a',
|
||||
active: '#1f1f27',
|
||||
},
|
||||
|
||||
common: {
|
||||
bright: '#e1e1e1',
|
||||
light: '#a19fad',
|
||||
main: '#fff',
|
||||
dark: '#726f7e',
|
||||
active: '#2c3074',
|
||||
},
|
||||
```
|
||||
@ -1,4 +0,0 @@
|
||||
{
|
||||
"label": "UI Component Library",
|
||||
"position": 5
|
||||
}
|
||||
@ -1,27 +0,0 @@
|
||||
---
|
||||
name: AboutModal
|
||||
menu: General
|
||||
route: components/aboutModal
|
||||
---
|
||||
|
||||
import { AboutModal } from '@ohif/ui';
|
||||
|
||||
# AboutModal
|
||||
|
||||
AboutModal are used to show application version information.
|
||||
|
||||
## Import
|
||||
|
||||
```javascript
|
||||
import { AboutModal } from '@ohif/ui';
|
||||
```
|
||||
|
||||
## Usage
|
||||
|
||||
```jsx live
|
||||
<div className="p-4">
|
||||
<AboutModal />
|
||||
</div>
|
||||
```
|
||||
|
||||
## Properties
|
||||
@ -1,373 +0,0 @@
|
||||
---
|
||||
name: Button
|
||||
menu: General
|
||||
route: components/button
|
||||
---
|
||||
|
||||
import { Button, IconButton, Icon } from '@ohif/ui';
|
||||
import { ComponentPropsTable } from '../../../../src/components/ComponentPropsTable.jsx';
|
||||
|
||||
# Button
|
||||
|
||||
Buttons are used to execute actions when users interacts with them.
|
||||
|
||||
## Import
|
||||
|
||||
```javascript
|
||||
import { Button } from '@ohif/ui';
|
||||
```
|
||||
|
||||
## Outlined Buttons
|
||||
|
||||
```jsx live
|
||||
<div className="p-4">
|
||||
<Button variant="outlined" className="m-1">
|
||||
Default
|
||||
</Button>
|
||||
<Button variant="outlined" color="primary" className="m-1">
|
||||
Primary
|
||||
</Button>
|
||||
<Button variant="outlined" color="secondary" className="m-1">
|
||||
Secondary
|
||||
</Button>
|
||||
<Button variant="outlined" color="white" className="m-1">
|
||||
White
|
||||
</Button>
|
||||
</div>
|
||||
```
|
||||
|
||||
## Contained Buttons
|
||||
|
||||
```jsx live
|
||||
<div className="p-4">
|
||||
<Button variant="contained" className="m-1">
|
||||
Default
|
||||
</Button>
|
||||
<Button variant="contained" color="primary" className="m-1">
|
||||
Primary
|
||||
</Button>
|
||||
<Button variant="contained" color="secondary" className="m-1">
|
||||
Secondary
|
||||
</Button>
|
||||
<Button variant="contained" color="white" className="m-1">
|
||||
White
|
||||
</Button>
|
||||
</div>
|
||||
```
|
||||
|
||||
## Text Buttons
|
||||
|
||||
```jsx live
|
||||
<div className="p-4">
|
||||
<Button variant="text" className="m-1">
|
||||
Default
|
||||
</Button>
|
||||
<Button variant="text" color="primary" className="m-1">
|
||||
Primary
|
||||
</Button>
|
||||
<Button variant="text" color="secondary" className="m-1">
|
||||
Secondary
|
||||
</Button>
|
||||
<Button variant="text" color="white" className="m-1">
|
||||
White
|
||||
</Button>
|
||||
</div>
|
||||
```
|
||||
|
||||
## Rounded Buttons
|
||||
|
||||
```jsx live
|
||||
<div className="p-4">
|
||||
<div className="mb-2">
|
||||
<Button variant="contained" rounded="none" className="m-1">
|
||||
Non Rounded
|
||||
</Button>
|
||||
<Button variant="contained" rounded="small" className="m-1">
|
||||
Small Rounded
|
||||
</Button>
|
||||
<Button variant="contained" rounded="medium" className="m-1">
|
||||
Medium Rounded
|
||||
</Button>
|
||||
<Button variant="contained" rounded="large" className="m-1">
|
||||
Large Rounded
|
||||
</Button>
|
||||
<Button variant="contained" rounded="full" className="m-1">
|
||||
Full Rounded
|
||||
</Button>
|
||||
</div>
|
||||
<div className="mb-2">
|
||||
<Button variant="contained" rounded="none" color="primary" className="m-1">
|
||||
Non Rounded
|
||||
</Button>
|
||||
<Button variant="contained" rounded="small" color="primary" className="m-1">
|
||||
Small Rounded
|
||||
</Button>
|
||||
<Button
|
||||
variant="contained"
|
||||
rounded="medium"
|
||||
color="primary"
|
||||
className="m-1"
|
||||
>
|
||||
Medium Rounded
|
||||
</Button>
|
||||
<Button variant="contained" rounded="large" color="primary" className="m-1">
|
||||
Large Rounded
|
||||
</Button>
|
||||
<Button variant="contained" rounded="full" color="primary" className="m-1">
|
||||
Full Rounded
|
||||
</Button>
|
||||
</div>
|
||||
<div className="mb-2">
|
||||
<Button
|
||||
variant="contained"
|
||||
rounded="none"
|
||||
color="secondary"
|
||||
className="m-1"
|
||||
>
|
||||
Non Rounded
|
||||
</Button>
|
||||
<Button
|
||||
variant="contained"
|
||||
rounded="small"
|
||||
color="secondary"
|
||||
className="m-1"
|
||||
>
|
||||
Small Rounded
|
||||
</Button>
|
||||
<Button
|
||||
variant="contained"
|
||||
rounded="medium"
|
||||
color="secondary"
|
||||
className="m-1"
|
||||
>
|
||||
Medium Rounded
|
||||
</Button>
|
||||
<Button
|
||||
variant="contained"
|
||||
rounded="large"
|
||||
color="secondary"
|
||||
className="m-1"
|
||||
>
|
||||
Large Rounded
|
||||
</Button>
|
||||
<Button
|
||||
variant="contained"
|
||||
rounded="full"
|
||||
color="secondary"
|
||||
className="m-1"
|
||||
>
|
||||
Full Rounded
|
||||
</Button>
|
||||
</div>
|
||||
<div className="mb-2">
|
||||
<Button variant="contained" rounded="none" color="white" className="m-1">
|
||||
Non Rounded
|
||||
</Button>
|
||||
<Button variant="contained" rounded="small" color="white" className="m-1">
|
||||
Small Rounded
|
||||
</Button>
|
||||
<Button variant="contained" rounded="medium" color="white" className="m-1">
|
||||
Medium Rounded
|
||||
</Button>
|
||||
<Button variant="contained" rounded="large" color="white" className="m-1">
|
||||
Large Rounded
|
||||
</Button>
|
||||
<Button variant="contained" rounded="full" color="white" className="m-1">
|
||||
Full Rounded
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
```
|
||||
|
||||
## Sizes
|
||||
|
||||
```jsx live
|
||||
<div className="p-4">
|
||||
<div>
|
||||
<Button variant="contained" size="small" className="m-1">
|
||||
Small
|
||||
</Button>
|
||||
<Button variant="contained" size="medium" className="m-1">
|
||||
Medium
|
||||
</Button>
|
||||
<Button variant="contained" size="large" className="m-1">
|
||||
Large
|
||||
</Button>
|
||||
</div>
|
||||
<div>
|
||||
<Button variant="contained" size="small" color="primary" className="m-1">
|
||||
Small
|
||||
</Button>
|
||||
<Button variant="contained" size="medium" color="primary" className="m-1">
|
||||
Medium
|
||||
</Button>
|
||||
<Button variant="contained" size="large" color="primary" className="m-1">
|
||||
Large
|
||||
</Button>
|
||||
</div>
|
||||
<div>
|
||||
<Button variant="contained" size="small" color="secondary" className="m-1">
|
||||
Small
|
||||
</Button>
|
||||
<Button variant="contained" size="medium" color="secondary" className="m-1">
|
||||
Medium
|
||||
</Button>
|
||||
<Button variant="contained" size="large" color="secondary" className="m-1">
|
||||
Large
|
||||
</Button>
|
||||
</div>
|
||||
<div>
|
||||
<Button variant="contained" size="small" color="white" className="m-1">
|
||||
Small
|
||||
</Button>
|
||||
<Button variant="contained" size="medium" color="white" className="m-1">
|
||||
Medium
|
||||
</Button>
|
||||
<Button variant="contained" size="large" color="white" className="m-1">
|
||||
Large
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
```
|
||||
|
||||
## Buttons with icons
|
||||
|
||||
```jsx live
|
||||
<div className="p-4 flex">
|
||||
<Button
|
||||
variant="contained"
|
||||
color="primary"
|
||||
className="m-1"
|
||||
startIcon={<Icon name="settings" />}
|
||||
>
|
||||
Settings
|
||||
</Button>
|
||||
<Button
|
||||
variant="contained"
|
||||
color="primary"
|
||||
className="m-1"
|
||||
endIcon={<Icon name="settings" />}
|
||||
>
|
||||
Download
|
||||
</Button>
|
||||
<Button
|
||||
variant="outlined"
|
||||
rounded="full"
|
||||
color="default"
|
||||
className="m-1"
|
||||
endIcon={<Icon name="settings" />}
|
||||
>
|
||||
Download
|
||||
</Button>
|
||||
</div>
|
||||
```
|
||||
|
||||
## Icon Buttons
|
||||
|
||||
Icon buttons are generally used in toolbars.
|
||||
|
||||
```javascript
|
||||
import { IconButton } from '@ohif/ui';
|
||||
```
|
||||
|
||||
```jsx live
|
||||
<div className="p-4 flex flex-col items-center">
|
||||
<div className="">
|
||||
<IconButton className="m-2">
|
||||
<Icon name="settings" />
|
||||
</IconButton>
|
||||
<IconButton className="m-2" variant="text">
|
||||
<Icon name="settings" />
|
||||
</IconButton>
|
||||
<IconButton className="m-2" variant="outlined">
|
||||
<Icon name="settings" />
|
||||
</IconButton>
|
||||
</div>
|
||||
<div>
|
||||
<IconButton className="m-2" color="primary">
|
||||
<Icon name="launch-arrow" />
|
||||
</IconButton>
|
||||
<IconButton className="m-2" color="primary" variant="text">
|
||||
<Icon name="launch-arrow" />
|
||||
</IconButton>
|
||||
<IconButton className="m-2" color="primary" variant="outlined">
|
||||
<Icon name="launch-arrow" />
|
||||
</IconButton>
|
||||
</div>
|
||||
<div>
|
||||
<IconButton className="m-2" color="secondary">
|
||||
<Icon name="cancel" />
|
||||
</IconButton>
|
||||
<IconButton className="m-2" color="secondary" variant="text">
|
||||
<Icon name="cancel" />
|
||||
</IconButton>
|
||||
<IconButton className="m-2" color="secondary" variant="outlined">
|
||||
<Icon name="cancel" />
|
||||
</IconButton>
|
||||
</div>
|
||||
<div>
|
||||
<IconButton className="m-2" color="white">
|
||||
<Icon name="settings" />
|
||||
</IconButton>
|
||||
<IconButton className="m-2" variant="text" color="white">
|
||||
<Icon name="launch-arrow" />
|
||||
</IconButton>
|
||||
<IconButton className="m-2" variant="outlined" color="white">
|
||||
<Icon name="cancel" />
|
||||
</IconButton>
|
||||
</div>
|
||||
</div>
|
||||
```
|
||||
|
||||
```jsx live
|
||||
<div className="p-4">
|
||||
<div className="">
|
||||
<IconButton className="m-2">
|
||||
<Icon name="settings" />
|
||||
</IconButton>
|
||||
<IconButton className="m-2" variant="outlined">
|
||||
<Icon name="settings" />
|
||||
</IconButton>
|
||||
<IconButton className="m-2" variant="text">
|
||||
<Icon name="settings" />
|
||||
</IconButton>
|
||||
</div>
|
||||
<div>
|
||||
<IconButton className="m-2" color="primary">
|
||||
<Icon name="launch-arrow" />
|
||||
</IconButton>
|
||||
<IconButton className="m-2" color="primary" variant="text">
|
||||
<Icon name="launch-arrow" />
|
||||
</IconButton>
|
||||
<IconButton className="m-2" color="primary" variant="outlined">
|
||||
<Icon name="launch-arrow" />
|
||||
</IconButton>
|
||||
</div>
|
||||
<div>
|
||||
<IconButton className="m-2" color="secondary">
|
||||
<Icon name="cancel" />
|
||||
</IconButton>
|
||||
<IconButton className="m-2" color="secondary" variant="text">
|
||||
<Icon name="cancel" />
|
||||
</IconButton>
|
||||
<IconButton className="m-2" color="secondary" variant="outlined">
|
||||
<Icon name="cancel" />
|
||||
</IconButton>
|
||||
</div>
|
||||
<div>
|
||||
<IconButton className="m-2" color="white">
|
||||
<Icon name="settings" />
|
||||
</IconButton>
|
||||
<IconButton className="m-2" variant="text" color="white">
|
||||
<Icon name="launch-arrow" />
|
||||
</IconButton>
|
||||
<IconButton className="m-2" variant="outlined" color="white">
|
||||
<Icon name="cancel" />
|
||||
</IconButton>
|
||||
</div>
|
||||
</div>
|
||||
```
|
||||
|
||||
## Properties
|
||||
|
||||
<ComponentPropsTable componentName={'Button'} />
|
||||
@ -1,111 +0,0 @@
|
||||
---
|
||||
name: ButtonGroup
|
||||
menu: General
|
||||
route: components/buttonGroup
|
||||
---
|
||||
|
||||
import { ButtonGroup, Button, IconButton, Icon } from '@ohif/ui';
|
||||
import { ComponentPropsTable } from '../../../../src/components/ComponentPropsTable.jsx';
|
||||
|
||||
# ButtonGroup
|
||||
|
||||
Group Button display buttons together sharing its configurations
|
||||
|
||||
## Import
|
||||
|
||||
```javascript
|
||||
import { ButtonGroup } from '@ohif/ui';
|
||||
```
|
||||
|
||||
## Basic button group
|
||||
|
||||
```jsx live
|
||||
<div className="p-4 flex flex-col items-center">
|
||||
<ButtonGroup color="primary" className="m-2">
|
||||
<Button>One</Button>
|
||||
<Button>Two</Button>
|
||||
<Button>Three</Button>
|
||||
</ButtonGroup>
|
||||
<ButtonGroup color="primary" variant="contained" className="m-2">
|
||||
<Button>One</Button>
|
||||
<Button>Two</Button>
|
||||
<Button>Three</Button>
|
||||
</ButtonGroup>
|
||||
<ButtonGroup color="primary" variant="text" className="m-2">
|
||||
<Button>One</Button>
|
||||
<Button>Two</Button>
|
||||
<Button>Three</Button>
|
||||
</ButtonGroup>
|
||||
</div>
|
||||
```
|
||||
|
||||
## Group sizes and colorss
|
||||
|
||||
```jsx live
|
||||
<div className="p-4 flex flex-col items-center">
|
||||
<ButtonGroup color="default" size="small" className="m-2">
|
||||
<Button>One</Button>
|
||||
<Button>Two</Button>
|
||||
<Button>Three</Button>
|
||||
</ButtonGroup>
|
||||
<ButtonGroup color="primary" size="medium" className="m-2">
|
||||
<Button>One</Button>
|
||||
<Button>Two</Button>
|
||||
<Button>Three</Button>
|
||||
</ButtonGroup>
|
||||
<ButtonGroup color="secondary" size="large" className="m-2">
|
||||
<Button>One</Button>
|
||||
<Button>Two</Button>
|
||||
<Button>Three</Button>
|
||||
</ButtonGroup>
|
||||
</div>
|
||||
```
|
||||
|
||||
## Group orientation
|
||||
|
||||
```jsx live
|
||||
<div className="p-4 flex flex-row justify-center">
|
||||
<ButtonGroup orientation="vertical" color="primary" className="m-2">
|
||||
<Button>One</Button>
|
||||
<Button>Two</Button>
|
||||
<Button>Three</Button>
|
||||
</ButtonGroup>
|
||||
<ButtonGroup
|
||||
orientation="vertical"
|
||||
color="primary"
|
||||
variant="contained"
|
||||
className="m-2"
|
||||
>
|
||||
<Button>One</Button>
|
||||
<Button>Two</Button>
|
||||
<Button>Three</Button>
|
||||
</ButtonGroup>
|
||||
<ButtonGroup
|
||||
orientation="vertical"
|
||||
color="primary"
|
||||
variant="text"
|
||||
className="m-2"
|
||||
>
|
||||
<Button>One</Button>
|
||||
<Button>Two</Button>
|
||||
<Button>Three</Button>
|
||||
</ButtonGroup>
|
||||
</div>
|
||||
```
|
||||
|
||||
## Split Button
|
||||
|
||||
```jsx live
|
||||
<div className="p-4 flex flex-col items-center">
|
||||
<ButtonGroup color="primary" className="m-2">
|
||||
<Button>Options</Button>
|
||||
<IconButton className="mr-2">
|
||||
<Icon name="settings" />
|
||||
</IconButton>
|
||||
</ButtonGroup>
|
||||
</div>
|
||||
```
|
||||
|
||||
## Properties
|
||||
|
||||
<ComponentPropsTable componentName={'ButtonGroup'} />
|
||||
@ -1,38 +0,0 @@
|
||||
---
|
||||
name: CinePlayer
|
||||
menu: General
|
||||
route: components/CinePlayer
|
||||
---
|
||||
|
||||
import { useState } from 'react';
|
||||
import { ComponentPropsTable } from '../../../../src/components/ComponentPropsTable.jsx';
|
||||
|
||||
## Import
|
||||
|
||||
```javascript
|
||||
import { CinePlayer } from '@ohif/ui';
|
||||
```
|
||||
|
||||
## Basic usage
|
||||
|
||||
```jsx live
|
||||
function() {
|
||||
return (
|
||||
<div className="flex flex-col flex-1 p-4 items-center">
|
||||
<div className="w-56">
|
||||
<CinePlayer
|
||||
cineMinFrameRate={1}
|
||||
cineMaxFrameRate={90}
|
||||
cineStepFrameRate={1}
|
||||
cineFrameRate={24}
|
||||
isPlaying={false}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
```
|
||||
|
||||
## Properties
|
||||
|
||||
<ComponentPropsTable componentName={'CinePlayer'} />
|
||||
@ -1,49 +0,0 @@
|
||||
---
|
||||
name: Context Menu
|
||||
menu: General
|
||||
route: components/contextMenu
|
||||
---
|
||||
|
||||
import { ContextMenu } from '@ohif/ui';
|
||||
import { ComponentPropsTable } from '../../../../src/components/ComponentPropsTable.jsx';
|
||||
|
||||
# Context Menu
|
||||
|
||||
...
|
||||
|
||||
## Import
|
||||
|
||||
```javascript
|
||||
import { ContextMenu } from '@ohif/ui';
|
||||
```
|
||||
|
||||
```jsx live
|
||||
function() {
|
||||
const items = [
|
||||
{
|
||||
label: 'Delete measurement',
|
||||
actionType: 'Delete',
|
||||
action: () => alert('Delete'),
|
||||
},
|
||||
{
|
||||
label: 'Relabel',
|
||||
actionType: 'setLabel',
|
||||
action: () => alert('Relabel'),
|
||||
},
|
||||
{
|
||||
label: 'Add Description',
|
||||
actionType: 'setDescription',
|
||||
action: () => alert('Add Description'),
|
||||
},
|
||||
];
|
||||
return (
|
||||
<div className="p-4">
|
||||
<ContextMenu items={items} />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
```
|
||||
|
||||
## Properties
|
||||
|
||||
<ComponentPropsTable componentName={'ContextMenu'} />
|
||||
@ -1,46 +0,0 @@
|
||||
---
|
||||
name: Date Range
|
||||
menu: Form
|
||||
route: components/date-range
|
||||
---
|
||||
|
||||
import { useState } from 'react';
|
||||
import { ComponentPropsTable } from '../../../../src/components/ComponentPropsTable.jsx';
|
||||
|
||||
import { DateRange } from '@ohif/ui';
|
||||
|
||||
# Date Range
|
||||
|
||||
Date Range is used to select a range of dates.
|
||||
|
||||
## Import
|
||||
|
||||
```javascript
|
||||
import { DateRange } from '@ohif/ui';
|
||||
```
|
||||
|
||||
## Date Range
|
||||
|
||||
```jsx live
|
||||
function() {
|
||||
const [dates, setDates] = useState({
|
||||
startDate: null,
|
||||
endDate: null,
|
||||
});
|
||||
return (
|
||||
<div className="p-4 flex flex-col items-center">
|
||||
<DateRange
|
||||
startDate={dates.startDate}
|
||||
endDate={dates.endDate}
|
||||
onChange={({ startDate, endDate }) =>
|
||||
setDates({ startDate, endDate })
|
||||
}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
```
|
||||
|
||||
## Properties
|
||||
|
||||
<ComponentPropsTable componentName={'DateRange'} />
|
||||
@ -1,68 +0,0 @@
|
||||
---
|
||||
name: Dropdown
|
||||
menu: General
|
||||
route: components/dropdown
|
||||
---
|
||||
|
||||
import { Dropdown, IconButton, Icon } from '@ohif/ui';
|
||||
import { ComponentPropsTable } from '../../../../src/components/ComponentPropsTable.jsx';
|
||||
|
||||
# Dropdown
|
||||
|
||||
This component is used when there are more than a few options to choose from. By
|
||||
hovering or clicking on the trigger, a dropdown menu will appear, which allows
|
||||
you to choose an option and execute the relevant action.
|
||||
|
||||
## Import
|
||||
|
||||
```javascript
|
||||
import { Dropdown } from '@ohif/ui';
|
||||
```
|
||||
|
||||
```jsx live
|
||||
function() {
|
||||
const handleClick = () => {
|
||||
alert('Clicked');
|
||||
};
|
||||
return (
|
||||
<div className="py-4">
|
||||
<Dropdown
|
||||
showDropdownIcon={false}
|
||||
list={[
|
||||
{
|
||||
title: 'Option 1',
|
||||
icon: 'info',
|
||||
onClick: handleClick,
|
||||
},
|
||||
{
|
||||
title: 'Option 2',
|
||||
icon: 'settings',
|
||||
onClick: handleClick,
|
||||
},
|
||||
]}
|
||||
>
|
||||
<IconButton
|
||||
variant="text"
|
||||
color="inherit"
|
||||
size="initial"
|
||||
className="text-primary-active"
|
||||
>
|
||||
<Icon name="settings" />
|
||||
</IconButton>
|
||||
<IconButton
|
||||
variant="text"
|
||||
color="inherit"
|
||||
size="initial"
|
||||
className="text-primary-active"
|
||||
>
|
||||
<Icon name="chevron-down" />
|
||||
</IconButton>
|
||||
</Dropdown>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
```
|
||||
|
||||
## Properties
|
||||
|
||||
<ComponentPropsTable componentName={'Dropdown'} />
|
||||
@ -1,30 +0,0 @@
|
||||
---
|
||||
name: Empty Studies
|
||||
menu: Data Display
|
||||
route: components/empty-studies
|
||||
---
|
||||
|
||||
import { EmptyStudies } from '@ohif/ui';
|
||||
import { ComponentPropsTable } from '../../../../src/components/ComponentPropsTable.jsx';
|
||||
|
||||
# Empty Studies
|
||||
|
||||
This component can be used to display a message when there are no studies.
|
||||
|
||||
## Import
|
||||
|
||||
```javascript
|
||||
import { EmptyStudies } from '@ohif/ui';
|
||||
```
|
||||
|
||||
## Basic usage
|
||||
|
||||
```jsx live
|
||||
<div className="p-4">
|
||||
<EmptyStudies />
|
||||
</div>
|
||||
```
|
||||
|
||||
## Properties
|
||||
|
||||
<ComponentPropsTable componentName={'EmptyStudies'} />
|
||||
@ -1,59 +0,0 @@
|
||||
---
|
||||
name: Error Boundary
|
||||
menu: Data Display
|
||||
route: components/errorBoundary
|
||||
---
|
||||
|
||||
import { ErrorBoundary } from '@ohif/ui';
|
||||
import { ComponentPropsTable } from '../../../../src/components/ComponentPropsTable.jsx';
|
||||
|
||||
# Error Boundary
|
||||
|
||||
This component can be used to display a message or handle unhandled errors.
|
||||
|
||||
## Import
|
||||
|
||||
```javascript
|
||||
import { ErrorBoundary } from '@ohif/ui';
|
||||
```
|
||||
|
||||
## Basic usage
|
||||
|
||||
```jsx live
|
||||
<div className="p-4">
|
||||
<ErrorBoundary context="Somewhere">
|
||||
{function() {
|
||||
throw new Error('Error!');
|
||||
return <p></p>;
|
||||
}}
|
||||
</ErrorBoundary>
|
||||
</div>
|
||||
```
|
||||
|
||||
## Custom error fallback
|
||||
|
||||
```jsx live
|
||||
function() {
|
||||
const CustomFallback = ({ error, componentStack, resetErrorBoundary }) => {
|
||||
return (
|
||||
<div>
|
||||
<p>This is a custom fallback!</p>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
return (
|
||||
<div className="p-4">
|
||||
<ErrorBoundary context="Somewhere" fallbackComponent={CustomFallback}>
|
||||
{function() {
|
||||
throw new Error('Error!');
|
||||
return <p></p>;
|
||||
}}
|
||||
</ErrorBoundary>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
```
|
||||
|
||||
## Properties
|
||||
|
||||
<ComponentPropsTable componentName={'ErrorBoundary'} />
|
||||
@ -1,87 +0,0 @@
|
||||
---
|
||||
name: Expandable Toolbar Button
|
||||
menu: General
|
||||
route: components/expandableToolbarButton
|
||||
---
|
||||
|
||||
import { useState } from 'react';
|
||||
import { ComponentPropsTable } from '../../../../src/components/ComponentPropsTable.jsx';
|
||||
import { ExpandableToolbarButton, ListMenu } from '@ohif/ui';
|
||||
|
||||
# Toolbar Button
|
||||
|
||||
Expandable Toolbar Buttons are used to populate the Toolbar.
|
||||
|
||||
## Import
|
||||
|
||||
```javascript
|
||||
import { ExpandableToolbarButton, ListMenu } from '@ohif/ui';
|
||||
```
|
||||
|
||||
```jsx live
|
||||
function() {
|
||||
const props = {
|
||||
content: ListMenu,
|
||||
contentProps: {
|
||||
options: [
|
||||
{
|
||||
value: 'windowLevelPreset1',
|
||||
title: 'Soft tissue',
|
||||
subtitle: '400 / 40',
|
||||
},
|
||||
{
|
||||
value: 'windowLevelPreset2',
|
||||
title: 'Lung',
|
||||
subtitle: '1500 / -600',
|
||||
},
|
||||
{ value: 'windowLevelPreset3', title: 'Liver', subtitle: '150 / 90' },
|
||||
{ value: 'windowLevelPreset4', title: 'Bone', subtitle: '80 / 40' },
|
||||
{
|
||||
value: 'windowLevelPreset5',
|
||||
title: 'Brain',
|
||||
subtitle: '2500 / 480',
|
||||
},
|
||||
],
|
||||
renderer: ({ title, subtitle, isActive, index }) => (
|
||||
<>
|
||||
<div>
|
||||
<span
|
||||
className={classnames(
|
||||
isActive ? 'text-black' : 'text-white',
|
||||
'mr-2 text-base'
|
||||
)}
|
||||
>
|
||||
{title}
|
||||
</span>
|
||||
<span
|
||||
className={classnames(
|
||||
isActive ? 'text-black' : 'text-aqua-pale',
|
||||
'font-light text-sm'
|
||||
)}
|
||||
>
|
||||
{subtitle}
|
||||
</span>
|
||||
</div>
|
||||
<span
|
||||
className={classnames(
|
||||
isActive ? 'text-black' : 'text-primary-active',
|
||||
'text-sm'
|
||||
)}
|
||||
>
|
||||
{index + 1}
|
||||
</span>
|
||||
</>
|
||||
),
|
||||
},
|
||||
};
|
||||
return (
|
||||
<div className="py-10 flex justify-center">
|
||||
<ExpandableToolbarButton {...props} />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
```
|
||||
|
||||
## Properties
|
||||
|
||||
<ComponentPropsTable componentName={'ExpandableToolbarButton'} />
|
||||
@ -1,39 +0,0 @@
|
||||
---
|
||||
name: Input
|
||||
menu: Form
|
||||
route: components/input
|
||||
---
|
||||
|
||||
import { Input } from '@ohif/ui';
|
||||
import { ComponentPropsTable } from '../../../../src/components/ComponentPropsTable.jsx';
|
||||
|
||||
# Input
|
||||
|
||||
## Import
|
||||
|
||||
```javascript
|
||||
import { Input } from '@ohif/ui';
|
||||
```
|
||||
|
||||
## Basic usage
|
||||
|
||||
```jsx live
|
||||
function() {
|
||||
const [inputValue, setInputValue] = React.useState('');
|
||||
return (
|
||||
<div className="p-4">
|
||||
<Input
|
||||
transparent
|
||||
containerClassName="mb-3"
|
||||
label="Label"
|
||||
placeholder="With Label"
|
||||
/>
|
||||
<Input placeholder="Without label" />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
```
|
||||
|
||||
## Properties
|
||||
|
||||
<ComponentPropsTable componentName={'Input'} />
|
||||
@ -1,44 +0,0 @@
|
||||
---
|
||||
name: InputDateRange
|
||||
menu: Form
|
||||
route: components/InputDateRange
|
||||
---
|
||||
|
||||
import { useState } from 'react';
|
||||
import { ComponentPropsTable } from '../../../../src/components/ComponentPropsTable.jsx';
|
||||
|
||||
import { InputDateRange } from '@ohif/ui';
|
||||
|
||||
# Input Date Range
|
||||
|
||||
## Import
|
||||
|
||||
```javascript
|
||||
import { InputDateRange } from '@ohif/ui';
|
||||
```
|
||||
|
||||
## Basic usage
|
||||
|
||||
```jsx live
|
||||
function() {
|
||||
const [dates, setDates] = useState({
|
||||
startDate: null,
|
||||
endDate: null,
|
||||
});
|
||||
return (
|
||||
<div className="p-4 flex flex-col items-center">
|
||||
<div className="w-56">
|
||||
<InputDateRange
|
||||
label="Dates"
|
||||
value={dates}
|
||||
onChange={dates => setDates(dates)}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
```
|
||||
|
||||
## Properties
|
||||
|
||||
<ComponentPropsTable componentName={'InputDateRange'} />
|
||||
@ -1,91 +0,0 @@
|
||||
---
|
||||
name: InputGroup
|
||||
menu: Form
|
||||
route: components/InputGroup
|
||||
---
|
||||
|
||||
import { useState } from 'react';
|
||||
import { ComponentPropsTable } from '../../../../src/components/ComponentPropsTable.jsx';
|
||||
|
||||
import { InputGroup } from '@ohif/ui';
|
||||
|
||||
# Input Group
|
||||
|
||||
## Import
|
||||
|
||||
```javascript
|
||||
import { InputGroup } from '@ohif/ui';
|
||||
```
|
||||
|
||||
## Basic usage
|
||||
|
||||
```jsx live
|
||||
function() {
|
||||
const [filterValues, setFilterValues] = useState({
|
||||
patient: '',
|
||||
studyDate: {
|
||||
startDate: null,
|
||||
endDate: null,
|
||||
},
|
||||
modality: [],
|
||||
});
|
||||
const [filterSorting, setFilterSorting] = useState({
|
||||
sortBy: '',
|
||||
sortDirection: 'none',
|
||||
});
|
||||
const filtersMeta = [
|
||||
{
|
||||
name: 'patient',
|
||||
displayName: 'Patient Name',
|
||||
inputType: 'Text',
|
||||
isSortable: true,
|
||||
gridCol: 6,
|
||||
},
|
||||
{
|
||||
name: 'studyDate',
|
||||
displayName: 'Study date',
|
||||
inputType: 'DateRange',
|
||||
isSortable: true,
|
||||
gridCol: 6,
|
||||
},
|
||||
{
|
||||
name: 'modality',
|
||||
displayName: 'Modality',
|
||||
inputType: 'MultiSelect',
|
||||
inputProps: {
|
||||
options: [
|
||||
{ value: 'SEG', label: 'SEG' },
|
||||
{ value: 'CT', label: 'CT' },
|
||||
{ value: 'MR', label: 'MR' },
|
||||
{ value: 'SR', label: 'SR' },
|
||||
],
|
||||
},
|
||||
isSortable: true,
|
||||
gridCol: 6,
|
||||
},
|
||||
{
|
||||
name: 'numberOfInstance',
|
||||
displayName: 'Number of Instances',
|
||||
inputType: 'None',
|
||||
isSortable: true,
|
||||
gridCol: 6,
|
||||
},
|
||||
];
|
||||
return (
|
||||
<div className="py-4">
|
||||
<InputGroup
|
||||
inputMeta={filtersMeta}
|
||||
values={filterValues}
|
||||
onValuesChange={setFilterValues}
|
||||
sorting={filterSorting}
|
||||
onSortingChange={setFilterSorting}
|
||||
isSortingEnable={true}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
```
|
||||
|
||||
## Properties
|
||||
|
||||
<ComponentPropsTable componentName={'InputGroup'} />
|
||||
@ -1,49 +0,0 @@
|
||||
---
|
||||
name: InputMultiSelect
|
||||
menu: Form
|
||||
route: components/InputMultiSelect
|
||||
---
|
||||
|
||||
import { useState } from 'react';
|
||||
import { ComponentPropsTable } from '../../../../src/components/ComponentPropsTable.jsx';
|
||||
|
||||
import { InputMultiSelect } from '@ohif/ui';
|
||||
|
||||
# Input Multi Select
|
||||
|
||||
## Import
|
||||
|
||||
```javascript
|
||||
import { InputMultiSelect } from '@ohif/ui';
|
||||
```
|
||||
|
||||
## Basic usage
|
||||
|
||||
```jsx live
|
||||
function() {
|
||||
const [values, setValues] = useState([]);
|
||||
return (
|
||||
<div className="flex flex-col flex-1 p-4 items-center">
|
||||
<div className="w-56">
|
||||
<InputMultiSelect
|
||||
label="Modality"
|
||||
options={[
|
||||
{ value: 'SEG', label: 'SEG' },
|
||||
{ value: 'CT', label: 'CT' },
|
||||
{ value: 'MR', label: 'MR' },
|
||||
{ value: 'SR', label: 'SR' },
|
||||
]}
|
||||
value={values}
|
||||
onChange={values => {
|
||||
setValues(values);
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
```
|
||||
|
||||
## Properties
|
||||
|
||||
<ComponentPropsTable componentName={'InputMultiSelect'} />
|
||||
@ -1,43 +0,0 @@
|
||||
---
|
||||
name: InputText
|
||||
menu: Form
|
||||
route: components/InputText
|
||||
---
|
||||
|
||||
import { useState } from 'react';
|
||||
import { ComponentPropsTable } from '../../../../src/components/ComponentPropsTable.jsx';
|
||||
|
||||
import { InputText } from '@ohif/ui';
|
||||
|
||||
# Input Text
|
||||
|
||||
## Import
|
||||
|
||||
```javascript
|
||||
import { InputText } from '@ohif/ui';
|
||||
```
|
||||
|
||||
## Basic usage
|
||||
|
||||
```jsx live
|
||||
function() {
|
||||
const [text, setText] = useState('');
|
||||
return (
|
||||
<div className="flex flex-col flex-1 p-4 items-center">
|
||||
<div className="w-56">
|
||||
<InputText
|
||||
label="Name"
|
||||
value={text}
|
||||
onChange={value => {
|
||||
setText(value);
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
```
|
||||
|
||||
## Properties
|
||||
|
||||
<ComponentPropsTable componentName={'InputText'} />
|
||||
@ -1,32 +0,0 @@
|
||||
---
|
||||
name: Label
|
||||
menu: Form
|
||||
route: components/label
|
||||
---
|
||||
|
||||
import { Label } from '@ohif/ui';
|
||||
import { ComponentPropsTable } from '../../../../src/components/ComponentPropsTable.jsx';
|
||||
|
||||
# Label
|
||||
|
||||
## Import
|
||||
|
||||
```javascript
|
||||
import { Label } from '@ohif/ui';
|
||||
```
|
||||
|
||||
## Basic usage
|
||||
|
||||
```jsx live
|
||||
function() {
|
||||
return (
|
||||
<div className="p-4">
|
||||
<Label text="Label" />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
```
|
||||
|
||||
## Properties
|
||||
|
||||
<ComponentPropsTable componentName={'Label'} />
|
||||
@ -1,82 +0,0 @@
|
||||
---
|
||||
name: List Menu
|
||||
menu: General
|
||||
route: components/listMenu
|
||||
---
|
||||
|
||||
import { useState } from 'react';
|
||||
import { ComponentPropsTable } from '../../../../src/components/ComponentPropsTable.jsx';
|
||||
|
||||
import { ListMenu, ToolbarButton } from '@ohif/ui';
|
||||
|
||||
# List Menu
|
||||
|
||||
List Menus are used to populate expandable Toolbar.
|
||||
|
||||
## Import
|
||||
|
||||
```javascript
|
||||
import { ListMenu, ToolbarButton } from '@ohif/ui';
|
||||
```
|
||||
|
||||
```jsx live
|
||||
function() {
|
||||
return (
|
||||
<ToolbarButton
|
||||
items={[
|
||||
{
|
||||
value: 'windowLevelPreset1',
|
||||
title: 'Soft tissue',
|
||||
subtitle: '400 / 40',
|
||||
},
|
||||
{
|
||||
value: 'windowLevelPreset2',
|
||||
title: 'Lung',
|
||||
subtitle: '1500 / -600',
|
||||
},
|
||||
{ value: 'windowLevelPreset3', title: 'Liver', subtitle: '150 / 90' },
|
||||
{ value: 'windowLevelPreset4', title: 'Bone', subtitle: '80 / 40' },
|
||||
{
|
||||
value: 'windowLevelPreset5',
|
||||
title: 'Brain',
|
||||
subtitle: '2500 / 480',
|
||||
},
|
||||
]}
|
||||
renderer={({ title, subtitle, isActive, index }) => (
|
||||
<>
|
||||
<div>
|
||||
<span
|
||||
className={classnames(
|
||||
isActive ? 'text-black' : 'text-white',
|
||||
'mr-2 text-base'
|
||||
)}
|
||||
>
|
||||
{title}
|
||||
</span>
|
||||
<span
|
||||
className={classnames(
|
||||
isActive ? 'text-black' : 'text-aqua-pale',
|
||||
'font-light text-sm'
|
||||
)}
|
||||
>
|
||||
{subtitle}
|
||||
</span>
|
||||
</div>
|
||||
<span
|
||||
className={classnames(
|
||||
isActive ? 'text-black' : 'text-primary-active',
|
||||
'text-sm'
|
||||
)}
|
||||
>
|
||||
{index + 1}
|
||||
</span>
|
||||
</>
|
||||
)}
|
||||
/>
|
||||
);
|
||||
}
|
||||
```
|
||||
|
||||
## Properties
|
||||
|
||||
<ComponentPropsTable componentName={'ListMenu'} />
|
||||
@ -1,59 +0,0 @@
|
||||
---
|
||||
name: Measurement Table
|
||||
menu: Data Display
|
||||
route: components/measurementTable
|
||||
---
|
||||
|
||||
import { useState } from 'react';
|
||||
import { ComponentPropsTable } from '../../../../src/components/ComponentPropsTable.jsx';
|
||||
|
||||
import { MeasurementTable } from '@ohif/ui';
|
||||
|
||||
# Measurement Table
|
||||
|
||||
## Import
|
||||
|
||||
```javascript
|
||||
import { MeasurementTable } from '@ohif/ui';
|
||||
```
|
||||
|
||||
## Basic usage
|
||||
|
||||
```jsx live
|
||||
function() {
|
||||
const [activeMeasurementItem, setActiveMeasurementItem] = useState(null);
|
||||
const measurementTableData = {
|
||||
title: 'Measurements',
|
||||
amount: 10,
|
||||
data: new Array(10).fill({}).map((el, i) => ({
|
||||
id: i + 1,
|
||||
label: 'Label short description',
|
||||
displayText: ['24.0 x 24.0 mm (S:4, I:22)'],
|
||||
isActive: activeMeasurementItem === i + 1,
|
||||
})),
|
||||
onClick: id => setActiveMeasurementItem(s => (s === id ? null : id)),
|
||||
onEdit: id => alert(`Edit: ${id}`),
|
||||
};
|
||||
return (
|
||||
<div className="p-4 w-80">
|
||||
<MeasurementTable {...measurementTableData} />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
```
|
||||
|
||||
## Empty Data
|
||||
|
||||
```jsx live
|
||||
function() {
|
||||
return (
|
||||
<div className="p-4 w-80">
|
||||
<MeasurementTable title="Measurements" />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
```
|
||||
|
||||
## Properties
|
||||
|
||||
<ComponentPropsTable componentName={'MeasurementTable'} />
|
||||
@ -1,30 +0,0 @@
|
||||
---
|
||||
name: NavBar
|
||||
menu: Navigation
|
||||
route: components/navBar
|
||||
---
|
||||
|
||||
import { NavBar, Typography } from '@ohif/ui';
|
||||
import { ComponentPropsTable } from '../../../../src/components/ComponentPropsTable.jsx';
|
||||
|
||||
# NavBar
|
||||
|
||||
## Import
|
||||
|
||||
```javascript
|
||||
import { NavBar } from '@ohif/ui';
|
||||
```
|
||||
|
||||
## Basic usage
|
||||
|
||||
```jsx live
|
||||
<NavBar className="justify-center">
|
||||
<Typography variant="h3" className="m-2">
|
||||
Header content
|
||||
</Typography>
|
||||
</NavBar>
|
||||
```
|
||||
|
||||
## Properties
|
||||
|
||||
<ComponentPropsTable componentName={'NavBar'} />
|
||||
@ -1,58 +0,0 @@
|
||||
---
|
||||
name: Notification
|
||||
menu: Feedback
|
||||
route: components/notification
|
||||
---
|
||||
|
||||
import { Notification } from '@ohif/ui';
|
||||
import { ComponentPropsTable } from '../../../../src/components/ComponentPropsTable.jsx';
|
||||
|
||||
# Notification
|
||||
|
||||
A notification displays a short message in a way that attracts the user's
|
||||
attention without interrupting the user's task.
|
||||
|
||||
## Import
|
||||
|
||||
```javascript
|
||||
import { Notification } from '@ohif/ui';
|
||||
```
|
||||
|
||||
## Basic usage
|
||||
|
||||
```jsx live
|
||||
function() {
|
||||
return (
|
||||
<div className="p-4 w-full lg:w-2/3">
|
||||
<Notification
|
||||
message="Track all measurement for this series?"
|
||||
type="info"
|
||||
actions={[
|
||||
{
|
||||
type: 'cancel',
|
||||
text: 'No',
|
||||
value: 0,
|
||||
},
|
||||
{
|
||||
type: 'secondary',
|
||||
text: 'No, do not ask again',
|
||||
value: -1,
|
||||
},
|
||||
{
|
||||
type: 'primary',
|
||||
text: 'Yes',
|
||||
value: 1,
|
||||
},
|
||||
]}
|
||||
onSubmit={value => {
|
||||
window.alert(value);
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
```
|
||||
|
||||
## Properties
|
||||
|
||||
<ComponentPropsTable componentName={'Notification'} />
|
||||
@ -1,37 +0,0 @@
|
||||
---
|
||||
name: Segmentation Table
|
||||
menu: Data Display
|
||||
route: components/segmentationTable
|
||||
---
|
||||
|
||||
import { SegmentationTable } from '@ohif/ui';
|
||||
import { ComponentPropsTable } from '../../../../src/components/ComponentPropsTable.jsx';
|
||||
|
||||
# Segmentation Table
|
||||
|
||||
## Import
|
||||
|
||||
```javascript
|
||||
import { SegmentationTable } from '@ohif/ui';
|
||||
```
|
||||
|
||||
## Basic usage
|
||||
|
||||
```jsx live
|
||||
function() {
|
||||
const tableData = {
|
||||
title: 'Segments',
|
||||
amount: 12,
|
||||
data: new Array(12).fill(''),
|
||||
};
|
||||
return (
|
||||
<div className="p-4 w-80">
|
||||
<SegmentationTable {...tableData} />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
```
|
||||
|
||||
## Properties
|
||||
|
||||
<ComponentPropsTable componentName={'SegmentationTable'} />
|
||||
@ -1,70 +0,0 @@
|
||||
---
|
||||
name: Select
|
||||
menu: Form
|
||||
route: components/select
|
||||
---
|
||||
|
||||
import { Select } from '@ohif/ui';
|
||||
import { ComponentPropsTable } from '../../../../src/components/ComponentPropsTable.jsx';
|
||||
|
||||
# Select
|
||||
|
||||
## Import
|
||||
|
||||
```javascript
|
||||
import { Select } from '@ohif/ui';
|
||||
```
|
||||
|
||||
## Basic usage
|
||||
|
||||
```jsx live
|
||||
<div className="flex flex-col flex-1 p-4 items-center">
|
||||
<div className="w-56">
|
||||
<Select
|
||||
options={[
|
||||
{ value: 'ONE', label: 'ONE' },
|
||||
{ value: 'TWO', label: 'TWO' },
|
||||
{ value: 'THREE', label: 'THREE' },
|
||||
{ value: 'FOUR', label: 'FOUR' },
|
||||
]}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
```
|
||||
|
||||
## Disabled
|
||||
|
||||
```jsx live
|
||||
<div className="flex flex-col flex-1 p-4 items-center">
|
||||
<div className="w-56">
|
||||
<Select
|
||||
isDisabled
|
||||
options={[
|
||||
{ value: 'ONE', label: 'ONE' },
|
||||
{ value: 'TWO', label: 'TWO' },
|
||||
{ value: 'THREE', label: 'THREE' },
|
||||
{ value: 'FOUR', label: 'FOUR' },
|
||||
]}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
```
|
||||
|
||||
## No Options
|
||||
|
||||
```jsx live
|
||||
<div className="flex flex-col flex-1 p-4 items-center">
|
||||
<div className="w-56">
|
||||
<Select
|
||||
noOptionsMessage=function() {
|
||||
'No Options';
|
||||
}}
|
||||
options={[]}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
```
|
||||
|
||||
## Properties
|
||||
|
||||
<ComponentPropsTable componentName={'Select'} />
|
||||
@ -1,84 +0,0 @@
|
||||
---
|
||||
name: SidePanel
|
||||
menu: General
|
||||
route: components/sidePanel
|
||||
---
|
||||
|
||||
import { SidePanel } from '@ohif/ui';
|
||||
|
||||
# SidePanel
|
||||
|
||||
## Import
|
||||
|
||||
```javascript
|
||||
import { SidePanel } from '@ohif/ui';
|
||||
```
|
||||
|
||||
## Basic usage
|
||||
|
||||
```jsx live
|
||||
<div
|
||||
className="flex flex-row flex-nowrap flex-1 items-stretch overflow-hidden w-full"
|
||||
style={{ height: '500px' }}
|
||||
>
|
||||
<SidePanel
|
||||
side="left"
|
||||
childComponents={{
|
||||
iconName: 'group-layers',
|
||||
iconLabel: 'Studies',
|
||||
name: 'studies',
|
||||
label: 'Studies',
|
||||
content: (
|
||||
<div className="flex justify-center text-white p-2">panel content</div>
|
||||
),
|
||||
}}
|
||||
/>
|
||||
<div className="flex flex-1 h-100 overflow-hidden bg-primary-main items-center justify-center text-white">
|
||||
CONTENT
|
||||
</div>
|
||||
</div>
|
||||
```
|
||||
|
||||
## Multiple panels
|
||||
|
||||
```jsx live
|
||||
<div
|
||||
className="flex flex-row flex-nowrap flex-1 items-stretch overflow-hidden w-full"
|
||||
style={{ height: '500px' }}
|
||||
>
|
||||
<SidePanel
|
||||
side="left"
|
||||
childComponents={[
|
||||
{
|
||||
iconName: 'group-layers',
|
||||
iconLabel: 'Studies',
|
||||
name: 'studies',
|
||||
label: 'Studies',
|
||||
content: (
|
||||
<div className="flex justify-center text-white p-2">
|
||||
studies panel content
|
||||
</div>
|
||||
),
|
||||
},
|
||||
{
|
||||
iconName: 'list-bullets',
|
||||
iconLabel: 'Measure',
|
||||
name: 'measurements',
|
||||
label: 'Measurements',
|
||||
content: (
|
||||
<div className="flex justify-center text-white p-2">
|
||||
measure panel content
|
||||
</div>
|
||||
),
|
||||
},
|
||||
]}
|
||||
/>
|
||||
<div className="flex flex-1 h-100 overflow-hidden bg-primary-main items-center justify-center text-white">
|
||||
CONTENT
|
||||
</div>
|
||||
</div>
|
||||
```
|
||||
|
||||
## Properties
|
||||
|
||||
(<ComponentPropsTable componentName={'SidePanel'} />)``
|
||||
@ -1,88 +0,0 @@
|
||||
---
|
||||
name: Split Button
|
||||
menu: General
|
||||
route: components/splitButton
|
||||
---
|
||||
|
||||
import { useState } from 'react';
|
||||
|
||||
import { SplitButton, WindowLevelMenuItem } from '@ohif/ui';
|
||||
import { ComponentPropsTable } from '../../../../src/components/ComponentPropsTable.jsx';
|
||||
|
||||
# Split Button
|
||||
|
||||
Split Buttons are used to populate the Toolbar.
|
||||
|
||||
## Import
|
||||
|
||||
```javascript
|
||||
import { SplitButton, WindowLevelMenuItem } from '@ohif/ui';
|
||||
```
|
||||
|
||||
```jsx live
|
||||
function() {
|
||||
const mockedProps = {
|
||||
bState: {
|
||||
primaryToolId: 'WWWC',
|
||||
toggles: {},
|
||||
},
|
||||
primary: {
|
||||
tooltip: 'W/L',
|
||||
type: 'tool',
|
||||
icon: 'tool-window-level',
|
||||
onClick: args => console.debug('Primary click!', args),
|
||||
},
|
||||
secondary: {
|
||||
icon: 'chevron-down',
|
||||
label: '',
|
||||
isActive: true,
|
||||
tooltip: 'More Measure Tools',
|
||||
},
|
||||
items: [
|
||||
{
|
||||
id: '1',
|
||||
icon: 'tool-layout',
|
||||
label: 'Layout',
|
||||
onClick: args => console.debug('Item click!', args),
|
||||
},
|
||||
{
|
||||
id: '2',
|
||||
icon: 'tool-window-level',
|
||||
label: 'W/L',
|
||||
onClick: args => console.debug('Item click!', args),
|
||||
},
|
||||
{
|
||||
id: '3',
|
||||
icon: 'tool-length',
|
||||
label: 'Length',
|
||||
onClick: args => console.debug('Item click!', args),
|
||||
},
|
||||
],
|
||||
onClick: args => console.debug('Any click!', args),
|
||||
};
|
||||
return (
|
||||
<div className="mb-2">
|
||||
<div className="flex flex-row w-full justify-center items-center bg-secondary-dark">
|
||||
<SplitButton {...mockedProps} isRadio />
|
||||
<SplitButton
|
||||
{...mockedProps}
|
||||
isAction
|
||||
renderer={WindowLevelMenuItem}
|
||||
items={[
|
||||
{ id: '1', value: 1, title: 'Soft tissue', subtitle: '400 / 40' },
|
||||
{ id: '2', value: 2, title: 'Lung', subtitle: '1500 / -600' },
|
||||
{ id: '3', value: 3, title: 'Liver', subtitle: '150 / 90' },
|
||||
{ id: '4', value: 4, title: 'Bone', subtitle: '80 / 40' },
|
||||
{ id: '5', value: 5, title: 'Brain', subtitle: '2500 / 480' },
|
||||
]}
|
||||
/>
|
||||
<SplitButton {...mockedProps} />
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
```
|
||||
|
||||
## Properties
|
||||
|
||||
<ComponentPropsTable componentName={'SplitButton'} />
|
||||
@ -1,111 +0,0 @@
|
||||
---
|
||||
name: StudyBrowser
|
||||
menu: General
|
||||
route: components/studyBrowser
|
||||
---
|
||||
|
||||
import { StudyBrowser } from '@ohif/ui';
|
||||
import { ComponentPropsTable } from '../../../../src/components/ComponentPropsTable.jsx';
|
||||
|
||||
# StudyBrowser
|
||||
|
||||
## Import
|
||||
|
||||
```javascript
|
||||
import { StudyBrowser } from '@ohif/ui';
|
||||
```
|
||||
|
||||
## Basic usage
|
||||
|
||||
```jsx live
|
||||
function() {
|
||||
const studyWithSR = {
|
||||
studyInstanceUid: '1',
|
||||
date: '07-Sept-2010',
|
||||
description: 'CHEST/ABD/PELVIS W/CONTRAST',
|
||||
numInstances: 902,
|
||||
modalities: 'CT,SR',
|
||||
displaySets: [
|
||||
{
|
||||
displaySetInstanceUID: 'f69f6asdasd48c-223e-db7f-c4af-b8906641a66e',
|
||||
description: 'Multiple line image series description lorem sit',
|
||||
seriesNumber: 1,
|
||||
numInstances: 68,
|
||||
componentType: 'thumbnailTracked',
|
||||
viewportIdentificator: 'A',
|
||||
isTracked: true,
|
||||
},
|
||||
{
|
||||
displaySetInstanceUID: 'f69f648c-223e-db7f-c4asdasdaf-b8906641a66e',
|
||||
description: 'Multiple line image series description lorem sit',
|
||||
seriesNumber: 1,
|
||||
numInstances: 68,
|
||||
componentType: 'thumbnailTracked',
|
||||
viewportIdentificator: 'B',
|
||||
},
|
||||
{
|
||||
displaySetInstanceUID: 'f69f648c-223e-dasdasdb7f-c4af-b8906641a66e',
|
||||
description: 'Multiple line image series description lorem sit',
|
||||
seriesNumber: 1,
|
||||
numInstances: 68,
|
||||
componentType: 'thumbnailTracked',
|
||||
},
|
||||
{
|
||||
displaySetInstanceUID: 'f69f648c-223e-db7f-c4afas-b8906asd641a66e',
|
||||
description: 'Multiple line description lorem ipsum dolor sit amet',
|
||||
modality: 'SR',
|
||||
componentType: 'thumbnailNoImage',
|
||||
seriesDate: '07-Sept-2010',
|
||||
},
|
||||
],
|
||||
};
|
||||
const studySimple = {
|
||||
studyInstanceUid: '2',
|
||||
date: '07-Sept-2010',
|
||||
description: 'CHEST/ABD/PELVIS W/CONTRAST',
|
||||
numInstances: 902,
|
||||
modalities: 'CT',
|
||||
displaySets: [
|
||||
{
|
||||
displaySetInstanceUID: 'f69f648c-223e-db7f-c4af-b8906641a66e',
|
||||
description: 'Multiple line image series description lorem sit',
|
||||
seriesNumber: 1,
|
||||
numInstances: 68,
|
||||
componentType: 'thumbnailTracked',
|
||||
},
|
||||
],
|
||||
};
|
||||
const tabs = [
|
||||
{
|
||||
name: 'primary',
|
||||
label: 'Primary',
|
||||
studies: [studySimple],
|
||||
},
|
||||
{
|
||||
name: 'recent',
|
||||
label: 'Recent',
|
||||
studies: [studyWithSR, studySimple],
|
||||
},
|
||||
{
|
||||
name: 'all',
|
||||
label: 'All',
|
||||
studies: [studySimple, studyWithSR],
|
||||
},
|
||||
];
|
||||
return (
|
||||
<div className="flex flex-1" style={{ height: '400px' }}>
|
||||
<div className="overflow-hidden w-64">
|
||||
<StudyBrowser
|
||||
tabs={tabs}
|
||||
activeTabName="primary"
|
||||
expandedStudyInstanceUIDs={[]}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
```
|
||||
|
||||
## Properties
|
||||
|
||||
<ComponentPropsTable componentName={'StudyBrowser'} />
|
||||
@ -1,47 +0,0 @@
|
||||
---
|
||||
name: StudyItem
|
||||
menu: General
|
||||
route: components/studyItem
|
||||
---
|
||||
|
||||
import { useState } from 'react';
|
||||
|
||||
import { StudyItem } from '@ohif/ui';
|
||||
|
||||
# StudyItem
|
||||
|
||||
Used to expose study information as a card
|
||||
|
||||
## Import
|
||||
|
||||
```javascript
|
||||
import { StudyItem } from '@ohif/ui';
|
||||
```
|
||||
|
||||
## Basic usage
|
||||
|
||||
```jsx live
|
||||
function() {
|
||||
const [studyActive, setStudyActive] = useState(null);
|
||||
return (
|
||||
<div className="flex flex-1 items-center justify-center p-4">
|
||||
<div className="w-56">
|
||||
<StudyItem
|
||||
studyInstanceUid="1"
|
||||
date="07-Sept-2010"
|
||||
description="CHEST/ABD/PELVIS W/CONTRAST"
|
||||
numInstances={902}
|
||||
modalities="CT,SR"
|
||||
isActive={studyActive}
|
||||
onClick={() => setStudyActive(studyActive === '1' ? null : '1')}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
```
|
||||
|
||||
## Properties
|
||||
|
||||
<ComponentPropsTable componentName={'StudyItem'} />
|
||||
```
|
||||
@ -1,122 +0,0 @@
|
||||
---
|
||||
name: Study List Filter
|
||||
menu: Data Display
|
||||
route: components/studyListFilter
|
||||
---
|
||||
|
||||
import { useState } from 'react';
|
||||
import { ComponentPropsTable } from '../../../../src/components/ComponentPropsTable.jsx';
|
||||
|
||||
import { StudyListFilter, Modal } from '@ohif/ui';
|
||||
import { ModalProvider } from '@ohif/ui';
|
||||
|
||||
# Study List Filter
|
||||
|
||||
## Import
|
||||
|
||||
```javascript
|
||||
import { StudyListFilter, ModalProvider, Modal } from '@ohif/ui';
|
||||
```
|
||||
|
||||
## Basic usage
|
||||
|
||||
```jsx live
|
||||
function() {
|
||||
const defaultFilterValues = {
|
||||
patientName: '',
|
||||
mrn: '',
|
||||
studyDate: {
|
||||
startDate: null,
|
||||
endDate: null,
|
||||
},
|
||||
description: '',
|
||||
modality: undefined,
|
||||
accession: '',
|
||||
sortBy: '',
|
||||
sortDirection: 'none',
|
||||
page: 0,
|
||||
resultsPerPage: 25,
|
||||
};
|
||||
const [filterValues, setFilterValues] = useState(defaultFilterValues);
|
||||
const filtersMeta = [
|
||||
{
|
||||
name: 'patientName',
|
||||
displayName: 'Patient Name',
|
||||
inputType: 'Text',
|
||||
isSortable: true,
|
||||
gridCol: 4,
|
||||
},
|
||||
{
|
||||
name: 'mrn',
|
||||
displayName: 'MRN',
|
||||
inputType: 'Text',
|
||||
isSortable: true,
|
||||
gridCol: 2,
|
||||
},
|
||||
{
|
||||
name: 'studyDate',
|
||||
displayName: 'Study date',
|
||||
inputType: 'DateRange',
|
||||
isSortable: true,
|
||||
gridCol: 5,
|
||||
},
|
||||
{
|
||||
name: 'description',
|
||||
displayName: 'Description',
|
||||
inputType: 'Text',
|
||||
isSortable: true,
|
||||
gridCol: 4,
|
||||
},
|
||||
{
|
||||
name: 'modality',
|
||||
displayName: 'Modality',
|
||||
inputType: 'MultiSelect',
|
||||
inputProps: {
|
||||
options: [
|
||||
{ value: 'SEG', label: 'SEG' },
|
||||
{ value: 'CT', label: 'CT' },
|
||||
{ value: 'MR', label: 'MR' },
|
||||
{ value: 'SR', label: 'SR' },
|
||||
],
|
||||
},
|
||||
isSortable: true,
|
||||
gridCol: 3,
|
||||
},
|
||||
{
|
||||
name: 'accession',
|
||||
displayName: 'Accession',
|
||||
inputType: 'Text',
|
||||
isSortable: true,
|
||||
gridCol: 4,
|
||||
},
|
||||
{
|
||||
name: 'instances',
|
||||
displayName: 'Instances',
|
||||
inputType: 'None',
|
||||
isSortable: true,
|
||||
gridCol: 2,
|
||||
},
|
||||
];
|
||||
const isFiltering = (filterValues, defaultFilterValues) => {
|
||||
return Object.keys(defaultFilterValues).some(name => {
|
||||
return filterValues[name] !== defaultFilterValues[name];
|
||||
});
|
||||
};
|
||||
return (
|
||||
<ModalProvider modal={Modal}>
|
||||
<StudyListFilter
|
||||
numOfStudies={100}
|
||||
filtersMeta={filtersMeta}
|
||||
filterValues={filterValues}
|
||||
onChange={setFilterValues}
|
||||
clearFilters={() => setFilterValues(defaultFilterValues)}
|
||||
isFiltering={isFiltering(filterValues, defaultFilterValues)}
|
||||
/>
|
||||
</ModalProvider>
|
||||
);
|
||||
}
|
||||
```
|
||||
|
||||
## Properties
|
||||
|
||||
<ComponentPropsTable componentName={'StudyListFilter'} />
|
||||
@ -1,46 +0,0 @@
|
||||
---
|
||||
name: Study List Pagination
|
||||
menu: Navigation
|
||||
route: components/studyListPagination
|
||||
---
|
||||
|
||||
import { useState } from 'react';
|
||||
import { ComponentPropsTable } from '../../../../src/components/ComponentPropsTable.jsx';
|
||||
|
||||
import { StudyListPagination } from '@ohif/ui';
|
||||
|
||||
# StudyListPagination
|
||||
|
||||
## Import
|
||||
|
||||
```javascript
|
||||
import { StudyListPagination } from '@ohif/ui';
|
||||
```
|
||||
|
||||
## Basic usage
|
||||
|
||||
```jsx live
|
||||
function() {
|
||||
const [currentPage, setCurrentPage] = useState(1);
|
||||
const [perPage, setPerPage] = useState(25);
|
||||
const onChangePage = page => {
|
||||
setCurrentPage(page);
|
||||
};
|
||||
const onChangePerPage = perPage => {
|
||||
setPerPage(perPage);
|
||||
setCurrentPage(1);
|
||||
};
|
||||
return (
|
||||
<StudyListPagination
|
||||
onChangePage={onChangePage}
|
||||
onChangePerPage={onChangePerPage}
|
||||
currentPage={currentPage}
|
||||
perPage={perPage}
|
||||
/>
|
||||
);
|
||||
}
|
||||
```
|
||||
|
||||
## Properties
|
||||
|
||||
<ComponentPropsTable componentName={'StudyListPagination'} />
|
||||
@ -1,63 +0,0 @@
|
||||
---
|
||||
name: Study List Table
|
||||
menu: Data Display
|
||||
route: components/studyListTable
|
||||
---
|
||||
|
||||
import { useState } from 'react';
|
||||
import { ComponentPropsTable } from '../../../../src/components/ComponentPropsTable.jsx';
|
||||
|
||||
import { StudyListTable } from '@ohif/ui';
|
||||
|
||||
# StudyListTable
|
||||
|
||||
This component is used to display a studies list.
|
||||
|
||||
## Import
|
||||
|
||||
```javascript
|
||||
import { StudyListTable } from '@ohif/ui';
|
||||
```
|
||||
|
||||
## Basic usage
|
||||
|
||||
```jsx live
|
||||
function() {
|
||||
const studies = new Array(10).fill('');
|
||||
const [expandedRows, setExpandedRows] = useState([]);
|
||||
const tableDataSource = studies.map((study, key) => {
|
||||
const rowKey = key + 1;
|
||||
const isExpanded = expandedRows.some(k => k === rowKey);
|
||||
return {
|
||||
row: [
|
||||
{ key: 'Cell 01', content: 'Cell 01', gridCol: 2 },
|
||||
{ key: 'Cell 02', content: 'Cell 02', gridCol: 4 },
|
||||
{ key: 'Cell 03', content: 'Cell 03', gridCol: 4 },
|
||||
{ key: 'Cell 04', content: 'Cell 04', gridCol: 4 },
|
||||
],
|
||||
expandedContent: (
|
||||
<td className="w-full p-8">
|
||||
Custom expanded content for row {rowKey}
|
||||
</td>
|
||||
),
|
||||
onClickRow: () =>
|
||||
setExpandedRows(rows =>
|
||||
isExpanded ? rows.filter(n => rowKey !== n) : [...rows, rowKey]
|
||||
),
|
||||
isExpanded,
|
||||
};
|
||||
});
|
||||
return (
|
||||
<div className="py-4">
|
||||
<StudyListTable
|
||||
tableDataSource={tableDataSource}
|
||||
numOfStudies={studies.length}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
```
|
||||
|
||||
## Properties
|
||||
|
||||
<ComponentPropsTable componentName={'StudyListTable'} />
|
||||
@ -1,78 +0,0 @@
|
||||
---
|
||||
name: Table
|
||||
menu: Data Display
|
||||
route: components/table
|
||||
---
|
||||
|
||||
import { Table, TableHead, TableBody, TableRow, TableCell } from '@ohif/ui';
|
||||
import { ComponentPropsTable } from '../../../../src/components/ComponentPropsTable.jsx';
|
||||
|
||||
# Table
|
||||
|
||||
Tables display sets of data.
|
||||
|
||||
_The Table component and its components in the tree are built using divs._
|
||||
|
||||
## Import
|
||||
|
||||
Check the given example below to see how to import each component to create a
|
||||
table.
|
||||
|
||||
```javascript
|
||||
import { Table, TableBody, TableCell, TableHead, TableRow } from '@ohif/ui';
|
||||
```
|
||||
|
||||
## Basic usage
|
||||
|
||||
```jsx live
|
||||
<div className="p-4">
|
||||
<Table>
|
||||
<TableHead>
|
||||
<TableRow>
|
||||
<TableCell>Item 01</TableCell>
|
||||
<TableCell>Item 02</TableCell>
|
||||
<TableCell>Item 03</TableCell>
|
||||
<TableCell>Item 04</TableCell>
|
||||
</TableRow>
|
||||
</TableHead>
|
||||
<TableBody>
|
||||
{new Array(25).fill('').map(row => (
|
||||
<TableRow>
|
||||
<TableCell>Content 01</TableCell>
|
||||
<TableCell>Content 02</TableCell>
|
||||
<TableCell>Content 03</TableCell>
|
||||
<TableCell>Content 04</TableCell>
|
||||
</TableRow>
|
||||
))}
|
||||
</TableBody>
|
||||
</Table>
|
||||
</div>
|
||||
```
|
||||
|
||||
## Table width
|
||||
|
||||
Table has full width by default. If you want to change its width, you will have
|
||||
to set the `fullWidth` prop to `false` and then define your own table width by
|
||||
passing a `className` or `style`.
|
||||
|
||||
## Properties
|
||||
|
||||
### Table Props
|
||||
|
||||
<ComponentPropsTable componentName={'Table'} />
|
||||
|
||||
### TableHead Props
|
||||
|
||||
<ComponentPropsTable componentName={'TableHead'} />
|
||||
|
||||
### TableBody Props
|
||||
|
||||
<ComponentPropsTable componentName={'TableBody'} />
|
||||
|
||||
### TableRow Props
|
||||
|
||||
<ComponentPropsTable componentName={'TableRow'} />
|
||||
|
||||
### TableCell Props
|
||||
|
||||
<ComponentPropsTable componentName={'TableCell'} />
|
||||
@ -1,40 +0,0 @@
|
||||
---
|
||||
name: Thumbnail
|
||||
menu: General
|
||||
route: components/thumbnail
|
||||
---
|
||||
|
||||
|
||||
import { Thumbnail } from '../';
|
||||
|
||||
# Thumbnail
|
||||
|
||||
Used to expose a display set showing some information about the group of images
|
||||
and a thumbnail
|
||||
|
||||
## Import
|
||||
|
||||
```javascript
|
||||
import { Thumbnail } from '@ohif/ui';
|
||||
```
|
||||
|
||||
## Basic usage
|
||||
|
||||
```jsx live
|
||||
<div className="flex flex-1 items-center justify-center p-4">
|
||||
<div className="w-56">
|
||||
<Thumbnail
|
||||
imageAltText="DisplaySet thumbnail image"
|
||||
description="Multiple line image series description lorem sit"
|
||||
seriesNumber={4}
|
||||
numInstances={902}
|
||||
onClick={() => alert('Thumbnail was clicked!')}
|
||||
isActive={false}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
```
|
||||
|
||||
## Properties
|
||||
|
||||
<ComponentPropsTable componentName={'Thumbnail'} />
|
||||
@ -1,37 +0,0 @@
|
||||
---
|
||||
name: ThumbnailNoImage
|
||||
menu: General
|
||||
route: components/ThumbnailNoImage
|
||||
---
|
||||
|
||||
|
||||
import { ThumbnailNoImage } from '../';
|
||||
|
||||
# ThumbnailNoImage
|
||||
|
||||
Used to expose
|
||||
|
||||
## Import
|
||||
|
||||
```javascript
|
||||
import { Thumbnail } from '@ohif/ui';
|
||||
```
|
||||
|
||||
## Basic usage
|
||||
|
||||
```jsx live
|
||||
<div className="flex flex-1 items-center justify-center p-4">
|
||||
<div className="w-64">
|
||||
<ThumbnailNoImage
|
||||
modality={'SR'}
|
||||
seriesDate="13-Mar-1999"
|
||||
description="Multiple line image series description lorem sit"
|
||||
onClick={() => alert('ThumbnailNoImage was clicked!')}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
```
|
||||
|
||||
## Properties
|
||||
|
||||
<ComponentPropsTable componentName={'ThumbnailNoImage'} />
|
||||
@ -1,40 +0,0 @@
|
||||
---
|
||||
name: ThumbnailTracked
|
||||
menu: General
|
||||
route: components/ThumbnailTracked
|
||||
---
|
||||
|
||||
|
||||
import { ThumbnailTracked } from '../';
|
||||
import { ComponentPropsTable } from '../../../../src/components/ComponentPropsTable.jsx';
|
||||
|
||||
# ThumbnailTracked
|
||||
|
||||
## Import
|
||||
|
||||
```javascript
|
||||
import { ThumbnailTracked } from '@ohif/ui';
|
||||
```
|
||||
|
||||
## Basic usage
|
||||
|
||||
```jsx live
|
||||
<div className="flex flex-1 items-center justify-center p-4">
|
||||
<div className="w-64">
|
||||
<ThumbnailTracked
|
||||
imageAltText="DisplaySet thumbnail image"
|
||||
description="Multiple line image series description lorem sit"
|
||||
seriesNumber={4}
|
||||
numInstances={902}
|
||||
onClick={() => alert('Thumbnail was clicked!')}
|
||||
viewportIdentificator={["A"]}
|
||||
isTracked={true}
|
||||
isActive={false}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
```
|
||||
|
||||
## Properties
|
||||
|
||||
<ComponentPropsTable componentName={'ThumbnailTracked'} />
|
||||
@ -1,47 +0,0 @@
|
||||
---
|
||||
name: Toolbar Button
|
||||
menu: General
|
||||
route: components/toolbarButton
|
||||
---
|
||||
|
||||
import { useState, useCallback } from 'react';
|
||||
import { ComponentPropsTable } from '../../../../src/components/ComponentPropsTable.jsx';
|
||||
|
||||
import { ToolbarButton } from '@ohif/ui';
|
||||
|
||||
# Toolbar Button
|
||||
|
||||
Toolbar Buttons are used to populate the Toolbar.
|
||||
|
||||
## Import
|
||||
|
||||
```javascript
|
||||
import { ToolbarButton } from '@ohif/ui';
|
||||
```
|
||||
|
||||
```jsx live
|
||||
function() {
|
||||
const [isActive, setIsActive] = useState(false);
|
||||
|
||||
const tool = {
|
||||
id: 'Zoom',
|
||||
label: 'Zoom',
|
||||
icon: 'tool-zoom',
|
||||
type: null,
|
||||
/*commandName: 'setToolActive',
|
||||
commandOptions: { toolName: 'Zoom' },*/
|
||||
onInteraction: () => setIsActive(!isActive),
|
||||
isActive,
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="py-10 flex justify-center">
|
||||
<ToolbarButton {...tool} />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
```
|
||||
|
||||
## Properties
|
||||
|
||||
<ComponentPropsTable componentName={'ToolbarButton'} />
|
||||
@ -1,40 +0,0 @@
|
||||
---
|
||||
name: Tooltip
|
||||
menu: Data Display
|
||||
route: components/tooltip
|
||||
---
|
||||
|
||||
import { Tooltip, Typography } from '@ohif/ui';
|
||||
import { ComponentPropsTable } from '../../../../src/components/ComponentPropsTable.jsx';
|
||||
|
||||
# Tooltip
|
||||
|
||||
Tooltips display informative content when users hover over, focus on, or tap an
|
||||
element.
|
||||
|
||||
## Import
|
||||
|
||||
```javascript
|
||||
import { Tooltip } from '@ohif/ui';
|
||||
```
|
||||
|
||||
```jsx live
|
||||
function TooltipExample(props) {
|
||||
const tooltips = ['bottom', 'bottom-left', 'bottom-right', 'left', 'right'];
|
||||
return (
|
||||
<div className="py-10 flex flex-col items-center justify-center">
|
||||
{tooltips.map(tooltip => (
|
||||
<div className="mb-16">
|
||||
<Tooltip content="Tooltip content" position={tooltip}>
|
||||
<Typography>Tooltip {tooltip}</Typography>
|
||||
</Tooltip>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
```
|
||||
|
||||
## Properties
|
||||
|
||||
<ComponentPropsTable componentName={'Tooltip'} />
|
||||
@ -1,29 +0,0 @@
|
||||
---
|
||||
name: TooltipClipboard
|
||||
menu: Data Display
|
||||
route: components/tooltipClipboard
|
||||
---
|
||||
|
||||
import { TooltipClipboard } from '@ohif/ui';
|
||||
import { ComponentPropsTable } from '../../../../src/components/ComponentPropsTable.jsx';
|
||||
|
||||
# Tooltip Clipboard
|
||||
|
||||
Tooltips display informative content when users hover over, focus on, or tap an
|
||||
element.
|
||||
|
||||
## Import
|
||||
|
||||
```javascript
|
||||
import { TooltipClipboard } from '@ohif/ui';
|
||||
```
|
||||
|
||||
```jsx live
|
||||
<div className="p-4">
|
||||
<TooltipClipboard>Text to be copied</TooltipClipboard>
|
||||
</div>
|
||||
```
|
||||
|
||||
## Properties
|
||||
|
||||
<ComponentPropsTable componentName={'TooltipClipboard'} />
|
||||
@ -1,69 +0,0 @@
|
||||
---
|
||||
name: Typography
|
||||
menu: General
|
||||
route: components/typography
|
||||
---
|
||||
|
||||
import { Typography } from '@ohif/ui';
|
||||
import { ComponentPropsTable } from '../../../../src/components/ComponentPropsTable.jsx';
|
||||
|
||||
# Typography
|
||||
|
||||
Use typography to display text using the available props for customizing your
|
||||
content.
|
||||
|
||||
## Import
|
||||
|
||||
```javascript
|
||||
import { Typography } from '@ohif/ui';
|
||||
```
|
||||
|
||||
## Basic usage
|
||||
|
||||
```jsx live
|
||||
<div className="p-4">
|
||||
<Typography variant="h1">
|
||||
h1. The five boxing wizards jump quickly.
|
||||
</Typography>
|
||||
<Typography variant="h2">
|
||||
h2. The five boxing wizards jump quickly.
|
||||
</Typography>
|
||||
<Typography variant="h3">
|
||||
h3. The five boxing wizards jump quickly.
|
||||
</Typography>
|
||||
<Typography variant="h4">
|
||||
h4. The five boxing wizards jump quickly.
|
||||
</Typography>
|
||||
<Typography variant="h5">
|
||||
h5. The five boxing wizards jump quickly.
|
||||
</Typography>
|
||||
<Typography variant="h6">
|
||||
h6. The five boxing wizards jump quickly.
|
||||
</Typography>
|
||||
<Typography variant="subtitle">
|
||||
subtitle. The five boxing wizards jump quickly.
|
||||
</Typography>
|
||||
<Typography variant="body">
|
||||
body. The five boxing wizards jump quickly.
|
||||
</Typography>
|
||||
</div>
|
||||
```
|
||||
|
||||
## Changing the HTML element
|
||||
|
||||
There are different semantic elements to be used in the Typography component.
|
||||
You can use the prop `component` to associate the component to be rendered with
|
||||
a semantic element. The style of a Typography is independent of the semantic
|
||||
element.
|
||||
|
||||
```jsx live
|
||||
<div className="p-4">
|
||||
<Typography variant="h1" component="h2">
|
||||
This is a h2 using the h1 styles.
|
||||
</Typography>
|
||||
</div>
|
||||
```
|
||||
|
||||
## Properties
|
||||
|
||||
<ComponentPropsTable componentName={'Typography'} />
|
||||
@ -1,55 +0,0 @@
|
||||
---
|
||||
name: Viewport
|
||||
menu: Data Display
|
||||
route: components/viewport
|
||||
---
|
||||
|
||||
import { Viewport } from '@ohif/ui';
|
||||
import { ComponentPropsTable } from '../../../../src/components/ComponentPropsTable.jsx';
|
||||
|
||||
# Viewport
|
||||
|
||||
Viewport component to be used in the ViewportGrid.
|
||||
|
||||
## Import
|
||||
|
||||
```javascript
|
||||
import { Viewport } from '@ohif/ui';
|
||||
```
|
||||
|
||||
## Basic usage
|
||||
|
||||
```jsx live
|
||||
<div className="p-4 h-screen">
|
||||
<Viewport
|
||||
viewportIndex={0}
|
||||
onSeriesChange={direction => alert(`Series ${direction}`)}
|
||||
studyData={{
|
||||
label: 'A',
|
||||
isTracked: true,
|
||||
isLocked: false,
|
||||
isRehydratable: false,
|
||||
studyDate: '07-Sep-2011',
|
||||
currentSeries: 1,
|
||||
seriesDescription:
|
||||
'Series description lorem ipsum dolor sit Series description lorem ipsum dolor sit Series description lorem ipsum dolor sit ',
|
||||
modality: 'CT',
|
||||
patientInformation: {
|
||||
patientName: 'Smith, Jane',
|
||||
patientSex: 'F',
|
||||
patientAge: '59',
|
||||
MRN: '10000001',
|
||||
thickness: '5.0mm',
|
||||
spacing: '1.25mm',
|
||||
scanner: 'Aquilion',
|
||||
},
|
||||
}}
|
||||
>
|
||||
<div className="flex justify-center items-center h-full">CONTENT</div>
|
||||
</Viewport>
|
||||
</div>
|
||||
```
|
||||
|
||||
## Properties
|
||||
|
||||
<ComponentPropsTable componentName={'Viewport'} />
|
||||
@ -1,136 +0,0 @@
|
||||
---
|
||||
name: Viewport Action Bar
|
||||
menu: Data Display
|
||||
route: components/viewportActionBar
|
||||
---
|
||||
|
||||
import { ViewportActionBar } from '@ohif/ui';
|
||||
import { ComponentPropsTable } from '../../../../src/components/ComponentPropsTable.jsx';
|
||||
|
||||
# Viewport Action Bar
|
||||
|
||||
Used to display an Action Bar in the viewer.
|
||||
|
||||
## Import
|
||||
|
||||
```javascript
|
||||
import { ViewportActionBar } from '@ohif/ui';
|
||||
```
|
||||
|
||||
## Basic usage
|
||||
|
||||
```jsx live
|
||||
<div className="p-4 h-64">
|
||||
<ViewportActionBar
|
||||
onSeriesChange={direction => alert(`Series ${direction}`)}
|
||||
studyData={{
|
||||
label: 'A',
|
||||
isTracked: true,
|
||||
isLocked: false,
|
||||
isRehydratable: false,
|
||||
studyDate: '07-Sep-2010',
|
||||
currentSeries: 1,
|
||||
seriesDescription:
|
||||
'Series description lorem ipsum dolor sit Series description lorem ipsum dolor sit Series description lorem ipsum dolor sit ',
|
||||
modality: 'CT',
|
||||
patientInformation: {
|
||||
patientName: 'Smith, Jane',
|
||||
patientSex: 'F',
|
||||
patientAge: '59',
|
||||
MRN: '10000001',
|
||||
thickness: '2.0mm',
|
||||
spacing: '1.25mm',
|
||||
scanner: 'Aquilion',
|
||||
},
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
```
|
||||
|
||||
```jsx live
|
||||
<div className="p-4 h-64">
|
||||
<ViewportActionBar
|
||||
onSeriesChange={direction => alert(`Series ${direction}`)}
|
||||
studyData={{
|
||||
label: 'A',
|
||||
isTracked: false,
|
||||
isLocked: false,
|
||||
isRehydratable: true,
|
||||
studyDate: '07-Sep-2010',
|
||||
currentSeries: 1,
|
||||
seriesDescription:
|
||||
'Series description lorem ipsum dolor sit Series description lorem ipsum dolor sit Series description lorem ipsum dolor sit ',
|
||||
modality: 'CT',
|
||||
patientInformation: {
|
||||
patientName: 'Smith, Jane',
|
||||
patientSex: 'F',
|
||||
patientAge: '59',
|
||||
MRN: '10000001',
|
||||
thickness: '2.0mm',
|
||||
spacing: '1.25mm',
|
||||
scanner: 'Aquilion',
|
||||
},
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
```
|
||||
|
||||
```jsx live
|
||||
<div className="p-4 h-64">
|
||||
<ViewportActionBar
|
||||
onSeriesChange={direction => alert(`Series ${direction}`)}
|
||||
studyData={{
|
||||
label: 'A',
|
||||
isTracked: false,
|
||||
isLocked: false,
|
||||
isRehydratable: false,
|
||||
studyDate: '07-Sep-2010',
|
||||
currentSeries: 1,
|
||||
seriesDescription:
|
||||
'Series description lorem ipsum dolor sit Series description lorem ipsum dolor sit Series description lorem ipsum dolor sit ',
|
||||
modality: 'SR',
|
||||
patientInformation: {
|
||||
patientName: 'Smith, Jane',
|
||||
patientSex: 'F',
|
||||
patientAge: '59',
|
||||
MRN: '10000001',
|
||||
thickness: '2.0mm',
|
||||
spacing: '1.25mm',
|
||||
scanner: 'Aquilion',
|
||||
},
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
```
|
||||
|
||||
```jsx live
|
||||
<div className="p-4 h-64">
|
||||
<ViewportActionBar
|
||||
onSeriesChange={direction => alert(`Series ${direction}`)}
|
||||
studyData={{
|
||||
label: 'A',
|
||||
isTracked: false,
|
||||
isLocked: false,
|
||||
isRehydratable: true,
|
||||
studyDate: '07-Sep-2010',
|
||||
currentSeries: 1,
|
||||
seriesDescription:
|
||||
'Series description lorem ipsum dolor sit Series description lorem ipsum dolor sit Series description lorem ipsum dolor sit ',
|
||||
modality: 'SR',
|
||||
patientInformation: {
|
||||
patientName: 'Smith, Jane',
|
||||
patientSex: 'F',
|
||||
patientAge: '59',
|
||||
MRN: '10000001',
|
||||
thickness: '2.0mm',
|
||||
spacing: '1.25mm',
|
||||
scanner: 'Aquilion',
|
||||
},
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
```
|
||||
|
||||
## Properties
|
||||
|
||||
<ComponentPropsTable componentName={'ViewportActionBar'} />
|
||||
@ -1,39 +0,0 @@
|
||||
---
|
||||
name: ViewportGrid
|
||||
menu: General
|
||||
route: components/viewportGrid
|
||||
---
|
||||
|
||||
import { DragAndDropProvider, ViewportGrid } from '@ohif/ui';
|
||||
import { ComponentPropsTable } from '../../../../src/components/ComponentPropsTable.jsx';
|
||||
|
||||
# ViewportGrid
|
||||
|
||||
Used to display viewports in the viewer page.
|
||||
|
||||
## Import
|
||||
|
||||
```javascript
|
||||
import { ViewportGrid } from '@ohif/ui';
|
||||
```
|
||||
|
||||
## Basic usage
|
||||
|
||||
```jsx live
|
||||
<DragAndDropProvider>
|
||||
<div className="p-4 h-56">
|
||||
<ViewportGrid numRows={1} numCols={2}>
|
||||
<div className="flex items-center justify-center h-full text-white">
|
||||
Viewport1
|
||||
</div>
|
||||
<div className="flex items-center justify-center h-full text-white">
|
||||
Viewport2
|
||||
</div>
|
||||
</ViewportGrid>
|
||||
</div>
|
||||
</DragAndDropProvider>
|
||||
```
|
||||
|
||||
## Properties
|
||||
|
||||
<ComponentPropsTable componentName={'ViewportGrid'} />
|
||||
@ -1,36 +0,0 @@
|
||||
---
|
||||
name: ViewportPane
|
||||
menu: General
|
||||
route: components/viewport-pane
|
||||
---
|
||||
|
||||
|
||||
import { ViewportGrid, ViewportPane, DragAndDropProvider } from '@ohif/ui';
|
||||
import { ComponentPropsTable } from '../../../../src/components/ComponentPropsTable.jsx';
|
||||
|
||||
# ViewportPane
|
||||
|
||||
Used to display viewports in the viewer page.
|
||||
|
||||
## Import
|
||||
|
||||
```javascript
|
||||
import { ViewportPane } from '@ohif/ui';
|
||||
```
|
||||
|
||||
## Basic usage
|
||||
|
||||
```jsx live
|
||||
<div className="p-4 h-56">
|
||||
<DragAndDropProvider>
|
||||
<ViewportGrid numRows={1} numCols={2}>
|
||||
<ViewportPane onDrop={() => {}} isActive={true}><h3>Hello</h3></ViewportPane>
|
||||
<ViewportPane onDrop={() => {}} isActive={false}><h3>World</h3></ViewportPane>
|
||||
</ViewportGrid>
|
||||
</DragAndDropProvider>
|
||||
</div>
|
||||
```
|
||||
|
||||
## Properties
|
||||
|
||||
<ComponentPropsTable componentName={'ViewportPane'} />
|
||||
@ -1,34 +0,0 @@
|
||||
---
|
||||
name: Window Level Menu Item
|
||||
menu: General
|
||||
route: components/windowLevelMenuItem
|
||||
---
|
||||
|
||||
import { useState } from 'react';
|
||||
import { ComponentPropsTable } from '../../../../src/components/ComponentPropsTable.jsx';
|
||||
|
||||
import { ListMenu, WindowLevelMenuItem } from '@ohif/ui';
|
||||
|
||||
# Window Level Menu Item
|
||||
|
||||
Window Level Menu Item are used as renderer of the ListMenu.
|
||||
|
||||
## Import
|
||||
|
||||
```javascript
|
||||
import { WindowLevelMenuItem, ListMenu } from '@ohif/ui';
|
||||
```
|
||||
|
||||
```jsx live
|
||||
function() {
|
||||
return (
|
||||
<div className="py-10 flex justify-center">
|
||||
<ListMenu renderer={WindowLevelMenuItem} items={[]} />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
```
|
||||
|
||||
## Properties
|
||||
|
||||
<ComponentPropsTable componentName={'WindowLevelMenuItem'} />
|
||||
@ -1,4 +0,0 @@
|
||||
{
|
||||
"label": "Components",
|
||||
"position": 5
|
||||
}
|
||||
@ -1,50 +0,0 @@
|
||||
---
|
||||
name: Icon
|
||||
menu: General
|
||||
route: components/icon
|
||||
---
|
||||
|
||||
import { Icon, ICONS } from '@ohif/ui';
|
||||
import { ComponentPropsTable } from '../../../../src/components/ComponentPropsTable.jsx';
|
||||
|
||||
# Icon
|
||||
|
||||
## Import
|
||||
|
||||
```javascript
|
||||
import { Icon } from '@ohif/ui';
|
||||
```
|
||||
|
||||
## Basic usage
|
||||
|
||||
```jsx live
|
||||
<div className="p-4">
|
||||
<Icon name="series-active" className="text-primary-light m-4" />
|
||||
</div>
|
||||
```
|
||||
|
||||
## All Icons
|
||||
|
||||
<div className="p-4 flex flex-wrap items-center bg-black py-8">
|
||||
{Object.keys(ICONS)
|
||||
.sort()
|
||||
.map((name, i) => {
|
||||
return (
|
||||
<React.Fragment key={i}>
|
||||
<div className="flex flex-col items-center w-48 py-4">
|
||||
<div className="flex items-center justify-center rounded border border-primary-light p-4 m-2 w-20 h-20">
|
||||
<Icon name={name} className="text-primary-light w-6" />
|
||||
</div>
|
||||
<div className="break-normal text-white">{name}</div>
|
||||
</div>
|
||||
</React.Fragment>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
|
||||
## Properties
|
||||
|
||||
<ComponentPropsTable componentName={'Icon'} />
|
||||
|
||||
The `Icon` component takes a single prop of `name`, which indicates which Icon
|
||||
should be displayed. The icon inherit the component text/font styles.
|
||||
@ -1,117 +0,0 @@
|
||||
---
|
||||
name: ModalProvider
|
||||
route: customHooks/modalProvider
|
||||
---
|
||||
|
||||
import { ModalComponent, ModalProvider } from '@ohif/ui';
|
||||
|
||||
# Modal Context Provider
|
||||
|
||||
This is a context provider that allow the application to share the modal
|
||||
component across all application.
|
||||
|
||||
## ModalProvider
|
||||
|
||||
Properties:
|
||||
|
||||
<Props of={ModalProvider} />
|
||||
|
||||
Usage example:
|
||||
|
||||
```javascript
|
||||
import { ModalProvider } from '@ohif/ui';
|
||||
import YourModalComponent from 'your-modal-component';
|
||||
|
||||
const App = () => {
|
||||
return (
|
||||
<ModalProvider modal={YourModalComponent}>
|
||||
/** You app content */
|
||||
</ModalComponent>;
|
||||
)
|
||||
};
|
||||
|
||||
export default App;
|
||||
```
|
||||
|
||||
## useModal
|
||||
|
||||
Used for React Functional Components. Should be used in the body of the
|
||||
functional component to get access to the context together with the `show/hide`
|
||||
functions.
|
||||
|
||||
Usage example:
|
||||
|
||||
```javascript
|
||||
import { withModal } from '@ohif/ui';
|
||||
|
||||
const SampleComponent = () => {
|
||||
const { show, hide } = useModal();
|
||||
|
||||
const openModal = () => {
|
||||
show({
|
||||
content: <div> Modal Content </div>,
|
||||
title: 'Modal title',
|
||||
});
|
||||
}
|
||||
|
||||
const closeModal = () => {
|
||||
hide();
|
||||
}
|
||||
|
||||
return (
|
||||
<button onClick={openModal}>
|
||||
Open modal
|
||||
</button>
|
||||
<button onClick={closeModal}>
|
||||
Close modal
|
||||
</button>
|
||||
);
|
||||
};
|
||||
|
||||
export default SampleComponent;
|
||||
```
|
||||
|
||||
## withModal
|
||||
|
||||
Used for React Class Components. This function show receive a Component as a
|
||||
property and this component will have access to the context through its own
|
||||
properties.
|
||||
|
||||
Usage example:
|
||||
|
||||
```javascript
|
||||
import { withModal } from '@ohif/ui';
|
||||
import React from 'react';
|
||||
|
||||
class SampleComponent extends React.Component {
|
||||
openModal() {
|
||||
this.props.modal.show({
|
||||
content: <div> Modal Content </div>,
|
||||
title: 'Modal title',
|
||||
});
|
||||
}
|
||||
|
||||
closeModal() = {
|
||||
this.props.modal.hide();
|
||||
}
|
||||
|
||||
render() {
|
||||
return (
|
||||
<button onClick={this.openModal}>
|
||||
Open modal
|
||||
</button>
|
||||
<button onClick={this.closeModal}>
|
||||
Close modal
|
||||
</button>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default withModal(SampleComponent);
|
||||
```
|
||||
|
||||
## Modal Properties
|
||||
|
||||
The Modal Properties that can be override are:
|
||||
|
||||
<Props of={ModalComponent} />
|
||||
@ -1,185 +0,0 @@
|
||||
---
|
||||
name: ViewportDialogProvider
|
||||
route: customHooks/viewportDialogProvider
|
||||
---
|
||||
|
||||
<!-- This is a workaround to import things from ohif/core as docz does not allow us to access window element and @ohif/core does use it once we import to instanciate cornerstone -->
|
||||
<!-- import UIViewportDialogService from './../../../core/src/services/UIViewportDialogService';
|
||||
import ServicesManager from './../../../core/src/services/ServicesManager'; !-->
|
||||
|
||||
import {
|
||||
Dialog,
|
||||
Button,
|
||||
Notification,
|
||||
ViewportDialogProvider,
|
||||
useViewportDialog,
|
||||
} from '@ohif/ui';
|
||||
|
||||
# Viewport Dialog Provider
|
||||
|
||||
This is a context provider that allow the application to share the modal
|
||||
component across all application.
|
||||
|
||||
## Sample
|
||||
|
||||
```jsx live
|
||||
function() {
|
||||
const ViewportNotification = ({ hide }) => {
|
||||
return (
|
||||
<Notification
|
||||
message="Track all measurement for this series?"
|
||||
type="info"
|
||||
actions={[
|
||||
{
|
||||
type: 'cancel',
|
||||
text: 'No',
|
||||
value: 0,
|
||||
},
|
||||
{
|
||||
type: 'secondary',
|
||||
text: 'No, do not ask again',
|
||||
value: -1,
|
||||
},
|
||||
{
|
||||
type: 'primary',
|
||||
text: 'Yes',
|
||||
value: 1,
|
||||
},
|
||||
]}
|
||||
onSubmit={value => {
|
||||
if (typeof window !== 'undefined') {
|
||||
window.alert(value);
|
||||
}
|
||||
}}
|
||||
/>
|
||||
);
|
||||
};
|
||||
const ViewportActionButtons = () => {
|
||||
const [dialogState, dialogApi] = useViewportDialog();
|
||||
return (
|
||||
<Button onClick={() => dialogApi.show({ content: ViewportNotification })}>
|
||||
Open Dialog
|
||||
</Button>
|
||||
);
|
||||
};
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="w-full flex flex-row p-4" style={{height: '400px'}}>
|
||||
<div className="flex flex-1 items-center justify-center h-full w-full bg-black text-white border border-primary-main">
|
||||
<ViewportDialogProvider dialog={Dialog}>
|
||||
<div className="flex flex-1 flex-col items-center justify-center h-full">
|
||||
<ViewportActionButtons />
|
||||
<span>CONTENT 1</span>
|
||||
</div>
|
||||
</ViewportDialogProvider>
|
||||
</div>
|
||||
<div className="flex flex-1 items-center justify-center h-full w-full bg-black text-white border border-primary-main">
|
||||
<ViewportDialogProvider dialog={Dialog}>
|
||||
<div className="flex flex-1 flex-col items-center justify-center h-full">
|
||||
<ViewportActionButtons />
|
||||
<span>CONTENT 1</span>
|
||||
</div>
|
||||
</ViewportDialogProvider>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}}
|
||||
```
|
||||
|
||||
## Example using UIViewportDialogService
|
||||
|
||||
```jsx live
|
||||
function() {
|
||||
const ViewportNotification = ({ hide }) => {
|
||||
return (
|
||||
<Notification
|
||||
message="Track all measurement for this series?"
|
||||
type="info"
|
||||
actions={[
|
||||
{
|
||||
type: 'cancel',
|
||||
text: 'No',
|
||||
value: 0,
|
||||
},
|
||||
{
|
||||
type: 'secondary',
|
||||
text: 'No, do not ask again',
|
||||
value: -1,
|
||||
},
|
||||
{
|
||||
type: 'primary',
|
||||
text: 'Yes',
|
||||
value: 1,
|
||||
},
|
||||
]}
|
||||
onSubmit={value => {
|
||||
if (typeof window !== 'undefined') {
|
||||
window.alert(value);
|
||||
}
|
||||
}}
|
||||
/>
|
||||
);
|
||||
};
|
||||
// Creating servicesManager and register services should be in the root of your app
|
||||
const servicesManager = new ServicesManager();
|
||||
servicesManager.registerServices([UIViewportDialogService]);
|
||||
// Get service instance
|
||||
const _UIViewportDialogService =
|
||||
servicesManager.services.UIViewportDialogService;
|
||||
console.log(_UIViewportDialogService);
|
||||
return (
|
||||
<div className="w-full flex flex-col p-4" style={{height: '400px'}}>
|
||||
<div className="flex flex-2">
|
||||
<Button
|
||||
className="mr-4 mb-4"
|
||||
onClick={() =>
|
||||
_UIViewportDialogService.show({
|
||||
content: ViewportNotification,
|
||||
viewportIndex: 0,
|
||||
})
|
||||
}
|
||||
>
|
||||
Open dialog on 0
|
||||
</Button>
|
||||
<Button
|
||||
className="mr-4 mb-4"
|
||||
onClick={() =>
|
||||
_UIViewportDialogService.show({
|
||||
content: ViewportNotification,
|
||||
viewportIndex: 1,
|
||||
})
|
||||
}
|
||||
>
|
||||
Open dialog on 1
|
||||
</Button>
|
||||
</div>
|
||||
<div className="flex flex-1 w-full flex-row">
|
||||
<ViewportDialogProvider
|
||||
dialog={Dialog}
|
||||
service={_UIViewportDialogService}
|
||||
viewportIndex={0}
|
||||
>
|
||||
<div className="flex flex-1 items-center justify-center h-full bg-black text-white border border-primary-main">
|
||||
CONTENT 0
|
||||
</div>
|
||||
</ViewportDialogProvider>
|
||||
<ViewportDialogProvider
|
||||
dialog={Dialog}
|
||||
service={_UIViewportDialogService}
|
||||
viewportIndex={1}
|
||||
>
|
||||
<div className="flex flex-1 items-center justify-center h-full bg-black text-white border border-primary-main">
|
||||
CONTENT 1
|
||||
</div>
|
||||
</ViewportDialogProvider>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}}
|
||||
```
|
||||
|
||||
## Properties:
|
||||
|
||||
<Props of={ViewportDialogProvider} />
|
||||
````
|
||||
@ -1,178 +0,0 @@
|
||||
---
|
||||
name: ViewportDialogProvider
|
||||
route: customHooks/viewportDialogProvider
|
||||
---
|
||||
|
||||
|
||||
|
||||
<!-- This is a workaround to import things from ohif/core as docz does not allow us to access window element and @ohif/core does use it once we import to instanciate cornerstone -->
|
||||
import UIViewportDialogService from './../../../core/src/services/UIViewportDialogService';
|
||||
import ServicesManager from './../../../core/src/services/ServicesManager';
|
||||
|
||||
import { Dialog, Button, Notification, ViewportDialogProvider, useViewportDialog } from '@ohif/ui';
|
||||
|
||||
# Viewport Dialog Provider
|
||||
|
||||
This is a context provider that allow the application to share the modal
|
||||
component across all application.
|
||||
|
||||
## Sample
|
||||
|
||||
```jsx live
|
||||
{() => {
|
||||
const ViewportNotification = ({ hide }) => {
|
||||
return (
|
||||
<Notification
|
||||
message="Track all measurement for this series?"
|
||||
type="info"
|
||||
actions={[
|
||||
{
|
||||
type: 'cancel',
|
||||
text: 'No',
|
||||
value: 0,
|
||||
},
|
||||
{
|
||||
type: 'secondary',
|
||||
text: 'No, do not ask again',
|
||||
value: -1,
|
||||
},
|
||||
{
|
||||
type: 'primary',
|
||||
text: 'Yes',
|
||||
value: 1,
|
||||
},
|
||||
]}
|
||||
onSubmit={value => {
|
||||
if (typeof window !== 'undefined') {
|
||||
window.alert(value);
|
||||
}
|
||||
}}
|
||||
/>
|
||||
);
|
||||
};
|
||||
const ViewportActionButtons = () => {
|
||||
const [dialogState, dialogApi] = useViewportDialog();
|
||||
return (
|
||||
<Button onClick={() => dialogApi.show({ content: ViewportNotification })}>
|
||||
Open Dialog
|
||||
</Button>
|
||||
);
|
||||
};
|
||||
return (
|
||||
<div className="w-full flex flex-row p-4" style={{height: '400px'}}>
|
||||
<div className="flex flex-1 items-center justify-center h-full w-full bg-black text-white border border-primary-main">
|
||||
<ViewportDialogProvider dialog={Dialog}>
|
||||
<div className="flex flex-1 flex-col items-center justify-center h-full">
|
||||
<ViewportActionButtons />
|
||||
<span>CONTENT 1</span>
|
||||
</div>
|
||||
</ViewportDialogProvider>
|
||||
</div>
|
||||
<div className="flex flex-1 items-center justify-center h-full w-full bg-black text-white border border-primary-main">
|
||||
<ViewportDialogProvider dialog={Dialog}>
|
||||
<div className="flex flex-1 flex-col items-center justify-center h-full">
|
||||
<ViewportActionButtons />
|
||||
<span>CONTENT 1</span>
|
||||
</div>
|
||||
</ViewportDialogProvider>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}}
|
||||
```
|
||||
|
||||
## Example using UIViewportDialogService
|
||||
|
||||
```jsx live
|
||||
{() => {
|
||||
const ViewportNotification = ({ hide }) => {
|
||||
return (
|
||||
<Notification
|
||||
message="Track all measurement for this series?"
|
||||
type="info"
|
||||
actions={[
|
||||
{
|
||||
type: 'cancel',
|
||||
text: 'No',
|
||||
value: 0,
|
||||
},
|
||||
{
|
||||
type: 'secondary',
|
||||
text: 'No, do not ask again',
|
||||
value: -1,
|
||||
},
|
||||
{
|
||||
type: 'primary',
|
||||
text: 'Yes',
|
||||
value: 1,
|
||||
},
|
||||
]}
|
||||
onSubmit={value => {
|
||||
if (typeof window !== 'undefined') {
|
||||
window.alert(value);
|
||||
}
|
||||
}}
|
||||
/>
|
||||
);
|
||||
};
|
||||
// Creating servicesManager and register services should be in the root of your app
|
||||
const servicesManager = new ServicesManager();
|
||||
servicesManager.registerServices([UIViewportDialogService]);
|
||||
// Get service instance
|
||||
const _UIViewportDialogService =
|
||||
servicesManager.services.UIViewportDialogService;
|
||||
console.log(_UIViewportDialogService);
|
||||
return (
|
||||
<div className="w-full flex flex-col p-4" style={{height: '400px'}}>
|
||||
<div className="flex flex-2">
|
||||
<Button
|
||||
className="mr-4 mb-4"
|
||||
onClick={() =>
|
||||
_UIViewportDialogService.show({
|
||||
content: ViewportNotification,
|
||||
viewportIndex: 0,
|
||||
})
|
||||
}
|
||||
>
|
||||
Open dialog on 0
|
||||
</Button>
|
||||
<Button
|
||||
className="mr-4 mb-4"
|
||||
onClick={() =>
|
||||
_UIViewportDialogService.show({
|
||||
content: ViewportNotification,
|
||||
viewportIndex: 1,
|
||||
})
|
||||
}
|
||||
>
|
||||
Open dialog on 1
|
||||
</Button>
|
||||
</div>
|
||||
<div className="flex flex-1 w-full flex-row">
|
||||
<ViewportDialogProvider
|
||||
dialog={Dialog}
|
||||
service={_UIViewportDialogService}
|
||||
viewportIndex={0}
|
||||
>
|
||||
<div className="flex flex-1 items-center justify-center h-full bg-black text-white border border-primary-main">
|
||||
CONTENT 0
|
||||
</div>
|
||||
</ViewportDialogProvider>
|
||||
<ViewportDialogProvider
|
||||
dialog={Dialog}
|
||||
service={_UIViewportDialogService}
|
||||
viewportIndex={1}
|
||||
>
|
||||
<div className="flex flex-1 items-center justify-center h-full bg-black text-white border border-primary-main">
|
||||
CONTENT 1
|
||||
</div>
|
||||
</ViewportDialogProvider>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}}
|
||||
```
|
||||
|
||||
## Properties:
|
||||
|
||||
<Props of={ViewportDialogProvider} />
|
||||
@ -1,4 +0,0 @@
|
||||
{
|
||||
"label": "Context Providers",
|
||||
"position": 5
|
||||
}
|
||||
@ -1,345 +0,0 @@
|
||||
---
|
||||
name: Study List
|
||||
menu: Views
|
||||
route: examples/studyList
|
||||
---
|
||||
|
||||
import { useState } from 'react';
|
||||
import {
|
||||
Icon,
|
||||
StudyListExpandedRow,
|
||||
Button,
|
||||
NavBar,
|
||||
Svg,
|
||||
IconButton,
|
||||
EmptyStudies,
|
||||
StudyListTable,
|
||||
StudyListPagination,
|
||||
StudyListFilter,
|
||||
} from '@ohif/ui';
|
||||
import utils from '../../../../src/utils';
|
||||
|
||||
import classnames from 'classnames';
|
||||
import moment from 'moment';
|
||||
|
||||
# Study List
|
||||
|
||||
This example shows you how you can build a Study List page using the available
|
||||
components.
|
||||
|
||||
```jsx live
|
||||
function () {
|
||||
const defaultFilterValues = {
|
||||
patientName: '',
|
||||
mrn: '',
|
||||
studyDate: {
|
||||
startDate: null,
|
||||
endDate: null,
|
||||
},
|
||||
description: '',
|
||||
modality: undefined,
|
||||
accession: '',
|
||||
sortBy: '',
|
||||
sortDirection: 'none',
|
||||
page: 0,
|
||||
resultsPerPage: 25,
|
||||
};
|
||||
const [filterValues, setFilterValues] = useState(defaultFilterValues);
|
||||
const [studies, setStudies] = useState([]);
|
||||
const numOfStudies = studies.length;
|
||||
const [expandedRows, setExpandedRows] = useState([]);
|
||||
const filtersMeta = [
|
||||
{
|
||||
name: 'patientName',
|
||||
displayName: 'Patient Name',
|
||||
inputType: 'Text',
|
||||
isSortable: true,
|
||||
gridCol: 4,
|
||||
},
|
||||
{
|
||||
name: 'mrn',
|
||||
displayName: 'MRN',
|
||||
inputType: 'Text',
|
||||
isSortable: true,
|
||||
gridCol: 2,
|
||||
},
|
||||
{
|
||||
name: 'studyDate',
|
||||
displayName: 'Study date',
|
||||
inputType: 'DateRange',
|
||||
isSortable: true,
|
||||
gridCol: 5,
|
||||
},
|
||||
{
|
||||
name: 'description',
|
||||
displayName: 'Description',
|
||||
inputType: 'Text',
|
||||
isSortable: true,
|
||||
gridCol: 4,
|
||||
},
|
||||
{
|
||||
name: 'modality',
|
||||
displayName: 'Modality',
|
||||
inputType: 'MultiSelect',
|
||||
inputProps: {
|
||||
options: [
|
||||
{ value: 'SEG', label: 'SEG' },
|
||||
{ value: 'CT', label: 'CT' },
|
||||
{ value: 'MR', label: 'MR' },
|
||||
{ value: 'SR', label: 'SR' },
|
||||
],
|
||||
},
|
||||
isSortable: true,
|
||||
gridCol: 3,
|
||||
},
|
||||
{
|
||||
name: 'accession',
|
||||
displayName: 'Accession',
|
||||
inputType: 'Text',
|
||||
isSortable: true,
|
||||
gridCol: 4,
|
||||
},
|
||||
{
|
||||
name: 'instances',
|
||||
displayName: 'Instances',
|
||||
inputType: 'None',
|
||||
isSortable: true,
|
||||
gridCol: 2,
|
||||
},
|
||||
];
|
||||
const isFiltering = (filterValues, defaultFilterValues) => {
|
||||
return Object.keys(defaultFilterValues).some(name => {
|
||||
return filterValues[name] !== defaultFilterValues[name];
|
||||
});
|
||||
};
|
||||
const tableDataSource = studies.map((study, key) => {
|
||||
const rowKey = key + 1;
|
||||
const isExpanded = expandedRows.some(k => k === rowKey);
|
||||
const {
|
||||
AccessionNumber,
|
||||
Modalities,
|
||||
Instances,
|
||||
StudyDescription,
|
||||
PatientId,
|
||||
PatientName,
|
||||
StudyDate,
|
||||
series,
|
||||
} = study;
|
||||
const seriesTableColumns = {
|
||||
description: 'Description',
|
||||
seriesNumber: 'Series',
|
||||
modality: 'Modality',
|
||||
Instances: 'Instances',
|
||||
};
|
||||
const seriesTableDataSource = series.map(seriesItem => {
|
||||
const { SeriesNumber, Modality, instances } = seriesItem;
|
||||
return {
|
||||
description: 'Patient Protocol',
|
||||
seriesNumber: SeriesNumber,
|
||||
modality: Modality,
|
||||
Instances: instances.length,
|
||||
};
|
||||
});
|
||||
return {
|
||||
row: [
|
||||
{
|
||||
key: 'patientName',
|
||||
content: PatientName,
|
||||
gridCol: 4,
|
||||
},
|
||||
{
|
||||
key: 'mrn',
|
||||
content: PatientId,
|
||||
gridCol: 2,
|
||||
},
|
||||
{
|
||||
key: 'studyDate',
|
||||
content: (
|
||||
<div>
|
||||
<span className="mr-4">
|
||||
{moment(StudyDate).format('MMM-DD-YYYY')}
|
||||
</span>
|
||||
<span>{moment(StudyDate).format('hh:mm A')}</span>
|
||||
</div>
|
||||
),
|
||||
gridCol: 5,
|
||||
},
|
||||
{
|
||||
key: 'description',
|
||||
content: StudyDescription,
|
||||
gridCol: 4,
|
||||
},
|
||||
{
|
||||
key: 'modality',
|
||||
content: Modalities,
|
||||
gridCol: 3,
|
||||
},
|
||||
{
|
||||
key: 'accession',
|
||||
content: AccessionNumber,
|
||||
gridCol: 4,
|
||||
},
|
||||
{
|
||||
key: 'instances',
|
||||
content: (
|
||||
<>
|
||||
<Icon
|
||||
name="group-layers"
|
||||
className={classnames('inline-flex mr-2 w-4', {
|
||||
'text-primary-active': isExpanded,
|
||||
'text-secondary-light': !isExpanded,
|
||||
})}
|
||||
/>
|
||||
{Instances}
|
||||
</>
|
||||
),
|
||||
gridCol: 4,
|
||||
},
|
||||
],
|
||||
expandedContent: (
|
||||
<StudyListExpandedRow
|
||||
seriesTableColumns={seriesTableColumns}
|
||||
seriesTableDataSource={seriesTableDataSource}
|
||||
>
|
||||
<Button
|
||||
rounded="full"
|
||||
variant="contained"
|
||||
className="mr-4 font-bold"
|
||||
endIcon={
|
||||
<Icon name="launch-arrow" style={{ color: '#21a7c6' }} />
|
||||
}
|
||||
>
|
||||
Basic Viewer
|
||||
</Button>
|
||||
<Button
|
||||
rounded="full"
|
||||
variant="contained"
|
||||
className="mr-4 font-bold"
|
||||
endIcon={
|
||||
<Icon name="launch-arrow" style={{ color: '#21a7c6' }} />
|
||||
}
|
||||
>
|
||||
Segmentation
|
||||
</Button>
|
||||
<Button
|
||||
rounded="full"
|
||||
variant="outlined"
|
||||
endIcon={<Icon name="launch-info" />}
|
||||
className="font-bold"
|
||||
>
|
||||
Module 3
|
||||
</Button>
|
||||
<div className="ml-5 text-lg text-common-bright inline-flex items-center">
|
||||
<Icon
|
||||
name="notificationwarning-diamond"
|
||||
className="mr-2 w-5 h-5"
|
||||
/>
|
||||
Feedback text lorem ipsum dolor sit amet
|
||||
</div>
|
||||
</StudyListExpandedRow>
|
||||
),
|
||||
onClickRow: () =>
|
||||
setExpandedRows(s =>
|
||||
isExpanded ? s.filter(n => rowKey !== n) : [...s, rowKey]
|
||||
),
|
||||
isExpanded,
|
||||
};
|
||||
});
|
||||
const handleStudyList = number => {
|
||||
const studies = utils.getMockedStudies(number);
|
||||
setStudies(studies);
|
||||
setCurrentPage(1);
|
||||
};
|
||||
const [currentPage, setCurrentPage] = useState(1);
|
||||
const [perPage, setPerPage] = useState(25);
|
||||
const totalPages = Math.floor(numOfStudies / perPage);
|
||||
const onChangePage = page => {
|
||||
if (page > totalPages) {
|
||||
return;
|
||||
}
|
||||
setCurrentPage(page);
|
||||
};
|
||||
const onChangePerPage = perPage => {
|
||||
setPerPage(perPage);
|
||||
setCurrentPage(1);
|
||||
};
|
||||
const hasStudies = numOfStudies > 0;
|
||||
return (
|
||||
<div>
|
||||
<div className="bg-white p-4">
|
||||
<Button className="mr-2" onClick={() => handleStudyList(0)}>
|
||||
0 Studies
|
||||
</Button>
|
||||
<Button className="mr-2" onClick={() => handleStudyList(50)}>
|
||||
50 Studies
|
||||
</Button>
|
||||
<Button className="mr-2" onClick={() => handleStudyList(100)}>
|
||||
100 Studies
|
||||
</Button>
|
||||
<Button className="mr-2" onClick={() => handleStudyList(1000)}>
|
||||
1000 Studies
|
||||
</Button>
|
||||
</div>
|
||||
<div
|
||||
className={classnames('bg-black h-full', {
|
||||
'h-screen': !hasStudies,
|
||||
})}
|
||||
>
|
||||
<NavBar className="justify-between border-b-4 border-black" isSticky>
|
||||
<div className="flex items-center">
|
||||
<div className="mx-3">
|
||||
<Svg name="logo-ohif" />
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex items-center">
|
||||
<span className="mr-3 text-common-light text-lg">
|
||||
FOR INVESTIGATIONAL USE ONLY
|
||||
</span>
|
||||
<IconButton
|
||||
variant="text"
|
||||
color="inherit"
|
||||
className="text-primary-active"
|
||||
onClick={() => {}}
|
||||
>
|
||||
<React.Fragment>
|
||||
<Icon name="settings" />
|
||||
<Icon name="chevron-down" />
|
||||
</React.Fragment>
|
||||
</IconButton>
|
||||
</div>
|
||||
</NavBar>
|
||||
<StudyListFilter
|
||||
numOfStudies={numOfStudies}
|
||||
filtersMeta={filtersMeta}
|
||||
filterValues={filterValues}
|
||||
onChange={setFilterValues}
|
||||
clearFilters={() => setFilterValues(defaultFilterValues)}
|
||||
isFiltering={isFiltering(filterValues, defaultFilterValues)}
|
||||
/>
|
||||
{hasStudies ? (
|
||||
<>
|
||||
<StudyListTable
|
||||
tableDataSource={tableDataSource.slice(
|
||||
(currentPage - 1) * perPage,
|
||||
(currentPage - 1) * perPage + perPage
|
||||
)}
|
||||
numOfStudies={numOfStudies}
|
||||
filtersMeta={filtersMeta}
|
||||
/>
|
||||
<StudyListPagination
|
||||
onChangePage={onChangePage}
|
||||
onChangePerPage={onChangePerPage}
|
||||
currentPage={currentPage}
|
||||
perPage={perPage}
|
||||
/>
|
||||
</>
|
||||
) : (
|
||||
<div className="flex flex-col items-center justify-center pt-48">
|
||||
<EmptyStudies />
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
```
|
||||
@ -1,178 +0,0 @@
|
||||
---
|
||||
name: Viewer
|
||||
menu: Views
|
||||
route: examples/viewer
|
||||
---
|
||||
|
||||
import { useState } from 'react';
|
||||
|
||||
import {
|
||||
NavBar,
|
||||
SidePanel,
|
||||
Svg,
|
||||
SegmentationTable,
|
||||
ButtonGroup,
|
||||
Button,
|
||||
Icon,
|
||||
IconButton,
|
||||
StudyBrowser,
|
||||
ViewportActionBar,
|
||||
Notification,
|
||||
Viewport,
|
||||
ViewportGrid,
|
||||
ViewportPane,
|
||||
StudySummary,
|
||||
MeasurementTable,
|
||||
Header,
|
||||
DragAndDropProvider,
|
||||
} from '@ohif/ui';
|
||||
|
||||
import { tabs } from './studyBrowserMockData';
|
||||
|
||||
# Viewer
|
||||
|
||||
```jsx live
|
||||
{() => {
|
||||
const [activeMeasurementItem, setActiveMeasurementItem] = useState(null);
|
||||
const descriptionData = {
|
||||
date: '07-Sep-2010',
|
||||
modality: 'CT',
|
||||
description: 'CHEST/ABD/PELVIS W CONTRAST',
|
||||
};
|
||||
const measurementTableData = {
|
||||
title: 'Measurements',
|
||||
amount: 10,
|
||||
data: new Array(10).fill({}).map((el, i) => ({
|
||||
id: i + 1,
|
||||
label: 'Label short description',
|
||||
displayText: '24.0 x 24.0 mm (S:4, I:22)',
|
||||
isActive: activeMeasurementItem === i + 1,
|
||||
})),
|
||||
onClick: (id) => setActiveMeasurementItem((s) => (s === id ? null : id)),
|
||||
onEdit: (id) => alert(`Edit: ${id}`),
|
||||
};
|
||||
const [activeViewportIndex, setActiveViewportIndex] = useState(0);
|
||||
return (
|
||||
<DragAndDropProvider>
|
||||
<Header />
|
||||
<div
|
||||
className="flex flex-row flex-nowrap items-stretch overflow-hidden w-full"
|
||||
style={{ height: 'calc(100vh - 52px' }}
|
||||
>
|
||||
{/* LEFT SIDEPANELS */}
|
||||
<SidePanel
|
||||
side="left"
|
||||
defaultComponentOpen='studies'
|
||||
childComponents={{
|
||||
iconName: 'group-layers',
|
||||
iconLabel: 'Studies',
|
||||
label: 'Studies',
|
||||
name: 'studies',
|
||||
content: <StudyBrowser tabs={tabs} />
|
||||
}}
|
||||
/>
|
||||
{/* TOOLBAR + GRID */}
|
||||
<div className="flex flex-col flex-1 h-full">
|
||||
<div className="flex flex-2 w-100 border-b border-transparent h-12">
|
||||
{/* <ViewportToolbar /> Secondary Toolbar */}
|
||||
</div>
|
||||
{/* VIEWPORT GRID CONTAINER */}
|
||||
<div className="flex flex-1 h-full overflow-hidden bg-black items-center justify-center pb-2 pt-1">
|
||||
<ViewportGrid numRows={1} numCols={2}>
|
||||
{[0, 1].map(viewportIndex => (
|
||||
<ViewportPane key={viewportIndex} className="m-1" isActive={false} onDrop={() => {}}>
|
||||
<Viewport
|
||||
viewportIndex={viewportIndex}
|
||||
onSeriesChange={(direction) => alert(`Series ${direction}`)}
|
||||
studyData={{
|
||||
label: 'A',
|
||||
isTracked: true,
|
||||
isLocked: false,
|
||||
isRehydratable: false,
|
||||
studyDate: '07-Sep-2011',
|
||||
currentSeries: 1,
|
||||
seriesDescription:
|
||||
'Series description lorem ipsum dolor sit Series description lorem ipsum dolor sit Series description lorem ipsum dolor sit ',
|
||||
modality: 'CT',
|
||||
patientInformation: {
|
||||
patientName: 'Smith, Jane',
|
||||
patientSex: 'F',
|
||||
patientAge: '59',
|
||||
MRN: '10000001',
|
||||
thickness: '5.0mm',
|
||||
spacing: '1.25mm',
|
||||
scanner: 'Aquilion',
|
||||
},
|
||||
}}
|
||||
>
|
||||
<div className="flex justify-center items-center h-full">
|
||||
CONTENT
|
||||
</div>
|
||||
</Viewport>
|
||||
</ViewportPane>)
|
||||
)}
|
||||
</ViewportGrid>
|
||||
</div>
|
||||
</div>
|
||||
<SidePanel
|
||||
side="right"
|
||||
defaultComponentOpen="measurements"
|
||||
childComponents={{
|
||||
iconName: 'list-bullets',
|
||||
iconLabel: 'Measure',
|
||||
label: 'Measurements',
|
||||
name: 'measurements',
|
||||
content: (
|
||||
<>
|
||||
<div className="overflow-x-hidden overflow-y-auto invisible-scrollbar">
|
||||
<StudySummary
|
||||
date={descriptionData.date}
|
||||
modality={descriptionData.modality}
|
||||
description={descriptionData.description}
|
||||
/>
|
||||
<MeasurementTable
|
||||
title="Measurements"
|
||||
amount={measurementTableData.data.length}
|
||||
data={measurementTableData.data}
|
||||
onClick={() => {}}
|
||||
onEdit={id => alert(`Edit: ${id}`)}
|
||||
/>
|
||||
</div>
|
||||
<div className="flex justify-center p-4">
|
||||
<React.Fragment>
|
||||
<ButtonGroup onClick={() => alert('Export')}>
|
||||
<Button
|
||||
className="text-white border-primary-main bg-black text-base py-2 px-2"
|
||||
size="initial"
|
||||
color="inherit"
|
||||
>
|
||||
Export
|
||||
</Button>
|
||||
<IconButton
|
||||
className="bg-black border-primary-main px-2 text-white px-2"
|
||||
color="inherit"
|
||||
size="initial"
|
||||
>
|
||||
<Icon name="arrow-down" />
|
||||
</IconButton>
|
||||
</ButtonGroup>
|
||||
<Button
|
||||
className="text-white border border-primary-main bg-black text-base py-2 px-2 ml-2"
|
||||
variant="outlined"
|
||||
size="initial"
|
||||
color="inherit"
|
||||
onClick={() => alert('Create Report')}
|
||||
>
|
||||
Create Report
|
||||
</Button>
|
||||
</React.Fragment>
|
||||
</div>
|
||||
</>
|
||||
)
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
</DragAndDropProvider>
|
||||
);
|
||||
}}
|
||||
```
|
||||
@ -1,4 +0,0 @@
|
||||
{
|
||||
"label": "Example Views",
|
||||
"position": 6
|
||||
}
|
||||
@ -1,44 +0,0 @@
|
||||
---
|
||||
sidebar_position: 1
|
||||
sidebar_label: Getting Started
|
||||
---
|
||||
|
||||
import { Button } from '@ohif/ui';
|
||||
|
||||
# Getting Started
|
||||
|
||||
`@ohif/ui` is a collection of components and utilities that power OHIF's
|
||||
zero-footprint DICOM viewer.
|
||||
|
||||
It's maintained in a monorepo, in the
|
||||
[OHIF's repository](https://github.com/OHIF/Viewers/).
|
||||
|
||||
## Installation
|
||||
|
||||
Install `@ohif/ui` from your terminal:
|
||||
|
||||
```bash
|
||||
# with npm
|
||||
npm i @ohif/ui --save-exact
|
||||
|
||||
# with yarn
|
||||
yarn add @ohif/ui --exact
|
||||
```
|
||||
|
||||
## Usage
|
||||
|
||||
```javascript
|
||||
// Import and use components
|
||||
import { Button } from '@ohif/ui';
|
||||
```
|
||||
|
||||
```jsx live
|
||||
<div className="p-8">
|
||||
<Button onClick={() => alert('Hello!')}>Click here!</Button>
|
||||
</div>
|
||||
```
|
||||
|
||||
## Examples
|
||||
|
||||
In the **Examples** section you can check many examples on how to build your
|
||||
application using `@ohif/ui` components.
|
||||
@ -258,7 +258,7 @@ differently.
|
||||
<tbody>
|
||||
<tr>
|
||||
<td align="left">
|
||||
<a href="./modules/layout-template.md">
|
||||
<a href="./modules/layout-template">
|
||||
LayoutTemplate (NEW)
|
||||
</a>
|
||||
</td>
|
||||
@ -266,7 +266,7 @@ differently.
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="left">
|
||||
<a href="./modules/data-source.md">
|
||||
<a href="./modules/data-source">
|
||||
DataSource (NEW)
|
||||
</a>
|
||||
</td>
|
||||
@ -274,7 +274,7 @@ differently.
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="left">
|
||||
<a href="./modules/sop-class-handler.md">
|
||||
<a href="./modules/sop-class-handler">
|
||||
SOPClassHandler
|
||||
</a>
|
||||
</td>
|
||||
@ -282,7 +282,7 @@ differently.
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="left">
|
||||
<a href="./modules/panel.md">
|
||||
<a href="./modules/panel">
|
||||
Panel
|
||||
</a>
|
||||
</td>
|
||||
@ -290,7 +290,7 @@ differently.
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="left">
|
||||
<a href="./modules/viewport.md">
|
||||
<a href="./modules/viewport">
|
||||
Viewport
|
||||
</a>
|
||||
</td>
|
||||
@ -298,7 +298,7 @@ differently.
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="left">
|
||||
<a href="./modules/commands.md">
|
||||
<a href="./modules/commands">
|
||||
Commands
|
||||
</a>
|
||||
</td>
|
||||
@ -306,7 +306,7 @@ differently.
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="left">
|
||||
<a href="./modules/toolbar.md">
|
||||
<a href="./modules/toolbar">
|
||||
Toolbar
|
||||
</a>
|
||||
</td>
|
||||
@ -314,7 +314,7 @@ differently.
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="left">
|
||||
<a href="./modules/context.md">
|
||||
<a href="./modules/contextModule">
|
||||
Context
|
||||
</a>
|
||||
</td>
|
||||
@ -322,7 +322,7 @@ differently.
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="left">
|
||||
<a href="./modules/hpModule.md">
|
||||
<a href="./modules/hpModule">
|
||||
HangingProtocol
|
||||
</a>
|
||||
</td>
|
||||
|
||||
@ -2,16 +2,22 @@
|
||||
sidebar_position: 7
|
||||
sidebar_label: Layout Template
|
||||
---
|
||||
|
||||
# Module: Layout Template
|
||||
|
||||
## Overview
|
||||
`LayoutTemplates` are a new concept in v3 that modes use to control the layout of a route.
|
||||
A layout template is a React component that is given a set of managers that define apis to access toolbar state, commands, and hotkeys, as well as props defined by the layout template.
|
||||
|
||||
For instance the default LayoutTemplate takes in leftPanels, rightPanels and viewports as props, which it uses to build its view.
|
||||
`LayoutTemplates` are a new concept in v3 that modes use to control the layout
|
||||
of a route. A layout template is a React component that is given a set of
|
||||
managers that define apis to access toolbar state, commands, and hotkeys, as
|
||||
well as props defined by the layout template.
|
||||
|
||||
In addition, `layout template` has complete control over the structure of the application. You could have tools down the left side, or a strict guided workflow with tools set programmatically, the choice is yours for your use case.
|
||||
For instance the default LayoutTemplate takes in leftPanels, rightPanels and
|
||||
viewports as props, which it uses to build its view.
|
||||
|
||||
In addition, `layout template` has complete control over the structure of the
|
||||
application. You could have tools down the left side, or a strict guided
|
||||
workflow with tools set programmatically, the choice is yours for your use case.
|
||||
|
||||
```jsx
|
||||
const getLayoutTemplateModule = (/* ... */) => [
|
||||
@ -23,28 +29,25 @@ const getLayoutTemplateModule = (/* ... */) => [
|
||||
];
|
||||
```
|
||||
|
||||
The `props` that are passed to `layoutTemplate` are managers and service, along with
|
||||
the defined mode left/right panels, mode's defined viewports and OHIF `ViewportGridComp`.
|
||||
LayoutTemplate leverages extensionManager to grab typed extension module entries:
|
||||
`*.getModuleEntry(id)`
|
||||
The `props` that are passed to `layoutTemplate` are managers and service, along
|
||||
with the defined mode left/right panels, mode's defined viewports and OHIF
|
||||
`ViewportGridComp`. LayoutTemplate leverages extensionManager to grab typed
|
||||
extension module entries: `*.getModuleEntry(id)`
|
||||
|
||||
|
||||
|
||||
|
||||
A simplified code for `Default extention`'s layout template is:
|
||||
A simplified code for `Default extension`'s layout template is:
|
||||
|
||||
```jsx title="extensions/default/src/ViewerLayout/index.jsx"
|
||||
import React from 'react'
|
||||
import { SidePanel } from '@ohif/ui'
|
||||
import React from 'react';
|
||||
import { SidePanel } from '@ohif/ui';
|
||||
|
||||
function Toolbar({ servicesManager }) {
|
||||
const { ToolBarService } = servicesManager.services
|
||||
const { ToolBarService } = servicesManager.services;
|
||||
|
||||
return (
|
||||
<>
|
||||
// ToolBarService.getButtonSection('primary') to get toolbarButtons
|
||||
{toolbarButtons.map((toolDef, index) => {
|
||||
const { id, Component, componentProps } = toolDef
|
||||
const { id, Component, componentProps } = toolDef;
|
||||
return (
|
||||
<Component
|
||||
key={id}
|
||||
@ -52,12 +55,12 @@ function Toolbar({ servicesManager }) {
|
||||
{...componentProps}
|
||||
bState={buttonState}
|
||||
isActive={isActive}
|
||||
onInteraction={(args) => ToolBarService.recordInteraction(args)}
|
||||
onInteraction={args => ToolBarService.recordInteraction(args)}
|
||||
/>
|
||||
)
|
||||
);
|
||||
})}
|
||||
</>
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
function ViewerLayout({
|
||||
@ -72,9 +75,9 @@ function ViewerLayout({
|
||||
viewports,
|
||||
ViewportGridComp,
|
||||
}) {
|
||||
const getPanelData = (id) => {
|
||||
const entry = extensionManager.getModuleEntry(id)
|
||||
const content = entry.component
|
||||
const getPanelData = id => {
|
||||
const entry = extensionManager.getModuleEntry(id);
|
||||
const content = entry.component;
|
||||
|
||||
return {
|
||||
iconName: entry.iconName,
|
||||
@ -82,21 +85,21 @@ function ViewerLayout({
|
||||
label: entry.label,
|
||||
name: entry.name,
|
||||
content,
|
||||
}
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
const getViewportComponentData = (viewportComponent) => {
|
||||
const entry = extensionManager.getModuleEntry(viewportComponent.namespace)
|
||||
const getViewportComponentData = viewportComponent => {
|
||||
const entry = extensionManager.getModuleEntry(viewportComponent.namespace);
|
||||
|
||||
return {
|
||||
component: entry.component,
|
||||
displaySetsToDisplay: viewportComponent.displaySetsToDisplay,
|
||||
}
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
const leftPanelComponents = leftPanels.map(getPanelData)
|
||||
const rightPanelComponents = rightPanels.map(getPanelData)
|
||||
const viewportComponents = viewports.map(getViewportComponentData)
|
||||
const leftPanelComponents = leftPanels.map(getPanelData);
|
||||
const rightPanelComponents = rightPanels.map(getPanelData);
|
||||
const viewportComponents = viewports.map(getViewportComponentData);
|
||||
|
||||
return (
|
||||
<div>
|
||||
@ -125,7 +128,7 @@ function ViewerLayout({
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
);
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
@ -2,12 +2,14 @@
|
||||
sidebar_position: 1
|
||||
sidebar_label: Introduction
|
||||
---
|
||||
|
||||
# Managers
|
||||
|
||||
## Overview
|
||||
|
||||
|
||||
`OHIF` uses `Managers` to accomplish various purposes such as registering new services, dependency injection, and aggregating and exposing `extension` features.
|
||||
`OHIF` uses `Managers` to accomplish various purposes such as registering new
|
||||
services, dependency injection, and aggregating and exposing `extension`
|
||||
features.
|
||||
|
||||
`OHIF-v3` provides the following managers which we will discuss in depth.
|
||||
|
||||
@ -21,7 +23,7 @@ sidebar_label: Introduction
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>
|
||||
<a href="./extension.md">
|
||||
<a href="./extension">
|
||||
Extension Manager
|
||||
</a>
|
||||
</td>
|
||||
@ -31,7 +33,7 @@ sidebar_label: Introduction
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<a href="./service.md">
|
||||
<a href="./service">
|
||||
Services Manager
|
||||
</a>
|
||||
</td>
|
||||
@ -41,7 +43,7 @@ sidebar_label: Introduction
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<a href="./commands.md">
|
||||
<a href="./commands">
|
||||
Commands Manager
|
||||
</a>
|
||||
</td>
|
||||
@ -51,7 +53,7 @@ sidebar_label: Introduction
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<a href="./hotkeys.md">
|
||||
<a href="./hotkeys">
|
||||
Hotkeys Manager
|
||||
</a>
|
||||
</td>
|
||||
@ -62,10 +64,6 @@ sidebar_label: Introduction
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<!--
|
||||
LINKS
|
||||
-->
|
||||
|
||||
@ -99,7 +99,7 @@ export default function mode() {
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="left">
|
||||
<a href="./lifeCycle.md#onModeEnter">
|
||||
<a href="./lifecycle#onModeEnter">
|
||||
onModeEnter
|
||||
</a>
|
||||
</td>
|
||||
@ -107,7 +107,7 @@ export default function mode() {
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="left">
|
||||
<a href="./lifeCycle.md#onModeExit">
|
||||
<a href="./lifecycle#onModeExit">
|
||||
onModeExit
|
||||
</a>
|
||||
</td>
|
||||
@ -139,7 +139,7 @@ export default function mode() {
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="left">
|
||||
<a href="./index.md#consuming-extensions">
|
||||
<a href="./index#consuming-extensions">
|
||||
extensions
|
||||
</a>
|
||||
</td>
|
||||
|
||||
@ -10,9 +10,6 @@ processes:
|
||||
```bash
|
||||
# Static Asset output: For deploying PWAs
|
||||
yarn run build
|
||||
|
||||
# Single `.js` script, for embedding viewer into existing apps
|
||||
yarn run build:package
|
||||
```
|
||||
|
||||
## Progressive Web Application (PWA)
|
||||
|
||||
@ -2,14 +2,16 @@
|
||||
sidebar_position: 1
|
||||
sidebar_label: Introduction
|
||||
---
|
||||
|
||||
# Services
|
||||
|
||||
|
||||
## Overview
|
||||
Services are "concern-specific" code modules that can be consumed across layers. Services provide
|
||||
a set of operations, often tied to some shared state, and are made available to
|
||||
through out the app via the `ServicesManager`. Services are particularly well suited to
|
||||
address [cross-cutting concerns][cross-cutting-concerns].
|
||||
|
||||
Services are "concern-specific" code modules that can be consumed across layers.
|
||||
Services provide a set of operations, often tied to some shared state, and are
|
||||
made available to through out the app via the `ServicesManager`. Services are
|
||||
particularly well suited to address [cross-cutting
|
||||
concerns][cross-cutting-concerns].
|
||||
|
||||
Each service should be:
|
||||
|
||||
@ -17,13 +19,13 @@ Each service should be:
|
||||
- able to fail and/or be removed without breaking the application
|
||||
- completely interchangeable with another module implementing the same interface
|
||||
|
||||
|
||||
> In `OHIF-v3` we have added multiple non-UI services and have introduced **pub/sub** pattern to reduce coupling between layers.
|
||||
> In `OHIF-v3` we have added multiple non-UI services and have introduced
|
||||
> **pub/sub** pattern to reduce coupling between layers.
|
||||
>
|
||||
> [Read more about Pub/Sub](./pubsub.md)
|
||||
|
||||
|
||||
## Services
|
||||
|
||||
The following services is available in the `OHIF-v3`.
|
||||
|
||||
<table>
|
||||
@ -37,7 +39,7 @@ The following services is available in the `OHIF-v3`.
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>
|
||||
<a href="./data/DicomMetadataStore.md">
|
||||
<a href="./data/DicomMetadataStore">
|
||||
DicomMetadataStore (NEW)
|
||||
</a>
|
||||
</td>
|
||||
@ -48,7 +50,7 @@ The following services is available in the `OHIF-v3`.
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<a href="./data/DisplaySetService.md">
|
||||
<a href="./data/DisplaySetService">
|
||||
DisplaySetService (NEW)
|
||||
</a>
|
||||
</td>
|
||||
@ -59,7 +61,7 @@ The following services is available in the `OHIF-v3`.
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<a href="./data/HangingProtocolService.md">
|
||||
<a href="./data/HangingProtocolService">
|
||||
HangingProtocolService (NEW)
|
||||
</a>
|
||||
</td>
|
||||
@ -70,7 +72,7 @@ The following services is available in the `OHIF-v3`.
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<a href="./data/MeasurementService.md">
|
||||
<a href="./data/MeasurementService">
|
||||
MeasurementService (MODIFIED)
|
||||
</a>
|
||||
</td>
|
||||
@ -81,7 +83,7 @@ The following services is available in the `OHIF-v3`.
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<a href="./data/ToolbarService.md">
|
||||
<a href="./data/ToolbarService">
|
||||
ToolBarService (NEW)
|
||||
</a>
|
||||
</td>
|
||||
@ -92,7 +94,7 @@ The following services is available in the `OHIF-v3`.
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<a href="./ui/ViewportGridService.md">
|
||||
<a href="./ui/viewport-grid-service">
|
||||
ViewportGridService (NEW)
|
||||
</a>
|
||||
</td>
|
||||
@ -103,7 +105,7 @@ The following services is available in the `OHIF-v3`.
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<a href="./ui/cine.md">
|
||||
<a href="./ui/cine-service">
|
||||
Cine Service (NEW)
|
||||
</a>
|
||||
</td>
|
||||
@ -114,7 +116,7 @@ The following services is available in the `OHIF-v3`.
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<a href="./ui/ui-dialog-service.md">
|
||||
<a href="./ui/ui-dialog-service">
|
||||
UIDialogService
|
||||
</a>
|
||||
</td>
|
||||
@ -125,7 +127,7 @@ The following services is available in the `OHIF-v3`.
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<a href="./ui/ui-modal-service.md">
|
||||
<a href="./ui/ui-modal-service">
|
||||
UIModalService
|
||||
</a>
|
||||
</td>
|
||||
@ -136,7 +138,7 @@ The following services is available in the `OHIF-v3`.
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<a href="./ui/ui-notification-service.md">
|
||||
<a href="./ui/ui-notification-service">
|
||||
UINotificationService
|
||||
</a>
|
||||
</td>
|
||||
@ -147,7 +149,7 @@ The following services is available in the `OHIF-v3`.
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<a href="./ui/ui-viewport-dialog-service.md">
|
||||
<a href="./ui/ui-viewport-dialog-service">
|
||||
UIViewportDialogService (NEW)
|
||||
</a>
|
||||
</td>
|
||||
@ -159,7 +161,6 @@ The following services is available in the `OHIF-v3`.
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
|
||||
<!--
|
||||
LINKS
|
||||
-->
|
||||
|
||||
8
platform/docs/docs/platform/services/ui/cine-service.md
Normal file
8
platform/docs/docs/platform/services/ui/cine-service.md
Normal file
@ -0,0 +1,8 @@
|
||||
---
|
||||
sidebar_position: 7
|
||||
sidebar_label: CINE Service
|
||||
---
|
||||
|
||||
# CINE Service
|
||||
|
||||
TODO...
|
||||
@ -22,8 +22,8 @@ We maintain the following UI Services:
|
||||
- [UI Modal Service](ui-modal-service.md)
|
||||
- [UI Dialog Service](ui-dialog-service.md)
|
||||
- [UI Viewport Dialog Service](ui-viewport-dialog-service.md)
|
||||
- Cine Service
|
||||
- [Viewport Grid Service](ViewportGridService.md)
|
||||
- [CINE Service](cine-service.md)
|
||||
- [Viewport Grid Service](viewport-grid-service.md)
|
||||
|
||||
<!-- <div style="text-align: center;">
|
||||
<a href="/assets/img/ui-services.png">
|
||||
|
||||
141
platform/docs/docs/release-notes.md
Normal file
141
platform/docs/docs/release-notes.md
Normal file
@ -0,0 +1,141 @@
|
||||
---
|
||||
sidebar_position: 2
|
||||
sidebar_label: Release Notes
|
||||
---
|
||||
|
||||
# Release Notes
|
||||
|
||||
> New `OHIF-v3` architecture has made OHIF a general purpose extensible medical
|
||||
> imaging **platform**, as opposed to a configurable viewer.
|
||||
|
||||
## What's new in `OHIF-v3`
|
||||
|
||||
`OHIF-v3` is our second try for a React-based viewer, and is the third version
|
||||
of our medical image web viewers from the start. The summary of changes include:
|
||||
|
||||
- Addition of workflow modes
|
||||
- Often, medical imaging use cases involves lots of specific workflows that
|
||||
re-use functionalities. We have added the capability of workflow modes, that
|
||||
enable people to customize user interface and configure application for
|
||||
specific workflow.
|
||||
- The idea is to re-use the functionalities that extensions provide and create
|
||||
a workflow. Brain segmentation workflow is different from prostate
|
||||
segmentation in UI for sure; however, they share the segmentation tools that
|
||||
can be re-used.
|
||||
- Our vision is that technical people focus of developing extensions which
|
||||
provides core functionalities, and experts to build modes by picking the
|
||||
appropriate functionalities from each extension.
|
||||
|
||||
* UI has been completely redesigned with modularity and workflow modes in mind.
|
||||
* New UI components have been built with Tailwind CSS
|
||||
* Redux store has been removed from the viewer in favour of services backed by
|
||||
React's Context API
|
||||
|
||||
Below, you can find the gap analysis between the `OHIF-v2` and `OHIF-v3`:
|
||||
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th align="left" width="50%">OHIF-v2 functionalities</th>
|
||||
<th align="center">OHIF-v3</th>
|
||||
<th align="center">Comment</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td align="left">Rendering of 2D images via Cornerstone</td>
|
||||
<td align="center">✅</td>
|
||||
<td align="center"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="left">Study List</td>
|
||||
<td align="center">✅</td>
|
||||
<td align="center"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="left">Series Browser</td>
|
||||
<td align="center">✅</td>
|
||||
<td align="center"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="left">DICOM JSON</td>
|
||||
<td align="center">✅</td>
|
||||
<td align="center"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="left">2D Tools via CornerstoneTools</td>
|
||||
<td align="center">✅</td>
|
||||
<td align="center"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="left">OpenID Connect standard authentication flow for connecting to identity providers</td>
|
||||
<td align="center">✅</td>
|
||||
<td align="center"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="left">Internationalization</td>
|
||||
<td align="center">✅</td>
|
||||
<td align="center"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="left">Drag/drop DICOM data into the viewer (see https://viewer.ohif.org/local)</td>
|
||||
<td align="center">✅</td>
|
||||
<td align="center"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="left">White-labelling: Easily replace the OHIF Logo with your logo</td>
|
||||
<td align="center">✅</td>
|
||||
<td align="center"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="left">DICOM Whole-slide imaging viewport</td>
|
||||
<td align="center">🔜</td>
|
||||
<td align="center">In Progress</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="left">IHE Invoke Image Display - Standard-compliant launching of the viewer (e.g. from PACS or RIS)</td>
|
||||
<td align="center">🔜</td>
|
||||
<td align="center">Not Started</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="left">DICOM PDF support</td>
|
||||
<td align="center">🔜</td>
|
||||
<td align="center">Not Started</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="left">Displaying non-renderable DICOM as HTML</td>
|
||||
<td align="center">🔜</td>
|
||||
<td align="center">Not Started</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="left">Segmentation support</td>
|
||||
<td align="center">🔜</td>
|
||||
<td align="center">Not Started</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="left">RT STRUCT support</td>
|
||||
<td align="center">🔜</td>
|
||||
<td align="center">Not Started</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="left">DICOM upload to PACS</td>
|
||||
<td align="center">🔜</td>
|
||||
<td align="center">Not Started</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="left">Google Cloud adapter</td>
|
||||
<td align="center">🔜</td>
|
||||
<td align="center">Not Started</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="left">VTK Extension + MIP / MPR layout</td>
|
||||
<td align="center">❌</td>
|
||||
<td align="center">Other plans that involves amazing news soon!</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="left">UMD Build (Embedded Viewer). </td>
|
||||
<td align="center">❌</td>
|
||||
<td align="center">The problem is that this breaks a bunch of extensions that rely on third party scripts (e.g. VTK) which have their own web worker loaders.</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
@ -46,7 +46,7 @@ const isI18nStaging = process.env.I18N_STAGING === 'true';
|
||||
/** @type {import('@docusaurus/types').DocusaurusConfig} */
|
||||
(module.exports = {
|
||||
title: 'OHIF',
|
||||
tagline: 'Open-source web-based medical imaging viewer',
|
||||
tagline: 'Open-source web-based medical imaging platform',
|
||||
organizationName: 'Open Health Imaging Foundation',
|
||||
projectName: 'OHIF',
|
||||
baseUrl,
|
||||
@ -81,7 +81,7 @@ const isI18nStaging = process.env.I18N_STAGING === 'true';
|
||||
redirects: [
|
||||
{
|
||||
// we need this for https://cloud.google.com/healthcare/docs/how-tos/dicom-viewers
|
||||
to: '/deployment/recipes/google-cloud-healthcare',
|
||||
to: '/2.0/deployment/recipes/google-cloud-healthcare',
|
||||
from: [
|
||||
'/connecting-to-image-archives/google-cloud-healthcare',
|
||||
'/connecting-to-image-archives/google-cloud-healthcare.html',
|
||||
@ -187,21 +187,7 @@ const isI18nStaging = process.env.I18N_STAGING === 'true';
|
||||
// },
|
||||
// ],
|
||||
// },
|
||||
// ],
|
||||
[
|
||||
'docusaurus-plugin-react-docgen',
|
||||
{
|
||||
// pass in a single string or an array of strings
|
||||
//id: 'docgen-button',
|
||||
src: ['../ui/src/components/**/*.jsx'],
|
||||
global: true,
|
||||
/*route: {
|
||||
path: '/docs/api',
|
||||
component: require.resolve('./ComponentDocPage.jsx'),
|
||||
exact: true,
|
||||
},*/
|
||||
},
|
||||
],
|
||||
// ]
|
||||
],
|
||||
presets: [
|
||||
[
|
||||
@ -215,9 +201,10 @@ const isI18nStaging = process.env.I18N_STAGING === 'true';
|
||||
path: 'docs',
|
||||
sidebarPath: require.resolve('./sidebars.js'),
|
||||
editUrl: ({ locale, docPath }) => {
|
||||
if (locale !== 'en') {
|
||||
/*if (locale !== 'en') {
|
||||
return `https://crowdin.com/project/docusaurus-v2/${locale}`;
|
||||
}
|
||||
}*/
|
||||
|
||||
// We want users to submit doc updates to the upstream/next version!
|
||||
// Otherwise we risk losing the update on the next release.
|
||||
const nextVersionDocsDirPath = 'docs';
|
||||
@ -229,19 +216,24 @@ const isI18nStaging = process.env.I18N_STAGING === 'true';
|
||||
// [require('@docusaurus/remark-plugin-npm2yarn'), { sync: true }],
|
||||
// ],
|
||||
// disableVersioning: isVersioningDisabled,
|
||||
// lastVersion: 'current',
|
||||
lastVersion: 'current',
|
||||
// onlyIncludeVersions:
|
||||
// !isVersioningDisabled && (isDev || isDeployPreview)
|
||||
// ? ['current', ...versions.slice(0, 2)]
|
||||
// : undefined,
|
||||
// versions: {
|
||||
// current: {
|
||||
// // label: `${getNextBetaVersionName()} 🚧`,
|
||||
// // label: `2.0 🎉`,
|
||||
// label: `2.0`,
|
||||
// // path: `2.0`,
|
||||
// },
|
||||
// },
|
||||
versions: {
|
||||
current: {
|
||||
label: 'Version 3.0 🚧',
|
||||
},
|
||||
'2.0': {
|
||||
label: 'Version 2.0',
|
||||
//path: `2.0`,
|
||||
},
|
||||
'1.0': {
|
||||
label: 'Version 1.0',
|
||||
//path: `1.0`,
|
||||
},
|
||||
},
|
||||
},
|
||||
theme: {
|
||||
customCss: [require.resolve('./src/css/custom.css')],
|
||||
@ -277,9 +269,9 @@ const isI18nStaging = process.env.I18N_STAGING === 'true';
|
||||
},
|
||||
image: 'img/docusaurus-soc.png',
|
||||
// metadatas: [{name: 'twitter:card', content: 'summary'}],
|
||||
// gtag: {
|
||||
// trackingID: 'UA-110573590-2',
|
||||
// },
|
||||
gtag: {
|
||||
trackingID: 'UA-110573590-2',
|
||||
},
|
||||
// algolia: {
|
||||
// apiKey: '47ecd3b21be71c5822571b9f59e52544',
|
||||
// indexName: 'docusaurus-2',
|
||||
@ -319,8 +311,8 @@ const isI18nStaging = process.env.I18N_STAGING === 'true';
|
||||
position: 'left',
|
||||
},
|
||||
{
|
||||
to: 'next/help',
|
||||
activeBaseRegex: '(^/help$)|(/next/help)',
|
||||
to: '/help',
|
||||
//activeBaseRegex: '(^/help$)|(/help)',
|
||||
label: 'Help',
|
||||
position: 'right',
|
||||
},
|
||||
@ -337,7 +329,7 @@ const isI18nStaging = process.env.I18N_STAGING === 'true';
|
||||
position: 'right',
|
||||
dropdownItemsAfter: [
|
||||
{
|
||||
to: 'next/viewer/internationalization',
|
||||
to: '/platform/internationalization',
|
||||
label: 'Help Us Translate',
|
||||
},
|
||||
],
|
||||
@ -396,7 +388,7 @@ const isI18nStaging = process.env.I18N_STAGING === 'true';
|
||||
items: [
|
||||
{
|
||||
label: 'Donate',
|
||||
to: 'https://google.com/',
|
||||
to: 'https://giving.massgeneral.org/ohif',
|
||||
},
|
||||
{
|
||||
label: 'GitHub',
|
||||
@ -406,13 +398,13 @@ const isI18nStaging = process.env.I18N_STAGING === 'true';
|
||||
label: 'Twitter',
|
||||
to: 'https://twitter.com/OHIFviewer',
|
||||
},
|
||||
// {
|
||||
// html: `
|
||||
// <a href="https://viewer.ohif.org/" target="_blank" rel="noreferrer noopener" aria-label="Deploys by Netlify">
|
||||
// <img src="https://www.netlify.com/img/global/badges/netlify-color-accent.svg" alt="Deploys by Netlify" />
|
||||
// </a>
|
||||
// `,
|
||||
// },
|
||||
{
|
||||
html: `
|
||||
<a href="https://v3-demo.ohif.org/" target="_blank" rel="noreferrer noopener" aria-label="Deploys by Netlify">
|
||||
<img src="https://www.netlify.com/img/global/badges/netlify-color-accent.svg" alt="Deploys by Netlify" />
|
||||
</a>
|
||||
`,
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
|
||||
@ -33,7 +33,6 @@
|
||||
"@docusaurus/remark-plugin-npm2yarn": "2.0.0-beta.3",
|
||||
"@docusaurus/theme-live-codeblock": "2.0.0-beta.3",
|
||||
"@mdx-js/react": "^1.6.21",
|
||||
"@ohif/ui": "^2.0.0",
|
||||
"@svgr/webpack": "^5.5.0",
|
||||
"classnames": "^2.3.1",
|
||||
"clsx": "^1.1.1",
|
||||
@ -58,13 +57,7 @@
|
||||
]
|
||||
},
|
||||
"devDependencies": {
|
||||
"capitalize": "^2.0.3",
|
||||
"docusaurus-plugin-react-docgen": "^0.0.2",
|
||||
"lodash.get": "^4.4.2",
|
||||
"postcss-import": "^14.0.2",
|
||||
"postcss-preset-env": "^6.7.0",
|
||||
"react-docgen": "^5.4.0",
|
||||
"react-tooltip": "^4.2.21",
|
||||
"tailwindcss": "^2.2.4"
|
||||
"postcss-preset-env": "^6.7.0"
|
||||
}
|
||||
}
|
||||
|
||||
@ -23,14 +23,13 @@ module.exports = function(context, options) {
|
||||
},
|
||||
configurePostCss(postcssOptions) {
|
||||
postcssOptions.plugins.push(
|
||||
require('postcss-import'),
|
||||
require('tailwindcss'),
|
||||
require('postcss-preset-env')({
|
||||
require('postcss-import')
|
||||
/*require('postcss-preset-env')({
|
||||
autoprefixer: {
|
||||
flexbox: 'no-2009',
|
||||
},
|
||||
stage: 4,
|
||||
})
|
||||
})*/
|
||||
);
|
||||
return postcssOptions;
|
||||
},
|
||||
|
||||
@ -1,24 +0,0 @@
|
||||
import React from 'react'
|
||||
import PropTypes from 'prop-types'
|
||||
import { usePluginData } from '@docusaurus/useGlobalData';
|
||||
import { PropsTable } from '../react-docgen-props-table/PropsTable'
|
||||
|
||||
export function ComponentPropsTable({ componentName }) {
|
||||
if (!componentName) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const data = usePluginData('docusaurus-plugin-react-docgen')
|
||||
const componentDocGenData = data[componentName.toLowerCase()]
|
||||
if (!componentDocGenData) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (
|
||||
<PropsTable className={'table-auto'} props={componentDocGenData.props}/>
|
||||
)
|
||||
}
|
||||
|
||||
ComponentPropsTable.PropTypes = {
|
||||
componentName: PropTypes.string.required
|
||||
}
|
||||
@ -1,64 +0,0 @@
|
||||
import React from 'react';
|
||||
import clsx from 'clsx';
|
||||
import styles from './HomepageFeatures.module.css';
|
||||
|
||||
const FeatureList = [
|
||||
{
|
||||
title: 'Easy to Use',
|
||||
Svg: require('../../static/img/undraw_docusaurus_mountain.svg').default,
|
||||
description: (
|
||||
<>
|
||||
Docusaurus was designed from the ground up to be easily installed and
|
||||
used to get your website up and running quickly.
|
||||
</>
|
||||
),
|
||||
},
|
||||
{
|
||||
title: 'Focus on What Matters',
|
||||
Svg: require('../../static/img/undraw_docusaurus_tree.svg').default,
|
||||
description: (
|
||||
<>
|
||||
Docusaurus lets you focus on your docs, and we'll do the chores. Go
|
||||
ahead and move your docs into the <code>docs</code> directory.
|
||||
</>
|
||||
),
|
||||
},
|
||||
{
|
||||
title: 'Powered by React',
|
||||
Svg: require('../../static/img/undraw_docusaurus_react.svg').default,
|
||||
description: (
|
||||
<>
|
||||
Extend or customize your website layout by reusing React. Docusaurus can
|
||||
be extended while reusing the same header and footer.
|
||||
</>
|
||||
),
|
||||
},
|
||||
];
|
||||
|
||||
function Feature({Svg, title, description}) {
|
||||
return (
|
||||
<div className={clsx('col col--4')}>
|
||||
<div className="text--center">
|
||||
<Svg className={styles.featureSvg} alt={title} />
|
||||
</div>
|
||||
<div className="text--center padding-horiz--md">
|
||||
<h3>{title}</h3>
|
||||
<p>{description}</p>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default function HomepageFeatures() {
|
||||
return (
|
||||
<section className={styles.features}>
|
||||
<div className="container">
|
||||
<div className="row">
|
||||
{FeatureList.map((props, idx) => (
|
||||
<Feature key={idx} {...props} />
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
);
|
||||
}
|
||||
@ -1,13 +0,0 @@
|
||||
/* stylelint-disable docusaurus/copyright-header */
|
||||
|
||||
.features {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 2rem 0;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.featureSvg {
|
||||
height: 200px;
|
||||
width: 200px;
|
||||
}
|
||||
@ -99,7 +99,7 @@ html[data-theme='dark'] {
|
||||
@import url('https://fonts.googleapis.com/css2?family=Inter:wght@400;600;700&display=swap');
|
||||
|
||||
html {
|
||||
font-size: 18px;
|
||||
font-size: 1em;
|
||||
}
|
||||
|
||||
body {
|
||||
@ -225,7 +225,6 @@ article header h3 {
|
||||
display: none;
|
||||
}
|
||||
|
||||
|
||||
/* Footer logo MGH */
|
||||
|
||||
@media (max-width: 1200px) {
|
||||
|
||||
@ -1,7 +1,3 @@
|
||||
---
|
||||
sidebar_position: 7
|
||||
---
|
||||
|
||||
# Help
|
||||
|
||||
We all need a little help sometimes. Don't let a few roadblocks stand in the way
|
||||
@ -28,12 +24,8 @@ persue paid support.
|
||||
## Commercial Support
|
||||
|
||||
The Open Health Imaging Foundation does not offer commercial support, however,
|
||||
some community members do offer consulting services:
|
||||
|
||||
- Rob Lewis ([Radical Imaging](https://radicalimaging.com/))
|
||||
|
||||
**Please file a Pull Request if you wish to add your name or organization to
|
||||
this list.**
|
||||
some community members do offer consulting services. You can search our
|
||||
[Community Forum](https://community.ohif.org/) for more information.
|
||||
|
||||
<!--
|
||||
Links
|
||||
@ -1,25 +0,0 @@
|
||||
/* stylelint-disable docusaurus/copyright-header */
|
||||
|
||||
/**
|
||||
* CSS files with the .module.css suffix will be treated as CSS modules
|
||||
* and scoped locally.
|
||||
*/
|
||||
|
||||
.heroBanner {
|
||||
padding: 4rem 0;
|
||||
text-align: center;
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
@media screen and (max-width: 966px) {
|
||||
.heroBanner {
|
||||
padding: 2rem;
|
||||
}
|
||||
}
|
||||
|
||||
.buttons {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
@ -1,7 +0,0 @@
|
||||
---
|
||||
title: Markdown page example
|
||||
---
|
||||
|
||||
# Markdown page example
|
||||
|
||||
You don't need React to write simple standalone pages.
|
||||
@ -1,102 +0,0 @@
|
||||
import React from 'react';
|
||||
import get from 'lodash.get';
|
||||
import capitalize from 'capitalize';
|
||||
|
||||
import { humanize } from './humanize-prop';
|
||||
import { Table } from './components/Table';
|
||||
import { Tooltip } from './components/Tooltip';
|
||||
|
||||
const styles = {
|
||||
thead: {
|
||||
textAlign: 'left',
|
||||
},
|
||||
};
|
||||
|
||||
export const getPropType = (prop, Tooltip) => {
|
||||
const propName = prop.flowType ? prop.flowType.name : prop.type.name;
|
||||
const isEnum = propName.startsWith('"') || propName === 'enum';
|
||||
const name = capitalize(isEnum ? 'enum' : propName);
|
||||
const value = prop.type && prop.type.value;
|
||||
|
||||
if (!name) return null;
|
||||
|
||||
if (
|
||||
!Tooltip ||
|
||||
(isEnum && typeof value === 'string') ||
|
||||
(!prop.flowType && !isEnum && !value) ||
|
||||
(prop.flowType && !prop.flowType.elements)
|
||||
) {
|
||||
return name;
|
||||
}
|
||||
|
||||
return prop.flowType ? (
|
||||
<Tooltip text={humanize(prop.flowType)}>{name}</Tooltip>
|
||||
) : (
|
||||
<Tooltip text={humanize(prop.type)}>{name}</Tooltip>
|
||||
);
|
||||
};
|
||||
|
||||
export const PropsTable = ({ props, ...rest }) => {
|
||||
if (!props || typeof props !== 'object') {
|
||||
throw new Error('invalid props passed to PropsTable');
|
||||
}
|
||||
|
||||
const hasDescription = Object.keys(props).some(name => {
|
||||
const description = get(props, `${name}.description`);
|
||||
return Boolean(description) && Boolean(get(description, 'length'));
|
||||
});
|
||||
|
||||
const Thead = 'thead';
|
||||
const Tr = 'tr';
|
||||
const Th = 'th';
|
||||
const Tbody = 'tbody';
|
||||
const Td = 'td';
|
||||
|
||||
return (
|
||||
<Table {...rest}>
|
||||
<Thead style={styles.thead}>
|
||||
<Tr>
|
||||
<Th>Property</Th>
|
||||
<Th>Type</Th>
|
||||
<Th>Required</Th>
|
||||
<Th>Default</Th>
|
||||
|
||||
{hasDescription && <Th width="40%">Description</Th>}
|
||||
</Tr>
|
||||
</Thead>
|
||||
|
||||
<Tbody>
|
||||
{props &&
|
||||
Object.keys(props).map(name => {
|
||||
const prop = props[name];
|
||||
|
||||
if (!prop.flowType && !prop.type) return null;
|
||||
return (
|
||||
<Tr key={name}>
|
||||
<Td>{name}</Td>
|
||||
<Td>{getPropType(prop, Tooltip)}</Td>
|
||||
<Td>{String(prop.required)}</Td>
|
||||
{!prop.defaultValue ? (
|
||||
<Td>
|
||||
<em>-</em>
|
||||
</Td>
|
||||
) : (
|
||||
<Td>
|
||||
{prop.defaultValue.value === "''" ? (
|
||||
<em>[Empty String]</em>
|
||||
) : (
|
||||
prop.defaultValue &&
|
||||
prop.defaultValue.value.replace(/'/g, '')
|
||||
)}
|
||||
</Td>
|
||||
)}
|
||||
{hasDescription && (
|
||||
<Td>{prop.description && prop.description}</Td>
|
||||
)}
|
||||
</Tr>
|
||||
);
|
||||
})}
|
||||
</Tbody>
|
||||
</Table>
|
||||
);
|
||||
};
|
||||
@ -1,10 +0,0 @@
|
||||
import React from 'react';
|
||||
|
||||
export const Table = props => {
|
||||
const { className, style, ...rest } = props;
|
||||
return (
|
||||
<div className={className}>
|
||||
<table className={className} {...rest} />
|
||||
</div>
|
||||
);
|
||||
};
|
||||
@ -1,17 +0,0 @@
|
||||
import React from 'react';
|
||||
import ReactTooltip from 'react-tooltip';
|
||||
|
||||
export const Tooltip = ({ text, children }) => {
|
||||
const id = JSON.stringify(text);
|
||||
return (
|
||||
<React.Fragment>
|
||||
<a data-tip data-for={id} href="#" onClick={ev => ev.preventDefault()}>
|
||||
{children}
|
||||
</a>
|
||||
|
||||
<ReactTooltip id={id} effect="solid">
|
||||
{text}
|
||||
</ReactTooltip>
|
||||
</React.Fragment>
|
||||
);
|
||||
};
|
||||
@ -1,23 +0,0 @@
|
||||
import capitalize from 'capitalize'
|
||||
import get from 'lodash.get'
|
||||
import { humanize } from './humanize-prop'
|
||||
|
||||
export const getPropType = (prop) => {
|
||||
const propName = get(prop.flowType || prop.type, 'name')
|
||||
if (!propName) return null
|
||||
|
||||
const isEnum = propName.startsWith('"') || propName === 'enum'
|
||||
const name = capitalize(isEnum ? 'enum' : propName)
|
||||
const value = get(prop, 'type.value')
|
||||
if (!name) return null
|
||||
|
||||
if (
|
||||
(isEnum && typeof value === 'string') ||
|
||||
(!prop.flowType && !isEnum && !value) ||
|
||||
(prop.flowType && !prop.flowType.elements)
|
||||
) {
|
||||
return name
|
||||
}
|
||||
|
||||
return prop.flowType ? humanize(prop.flowType) : humanize(prop.type)
|
||||
}
|
||||
@ -1,49 +0,0 @@
|
||||
import capitalize from 'capitalize'
|
||||
|
||||
const RE_OBJECTOF = /(?:React\.)?(?:PropTypes\.)?objectOf\((?:React\.)?(?:PropTypes\.)?(\w+)\)/
|
||||
|
||||
const getTypeStr = (type) => {
|
||||
switch (type.name.toLowerCase()) {
|
||||
case 'instanceof':
|
||||
return `Class(${type.value})`
|
||||
case 'enum':
|
||||
if (type.computed) return type.value
|
||||
return type.value
|
||||
? type.value.map((v) => `${v.value}`).join(' │ ')
|
||||
: type.raw
|
||||
case 'union':
|
||||
return type.value
|
||||
? type.value.map((t) => `${getTypeStr(t)}`).join(' │ ')
|
||||
: type.raw
|
||||
case 'array':
|
||||
return type.raw
|
||||
case 'arrayof':
|
||||
return `Array<${getTypeStr(type.value)}>`
|
||||
case 'custom':
|
||||
if (type.raw.indexOf('function') !== -1 || type.raw.indexOf('=>') !== -1) {
|
||||
return 'Custom(Function)'
|
||||
} else if (type.raw.toLowerCase().indexOf('objectof') !== -1) {
|
||||
const m = type.raw.match(RE_OBJECTOF)
|
||||
if (m && m[1]) return `ObjectOf(${capitalize(m[1])})`
|
||||
return 'ObjectOf'
|
||||
}
|
||||
return 'Custom'
|
||||
case 'bool':
|
||||
return 'Boolean'
|
||||
case 'func':
|
||||
return 'Function'
|
||||
case 'shape':
|
||||
const shape = type.value
|
||||
const rst = {}
|
||||
|
||||
Object.keys(shape).forEach(key => {
|
||||
rst[key] = getTypeStr(shape[key])
|
||||
})
|
||||
|
||||
return JSON.stringify(rst, null, 2)
|
||||
default:
|
||||
return capitalize(type.name)
|
||||
}
|
||||
}
|
||||
|
||||
export const humanize = (type) => getTypeStr(type)
|
||||
@ -1,2 +0,0 @@
|
||||
import { PropsTable } from './PropsTable'
|
||||
export default PropsTable
|
||||
@ -1,24 +0,0 @@
|
||||
/**
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
import React from 'react';
|
||||
import classnames from 'classnames';
|
||||
import moment from 'moment';
|
||||
import * as ui from '@ohif/ui';
|
||||
import utils from '../../utils/';
|
||||
|
||||
// Add react-live imports you need here
|
||||
const ReactLiveScope = {
|
||||
React,
|
||||
...React,
|
||||
...ui,
|
||||
classnames,
|
||||
utils,
|
||||
moment,
|
||||
};
|
||||
|
||||
export default ReactLiveScope;
|
||||
@ -3,6 +3,7 @@ module.exports = {
|
||||
important: false,
|
||||
separator: ':',
|
||||
purge: {
|
||||
enabled: true,
|
||||
content: [
|
||||
'./docs/**/*.jsx',
|
||||
'./docs/**/*.mdx',
|
||||
|
||||
@ -6,28 +6,46 @@ sidebar_position: 1
|
||||
|
||||
##### Looking for your Deploy Preview? - <a onClick="function redirect() { window.location.href='/demo/'; } redirect();">Deploy Preview for Viewer</a>
|
||||
|
||||
The [Open Health Imaging Foundation](https://www.ohif.org) is developing an open
|
||||
source framework for constructing web-based medical imaging applications. The
|
||||
application framework is built using modern HTML / CSS / JavaScript and uses
|
||||
[Cornerstone](https://cornerstonejs.org/) at its core to display and manipulate
|
||||
medical images. It is built with Meteor, a Node.js-based full-stack JavaScript
|
||||
platform.
|
||||
|
||||
The [Open Health Imaging Foundation](https://www.ohif.org) is developing an open source framework for constructing web-based medical imaging applications. The application framework is built using modern HTML / CSS / JavaScript and uses [Cornerstone](https://cornerstonejs.org/) at its core to display and manipulate medical images. It is built with Meteor, a Node.js-based full-stack JavaScript platform.
|
||||
|
||||
This documentation concerns the OHIF framework itself and its three example applications: the OHIF Viewer, Lesion Tracker, and the Standalone Viewer.
|
||||
This documentation concerns the OHIF framework itself and its three example
|
||||
applications: the OHIF Viewer, Lesion Tracker, and the Standalone Viewer.
|
||||
|
||||
## The **OHIF Viewer**: A general purpose DICOM Viewer ([demo](http://viewer.ohif.org/))
|
||||
|
||||

|
||||
|
||||
The Open Health Imaging Foundation intends to provide a simple general purpose DICOM Viewer which can be easily extended for specific uses. The primary purpose of the OHIF Viewer is to serve as a testing ground for the underlying packages and the [Cornerstone](https://cornerstonejs.org/) family of libraries.
|
||||
The Open Health Imaging Foundation intends to provide a simple general purpose
|
||||
DICOM Viewer which can be easily extended for specific uses. The primary purpose
|
||||
of the OHIF Viewer is to serve as a testing ground for the underlying packages
|
||||
and the [Cornerstone](https://cornerstonejs.org/) family of libraries.
|
||||
|
||||
## **Lesion Tracker**: An oncology-focused imaging application ([demo](http://lesiontracker.ohif.org/))
|
||||
|
||||

|
||||
|
||||
The Lesion Tracker is designed to facilitate quantitative assessments of tumour burden over time. It is similar in scope to the ePAD Imaging Platform (https://epad.stanford.edu/), developed at Stanford Medicine.
|
||||
The Lesion Tracker is designed to facilitate quantitative assessments of tumour
|
||||
burden over time. It is similar in scope to the ePAD Imaging Platform
|
||||
(https://epad.stanford.edu/), developed at Stanford Medicine.
|
||||
|
||||
## Study List & DICOM Connectivity
|
||||
|
||||

|
||||
|
||||
The solution provides a study list and other resources for connecting to PACS and other Image Archives through standard communication approaches (DICOM Web, DICOM Messages).
|
||||
The solution provides a study list and other resources for connecting to PACS
|
||||
and other Image Archives through standard communication approaches (DICOM Web,
|
||||
DICOM Messages).
|
||||
|
||||
## Standalone Viewer ([demo](ohif-viewer.s3-website.eu-central-1.amazonaws.com/?url=https://raw.githubusercontent.com/OHIF/Viewers/master/StandaloneViewer/etc/sampleDICOM.json))
|
||||
## Standalone Viewer ([demo](https://ohif-viewer.s3-website.eu-central-1.amazonaws.com/?url=https://raw.githubusercontent.com/OHIF/Viewers/master/StandaloneViewer/etc/sampleDICOM.json))
|
||||
|
||||
The Standalone Viewer offers only the client-side portions of the OHIF Viewer with the Study List pages removed. This single-page viewer can be hosted as a static site (e.g. on Amazon S3, Azure Blob Storage, or Github Pages), and easily integrated with existing back-end DICOM storage systems. Alternative [Cornerstone](https://cornerstonejs.org/) Image Loaders can be included to allow your viewer to support non-DICOM objects (e.g. PNG, JPEG).
|
||||
The Standalone Viewer offers only the client-side portions of the OHIF Viewer
|
||||
with the Study List pages removed. This single-page viewer can be hosted as a
|
||||
static site (e.g. on Amazon S3, Azure Blob Storage, or Github Pages), and easily
|
||||
integrated with existing back-end DICOM storage systems. Alternative
|
||||
[Cornerstone](https://cornerstonejs.org/) Image Loaders can be included to allow
|
||||
your viewer to support non-DICOM objects (e.g. PNG, JPEG).
|
||||
|
||||
@ -2,6 +2,7 @@
|
||||
id: contributing
|
||||
sidebar_position: 2
|
||||
---
|
||||
|
||||
# Contributing
|
||||
|
||||
### I would like to contribute code - how do I do this?
|
||||
@ -10,27 +11,45 @@ Fork the repository, make your change and submit a pull request.
|
||||
|
||||
### Any guidance on submitting changes?
|
||||
|
||||
While we do appreciate code contributions, triaging and integrating contributed code changes can be very time consuming. Please consider the following tips when working on your pull requests:
|
||||
While we do appreciate code contributions, triaging and integrating contributed
|
||||
code changes can be very time consuming. Please consider the following tips when
|
||||
working on your pull requests:
|
||||
|
||||
- Functionality is appropriate for the repository. Consider posting on the forum if you are not sure.
|
||||
- Code quality is acceptable. We don't have coding standards defined, but make sure it passes ESLint and looks like the rest of the code in the repository.
|
||||
- Quality of design is acceptable. This is a bit subjective so you should consider posting on the forum for specific guidance.
|
||||
- The scope of the pull request is not too large. Please consider separate pull requests for each feature as big pull requests are very time consuming to understand.
|
||||
- Functionality is appropriate for the repository. Consider posting on the forum
|
||||
if you are not sure.
|
||||
- Code quality is acceptable. We don't have coding standards defined, but make
|
||||
sure it passes ESLint and looks like the rest of the code in the repository.
|
||||
- Quality of design is acceptable. This is a bit subjective so you should
|
||||
consider posting on the forum for specific guidance.
|
||||
- The scope of the pull request is not too large. Please consider separate pull
|
||||
requests for each feature as big pull requests are very time consuming to
|
||||
understand.
|
||||
|
||||
We will provide feedback on your pull requests as soon as possible. Following the tips above will help ensure your changes are reviewed.
|
||||
We will provide feedback on your pull requests as soon as possible. Following
|
||||
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://netlify.com) so that pull requests are autogenerated
|
||||
and available for testing.
|
||||
|
||||
For example, [this url](https://deploy-preview-237--ohif.netlify.com/viewer/?url=https://s3.eu-central-1.amazonaws.com/ohif-viewer/sampleDICOM.json) allows you to test [pull request 237, the request that created this FAQ entry,](https://github.com/OHIF/Viewers/pull/237) using data pulled from Amazon S3.
|
||||
For example,
|
||||
[this url](https://deploy-preview-237--ohif.netlify.com/viewer/?url=https://s3.eu-central-1.amazonaws.com/ohif-viewer/sampleDICOM.json)
|
||||
allows you to test
|
||||
[pull request 237, the request that created this FAQ entry,](https://github.com/OHIF/Viewers/pull/237)
|
||||
using data pulled from Amazon S3.
|
||||
|
||||
Replacing the number 237 in the link below with your pull request number should
|
||||
let you test it as well and you can use this link for discussions on github
|
||||
without requiring reviewers to download and build your branch.
|
||||
|
||||
Replacing the number 237 in the link below with your pull request number should let you test it as well and you can use this link for discussions on github without requiring reviewers to download and build your branch.
|
||||
```
|
||||
https://deploy-preview-237--ohif.netlify.com/viewer/?url=https://s3.eu-central-1.amazonaws.com/ohif-viewer/sampleDICOM.json
|
||||
```
|
||||
|
||||
If you have made a documentation change, a link like this will let you preview the gitbook generated by the pull request:
|
||||
If you have made a documentation change, a link like this will let you preview
|
||||
the gitbook generated by the pull request:
|
||||
|
||||
```
|
||||
https://deploy-preview-237--ohif.netlify.com/contributing.html
|
||||
```
|
||||
|
||||
@ -54,13 +54,8 @@ proposed collaboration has an impact on cancer research.
|
||||
### Do you offer commercial support?
|
||||
|
||||
The Open Health Imaging Foundation does not offer commercial support, however,
|
||||
some community members do offer consulting services. The following contacts may
|
||||
be useful:
|
||||
|
||||
- Rob Lewis ([Radical Imaging](http://radicalimaging.com/))
|
||||
|
||||
**Please file a Pull Request if you wish to add your name or organization to
|
||||
this list.**
|
||||
some community members do offer consulting services. You can search our
|
||||
[Community Forum](https://community.ohif.org/) for more information.
|
||||
|
||||
### I emailed my question to you directly and you did not respond. Why not?
|
||||
|
||||
|
||||
@ -1,68 +1,91 @@
|
||||
---
|
||||
sidebar_position: 2
|
||||
---
|
||||
|
||||
# Installation on Windows
|
||||
On Windows, the easiest way to install LesionTracker is using the provided Windows Installer. You can download the latest version of LesionTracker installer from [OHIF](ohif.org)
|
||||
|
||||
On Windows, the easiest way to install LesionTracker is using the provided
|
||||
Windows Installer. You can download the latest version of LesionTracker
|
||||
installer from [OHIF](https://ohif.org)
|
||||
|
||||
## Install
|
||||
|
||||
1. After you have obtained the latest version of LesionTracker installer, double-click the installer to install the application.
|
||||
1. After you have obtained the latest version of LesionTracker installer,
|
||||
double-click the installer to install the application.
|
||||
2. When you start the installer, setup wizard will pop up.
|
||||
|
||||

|
||||

|
||||
|
||||
3. Click **Install** to start the installation.
|
||||
4. LesionTracker will install prerequisites if they do not exist before installing the application.
|
||||
4. LesionTracker will install prerequisites if they do not exist before
|
||||
installing the application.
|
||||
|
||||

|
||||

|
||||
|
||||
5. Click the **Next** if you accept the installation.
|
||||
|
||||

|
||||

|
||||
|
||||
6. Read the license agreement, and if you agree, click **I accept the terms in the License Agreement** and then click the **Next**.
|
||||
6. Read the license agreement, and if you agree, click **I accept the terms in
|
||||
the License Agreement** and then click the **Next**.
|
||||
|
||||

|
||||

|
||||
|
||||
7. Select a location to install LesionTracker and click the **Next** to continue.
|
||||
7. Select a location to install LesionTracker and click the **Next** to
|
||||
continue.
|
||||
|
||||

|
||||

|
||||
|
||||
8. Click the **Install** to start the installation and the installation will be started.
|
||||
8. Click the **Install** to start the installation and the installation will be
|
||||
started.
|
||||
|
||||

|
||||

|
||||
|
||||
9. Click **Finish** to complete the installation.
|
||||
|
||||

|
||||

|
||||
|
||||
10. When the installation is done,
|
||||
* You will see the final dialog which gives the URLs in order to connect to LesionTracker Viewer and Orthanc Server.
|
||||
|
||||
* It will launch computer's default browser and display LesionTracker Viewer if you click 'http://localhost:3000'
|
||||
* It will launch computer's default browser and enables to upload studies to Orthanc Server if you click 'http://localhost:8042'
|
||||
- You will see the final dialog which gives the URLs in order to connect to
|
||||
LesionTracker Viewer and Orthanc Server.
|
||||
|
||||
- It will launch computer's default browser and display LesionTracker Viewer
|
||||
if you click 'http://localhost:3000'
|
||||
- It will launch computer's default browser and enables to upload studies to
|
||||
Orthanc Server if you click 'http://localhost:8042'
|
||||
|
||||

|
||||
|
||||
* Also, LesionTracker installer will create two shortcuts named LesionTracker and Orthanc Server on the Desktop.
|
||||
- Also, LesionTracker installer will create two shortcuts named LesionTracker
|
||||
and Orthanc Server on the Desktop.
|
||||
|
||||
* It will launch computer's default browser and display LesionTracker image viewer if you click LesionTracker application on the Desktop.
|
||||
* It will launch computer's default browser and enables to upload studies to Orthanc Server if you click Orthanc Server application.
|
||||
- It will launch computer's default browser and display LesionTracker image
|
||||
viewer if you click LesionTracker application on the Desktop.
|
||||
- It will launch computer's default browser and enables to upload studies to
|
||||
Orthanc Server if you click Orthanc Server application.
|
||||
|
||||

|
||||
|
||||
11. Click the **Done** and **Close** to close the installation window.
|
||||
|
||||

|
||||

|
||||
|
||||
12. After the installation is completed,
|
||||
* You can find the project folder in C:\Program Files\OHIF\LesionTracker if you use the default installation location.
|
||||
* You will find 4 program executables which eases managing the services in the project folder:
|
||||
|
||||
* **Start Services.exe:** Starts LesionTracker, MongoDB and Orthanc services manually.
|
||||
* **Stop Services.exe:** Stops LesionTracker, MongoDB and Orthanc services manually.
|
||||
* **Turn Off Auto Services.exe:** Configures not to start LesionTracker, MongoDB and Orthanc services automatically when Windows starts up.
|
||||
* **Turn On Auto Services.exe:** Configures to start LesionTracker, MongoDB and Orthanc services automatically when Windows starts up.
|
||||
- You can find the project folder in C:\Program Files\OHIF\LesionTracker if you
|
||||
use the default installation location.
|
||||
- You will find 4 program executables which eases managing the services in the
|
||||
project folder:
|
||||
|
||||
- **Start Services.exe:** Starts LesionTracker, MongoDB and Orthanc services
|
||||
manually.
|
||||
- **Stop Services.exe:** Stops LesionTracker, MongoDB and Orthanc services
|
||||
manually.
|
||||
- **Turn Off Auto Services.exe:** Configures not to start LesionTracker,
|
||||
MongoDB and Orthanc services automatically when Windows starts up.
|
||||
- **Turn On Auto Services.exe:** Configures to start LesionTracker, MongoDB
|
||||
and Orthanc services automatically when Windows starts up.
|
||||
|
||||

|
||||
|
||||
@ -72,17 +95,18 @@ On Windows, the easiest way to install LesionTracker is using the provided Windo
|
||||
2. Click **Settings**.
|
||||
3. Click **Apps** on the Settings menu.
|
||||
4. Select **Apps & features** from the left panel.
|
||||
5. Find the LesionTracker in programs list and click LesionTracker, then click the **Uninstall**.
|
||||
5. Find the LesionTracker in programs list and click LesionTracker, then click
|
||||
the **Uninstall**.
|
||||
|
||||

|
||||

|
||||
|
||||
6. Click **Uninstall** from the LesionTracker Setup dialog.
|
||||
|
||||

|
||||

|
||||
|
||||
When the uninstallation is done, the uninstallation will remove;
|
||||
|
||||
* Prerequisites: MongoDB, nodejs and Orthanc Server
|
||||
* The project folder, OHIF, from C:\Program Files
|
||||
* Background Services: LesionTracker Server, MongoDB and Orthanc services
|
||||
* Shortcuts: LesionTracker and Orthanc Server shortcuts on the Desktop
|
||||
- Prerequisites: MongoDB, nodejs and Orthanc Server
|
||||
- The project folder, OHIF, from C:\Program Files
|
||||
- Background Services: LesionTracker Server, MongoDB and Orthanc services
|
||||
- Shortcuts: LesionTracker and Orthanc Server shortcuts on the Desktop
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
---
|
||||
sidebar_position: 1
|
||||
sidebar_label: Overview
|
||||
---# Frequently Asked Questions
|
||||
sidebar_label: Overview ---# Frequently Asked Questions
|
||||
---
|
||||
|
||||
## Index
|
||||
|
||||
@ -38,13 +38,8 @@ proposed collaboration has an impact on cancer research.
|
||||
### Does OHIF offer commercial support?
|
||||
|
||||
The Open Health Imaging Foundation does not offer commercial support, however,
|
||||
some community members do offer consulting services. The following contacts may
|
||||
be useful:
|
||||
|
||||
- Rob Lewis ([Radical Imaging](http://radicalimaging.com/))
|
||||
|
||||
**Please file a Pull Request if you wish to add your name or organization to
|
||||
this list.**
|
||||
some community members do offer consulting services. You can search our
|
||||
[Community Forum](https://community.ohif.org/) for more information.
|
||||
|
||||
### Does The OHIF Viewer have [510(k) Clearance][501k-clearance] from the U.S. F.D.A or [CE Marking][ce-marking] from the European Commission?
|
||||
|
||||
|
||||
@ -24,12 +24,8 @@ persue paid support.
|
||||
## Commercial Support
|
||||
|
||||
The Open Health Imaging Foundation does not offer commercial support, however,
|
||||
some community members do offer consulting services:
|
||||
|
||||
- Rob Lewis ([Radical Imaging](http://radicalimaging.com/))
|
||||
|
||||
**Please file a Pull Request if you wish to add your name or organization to
|
||||
this list.**
|
||||
some community members do offer consulting services. You can search our
|
||||
[Community Forum](https://community.ohif.org/) for more information.
|
||||
|
||||
<!--
|
||||
Links
|
||||
|
||||
@ -10,7 +10,9 @@ describe('OHIF Cornerstone Toolbar', () => {
|
||||
cy.initCornerstoneToolsAliases();
|
||||
cy.initCommonElementsAliases();
|
||||
|
||||
cy.get('[data-cy="study-browser-thumbnail"]').eq(1).click();
|
||||
cy.get('[data-cy="study-browser-thumbnail"]')
|
||||
.eq(1)
|
||||
.click();
|
||||
|
||||
//const expectedText = 'Ser: 1';
|
||||
//cy.get('@viewportInfoBottomLeft').should('contains.text', expectedText);
|
||||
@ -19,24 +21,15 @@ describe('OHIF Cornerstone Toolbar', () => {
|
||||
});
|
||||
|
||||
it('checks if all primary buttons are being displayed', () => {
|
||||
cy.get('@zoomBtn')
|
||||
.should('be.visible');
|
||||
cy.get('@wwwcBtnPrimary')
|
||||
.should('be.visible');
|
||||
cy.get('@wwwcBtnSecondary')
|
||||
.should('be.visible');
|
||||
cy.get('@panBtn')
|
||||
.should('be.visible');
|
||||
cy.get('@measurementToolsBtnPrimary')
|
||||
.should('be.visible');
|
||||
cy.get('@measurementToolsBtnSecondary')
|
||||
.should('be.visible');
|
||||
cy.get('@moreBtnPrimary')
|
||||
.should('be.visible');
|
||||
cy.get('@moreBtnSecondary')
|
||||
.should('be.visible');
|
||||
cy.get('@layoutBtn')
|
||||
.should('be.visible');
|
||||
cy.get('@zoomBtn').should('be.visible');
|
||||
cy.get('@wwwcBtnPrimary').should('be.visible');
|
||||
cy.get('@wwwcBtnSecondary').should('be.visible');
|
||||
cy.get('@panBtn').should('be.visible');
|
||||
cy.get('@measurementToolsBtnPrimary').should('be.visible');
|
||||
cy.get('@measurementToolsBtnSecondary').should('be.visible');
|
||||
cy.get('@moreBtnPrimary').should('be.visible');
|
||||
cy.get('@moreBtnSecondary').should('be.visible');
|
||||
cy.get('@layoutBtn').should('be.visible');
|
||||
});
|
||||
|
||||
/*it('checks if Stack Scroll tool will navigate across all series in the viewport', () => {
|
||||
@ -113,8 +106,12 @@ describe('OHIF Cornerstone Toolbar', () => {
|
||||
it('checks if Length annotation can be added to viewport and shows up in the measurements panel', () => {
|
||||
//Click on button and verify if icon is active on toolbar
|
||||
cy.addLengthMeasurement();
|
||||
cy.get('[data-cy="measurement-tracking-prompt-begin-tracking"]').should('exist')
|
||||
cy.get('[data-cy="measurement-tracking-prompt-begin-tracking"]').should('be.visible')
|
||||
cy.get('[data-cy="measurement-tracking-prompt-begin-tracking"]').should(
|
||||
'exist'
|
||||
);
|
||||
cy.get('[data-cy="measurement-tracking-prompt-begin-tracking"]').should(
|
||||
'be.visible'
|
||||
);
|
||||
cy.get('[data-cy="prompt-begin-tracking-yes"]').click();
|
||||
|
||||
//Verify the measurement exists in the table
|
||||
@ -235,21 +232,19 @@ describe('OHIF Cornerstone Toolbar', () => {
|
||||
.should('be.visible');
|
||||
|
||||
// Click on one of the secondary tools from the overlay
|
||||
cy.get('[data-cy="Magnify"]').click()
|
||||
cy.get('[data-cy="Magnify"]').click();
|
||||
|
||||
// Check if More button is active and if it has same icon as the secondary tool selected
|
||||
cy.get('@moreBtnPrimary')
|
||||
.then($moreBtn => {
|
||||
cy.wrap($moreBtn)
|
||||
.should('have.class', 'active')
|
||||
.should('have.attr', 'data-tool', 'Magnify')
|
||||
});
|
||||
cy.get('@moreBtnPrimary').then($moreBtn => {
|
||||
cy.wrap($moreBtn)
|
||||
.should('have.class', 'active')
|
||||
.should('have.attr', 'data-tool', 'Magnify');
|
||||
});
|
||||
|
||||
// Verify if overlay is hidden
|
||||
cy.get('@toolbarOverlay').should('not.be.visible');
|
||||
});
|
||||
|
||||
|
||||
/*it('checks if Layout tool will multiply the number of viewports displayed', () => {
|
||||
//Click on Layout button and verify if overlay is displayed
|
||||
cy.get('@layoutBtn')
|
||||
@ -371,9 +366,6 @@ describe('OHIF Cornerstone Toolbar', () => {
|
||||
|
||||
//Verify if measurements were removed from the measurements panel
|
||||
|
||||
// TODO: We need a seperate test server for this to work.
|
||||
// As anyone can save measurements on a different slice.
|
||||
|
||||
//cy.get('.measurementItem'); //.should('not.exist');
|
||||
|
||||
//Close More button overlay
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user