diff --git a/LesionTracker/client/components/viewerSection/viewerSection.html b/LesionTracker/client/components/viewerSection/viewerSection.html index 3d2ade39a..4b4d2e234 100644 --- a/LesionTracker/client/components/viewerSection/viewerSection.html +++ b/LesionTracker/client/components/viewerSection/viewerSection.html @@ -2,8 +2,8 @@
{{>viewerMain (clone this)}} diff --git a/LesionTracker/client/components/viewerSection/viewerSection.js b/LesionTracker/client/components/viewerSection/viewerSection.js index 46a20fab9..d14431cbd 100644 --- a/LesionTracker/client/components/viewerSection/viewerSection.js +++ b/LesionTracker/client/components/viewerSection/viewerSection.js @@ -25,7 +25,16 @@ Template.viewerSection.helpers({ const timepoints = timepointApi.all(); return { timepointApi, - timepoints + timepoints, + + timepointChildTemplate: 'timepointBrowserStudies', + studyChildTemplate: 'studyBrowserSeries', + + studyClickCallback(studyInformation, element) { + const $element = $(element); + $element.siblings().removeClass('active'); + $element.toggleClass('active'); + } }; } }); diff --git a/Packages/ohif-lesiontracker/client/components/timepointBrowser/index.js b/Packages/ohif-lesiontracker/client/components/timepointBrowser/index.js index 66e32a13e..f980d29c3 100644 --- a/Packages/ohif-lesiontracker/client/components/timepointBrowser/index.js +++ b/Packages/ohif-lesiontracker/client/components/timepointBrowser/index.js @@ -1,3 +1,6 @@ -import './list.html'; import './item.html'; import './item.js'; +import './item.styl'; +import './list.html'; +import './studies.html'; +import './studies.js'; diff --git a/Packages/ohif-lesiontracker/client/components/timepointBrowser/item.html b/Packages/ohif-lesiontracker/client/components/timepointBrowser/item.html index 9d041de13..2920dc678 100644 --- a/Packages/ohif-lesiontracker/client/components/timepointBrowser/item.html +++ b/Packages/ohif-lesiontracker/client/components/timepointBrowser/item.html @@ -1,6 +1,6 @@ diff --git a/Packages/ohif-lesiontracker/client/components/timepointBrowser/item.js b/Packages/ohif-lesiontracker/client/components/timepointBrowser/item.js index 7b986aaba..cf2a35deb 100644 --- a/Packages/ohif-lesiontracker/client/components/timepointBrowser/item.js +++ b/Packages/ohif-lesiontracker/client/components/timepointBrowser/item.js @@ -1,28 +1,67 @@ import { Meteor } from 'meteor/meteor'; import { Template } from 'meteor/templating'; import { ReactiveVar } from 'meteor/reactive-var'; +import { $ } from 'meteor/jquery'; +import { _ } from 'meteor/underscore'; import { OHIF } from 'meteor/ohif:core'; Template.timepointBrowserItem.onCreated(() => { const instance = Template.instance(); const { timepoint, timepointApi } = instance.data; + instance.summary = new ReactiveVar(''); instance.loading = new ReactiveVar(false); instance.loaded = !!(timepoint.studiesData && timepoint.studiesData.length); - instance.autorun(() => { - if (instance.loaded || !instance.loading.get()) return; + // Build the modalities summary of all timepoint's studies + instance.setModalitiesSummary = () => { + const modalities = {}; + timepoint.studiesData.forEach(study => { + const modality = study.modalities || 'UN'; + modalities[modality] = modalities[modality] + 1 || 1; + }); + const summary = []; + _.each(modalities, (count, modality) => summary.push(`${count} ${modality}`)); + + instance.summary.set(summary.join(', ')); + }; + + instance.loadStudies = () => new Promise((resolve, reject) => { const filter = { studyInstanceUid: timepoint.studyInstanceUids }; + instance.summary.set('Loading...'); Meteor.call('StudyListSearch', filter, (error, studiesData) => { if (error) { const text = 'An error has occurred while retrieving studies information'; OHIF.ui.notifications.danger({ text }); OHIF.log.error(error); + reject(error); } else { timepoint.studiesData = studiesData; - timepointApi.timepoints.update(timepoint._id, { $set: studiesData }); + timepointApi.timepoints.update(timepoint._id, { $set: { studiesData } }); + instance.loaded = true; + instance.loading.set(false); + resolve(studiesData); } }); }); + + if (instance.loaded) { + instance.setModalitiesSummary(); + } +}); + +Template.timepointBrowserItem.events({ + 'click .timepointEntry'(event, instance) { + const element = event.currentTarget.parentElement; + const $element = $(element); + if (!instance.loaded) { + instance.loadStudies().then(() => { + $element.addClass('active'); + instance.setModalitiesSummary(); + }); + } else { + $element.toggleClass('active'); + } + } }); diff --git a/Packages/ohif-lesiontracker/client/components/timepointBrowser/item.styl b/Packages/ohif-lesiontracker/client/components/timepointBrowser/item.styl new file mode 100644 index 000000000..989a14e73 --- /dev/null +++ b/Packages/ohif-lesiontracker/client/components/timepointBrowser/item.styl @@ -0,0 +1,71 @@ +@require '{ohif:design}/app' + +.timepoint-browser-item + + .timepointEntry + cursor: pointer + font-size: 13px + + .timepoint-browser-studies + opacity: 1 + overflow: hidden + transform(translateY(0)) + transform-origin(50% 0%) + transition(max-height 0.3s ease\, opacity 0.3s ease\, transform 0.3s ease) + + &:not(.active) .timepoint-browser-studies + max-height: 0 !important + opacity: 0 + transform(translateY(-100%)) + + .timepointDate + opacity: 1 + + &.active + .timepointModalities + max-height: 0 + opacity: 0 + + .timepointDate + opacity: 0 + + .expandIcon i + transform: rotateX(180deg) + + .timepointFollowupTitle + font-size: 14px + theme('color', '$textSecondaryColor') + text-transform: uppercase + + & + .expandIcon i, + .timepointFollowupTitle, + .timepointDate, + .timepointModalities + theme('color', '$textSecondaryColor') + transition($sidebarTransition) + + &:hover + &, + .timepointFollowupTitle, + .expandIcon i, + .timepointDate, + .timepointModalities + theme('color', '$textPrimaryColor') !important + + .timepointDetails + .timepointModalities + line-height: 25px + + .timepointModalities + height: 25px + max-height: 25px + opacity: 1 + overflow: hidden + + .expandIcon i + theme('color', '$defaultColor') + + .timepointFollowupTitle + theme('color', '$textPrimaryColor') + padding-top: 2px diff --git a/Packages/ohif-lesiontracker/client/components/timepointBrowser/list.html b/Packages/ohif-lesiontracker/client/components/timepointBrowser/list.html index 66f179f9e..1b35366f1 100644 --- a/Packages/ohif-lesiontracker/client/components/timepointBrowser/list.html +++ b/Packages/ohif-lesiontracker/client/components/timepointBrowser/list.html @@ -1,7 +1,7 @@ diff --git a/Packages/ohif-lesiontracker/client/components/timepointBrowser/studies.html b/Packages/ohif-lesiontracker/client/components/timepointBrowser/studies.html new file mode 100644 index 000000000..f892188f1 --- /dev/null +++ b/Packages/ohif-lesiontracker/client/components/timepointBrowser/studies.html @@ -0,0 +1,5 @@ + diff --git a/Packages/ohif-lesiontracker/client/components/timepointBrowser/studies.js b/Packages/ohif-lesiontracker/client/components/timepointBrowser/studies.js new file mode 100644 index 000000000..405a51358 --- /dev/null +++ b/Packages/ohif-lesiontracker/client/components/timepointBrowser/studies.js @@ -0,0 +1,16 @@ +import { Meteor } from 'meteor/meteor'; +import { Template } from 'meteor/templating'; + +Template.timepointBrowserStudies.onRendered(() => { + const instance = Template.instance(); + const $container = instance.$('.timepoint-browser-studies'); + instance.adjustMaxHeight = () => $container.adjustMax('height'); + instance.adjustMaxHeight(); +}); + +Template.timepointBrowserStudies.events({ + 'ohif.studies.study.click'(event, instance) { + // FIXME disable all transitions during $.tempShow + Meteor.setTimeout(instance.adjustMaxHeight, 300); + } +}); diff --git a/Packages/ohif-measurements/both/schema/timepoints.js b/Packages/ohif-measurements/both/schema/timepoints.js index 1b734cbf3..78a13d888 100644 --- a/Packages/ohif-measurements/both/schema/timepoints.js +++ b/Packages/ohif-measurements/both/schema/timepoints.js @@ -40,6 +40,7 @@ export const schema = new SimpleSchema({ studiesData: { type: [Object], label: 'Studies data to allow lazy loading', - optional: true + optional: true, + blackbox: true } }); diff --git a/Packages/ohif-studies/imports/client/components/browser/item.js b/Packages/ohif-studies/imports/client/components/browser/item.js index 4134ac5f3..a4cd095bc 100644 --- a/Packages/ohif-studies/imports/client/components/browser/item.js +++ b/Packages/ohif-studies/imports/client/components/browser/item.js @@ -20,12 +20,13 @@ Template.studyBrowserItem.events({ const { studyClickCallback, studyInformation } = instance.data; const element = event.currentTarget.parentElement; const $element = $(element); - $element.trigger('ohif.studies.study.click', studyInformation); const triggerClickCallback = () => { if (typeof studyClickCallback === 'function') { studyClickCallback(studyInformation, element); } + + $element.trigger('ohif.studies.study.click', studyInformation); }; if (instance.loaded) { diff --git a/Packages/ohif-viewerbase/client/components/viewer/studyTimepointBrowser/studyTimepointBrowser.js b/Packages/ohif-viewerbase/client/components/viewer/studyTimepointBrowser/studyTimepointBrowser.js index 367f7196f..26ead8eba 100644 --- a/Packages/ohif-viewerbase/client/components/viewer/studyTimepointBrowser/studyTimepointBrowser.js +++ b/Packages/ohif-viewerbase/client/components/viewer/studyTimepointBrowser/studyTimepointBrowser.js @@ -195,22 +195,12 @@ Template.studyTimepointBrowser.helpers({ const studies = instance.getStudies(timepoint); - const includedUids = new Set(); const modalities = {}; studies.forEach(study => { const modality = study.modalities || 'UN'; modalities[modality] = modalities[modality] + 1 || 1; - includedUids.add(study.studyInstanceUid); }); - if (_.isArray(timepoint.studiesData)) { - timepoint.studiesData.forEach(({ modality, studyInstanceUid }) => { - if (includedUids.has(studyInstanceUid)) return; - modalities[modality] = modalities[modality] + 1 || 1; - includedUids.add(studyInstanceUid); - }); - } - const result = []; _.each(modalities, (count, modality) => { result.push(`${count} ${modality}`); diff --git a/Packages/ohif-viewerbase/client/components/viewer/studyTimepointBrowser/studyTimepointBrowser.styl b/Packages/ohif-viewerbase/client/components/viewer/studyTimepointBrowser/studyTimepointBrowser.styl index ff0d09cad..d956cb3a2 100644 --- a/Packages/ohif-viewerbase/client/components/viewer/studyTimepointBrowser/studyTimepointBrowser.styl +++ b/Packages/ohif-viewerbase/client/components/viewer/studyTimepointBrowser/studyTimepointBrowser.styl @@ -28,54 +28,6 @@ $timepointButtonHeight = 55px .studyTimepointScrollArea padding-top: $timepointButtonHeight - .timepointEntry - &.active - .timepointModalities - height: 0 - .timepointDate - display: none - .expandIcon i - transform: rotateX(180deg) - .timepointFollowupTitle - font-size: 14px - theme('color', '$textSecondaryColor') - text-transform: uppercase - - .timepointHeader - cursor: pointer - font-size: 13px - - & - .expandIcon i - .timepointFollowupTitle - .timepointDate - .timepointModalities - theme('color', '$textSecondaryColor') - transition($sidebarTransition) - - &:hover - & - .timepointFollowupTitle - .expandIcon i - .timepointDate - .timepointModalities - theme('color', '$textPrimaryColor') !important - - .timepointDetails - .timepointModalities - line-height: 25px - - .timepointModalities - height: 25px - overflow: hidden - - .expandIcon i - theme('color', '$defaultColor') - - .timepointFollowupTitle - theme('color', '$textPrimaryColor') - padding-top: 2px - .studyTimepointScrollArea height: 100% overflow-x: hidden