docs: Remove UI components for now, we will use Storybook instead later. Clean up links and introduction. (#2520)

This commit is contained in:
Erik Ziegler 2021-08-24 14:13:54 +02:00 committed by Alireza
parent 2327b4ae12
commit 00d7192423
104 changed files with 538 additions and 4956 deletions

View File

@ -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

View File

@ -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 */

View File

@ -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_
>

View File

@ -13,7 +13,7 @@
"engines": {
"node": ">=10",
"npm": ">=6",
"yarn": ">=1.19.1"
"yarn": ">=1.18.0"
},
"files": [
"dist",

View File

@ -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'),

View File

@ -13,7 +13,7 @@
"engines": {
"node": ">=10",
"npm": ">=6",
"yarn": ">=1.19.1"
"yarn": ">=1.18.0"
},
"files": [
"dist",

View File

@ -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
![OHIF Viewer Screenshot](./assets/img/OHIF-Viewer.png)
<!-- <center><i>The <strong>OHIF Viewer v3</strong>: A general purpose DICOM Viewer (<a href="http://viewer.ohif.org/">Live Demo</a>)</center> -->
&nbsp;
## 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)
&nbsp;
<!--
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 -->

View File

@ -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

View File

@ -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

View File

@ -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?

View File

@ -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.

View File

@ -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',
},
```

View File

@ -1,4 +0,0 @@
{
"label": "UI Component Library",
"position": 5
}

View File

@ -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

View File

@ -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'} />

View File

@ -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'} />

View File

@ -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'} />

View File

@ -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'} />

View File

@ -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'} />

View File

@ -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'} />

View File

@ -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'} />

View File

@ -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'} />

View File

@ -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'} />

View File

@ -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'} />

View File

@ -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'} />

View File

@ -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'} />

View File

@ -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'} />

View File

@ -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'} />

View File

@ -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'} />

View File

@ -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'} />

View File

@ -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'} />

View File

@ -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'} />

View File

@ -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'} />

View File

@ -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'} />

View File

@ -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'} />

View File

@ -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'} />)``

View File

@ -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'} />

View File

@ -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'} />

View File

@ -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'} />
```

View File

@ -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'} />

View File

@ -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'} />

View File

@ -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'} />

View File

@ -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'} />

View File

@ -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'} />

View File

@ -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'} />

View File

@ -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'} />

View File

@ -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'} />

View File

@ -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'} />

View File

@ -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'} />

View File

@ -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'} />

View File

@ -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'} />

View File

@ -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'} />

View File

@ -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'} />

View File

@ -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'} />

View File

@ -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'} />

View File

@ -1,4 +0,0 @@
{
"label": "Components",
"position": 5
}

View File

@ -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.

View File

@ -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} />

View File

@ -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} />
````

View File

@ -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} />

View File

@ -1,4 +0,0 @@
{
"label": "Context Providers",
"position": 5
}

View File

@ -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>
);
}
```

View File

@ -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>
);
}}
```

View File

@ -1,4 +0,0 @@
{
"label": "Example Views",
"position": 6
}

View File

@ -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.

View File

@ -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>

View File

@ -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>
)
);
}
```

View File

@ -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
-->

View File

@ -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>

View File

@ -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)

View File

@ -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
-->

View File

@ -0,0 +1,8 @@
---
sidebar_position: 7
sidebar_label: CINE Service
---
# CINE Service
TODO...

View File

@ -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">

View 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>

View File

@ -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>
`,
},
],
},
],

View File

@ -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"
}
}

View File

@ -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;
},

View File

@ -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
}

View File

@ -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&apos;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>
);
}

View File

@ -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;
}

View File

@ -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) {

View File

@ -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

View File

@ -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;
}

View File

@ -1,7 +0,0 @@
---
title: Markdown page example
---
# Markdown page example
You don't need React to write simple standalone pages.

View File

@ -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>
);
};

View File

@ -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>
);
};

View File

@ -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>
);
};

View File

@ -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)
}

View File

@ -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)

View File

@ -1,2 +0,0 @@
import { PropsTable } from './PropsTable'
export default PropsTable

View File

@ -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;

View File

@ -3,6 +3,7 @@ module.exports = {
important: false,
separator: ':',
purge: {
enabled: true,
content: [
'./docs/**/*.jsx',
'./docs/**/*.mdx',

View File

@ -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/))
![OHIF Viewer Screenshot](./assets/img/viewer.png)
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/))
![Lesion Tracker Screenshot](./assets/img/lesionTracker.png)
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
![Study List Screenshot](./assets/img/worklist.png)
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).

View File

@ -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
```

View File

@ -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?

View File

@ -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.
![Installer Initial](../assets/img/LesionTracker/LT_Installer_Initial.png)
![Installer Initial](../assets/img/LesionTracker/LT_Installer_Initial.png)
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.
![Prerequisites](../assets/img/LesionTracker/LT_Installer_Prerequisites.png)
![Prerequisites](../assets/img/LesionTracker/LT_Installer_Prerequisites.png)
5. Click the **Next** if you accept the installation.
![After Prerequisites](../assets/img/LesionTracker/LT_Installer_After_Prerequisites.png)
![After Prerequisites](../assets/img/LesionTracker/LT_Installer_After_Prerequisites.png)
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**.
![License Aggrement](../assets/img/LesionTracker/LT_Installer_License_Aggrement.png)
![License Aggrement](../assets/img/LesionTracker/LT_Installer_License_Aggrement.png)
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.
![Select Location](../assets/img/LesionTracker/LT_Installer_Select_Location.png)
![Select Location](../assets/img/LesionTracker/LT_Installer_Select_Location.png)
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.
![Launch Installation](../assets/img/LesionTracker/LT_Installer_Launch_Installation.png)
![Launch Installation](../assets/img/LesionTracker/LT_Installer_Launch_Installation.png)
9. Click **Finish** to complete the installation.
![Finish](../assets/img/LesionTracker/LT_Installer_Finish.png)
![Finish](../assets/img/LesionTracker/LT_Installer_Finish.png)
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'
![Final](../assets/img/LesionTracker/LT_Installer_Final.png)
* 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.
![Desktop Shortcuts](../assets/img/LesionTracker/LT_Installer_Desktop_Shortcuts.png)
11. Click the **Done** and **Close** to close the installation window.
![Installation Successful](../assets/img/LesionTracker/LT_Installer_Successful.png)
![Installation Successful](../assets/img/LesionTracker/LT_Installer_Successful.png)
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.
![Services](../assets/img/LesionTracker/LT_Installer_Services.png)
@ -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**.
![Uninstall](../assets/img/LesionTracker/LT_Installer_Uninstall.png)
![Uninstall](../assets/img/LesionTracker/LT_Installer_Uninstall.png)
6. Click **Uninstall** from the LesionTracker Setup dialog.
![Launch Uninstall](../assets/img/LesionTracker/LT_Installer_Launch_Uninstall.png)
![Launch Uninstall](../assets/img/LesionTracker/LT_Installer_Launch_Uninstall.png)
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

View File

@ -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?

View File

@ -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

View File

@ -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