Using the new time point browser on the sidebar

This commit is contained in:
Bruno Alves de Faria 2017-10-12 16:49:50 -03:00
parent fd9cfed8e9
commit d721c0dbde
13 changed files with 164 additions and 72 deletions

View File

@ -2,8 +2,8 @@
<div class="viewerSection">
<div class="sidebarMenu sidebar-left {{#if leftSidebarOpen}}sidebar-open{{/if}}">
{{>timepointBrowserList (extend timepointBrowserData scrollableClass='p-a-1')}}
<hr>
{{>studyTimepointBrowser (clone this)}}
<!-- <hr>
{{>studyTimepointBrowser (clone this)}} -->
</div>
<div class="mainContent {{#if leftSidebarOpen}}sidebar-left-open{{/if}} {{#if rightSidebarOpen}}sidebar-right-open{{/if}}">
{{>viewerMain (clone this)}}

View File

@ -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');
}
};
}
});

View File

@ -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';

View File

@ -1,6 +1,6 @@
<template name="timepointBrowserItem">
<div class="timepointEntry p-y-2">
<div class="timepointHeader">
<div class="timepoint-browser-item">
<div class="timepointEntry p-y-2">
<div class="timepointDetails clearfix">
<div class="timepointFollowupTitle pull-left">
{{this.timepointApi.title timepoint}}
@ -10,7 +10,12 @@
</div>
<div class="timepointDate pull-right m-r-1">{{formatDA this.timepoint.earliestDate 'D-MMM-YYYY'}}</div>
</div>
<!-- <div class="timepointModalities">{{modalitiesSummary timepoint}}</div> -->
<div class="timepointModalities">{{choose instance.summary.get 'Click to load'}}</div>
</div>
{{#if this.timepointChildTemplate}}
{{#if and (not instance.loading.get) instance.loaded}}
{{>Template.dynamic template=this.timepointChildTemplate data=(clone this studiesInformation=timepoint.studiesData)}}
{{/if}}
{{/if}}
</div>
</template>

View File

@ -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');
}
}
});

View File

@ -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

View File

@ -1,7 +1,7 @@
<template name="timepointBrowserList">
{{#scrollArea class=(concat 'full-height ' this.class) scrollableClass=this.scrollableClass}}
<div class="timepoint-browser-list {{this.class}}">
{{#each timepoint in this.timepoints}}
{{>timepointBrowserItem (clone this timepoint=timepoint)}}
{{/each}}
{{/scrollArea}}
</div>
</template>

View File

@ -0,0 +1,5 @@
<template name="timepointBrowserStudies">
<div class="timepoint-browser-studies">
{{>studyBrowserList this}}
</div>
</template>

View File

@ -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);
}
});

View File

@ -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
}
});

View File

@ -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) {

View File

@ -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}`);

View File

@ -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