Creating ohif-studies package to deal with studies browsing
This commit is contained in:
parent
956e6da0b3
commit
0b51a53976
@ -87,6 +87,7 @@
|
||||
"wsh" : false, // Windows Scripting Host
|
||||
"yui" : false, // Yahoo User Interface
|
||||
"globals" : {
|
||||
"require": true,
|
||||
"Package" : true, // Meteor Package definition
|
||||
|
||||
"cornerstone": true, // This group: cornerstone globals
|
||||
|
||||
@ -6,7 +6,7 @@ html body
|
||||
|
||||
html body.stretch
|
||||
height: 100%
|
||||
minWidth: 0
|
||||
min-width: 0
|
||||
overflow: hidden
|
||||
position: fixed
|
||||
width: 100%
|
||||
|
||||
@ -7,3 +7,22 @@ const defaultLevel = Meteor.isProduction ? 'ERROR' : 'TRACE';
|
||||
// Create package logger using loglevel
|
||||
OHIF.log = loglevel.getLogger('OHIF');
|
||||
OHIF.log.setLevel(defaultLevel);
|
||||
|
||||
// Add time and timeEnd to OHIF.log namespace
|
||||
const times = new Map();
|
||||
|
||||
// Register the time method
|
||||
OHIF.log.time = givenKey => {
|
||||
const key = typeof givenKey === 'undefined' ? 'default' : givenKey;
|
||||
times.set(key, new Date().getTime());
|
||||
};
|
||||
|
||||
// Register the timeEnd method
|
||||
OHIF.log.timeEnd = givenKey => {
|
||||
const key = typeof givenKey === 'undefined' ? 'default' : givenKey;
|
||||
const now = new Date().getTime();
|
||||
const last = times.get(key) || now;
|
||||
times.delete(key);
|
||||
const duration = now - last;
|
||||
OHIF.log.info(`${key}: ${duration}ms`);
|
||||
};
|
||||
|
||||
5
Packages/ohif-studies/both/main.js
Normal file
5
Packages/ohif-studies/both/main.js
Normal file
@ -0,0 +1,5 @@
|
||||
import { OHIF } from 'meteor/ohif:core';
|
||||
|
||||
OHIF.studies = {};
|
||||
|
||||
require('../imports/both');
|
||||
1
Packages/ohif-studies/client/main.js
Normal file
1
Packages/ohif-studies/client/main.js
Normal file
@ -0,0 +1 @@
|
||||
require('../imports/client');
|
||||
0
Packages/ohif-studies/imports/both/index.js
Normal file
0
Packages/ohif-studies/imports/both/index.js
Normal file
@ -0,0 +1,5 @@
|
||||
import './list.html';
|
||||
import './list.js';
|
||||
import './item.html';
|
||||
import './item.js';
|
||||
import './item.styl';
|
||||
@ -0,0 +1,21 @@
|
||||
<template name="studyBrowserItem">
|
||||
<div class="study-browser-item {{this.settings.studyItemClass}} {{#if isActive}}active{{/if}} {{#if isLoading}}loading{{/if}}" data-uid="{{this.studyInformation.studyInstanceUid}}">
|
||||
<div class="study-item">
|
||||
{{#if isLoading}}
|
||||
{{>loadingText}}
|
||||
{{/if}}
|
||||
<div class="study-item-box">
|
||||
<div class="study-modality">
|
||||
<div class="study-modality-text" style="{{modalityStyle}}">{{instance.modalities}}</div>
|
||||
</div>
|
||||
<div class="study-text">
|
||||
<div class="study-date">{{formatDA this.studyInformation.date 'D-MMM-YYYY'}}</div>
|
||||
<div class="study-description">{{this.studyInformation.description}}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{{#if this.settings.studyTemplate}}
|
||||
{{>Template.dynamic template=this.settings.studyTemplate data=(clone this)}}
|
||||
{{/if}}
|
||||
</div>
|
||||
</template>
|
||||
@ -0,0 +1,43 @@
|
||||
import { Template } from 'meteor/templating';
|
||||
import { $ } from 'meteor/jquery';
|
||||
|
||||
Template.studyBrowserItem.onCreated(() => {
|
||||
const instance = Template.instance();
|
||||
|
||||
const modality = instance.data.studyInformation.modality || 'UN';
|
||||
instance.modalities = modality.replace(/\\/g, ' ');
|
||||
});
|
||||
|
||||
Template.studyBrowserItem.events({
|
||||
'click .study-browser-item'(event, instance) {
|
||||
const element = event.currentTarget;
|
||||
const $element = $(element);
|
||||
$element.trigger('ohif.studies.study.click', instance.data.studyInformation);
|
||||
const { settings, studyInformation } = instance.data;
|
||||
if (settings && typeof settings.studyClickCallback) {
|
||||
settings.studyClickCallback(studyInformation, element);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
Template.studyBrowserItem.helpers({
|
||||
modalityStyle() {
|
||||
// Responsively styles the Modality Acronyms for studies
|
||||
// with more than one modality
|
||||
const instance = Template.instance();
|
||||
const numModalities = instance.modalities.split(/\s/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';
|
||||
}
|
||||
}
|
||||
});
|
||||
@ -1,4 +1,4 @@
|
||||
@import "{ohif:design}/app"
|
||||
@require '{ohif:design}/app'
|
||||
|
||||
$boxBorderColor = transparent
|
||||
$boxHoverBackgroundColor = #14191E
|
||||
@ -11,7 +11,7 @@ $nestingMargin = 6px
|
||||
$spacerX = 7px
|
||||
$spacerY = 12px
|
||||
|
||||
.studyTimepointStudy
|
||||
.study-browser-item
|
||||
position: relative
|
||||
// required transformation to make inner fixed elements relative to this one
|
||||
transform(scale(1))
|
||||
@ -33,12 +33,12 @@ $spacerY = 12px
|
||||
opacity: 0.75
|
||||
right: 16px
|
||||
|
||||
.studyModality
|
||||
.study-item-box
|
||||
opacity: 0.2
|
||||
|
||||
&.active
|
||||
.studyModality
|
||||
.studyModalityBox
|
||||
.study-item-box
|
||||
.study-modality
|
||||
theme('color', '$primaryBackgroundColor')
|
||||
&
|
||||
&:before
|
||||
@ -53,7 +53,7 @@ $spacerY = 12px
|
||||
overflow: hidden
|
||||
transition($sidebarTransition)
|
||||
|
||||
.studyModality
|
||||
.study-item-box
|
||||
border: 1px solid $boxBorderColor
|
||||
border-radius: 12px
|
||||
cursor: pointer
|
||||
@ -78,28 +78,29 @@ $spacerY = 12px
|
||||
padding: 0
|
||||
text-align: center
|
||||
|
||||
.studyText
|
||||
.study-text
|
||||
font-size: 13px
|
||||
left: ($spacerX * 3) + $boxWidth + ($nestingMargin * 3)
|
||||
line-height: 14px
|
||||
position: absolute
|
||||
right: $spacerX
|
||||
top: $spacerY
|
||||
.studyDate
|
||||
.study-date
|
||||
margin-top: 8px
|
||||
theme('color', '$textSecondaryColor')
|
||||
.studyDescription
|
||||
.study-description
|
||||
margin-top: 8px
|
||||
theme('color', '$textPrimaryColor')
|
||||
|
||||
.studyModalityBox
|
||||
.study-modality
|
||||
theme('color', '$textSecondaryColor')
|
||||
font-size: 20px
|
||||
line-height: $boxWidth
|
||||
margin-left: $nestingMargin * 2
|
||||
margin-top: $nestingMargin * 2
|
||||
position: relative
|
||||
|
||||
.studyModalityText
|
||||
.study-modality-text
|
||||
text-align: center
|
||||
text-transform: uppercase
|
||||
height: 100%
|
||||
@ -0,0 +1,7 @@
|
||||
<template name="studyBrowserList">
|
||||
<div class="study-browser-list {{this.settings.studyListClass}}">
|
||||
{{#each studyInformation in studiesInformation}}
|
||||
{{>studyBrowserItem (clone this studyInformation=studyInformation)}}
|
||||
{{/each}}
|
||||
</div>
|
||||
</template>
|
||||
1
Packages/ohif-studies/imports/client/components/index.js
Normal file
1
Packages/ohif-studies/imports/client/components/index.js
Normal file
@ -0,0 +1 @@
|
||||
import './browser';
|
||||
2
Packages/ohif-studies/imports/client/index.js
Normal file
2
Packages/ohif-studies/imports/client/index.js
Normal file
@ -0,0 +1,2 @@
|
||||
import './components';
|
||||
import './lib';
|
||||
0
Packages/ohif-studies/imports/client/lib/index.js
Normal file
0
Packages/ohif-studies/imports/client/lib/index.js
Normal file
@ -0,0 +1,102 @@
|
||||
import { Meteor } from 'meteor/meteor';
|
||||
import { OHIF } from 'meteor/ohif:core';
|
||||
import 'meteor/ohif:viewerbase';
|
||||
|
||||
// Define the StudyMetaDataPromises object. This is used as a cache to store study meta data
|
||||
// promises and prevent unnecessary subsequent calls to the server
|
||||
const StudyMetaDataPromises = new Map();
|
||||
|
||||
/**
|
||||
* Retrieves study metadata using a server call
|
||||
*
|
||||
* @param {String} studyInstanceUid The UID of the Study to be retrieved
|
||||
* @returns {Promise} that will be resolved with the metadata or rejected with the error
|
||||
*/
|
||||
OHIF.studies.retrieveStudyMetadata = (studyInstanceUid, seriesInstanceUids) => {
|
||||
|
||||
// @TODO: Whenever a study metadata request has failed, its related promise will be rejected once and for all
|
||||
// and further requests for that metadata will always fail. On failure, we probably need to remove the
|
||||
// corresponding promise from the "StudyMetaDataPromises" map...
|
||||
|
||||
// If the StudyMetaDataPromises cache already has a pending or resolved promise related to the
|
||||
// given studyInstanceUid, then that promise is returned
|
||||
if (StudyMetaDataPromises.has(studyInstanceUid)) {
|
||||
return StudyMetaDataPromises.get(studyInstanceUid);
|
||||
}
|
||||
|
||||
const seriesKeys = Array.isArray(seriesInstanceUids) ? '|' + seriesInstanceUids.join('|') : '';
|
||||
const timingKey = `retrieveStudyMetadata[${studyInstanceUid}${seriesKeys}]`;
|
||||
OHIF.log.time(timingKey);
|
||||
|
||||
// Create a promise to handle the data retrieval
|
||||
const promise = new Promise((resolve, reject) => {
|
||||
// If no study metadata is in the cache variable, we need to retrieve it from
|
||||
// the server with a call.
|
||||
Meteor.call('GetStudyMetadata', studyInstanceUid, function(error, study) {
|
||||
OHIF.log.timeEnd(timingKey);
|
||||
|
||||
if (error) {
|
||||
const errorType = error.error;
|
||||
let errorMessage = '';
|
||||
|
||||
if (errorType === 'server-connection-error') {
|
||||
errorMessage = 'There was an error connecting to the DICOM server, please verify if it is up and running.';
|
||||
} else if (errorType === 'server-internal-error') {
|
||||
errorMessage = `There was an internal error with the DICOM server getting metadeta for ${studyInstanceUid}`;
|
||||
} else {
|
||||
errorMessage = `For some reason we could not retrieve the study\'s metadata for ${studyInstanceUid}.`;
|
||||
}
|
||||
|
||||
OHIF.log.error(errorMessage);
|
||||
OHIF.log.error(error.stack);
|
||||
reject(`GetStudyMetadata: ${errorMessage}`);
|
||||
return;
|
||||
}
|
||||
|
||||
// Filter series if seriesInstanceUid exists
|
||||
if (seriesInstanceUids && seriesInstanceUids.length) {
|
||||
study.seriesList = study.seriesList.filter(series => seriesInstanceUids.indexOf(series.seriesInstanceUid) > -1);
|
||||
}
|
||||
|
||||
if (!study) {
|
||||
reject(`GetStudyMetadata: No study data returned from server: ${studyInstanceUid}`);
|
||||
return;
|
||||
}
|
||||
|
||||
if (window.HipaaLogger && Meteor.user && Meteor.user()) {
|
||||
window.HipaaLogger.logEvent({
|
||||
eventType: 'viewed',
|
||||
userId: Meteor.userId(),
|
||||
userName: Meteor.user().profile.fullName,
|
||||
collectionName: 'Study',
|
||||
recordId: studyInstanceUid,
|
||||
patientId: study.patientId,
|
||||
patientName: study.patientName
|
||||
});
|
||||
}
|
||||
|
||||
// Once the data was retrieved, the series are sorted by series and instance number
|
||||
OHIF.viewerbase.sortStudy(study);
|
||||
|
||||
// Updates WADO-RS metaDataManager
|
||||
OHIF.viewerbase.updateMetaDataManager(study);
|
||||
|
||||
// Transform the study in a StudyMetadata object
|
||||
const studyMetadata = new OHIF.metadata.StudyMetadata(study);
|
||||
|
||||
// Add the display sets to the study
|
||||
study.displaySets = OHIF.viewerbase.sortingManager.getDisplaySets(studyMetadata);
|
||||
study.displaySets.forEach(displaySet => {
|
||||
OHIF.viewerbase.stackManager.makeAndAddStack(study, displaySet);
|
||||
});
|
||||
|
||||
// Resolve the promise with the final study metadata object
|
||||
resolve(study);
|
||||
});
|
||||
});
|
||||
|
||||
// Store the promise in cache
|
||||
StudyMetaDataPromises.set(studyInstanceUid, promise);
|
||||
|
||||
return promise;
|
||||
};
|
||||
0
Packages/ohif-studies/imports/server/index.js
Normal file
0
Packages/ohif-studies/imports/server/index.js
Normal file
35
Packages/ohif-studies/package.js
Normal file
35
Packages/ohif-studies/package.js
Normal file
@ -0,0 +1,35 @@
|
||||
Package.describe({
|
||||
name: 'ohif:studies',
|
||||
summary: 'OHIF Studies Library to deal with studies UI, retrieval and manipulation',
|
||||
version: '0.0.1'
|
||||
});
|
||||
|
||||
Package.onUse(function(api) {
|
||||
api.versionsFrom('1.4');
|
||||
|
||||
api.use([
|
||||
'ecmascript',
|
||||
'templating',
|
||||
'stylus',
|
||||
'http'
|
||||
]);
|
||||
|
||||
// Our custom packages
|
||||
api.use([
|
||||
'ohif:design',
|
||||
'ohif:core',
|
||||
'ohif:log',
|
||||
'ohif:dicom-services',
|
||||
'ohif:viewerbase',
|
||||
'ohif:wadoproxy'
|
||||
]);
|
||||
|
||||
// Client and server imports
|
||||
api.addFiles('both/main.js', [ 'client', 'server' ]);
|
||||
|
||||
// Server imports
|
||||
api.addFiles('server/main.js', 'server');
|
||||
|
||||
// Client imports
|
||||
api.addFiles('client/main.js', 'client');
|
||||
});
|
||||
1
Packages/ohif-studies/server/main.js
Normal file
1
Packages/ohif-studies/server/main.js
Normal file
@ -0,0 +1 @@
|
||||
require('../imports/server');
|
||||
@ -53,7 +53,7 @@ Template.studySeriesQuickSwitch.onCreated(() => {
|
||||
|
||||
const checkScrollArea = element => {
|
||||
const { scrollHeight, offsetHeight, scrollTop } = element;
|
||||
|
||||
|
||||
const matrix = $(element).find('.thumbnailsWrapper').css('transform');
|
||||
|
||||
let translateY = 0;
|
||||
@ -92,7 +92,7 @@ Template.studySeriesQuickSwitch.events({
|
||||
instance.$('.js-quick-switch, .switchSectionSeries').removeClass('hover');
|
||||
instance.$('.quickSwitchWrapper').removeClass('overlay');
|
||||
},
|
||||
'click .studyTimepointStudy'(event, instance) {
|
||||
'click .study-browser-item'(event, instance) {
|
||||
instance.$('.switchSectionSeries').addClass('hover');
|
||||
},
|
||||
'scroll .scrollArea'(event) {
|
||||
|
||||
@ -105,7 +105,7 @@ $seriesSpacing = 2px
|
||||
.studySwitch
|
||||
.studyTimepointBrowser
|
||||
background-color: transparent
|
||||
.studyTimepointStudy.active .studyModality
|
||||
.study-browser-item.active .study-item-box
|
||||
theme('box-shadow', 'inset 0 0 0 3px $activeColor')
|
||||
.studyBox
|
||||
theme('background-color', '$uiGrayDark')
|
||||
@ -164,10 +164,10 @@ $seriesSpacing = 2px
|
||||
overflow-x: hidden
|
||||
overflow-y: scroll
|
||||
width: calc(100% + 22px)
|
||||
|
||||
|
||||
&.is-mac
|
||||
padding-right: 22px
|
||||
|
||||
|
||||
&.show-scroll-indicator-up:before
|
||||
&.show-scroll-indicator-down:after
|
||||
font-family: FontAwesome
|
||||
@ -180,11 +180,11 @@ $seriesSpacing = 2px
|
||||
z-index: 1
|
||||
text-align: center
|
||||
left: 0
|
||||
|
||||
|
||||
&.show-scroll-indicator-up:before
|
||||
top: -10px
|
||||
content: '\f102'
|
||||
|
||||
|
||||
&.show-scroll-indicator-down:after
|
||||
bottom: 18px
|
||||
content: '\f103'
|
||||
|
||||
@ -53,7 +53,7 @@ Template.studyTimepoint.events({
|
||||
}
|
||||
|
||||
// Removes selected state from all studies but the triggered study
|
||||
$studiesTarget.find('.studyTimepointStudy').not($selection).removeClass('active');
|
||||
$studiesTarget.find('.study-browser-item').not($selection).removeClass('active');
|
||||
|
||||
if (changed.isQuickSwitch) {
|
||||
// Reset active studies map to allow only one active study
|
||||
|
||||
@ -26,7 +26,7 @@
|
||||
<hr>
|
||||
{{/each}}
|
||||
{{#if and this.currentStudy (not showAdditionalTimepoints) hasAdditionalTimepoints}}
|
||||
<div class="studyModality additional">
|
||||
<div class="study-item-box additional">
|
||||
Show additional timepoints
|
||||
</div>
|
||||
{{/if}}
|
||||
|
||||
@ -28,22 +28,18 @@ Template.studyTimepointBrowser.onCreated(() => {
|
||||
}
|
||||
|
||||
return timepoint.studyInstanceUids.map(studyInstanceUid => {
|
||||
const query = {
|
||||
patientId: timepoint.patientId,
|
||||
studyInstanceUid: studyInstanceUid
|
||||
};
|
||||
const query = { studyInstanceUid };
|
||||
|
||||
const loadedStudy = OHIF.viewer.Studies.findBy(query);
|
||||
if (loadedStudy) {
|
||||
return loadedStudy;
|
||||
}
|
||||
if (loadedStudy) return loadedStudy;
|
||||
|
||||
const notYetLoaded = OHIF.studylist.collections.Studies.findOne(query);
|
||||
if (!notYetLoaded) {
|
||||
throw new OHIFError(`No study data available for Study: ${studyInstanceUid}`);
|
||||
}
|
||||
if (notYetLoaded) return notYetLoaded;
|
||||
|
||||
return notYetLoaded;
|
||||
// const studyData = _.findWhere(timepoint.studiesData, query);
|
||||
// if (studyData) return studyData;
|
||||
|
||||
throw new OHIFError(`No study data available for Study: ${studyInstanceUid}`);
|
||||
});
|
||||
};
|
||||
});
|
||||
@ -57,7 +53,7 @@ Template.studyTimepointBrowser.onRendered(() => {
|
||||
const type = instance.timepointViewType.get();
|
||||
|
||||
// Removes all active classes to collapse the timepoints and studies
|
||||
instance.$('.timepointEntry, .studyTimepointStudy').removeClass('active');
|
||||
instance.$('.timepointEntry, .study-browser-item').removeClass('active');
|
||||
if (type === 'key' && !instance.data.currentStudy) {
|
||||
// Show only first timepoint expanded for key timepoints
|
||||
instance.$('.timepointEntry:first').addClass('active');
|
||||
@ -71,7 +67,7 @@ Template.studyTimepointBrowser.onRendered(() => {
|
||||
// Wait for rerendering and set the timepoint as active
|
||||
instance.refreshActiveStudies = () => Tracker.afterFlush(() => {
|
||||
_.each(activeStudiesUids, studyInstanceUid => {
|
||||
instance.$(`.studyTimepointStudy[data-uid='${studyInstanceUid}']`).addClass('active');
|
||||
instance.$(`.study-browser-item[data-uid='${studyInstanceUid}']`).addClass('active');
|
||||
});
|
||||
// Show only first timepoint expanded for key timepoints
|
||||
instance.$('.timepointEntry:first').addClass('active');
|
||||
@ -108,7 +104,7 @@ Template.studyTimepointBrowser.events({
|
||||
$timepoint.toggleClass('active');
|
||||
},
|
||||
|
||||
'click .studyModality.additional'(event, instance) {
|
||||
'click .study-item-box.additional'(event, instance) {
|
||||
// Show all key timepoints
|
||||
instance.showAdditionalTimepoints.set(true);
|
||||
}
|
||||
@ -199,12 +195,22 @@ 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}`);
|
||||
|
||||
@ -1,23 +1,19 @@
|
||||
<template name="studyTimepointStudy">
|
||||
{{#let isSidebar=(isUndefined viewportIndex)}}
|
||||
<div class="studyTimepointStudy {{#if isSidebar}}studySidebarTimepoint{{else}}studyQuickSwitchTimepoint{{/if}} {{#if this.active}}active{{/if}} {{#if isLoading}}loading{{/if}}" data-uid="{{this.study.studyInstanceUid}}">
|
||||
<div class="studyItem">
|
||||
<div class="study-browser-item {{#if isSidebar}}studySidebarTimepoint{{else}}studyQuickSwitchTimepoint{{/if}} {{#if this.active}}active{{/if}} {{#if isLoading}}loading{{/if}}" data-uid="{{this.study.studyInstanceUid}}">
|
||||
<div class="study-item">
|
||||
{{#if isLoading}}
|
||||
{{>loadingText}}
|
||||
{{/if}}
|
||||
<div class="studyModality">
|
||||
<div class="studyModalityBox">
|
||||
<div class="studyModalityText" style="{{modalityStyle}}">
|
||||
{{#if instance.modalities}}
|
||||
{{modalities}}
|
||||
{{else}}
|
||||
UN
|
||||
{{/if}}
|
||||
<div class="study-item-box">
|
||||
<div class="study-modality">
|
||||
<div class="study-modality-text" style="{{modalityStyle}}">
|
||||
{{choose instance.modalities 'UN'}}
|
||||
</div>
|
||||
</div>
|
||||
<div class="studyText">
|
||||
<div class="studyDate">{{formatDA instance.studyDate 'D-MMM-YYYY'}}</div>
|
||||
<div class="studyDescription">{{instance.studyDescription}}</div>
|
||||
<div class="study-text">
|
||||
<div class="study-date">{{formatDA instance.studyDate 'D-MMM-YYYY'}}</div>
|
||||
<div class="study-description">{{instance.studyDescription}}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@ -21,7 +21,7 @@ Template.studyTimepointStudy.onCreated(() => {
|
||||
// Get the current study element
|
||||
instance.getStudyElement = (isGlobal=false) => {
|
||||
const studyInstanceUid = instance.data.study.studyInstanceUid;
|
||||
const selector = `.studyTimepointStudy[data-uid='${studyInstanceUid}']`;
|
||||
const selector = `.study-browser-item[data-uid='${studyInstanceUid}']`;
|
||||
return isGlobal ? $(selector) : instance.$browser.find(selector);
|
||||
};
|
||||
|
||||
@ -73,7 +73,7 @@ Template.studyTimepointStudy.onRendered(() => {
|
||||
const instance = Template.instance();
|
||||
|
||||
// Keep the study timepoint browser element to manipulate elements even after DOM is removed
|
||||
instance.$browser = instance.$('.studyTimepointStudy').closest('.studyTimepointBrowser');
|
||||
instance.$browser = instance.$('.study-browser-item').closest('.studyTimepointBrowser');
|
||||
|
||||
instance.initializeStudyWrapper();
|
||||
});
|
||||
@ -87,23 +87,23 @@ Template.studyTimepointStudy.events({
|
||||
},
|
||||
|
||||
// Transfers the active state to the current study
|
||||
'click .studyQuickSwitchTimepoint .studyModality'(event, instance) {
|
||||
'click .studyQuickSwitchTimepoint .study-item-container'(event, instance) {
|
||||
instance.select(true);
|
||||
},
|
||||
|
||||
// Set loading state
|
||||
'loadStarted .studyTimepointStudy'(event, instance) {
|
||||
'loadStarted .study-browser-item'(event, instance) {
|
||||
instance.loading.set(true);
|
||||
},
|
||||
|
||||
// Remove loading state and fix the thumbnails wrappers height
|
||||
'loadEnded .studyTimepointStudy'(event, instance) {
|
||||
'loadEnded .study-browser-item'(event, instance) {
|
||||
instance.loading.set(false);
|
||||
instance.initializeStudyWrapper();
|
||||
},
|
||||
|
||||
// Changes the current study selection for the clicked study
|
||||
'click .studyModality'(event, instance) {
|
||||
'click .study-item-box'(event, instance) {
|
||||
const studyData = instance.data.study;
|
||||
const { studyInstanceUid } = studyData;
|
||||
const isQuickSwitch = instance.isQuickSwitch();
|
||||
@ -128,7 +128,7 @@ Template.studyTimepointStudy.events({
|
||||
}).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 {
|
||||
@ -167,15 +167,15 @@ Template.studyTimepointStudy.helpers({
|
||||
|
||||
if (numModalities === 1) {
|
||||
// If we have only one modality, it should take up the whole div.
|
||||
return 'font-size: 1vw';
|
||||
return 'font-size: 1em';
|
||||
} else if (numModalities === 2) {
|
||||
// If we have two, let them sit side-by-side
|
||||
return 'font-size: 0.75vw';
|
||||
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 + 'vh';
|
||||
return 'line-height: ' + lineHeight + 'em';
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
@ -17,30 +17,25 @@ export const prepareViewerData = ({ studyInstanceUids, seriesInstanceUids, timep
|
||||
// Retrieve the studies metadata
|
||||
const promise = new Promise((resolve, reject) => {
|
||||
const processData = viewerData => {
|
||||
const studies = [];
|
||||
resolve({
|
||||
studies,
|
||||
viewerData
|
||||
});
|
||||
// OHIF.studylist.retrieveStudiesMetadata(viewerData.studyInstanceUids, viewerData.seriesInstanceUids).then(studies => {
|
||||
// // Add additional metadata to our study from the studylist
|
||||
// studies.forEach(study => {
|
||||
// const studylistStudy = OHIF.studylist.collections.Studies.findOne({
|
||||
// studyInstanceUid: study.studyInstanceUid
|
||||
// });
|
||||
//
|
||||
// if (!studylistStudy) {
|
||||
// return;
|
||||
// }
|
||||
//
|
||||
// Object.assign(study, studylistStudy);
|
||||
// });
|
||||
//
|
||||
// resolve({
|
||||
// studies,
|
||||
// viewerData
|
||||
// });
|
||||
// }).catch(reject);
|
||||
OHIF.studylist.retrieveStudiesMetadata(viewerData.studyInstanceUids, viewerData.seriesInstanceUids).then(studies => {
|
||||
// Add additional metadata to our study from the studylist
|
||||
studies.forEach(study => {
|
||||
const studylistStudy = OHIF.studylist.collections.Studies.findOne({
|
||||
studyInstanceUid: study.studyInstanceUid
|
||||
});
|
||||
|
||||
if (!studylistStudy) {
|
||||
return;
|
||||
}
|
||||
|
||||
Object.assign(study, studylistStudy);
|
||||
});
|
||||
|
||||
resolve({
|
||||
studies,
|
||||
viewerData
|
||||
});
|
||||
}).catch(reject);
|
||||
};
|
||||
|
||||
// Check if the studies are already given and ignore the timepoint ID if so
|
||||
|
||||
@ -192,7 +192,6 @@ Package.onUse(function(api) {
|
||||
api.addFiles('client/components/viewer/studyTimepointBrowser/studyTimepointBrowser.js', 'client');
|
||||
|
||||
api.addFiles('client/components/viewer/studyTimepointBrowser/studyTimepointStudy.html', 'client');
|
||||
api.addFiles('client/components/viewer/studyTimepointBrowser/studyTimepointStudy.styl', 'client');
|
||||
api.addFiles('client/components/viewer/studyTimepointBrowser/studyTimepointStudy.js', 'client');
|
||||
|
||||
api.addFiles('client/components/viewer/windowLevelPresets/form.html', 'client');
|
||||
|
||||
Loading…
Reference in New Issue
Block a user