diff --git a/LesionTracker/client/components/viewerSection/viewerSection.js b/LesionTracker/client/components/viewerSection/viewerSection.js
index 4ec727a0e..92685b1ca 100644
--- a/LesionTracker/client/components/viewerSection/viewerSection.js
+++ b/LesionTracker/client/components/viewerSection/viewerSection.js
@@ -8,7 +8,9 @@ Template.viewerSection.onCreated(() => {
instance.isTimepointBrowser = () => !!OHIF.viewer.data.currentTimepointId;
+ OHIF.viewer.quickSwitchStudyBrowserTemplate = 'timepointBrowserQuickSwitch';
if (!instance.isTimepointBrowser()) {
+ OHIF.viewer.quickSwitchStudyBrowserTemplate = 'studyBrowserQuickSwitch';
instance.loading = new ReactiveVar(true);
instance.studiesInformation = new ReactiveVar([]);
const filter = { studyInstanceUid: OHIF.viewer.data.studyInstanceUids };
diff --git a/Packages/ohif-lesiontracker/client/components/timepointBrowser/index.js b/Packages/ohif-lesiontracker/client/components/timepointBrowser/index.js
index c8c8f6526..2ef72e316 100644
--- a/Packages/ohif-lesiontracker/client/components/timepointBrowser/index.js
+++ b/Packages/ohif-lesiontracker/client/components/timepointBrowser/index.js
@@ -2,6 +2,8 @@ import './item.html';
import './item.js';
import './list.html';
import './list.styl';
+import './quickSwitch.html';
+import './quickSwitch.js';
import './sidebar.html';
import './sidebar.js';
import './studies.html';
diff --git a/Packages/ohif-lesiontracker/client/components/timepointBrowser/item.js b/Packages/ohif-lesiontracker/client/components/timepointBrowser/item.js
index 0c7580b2d..5eaa78693 100644
--- a/Packages/ohif-lesiontracker/client/components/timepointBrowser/item.js
+++ b/Packages/ohif-lesiontracker/client/components/timepointBrowser/item.js
@@ -5,8 +5,6 @@ import { $ } from 'meteor/jquery';
import { _ } from 'meteor/underscore';
import { OHIF } from 'meteor/ohif:core';
-const studySearchPromises = new Map();
-
Template.timepointBrowserItem.onCreated(() => {
const instance = Template.instance();
const { timepoint, timepointApi } = instance.data;
@@ -30,18 +28,7 @@ Template.timepointBrowserItem.onCreated(() => {
};
const filter = { studyInstanceUid: timepoint.studyInstanceUids };
- instance.loadStudies = () => {
- const promiseKey = JSON.stringify(filter);
- if (studySearchPromises.has(promiseKey)) {
- return studySearchPromises.get(promiseKey);
- } else {
- const promise = instance.performLoad();
- studySearchPromises.set(promiseKey, promise);
- return promise;
- }
- };
-
- instance.performLoad = () => OHIF.studies.searchStudies(filter).then(studiesData => {
+ instance.loadStudies = () => OHIF.studies.searchStudies(filter).then(studiesData => {
timepoint.studiesData = studiesData;
timepointApi.timepoints.update(timepoint._id, { $set: { studiesData } });
instance.loaded = true;
diff --git a/Packages/ohif-lesiontracker/client/components/timepointBrowser/quickSwitch.html b/Packages/ohif-lesiontracker/client/components/timepointBrowser/quickSwitch.html
new file mode 100644
index 000000000..5e7d638cc
--- /dev/null
+++ b/Packages/ohif-lesiontracker/client/components/timepointBrowser/quickSwitch.html
@@ -0,0 +1,6 @@
+
+ {{>timepointBrowserList (extend timepointBrowserData)}}
+ {{#unless instance.showAdditional.get}}
+ Show additional timepoints
+ {{/unless}}
+
diff --git a/Packages/ohif-lesiontracker/client/components/timepointBrowser/quickSwitch.js b/Packages/ohif-lesiontracker/client/components/timepointBrowser/quickSwitch.js
new file mode 100644
index 000000000..51ce41925
--- /dev/null
+++ b/Packages/ohif-lesiontracker/client/components/timepointBrowser/quickSwitch.js
@@ -0,0 +1,94 @@
+import { Meteor } from 'meteor/meteor';
+import { Template } from 'meteor/templating';
+import { ReactiveVar } from 'meteor/reactive-var';
+import { Tracker } from 'meteor/tracker';
+import { OHIF } from 'meteor/ohif:core';
+
+Template.timepointBrowserQuickSwitch.onCreated(() => {
+ const instance = Template.instance();
+ instance.showAdditional = new ReactiveVar(false);
+ instance.currentTimepoint = new ReactiveVar();
+
+ instance.updateCurrentTimepoint = studyInstanceUid => {
+ const currentTimepoint = OHIF.viewer.timepointApi.study(studyInstanceUid)[0];
+ instance.currentTimepoint.set(currentTimepoint);
+ };
+
+ const { viewportIndex } = instance.data;
+ instance.autorun(() => {
+ OHIF.viewerbase.layoutManager.observer.depend();
+ const viewportData = OHIF.viewerbase.layoutManager.viewportData[viewportIndex];
+ instance.updateCurrentTimepoint(viewportData.studyInstanceUid);
+ });
+
+ instance.autorun(() => {
+ instance.data.currentStudy.dep.depend();
+ instance.showAdditional.set(false);
+ });
+});
+
+Template.timepointBrowserQuickSwitch.onRendered(() => {
+ const instance = Template.instance();
+
+ instance.autorun(() => {
+ const currentTimepoint = instance.currentTimepoint.get();
+ const currentTimepointId = (currentTimepoint && currentTimepoint.timepointId) || '';
+ const $allBrowserItems = instance.$('.timepoint-browser-item');
+ const $browserItem = $allBrowserItems.filter(`[data-id=${currentTimepointId}]`);
+ if (!$browserItem.hasClass('active')) {
+ $browserItem.find('.timepoint-item').trigger('click');
+ }
+ });
+
+ instance.autorun(() => {
+ const currentStudy = instance.data.currentStudy.get();
+ const studyInstanceUid = (currentStudy && currentStudy.studyInstanceUid) || '';
+ Tracker.afterFlush(() => {
+ const $studyBrowserItems = instance.$('.study-browser-item');
+ $studyBrowserItems.removeClass('active');
+ $studyBrowserItems.filter(`[data-uid="${studyInstanceUid}"]`).addClass('active');
+ });
+ });
+});
+
+Template.timepointBrowserQuickSwitch.events({
+ 'ohif.lesiontracker.timepoint.click'(event, instance) {
+ const $element = $(event.currentTarget);
+
+ // Defer the active class toggling to wait for child template rendering
+ Meteor.defer(() => $element.toggleClass('active'));
+ },
+
+ 'ohif.studies.study.click'(event, instance, studyInformation) {
+ const { studyInstanceUid } = studyInformation;
+ const study = OHIF.viewer.Studies.findBy({ studyInstanceUid });
+ instance.data.currentStudy.set(study);
+ const $studySwitch = $(event.currentTarget).closest('.study-switch');
+ $studySwitch.siblings('.series-switch').trigger('rescale');
+ instance.updateCurrentTimepoint(studyInformation.studyInstanceUid);
+ },
+
+ 'click .show-additional'(event, instance) {
+ instance.showAdditional.set(true);
+ },
+});
+
+Template.timepointBrowserQuickSwitch.helpers({
+ timepointBrowserData() {
+ const instance = Template.instance();
+ const { timepointApi } = OHIF.viewer;
+ const currentTimepoint = instance.currentTimepoint.get();
+ let timepoints;
+ if (instance.showAdditional.get()) {
+ timepoints = timepointApi.key();
+ } else {
+ timepoints = [currentTimepoint];
+ }
+
+ return {
+ timepointApi,
+ timepoints,
+ timepointChildTemplate: 'timepointBrowserStudies'
+ };
+ }
+});
diff --git a/Packages/ohif-lesiontracker/client/components/timepointBrowser/sidebar.html b/Packages/ohif-lesiontracker/client/components/timepointBrowser/sidebar.html
index 6f760af62..bb2762f50 100644
--- a/Packages/ohif-lesiontracker/client/components/timepointBrowser/sidebar.html
+++ b/Packages/ohif-lesiontracker/client/components/timepointBrowser/sidebar.html
@@ -5,7 +5,7 @@
{{>roundedButtonGroup viewTypeButtonGroupData}}
- {{#scrollArea class='flex-grow' class='fit' scrollableClass='p-a-1' scrollStep=191}}
+ {{#scrollArea class='flex-grow fit' scrollableClass='p-a-1' scrollStep=191}}
{{>timepointBrowserList (extend timepointBrowserData)}}
{{/scrollArea}}
diff --git a/Packages/ohif-studies/imports/client/components/browser/index.js b/Packages/ohif-studies/imports/client/components/browser/index.js
index 1e199fc33..5474d5ef4 100644
--- a/Packages/ohif-studies/imports/client/components/browser/index.js
+++ b/Packages/ohif-studies/imports/client/components/browser/index.js
@@ -1,7 +1,9 @@
-import './list.html';
-import './list.styl';
import './item.html';
import './item.js';
+import './list.html';
+import './list.styl';
+import './quickSwitch.html';
+import './quickSwitch.js';
import './series.html';
import './series.js';
import './sidebar.html';
diff --git a/Packages/ohif-studies/imports/client/components/browser/quickSwitch.html b/Packages/ohif-studies/imports/client/components/browser/quickSwitch.html
new file mode 100644
index 000000000..5491cae86
--- /dev/null
+++ b/Packages/ohif-studies/imports/client/components/browser/quickSwitch.html
@@ -0,0 +1,3 @@
+
+ {{>studyBrowserList studyBrowserData}}
+
diff --git a/Packages/ohif-studies/imports/client/components/browser/quickSwitch.js b/Packages/ohif-studies/imports/client/components/browser/quickSwitch.js
new file mode 100644
index 000000000..25cf327bb
--- /dev/null
+++ b/Packages/ohif-studies/imports/client/components/browser/quickSwitch.js
@@ -0,0 +1,43 @@
+import { Template } from 'meteor/templating';
+import { ReactiveVar } from 'meteor/reactive-var';
+import { Tracker } from 'meteor/tracker';
+import { OHIF } from 'meteor/ohif:core';
+
+Template.studyBrowserQuickSwitch.onCreated(() => {
+ const instance = Template.instance();
+ instance.studiesInformation = new ReactiveVar();
+ const filter = { studyInstanceUid: OHIF.viewer.data.studyInstanceUids };
+ OHIF.studies.searchStudies(filter).then(studies => instance.studiesInformation.set(studies));
+});
+
+Template.studyBrowserQuickSwitch.onRendered(() => {
+ const instance = Template.instance();
+ instance.autorun(() => {
+ instance.studiesInformation.dep.depend();
+ const currentStudy = instance.data.currentStudy.get();
+ const studyInstanceUid = (currentStudy && currentStudy.studyInstanceUid) || '';
+ Tracker.afterFlush(() => {
+ const $studyBrowserItems = instance.$('.study-browser-item');
+ $studyBrowserItems.removeClass('active');
+ $studyBrowserItems.filter(`[data-uid="${studyInstanceUid}"]`).addClass('active');
+ });
+ });
+});
+
+Template.studyBrowserQuickSwitch.events({
+ 'ohif.studies.study.click'(event, instance, studyInformation) {
+ const { studyInstanceUid } = studyInformation;
+ const study = OHIF.viewer.Studies.findBy({ studyInstanceUid });
+ instance.data.currentStudy.set(study);
+ const $studySwitch = $(event.currentTarget).closest('.study-switch');
+ $studySwitch.siblings('.series-switch').trigger('rescale');
+ }
+});
+
+Template.studyBrowserQuickSwitch.helpers({
+ studyBrowserData() {
+ const instance = Template.instance();
+ const studiesInformation = instance.studiesInformation.get();
+ return { studiesInformation };
+ }
+});
diff --git a/Packages/ohif-studies/imports/client/components/browser/sidebar.html b/Packages/ohif-studies/imports/client/components/browser/sidebar.html
index 06d6d951f..505033faa 100644
--- a/Packages/ohif-studies/imports/client/components/browser/sidebar.html
+++ b/Packages/ohif-studies/imports/client/components/browser/sidebar.html
@@ -1,5 +1,5 @@
- {{#scrollArea class='full-height' class='fit' scrollableClass='p-a-1' scrollStep=191}}
+ {{#scrollArea class='fit' scrollableClass='p-a-1' scrollStep=191}}
{{>studyBrowserList (clone this studyChildTemplate='studyBrowserSeries')}}
{{/scrollArea}}
diff --git a/Packages/ohif-studies/imports/client/lib/searchStudies.js b/Packages/ohif-studies/imports/client/lib/searchStudies.js
index 98639c890..5a7b5a5a0 100644
--- a/Packages/ohif-studies/imports/client/lib/searchStudies.js
+++ b/Packages/ohif-studies/imports/client/lib/searchStudies.js
@@ -1,18 +1,29 @@
import { Meteor } from 'meteor/meteor';
import { OHIF } from 'meteor/ohif:core';
+const studySearchPromises = new Map();
+
/**
* Search for studies information by the given filter
*
* @param {Object} filter Filter that will be used on search
* @returns {Promise} resolved with an array of studies information or rejected with an error
*/
-OHIF.studies.searchStudies = filter => new Promise((resolve, reject) => {
- Meteor.call('StudyListSearch', filter, (error, studiesData) => {
- if (error) {
- reject(error);
- } else {
- resolve(studiesData);
- }
- });
-});
+OHIF.studies.searchStudies = filter => {
+ const promiseKey = JSON.stringify(filter);
+ if (studySearchPromises.has(promiseKey)) {
+ return studySearchPromises.get(promiseKey);
+ } else {
+ const promise = new Promise((resolve, reject) => {
+ Meteor.call('StudyListSearch', filter, (error, studiesData) => {
+ if (error) {
+ reject(error);
+ } else {
+ resolve(studiesData);
+ }
+ });
+ });
+ studySearchPromises.set(promiseKey, promise);
+ return promise;
+ }
+};
diff --git a/Packages/ohif-viewerbase/client/components/viewer/gridLayout/gridLayout.html b/Packages/ohif-viewerbase/client/components/viewer/gridLayout/gridLayout.html
index e44715abc..e5f1a522e 100644
--- a/Packages/ohif-viewerbase/client/components/viewer/gridLayout/gridLayout.html
+++ b/Packages/ohif-viewerbase/client/components/viewer/gridLayout/gridLayout.html
@@ -5,7 +5,7 @@
{{>imageViewerViewport (clone viewport)}}
- {{>seriesQuickSwitch (clone this viewportIndex=@index)}}
+ {{>seriesQuickSwitch (clone this viewport=viewport viewportIndex=@index)}}
{{/each}}
diff --git a/Packages/ohif-viewerbase/client/components/viewer/seriesQuickSwitch/seriesQuickSwitch.html b/Packages/ohif-viewerbase/client/components/viewer/seriesQuickSwitch/seriesQuickSwitch.html
index 264bc52f8..1406b8fcf 100644
--- a/Packages/ohif-viewerbase/client/components/viewer/seriesQuickSwitch/seriesQuickSwitch.html
+++ b/Packages/ohif-viewerbase/client/components/viewer/seriesQuickSwitch/seriesQuickSwitch.html
@@ -20,7 +20,7 @@
Study
{{#scrollArea class='study-browser'}}
-
AAAAA
+ {{>Template.dynamic template=studyBrowserTemplate data=(clone this currentStudy=instance.currentStudy)}}
{{/scrollArea}}
diff --git a/Packages/ohif-viewerbase/client/components/viewer/seriesQuickSwitch/seriesQuickSwitch.js b/Packages/ohif-viewerbase/client/components/viewer/seriesQuickSwitch/seriesQuickSwitch.js
index b8444fa36..023b6172d 100644
--- a/Packages/ohif-viewerbase/client/components/viewer/seriesQuickSwitch/seriesQuickSwitch.js
+++ b/Packages/ohif-viewerbase/client/components/viewer/seriesQuickSwitch/seriesQuickSwitch.js
@@ -94,11 +94,15 @@ Template.seriesQuickSwitch.helpers({
}
return seriesItems;
+ },
+
+ studyBrowserTemplate() {
+ return OHIF.viewer.quickSwitchStudyBrowserTemplate || 'studyBrowserQuickSwitch';
}
});
Template.seriesQuickSwitch.events({
- 'mouseenter .series-switch'(event, instance) {
+ 'mouseenter .series-switch, rescale .series-switch'(event, instance) {
// Control the width of the series browser
const $switch = $(event.currentTarget);
const browserWidth = $switch.offset().left + $switch.outerWidth();
diff --git a/Packages/ohif-viewerbase/client/components/viewer/seriesQuickSwitch/seriesQuickSwitch.styl b/Packages/ohif-viewerbase/client/components/viewer/seriesQuickSwitch/seriesQuickSwitch.styl
index c3ebec0a0..35d56ebcf 100644
--- a/Packages/ohif-viewerbase/client/components/viewer/seriesQuickSwitch/seriesQuickSwitch.styl
+++ b/Packages/ohif-viewerbase/client/components/viewer/seriesQuickSwitch/seriesQuickSwitch.styl
@@ -66,13 +66,27 @@
float: left
position: relative
- .study-browser
- background: purple
+ .study-switch:hover:after
+ content: ''
+ display: block
+ height: 100px
left: 0
+ position: absolute
+ top: 0
+ width: 300px
+
+ .study-browser
+ left: 0
+ margin-top: 100px
+ max-height: calc(100vh - 100px)
transform-origin(1em calc(1em + 17px))
- width: 285px
+ width: 300px
+
+ .study-browser-list
+ padding: 0 10px
.series-browser
+ max-height: 100vh
max-width: 711px
right: 0
transform-origin(calc(100% - 1em) calc(1em + 15px))
@@ -95,7 +109,6 @@
.series-browser,
.study-browser
- max-height: 100vh
min-height: 120px
opacity: 0
position: absolute
@@ -164,6 +177,9 @@
transform(translateY(0))
transition-delay(0.3s)
+ .study-browser-item.active .study-item-box
+ theme('box-shadow', 'inset 0 0 0 3px $activeColor')
+
@media screen and (max-width: 1599px)
.series-quick-switch