diff --git a/Packages/ohif-lesiontracker/client/components/timepointBrowser/item.js b/Packages/ohif-lesiontracker/client/components/timepointBrowser/item.js
index a784c987c..0c7580b2d 100644
--- a/Packages/ohif-lesiontracker/client/components/timepointBrowser/item.js
+++ b/Packages/ohif-lesiontracker/client/components/timepointBrowser/item.js
@@ -5,6 +5,8 @@ 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;
@@ -28,10 +30,22 @@ Template.timepointBrowserItem.onCreated(() => {
};
const filter = { studyInstanceUid: timepoint.studyInstanceUids };
- instance.loadStudies = () => OHIF.studies.searchStudies(filter).then(studiesData => {
+ 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 => {
timepoint.studiesData = studiesData;
timepointApi.timepoints.update(timepoint._id, { $set: { studiesData } });
instance.loaded = true;
+ instance.setModalitiesSummary();
instance.loading.set(false);
}).catch(error => {
const text = 'An error has occurred while retrieving studies information';
@@ -45,6 +59,10 @@ Template.timepointBrowserItem.onCreated(() => {
});
Template.timepointBrowserItem.events({
+ 'ohif.lesiontracker.timepoint.load .timepoint-item'(event, instance) {
+ instance.loadStudies();
+ },
+
'click .timepoint-item'(event, instance) {
const element = event.currentTarget.parentElement;
const $element = $(element);
@@ -55,10 +73,7 @@ Template.timepointBrowserItem.events({
if (!instance.loaded) {
instance.summary.set('Loading...');
- instance.loadStudies().then(() => {
- Tracker.afterFlush(triggerClick);
- instance.setModalitiesSummary();
- });
+ instance.loadStudies().then(() => Tracker.afterFlush(triggerClick));
} else {
triggerClick();
}
diff --git a/Packages/ohif-lesiontracker/client/components/timepointBrowser/sidebar.html b/Packages/ohif-lesiontracker/client/components/timepointBrowser/sidebar.html
index 5e2d752f8..6f760af62 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' scrollableClass='p-a-1'}}
+ {{#scrollArea class='flex-grow' class='fit' scrollableClass='p-a-1' scrollStep=191}}
{{>timepointBrowserList (extend timepointBrowserData)}}
{{/scrollArea}}
diff --git a/Packages/ohif-lesiontracker/client/components/timepointBrowser/sidebar.js b/Packages/ohif-lesiontracker/client/components/timepointBrowser/sidebar.js
index f7f4c13d3..ba71c4e26 100644
--- a/Packages/ohif-lesiontracker/client/components/timepointBrowser/sidebar.js
+++ b/Packages/ohif-lesiontracker/client/components/timepointBrowser/sidebar.js
@@ -11,18 +11,19 @@ Template.timepointBrowserSidebar.onCreated(() => {
Template.timepointBrowserSidebar.onRendered(() => {
const instance = Template.instance();
+ instance.lastType = '';
// Collapse all timepoints but first when timepoint view type changes
+ instance.$browserList = instance.$('.timepoint-browser-list').first();
instance.autorun(() => {
// Runs this computation every time the timepointViewType is changed
const type = instance.timepointViewType.get();
-
- // Removes all active classes to collapse the timepoints and studies
- instance.$('.timepoint-browser-item, .study-browser-item').removeClass('active');
- if (type === 'key') {
- // Show only first timepoint expanded for key timepoints
- instance.$('.timepoint-browser-item:first .timepoint-item').trigger('click');
+ if (type !== instance.lastType) {
+ const eventKey = 'ohif.lesiontracker.timepoint.changeViewType';
+ instance.$browserList.trigger(eventKey, type);
}
+
+ instance.lastType = type;
});
});
diff --git a/Packages/ohif-studies/imports/client/components/browser/sidebar.html b/Packages/ohif-studies/imports/client/components/browser/sidebar.html
index 8222d53ac..06d6d951f 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' scrollableClass='p-a-1'}}
+ {{#scrollArea class='full-height' class='fit' scrollableClass='p-a-1' scrollStep=191}}
{{>studyBrowserList (clone this studyChildTemplate='studyBrowserSeries')}}
{{/scrollArea}}
diff --git a/Packages/ohif-viewerbase/client/components/studyBrowser/thumbnailEntry/thumbnailEntry.styl b/Packages/ohif-viewerbase/client/components/studyBrowser/thumbnailEntry/thumbnailEntry.styl
index 0e03ce780..2f796a166 100644
--- a/Packages/ohif-viewerbase/client/components/studyBrowser/thumbnailEntry/thumbnailEntry.styl
+++ b/Packages/ohif-viewerbase/client/components/studyBrowser/thumbnailEntry/thumbnailEntry.styl
@@ -23,7 +23,6 @@ $seriesCountBackgroundColor = #678696
word-wrap: break-word
&.info-only
- min-height: auto
.seriesDescription
display: none
diff --git a/Packages/ohif-viewerbase/client/components/viewer/seriesQuickSwitch/seriesQuickSwitch.html b/Packages/ohif-viewerbase/client/components/viewer/seriesQuickSwitch/seriesQuickSwitch.html
index a7aa49d0b..264bc52f8 100644
--- a/Packages/ohif-viewerbase/client/components/viewer/seriesQuickSwitch/seriesQuickSwitch.html
+++ b/Packages/ohif-viewerbase/client/components/viewer/seriesQuickSwitch/seriesQuickSwitch.html
@@ -4,17 +4,15 @@
Series
-
-
-
-
-
-
-
-
-
37
- {{#scrollArea class='series-browser'}}
-
BBBBB
+ {{#each seriesItem in seriesItems}}
+
{{seriesItem.value}}
+ {{/each}}
+ {{#scrollArea class='series-browser' scrollStep=201}}
+
+ {{#each thumbnail in (studyThumbnails instance.currentStudy.get)}}
+ {{>thumbnailEntry (clone this thumbnail=thumbnail)}}
+ {{/each}}
+
{{/scrollArea}}
diff --git a/Packages/ohif-viewerbase/client/components/viewer/seriesQuickSwitch/seriesQuickSwitch.js b/Packages/ohif-viewerbase/client/components/viewer/seriesQuickSwitch/seriesQuickSwitch.js
index 6d4bab3c8..b8444fa36 100644
--- a/Packages/ohif-viewerbase/client/components/viewer/seriesQuickSwitch/seriesQuickSwitch.js
+++ b/Packages/ohif-viewerbase/client/components/viewer/seriesQuickSwitch/seriesQuickSwitch.js
@@ -1,9 +1,57 @@
import { Template } from 'meteor/templating';
+import { ReactiveVar } from 'meteor/reactive-var';
import { $ } from 'meteor/jquery';
import { OHIF } from 'meteor/ohif:core';
// FIXME >>>> REMOVE
$(document.body).on('keydown', e => (e.keyCode === 69 && $('.quickSwitchWrapper').toggle()) || 1);
+OHIF.cornerstone.renderer = '';
+
+Template.seriesQuickSwitch.onCreated(() => {
+ const instance = Template.instance();
+
+ // Defines the study being shown in the current viewport
+ instance.currentStudy = new ReactiveVar();
+
+ // Gets the viewport data for the given viewport index
+ instance.getViewportData = viewportIndex => {
+ const layoutManager = OHIF.viewerbase.layoutManager;
+ return layoutManager && layoutManager.viewportData && layoutManager.viewportData[viewportIndex];
+ };
+
+ // Gets the current viewport data
+ const viewportIndex = instance.data.viewportIndex;
+
+ instance.study = {};
+ instance.lastStudy = {};
+
+ instance.autorun(() => {
+ OHIF.viewerbase.layoutManager.observer.depend();
+
+ const viewportData = instance.getViewportData(viewportIndex);
+
+ // @TypeSafeStudies
+ if (viewportData) {
+ // Finds the current study and return it
+ instance.study = OHIF.viewer.Studies.findBy({
+ studyInstanceUid: viewportData.studyInstanceUid
+ });
+ } else {
+ instance.study = OHIF.viewer.Studies.getElementByIndex(0);
+ }
+
+ if (!instance.study) {
+ return;
+ }
+
+ if (instance.study.studyInstanceUid !== instance.lastStudy.studyInstanceUid) {
+ // Change the current study to update the thumbnails
+ instance.currentStudy.set(instance.study);
+
+ instance.lastStudy = instance.study;
+ }
+ });
+});
Template.seriesQuickSwitch.helpers({
shallDisplay() {
@@ -17,13 +65,54 @@ Template.seriesQuickSwitch.helpers({
const { columns, viewportIndex } = instance.data;
if (columns === 1) return '';
return viewportIndex === 0 ? 'left' : 'right';
+ },
+
+ seriesItems() {
+ const instance = Template.instance();
+
+ OHIF.viewerbase.layoutManager.observer.depend();
+ const { viewportIndex } = instance.data;
+ const viewportData = OHIF.viewerbase.layoutManager.viewportData[viewportIndex];
+ const study = instance.currentStudy.get();
+
+ const seriesItems = [];
+
+ const items = study.displaySets.length;
+ for (let i = 0; i < items; i++) {
+ const displaySet = study.displaySets[i];
+ const item = { class: '' };
+ seriesItems.push(item);
+ if (i === 8 && items !== 9) {
+ item.class += ' count';
+ item.value = items;
+ break;
+ }
+
+ if (displaySet.displaySetInstanceUid === viewportData.displaySetInstanceUid) {
+ item.class += ' active';
+ }
+ }
+
+ return seriesItems;
}
});
Template.seriesQuickSwitch.events({
'mouseenter .series-switch'(event, instance) {
+ // Control the width of the series browser
const $switch = $(event.currentTarget);
const browserWidth = $switch.offset().left + $switch.outerWidth();
- $switch.find('.series-browser').width(browserWidth);
+ const $seriesBrowser = $switch.find('.series-browser');
+ $seriesBrowser.width(browserWidth);
+
+ instance.$('.series-quick-switch').addClass('series-triggered');
+ },
+
+ 'mouseleave .series-browser'(event, instance) {
+ $(event.currentTarget).children('.scrollable').stop().animate({ scrollTop: 0 }, 300, 'swing');
+ },
+
+ 'mouseleave .series-quick-switch'(event, instance) {
+ $(event.currentTarget).removeClass('series-triggered');
}
});
diff --git a/Packages/ohif-viewerbase/client/components/viewer/seriesQuickSwitch/seriesQuickSwitch.styl b/Packages/ohif-viewerbase/client/components/viewer/seriesQuickSwitch/seriesQuickSwitch.styl
index a22578ff6..c3ebec0a0 100644
--- a/Packages/ohif-viewerbase/client/components/viewer/seriesQuickSwitch/seriesQuickSwitch.styl
+++ b/Packages/ohif-viewerbase/client/components/viewer/seriesQuickSwitch/seriesQuickSwitch.styl
@@ -42,7 +42,13 @@
right: auto
transform-origin(1em calc(1em + 15px))
- .series-box .series-item
+ .thumbnails-wrapper
+ transform-origin(0% 0%)
+
+ .thumbnailEntry
+ float: left
+
+ .series-item
float: left
.title-label
@@ -50,8 +56,10 @@
font-size: 12px
font-weight: 500
line-height: 12px
+ opacity: 1
padding-bottom: 3px
text-align: center
+ transition(opacity 0.3s ease)
.series-switch,
.study-switch
@@ -65,51 +73,114 @@
width: 285px
.series-browser
- background: blue
max-width: 711px
right: 0
transform-origin(calc(100% - 1em) calc(1em + 15px))
+ .thumbnails-wrapper
+ transition(transform 0.3s ease)
+ transform-origin(100% 0%)
+
+ .thumbnailEntry
+ float: right
+
+ .seriesDetails
+ opacity: 0
+ transform(translateY(-100%))
+ transition(transform 0.3s ease\, opacity 0.3s ease)
+
+ .scrollable
+ padding-top: 15px
+ transition(padding-bottom 0.3s ease)
+
.series-browser,
.study-browser
max-height: 100vh
min-height: 120px
+ opacity: 0
position: absolute
top: 0
transform(scale(0))
- transition(transform 0.3s ease)
+ transition(transform 0.3s ease\, opacity 0.3s ease)
+ z-index: 3
- .series-box
+ .series-box,
+ .study-box
height: 57px
width: 57px
- .series-item
- theme('background-color', '$boxBackgroundColor')
- border-radius(3px)
- float: right
- height: 15px
- margin: 2px
- width: 15px
-
- &.count
- theme('color', '$textPrimaryColor')
- background-color: transparent
- font-size: 12px
- font-weight: 500
- line-height: 17px
- text-align: center
-
- &.active
- theme('background-color', '$activeColor')
-
-
.study-box
theme('background-color', '$uiGrayDark')
theme('border', 'solid 2px $uiBorderColorDark')
- border-radius: 11px
- height: 57px
- width: 57px
+ border-radius(11px)
+ .series-item
+ theme('background-color', '$boxBackgroundColor')
+ border-radius(3px)
+ float: right
+ height: 15px
+ margin: 2px
+ transition(opacity 0.3s ease)
+ width: 15px
+
+ &.count
+ theme('color', '$textPrimaryColor')
+ background-color: transparent
+ font-size: 12px
+ font-weight: 500
+ line-height: 17px
+ text-align: center
+
+ &.active
+ theme('background-color', '$activeColor')
+
+ &.series-triggered .series-browser,
.series-switch:hover .series-browser,
.study-switch:hover .study-browser
+ opacity: 1
transform(scale(1))
+
+ &.series-triggered .series-item,
+ .series-switch:hover .title-label
+ opacity: 0
+
+ &.series-triggered
+ .thumbnails-wrapper
+ transform(scale(0.9) translateY(80px))
+
+ .series-browser:not(:hover)
+ &>.scrollable
+ padding-bottom: 80px
+
+ &>.scroll-nav
+ opacity: 0
+
+ .series-switch:hover .series-browser
+ .thumbnails-wrapper
+ transform(scale(1) translateY(0))
+
+ .thumbnailEntry .seriesDetails
+ opacity: 1
+ transform(translateY(0))
+ transition-delay(0.3s)
+
+@media screen and (max-width: 1599px)
+ .series-quick-switch
+
+ .series-box,
+ .study-box
+ width: 36px
+ height: 36px
+
+ .study-box
+ border-radius(7px)
+
+ .series-item
+ height: 10px
+ margin: 1px
+ width: 10px
+
+ &.count
+ font-size: 10px
+ font-weight: 300
+ line-height: 10px
diff --git a/Packages/ohif-viewerbase/client/lib/classes/LayoutManager.js b/Packages/ohif-viewerbase/client/lib/classes/LayoutManager.js
index 623dfb90a..50dc88b2c 100644
--- a/Packages/ohif-viewerbase/client/lib/classes/LayoutManager.js
+++ b/Packages/ohif-viewerbase/client/lib/classes/LayoutManager.js
@@ -18,6 +18,7 @@ export class LayoutManager {
constructor(parentNode, studies) {
OHIF.log.info('LayoutManager constructor');
+ this.observer = new Tracker.Dependency();
this.parentNode = parentNode;
this.studies = studies;
this.viewportData = [];
@@ -30,7 +31,10 @@ export class LayoutManager {
this.isZoomed = false;
- const updateSessionFn = () => Tracker.afterFlush(() => Session.set('LayoutManagerUpdated', Math.random()));
+ const updateSessionFn = () => Tracker.afterFlush(() => {
+ Session.set('LayoutManagerUpdated', Math.random());
+ this.observer.changed();
+ });
this.updateSession = _.throttle(updateSessionFn, 300);
}