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']),