diff --git a/Packages/viewerbase/client/components/studyBrowser/studyBrowser/studyBrowser.html b/Packages/viewerbase/client/components/studyBrowser/studyBrowser/studyBrowser.html index fd4b88b79..16b7dab1f 100644 --- a/Packages/viewerbase/client/components/studyBrowser/studyBrowser/studyBrowser.html +++ b/Packages/viewerbase/client/components/studyBrowser/studyBrowser/studyBrowser.html @@ -2,7 +2,7 @@
{{#each study in studies}} - {{#each thumbnail in (studyThumbnails study)}} + {{#each thumbnail in (sort (studyThumbnails study) thumbnailSortBy thumbnailSortType)}} {{>thumbnailEntry thumbnail=thumbnail}} {{/each}} {{/each}} diff --git a/Packages/viewerbase/lib/createStacks.js b/Packages/viewerbase/lib/createStacks.js index e31ca9c5c..c8695efa3 100644 --- a/Packages/viewerbase/lib/createStacks.js +++ b/Packages/viewerbase/lib/createStacks.js @@ -49,6 +49,9 @@ createStacks = function(study) { // Include the instance number displaySet.instanceNumber = instance.instanceNumber; + // Include the acquisition datetime + displaySet.acquisitionDatetime = instance.acquisitionDatetime; + displaySets.push(displaySet); } else if (isSingleImageModality(instance.modality)) { displaySet = makeDisplaySet(series, [ instance ]); @@ -59,6 +62,9 @@ createStacks = function(study) { // Include the instance number displaySet.instanceNumber = instance.instanceNumber; + // Include the acquisition datetime + displaySet.acquisitionDatetime = instance.acquisitionDatetime; + displaySets.push(displaySet); } else { stackableInstances.push(instance); diff --git a/Packages/viewerbase/lib/helpers/sorting.js b/Packages/viewerbase/lib/helpers/sorting.js new file mode 100644 index 000000000..7a1475dc7 --- /dev/null +++ b/Packages/viewerbase/lib/helpers/sorting.js @@ -0,0 +1,59 @@ +import { _ } from 'meteor/underscore'; +import { Template } from 'meteor/templating'; + +/** + * Global Blaze UI helper to sort array elements + * by an array element's property (property) or deep object property (property.childProperty) + * Sorts ascending as default + */ +Template.registerHelper('sort', (array, sortBy, sortType) => { + if (!sortBy) { + return array; + } + + console.log(array); + + // To keep the order for the same values of the field which is used to sort: + // 1. Group the array by the field + // 2. Sort the grouped array + // 3. Ungroup the sorted array + + const groupedArray = _.groupBy(array, (element) => { + if (sortBy) { + var groupingElement = getKeyValue(element, sortBy); + if (groupingElement) { + return groupingElement; + } + } + return element; + }); + + const sortedArray = _.sortBy(groupedArray, (element) => { + if (sortBy) { + var sortingElement = getKeyValue(element[0], sortBy); + if (sortingElement) { + return sortingElement; + } + } + return element; + }); + + if (sortType === 'desc') { + return _.flatten(sortedArray.reverse(), true); + } + + return _.flatten(sortedArray, true); +}); + +function getKeyValue(object, keyPath) { + keyPath = keyPath.split('.'); + for (var i = 0; i < keyPath.length; i++) { + if (object && _.has(object, keyPath[i])) { + object = object[keyPath[i]]; + } + else { + return undefined; + } + } + return object; +} \ No newline at end of file diff --git a/Packages/viewerbase/package.js b/Packages/viewerbase/package.js index 107050b87..8bdb6d999 100644 --- a/Packages/viewerbase/package.js +++ b/Packages/viewerbase/package.js @@ -206,6 +206,7 @@ Package.onUse(function(api) { 'lib/helpers/objectEach.js', 'lib/helpers/ifTypeIs.js', 'lib/helpers/prettyPrintStringify.js', + 'lib/helpers/sorting.js', 'lib/helpers/studyThumbnails.js', 'lib/helpers/formatPN.js' ], 'client'); diff --git a/Packages/worklist/server/services/dimse/retrieveMetadata.js b/Packages/worklist/server/services/dimse/retrieveMetadata.js index 271c43a85..e4d5bc202 100755 --- a/Packages/worklist/server/services/dimse/retrieveMetadata.js +++ b/Packages/worklist/server/services/dimse/retrieveMetadata.js @@ -100,6 +100,7 @@ function resultDataToStudyMetadata(studyInstanceUid, resultData) { sourceImageInstanceUid: getSourceImageInstanceUid(instance), laterality: instance[0x00200062], viewPosition: instance[0x00185101], + acquisitionDatetime: instance[0x0008002A], numFrames: parseFloat(instance[0x00280008]), frameTime: parseFloat(instance[0x00181063]), lossyImageCompression: instance[0x00282110], diff --git a/Packages/worklist/server/services/remote/retrieveMetadata.js b/Packages/worklist/server/services/remote/retrieveMetadata.js index bb7e15c17..278cd7d3b 100755 --- a/Packages/worklist/server/services/remote/retrieveMetadata.js +++ b/Packages/worklist/server/services/remote/retrieveMetadata.js @@ -95,6 +95,7 @@ function resultDataToStudyMetadata(server, studyInstanceUid, resultData) { sourceImageInstanceUid: getSourceImageInstanceUid(instance), laterality: remoteGetValue(instance['0020,0062']), viewPosition: remoteGetValue(instance['0018,5101']), + acquisitionDatetime: remoteGetValue(instance['0008,002A']), numFrames: parseFloat(remoteGetValue(instance['0028,0008'])), frameTime: parseFloat(remoteGetValue(instance['0018,1063'])) }; diff --git a/Packages/worklist/server/services/wado/retrieveMetadata.js b/Packages/worklist/server/services/wado/retrieveMetadata.js index 7658cba26..466ca9a5b 100644 --- a/Packages/worklist/server/services/wado/retrieveMetadata.js +++ b/Packages/worklist/server/services/wado/retrieveMetadata.js @@ -106,6 +106,7 @@ function resultDataToStudyMetadata(server, studyInstanceUid, resultData) { sourceImageInstanceUid: getSourceImageInstanceUid(instance), laterality: DICOMWeb.getString(instance['00200062']), viewPosition: DICOMWeb.getString(instance['00185101']), + acquisitionDatetime: DICOMWeb.getString(instance['0008002A']), numFrames: DICOMWeb.getNumber(instance['00280008']), frameTime: DICOMWeb.getNumber(instance['00181063']), sliceThickness: DICOMWeb.getNumber(instance['00180050']),