Merge branch 'isReviewing'
This commit is contained in:
commit
546d579c7a
@ -238,6 +238,11 @@ Template.viewer.onCreated(function() {
|
||||
// Clear the toolData for this timepoint
|
||||
var imageId = data.timepoints[timepointId].imageId;
|
||||
removeToolDataWithMeasurementId(imageId, toolType, measurementId);
|
||||
|
||||
// Set reviewer for this timepoint
|
||||
if (data.timepoints[timepointId].studyInstanceUid) {
|
||||
Meteor.call('setReviewer',data.timepoints[timepointId].studyInstanceUid);
|
||||
}
|
||||
});
|
||||
|
||||
// Sync database data with toolData for all the measurements
|
||||
|
||||
@ -16,11 +16,11 @@ Meteor.startup(function() {
|
||||
qidoSupportsIncludeField: false,
|
||||
imageRendering: 'wadouri',
|
||||
requestOptions: {
|
||||
auth: 'orthanc:orthanc',
|
||||
logRequests: true,
|
||||
logResponses: false,
|
||||
logTiming: true
|
||||
}
|
||||
auth: 'orthanc:orthanc',
|
||||
logRequests: true,
|
||||
logResponses: false,
|
||||
logTiming: true
|
||||
}
|
||||
}]
|
||||
},
|
||||
dimse: [{
|
||||
@ -37,4 +37,15 @@ Meteor.startup(function() {
|
||||
};
|
||||
|
||||
console.log('Using default LesionTracker settings with service: ' + Meteor.settings.defaultServiceType);
|
||||
|
||||
// Bind events if window is closed
|
||||
$(window).bind('beforeunload', function (e) {
|
||||
closingWindow();
|
||||
// have to return null, unless you want a chrome popup alert
|
||||
//return 'If you leave this page then any unsaved changes will be lost.';
|
||||
});
|
||||
});
|
||||
|
||||
closingWindow = function(){
|
||||
Meteor.call('removeUserFromReviewers', Meteor.userId());
|
||||
};
|
||||
|
||||
@ -3,4 +3,5 @@ Studies = new Meteor.Collection('studies');
|
||||
Measurements = new Meteor.Collection('measurements');
|
||||
ImageMeasurements = new Meteor.Collection('imageMeasurements');
|
||||
|
||||
WorklistSubscriptions = ['studies', 'timepoints'];
|
||||
WorklistSubscriptions = ['studies', 'timepoints'];
|
||||
Reviewers = new Meteor.Collection('reviewers');
|
||||
|
||||
@ -0,0 +1 @@
|
||||
Meteor.subscribe('reviewers');
|
||||
@ -183,6 +183,14 @@ changeLesionLocationCallback = function(measurementData, eventData, doneCallback
|
||||
selected: true
|
||||
}
|
||||
});
|
||||
|
||||
// Set reviewer for this timepoint
|
||||
Object.keys(measurement.timepoints).forEach(function(key) {
|
||||
if (measurement.timepoints[key].studyInstanceUid) {
|
||||
Meteor.call('setReviewer',measurement.timepoints[key].studyInstanceUid);
|
||||
}
|
||||
});
|
||||
|
||||
};
|
||||
|
||||
var config = {
|
||||
|
||||
@ -62,7 +62,9 @@ Template.lesionTrackerLayout.onCreated(function() {
|
||||
clearInterval(handle);
|
||||
// Close the dialog
|
||||
dialog.css('display', 'none');
|
||||
|
||||
|
||||
// Remove reviewers info for the user
|
||||
Meteor.call('removeUserFromReviewers', Meteor.userId());
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
@ -1,6 +1,9 @@
|
||||
<template name="lesionTrackerWorklistStudy">
|
||||
<tr class="worklistStudy noselect">
|
||||
<td>
|
||||
{{#if reviewerTip}}
|
||||
<i class="fa fa-exclamation-circle reviewerTip" data-toggle="tooltip" data-placement="bottom" title="{{reviewerTip}}"></i>
|
||||
{{/if}}
|
||||
{{formatPN patientName}}
|
||||
</td>
|
||||
<td>
|
||||
@ -27,5 +30,6 @@
|
||||
{{numberOfStudyRelatedInstances}}
|
||||
</td>
|
||||
{{/unless}}
|
||||
|
||||
</tr>
|
||||
</template>
|
||||
@ -26,5 +26,74 @@ Template[defaultTemplate].helpers({
|
||||
}
|
||||
|
||||
return getTimepointName(timepoint);
|
||||
},
|
||||
reviewerTip: function() {
|
||||
var data = this;
|
||||
var study = Studies.findOne({
|
||||
studyInstanceUid: data.studyInstanceUid
|
||||
});
|
||||
|
||||
if (!study) {
|
||||
return;
|
||||
}
|
||||
|
||||
var timepoint = Timepoints.findOne({
|
||||
timepointId: study.timepointId
|
||||
});
|
||||
|
||||
if (!timepoint) {
|
||||
return;
|
||||
}
|
||||
|
||||
var timepointReviewers = Reviewers.findOne({timepointId: timepoint.timepointId});
|
||||
if (!timepointReviewers) {
|
||||
return;
|
||||
}
|
||||
|
||||
return getReviewerTipText(timepointReviewers.reviewers);
|
||||
}
|
||||
});
|
||||
|
||||
function getReviewerTipText(reviewers) {
|
||||
if (!reviewers || reviewers.length === 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
var newReviewers = reviewers.filter(function ( reviewer ) {
|
||||
return reviewer.userId !== Meteor.userId();
|
||||
});
|
||||
|
||||
if (newReviewers.length === 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
var tipText = 'The study is being reviewed by ';
|
||||
newReviewers.forEach(function(reviewer, index) {
|
||||
if (reviewer.userId === Meteor.userId()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (index > 0) {
|
||||
tipText += ',';
|
||||
}
|
||||
tipText += reviewer.userName;
|
||||
|
||||
});
|
||||
|
||||
return tipText;
|
||||
}
|
||||
|
||||
// Observe changes on WorklistTabs
|
||||
// remove the current user from Reviewers if tab is removed
|
||||
WorklistTabs.find().observe({
|
||||
removed: function(tab) {
|
||||
var contentId = tab.contentid;
|
||||
var timepointIds = ViewerData[contentId].timepointIds;
|
||||
if (timepointIds && timepointIds.length > 0) {
|
||||
timepointIds.forEach(function(timepointId) {
|
||||
// Remove the current user from Reviewers
|
||||
Meteor.call('removeReviewer', timepointId);
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
@ -1,2 +1,5 @@
|
||||
.worklistStudy
|
||||
cursor: pointer
|
||||
cursor: pointer
|
||||
|
||||
.reviewerTip
|
||||
color: darkred
|
||||
@ -45,6 +45,8 @@ Template.userAccountMenu.events({
|
||||
$('#serverInformationModal').modal('show');
|
||||
},
|
||||
'click #logoutButton': function() {
|
||||
// Remove reviewers info for the user
|
||||
Meteor.call('removeUserFromReviewers', Meteor.userId());
|
||||
Meteor.logout(function() {
|
||||
Router.go('/entrySignIn');
|
||||
});
|
||||
|
||||
@ -8,6 +8,14 @@ clearTools = function() {
|
||||
var seriesInstanceUids = []; // Holds seriesInstanceUid of imageViewerViewport elements
|
||||
viewportElements.each(function(index, element) {
|
||||
var enabledElement = cornerstone.getEnabledElement(element);
|
||||
var study = cornerstoneTools.metaData.get('study', enabledElement.image.imageId);
|
||||
if (!study) {
|
||||
return;
|
||||
}
|
||||
// Set reviewer for this timepoint
|
||||
if (study.studyInstanceUid) {
|
||||
Meteor.call('setReviewer',study.studyInstanceUid);
|
||||
}
|
||||
var series = cornerstoneTools.metaData.get('series', enabledElement.image.imageId);
|
||||
if (!series) {
|
||||
return;
|
||||
|
||||
@ -1,6 +1,5 @@
|
||||
handleMeasurementAdded = function(e, eventData) {
|
||||
var measurementData = eventData.measurementData;
|
||||
|
||||
switch (measurementData.toolType) {
|
||||
case 'nonTarget':
|
||||
case 'bidirectional':
|
||||
@ -10,6 +9,10 @@ handleMeasurementAdded = function(e, eventData) {
|
||||
log.info('CornerstoneToolsMeasurementAdded');
|
||||
LesionManager.updateLesionData(measurementData);
|
||||
TrialResponseCriteria.validateDelayed(measurementData);
|
||||
// Set reviewer for this timepoint
|
||||
if (measurementData.studyInstanceUid) {
|
||||
Meteor.call('setReviewer',measurementData.studyInstanceUid);
|
||||
}
|
||||
break;
|
||||
case 'ellipticalRoi':
|
||||
case 'length':
|
||||
@ -33,4 +36,5 @@ handleMeasurementAdded = function(e, eventData) {
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
@ -9,6 +9,10 @@ handleMeasurementModified = function(e, eventData) {
|
||||
log.info('CornerstoneToolsMeasurementModified');
|
||||
LesionManager.updateLesionData(measurementData);
|
||||
TrialResponseCriteria.validateDelayed(measurementData);
|
||||
// Set reviewer for this timepoint
|
||||
if (measurementData.studyInstanceUid) {
|
||||
Meteor.call('setReviewer',measurementData.studyInstanceUid);
|
||||
}
|
||||
break;
|
||||
case 'ellipticalRoi':
|
||||
case 'length':
|
||||
|
||||
@ -16,6 +16,10 @@ handleMeasurementRemoved = function(e, eventData) {
|
||||
if (!measurement) {
|
||||
return;
|
||||
}
|
||||
// Set reviewer for this timepoint
|
||||
if (measurementData.studyInstanceUid) {
|
||||
Meteor.call('setReviewer',measurementData.studyInstanceUid);
|
||||
}
|
||||
|
||||
clearMeasurementTimepointData(measurement._id, measurementData.timepointId);
|
||||
break;
|
||||
|
||||
@ -29,6 +29,8 @@ Package.onUse(function(api) {
|
||||
// Client-side collections
|
||||
api.addFiles('client/collections/LesionLocations.js', 'client');
|
||||
api.addFiles('client/collections/LocationResponses.js', 'client');
|
||||
api.addFiles('client/collections/subscriptions.js', 'client');
|
||||
|
||||
|
||||
// Additional Custom Cornerstone Tools for Lesion Tracker
|
||||
api.addFiles('client/compatibility/bidirectionalTool.js', 'client', {
|
||||
@ -158,6 +160,7 @@ Package.onUse(function(api) {
|
||||
// Server functions
|
||||
api.addFiles('server/collections.js', 'server');
|
||||
api.addFiles('server/removeCollections.js', [ 'server' ]);
|
||||
api.addFiles('server/reviewers.js', [ 'server' ]);
|
||||
|
||||
// Both client and server functions
|
||||
api.addFiles('both/collections.js', [ 'client', 'server' ]);
|
||||
@ -233,4 +236,7 @@ Package.onUse(function(api) {
|
||||
api.export('Measurements', [ 'client', 'server' ]);
|
||||
api.export('Studies', [ 'client', 'server' ]);
|
||||
api.export('Timepoints', [ 'client', 'server' ]);
|
||||
|
||||
api.export('Reviewers', [ 'client', 'server' ]);
|
||||
|
||||
});
|
||||
|
||||
@ -30,6 +30,11 @@ Meteor.publish('singlePatientImageMeasurements', function(patientId) {
|
||||
});
|
||||
});
|
||||
|
||||
Meteor.publish('reviewers', function() {
|
||||
return Reviewers.find();
|
||||
});
|
||||
|
||||
|
||||
// Temporary fix to drop all Collections on server restart
|
||||
// http://stackoverflow.com/questions/23891631/meteor-how-can-i-drop-all-mongo-collections-and-clear-all-data-on-startup
|
||||
Meteor.startup(function() {
|
||||
|
||||
75
Packages/lesiontracker/server/reviewers.js
Normal file
75
Packages/lesiontracker/server/reviewers.js
Normal file
@ -0,0 +1,75 @@
|
||||
Meteor.methods({
|
||||
setReviewer: function (studyInstanceUid) {
|
||||
if (!studyInstanceUid) {
|
||||
return;
|
||||
}
|
||||
var study = Studies.findOne({
|
||||
studyInstanceUid: studyInstanceUid
|
||||
});
|
||||
|
||||
if (!study) {
|
||||
return;
|
||||
}
|
||||
|
||||
var timepoint = Timepoints.findOne({
|
||||
timepointId: study.timepointId
|
||||
});
|
||||
|
||||
if (!timepoint) {
|
||||
return;
|
||||
}
|
||||
|
||||
var reviewerTimepoint = Reviewers.findOne({timepointId: timepoint.timepointId});
|
||||
var user = Meteor.users.findOne(Meteor.userId());
|
||||
if (reviewerTimepoint) {
|
||||
if (reviewerTimepoint.reviewers) {
|
||||
|
||||
// Check whether the user exists
|
||||
var isReviewerFound = reviewerTimepoint.reviewers.filter(function ( reviewer ) {
|
||||
return reviewer.userId === user._id;
|
||||
})[0];
|
||||
|
||||
// Return if user eixistes for related timepoint
|
||||
if (isReviewerFound) {
|
||||
return;
|
||||
}
|
||||
var existedReviewers = reviewerTimepoint.reviewers;
|
||||
existedReviewers.push({userId: user._id, userName: user.profile.fullName});
|
||||
|
||||
// Update reviewers array after pushing the user
|
||||
Reviewers.update(reviewerTimepoint._id, {$set: {reviewers: existedReviewers}});
|
||||
|
||||
} else {
|
||||
Reviewers.update(reviewerTimepoint._id, {$set: {reviewers: [{userId: user._id, userName: user.profile.fullName}]}});
|
||||
}
|
||||
} else {
|
||||
Reviewers.insert({timepointId: timepoint.timepointId, reviewers: [{userId: user._id, userName: user.profile.fullName}]});
|
||||
}
|
||||
},
|
||||
|
||||
removeReviewer: function (timepointId) {
|
||||
if (!timepointId) {
|
||||
return;
|
||||
}
|
||||
var reviewerTimepoint = Reviewers.findOne({timepointId: timepointId});
|
||||
if (!reviewerTimepoint || !reviewerTimepoint.reviewers) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Initalize a new array without the current user
|
||||
var reviewers = reviewerTimepoint.reviewers.filter(function ( reviewer ) {
|
||||
return reviewer.userId !== Meteor.userId();
|
||||
});
|
||||
Reviewers.update(reviewerTimepoint._id, {$set: {reviewers: reviewers}});
|
||||
},
|
||||
|
||||
removeUserFromReviewers: function(userId) {
|
||||
if (!userId) {
|
||||
return;
|
||||
}
|
||||
Reviewers.find().map(function (timepoint) {
|
||||
Reviewers.update({_id: timepoint._id}, {"$pull": {"reviewers": {"userId": userId}}});
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
Loading…
Reference in New Issue
Block a user