Updates for Timepoint assocation (LT-60) and Conformance Checks (LT-92, LT-93, LT-94)
This commit is contained in:
1 parent
6c4eae3699
commit
beaa56c0b3
144 files changed
+5050
-2416
No files matched your search
@@ -1,13 +0,0 @@
|
||||
/**
|
||||
*
|
||||
* @returns {string}
|
||||
*/
|
||||
generateUUID = function() {
|
||||
var d = new Date().getTime();
|
||||
var uuid = 'xxxxxxxx'.replace(/[xy]/g, function(c) {
|
||||
var r =(d + Math.random()*8)%8 | 0;
|
||||
d = Math.floor(d/8);
|
||||
return(c=='x' ? r :(r&0x3|0x8)).toString(8);
|
||||
});
|
||||
return uuid;
|
||||
};
|
||||
@@ -0,0 +1,62 @@
|
||||
/**
|
||||
* Retrieves metaData for multiple studies at once.
|
||||
*
|
||||
* This function calls getStudyMetadata several times, asynchronously,
|
||||
* and waits for all of the results to be returned.
|
||||
*
|
||||
* @param studyInstanceUids The UIDs of the Studies to be retrieved
|
||||
* @param doneCallback The callback function to be executed when the study retrieval has finished
|
||||
* @param failCallback The callback function to be executed when the study retrieval has failed
|
||||
*/
|
||||
getStudiesMetadata = function(studyInstanceUids, doneCallback, failCallback) {
|
||||
// Check to make sure studyInstanceUids were actually input
|
||||
if (!studyInstanceUids || !studyInstanceUids.length) {
|
||||
if (failCallback && typeof failCallback === 'function') {
|
||||
failCallback('No studyInstanceUids were input');
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// Create an empty array to store the Promises for each metaData
|
||||
// retrieval call
|
||||
var promises = [];
|
||||
|
||||
// Create an empty array to hold all the results of the promises
|
||||
var studies = [];
|
||||
|
||||
|
||||
// Loop through the array of studyInstanceUids
|
||||
studyInstanceUids.forEach(function(studyInstanceUid) {
|
||||
// Create a new Deferred to monitor the progress of the asynchronous
|
||||
// metaData retrieval
|
||||
var deferred = new $.Deferred();
|
||||
|
||||
// Send the call, and attach doneCallbacks and failCallbacks
|
||||
// which can resolve or reject the related promise based on its outcome
|
||||
getStudyMetadata(studyInstanceUid, function(study) {
|
||||
deferred.resolve(study);
|
||||
}, function(error) {
|
||||
deferred.reject(error);
|
||||
});
|
||||
|
||||
// Add the current promise to the array of promises
|
||||
promises.push(deferred.promise());
|
||||
});
|
||||
|
||||
// When all of the promises are complete, this callback runs
|
||||
$.when.apply($, promises).done(function() {
|
||||
// Convert the Arguments Array-like Object to an actual array
|
||||
var studies = $.makeArray(arguments);
|
||||
|
||||
// Pass the studies array to the doneCallback, if one exists
|
||||
if (doneCallback && typeof doneCallback === 'function') {
|
||||
doneCallback(studies);
|
||||
}
|
||||
}).fail(function(error) {
|
||||
log.warn(error);
|
||||
if (failCallback && typeof failCallback === 'function') {
|
||||
failCallback(error);
|
||||
}
|
||||
});
|
||||
};
|
||||
@@ -0,0 +1,45 @@
|
||||
// Define the StudyMetaData object. This is used as a cache
|
||||
// to store study meta data information to prevent unnecessary
|
||||
// calls to the server
|
||||
var StudyMetaData = {};
|
||||
|
||||
/**
|
||||
* Retrieves study metadata using a server call, and fires a callback
|
||||
* when completed.
|
||||
*
|
||||
* @params {string} studyInstanceUid The UID of the Study to be retrieved
|
||||
* @params {function} doneCallback The callback function to be executed when the study retrieval has finished
|
||||
* @param failCallback The callback function to be executed when the study retrieval has failed
|
||||
*/
|
||||
getStudyMetadata = function(studyInstanceUid, doneCallback, failCallback) {
|
||||
log.info('worklistStudy getStudyMetadata');
|
||||
|
||||
// If the StudyMetaData cache already has data related to this
|
||||
// studyInstanceUid, then we should fire the doneCallback with this data
|
||||
// and stop here.
|
||||
var study = StudyMetaData[studyInstanceUid];
|
||||
if (study) {
|
||||
doneCallback(study);
|
||||
return;
|
||||
}
|
||||
|
||||
// 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) {
|
||||
if (error) {
|
||||
log.warn(error);
|
||||
failCallback(error);
|
||||
return;
|
||||
}
|
||||
|
||||
// Once we have retrieved the data, we sort the series' by series
|
||||
// and instance number in ascending order
|
||||
sortStudy(study);
|
||||
|
||||
// Then we store this data in the cache variable
|
||||
StudyMetaData[studyInstanceUid] = study;
|
||||
|
||||
// Finally, we fire the doneCallback with this study meta data
|
||||
doneCallback(study);
|
||||
});
|
||||
};
|
||||
@@ -0,0 +1,30 @@
|
||||
/**
|
||||
* Opens a new tab in the tabbed worklist environment using
|
||||
* a given study and new tab title.
|
||||
*
|
||||
* @param studyInstanceUid The UID of the Study to be opened
|
||||
* @param title The title to be used for the tab heading
|
||||
*/
|
||||
openNewTab = function(studyInstanceUid, title) {
|
||||
// Generate a unique ID to represent this tab
|
||||
// We can't just use the Mongo entry ID because
|
||||
// then it will change after hot-reloading.
|
||||
var contentid = uuid.new();
|
||||
|
||||
// Create a new entry in the WorklistTabs Collection
|
||||
WorklistTabs.insert({
|
||||
title: title,
|
||||
contentid: contentid,
|
||||
active: false
|
||||
});
|
||||
|
||||
// Update the ViewerData global object
|
||||
ViewerData[contentid] = {
|
||||
title: title,
|
||||
contentid: contentid,
|
||||
studyInstanceUids: [studyInstanceUid]
|
||||
};
|
||||
|
||||
// Switch to the new tab
|
||||
switchToTab(contentid);
|
||||
};
|
||||
@@ -0,0 +1,90 @@
|
||||
/**
|
||||
* Switches to a new tab in the tabbed worklist container
|
||||
* This function renders either the Worklist or the Viewer template with new data.
|
||||
*
|
||||
* @param contentId The unique ID of the tab to be switched to
|
||||
*/
|
||||
switchToTab = function(contentId) {
|
||||
if (!contentId) {
|
||||
return;
|
||||
}
|
||||
log.info('Switching to tab: ' + contentId);
|
||||
|
||||
// Use Bootstrap's Tab JavaScript to show the contents of the current tab
|
||||
// Unless it is the worklist, it is currently an empty div
|
||||
$('.tabTitle a[data-target="#' + contentId + '"]').tab('show');
|
||||
|
||||
// Remove any previous Viewers from the DOM
|
||||
$('#viewer').remove();
|
||||
|
||||
// Update the 'activeContentId' variable in Session
|
||||
Session.set('activeContentId', contentId);
|
||||
|
||||
// If we are switching to the Worklist tab, reset any CSS styles
|
||||
// that have been applied to prevent scrolling in the Viewer.
|
||||
// Then stop here, since nothing needs to be re-rendered.
|
||||
if (contentId === 'worklistTab') {
|
||||
document.body.style.overflow = null;
|
||||
document.body.style.height = null;
|
||||
document.body.style.minWidth = null;
|
||||
document.body.style.position = null;
|
||||
return;
|
||||
}
|
||||
|
||||
// Tab was closed at some point, stop here
|
||||
if (!ViewerData[contentId]) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Use the stored ViewerData global object to retrieve the studyInstanceUid
|
||||
// related to this tab
|
||||
var studyInstanceUids = ViewerData[contentId].studyInstanceUids;
|
||||
|
||||
// Attempt to retrieve the meta data (it might be cached)
|
||||
getStudiesMetadata(studyInstanceUids, function(studies) {
|
||||
// Tab closed while study data was being retrieved, stop here
|
||||
if (!ViewerData[contentId]) {
|
||||
log.warn('Tab closed while study data was being retrieved');
|
||||
return;
|
||||
}
|
||||
|
||||
// Once we have the study data, store it in a structure with
|
||||
// any other saved data about this tab (e.g. layout structure)
|
||||
var data = jQuery.extend({}, ViewerData[contentId]);
|
||||
data.studies = studies;
|
||||
data.contentId = contentId;
|
||||
|
||||
if (ViewerData[contentId].studies && ViewerData[contentId].studies.length) {
|
||||
data.studies = ViewerData[contentId].studies;
|
||||
}
|
||||
|
||||
// Get tab content container given the contentId string
|
||||
// If no such container exists, stop here because something is wrong
|
||||
var container = $('.tab-content').find('#' + contentId).get(0);
|
||||
if (!container) {
|
||||
log.warn('No container present with the contentId: ' + contentId);
|
||||
return;
|
||||
}
|
||||
|
||||
// Remove the loading text template that is inside the tab container by default
|
||||
container.innerHTML = '';
|
||||
|
||||
// Use Blaze to render the Viewer Template into the container
|
||||
UI.renderWithData(Template.viewer, data, container);
|
||||
|
||||
// Retrieve the DOM element of the viewer
|
||||
var imageViewer = $('#viewer');
|
||||
|
||||
// If it is present in the DOM (it should be), then apply
|
||||
// styles to prevent page scrolling and overscrolling on mobile devices
|
||||
if (imageViewer) {
|
||||
document.body.style.overflow = 'hidden';
|
||||
document.body.style.height = '100%';
|
||||
document.body.style.width = '100%';
|
||||
document.body.style.minWidth = 0;
|
||||
|
||||
// Prevent overscroll on mobile devices
|
||||
document.body.style.position = 'fixed';
|
||||
}
|
||||
});
|
||||
};
|
||||
@@ -0,0 +1,13 @@
|
||||
Worklist = {
|
||||
functions: {},
|
||||
callbacks: {}
|
||||
};
|
||||
|
||||
Worklist.callbacks.dblClickOnStudy = dblClickOnStudy;
|
||||
Worklist.callbacks.middleClickOnStudy = dblClickOnStudy;
|
||||
|
||||
function dblClickOnStudy(data) {
|
||||
// Use the formatPN template helper to clean up the patient name
|
||||
var title = formatPN(data.patientName);
|
||||
openNewTab(data.studyInstanceUid, title);
|
||||
}
|
||||
Reference in new issue
Block a user