+
{renderDialogs()}
}
diff --git a/platform/ui/src/contextProviders/ViewportGridProvider.jsx b/platform/ui/src/contextProviders/ViewportGridProvider.jsx
index a522ea165..6c5c1120e 100644
--- a/platform/ui/src/contextProviders/ViewportGridProvider.jsx
+++ b/platform/ui/src/contextProviders/ViewportGridProvider.jsx
@@ -27,10 +27,10 @@ export function ViewportGridProvider({ children, service }) {
return { ...state, ...{ activeViewportIndex: action.payload } };
}
case 'SET_DISPLAYSET_FOR_VIEWPORT': {
- const { viewportIndex, displaySetInstanceUID } = action.payload;
+ const { viewportIndex, displaySetInstanceUID, imageIndex } = action.payload;
const viewports = state.viewports.slice();
- viewports[viewportIndex] = { displaySetInstanceUID };
+ viewports[viewportIndex] = { displaySetInstanceUID, imageIndex };
return { ...state, ...{ viewports } };
}
@@ -69,12 +69,13 @@ export function ViewportGridProvider({ children, service }) {
[dispatch]
);
const setDisplaysetForViewport = useCallback(
- ({ viewportIndex, displaySetInstanceUID }) =>
+ ({ viewportIndex, displaySetInstanceUID, imageIndex }) =>
dispatch({
type: 'SET_DISPLAYSET_FOR_VIEWPORT',
payload: {
viewportIndex,
displaySetInstanceUID,
+ imageIndex
},
}),
[dispatch]
diff --git a/platform/viewer/src/appExtensions/GenericViewerCommands/commandsModule.js b/platform/viewer/src/appExtensions/GenericViewerCommands/commandsModule.js
deleted file mode 100644
index e7e122cda..000000000
--- a/platform/viewer/src/appExtensions/GenericViewerCommands/commandsModule.js
+++ /dev/null
@@ -1,140 +0,0 @@
-import { redux } from '@ohif/core';
-import store from './../../store';
-
-const commandsModule = ({ commandsManager }) => {
- const { setViewportActive, setActiveViewportSpecificData } = redux.actions;
-
- const actions = {
- updateActiveViewport: ({ viewports, direction }) => {
- const { viewportSpecificData, activeViewportIndex } = viewports;
- const maxIndex = Object.keys(viewportSpecificData).length - 1;
-
- let newIndex = activeViewportIndex + direction;
- newIndex = newIndex > maxIndex ? 0 : newIndex;
- newIndex = newIndex < 0 ? maxIndex : newIndex;
-
- store.dispatch(setViewportActive(newIndex));
- },
- setWindowLevelPreset: ({ viewports, preset }) => {
- const state = store.getState();
- const { preferences = {} } = state;
- const { window, level } =
- preferences.windowLevelData && preferences.windowLevelData[preset];
-
- if (window && level) {
- commandsManager.runCommand('setWindowLevel', {
- viewports,
- window,
- level,
- });
- }
- },
- updateViewportDisplaySet: ({ viewports, direction }) => {
- const viewportSpecificData = { ...viewports.viewportSpecificData };
- const activeViewport =
- viewportSpecificData[viewports.activeViewportIndex];
- const studyMetadata = utils.studyMetadataManager.get(
- activeViewport.StudyInstanceUID
- );
-
- if (!studyMetadata) {
- return;
- }
-
- const allDisplaySets = studyMetadata.getDisplaySets();
- const currentDisplaySetIndex = allDisplaySets.findIndex(
- displaySet =>
- displaySet.displaySetInstanceUID ===
- activeViewport.displaySetInstanceUID
- );
- if (currentDisplaySetIndex < 0) {
- return;
- }
-
- const newDisplaySetIndex = currentDisplaySetIndex + direction;
- const newDisplaySetData = allDisplaySets[newDisplaySetIndex];
- if (!newDisplaySetData) {
- return;
- }
-
- store.dispatch(setActiveViewportSpecificData(newDisplaySetData));
- },
- };
-
- const definitions = {
- // Next/Previous active viewport
- incrementActiveViewport: {
- commandFn: actions.updateActiveViewport,
- storeContexts: ['viewports'],
- options: { direction: 1 },
- },
- decrementActiveViewport: {
- commandFn: actions.updateActiveViewport,
- storeContexts: ['viewports'],
- options: { direction: -1 },
- },
- // Window level Presets
- windowLevelPreset1: {
- commandFn: actions.setWindowLevelPreset,
- storeContexts: ['viewports'],
- options: { preset: 1 },
- },
- windowLevelPreset2: {
- commandFn: actions.setWindowLevelPreset,
- storeContexts: ['viewports'],
- options: { preset: 2 },
- },
- windowLevelPreset3: {
- commandFn: actions.setWindowLevelPreset,
- storeContexts: ['viewports'],
- options: { preset: 3 },
- },
- windowLevelPreset4: {
- commandFn: actions.setWindowLevelPreset,
- storeContexts: ['viewports'],
- options: { preset: 4 },
- },
- windowLevelPreset5: {
- commandFn: actions.setWindowLevelPreset,
- storeContexts: ['viewports'],
- options: { preset: 5 },
- },
- windowLevelPreset6: {
- commandFn: actions.setWindowLevelPreset,
- storeContexts: ['viewports'],
- options: { preset: 6 },
- },
- windowLevelPreset7: {
- commandFn: actions.setWindowLevelPreset,
- storeContexts: ['viewports'],
- options: { preset: 7 },
- },
- windowLevelPreset8: {
- commandFn: actions.setWindowLevelPreset,
- storeContexts: ['viewports'],
- options: { preset: 8 },
- },
- windowLevelPreset9: {
- commandFn: actions.setWindowLevelPreset,
- storeContexts: ['viewports'],
- options: { preset: 9 },
- },
- nextViewportDisplaySet: {
- commandFn: actions.updateViewportDisplaySet,
- storeContexts: ['viewports'],
- options: { direction: 1 },
- },
- previousViewportDisplaySet: {
- commandFn: actions.updateViewportDisplaySet,
- storeContexts: ['viewports'],
- options: { direction: -1 },
- },
- };
-
- return {
- definitions,
- defaultContext: 'VIEWER',
- };
-};
-
-export default commandsModule;
diff --git a/platform/viewer/src/appExtensions/MeasurementsPanel/jumpToRowItem.js b/platform/viewer/src/appExtensions/MeasurementsPanel/jumpToRowItem.js
deleted file mode 100644
index 4a95119cd..000000000
--- a/platform/viewer/src/appExtensions/MeasurementsPanel/jumpToRowItem.js
+++ /dev/null
@@ -1,118 +0,0 @@
-import { measurements, utils } from '@ohif/core';
-
-const { MeasurementApi } = measurements;
-const { studyMetadataManager } = utils;
-
-// TODO: Move this function to OHIF itself so we can use it on the OHIF measurment table (when it is finished)
-
-/**
- * Activates a set of measurements
- *
- * @param measurementData
- * @param viewportsState
- * @param timepointManagerState
- * @param options
- */
-export default function jumpToRowItem(
- measurementData,
- viewportsState,
- timepointManagerState,
- options = { invertViewportTimepointsOrder: false, childToolKey: null }
-) {
- const numViewports = viewportsState.layout.viewports.length;
- const numTimepoints = timepointManagerState.timepoints.length;
- const { measurements, timepoints } = timepointManagerState;
- const numViewportsToUpdate = Math.min(numTimepoints, numViewports);
- const { toolType, measurementNumber } = measurementData;
-
- if (options.invertViewportTimepointsOrder) {
- timepoints.reverse();
- }
-
- const measurementsForToolGroup = measurements[toolType];
-
- // Retrieve the measurements data
- const measurementsToJumpTo = [];
- for (let i = 0; i < numViewportsToUpdate; i++) {
- const { timepointId } = timepoints[i];
-
- const dataAtThisTimepoint = measurementsForToolGroup.find(entry => {
- return (
- entry.timepointId === timepointId &&
- entry.measurementNumber === measurementNumber
- );
- });
-
- if (!dataAtThisTimepoint) {
- measurementsToJumpTo.push(null);
- continue;
- }
-
- let measurement = dataAtThisTimepoint;
-
- const { tool } = MeasurementApi.getToolConfiguration(toolType);
- if (options.childToolKey) {
- measurement = dataAtThisTimepoint[options.childToolKey];
- } else if (Array.isArray(tool.childTools)) {
- const key = tool.childTools.find(key => !!dataAtThisTimepoint[key]);
- measurement = dataAtThisTimepoint[key];
- }
-
- measurementsToJumpTo.push(measurement);
- }
-
- // TODO: Add a single viewports state action which allows
- // - viewportData to be set
- // - layout to be set
- // - activeViewport to be set
-
- // Needs to update viewports.viewportData state to set image set data
-
- const displaySetContainsSopInstance = (displaySet, SOPInstanceUID) => {
- if (!displaySet.images || !displaySet.images.length) {
- return;
- }
-
- return displaySet.images.find(
- image => image.getSOPInstanceUID() === SOPInstanceUID
- );
- };
-
- const viewportSpecificData = [];
- measurementsToJumpTo.forEach((data, viewportIndex) => {
- // Skip if there is no measurement to jump
- if (!data) {
- return;
- }
-
- const study = studyMetadataManager.get(data.StudyInstanceUID);
- if (!study) {
- throw new Error('Study not found.');
- }
-
- const displaySet = study.findDisplaySet(displaySet => {
- return displaySetContainsSopInstance(displaySet, data.SOPInstanceUID);
- });
-
- if (!displaySet) {
- throw new Error('Display set not found.');
- }
-
- displaySet.SOPInstanceUID = data.SOPInstanceUID;
- if (data.frameIndex) {
- displaySet.frameIndex = data.frameIndex;
- }
-
- viewportIndex =
- (viewportIndex + viewportsState.activeViewportIndex) % numViewports;
- viewportSpecificData.push({
- viewportIndex,
- displaySet,
- });
- });
-
- return {
- viewportSpecificData,
- layout: [], // TODO: if we need to change layout, we should return this here
- };
-}
diff --git a/platform/viewer/src/components/EmptyViewport.jsx b/platform/viewer/src/components/EmptyViewport.jsx
index 70c684cfc..a6fa6f3ac 100644
--- a/platform/viewer/src/components/EmptyViewport.jsx
+++ b/platform/viewer/src/components/EmptyViewport.jsx
@@ -1,11 +1,7 @@
import React from 'react';
function EmptyViewport() {
- return (
-
-
Please drag a stack here to view images.
-
- );
+ return
;
}
export default EmptyViewport;
diff --git a/platform/viewer/src/components/Header/Header.css b/platform/viewer/src/components/Header/Header.css
deleted file mode 100644
index 7d8d1624d..000000000
--- a/platform/viewer/src/components/Header/Header.css
+++ /dev/null
@@ -1,142 +0,0 @@
-/* Viewer Route */
-.entry-header {
- padding: 10px 15px;
- height: var(--top-bar-height);
-}
-
-.header-left-box {
- display: inline-block;
- position: relative;
-}
-
-.header-brand {
- text-decoration: none;
- height: 30px;
- float: left;
- clear: both;
-}
-
-/* Home Page */
-.entry-header.header-big {
- background: rgba(21, 25, 30, 0.7);
- padding: 35px var(--study-list-padding);
- height: auto;
- display: inline-block;
- width: 100%;
-}
-
-.entry-header.header-big .header-brand {
- height: 50px;
- padding: 0;
-}
-
-.entry-header.header-big .header-logo-image {
- margin-right: 20px;
- width: 50px;
- height: 50px;
-}
-
-.entry-header.header-big .header-logo-text {
- width: 474px;
- height: auto;
-}
-
-/** OTHER STYLES **/
-
-.dd-item {
- width: 100%;
-}
-
-.header-viewerLink {
- float: left;
-}
-
-.header-logo-image {
- fill: transparent;
- height: 100%;
- margin: 0 8px 0 0;
- width: 30px;
- float: left;
-}
-
-.header-btn {
- color: var(--text-secondary-color);
- cursor: pointer;
- font-size: 13px;
- font-weight: 500;
- line-height: 26px;
-}
-
-.header-btn:hover {
- color: var(--hover-color);
-}
-
-.header-btn:active {
- color: var(--active-color);
-}
-
-.header-studyListLinkSection {
- border-left: var(--ui-border-thickness) solid var(--ui-border-color);
- margin: 3px 0 0 10px;
- padding: 0 0 0 10px;
- display: inline-block;
-}
-
-.header-menu {
- color: var(--text-primary-color);
- float: right;
- padding: 4px 0;
- font-size: 13px;
- font-weight: 400;
- line-height: 18px;
- text-decoration: none;
- margin-right: 10px;
-}
-
-.entry-header.header-big .header-menu {
- margin-right: 0;
-}
-
-.header-menu .research-use {
- float: left;
- font-size: 13px;
- font-weight: 700;
- color: #91b9cd;
- margin-right: 1rem;
-}
-
-.notification-bar {
- display: none;
- position: absolute;
- height: 20px;
- line-height: 20px;
- width: 100%;
- background-color: #91b9cd;
- color: #ffffff;
- font-weight: bold;
- text-align: center;
-}
-
-@media only screen and (max-width: 768px) {
- .entry-header,
- .entry-header.header-big {
- padding: 30px 15px 10px 15px;
- }
- .entry-header.header-big .header-logo-image {
- margin: 0 10px 0 0;
- width: 25px;
- height: 25px;
- }
-
- .entry-header.header-big .header-logo-text {
- width: 40%;
- }
-
- /* Toggle Notification Bar */
- .notification-bar {
- display: block;
- }
- .header-menu .research-use {
- display: none;
- }
-}
diff --git a/platform/viewer/src/components/Header/Header.js b/platform/viewer/src/components/Header/Header.js
deleted file mode 100644
index 19b7c76c0..000000000
--- a/platform/viewer/src/components/Header/Header.js
+++ /dev/null
@@ -1,124 +0,0 @@
-import React, { useState, useEffect } from 'react';
-import { Link, withRouter } from 'react-router-dom';
-import { withTranslation } from 'react-i18next';
-import PropTypes from 'prop-types';
-import classNames from 'classnames';
-import { Dropdown, AboutContent, withModal } from '@ohif/ui';
-//
-import { UserPreferences } from './../UserPreferences';
-import OHIFLogo from '../OHIFLogo/OHIFLogo.js';
-import './Header.css';
-
-function Header(props) {
- const {
- t,
- user,
- userManager,
- modal: { show },
- useLargeLogo,
- linkPath,
- linkText,
- location,
- children,
- } = props;
-
- const [options, setOptions] = useState([]);
- const hasLink = linkText && linkPath;
-
- useEffect(() => {
- const optionsValue = [
- {
- title: t('About'),
- icon: { name: 'info' },
- onClick: () =>
- show({
- content: AboutContent,
- title: t('OHIF Viewer - About'),
- }),
- },
- {
- title: t('Preferences'),
- icon: {
- name: 'user',
- },
- onClick: () =>
- show({
- content: UserPreferences,
- title: t('User Preferences'),
- }),
- },
- ];
-
- if (user && userManager) {
- optionsValue.push({
- title: t('Logout'),
- icon: { name: 'power-off' },
- onClick: () => userManager.signoutRedirect(),
- });
- }
-
- setOptions(optionsValue);
- }, [setOptions, show, t, user, userManager]);
-
- return (
- <>
-
{t('INVESTIGATIONAL USE ONLY')}
-
-
- {location && location.studyLink && (
-
- {t('Back to Viewer')}
-
- )}
-
- {children}
-
- {hasLink && (
-
- {t(linkText)}
-
- )}
-
-
-
- {t('INVESTIGATIONAL USE ONLY')}
-
-
-
- >
- );
-}
-
-Header.propTypes = {
- // Study list, /
- linkText: PropTypes.string,
- linkPath: PropTypes.string,
- useLargeLogo: PropTypes.bool,
- //
- location: PropTypes.object.isRequired,
- children: PropTypes.node,
- t: PropTypes.func.isRequired,
- userManager: PropTypes.object,
- user: PropTypes.object,
- modal: PropTypes.object,
-};
-
-Header.defaultProps = {
- useLargeLogo: false,
- children: OHIFLogo(),
-};
-
-export default withTranslation(['Header', 'AboutModal'])(
- withRouter(withModal(Header))
-);
diff --git a/platform/viewer/src/components/SidePanel.css b/platform/viewer/src/components/SidePanel.css
deleted file mode 100644
index 891ffefca..000000000
--- a/platform/viewer/src/components/SidePanel.css
+++ /dev/null
@@ -1,48 +0,0 @@
-.FlexboxLayout {
- display: flex;
- flex: 1;
- flex-flow: row nowrap;
- align-items: stretch;
- height: calc(100% - var(--toolbar-height) - var(--top-bar-height));
- width: 100%;
- overflow: hidden;
-}
-
-.sidepanel {
- flex: 1;
- height: 100%;
- transition: var(--sidepanel-transition);
- overflow-y: auto;
-}
-
-.from-left {
- border-right: var(--ui-border-thickness) solid var(--ui-border-color);
- margin-left: calc(var(--left-sidepanel-menu-width) * -1);
- max-width: var(--left-sidepanel-menu-width);
-}
-
-.from-right {
- border-left: var(--ui-border-thickness) solid var(--ui-border-color);
- margin-right: calc(var(--right-sidepanel-menu-width) * -1);
- max-width: var(--right-sidepanel-menu-width);
-}
-
-.sidepanel.is-open {
- margin-right: 0;
- margin-left: 0;
-}
-
-.main-content {
- flex: 1;
- height: 100%;
- overflow: hidden;
- transition: var(--sidepanel-transition);
- width: 100%;
-}
-
-@media only screen and (max-width: 768px) {
- /* Account for "Investigational Use" banner height */
- .FlexboxLayout {
- height: calc(100% - var(--toolbar-height) - var(--top-bar-height) - 16px);
- }
-}
diff --git a/platform/viewer/src/customHooks/useQuery.js b/platform/viewer/src/customHooks/useQuery.js
deleted file mode 100644
index 6a2ea87a9..000000000
--- a/platform/viewer/src/customHooks/useQuery.js
+++ /dev/null
@@ -1,11 +0,0 @@
-import { useLocation } from 'react-router-dom';
-
-/**
- * hook that builds on useLocation to parse
- * the query string for you.
- *
- * @name useQuery
- */
-export default function () {
- return new URLSearchParams(useLocation().search);
-}
diff --git a/yarn.lock b/yarn.lock
index 19aeaf498..080570257 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -7364,10 +7364,10 @@ dateformat@^3.0.0:
resolved "https://registry.yarnpkg.com/dateformat/-/dateformat-3.0.3.tgz#a6e37499a4d9a9cf85ef5872044d62901c9889ae"
integrity sha512-jyCETtSl3VMZMWeRo7iY1FL19ges1t55hMo5yaam4Jrsm5EPL89UQkoQRyiI+Yf4k8r2ZpdngkV8hr1lIdjb3Q==
-dcmjs@0.14.1:
- version "0.14.1"
- resolved "https://registry.yarnpkg.com/dcmjs/-/dcmjs-0.14.1.tgz#4a4f18d1e5332d38429e2d77340a6ad0052ec71e"
- integrity sha512-GGGQt4zjX7Fp0rLO5rcIQgmxZdLsEwBSZ1T74iXeJG5W32P1yiodJfBW900tNZCKj3zWamO3f5jDC1Xkv81fdg==
+dcmjs@0.14.2:
+ version "0.14.2"
+ resolved "https://registry.yarnpkg.com/dcmjs/-/dcmjs-0.14.2.tgz#bc4926c3312632ec61a5d68753c0857aebb65793"
+ integrity sha512-W4/f34Ph6Nrc95QhL/7f1kPlfR2YJMbyEsbPELt3xml17SFnkEgXAeO41qHZ7KywozO/lBW5sXGOpMenuYVV2g==
dependencies:
"@babel/polyfill" "^7.8.3"
"@babel/runtime" "^7.8.4"
@@ -17890,20 +17890,20 @@ react-clientside-effect@^1.2.2:
dependencies:
"@babel/runtime" "^7.0.0"
-react-cornerstone-viewport@2.3.8:
- version "2.3.8"
- resolved "https://registry.yarnpkg.com/react-cornerstone-viewport/-/react-cornerstone-viewport-2.3.8.tgz#7af8360f29bca986ae4e36b4e503269b88ddc52f"
- integrity sha512-aiG2uVNrDY6SQx4t/HBxIA3zsMsCwT+6TpcXK9qSSoXhs+X6OTmYEKncWUqL0jtxU1yfh6JTUz8ARTg03gtF+A==
+react-cornerstone-viewport@2.3.9:
+ version "2.3.9"
+ resolved "https://registry.yarnpkg.com/react-cornerstone-viewport/-/react-cornerstone-viewport-2.3.9.tgz#f9761da8e536f0a217137c6ca1a983f5882249f9"
+ integrity sha512-qrhq8CbX/jq6b93cQjV2qC/mhHOvFBpxzxcHlvHzEQZt/rmRMcaYxCqjpNaNbUmmBu61wNkxesUVsggkPTTcqg==
dependencies:
classnames "^2.2.6"
date-fns "^2.2.1"
prop-types "^15.7.2"
react-resize-detector "^4.2.1"
-react-cornerstone-viewport@2.3.9:
- version "2.3.9"
- resolved "https://registry.yarnpkg.com/react-cornerstone-viewport/-/react-cornerstone-viewport-2.3.9.tgz#f9761da8e536f0a217137c6ca1a983f5882249f9"
- integrity sha512-qrhq8CbX/jq6b93cQjV2qC/mhHOvFBpxzxcHlvHzEQZt/rmRMcaYxCqjpNaNbUmmBu61wNkxesUVsggkPTTcqg==
+react-cornerstone-viewport@3.0.0:
+ version "3.0.0"
+ resolved "https://registry.yarnpkg.com/react-cornerstone-viewport/-/react-cornerstone-viewport-3.0.0.tgz#c7be6dc29762fc844c639a73c3292feb69e31ba5"
+ integrity sha512-hLneVVOrZZlCkIhsKVdIHBGVPbOmeu5tsrPXaeCfsOlA5y7JhtacjuKHL4xzGmlXiCipftgiZ9+4gC2gcJSlcw==
dependencies:
classnames "^2.2.6"
date-fns "^2.2.1"