diff --git a/extensions/default/src/Panels/PanelStudyBrowser.jsx b/extensions/default/src/Panels/PanelStudyBrowser.jsx
new file mode 100644
index 000000000..533312b99
--- /dev/null
+++ b/extensions/default/src/Panels/PanelStudyBrowser.jsx
@@ -0,0 +1,257 @@
+import React, { useState, useEffect, useCallback } from 'react';
+import PropTypes from 'prop-types';
+import { StudyBrowser } from '@ohif/ui';
+import { dicomMetadataStore, useViewModel } from '@ohif/core';
+
+function PanelStudyBrowser({ getDataSources, commandsManager }) {
+ console.warn('StudyBrowserPanel rerender');
+ const [activeTabName, setActiveTabName] = useState('primary');
+ const [studyData, setStudyData] = useState([]);
+ const [thumbnailImageSrcMap, setThumbnailImageSrcMap] = useState(new Map());
+ const updateThumbnailMap = (k, v) => {
+ setThumbnailImageSrcMap(thumbnailImageSrcMap.set(k, v));
+ };
+
+ const viewModel = useViewModel();
+ const dataSource = getDataSources('dicomweb')[0];
+ const viewportData = []; //useViewportGrid();
+ const seriesTracking = {}; //useSeriesTracking();
+
+ // This effect
+ useEffect(() => {
+ if (!viewModel.displaySetInstanceUIDs.length) {
+ return;
+ }
+
+ let isSubscribed = true;
+
+ const command = commandsManager.getCommand(
+ 'getCornerstoneLibraries',
+ 'VIEWER'
+ );
+
+ if (!command) {
+ throw new Error('Required command not found');
+ }
+
+ const { cornerstone, cornerstoneTools } = command.commandFn();
+
+ viewModel.displaySetInstanceUIDs.forEach(uid => {
+ const imageIds = dataSource.getImageIdsForDisplaySet(uid);
+ const imageId = imageIds[Math.floor(imageIds.length / 2)];
+
+ getImageSrc(imageId, { cornerstone }).then(imageSrc => {
+ if (isSubscribed) {
+ updateThumbnailMap(uid, imageSrc);
+ }
+ });
+ });
+
+ const displaySets = viewModel.displaySetInstanceUIDs.map(
+ displaySetManager.getDisplaySetByUID
+ );
+
+ const aDisplaySet = displaySets[0];
+ const firstStudy = dicomMetadataStore.getStudy(
+ aDisplaySet.StudyInstanceUID
+ );
+ const firstInstance = firstStudy.series[0].instances[0];
+ const PatientID = firstInstance.PatientID;
+
+ dataSource.query.studies.search({ patientId: PatientID }).then(results => {
+ const studies = results.map(study => {
+ // TODO: Why does the data source return in this format?
+ return {
+ AccessionNumber: study.accession,
+ StudyDate: study.date,
+ StudyDescription: study.description,
+ NumInstances: study.instances,
+ ModalitiesInStudy: study.modalities,
+ PatientID: study.mrn,
+ PatientName: study.patientName,
+ StudyInstanceUID: study.studyInstanceUid,
+ StudyTime: study.time,
+ };
+ });
+
+ const studiesFromInstanceData = {};
+ displaySets.forEach(ds => {
+ const displaySet = {
+ displaySetInstanceUID: ds.displaySetInstanceUID,
+ description: ds.SeriesDescription,
+ seriesNumber: ds.SeriesNumber,
+ modality: ds.Modality,
+ date: ds.SeriesDate,
+ numInstances: ds.numImageFrames,
+ };
+
+ const displaySetViewportData = viewportData.find(
+ a => a.displaySetInstanceUID === ds.displaySetInstanceUID
+ );
+
+ if (displaySetViewportData) {
+ displaySet.viewportIdentificator = displaySetViewportData.identifier;
+ }
+
+ const trackingInfo = seriesTracking[ds.SeriesInstanceUID];
+ if (trackingInfo) {
+ displaySet.isTracked = trackingInfo.isTracked;
+ } else {
+ displaySet.isTracked = false;
+ }
+
+ displaySet.componentType = 'thumbnailTracked';
+
+ if (
+ !Object.keys(studiesFromInstanceData).includes(ds.StudyInstanceUID)
+ ) {
+ const study = dicomMetadataStore.getStudy(ds.StudyInstanceUID);
+ const anInstance = study.series[0].instances[0];
+
+ studiesFromInstanceData[ds.StudyInstanceUID] = {
+ date: anInstance.StudyDate, // TODO: Format this date to DD-MMM-YYYY
+ description: anInstance.StudyDescription,
+ displaySets: [],
+ numInstances: 0,
+ modalitiesSet: new Set(),
+ };
+ }
+
+ studiesFromInstanceData[ds.StudyInstanceUID].displaySets.push(
+ displaySet
+ );
+ studiesFromInstanceData[ds.StudyInstanceUID].numInstances +=
+ displaySet.numInstances;
+
+ studiesFromInstanceData[ds.StudyInstanceUID].modalitiesSet.add(
+ displaySet.modality
+ );
+
+ const modalitiesSet =
+ studiesFromInstanceData[ds.StudyInstanceUID].modalitiesSet;
+ studiesFromInstanceData[ds.StudyInstanceUID].modalities = Array.from(
+ modalitiesSet
+ ).join(', ');
+ });
+
+ // QIDO for all by MRN
+ const allStudies = studies.map(studyLevelData => {
+ const studyFromInstanceData =
+ studiesFromInstanceData[studyLevelData.StudyInstanceUID];
+
+ if (!studyFromInstanceData) {
+ return {
+ studyInstanceUid: studyLevelData.StudyInstanceUID,
+ date: studyLevelData.StudyDate,
+ description: studyLevelData.StudyDescription,
+ modalities: studyLevelData.ModalitiesInStudy,
+ numInstances: studyLevelData.NumInstances,
+ displaySets: [],
+ };
+ }
+
+ return {
+ studyInstanceUid: studyLevelData.StudyInstanceUID,
+ date: studyLevelData.StudyDate || studyFromInstanceData.date,
+ description:
+ studyLevelData.StudyDescription ||
+ studyFromInstanceData.description,
+ modalities:
+ studyFromInstanceData.modalities ||
+ studyLevelData.ModalitiesInStudy,
+ numInstances:
+ studyLevelData.NumInstances || studyFromInstanceData.numInstances,
+ displaySets: studyFromInstanceData.displaySets,
+ };
+ });
+
+ if (isSubscribed) {
+ setStudyData(allStudies);
+ }
+ });
+
+ return () => (isSubscribed = false);
+ }, [viewModel.displaySetInstanceUIDs, thumbnailImageSrcMap, setStudyData]);
+
+ studyData.forEach(study => {
+ study.displaySets.forEach(ds => {
+ ds.imageSrc = thumbnailImageSrcMap.get(ds.displaySetInstanceUID);
+ });
+ });
+
+ const primary = studyData.find(study => {
+ return true; // TODO: check study.StudyInstanceUID matches queryparam?
+ });
+
+ // TODO: Filter allStudies to dates within one year of current date
+ const recentStudies = studyData.filter(study => {
+ return true; // TODO: check study.date
+ });
+
+ const tabs = [
+ {
+ name: 'primary',
+ label: 'Primary',
+ studies: primary ? [primary] : [],
+ },
+ {
+ name: 'recent',
+ label: 'Recent',
+ studies: recentStudies,
+ },
+ {
+ name: 'all',
+ label: 'All',
+ studies: studyData,
+ },
+ ];
+
+ function onClickStudy(StudyInstanceUID) {
+ const study = studyData.find(a => a.studyInstanceUid === StudyInstanceUID);
+ if (study && study.displaySets && study.displaySets.length) {
+ return;
+ }
+
+ console.warn(`onClickStudy: ${StudyInstanceUID}`);
+ // TODO: This is weird, why can't the data source just be used as
+ // as function that doesn't expect a query string?
+ const queryParams = `?StudyInstanceUIDs=${StudyInstanceUID}`;
+
+ dataSource.retrieve.series.metadata(
+ queryParams,
+ displaySetManager.makeDisplaySets
+ );
+ }
+
+ const memoOnClickStudy = useCallback(
+ StudyInstanceUID => {
+ onClickStudy(StudyInstanceUID);
+ },
+ [studyData]
+ );
+
+ return (
+
+ );
+}
+
+function WrappedPanelStudyBrowser({ commandsManager, extensionManager }) {
+ return (
+
+ );
+}
+
+WrappedPanelStudyBrowser.propTypes = {
+ commandsManager: PropTypes.object.isRequired,
+ extensionManager: PropTypes.object.isRequired,
+};
+
+export { WrappedPanelStudyBrowser };
diff --git a/extensions/default/src/Panels/index.js b/extensions/default/src/Panels/index.js
new file mode 100644
index 000000000..b2847a9c1
--- /dev/null
+++ b/extensions/default/src/Panels/index.js
@@ -0,0 +1,5 @@
+import PanelStudyBrowser, {
+ WrappedPanelStudyBrowser,
+} from './PanelStudyBrowser';
+
+export { PanelStudyBrowser, WrappedPanelStudyBrowser };
diff --git a/extensions/default/src/getPanelModule.js b/extensions/default/src/getPanelModule.js
index a4c05e0f1..4054cb166 100644
--- a/extensions/default/src/getPanelModule.js
+++ b/extensions/default/src/getPanelModule.js
@@ -1,6 +1,5 @@
-import React, { useState, useEffect, useCallback } from 'react';
-import { StudyBrowser } from '@ohif/ui';
-import { dicomMetadataStore, useViewModel, useToolbarLayout } from '@ohif/core';
+import React from 'react';
+import { WrappedPanelStudyBrowser } from './Panels'
import MeasurementTable from './MeasurementTable.js';
@@ -23,281 +22,11 @@ function getImageSrc(imageId, { cornerstone }) {
});
}
-function StudyBrowserUIData({ getDataSources, commandsManager }) {
- const [activeTabName, setActiveTabName] = useState('primary');
- const [studyData, setStudyData] = useState([]);
- const [thumbnailImageSrcMap, setThumbnailImageSrcMap] = useState(new Map());
- const updateThumbnailMap = (k, v) => {
- setThumbnailImageSrcMap(thumbnailImageSrcMap.set(k, v));
- };
-
- console.log('StudyBrowserUIData rerender');
-
- return (
-
- );
-}
-
-function StudyBrowserPanel({
- activeTabName,
- getDataSources,
+function getPanelModule({
commandsManager,
- onSetTabActive,
- studyData,
- setStudyData,
- thumbnailImageSrcMap,
- updateThumbnailMap,
+ extensionManager,
+ servicesManager,
}) {
- console.warn('StudyBrowserPanel rerender');
- const viewModel = useViewModel();
-
- const dataSource = getDataSources('dicomweb')[0];
-
- const viewportData = []; //useViewportGrid();
- const seriesTracking = {}; //useSeriesTracking();
-
- // This effect
- useEffect(() => {
- if (!viewModel.displaySetInstanceUIDs.length) {
- return;
- }
-
- let isSubscribed = true;
-
- const command = commandsManager.getCommand(
- 'getCornerstoneLibraries',
- 'VIEWER'
- );
-
- if (!command) {
- throw new Error('Required command not found');
- }
-
- const { cornerstone, cornerstoneTools } = command.commandFn();
-
- viewModel.displaySetInstanceUIDs.forEach(uid => {
- const imageIds = dataSource.getImageIdsForDisplaySet(uid);
- const imageId = imageIds[Math.floor(imageIds.length / 2)];
-
- getImageSrc(imageId, { cornerstone }).then(imageSrc => {
- if (isSubscribed) {
- updateThumbnailMap(uid, imageSrc);
- }
- });
- });
-
- const displaySets = viewModel.displaySetInstanceUIDs.map(
- displaySetManager.getDisplaySetByUID
- );
-
- const aDisplaySet = displaySets[0];
- const firstStudy = dicomMetadataStore.getStudy(
- aDisplaySet.StudyInstanceUID
- );
- const firstInstance = firstStudy.series[0].instances[0];
- const PatientID = firstInstance.PatientID;
-
- dataSource.query.studies.search({ patientId: PatientID }).then(results => {
- const studies = results.map(study => {
- // TODO: Why does the data source return in this format?
- return {
- AccessionNumber: study.accession,
- StudyDate: study.date,
- StudyDescription: study.description,
- NumInstances: study.instances,
- ModalitiesInStudy: study.modalities,
- PatientID: study.mrn,
- PatientName: study.patientName,
- StudyInstanceUID: study.studyInstanceUid,
- StudyTime: study.time,
- };
- });
-
- const studiesFromInstanceData = {};
- displaySets.forEach(ds => {
- const displaySet = {
- displaySetInstanceUID: ds.displaySetInstanceUID,
- description: ds.SeriesDescription,
- seriesNumber: ds.SeriesNumber,
- modality: ds.Modality,
- date: ds.SeriesDate,
- numInstances: ds.numImageFrames,
- };
-
- const displaySetViewportData = viewportData.find(
- a => a.displaySetInstanceUID === ds.displaySetInstanceUID
- );
-
- if (displaySetViewportData) {
- displaySet.viewportIdentificator = displaySetViewportData.identifier;
- }
-
- const trackingInfo = seriesTracking[ds.SeriesInstanceUID];
- if (trackingInfo) {
- displaySet.isTracked = trackingInfo.isTracked;
- } else {
- displaySet.isTracked = false;
- }
-
- displaySet.componentType = 'thumbnailTracked';
-
- if (
- !Object.keys(studiesFromInstanceData).includes(ds.StudyInstanceUID)
- ) {
- const study = dicomMetadataStore.getStudy(ds.StudyInstanceUID);
- const anInstance = study.series[0].instances[0];
-
- studiesFromInstanceData[ds.StudyInstanceUID] = {
- date: anInstance.StudyDate, // TODO: Format this date to DD-MMM-YYYY
- description: anInstance.StudyDescription,
- displaySets: [],
- numInstances: 0,
- modalitiesSet: new Set(),
- };
- }
-
- studiesFromInstanceData[ds.StudyInstanceUID].displaySets.push(
- displaySet
- );
- studiesFromInstanceData[ds.StudyInstanceUID].numInstances +=
- displaySet.numInstances;
-
- studiesFromInstanceData[ds.StudyInstanceUID].modalitiesSet.add(
- displaySet.modality
- );
-
- const modalitiesSet =
- studiesFromInstanceData[ds.StudyInstanceUID].modalitiesSet;
- studiesFromInstanceData[ds.StudyInstanceUID].modalities = Array.from(
- modalitiesSet
- ).join(', ');
- });
-
- // QIDO for all by MRN
- const allStudies = studies.map(studyLevelData => {
- const studyFromInstanceData =
- studiesFromInstanceData[studyLevelData.StudyInstanceUID];
-
- if (!studyFromInstanceData) {
- return {
- studyInstanceUid: studyLevelData.StudyInstanceUID,
- date: studyLevelData.StudyDate,
- description: studyLevelData.StudyDescription,
- modalities: studyLevelData.ModalitiesInStudy,
- numInstances: studyLevelData.NumInstances,
- displaySets: [],
- };
- }
-
- return {
- studyInstanceUid: studyLevelData.StudyInstanceUID,
- date: studyLevelData.StudyDate || studyFromInstanceData.date,
- description:
- studyLevelData.StudyDescription ||
- studyFromInstanceData.description,
- modalities:
- studyFromInstanceData.modalities ||
- studyLevelData.ModalitiesInStudy,
- numInstances:
- studyLevelData.NumInstances || studyFromInstanceData.numInstances,
- displaySets: studyFromInstanceData.displaySets,
- };
- });
-
- if (isSubscribed) {
- setStudyData(allStudies);
- }
- });
-
- return () => (isSubscribed = false);
- }, [viewModel.displaySetInstanceUIDs, thumbnailImageSrcMap, setStudyData]);
-
- studyData.forEach(study => {
- study.displaySets.forEach(ds => {
- ds.imageSrc = thumbnailImageSrcMap.get(ds.displaySetInstanceUID);
- });
- });
-
- const primary = studyData.find(study => {
- return true; // TODO: check study.StudyInstanceUID matches queryparam?
- });
-
- // TODO: Filter allStudies to dates within one year of current date
- const recentStudies = studyData.filter(study => {
- return true; // TODO: check study.date
- });
-
- const tabs = [
- {
- name: 'primary',
- label: 'Primary',
- studies: primary ? [primary] : [],
- },
- {
- name: 'recent',
- label: 'Recent',
- studies: recentStudies,
- },
- {
- name: 'all',
- label: 'All',
- studies: studyData,
- },
- ];
-
- function onClickStudy(StudyInstanceUID) {
- const study = studyData.find(a => a.studyInstanceUid === StudyInstanceUID);
- if (study && study.displaySets && study.displaySets.length) {
- return;
- }
-
- console.warn(`onClickStudy: ${StudyInstanceUID}`);
- // TODO: This is weird, why can't the data source just be used as
- // as function that doesn't expect a query string?
- const queryParams = `?StudyInstanceUIDs=${StudyInstanceUID}`;
-
- dataSource.retrieve.series.metadata(
- queryParams,
- displaySetManager.makeDisplaySets
- );
- }
-
- const memoOnClickStudy = useCallback(
- StudyInstanceUID => {
- onClickStudy(StudyInstanceUID);
- },
- [studyData]
- );
-
- return (
-
- );
-}
-
-function getPanelModule({ getDataSources, commandsManager, servicesManager }) {
- const wrappedStudyBrowserPanel = () => {
- return (
-
- );
- };
-
const wrappedMeasurementPanel = () => {
return (
Need some way of selecting which displaySets hit the viewports.
+ // const { DisplaySetService } = servicesManager.services;
+
+ // // TODO -> Make a HangingProtocolService
+ // const HangingProtocolService = displaySets => {
+ // const displaySetInstanceUid = displaySets[Object.keys(displaySets)[0]][0].displaySetInstanceUid;
+
+ // return {
+ // numRows: 1,
+ // numCols: 1,
+ // activeViewportIndex: 0,
+ // viewports: [
+ // {
+ // displaySetInstanceUid,
+ // },
+ // ],
+ // };
+ // };
+
+ // const handleDisplaySetSubscription = useCallback(displaySets => {
+ // setViewportGrid(HangingProtocolService(displaySets));
+ // });
+
+ // useEffect(() => {
+ // const { unsubscribe } = DisplaySetService.subscribe(
+ // DisplaySetService.EVENTS.DISPLAY_SET_ADDED,
+ // handleDisplaySetSubscription
+ // );
+
+ // return unsubscribe;
+ // }, []);
diff --git a/platform/viewer/src/routes/buildModeRoutes.js b/platform/viewer/src/routes/buildModeRoutes.js
index 07e7762b5..a4822e4cd 100644
--- a/platform/viewer/src/routes/buildModeRoutes.js
+++ b/platform/viewer/src/routes/buildModeRoutes.js
@@ -24,11 +24,8 @@ import { ViewModelProvider } from '@ohif/core';
*/
export default function buildModeRoutes(
modes,
-
dataSources,
-
extensionManager,
-
servicesManager
) {
const routes = [];