diff --git a/platform/viewer/src/connectedComponents/ConnectedStudyBrowser.js b/platform/viewer/src/connectedComponents/ConnectedStudyBrowser.js
deleted file mode 100644
index 624837c67..000000000
--- a/platform/viewer/src/connectedComponents/ConnectedStudyBrowser.js
+++ /dev/null
@@ -1,57 +0,0 @@
-import OHIF from '@ohif/core';
-import { connect } from 'react-redux';
-import { StudyBrowser } from '@ohif/ui';
-import cloneDeep from 'lodash.clonedeep';
-import findDisplaySetByUID from './findDisplaySetByUID';
-
-const { setActiveViewportSpecificData } = OHIF.redux.actions;
-
-// TODO
-// - Determine in which display set is active from Redux (activeViewportIndex and layout viewportData)
-// - Pass in errors and stack loading progress from Redux
-const mapStateToProps = (state, ownProps) => {
- // If we know that the stack loading progress details have changed,
- // we can try to update the component state so that the thumbnail
- // progress bar is updated
- const stackLoadingProgressMap = state.loading.progress;
- const studiesWithLoadingData = cloneDeep(ownProps.studies);
-
- studiesWithLoadingData.forEach(study => {
- study.thumbnails.forEach(data => {
- const { displaySetInstanceUID } = data;
- const stackId = `StackProgress:${displaySetInstanceUID}`;
- const stackProgressData = stackLoadingProgressMap[stackId];
-
- let stackPercentComplete = 0;
- if (stackProgressData) {
- stackPercentComplete = stackProgressData.percentComplete;
- }
-
- data.stackPercentComplete = stackPercentComplete;
- });
- });
-
- return {
- studies: studiesWithLoadingData,
- };
-};
-
-const mapDispatchToProps = (dispatch, ownProps) => {
- return {
- onThumbnailClick: displaySetInstanceUID => {
- const displaySet = findDisplaySetByUID(
- ownProps.studyMetadata,
- displaySetInstanceUID
- );
-
- dispatch(setActiveViewportSpecificData(displaySet));
- },
- };
-};
-
-const ConnectedStudyBrowser = connect(
- mapStateToProps,
- mapDispatchToProps
-)(StudyBrowser);
-
-export default ConnectedStudyBrowser;
diff --git a/platform/viewer/src/connectedComponents/ConnectedViewerMain.js b/platform/viewer/src/connectedComponents/ConnectedViewerMain.js
deleted file mode 100644
index bb121bcb4..000000000
--- a/platform/viewer/src/connectedComponents/ConnectedViewerMain.js
+++ /dev/null
@@ -1,37 +0,0 @@
-import OHIF from '@ohif/core';
-import ViewerMain from './ViewerMain';
-import { connect } from 'react-redux';
-
-const {
- setViewportSpecificData,
- clearViewportSpecificData,
-} = OHIF.redux.actions;
-
-const mapStateToProps = state => {
- const { activeViewportIndex, layout, viewportSpecificData } = state.viewports;
-
- return {
- activeViewportIndex,
- layout,
- viewportSpecificData,
- viewports: state.viewports,
- };
-};
-
-const mapDispatchToProps = dispatch => {
- return {
- setViewportSpecificData: (viewportIndex, data) => {
- dispatch(setViewportSpecificData(viewportIndex, data));
- },
- clearViewportSpecificData: () => {
- dispatch(clearViewportSpecificData());
- },
- };
-};
-
-const ConnectedViewerMain = connect(
- mapStateToProps,
- mapDispatchToProps
-)(ViewerMain);
-
-export default ConnectedViewerMain;
diff --git a/platform/viewer/src/connectedComponents/ConnectedViewerRetrieveStudyData.js b/platform/viewer/src/connectedComponents/ConnectedViewerRetrieveStudyData.js
deleted file mode 100644
index 387bea839..000000000
--- a/platform/viewer/src/connectedComponents/ConnectedViewerRetrieveStudyData.js
+++ /dev/null
@@ -1,28 +0,0 @@
-import { connect } from 'react-redux';
-import ViewerRetrieveStudyData from './ViewerRetrieveStudyData.js';
-import OHIF from '@ohif/core';
-
-const { clearViewportSpecificData } = OHIF.redux.actions;
-const isActive = a => a.active === true;
-
-const mapStateToProps = (state, ownProps) => {
- const activeServer = state.servers.servers.find(isActive);
-
- return {
- server: ownProps.server || activeServer,
- };
-};
-const mapDispatchToProps = dispatch => {
- return {
- clearViewportSpecificData: () => {
- dispatch(clearViewportSpecificData());
- },
- };
-};
-
-const ConnectedViewerRetrieveStudyData = connect(
- mapStateToProps,
- mapDispatchToProps
-)(ViewerRetrieveStudyData);
-
-export default ConnectedViewerRetrieveStudyData;
diff --git a/platform/viewer/src/connectedComponents/ToolContextMenu.js b/platform/viewer/src/connectedComponents/ToolContextMenu.js
deleted file mode 100644
index 13dc3aeca..000000000
--- a/platform/viewer/src/connectedComponents/ToolContextMenu.js
+++ /dev/null
@@ -1,114 +0,0 @@
-import { ContextMenu } from '@ohif/ui';
-import PropTypes from 'prop-types';
-import React from 'react';
-import { commandsManager } from './../App.jsx';
-
-const toolTypes = [
- 'Angle',
- 'Bidirectional',
- 'Length',
- 'FreehandMouse',
- 'EllipticalRoi',
- 'CircleRoi',
- 'RectangleRoi',
-];
-
-const ToolContextMenu = ({
- onSetLabel,
- onSetDescription,
- isTouchEvent,
- eventData,
- onClose,
- onDelete,
-}) => {
- const defaultDropdownItems = [
- {
- label: 'Delete measurement',
- actionType: 'Delete',
- action: ({ nearbyToolData, eventData }) =>
- onDelete(nearbyToolData, eventData),
- },
- {
- label: 'Relabel',
- actionType: 'setLabel',
- action: ({ nearbyToolData, eventData }) => {
- const { tool: measurementData } = nearbyToolData;
- onSetLabel(eventData, measurementData);
- },
- },
- {
- actionType: 'setDescription',
- action: ({ nearbyToolData, eventData }) => {
- const { tool: measurementData } = nearbyToolData;
- onSetDescription(eventData, measurementData);
- },
- },
- ];
-
- const getDropdownItems = (eventData, isTouchEvent = false) => {
- const nearbyToolData = commandsManager.runCommand('getNearbyToolData', {
- element: eventData.element,
- canvasCoordinates: eventData.currentPoints.canvas,
- availableToolTypes: toolTypes,
- });
-
- /*
- * Annotate tools for touch events already have a press handle to edit it,
- * has a better UX for deleting it.
- */
- if (
- isTouchEvent &&
- nearbyToolData &&
- nearbyToolData.toolType === 'arrowAnnotate'
- ) {
- return;
- }
-
- let dropdownItems = [];
- if (nearbyToolData) {
- defaultDropdownItems.forEach(item => {
- item.params = { eventData, nearbyToolData };
-
- if (item.actionType === 'setDescription') {
- item.label = `${
- nearbyToolData.tool.description ? 'Edit' : 'Add'
- } Description`;
- }
-
- dropdownItems.push(item);
- });
- }
-
- return dropdownItems;
- };
-
- const onClickHandler = ({ action, params }) => {
- action(params);
- if (onClose) {
- onClose();
- }
- };
-
- const dropdownItems = getDropdownItems(eventData, isTouchEvent);
-
- return (
-
-
-
- );
-};
-
-ToolContextMenu.propTypes = {
- isTouchEvent: PropTypes.bool.isRequired,
- eventData: PropTypes.object,
- onClose: PropTypes.func,
- onSetDescription: PropTypes.func,
- onSetLabel: PropTypes.func,
- onDelete: PropTypes.func,
-};
-
-ToolContextMenu.defaultProps = {
- isTouchEvent: false,
-};
-
-export default ToolContextMenu;
diff --git a/platform/viewer/src/connectedComponents/ToolbarRow.js b/platform/viewer/src/connectedComponents/ToolbarRow.js
deleted file mode 100644
index 3a9d7ad9e..000000000
--- a/platform/viewer/src/connectedComponents/ToolbarRow.js
+++ /dev/null
@@ -1,386 +0,0 @@
-import React, { Component } from 'react';
-import PropTypes from 'prop-types';
-import { withTranslation } from 'react-i18next';
-
-import { MODULE_TYPES } from '@ohif/core';
-import {
- ExpandableToolMenu,
- RoundedButtonGroup,
- ToolbarButton,
- withModal,
- withDialog,
-} from '@ohif/ui';
-
-import './ToolbarRow.css';
-import { commandsManager, extensionManager } from './../App.jsx';
-
-import ConnectedCineDialog from './ConnectedCineDialog';
-import ConnectedLayoutButton from './ConnectedLayoutButton';
-import { withAppContext } from '../context/AppContext';
-
-class ToolbarRow extends Component {
- // TODO: Simplify these? isOpen can be computed if we say "any" value for selected,
- // closed if selected is null/undefined
- static propTypes = {
- isLeftSidePanelOpen: PropTypes.bool.isRequired,
- isRightSidePanelOpen: PropTypes.bool.isRequired,
- selectedLeftSidePanel: PropTypes.string.isRequired,
- selectedRightSidePanel: PropTypes.string.isRequired,
- handleSidePanelChange: PropTypes.func.isRequired,
- activeContexts: PropTypes.arrayOf(PropTypes.string).isRequired,
- studies: PropTypes.array,
- t: PropTypes.func.isRequired,
- // NOTE: withDialog, withModal HOCs
- dialog: PropTypes.any,
- modal: PropTypes.any,
- };
-
- static defaultProps = {
- studies: [],
- };
-
- constructor(props) {
- super(props);
-
- const toolbarButtonDefinitions = _getVisibleToolbarButtons.call(this);
- // TODO:
- // If it's a tool that can be active... Mark it as active?
- // - Tools that are on/off?
- // - Tools that can be bound to multiple buttons?
-
- // Normal ToolbarButtons...
- // Just how high do we need to hoist this state?
- // Why ToolbarRow instead of just Toolbar? Do we have any others?
- this.state = {
- toolbarButtons: toolbarButtonDefinitions,
- activeButtons: [],
- };
-
- this.seriesPerStudyCount = [];
-
- this._handleBuiltIn = _handleBuiltIn.bind(this);
-
- this.updateButtonGroups();
- }
-
- updateButtonGroups() {
- const panelModules = extensionManager.modules[MODULE_TYPES.PANEL];
-
- this.buttonGroups = {
- left: [],
- right: [],
- };
-
- // ~ FIND MENU OPTIONS
- panelModules.forEach(panelExtension => {
- const panelModule = panelExtension.module;
- const defaultContexts = Array.from(panelModule.defaultContext);
-
- panelModule.menuOptions.forEach(menuOption => {
- const contexts = Array.from(menuOption.context || defaultContexts);
- const hasActiveContext = this.props.activeContexts.some(actx =>
- contexts.includes(actx)
- );
-
- // It's a bit beefy to pass studies; probably only need to be reactive on `studyInstanceUIDs` and activeViewport?
- // Note: This does not cleanly handle `studies` prop updating with panel open
- const isDisabled =
- typeof menuOption.isDisabled === 'function' &&
- menuOption.isDisabled(this.props.studies);
-
- if (hasActiveContext && !isDisabled) {
- const menuOptionEntry = {
- value: menuOption.target,
- icon: menuOption.icon,
- bottomLabel: menuOption.label,
- };
- const from = menuOption.from || 'right';
-
- this.buttonGroups[from].push(menuOptionEntry);
- }
- });
- });
-
- // TODO: This should come from extensions, instead of being baked in
- this.buttonGroups.left.unshift({
- value: 'studies',
- icon: 'th-large',
- bottomLabel: this.props.t('Series'),
- });
- }
-
- componentDidUpdate(prevProps) {
- const activeContextsChanged =
- prevProps.activeContexts !== this.props.activeContexts;
-
- const prevStudies = prevProps.studies;
- const studies = this.props.studies;
- const seriesPerStudyCount = this.seriesPerStudyCount;
-
- let studiesUpdated = false;
-
- if (prevStudies.length !== studies.length) {
- studiesUpdated = true;
- } else {
- for (let i = 0; i < studies.length; i++) {
- if (studies[i].series.length !== seriesPerStudyCount[i]) {
- seriesPerStudyCount[i] = studies[i].series.length;
-
- studiesUpdated = true;
- break;
- }
- }
- }
-
- if (studiesUpdated) {
- this.updateButtonGroups();
- }
-
- if (activeContextsChanged) {
- this.setState(
- {
- toolbarButtons: _getVisibleToolbarButtons.call(this),
- },
- this.closeCineDialogIfNotApplicable
- );
- }
- }
-
- closeCineDialogIfNotApplicable = () => {
- const { dialog } = this.props;
- let { dialogId, activeButtons, toolbarButtons } = this.state;
- if (dialogId) {
- const cineButtonPresent = toolbarButtons.find(
- button => button.options && button.options.behavior === 'CINE'
- );
- if (!cineButtonPresent) {
- dialog.dismiss({ id: dialogId });
- activeButtons = activeButtons.filter(
- button => button.options && button.options.behavior !== 'CINE'
- );
- this.setState({ dialogId: null, activeButtons });
- }
- }
- };
-
- render() {
- const buttonComponents = _getButtonComponents.call(
- this,
- this.state.toolbarButtons,
- this.state.activeButtons
- );
-
- const onPress = (side, value) => {
- this.props.handleSidePanelChange(side, value);
- };
- const onPressLeft = onPress.bind(this, 'left');
- const onPressRight = onPress.bind(this, 'right');
-
- return (
- <>
-
-
-
-
- {buttonComponents}
-
-
- {this.buttonGroups.right.length && (
-
- )}
-
-
- >
- );
- }
-}
-
-function _getCustomButtonComponent(button, activeButtons) {
- const CustomComponent = button.CustomComponent;
- const isValidComponent = typeof CustomComponent === 'function';
-
- // Check if its a valid customComponent. Later on an CustomToolbarComponent interface could be implemented.
- if (isValidComponent) {
- const parentContext = this;
- const activeButtonsIds = activeButtons.map(button => button.id);
- const isActive = activeButtonsIds.includes(button.id);
-
- return (
-
- );
- }
-}
-
-function _getExpandableButtonComponent(button, activeButtons) {
- // Iterate over button definitions and update `onClick` behavior
- let activeCommand;
- const childButtons = button.buttons.map(childButton => {
- childButton.onClick = _handleToolbarButtonClick.bind(this, childButton);
-
- if (activeButtons.map(button => button.id).indexOf(childButton.id) > -1) {
- activeCommand = childButton.id;
- }
-
- return childButton;
- });
-
- return (
-
- );
-}
-
-function _getDefaultButtonComponent(button, activeButtons) {
- return (
- button.id).includes(button.id)}
- />
- );
-}
-/**
- * Determine which extension buttons should be showing, if they're
- * active, and what their onClick behavior should be.
- */
-function _getButtonComponents(toolbarButtons, activeButtons) {
- const _this = this;
- return toolbarButtons.map(button => {
- const hasCustomComponent = button.CustomComponent;
- const hasNestedButtonDefinitions = button.buttons && button.buttons.length;
-
- if (hasCustomComponent) {
- return _getCustomButtonComponent.call(_this, button, activeButtons);
- }
-
- if (hasNestedButtonDefinitions) {
- return _getExpandableButtonComponent.call(_this, button, activeButtons);
- }
-
- return _getDefaultButtonComponent.call(_this, button, activeButtons);
- });
-}
-
-/**
- * TODO: DEPRECATE
- * This is used exclusively in `extensions/cornerstone/src`
- * We have better ways with new UI Services to trigger "builtin" behaviors
- *
- * A handy way for us to handle different button types. IE. firing commands for
- * buttons, or initiation built in behavior.
- *
- * @param {*} button
- * @param {*} evt
- * @param {*} props
- */
-function _handleToolbarButtonClick(button, evt, props) {
- const { activeButtons } = this.state;
-
- if (button.commandName) {
- const options = Object.assign({ evt }, button.commandOptions);
- commandsManager.runCommand(button.commandName, options);
- }
-
- // TODO: Use Types ENUM
- // TODO: We can update this to be a `getter` on the extension to query
- // For the active tools after we apply our updates?
- if (button.type === 'setToolActive') {
- const toggables = activeButtons.filter(
- ({ options }) => options && !options.togglable
- );
- this.setState({ activeButtons: [...toggables, button] });
- } else if (button.type === 'builtIn') {
- this._handleBuiltIn(button);
- }
-}
-
-/**
- *
- */
-function _getVisibleToolbarButtons() {
- const toolbarModules = extensionManager.modules[MODULE_TYPES.TOOLBAR];
- const toolbarButtonDefinitions = [];
-
- toolbarModules.forEach(extension => {
- const { definitions, defaultContext } = extension.module;
- definitions.forEach(definition => {
- const context = definition.context || defaultContext;
-
- if (this.props.activeContexts.includes(context)) {
- toolbarButtonDefinitions.push(definition);
- }
- });
- });
-
- return toolbarButtonDefinitions;
-}
-
-function _handleBuiltIn(button) {
- /* TODO: Keep cine button active until its unselected. */
- const { dialog, t } = this.props;
- const { dialogId } = this.state;
- const { id, options } = button;
-
- if (options.behavior === 'CINE') {
- if (dialogId) {
- dialog.dismiss({ id: dialogId });
- this.setState(state => ({
- dialogId: null,
- activeButtons: [
- ...state.activeButtons.filter(button => button.id !== id),
- ],
- }));
- } else {
- const spacing = 20;
- const { x, y } = document
- .querySelector(`.ViewerMain`)
- .getBoundingClientRect();
- const newDialogId = dialog.create({
- content: ConnectedCineDialog,
- defaultPosition: {
- x: x + spacing || 0,
- y: y + spacing || 0,
- },
- });
- this.setState(state => ({
- dialogId: newDialogId,
- activeButtons: [...state.activeButtons, button],
- }));
- }
- }
-
- if (options.behavior === 'DOWNLOAD_SCREEN_SHOT') {
- commandsManager.runCommand('showDownloadViewportModal', {
- title: t('Download High Quality Image'),
- });
- }
-}
-
-export default withTranslation(['Common', 'ViewportDownloadForm'])(
- withModal(withDialog(withAppContext(ToolbarRow)))
-);
diff --git a/platform/viewer/src/connectedComponents/Viewer.js b/platform/viewer/src/connectedComponents/Viewer.js
deleted file mode 100644
index ee85b8b9b..000000000
--- a/platform/viewer/src/connectedComponents/Viewer.js
+++ /dev/null
@@ -1,400 +0,0 @@
-import React, { Component } from 'react';
-import PropTypes from 'prop-types';
-import classNames from 'classnames';
-
-import { MODULE_TYPES } from '@ohif/core';
-import OHIF, { DICOMSR } from '@ohif/core';
-import { withDialog } from '@ohif/ui';
-import moment from 'moment';
-import ConnectedHeader from './ConnectedHeader.js';
-import ToolbarRow from './ToolbarRow.js';
-import ConnectedStudyBrowser from './ConnectedStudyBrowser.js';
-import ConnectedViewerMain from './ConnectedViewerMain.js';
-import SidePanel from './../components/SidePanel.js';
-import { extensionManager } from './../App.jsx';
-
-// Contexts
-import WhiteLabelingContext from '../context/WhiteLabelingContext.js';
-import UserManagerContext from '../context/UserManagerContext';
-import AppContext from '../context/AppContext';
-
-import './Viewer.css';
-
-class Viewer extends Component {
- static propTypes = {
- studies: PropTypes.arrayOf(
- PropTypes.shape({
- StudyInstanceUID: PropTypes.string.isRequired,
- StudyDate: PropTypes.string,
- displaySets: PropTypes.arrayOf(
- PropTypes.shape({
- displaySetInstanceUID: PropTypes.string.isRequired,
- SeriesDescription: PropTypes.string,
- SeriesNumber: PropTypes.number,
- InstanceNumber: PropTypes.number,
- numImageFrames: PropTypes.number,
- Modality: PropTypes.string.isRequired,
- images: PropTypes.arrayOf(
- PropTypes.shape({
- getImageId: PropTypes.func.isRequired,
- })
- ),
- })
- ),
- })
- ),
- studyInstanceUIDs: PropTypes.array,
- activeServer: PropTypes.shape({
- type: PropTypes.string,
- wadoRoot: PropTypes.string,
- }),
- onTimepointsUpdated: PropTypes.func,
- onMeasurementsUpdated: PropTypes.func,
- // window.store.getState().viewports.viewportSpecificData
- viewports: PropTypes.object.isRequired,
- // window.store.getState().viewports.activeViewportIndex
- activeViewportIndex: PropTypes.number.isRequired,
- isStudyLoaded: PropTypes.bool,
- dialog: PropTypes.object,
- };
-
- constructor(props) {
- super(props);
-
- const { activeServer } = this.props;
- const server = Object.assign({}, activeServer);
-
- OHIF.measurements.MeasurementApi.setConfiguration({
- dataExchange: {
- retrieve: DICOMSR.retrieveMeasurements,
- store: DICOMSR.storeMeasurements,
- },
- server,
- });
-
- OHIF.measurements.TimepointApi.setConfiguration({
- dataExchange: {
- retrieve: this.retrieveTimepoints,
- store: this.storeTimepoints,
- remove: this.removeTimepoint,
- update: this.updateTimepoint,
- disassociate: this.disassociateStudy,
- },
- });
- }
-
- state = {
- isLeftSidePanelOpen: true,
- isRightSidePanelOpen: false,
- selectedRightSidePanel: '',
- selectedLeftSidePanel: 'studies', // TODO: Don't hardcode this
- thumbnails: [],
- };
-
- componentWillUnmount() {
- if (this.props.dialog) {
- this.props.dialog.dismissAll();
- }
- }
-
- retrieveTimepoints = filter => {
- OHIF.log.info('retrieveTimepoints');
-
- // Get the earliest and latest study date
- let earliestDate = new Date().toISOString();
- let latestDate = new Date().toISOString();
- if (this.props.studies) {
- latestDate = new Date('1000-01-01').toISOString();
- this.props.studies.forEach(study => {
- const StudyDate = moment(study.StudyDate, 'YYYYMMDD').toISOString();
- if (StudyDate < earliestDate) {
- earliestDate = StudyDate;
- }
- if (StudyDate > latestDate) {
- latestDate = StudyDate;
- }
- });
- }
-
- // Return a generic timepoint
- return Promise.resolve([
- {
- timepointType: 'baseline',
- timepointId: 'TimepointId',
- studyInstanceUIDs: this.props.studyInstanceUIDs,
- PatientID: filter.PatientID,
- earliestDate,
- latestDate,
- isLocked: false,
- },
- ]);
- };
-
- storeTimepoints = timepointData => {
- OHIF.log.info('storeTimepoints');
- return Promise.resolve();
- };
-
- updateTimepoint = (timepointData, query) => {
- OHIF.log.info('updateTimepoint');
- return Promise.resolve();
- };
-
- removeTimepoint = timepointId => {
- OHIF.log.info('removeTimepoint');
- return Promise.resolve();
- };
-
- disassociateStudy = (timepointIds, StudyInstanceUID) => {
- OHIF.log.info('disassociateStudy');
- return Promise.resolve();
- };
-
- onTimepointsUpdated = timepoints => {
- if (this.props.onTimepointsUpdated) {
- this.props.onTimepointsUpdated(timepoints);
- }
- };
-
- onMeasurementsUpdated = measurements => {
- if (this.props.onMeasurementsUpdated) {
- this.props.onMeasurementsUpdated(measurements);
- }
- };
-
- componentDidMount() {
- const { studies, isStudyLoaded } = this.props;
- const { TimepointApi, MeasurementApi } = OHIF.measurements;
- const currentTimepointId = 'TimepointId';
-
- const timepointApi = new TimepointApi(currentTimepointId, {
- onTimepointsUpdated: this.onTimepointsUpdated,
- });
-
- const measurementApi = new MeasurementApi(timepointApi, {
- onMeasurementsUpdated: this.onMeasurementsUpdated,
- });
-
- this.currentTimepointId = currentTimepointId;
- this.timepointApi = timepointApi;
- this.measurementApi = measurementApi;
-
- if (studies) {
- const PatientID = studies[0] && studies[0].PatientID;
-
- timepointApi.retrieveTimepoints({ PatientID });
- if (isStudyLoaded) {
- this.measurementApi.retrieveMeasurements(PatientID, [
- currentTimepointId,
- ]);
- }
- this.setState({
- thumbnails: _mapStudiesToThumbnails(studies),
- });
- }
- }
-
- componentDidUpdate(prevProps) {
- const { studies, isStudyLoaded } = this.props;
- if (studies !== prevProps.studies) {
- this.setState({
- thumbnails: _mapStudiesToThumbnails(studies),
- });
- }
- if (isStudyLoaded && isStudyLoaded !== prevProps.isStudyLoaded) {
- const PatientID = studies[0] && studies[0].PatientID;
- const { currentTimepointId } = this;
-
- this.timepointApi.retrieveTimepoints({ PatientID });
- this.measurementApi.retrieveMeasurements(PatientID, [currentTimepointId]);
- }
- }
-
- render() {
- let VisiblePanelLeft, VisiblePanelRight;
- const panelExtensions = extensionManager.modules[MODULE_TYPES.PANEL];
-
- panelExtensions.forEach(panelExt => {
- panelExt.module.components.forEach(comp => {
- if (comp.id === this.state.selectedRightSidePanel) {
- VisiblePanelRight = comp.component;
- } else if (comp.id === this.state.selectedLeftSidePanel) {
- VisiblePanelLeft = comp.component;
- }
- });
- });
-
- return (
- <>
- {/* HEADER */}
-
- {whiteLabeling => (
-
- {userManager => (
-
- {appContext => (
-
- {whiteLabeling &&
- whiteLabeling.createLogoComponentFn &&
- whiteLabeling.createLogoComponentFn(React)}
-
- )}
-
- )}
-
- )}
-
-
- {/* TOOLBAR */}
- {
- const sideClicked = side && side[0].toUpperCase() + side.slice(1);
- const openKey = `is${sideClicked}SidePanelOpen`;
- const selectedKey = `selected${sideClicked}SidePanel`;
- const updatedState = Object.assign({}, this.state);
-
- const isOpen = updatedState[openKey];
- const prevSelectedPanel = updatedState[selectedKey];
- // RoundedButtonGroup returns `null` if selected button is clicked
- const isSameSelectedPanel =
- prevSelectedPanel === selectedPanel || selectedPanel === null;
-
- updatedState[selectedKey] = selectedPanel || prevSelectedPanel;
-
- const isClosedOrShouldClose = !isOpen || isSameSelectedPanel;
- if (isClosedOrShouldClose) {
- updatedState[openKey] = !updatedState[openKey];
- }
-
- this.setState(updatedState);
- }}
- studies={this.props.studies}
- />
-
- {/**/}
- {/**/}
-
- {/* VIEWPORTS + SIDEPANELS */}
-
- {/* LEFT */}
-
- {VisiblePanelLeft ? (
-
- ) : (
-
- )}
-
-
- {/* MAIN */}
-
-
-
-
- {/* RIGHT */}
-
- {VisiblePanelRight && (
-
- )}
-
-
- >
- );
- }
-}
-
-export default withDialog(Viewer);
-
-/**
- * What types are these? Why do we have "mapping" dropped in here instead of in
- * a mapping layer?
- *
- * TODO[react]:
- * - Add sorting of display sets
- * - Add showStackLoadingProgressBar option
- *
- * @param {Study[]} studies
- * @param {DisplaySet[]} studies[].displaySets
- */
-const _mapStudiesToThumbnails = function(studies) {
- return studies.map(study => {
- const { StudyInstanceUID } = study;
-
- const thumbnails = study.displaySets.map(displaySet => {
- const {
- displaySetInstanceUID,
- SeriesDescription,
- SeriesNumber,
- InstanceNumber,
- numImageFrames,
- } = displaySet;
-
- let imageId;
- let altImageText;
-
- if (displaySet.Modality && displaySet.Modality === 'SEG') {
- // TODO: We want to replace this with a thumbnail showing
- // the segmentation map on the image, but this is easier
- // and better than what we have right now.
- altImageText = 'SEG';
- } else if (displaySet.images && displaySet.images.length) {
- const imageIndex = Math.floor(displaySet.images.length / 2);
-
- imageId = displaySet.images[imageIndex].getImageId();
- } else {
- altImageText = displaySet.Modality ? displaySet.Modality : 'UN';
- }
-
- return {
- imageId,
- altImageText,
- displaySetInstanceUID,
- SeriesDescription,
- SeriesNumber,
- InstanceNumber,
- numImageFrames,
- };
- });
-
- return {
- StudyInstanceUID,
- thumbnails,
- };
- });
-};
diff --git a/platform/viewer/src/connectedComponents/ViewerLocalFileData.js b/platform/viewer/src/connectedComponents/ViewerLocalFileData.js
deleted file mode 100644
index f2b6b116d..000000000
--- a/platform/viewer/src/connectedComponents/ViewerLocalFileData.js
+++ /dev/null
@@ -1,151 +0,0 @@
-import React, { Component } from 'react';
-import { metadata, utils } from '@ohif/core';
-
-import ConnectedViewer from './ConnectedViewer.js';
-import PropTypes from 'prop-types';
-import { extensionManager } from './../App.jsx';
-import Dropzone from 'react-dropzone';
-import filesToStudies from '../lib/filesToStudies';
-import './ViewerLocalFileData.css';
-import { withTranslation } from 'react-i18next';
-
-const { OHIFStudyMetadata } = metadata;
-const { studyMetadataManager } = utils;
-
-const dropZoneLinkDialog = (onDrop, i18n, dir) => {
- return (
-
- {({ getRootProps, getInputProps }) => (
-
- {dir ? (
-
- {i18n('Load folders')}
-
-
- ) : (
-
- {i18n('Load files')}
-
-
- )}
-
- )}
-
- );
-};
-
-const linksDialogMessage = (onDrop, i18n) => {
- return (
- <>
- {i18n('Or click to ')}
- {dropZoneLinkDialog(onDrop, i18n)}
- {i18n(' or ')}
- {dropZoneLinkDialog(onDrop, i18n, true)}
- {i18n(' from dialog')}
- >
- );
-};
-
-class ViewerLocalFileData extends Component {
- static propTypes = {
- studies: PropTypes.array,
- };
-
- state = {
- studies: null,
- loading: false,
- error: null,
- };
-
- updateStudies = studies => {
- // Render the viewer when the data is ready
- studyMetadataManager.purge();
-
- // Map studies to new format, update metadata manager?
- const updatedStudies = studies.map(study => {
- const studyMetadata = new OHIFStudyMetadata(
- study,
- study.StudyInstanceUID
- );
- const sopClassHandlerModules =
- extensionManager.modules['sopClassHandlerModule'];
-
- study.displaySets =
- study.displaySets ||
- studyMetadata.createDisplaySets(sopClassHandlerModules);
- studyMetadata.setDisplaySets(study.displaySets);
-
- studyMetadata.forEachDisplaySet(displayset => {
- displayset.localFile = true;
- });
-
- studyMetadataManager.add(studyMetadata);
-
- return study;
- });
-
- this.setState({
- studies: updatedStudies,
- });
- };
-
- render() {
- const onDrop = async acceptedFiles => {
- this.setState({ loading: true });
-
- const studies = await filesToStudies(acceptedFiles);
- const updatedStudies = this.updateStudies(studies);
-
- if (!updatedStudies) {
- return;
- }
-
- this.setState({ studies: updatedStudies, loading: false });
- };
-
- if (this.state.error) {
- return Error: {JSON.stringify(this.state.error)}
;
- }
-
- return (
-
- {({ getRootProps, getInputProps }) => (
-
- {this.state.studies ? (
-
a.StudyInstanceUID)
- }
- />
- ) : (
-
-
- {this.state.loading ? (
-
{this.props.t('Loading...')}
- ) : (
- <>
-
- {this.props.t(
- 'Drag and Drop DICOM files here to load them in the Viewer'
- )}
-
- {linksDialogMessage(onDrop, this.props.t)}
- >
- )}
-
-
- )}
-
- )}
-
- );
- }
-}
-
-export default withTranslation('Common')(ViewerLocalFileData);
diff --git a/platform/viewer/src/connectedComponents/ViewerMain.js b/platform/viewer/src/connectedComponents/ViewerMain.js
deleted file mode 100644
index 6a9589495..000000000
--- a/platform/viewer/src/connectedComponents/ViewerMain.js
+++ /dev/null
@@ -1,193 +0,0 @@
-import './ViewerMain.css';
-
-import { Component } from 'react';
-import { ConnectedViewportGrid } from './../components/ViewportGrid/index.js';
-import PropTypes from 'prop-types';
-import React from 'react';
-import memoize from 'lodash/memoize';
-import _values from 'lodash/values';
-
-var values = memoize(_values);
-
-class ViewerMain extends Component {
- static propTypes = {
- activeViewportIndex: PropTypes.number.isRequired,
- studies: PropTypes.array,
- viewportSpecificData: PropTypes.object.isRequired,
- layout: PropTypes.object.isRequired,
- setViewportSpecificData: PropTypes.func.isRequired,
- clearViewportSpecificData: PropTypes.func.isRequired,
- };
-
- constructor(props) {
- super(props);
-
- this.state = {
- displaySets: [],
- };
- }
-
- getDisplaySets(studies) {
- const displaySets = [];
- studies.forEach(study => {
- study.displaySets.forEach(dSet => {
- if (!dSet.plugin) {
- dSet.plugin = 'cornerstone';
- }
- displaySets.push(dSet);
- });
- });
-
- return displaySets;
- }
-
- findDisplaySet(studies, StudyInstanceUID, displaySetInstanceUID) {
- const study = studies.find(study => {
- return study.StudyInstanceUID === StudyInstanceUID;
- });
-
- if (!study) {
- return;
- }
-
- return study.displaySets.find(displaySet => {
- return displaySet.displaySetInstanceUID === displaySetInstanceUID;
- });
- }
-
- componentDidMount() {
- // Add beforeUnload event handler to check for unsaved changes
- //window.addEventListener('beforeunload', unloadHandlers.beforeUnload);
-
- // Get all the display sets for the viewer studies
- if (this.props.studies) {
- const displaySets = this.getDisplaySets(this.props.studies);
- this.setState({ displaySets }, this.fillEmptyViewportPanes);
- }
- }
-
- componentDidUpdate(prevProps) {
- const prevViewportAmount = prevProps.layout.viewports.length;
- const viewportAmount = this.props.layout.viewports.length;
- const isVtk = this.props.layout.viewports.some(vp => !!vp.vtk);
-
- if (
- this.props.studies !== prevProps.studies ||
- (viewportAmount !== prevViewportAmount && !isVtk)
- ) {
- const displaySets = this.getDisplaySets(this.props.studies);
- this.setState({ displaySets }, this.fillEmptyViewportPanes);
- }
- }
-
- fillEmptyViewportPanes = () => {
- // TODO: Here is the entry point for filling viewports on load.
- const dirtyViewportPanes = [];
- const { layout, viewportSpecificData } = this.props;
- const { displaySets } = this.state;
-
- if (!displaySets || !displaySets.length) {
- return;
- }
-
- for (let i = 0; i < layout.viewports.length; i++) {
- const viewportPane = viewportSpecificData[i];
- const isNonEmptyViewport =
- viewportPane &&
- viewportPane.StudyInstanceUID &&
- viewportPane.displaySetInstanceUID;
-
- if (isNonEmptyViewport) {
- dirtyViewportPanes.push({
- StudyInstanceUID: viewportPane.StudyInstanceUID,
- displaySetInstanceUID: viewportPane.displaySetInstanceUID,
- });
-
- continue;
- }
-
- const foundDisplaySet =
- displaySets.find(
- ds =>
- !dirtyViewportPanes.some(
- v => v.displaySetInstanceUID === ds.displaySetInstanceUID
- )
- ) || displaySets[displaySets.length - 1];
-
- dirtyViewportPanes.push(foundDisplaySet);
- }
-
- dirtyViewportPanes.forEach((vp, i) => {
- if (vp && vp.StudyInstanceUID) {
- this.setViewportData({
- viewportIndex: i,
- StudyInstanceUID: vp.StudyInstanceUID,
- displaySetInstanceUID: vp.displaySetInstanceUID,
- });
- }
- });
- };
-
- setViewportData = ({
- viewportIndex,
- StudyInstanceUID,
- displaySetInstanceUID,
- }) => {
- const displaySet = this.findDisplaySet(
- this.props.studies,
- StudyInstanceUID,
- displaySetInstanceUID
- );
-
- this.props.setViewportSpecificData(viewportIndex, displaySet);
- };
-
- render() {
- const { viewportSpecificData } = this.props;
- const viewportData = values(viewportSpecificData);
-
- return (
-
- {this.state.displaySets.length && (
-
- {/* Children to add to each viewport that support children */}
-
- )}
-
- );
- }
-
- componentWillUnmount() {
- // Clear the entire viewport specific data
- const { viewportSpecificData } = this.props;
- Object.keys(viewportSpecificData).forEach(viewportIndex => {
- this.props.clearViewportSpecificData(viewportIndex);
- });
-
- // TODO: These don't have to be viewer specific?
- // Could qualify for other routes?
- // hotkeys.destroy();
-
- // Remove beforeUnload event handler...
- //window.removeEventListener('beforeunload', unloadHandlers.beforeUnload);
- // Destroy the synchronizer used to update reference lines
- //OHIF.viewer.updateImageSynchronizer.destroy();
- // TODO: Instruct all plugins to clean up themselves
- //
- // Clear references to all stacks in the StackManager
- //StackManager.clearStacks();
- // @TypeSafeStudies
- // Clears OHIF.viewer.Studies collection
- //OHIF.viewer.Studies.removeAll();
- // @TypeSafeStudies
- // Clears OHIF.viewer.StudyMetadataList collection
- //OHIF.viewer.StudyMetadataList.removeAll();
- }
-}
-
-export default ViewerMain;
diff --git a/platform/viewer/src/connectedComponents/ViewerRetrieveStudyData.js b/platform/viewer/src/connectedComponents/ViewerRetrieveStudyData.js
deleted file mode 100644
index 63fc55093..000000000
--- a/platform/viewer/src/connectedComponents/ViewerRetrieveStudyData.js
+++ /dev/null
@@ -1,375 +0,0 @@
-import React, { useState, useEffect, useContext } from 'react';
-import { metadata, studies, utils, log } from '@ohif/core';
-import usePrevious from '../customHooks/usePrevious';
-
-import ConnectedViewer from './ConnectedViewer.js';
-import PropTypes from 'prop-types';
-import { extensionManager } from './../App.jsx';
-import { useSnackbarContext } from '@ohif/ui';
-
-const { OHIFStudyMetadata, OHIFSeriesMetadata } = metadata;
-const { retrieveStudiesMetadata, deleteStudyMetadataPromise } = studies;
-const { studyMetadataManager, makeCancelable } = utils;
-
-// Contexts
-import AppContext from '../context/AppContext';
-
-const _promoteToFront = (list, value, searchMethod) => {
- let response = [...list];
- let promoted = false;
- const index = response.findIndex(searchMethod.bind(undefined, value));
-
- if (index > 0) {
- const first = response.splice(index, 1);
- response = [...first, ...response];
- }
-
- if (index >= 0) {
- promoted = true;
- }
-
- return {
- promoted,
- data: response,
- };
-};
-
-/**
- * Promote series to front if find found equivalent on filters object
- * @param {Object} study - study reference to promote series against
- * @param {Object} [filters] - Object containing filters to be applied
- * @param {string} [filter.seriesInstanceUID] - series instance uid to filter results against
- * @param {boolean} isFilterStrategy - if filtering by query param strategy ON
- */
-const _promoteList = (study, studyMetadata, filters, isFilterStrategy) => {
- let promoted = false;
- // Promote only if no filter should be applied
- if (!isFilterStrategy) {
- _sortStudyDisplaySet(study, studyMetadata);
- promoted = _promoteStudyDisplaySet(study, studyMetadata, filters);
- }
-
- return promoted;
-};
-
-const _promoteStudyDisplaySet = (study, studyMetadata, filters) => {
- let promoted = false;
- const queryParamsLength = Object.keys(filters).length;
- const shouldPromoteToFront = queryParamsLength > 0;
-
- if (shouldPromoteToFront) {
- const { seriesInstanceUID } = filters;
-
- const _seriesLookup = (valueToCompare, displaySet) => {
- return displaySet.SeriesInstanceUID === valueToCompare;
- };
- const promotedResponse = _promoteToFront(
- studyMetadata.getDisplaySets(),
- seriesInstanceUID,
- _seriesLookup
- );
-
- study.displaySets = promotedResponse.data;
- promoted = promotedResponse.promoted;
- }
-
- return promoted;
-};
-
-/**
- * Method to identify if query param (from url) was applied to given list
- * @param {Object} study - study reference to promote series against
- * @param {Object} [filters] - Object containing filters to be applied
- * @param {string} [filter.seriesInstanceUID] - series instance uid to filter results against
- * @param {boolean} isFilterStrategy - if filtering by query param strategy ON
- */
-const _isQueryParamApplied = (study, filters = {}, isFilterStrategy) => {
- const { seriesInstanceUID } = filters;
- let applied = true;
- // skip in case no filter or no toast manager
- if (!seriesInstanceUID) {
- return applied;
- }
-
- const { series = [], displaySets = [] } = study;
- const firstSeries = isFilterStrategy ? series[0] : displaySets[0];
-
- if (!firstSeries || firstSeries.SeriesInstanceUID !== seriesInstanceUID) {
- applied = false;
- }
-
- return applied;
-};
-const _showUserMessage = (queryParamApplied, message, dialog = {}) => {
- if (queryParamApplied) {
- return;
- }
-
- const { show: showUserMessage = () => {} } = dialog;
- showUserMessage({
- message,
- });
-};
-
-const _addSeriesToStudy = (studyMetadata, series) => {
- const sopClassHandlerModules =
- extensionManager.modules['sopClassHandlerModule'];
- const study = studyMetadata.getData();
- const seriesMetadata = new OHIFSeriesMetadata(series, study);
- const existingSeries = studyMetadata.getSeriesByUID(series.SeriesInstanceUID);
- if (existingSeries) {
- studyMetadata.updateSeries(series.SeriesInstanceUID, seriesMetadata);
- } else {
- studyMetadata.addSeries(seriesMetadata);
- }
-
- studyMetadata.createAndAddDisplaySetsForSeries(
- sopClassHandlerModules,
- seriesMetadata
- );
- study.displaySets = studyMetadata.getDisplaySets();
- _updateStudyMetadataManager(study, studyMetadata);
-};
-
-const _updateStudyMetadataManager = (study, studyMetadata) => {
- const { StudyInstanceUID } = study;
-
- if (!studyMetadataManager.get(StudyInstanceUID)) {
- studyMetadataManager.add(studyMetadata);
- }
-};
-
-const _updateStudyDisplaySets = (study, studyMetadata) => {
- const sopClassHandlerModules =
- extensionManager.modules['sopClassHandlerModule'];
-
- if (!study.displaySets) {
- study.displaySets = studyMetadata.createDisplaySets(sopClassHandlerModules);
- }
-
- studyMetadata.setDisplaySets(study.displaySets);
-};
-
-const _sortStudyDisplaySet = (study, studyMetadata) => {
- studyMetadata.sortDisplaySets(study.displaySets);
-};
-
-function ViewerRetrieveStudyData({
- server,
- studyInstanceUIDs,
- seriesInstanceUIDs,
- clearViewportSpecificData,
-}) {
- // hooks
- const [error, setError] = useState(false);
- const [studies, setStudies] = useState([]);
- const [isStudyLoaded, setIsStudyLoaded] = useState(false);
- const snackbarContext = useSnackbarContext();
- const { appConfig = {} } = useContext(AppContext);
- const {
- filterQueryParam: isFilterStrategy = false,
- maxConcurrentMetadataRequests,
- } = appConfig;
-
- let cancelableSeriesPromises;
- let cancelableStudiesPromises;
- /**
- * Callback method when study is totally loaded
- * @param {object} study study loaded
- * @param {object} studyMetadata studyMetadata for given study
- * @param {Object} [filters] - Object containing filters to be applied
- * @param {string} [filter.seriesInstanceUID] - series instance uid to filter results against
- */
- const studyDidLoad = (study, studyMetadata, filters) => {
- // User message
- const promoted = _promoteList(
- study,
- studyMetadata,
- filters,
- isFilterStrategy
- );
-
- // Clear viewport to allow new promoted one to be displayed
- if (promoted) {
- clearViewportSpecificData(0);
- }
-
- const isQueryParamApplied = _isQueryParamApplied(
- study,
- filters,
- isFilterStrategy
- );
- // Show message in case not promoted neither filtered but should to
- _showUserMessage(
- isQueryParamApplied,
- 'Query parameters were not applied. Using original series list for given study.',
- snackbarContext
- );
-
- setStudies([...studies, study]);
- setIsStudyLoaded(true);
- };
-
- /**
- * Method to process studies. It will update displaySet, studyMetadata, load remaining series, ...
- * @param {Array} studiesData Array of studies retrieved from server
- * @param {Object} [filters] - Object containing filters to be applied
- * @param {string} [filter.seriesInstanceUID] - series instance uid to filter results against
- */
- const processStudies = (studiesData, filters) => {
- if (Array.isArray(studiesData) && studiesData.length > 0) {
- // Map studies to new format, update metadata manager?
- const studies = studiesData.map(study => {
- const studyMetadata = new OHIFStudyMetadata(
- study,
- study.StudyInstanceUID
- );
-
- _updateStudyDisplaySets(study, studyMetadata);
- _updateStudyMetadataManager(study, studyMetadata);
-
- // Attempt to load remaning series if any
- cancelableSeriesPromises[study.StudyInstanceUID] = makeCancelable(
- loadRemainingSeries(studyMetadata)
- )
- .then(result => {
- if (result && !result.isCanceled) {
- studyDidLoad(study, studyMetadata, filters);
- }
- })
- .catch(error => {
- if (error && !error.isCanceled) {
- setError(true);
- log.error(error);
- }
- });
-
- return study;
- });
-
- setStudies(studies);
- }
- };
-
- const forceRerender = () => setStudies(studies => [...studies]);
-
- const loadRemainingSeries = async studyMetadata => {
- const { seriesLoader } = studyMetadata.getData();
- if (!seriesLoader) return;
-
- const loadNextSeries = async () => {
- if (!seriesLoader.hasNext()) return;
- const series = await seriesLoader.next();
- _addSeriesToStudy(studyMetadata, series);
- forceRerender();
- return loadNextSeries();
- };
-
- const concurrentRequestsAllowed =
- maxConcurrentMetadataRequests || studyMetadata.getSeriesCount();
- const promises = Array(concurrentRequestsAllowed)
- .fill(null)
- .map(loadNextSeries);
-
- return await Promise.all(promises);
- };
-
- const loadStudies = async () => {
- try {
- const filters = {};
- // Use the first, discard others
- const seriesInstanceUID = seriesInstanceUIDs && seriesInstanceUIDs[0];
-
- const retrieveParams = [server, studyInstanceUIDs];
-
- if (seriesInstanceUID) {
- filters.seriesInstanceUID = seriesInstanceUID;
- // Query param filtering controlled by appConfig property
- if (isFilterStrategy) {
- retrieveParams.push(filters);
- }
- }
-
- cancelableStudiesPromises[studyInstanceUIDs] = makeCancelable(
- retrieveStudiesMetadata(...retrieveParams)
- )
- .then(result => {
- if (result && !result.isCanceled) {
- processStudies(result, filters);
- }
- })
- .catch(error => {
- if (error && !error.isCanceled) {
- setError(true);
- log.error(error);
- }
- });
- } catch (error) {
- if (error) {
- setError(true);
- log.error(error);
- }
- }
- };
-
- const purgeCancellablePromises = () => {
- for (let studyInstanceUIDs in cancelableStudiesPromises) {
- if ('cancel' in cancelableStudiesPromises[studyInstanceUIDs]) {
- cancelableStudiesPromises[studyInstanceUIDs].cancel();
- }
- }
-
- for (let studyInstanceUIDs in cancelableSeriesPromises) {
- if ('cancel' in cancelableSeriesPromises[studyInstanceUIDs]) {
- cancelableSeriesPromises[studyInstanceUIDs].cancel();
- deleteStudyMetadataPromise(studyInstanceUIDs);
- studyMetadataManager.remove(studyInstanceUIDs);
- }
- }
- };
-
- const prevStudyInstanceUIDs = usePrevious(studyInstanceUIDs);
-
- useEffect(() => {
- const hasStudyInstanceUIDsChanged = !(
- prevStudyInstanceUIDs &&
- prevStudyInstanceUIDs.every(e => studyInstanceUIDs.includes(e))
- );
-
- if (hasStudyInstanceUIDsChanged) {
- studyMetadataManager.purge();
- purgeCancellablePromises();
- }
- }, [studyInstanceUIDs]);
-
- useEffect(() => {
- cancelableSeriesPromises = {};
- cancelableStudiesPromises = {};
- loadStudies();
-
- return () => {
- purgeCancellablePromises();
- };
- }, []);
-
- if (error) {
- return Error: {JSON.stringify(error)}
;
- }
-
- return (
-
- );
-}
-
-ViewerRetrieveStudyData.propTypes = {
- studyInstanceUIDs: PropTypes.array.isRequired,
- seriesInstanceUIDs: PropTypes.array,
- server: PropTypes.object,
- clearViewportSpecificData: PropTypes.func.isRequired,
-};
-
-export default ViewerRetrieveStudyData;
diff --git a/platform/viewer/src/connectedComponents/findDisplaySetByUID.js b/platform/viewer/src/connectedComponents/findDisplaySetByUID.js
deleted file mode 100644
index d50e437ae..000000000
--- a/platform/viewer/src/connectedComponents/findDisplaySetByUID.js
+++ /dev/null
@@ -1,25 +0,0 @@
-/**
- * Finds displaySet by UID across all displaySets inside studyMetadata
- * @param {Array} studyMetadata
- * @param {string} displaySetInstanceUID
- */
-export default function findDisplaySetByUID(
- studyMetadata,
- displaySetInstanceUID
-) {
- if (!Array.isArray(studyMetadata)) return null;
-
- const allDisplaySets = studyMetadata.reduce((all, current) => {
- let currentDisplaySet = [];
- if (current && Array.isArray(current.displaySets)) {
- currentDisplaySet = current.displaySets;
- }
- return all.concat(currentDisplaySet);
- }, []);
-
- const bySetInstanceUID = ds =>
- ds.displaySetInstanceUID === displaySetInstanceUID;
-
- const displaySet = allDisplaySets.find(bySetInstanceUID);
- return displaySet || null;
-}
diff --git a/platform/viewer/src/connectedComponents/findDisplaySetByUID.test.js b/platform/viewer/src/connectedComponents/findDisplaySetByUID.test.js
deleted file mode 100644
index a53d1c544..000000000
--- a/platform/viewer/src/connectedComponents/findDisplaySetByUID.test.js
+++ /dev/null
@@ -1,43 +0,0 @@
-import findDisplaySetByUID from './findDisplaySetByUID';
-
-describe('findDisplaySetByUID', () => {
- test('returns null when studyMetadata isnt an array', () => {
- const result = findDisplaySetByUID(undefined, 'hello');
- expect(result).toBeNull();
- });
-
- test('returns null when no match found', () => {
- const result = findDisplaySetByUID([], 'no-match');
- expect(result).toBeNull();
- });
-
- test('it handles missing displaySet arrays', () => {
- const expected = '9388-2291-a8fe';
- const studyMetadata = [
- { displaySets: null },
- {
- displaySets: [{ displaySetInstanceUID: expected }],
- },
- null,
- 7,
- ];
- const result = findDisplaySetByUID(studyMetadata, expected);
- expect(result.displaySetInstanceUID).toBe(expected);
- });
-
- test('returns correct displaySet by UID', () => {
- const expected = '1234-5678';
- const studyMetadata = [
- { displaySets: [{ displaySetInstanceUID: '0011-2239' }] },
- {
- displaySets: [
- { displaySetInstanceUID: '0392-2211' },
- { displaySetInstanceUID: expected },
- ],
- },
- { displaySets: [{ displaySetInstanceUID: '3384-9933' }] },
- ];
- const result = findDisplaySetByUID(studyMetadata, expected);
- expect(result.displaySetInstanceUID).toBe(expected);
- });
-});