Skip to content

Commit

Permalink
fix(studybrowser): Differentiate recent and all in study panel based …
Browse files Browse the repository at this point in the history
…on a provided time period (OHIF#4242)

Co-authored-by: Salim Kanoun <salim.kanoun@gmail.com>
  • Loading branch information
IbrahimCSAE and salimkanoun authored Jun 20, 2024
1 parent e462fd3 commit 6f93449
Show file tree
Hide file tree
Showing 5 changed files with 91 additions and 158 deletions.
59 changes: 2 additions & 57 deletions extensions/default/src/Panels/PanelStudyBrowser.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { StudyBrowser, useImageViewer, useViewportGrid } from '@ohif/ui';
import { utils } from '@ohif/core';
import { useNavigate } from 'react-router-dom';

const { sortStudyInstances, formatDate } = utils;
const { sortStudyInstances, formatDate, createStudyBrowserTabs } = utils;

/**
*
Expand Down Expand Up @@ -206,7 +206,7 @@ function PanelStudyBrowser({
};
}, [StudyInstanceUIDs, thumbnailImageSrcMap, displaySetService]);

const tabs = _createStudyBrowserTabs(StudyInstanceUIDs, studyDisplayList, displaySets);
const tabs = createStudyBrowserTabs(StudyInstanceUIDs, studyDisplayList, displaySets);

// TODO: Should not fire this on "close"
function _handleStudyClick(StudyInstanceUID) {
Expand Down Expand Up @@ -324,58 +324,3 @@ function _getComponentType(ds) {

return 'thumbnail';
}

/**
*
* @param {string[]} primaryStudyInstanceUIDs
* @param {object[]} studyDisplayList
* @param {string} studyDisplayList.studyInstanceUid
* @param {string} studyDisplayList.date
* @param {string} studyDisplayList.description
* @param {string} studyDisplayList.modalities
* @param {number} studyDisplayList.numInstances
* @param {object[]} displaySets
* @returns tabs - The prop object expected by the StudyBrowser component
*/
function _createStudyBrowserTabs(primaryStudyInstanceUIDs, studyDisplayList, displaySets) {
const primaryStudies = [];
const recentStudies = [];
const allStudies = [];

studyDisplayList.forEach(study => {
const displaySetsForStudy = displaySets.filter(
ds => ds.StudyInstanceUID === study.studyInstanceUid
);
const tabStudy = Object.assign({}, study, {
displaySets: displaySetsForStudy,
});

if (primaryStudyInstanceUIDs.includes(study.studyInstanceUid)) {
primaryStudies.push(tabStudy);
} else {
// TODO: Filter allStudies to dates within one year of current date
recentStudies.push(tabStudy);
allStudies.push(tabStudy);
}
});

const tabs = [
{
name: 'primary',
label: 'Primary',
studies: primaryStudies,
},
{
name: 'recent',
label: 'Recent',
studies: recentStudies,
},
{
name: 'all',
label: 'All',
studies: allStudies,
},
];

return tabs;
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { utils } from '@ohif/core';
import { StudyBrowser, useImageViewer, useViewportGrid, Dialog, ButtonEnums } from '@ohif/ui';
import { useTrackedMeasurements } from '../../getContextModule';

const { formatDate } = utils;
const { formatDate, createStudyBrowserTabs } = utils;

/**
*
Expand Down Expand Up @@ -272,11 +272,10 @@ function PanelStudyBrowserTracking({
};
}, [thumbnailImageSrcMap, trackedSeries, viewports, dataSource, displaySetService]);

const tabs = _createStudyBrowserTabs(
const tabs = createStudyBrowserTabs(
StudyInstanceUIDs,
studyDisplayList,
displaySets,
hangingProtocolService
);

// TODO: Should not fire this on "close"
Expand Down Expand Up @@ -590,97 +589,6 @@ function _getComponentType(ds) {
return 'thumbnailTracked';
}

/**
*
* @param {string[]} primaryStudyInstanceUIDs
* @param {object[]} studyDisplayList
* @param {string} studyDisplayList.studyInstanceUid
* @param {string} studyDisplayList.date
* @param {string} studyDisplayList.description
* @param {string} studyDisplayList.modalities
* @param {number} studyDisplayList.numInstances
* @param {object[]} displaySets
* @returns tabs - The prop object expected by the StudyBrowser component
*/
function _createStudyBrowserTabs(
primaryStudyInstanceUIDs,
studyDisplayList,
displaySets,
hangingProtocolService
) {
const primaryStudies = [];
const recentStudies = [];
const allStudies = [];

// Iterate over each study...
studyDisplayList.forEach(study => {
// Find it's display sets
const displaySetsForStudy = displaySets.filter(
ds => ds.StudyInstanceUID === study.studyInstanceUid
);

// Sort them
const dsSortFn = hangingProtocolService.getDisplaySetSortFunction();
displaySetsForStudy.sort(dsSortFn);

/* Sort by series number, then by series date
displaySetsForStudy.sort((a, b) => {
if (a.seriesNumber !== b.seriesNumber) {
return a.seriesNumber - b.seriesNumber;
}
const seriesDateA = Date.parse(a.seriesDate);
const seriesDateB = Date.parse(b.seriesDate);
return seriesDateA - seriesDateB;
});
*/

// Map the study to it's tab/view representation
const tabStudy = Object.assign({}, study, {
displaySets: displaySetsForStudy,
});

// Add the "tab study" to the 'primary', 'recent', and/or 'all' tab group(s)
if (primaryStudyInstanceUIDs.includes(study.studyInstanceUid)) {
primaryStudies.push(tabStudy);
allStudies.push(tabStudy);
} else {
// TODO: Filter allStudies to dates within one year of current date
recentStudies.push(tabStudy);
allStudies.push(tabStudy);
}
});

// Newest first
const _byDate = (a, b) => {
const dateA = Date.parse(a);
const dateB = Date.parse(b);

return dateB - dateA;
};

const tabs = [
{
name: 'primary',
label: 'Primary',
studies: primaryStudies.sort((studyA, studyB) => _byDate(studyA.date, studyB.date)),
},
{
name: 'recent',
label: 'Recent',
studies: recentStudies.sort((studyA, studyB) => _byDate(studyA.date, studyB.date)),
},
{
name: 'all',
label: 'All',
studies: allStudies.sort((studyA, studyB) => _byDate(studyA.date, studyB.date)),
},
];

return tabs;
}

function _findTabAndStudyOfDisplaySet(displaySetInstanceUID, tabs) {
for (let t = 0; t < tabs.length; t++) {
const { studies } = tabs[t];
Expand Down
77 changes: 77 additions & 0 deletions platform/core/src/utils/createStudyBrowserTabs.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
/**
*
* @param {string[]} primaryStudyInstanceUIDs
* @param {object[]} studyDisplayList
* @param {string} studyDisplayList.studyInstanceUid
* @param {string} studyDisplayList.date
* @param {string} studyDisplayList.description
* @param {string} studyDisplayList.modalities
* @param {number} studyDisplayList.numInstances
* @param {object[]} displaySets
* @param {number} recentTimeframe - The number of milliseconds to consider a study recent
* @returns tabs - The prop object expected by the StudyBrowser component
*/

export function createStudyBrowserTabs(primaryStudyInstanceUIDs, studyDisplayList, displaySets, recentTimeframeMS = 31536000000) {
const primaryStudies = [];
const allStudies = [];

studyDisplayList.forEach(study => {
const displaySetsForStudy = displaySets.filter(
ds => ds.StudyInstanceUID === study.studyInstanceUid
);
const tabStudy = Object.assign({}, study, {
displaySets: displaySetsForStudy,
});

if (primaryStudyInstanceUIDs.includes(study.studyInstanceUid)) {
primaryStudies.push(tabStudy);
}
allStudies.push(tabStudy);
});

const primaryStudiesTimestamps = primaryStudies
.filter(study => study.date)
.map(study => new Date(study.date).getTime());

const recentStudies =
primaryStudiesTimestamps.length > 0
? allStudies.filter(study => {
const oldestPrimaryTimeStamp = Math.min(...primaryStudiesTimestamps);

if (!study.date) {
return false;
}
const studyTimeStamp = new Date(study.date).getTime();
console.log(oldestPrimaryTimeStamp, studyTimeStamp, recentTimeframeMS)
return oldestPrimaryTimeStamp - studyTimeStamp < recentTimeframeMS;
})
: [];

// Newest first
const _byDate = (a, b) => {
const dateA = Date.parse(a);
const dateB = Date.parse(b);

return dateB - dateA;
};
const tabs = [
{
name: 'primary',
label: 'Primary',
studies: primaryStudies.sort((studyA, studyB) => _byDate(studyA.date, studyB.date)),
},
{
name: 'recent',
label: 'Recent',
studies: recentStudies.sort((studyA, studyB) => _byDate(studyA.date, studyB.date)),
},
{
name: 'all',
label: 'All',
studies: allStudies.sort((studyA, studyB) => _byDate(studyA.date, studyB.date)),
},
];

return tabs;
}
3 changes: 3 additions & 0 deletions platform/core/src/utils/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ import {
} from './sortStudy';
import { subscribeToNextViewportGridChange } from './subscribeToNextViewportGridChange';
import { splitComma, getSplitParam } from './splitComma';
import { createStudyBrowserTabs } from './createStudyBrowserTabs';

// Commented out unused functionality.
// Need to implement new mechanism for derived displaySets using the displaySetManager.
Expand Down Expand Up @@ -80,6 +81,7 @@ const utils = {
splitComma,
getSplitParam,
generateAcceptHeader,
createStudyBrowserTabs,
};

export {
Expand Down Expand Up @@ -112,6 +114,7 @@ export {
splitComma,
getSplitParam,
generateAcceptHeader,
createStudyBrowserTabs,
};

export default utils;
14 changes: 7 additions & 7 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -7732,7 +7732,7 @@ class-variance-authority@^0.7.0:
dependencies:
clsx "2.0.0"

classnames@^2.2.5, classnames@^2.3.2:
classnames@^2.3.2:
version "2.5.1"
resolved "https://registry.yarnpkg.com/classnames/-/classnames-2.5.1.tgz#ba774c614be0f016da105c858e7159eae8e7687b"
integrity sha512-saHYOzhIQs6wy2sVxTM6bUDsQO4F50V9RQ22qBpEdCW+I+/Wmke2HOl6lS6dTpdxVhb88/I6+Hs+438c3lfUow==
Expand Down Expand Up @@ -17893,13 +17893,13 @@ react-dom@^18.3.1:
loose-envify "^1.1.0"
scheduler "^0.23.2"

react-draggable@4.4.3:
version "4.4.3"
resolved "https://registry.yarnpkg.com/react-draggable/-/react-draggable-4.4.3.tgz#0727f2cae5813e36b0e4962bf11b2f9ef2b406f3"
integrity sha512-jV4TE59MBuWm7gb6Ns3Q1mxX8Azffb7oTtDtBgFkxRvhDp38YAARmRplrj0+XGkhOJB5XziArX+4HUUABtyZ0w==
react-draggable@^4.4.6:
version "4.4.6"
resolved "https://registry.yarnpkg.com/react-draggable/-/react-draggable-4.4.6.tgz#63343ee945770881ca1256a5b6fa5c9f5983fe1e"
integrity sha512-LtY5Xw1zTPqHkVmtM3X8MUOxNDOUhv/khTgBgrUvwaS064bwVvxT+q5El0uUFNx5IEPKXuRejr7UqLwBIg5pdw==
dependencies:
classnames "^2.2.5"
prop-types "^15.6.0"
clsx "^1.1.1"
prop-types "^15.8.1"

react-dropzone@^10.1.7:
version "10.2.2"
Expand Down

0 comments on commit 6f93449

Please sign in to comment.