182 lines
6.7 KiB
JavaScript
182 lines
6.7 KiB
JavaScript
import { Meteor } from 'meteor/meteor';
|
|
import { Template } from 'meteor/templating';
|
|
import { ReactiveVar } from 'meteor/reactive-var';
|
|
import { _ } from 'meteor/underscore';
|
|
import { $ } from 'meteor/jquery';
|
|
import { OHIF } from 'meteor/ohif:core';
|
|
|
|
Template.studyTimepointStudy.onCreated(() => {
|
|
const instance = Template.instance();
|
|
|
|
instance.loading = new ReactiveVar(false);
|
|
|
|
const studyMetadata = OHIF.viewerbase.getStudyMetadata(instance.data.study);
|
|
const firstInstance = studyMetadata.getFirstInstance();
|
|
if (firstInstance) {
|
|
instance.modalities = firstInstance.getRawValue('x00080060');
|
|
instance.studyDescription = firstInstance.getRawValue('x00081030');
|
|
instance.studyDate = firstInstance.getRawValue('x00080020');
|
|
}
|
|
|
|
// Get the current study element
|
|
instance.getStudyElement = (isGlobal=false) => {
|
|
const studyInstanceUid = instance.data.study.studyInstanceUid;
|
|
const selector = `.study-browser-item[data-uid='${studyInstanceUid}']`;
|
|
return isGlobal ? $(selector) : instance.$browser.find(selector);
|
|
};
|
|
|
|
instance.isQuickSwitch = () => {
|
|
return !_.isUndefined(instance.data.viewportIndex);
|
|
};
|
|
|
|
// Set the current study as selected in the studies list
|
|
instance.select = (isQuickSwitch=false) => {
|
|
const studyInstanceUid = instance.data.study.studyInstanceUid;
|
|
|
|
const $study = instance.getStudyElement();
|
|
const $timepoint = $study.closest('.studyTimepoint');
|
|
|
|
const selectionChanged = {
|
|
selection: [$study[0]],
|
|
studyInstanceUid,
|
|
isQuickSwitch
|
|
};
|
|
|
|
$timepoint.trigger('selectionChanged', selectionChanged);
|
|
};
|
|
|
|
instance.initializeStudyWrapper = () => {
|
|
// Stop here if it's a quick switch
|
|
if (instance.isQuickSwitch()) {
|
|
return;
|
|
}
|
|
|
|
const $study = instance.getStudyElement();
|
|
const $thumbnails = $study.find('.study-browser-series');
|
|
$study.addClass('active');
|
|
// If element already has max-height property set, .height()
|
|
// will return that value, so remove it to recalculate
|
|
$thumbnails.css('max-height', '');
|
|
$thumbnails.css('max-height', $thumbnails.height());
|
|
$study.removeClass('active');
|
|
|
|
// Here we add, remove, and add the active class again because this way
|
|
// the max-height animation appears smooth to the user.
|
|
if (instance.data.active) {
|
|
Meteor.setTimeout(() => $study.addClass('active'), 1);
|
|
}
|
|
};
|
|
});
|
|
|
|
// Initialize the study wrapper max-height to enable CSS transition
|
|
Template.studyTimepointStudy.onRendered(() => {
|
|
const instance = Template.instance();
|
|
|
|
// Keep the study timepoint browser element to manipulate elements even after DOM is removed
|
|
instance.$browser = instance.$('.study-browser-item').closest('.studyTimepointBrowser');
|
|
|
|
instance.initializeStudyWrapper();
|
|
});
|
|
|
|
Template.studyTimepointStudy.events({
|
|
// Recalculates the timepoint height to make CSS transition smoother
|
|
'transitionend .study-browser-series'(event, instance) {
|
|
if (event.target === event.currentTarget) {
|
|
$(event.currentTarget).closest('.studyTimepoint').trigger('displayStateChanged');
|
|
}
|
|
},
|
|
|
|
// Transfers the active state to the current study
|
|
'click .studyQuickSwitchTimepoint .study-item-container'(event, instance) {
|
|
instance.select(true);
|
|
},
|
|
|
|
// Set loading state
|
|
'loadStarted .study-browser-item'(event, instance) {
|
|
instance.loading.set(true);
|
|
},
|
|
|
|
// Remove loading state and fix the thumbnails wrappers height
|
|
'loadEnded .study-browser-item'(event, instance) {
|
|
instance.loading.set(false);
|
|
instance.initializeStudyWrapper();
|
|
},
|
|
|
|
// Changes the current study selection for the clicked study
|
|
'click .study-item-box'(event, instance) {
|
|
const studyData = instance.data.study;
|
|
const { studyInstanceUid } = studyData;
|
|
const isQuickSwitch = instance.isQuickSwitch();
|
|
|
|
// @TypeSafeStudies
|
|
// Check if the study already has series data,
|
|
// and if not, retrieve it.
|
|
if (!studyData.seriesList) {
|
|
const alreadyLoaded = OHIF.viewer.Studies.findBy({ studyInstanceUid });
|
|
|
|
if (!alreadyLoaded) {
|
|
const $studies = instance.getStudyElement(true);
|
|
$studies.trigger('loadStarted');
|
|
OHIF.studies.retrieveStudyMetadata(studyInstanceUid).then(study => {
|
|
instance.data.study = study;
|
|
OHIF.viewer.Studies.insert(study);
|
|
|
|
Meteor.setTimeout(() => {
|
|
$studies.trigger('loadEnded');
|
|
instance.select(isQuickSwitch);
|
|
}, 1);
|
|
}).catch(error => {
|
|
OHIF.log.error(`There was an error trying to retrieve the study\'s metadata for studyInstanceUid: ${studyInstanceUid}`);
|
|
OHIF.log.error(error.stack);
|
|
|
|
OHIF.log.trace();
|
|
});
|
|
} else {
|
|
studyData.seriesList = alreadyLoaded.seriesList;
|
|
instance.select(isQuickSwitch);
|
|
}
|
|
} else {
|
|
instance.select(isQuickSwitch);
|
|
}
|
|
}
|
|
});
|
|
|
|
Template.studyTimepointStudy.helpers({
|
|
isLoading() {
|
|
// @TypeSafeStudies
|
|
const instance = Template.instance();
|
|
const studyData = instance.data.study;
|
|
const alreadyLoaded = OHIF.viewer.Studies.findBy({ studyInstanceUid: studyData.studyInstanceUid });
|
|
return instance.loading.get() && !alreadyLoaded;
|
|
},
|
|
|
|
modalities() {
|
|
const instance = Template.instance();
|
|
const modalities = instance.modalities || 'UN';
|
|
|
|
// Replace backslashes with spaces
|
|
return modalities.replace(/\\/g, ' ');
|
|
},
|
|
|
|
modalityStyle() {
|
|
// Responsively styles the Modality Acronyms for studies
|
|
// with more than one modality
|
|
const instance = Template.instance();
|
|
const modalities = instance.modalities || 'UN';
|
|
const numModalities = modalities.split(/\\/g).length;
|
|
|
|
if (numModalities === 1) {
|
|
// If we have only one modality, it should take up the whole div.
|
|
return 'font-size: 1em';
|
|
} else if (numModalities === 2) {
|
|
// If we have two, let them sit side-by-side
|
|
return 'font-size: 0.75em';
|
|
} else {
|
|
// If we have more than two modalities, change the line height to display multiple rows,
|
|
// depending on the number of modalities we need to display.
|
|
const lineHeight = Math.ceil(numModalities / 2) * 1.2;
|
|
return 'line-height: ' + lineHeight + 'em';
|
|
}
|
|
}
|
|
});
|