diff --git a/.netlify/build-deploy-preview.sh b/.netlify/build-deploy-preview.sh index 112590214..cb5d017d3 100755 --- a/.netlify/build-deploy-preview.sh +++ b/.netlify/build-deploy-preview.sh @@ -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 diff --git a/.webpack/webpack.base.js b/.webpack/webpack.base.js index b37f3405d..26171786f 100644 --- a/.webpack/webpack.base.js +++ b/.webpack/webpack.base.js @@ -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 */ diff --git a/README.md b/README.md index a9ef39699..bd3903e08 100644 --- a/README.md +++ b/README.md @@ -82,7 +82,7 @@ We offer support through - [Request a Feature 🚀](https://github.com/OHIF/Viewers/issues/new?assignees=&labels=Community%3A+Request+%3Ahand%3A&template=---feature-request.md) - [Ask a Question 🤗](https://github.com/OHIF/Viewers/issues/new?assignees=&labels=Community%3A+Question+%3Aquestion%3A&template=---support-question.md) -For commercial support, academic collaberations, and answers to common +For commercial support, academic collaborations, and answers to common questions; please read our [documented FAQ](https://docs.ohif.org/faq/index.html#does-ohif-offer-commercial-support). @@ -173,7 +173,7 @@ also supports a number of commands that can be found in their respective | `dev:project ` | 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_ > diff --git a/extensions/default/package.json b/extensions/default/package.json index f95b11892..ae0b10a7c 100644 --- a/extensions/default/package.json +++ b/extensions/default/package.json @@ -13,7 +13,7 @@ "engines": { "node": ">=10", "npm": ">=6", - "yarn": ">=1.19.1" + "yarn": ">=1.18.0" }, "files": [ "dist", diff --git a/extensions/default/src/ViewerLayout/index.jsx b/extensions/default/src/ViewerLayout/index.jsx index 3e1a9d26e..c57f87615 100644 --- a/extensions/default/src/ViewerLayout/index.jsx +++ b/extensions/default/src/ViewerLayout/index.jsx @@ -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'), diff --git a/extensions/measurement-tracking/package.json b/extensions/measurement-tracking/package.json index d76b90c16..4278e9f44 100644 --- a/extensions/measurement-tracking/package.json +++ b/extensions/measurement-tracking/package.json @@ -13,7 +13,7 @@ "engines": { "node": ">=10", "npm": ">=6", - "yarn": ">=1.19.1" + "yarn": ">=1.18.0" }, "files": [ "dist", diff --git a/platform/docs/docs/README.md b/platform/docs/docs/README.md index 1a9818074..8c4bdcffd 100644 --- a/platform/docs/docs/README.md +++ b/platform/docs/docs/README.md @@ -4,167 +4,41 @@ slug: / sidebar_position: 1 --- -
-Preview The OHIF Viewer - - -
- -> 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) - - -  - -## 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`: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
OHIF-v2 functionalitiesOHIF-v3Comment
Rendering of 2D images via Cornerstone
Study List
Series Browser
DICOM JSON
2D Tools via CornerstoneTools
OpenID Connect standard authentication flow for connecting to identity providers
Internationalization
Drag/drop DICOM data into the viewer (see https://viewer.ohif.org/local)
White-labelling: Easily replace the OHIF Logo with your logo
DICOM Whole-slide imaging viewport🔜In Progress
IHE Invoke Image Display - Standard-compliant launching of the viewer (e.g. from PACS or RIS)🔜Not Started
DICOM PDF support🔜Not Started
Displaying non-renderable DICOM as HTML🔜Not Started
Segmentation support🔜Not Started
RT STRUCT support🔜Not Started
DICOM upload to PACS🔜Not Started
Google Cloud adapter🔜Not Started
VTK Extension + MIP / MPR layoutOther plans that involves amazing news soon!
UMD Build (Embedded Viewer). 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.
+
+
+ Try the demo + Release Notes +
+
## 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) + +  [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 diff --git a/platform/docs/docs/deployment/index.md b/platform/docs/docs/deployment/index.md index 3d8b6b891..0b2f8bd69 100644 --- a/platform/docs/docs/deployment/index.md +++ b/platform/docs/docs/deployment/index.md @@ -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 - - -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 ( - { - if (typeof window !== 'undefined') { - window.alert(value); - } - }} - /> - ); - }; - const ViewportActionButtons = () => { - const [dialogState, dialogApi] = useViewportDialog(); - return ( - - ); - }; - } - - return ( -
-
- -
- - CONTENT 1 -
-
-
-
- -
- - CONTENT 1 -
-
-
-
- ); - }} -``` - -## Example using UIViewportDialogService - -```jsx live - function() { - const ViewportNotification = ({ hide }) => { - return ( - { - 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 ( -
-
- - -
-
- -
- CONTENT 0 -
-
- -
- CONTENT 1 -
-
-
-
- ); - }} -``` - -## Properties: - - -```` diff --git a/platform/docs/docs/platform/component-library/context-providers/ViewportDialogProvider.mdx.todo b/platform/docs/docs/platform/component-library/context-providers/ViewportDialogProvider.mdx.todo deleted file mode 100644 index 3425605dd..000000000 --- a/platform/docs/docs/platform/component-library/context-providers/ViewportDialogProvider.mdx.todo +++ /dev/null @@ -1,178 +0,0 @@ ---- -name: ViewportDialogProvider -route: customHooks/viewportDialogProvider ---- - - - - -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 ( - { - if (typeof window !== 'undefined') { - window.alert(value); - } - }} - /> - ); - }; - const ViewportActionButtons = () => { - const [dialogState, dialogApi] = useViewportDialog(); - return ( - - ); - }; - return ( -
-
- -
- - CONTENT 1 -
-
-
-
- -
- - CONTENT 1 -
-
-
-
- ); - }} -``` - -## Example using UIViewportDialogService - -```jsx live - {() => { - const ViewportNotification = ({ hide }) => { - return ( - { - 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 ( -
-
- - -
-
- -
- CONTENT 0 -
-
- -
- CONTENT 1 -
-
-
-
- ); - }} -``` - -## Properties: - - diff --git a/platform/docs/docs/platform/component-library/context-providers/_category_.json b/platform/docs/docs/platform/component-library/context-providers/_category_.json deleted file mode 100644 index 1a247737a..000000000 --- a/platform/docs/docs/platform/component-library/context-providers/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "Context Providers", - "position": 5 -} diff --git a/platform/docs/docs/platform/component-library/example-views/StudyList.mdx b/platform/docs/docs/platform/component-library/example-views/StudyList.mdx deleted file mode 100644 index be2c08b93..000000000 --- a/platform/docs/docs/platform/component-library/example-views/StudyList.mdx +++ /dev/null @@ -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: ( -
- - {moment(StudyDate).format('MMM-DD-YYYY')} - - {moment(StudyDate).format('hh:mm A')} -
- ), - gridCol: 5, - }, - { - key: 'description', - content: StudyDescription, - gridCol: 4, - }, - { - key: 'modality', - content: Modalities, - gridCol: 3, - }, - { - key: 'accession', - content: AccessionNumber, - gridCol: 4, - }, - { - key: 'instances', - content: ( - <> - - {Instances} - - ), - gridCol: 4, - }, - ], - expandedContent: ( - - - - -
- - Feedback text lorem ipsum dolor sit amet -
-
- ), - 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 ( -
-
- - - - -
-
- -
-
- -
-
-
- - FOR INVESTIGATIONAL USE ONLY - - {}} - > - - - - - -
-
- setFilterValues(defaultFilterValues)} - isFiltering={isFiltering(filterValues, defaultFilterValues)} - /> - {hasStudies ? ( - <> - - - - ) : ( -
- -
- )} -
-
- ); -} -``` diff --git a/platform/docs/docs/platform/component-library/example-views/Viewer.mdx.todo b/platform/docs/docs/platform/component-library/example-views/Viewer.mdx.todo deleted file mode 100644 index 5fb148455..000000000 --- a/platform/docs/docs/platform/component-library/example-views/Viewer.mdx.todo +++ /dev/null @@ -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 ( - -
-
- {/* LEFT SIDEPANELS */} - - }} - /> - {/* TOOLBAR + GRID */} -
-
- {/* Secondary Toolbar */} -
- {/* VIEWPORT GRID CONTAINER */} -
- - {[0, 1].map(viewportIndex => ( - {}}> - 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', - }, - }} - > -
- CONTENT -
-
-
) - )} -
-
-
- -
- - {}} - onEdit={id => alert(`Edit: ${id}`)} - /> -
-
- - alert('Export')}> - - - - - - - -
- - ) - }} - /> -
- - ); - }} -``` diff --git a/platform/docs/docs/platform/component-library/example-views/_category_.json b/platform/docs/docs/platform/component-library/example-views/_category_.json deleted file mode 100644 index f9601aa2b..000000000 --- a/platform/docs/docs/platform/component-library/example-views/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "Example Views", - "position": 6 -} diff --git a/platform/docs/docs/platform/component-library/getting-started.mdx b/platform/docs/docs/platform/component-library/getting-started.mdx deleted file mode 100644 index 80f3704c8..000000000 --- a/platform/docs/docs/platform/component-library/getting-started.mdx +++ /dev/null @@ -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 -
- -
-``` - -## Examples - -In the **Examples** section you can check many examples on how to build your -application using `@ohif/ui` components. diff --git a/platform/docs/docs/platform/extensions/index.md b/platform/docs/docs/platform/extensions/index.md index ea45995a0..9c1f25b46 100644 --- a/platform/docs/docs/platform/extensions/index.md +++ b/platform/docs/docs/platform/extensions/index.md @@ -258,7 +258,7 @@ differently. - + LayoutTemplate (NEW) @@ -266,7 +266,7 @@ differently. - + DataSource (NEW) @@ -274,7 +274,7 @@ differently. - + SOPClassHandler @@ -282,7 +282,7 @@ differently. - + Panel @@ -290,7 +290,7 @@ differently. - + Viewport @@ -298,7 +298,7 @@ differently. - + Commands @@ -306,7 +306,7 @@ differently. - + Toolbar @@ -314,7 +314,7 @@ differently. - + Context @@ -322,7 +322,7 @@ differently. - + HangingProtocol diff --git a/platform/docs/docs/platform/extensions/modules/layout-template.md b/platform/docs/docs/platform/extensions/modules/layout-template.md index 7184ae952..66c839dae 100644 --- a/platform/docs/docs/platform/extensions/modules/layout-template.md +++ b/platform/docs/docs/platform/extensions/modules/layout-template.md @@ -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 ( 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 (
@@ -125,7 +128,7 @@ function ViewerLayout({ />
- ) + ); } ``` diff --git a/platform/docs/docs/platform/managers/index.md b/platform/docs/docs/platform/managers/index.md index c2f4a30d8..ee6d6b2fc 100644 --- a/platform/docs/docs/platform/managers/index.md +++ b/platform/docs/docs/platform/managers/index.md @@ -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 - + Extension Manager @@ -31,7 +33,7 @@ sidebar_label: Introduction - + Services Manager @@ -41,7 +43,7 @@ sidebar_label: Introduction - + Commands Manager @@ -51,7 +53,7 @@ sidebar_label: Introduction - + Hotkeys Manager @@ -62,10 +64,6 @@ sidebar_label: Introduction - - - - diff --git a/platform/docs/docs/platform/modes/index.md b/platform/docs/docs/platform/modes/index.md index 28a3e710b..187d708fc 100644 --- a/platform/docs/docs/platform/modes/index.md +++ b/platform/docs/docs/platform/modes/index.md @@ -99,7 +99,7 @@ export default function mode() { - + onModeEnter @@ -107,7 +107,7 @@ export default function mode() { - + onModeExit @@ -139,7 +139,7 @@ export default function mode() { - + extensions diff --git a/platform/docs/docs/platform/pwa-vs-packaged.md b/platform/docs/docs/platform/pwa-vs-packaged.md index c4a0c6651..bdc411e6c 100644 --- a/platform/docs/docs/platform/pwa-vs-packaged.md +++ b/platform/docs/docs/platform/pwa-vs-packaged.md @@ -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) diff --git a/platform/docs/docs/platform/services/index.md b/platform/docs/docs/platform/services/index.md index 93cfd0866..e3735c3bc 100644 --- a/platform/docs/docs/platform/services/index.md +++ b/platform/docs/docs/platform/services/index.md @@ -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`. @@ -37,7 +39,7 @@ The following services is available in the `OHIF-v3`. @@ -48,7 +50,7 @@ The following services is available in the `OHIF-v3`. @@ -59,7 +61,7 @@ The following services is available in the `OHIF-v3`. @@ -70,7 +72,7 @@ The following services is available in the `OHIF-v3`. @@ -81,7 +83,7 @@ The following services is available in the `OHIF-v3`. @@ -92,7 +94,7 @@ The following services is available in the `OHIF-v3`. @@ -103,7 +105,7 @@ The following services is available in the `OHIF-v3`. @@ -114,7 +116,7 @@ The following services is available in the `OHIF-v3`. @@ -125,7 +127,7 @@ The following services is available in the `OHIF-v3`. @@ -136,7 +138,7 @@ The following services is available in the `OHIF-v3`. @@ -147,7 +149,7 @@ The following services is available in the `OHIF-v3`. @@ -159,7 +161,6 @@ The following services is available in the `OHIF-v3`.
- + DicomMetadataStore (NEW)
- + DisplaySetService (NEW)
- + HangingProtocolService (NEW)
- + MeasurementService (MODIFIED)
- + ToolBarService (NEW)
- + ViewportGridService (NEW)
- + Cine Service (NEW)
- + UIDialogService
- + UIModalService
- + UINotificationService
- + UIViewportDialogService (NEW)
- diff --git a/platform/docs/docs/platform/services/ui/cine-service.md b/platform/docs/docs/platform/services/ui/cine-service.md new file mode 100644 index 000000000..707b5d97f --- /dev/null +++ b/platform/docs/docs/platform/services/ui/cine-service.md @@ -0,0 +1,8 @@ +--- +sidebar_position: 7 +sidebar_label: CINE Service +--- + +# CINE Service + +TODO... diff --git a/platform/docs/docs/platform/services/ui/index.md b/platform/docs/docs/platform/services/ui/index.md index 63ffea903..d50cbe56e 100644 --- a/platform/docs/docs/platform/services/ui/index.md +++ b/platform/docs/docs/platform/services/ui/index.md @@ -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)