feat: Add White Labelling, Hanging Protocols, and tons of Extensions / Mode fixes

* modified

* new files in existing extensions/libraries/modes

* fixed bugs and tests

* Clean up

* fix: viewport display fixed

* Fixed configs for deployment

* Removed unnecessary files and functions

* Fixed default HP module

* Added white labelling

* Fixed hash routing

* Removed unnecessary routers

Co-authored-by: Alireza Sedghi <ar.sedghi@gmail.com>
This commit is contained in:
Erik ZieglerandAlireza Sedghi authored and GitHub committed 2021-05-28 14:32:48 -04:00
1 parent 0db81b30f3
commit 99b8dc4759
93 files changed
+3825 -1293

No files matched your search

@@ -114,15 +114,16 @@ function PanelMeasurementTableTracking({ servicesManager, extensionManager }) {
// Are we exposing the right API for measurementService?
// This watches for ALL MeasurementService changes. It updates a timestamp,
// which is debounced. After a brief period of inactivity, this triggers
// a re-render where we grab up-to-date measurements.
// a re-render where we grab up-to-date measurements
useEffect(() => {
const added = MeasurementService.EVENTS.MEASUREMENT_ADDED;
const addedRaw = MeasurementService.EVENTS.RAW_MEASUREMENT_ADDED;
const updated = MeasurementService.EVENTS.MEASUREMENT_UPDATED;
const removed = MeasurementService.EVENTS.MEASUREMENT_REMOVED;
const cleared = MeasurementService.EVENTS.MEASUREMENTS_CLEARED;
const subscriptions = [];
[added, updated, removed, cleared].forEach(evt => {
[added, addedRaw, updated, removed, cleared].forEach(evt => {
subscriptions.push(
MeasurementService.subscribe(evt, () => {
setMeasurementsUpdated(Date.now().toString());
@@ -28,7 +28,7 @@ function PanelStudyBrowserTracking({
// Normally you nest the components so the tree isn't so deep, and the data
// doesn't have to have such an intense shape. This works well enough for now.
// Tabs --> Studies --> DisplaySets --> Thumbnails
const [{ StudyInstanceUIDs }, dispatchImageViewer] = useImageViewer();
const { StudyInstanceUIDs } = useImageViewer();
const [
{ activeViewportIndex, viewports, numCols, numRows },
viewportGridService,
@@ -58,27 +58,34 @@ function PanelStudyBrowserTracking({
const isSingleViewport = numCols === 1 && numRows === 1;
// TODO: Should this be somewhere else? Feels more like a mode "lifecycle" setup/destroy?
useEffect(() => {
const { unsubscribe } = MeasurementService.subscribe(
MeasurementService.EVENTS.MEASUREMENT_ADDED,
({ source, measurement }) => {
const {
referenceSeriesUID: SeriesInstanceUID,
referenceStudyUID: StudyInstanceUID,
} = measurement;
const added = MeasurementService.EVENTS.MEASUREMENT_ADDED;
const addedRaw = MeasurementService.EVENTS.RAW_MEASUREMENT_ADDED;
const subscriptions = [];
sendTrackedMeasurementsEvent('SET_DIRTY', { SeriesInstanceUID });
sendTrackedMeasurementsEvent('TRACK_SERIES', {
viewportIndex: activeViewportIndex,
StudyInstanceUID,
SeriesInstanceUID,
});
}
);
[added, addedRaw].forEach(evt => {
subscriptions.push(
MeasurementService.subscribe(evt, ({ source, measurement }) => {
const {
referenceSeriesUID: SeriesInstanceUID,
referenceStudyUID: StudyInstanceUID,
} = measurement;
return unsubscribe;
// eslint-disable-next-line react-hooks/exhaustive-deps
sendTrackedMeasurementsEvent('SET_DIRTY', { SeriesInstanceUID });
sendTrackedMeasurementsEvent('TRACK_SERIES', {
viewportIndex: activeViewportIndex,
StudyInstanceUID,
SeriesInstanceUID,
});
}).unsubscribe
);
});
return () => {
subscriptions.forEach(unsub => {
unsub();
});
};
}, [MeasurementService, activeViewportIndex, sendTrackedMeasurementsEvent]);
const { trackedStudy, trackedSeries } = trackedMeasurements.context;
@@ -89,7 +96,6 @@ function PanelStudyBrowserTracking({
async function fetchStudiesForPatient(StudyInstanceUID) {
const qidoStudiesForPatient =
(await getStudiesForPatientByStudyInstanceUID(StudyInstanceUID)) || [];
// TODO: This should be "naturalized DICOM JSON" studies
const mappedStudies = _mapDataSourceStudies(qidoStudiesForPatient);
const actuallyMappedStudies = mappedStudies.map(qidoStudy => {
@@ -182,6 +188,7 @@ function PanelStudyBrowserTracking({
const imageIds = dataSource.getImageIdsForDisplaySet(displaySet);
const imageId = imageIds[Math.floor(imageIds.length / 2)];
// TODO: Is it okay that imageIds are not returned here for SR displaysets?
if (imageId) {
// When the image arrives, render it and store the result in the thumbnailImgSrcMap
@@ -2,6 +2,7 @@ async function getStudiesForPatientByStudyInstanceUID(
dataSource,
StudyInstanceUID
) {
if (StudyInstanceUID === undefined) return;
// TODO: The `DicomMetadataStore` should short-circuit both of these requests
// Data _could_ be here from route query, or if using JSON data source
// We could also force this to "await" these values being available in the DICOMStore?