LT-327: Added functionality to disassociate timepoints from studies

This commit is contained in:
Erik Ziegler 2016-11-13 20:02:20 +01:00
parent e957968494
commit 01d22aa3c5
9 changed files with 106 additions and 63 deletions

View File

@ -1,7 +1,7 @@
import { OHIF } from 'meteor/ohif:core'; import { OHIF } from 'meteor/ohif:core';
import { measurementTools } from './measurementTools'; import { measurementTools } from './measurementTools';
import { retrieveMeasurements, storeMeasurements, retrieveTimepoints, storeTimepoints, removeTimepoint, updateTimepoint } from './dataExchange'; import { retrieveMeasurements, storeMeasurements, retrieveTimepoints, storeTimepoints, removeTimepoint, updateTimepoint, disassociateStudy } from './dataExchange';
import { validateMeasurements } from './dataValidation'; import { validateMeasurements } from './dataValidation';
console.log('OHIF-LesionTracker: Defining Configuration for Measurements'); console.log('OHIF-LesionTracker: Defining Configuration for Measurements');
@ -28,6 +28,7 @@ OHIF.measurements.TimepointApi.setConfiguration({
retrieve: retrieveTimepoints, retrieve: retrieveTimepoints,
store: storeTimepoints, store: storeTimepoints,
remove: removeTimepoint, remove: removeTimepoint,
update: updateTimepoint update: updateTimepoint,
disassociate: disassociateStudy
} }
}); });

View File

@ -95,3 +95,19 @@ export const removeTimepoint = timepointData => {
}); });
}); });
}; };
export const disassociateStudy = (timepointIds, studyInstanceUid) => {
console.log('disassociateStudy');
console.log(timepointIds);
console.log(studyInstanceUid);
return new Promise((resolve, reject) => {
Meteor.call('disassociateStudy', timepointIds, studyInstanceUid, (error, response) => {
if (error) {
reject(error);
} else {
resolve(response);
}
});
});
};

View File

@ -37,8 +37,50 @@ Meteor.methods({
}); });
}, },
disassociateStudy(timepointIds, studyInstanceUid) {
OHIF.log.info('Disassociating Study from Timepoints');
timepointIds.forEach(timepointId => {
const timepoint = Timepoints.findOne({timepointId});
if (!timepoint) {
return;
}
// Find the index of the current studyInstanceUid in the array
// of reference studyInstanceUids
const index = timepoint.studyInstanceUids.indexOf(studyInstanceUid);
if (index < 0) {
return;
}
// Remove the specified studyInstanceUid from the array of associated studyInstanceUids
timepoint.studyInstanceUids.splice(index, 1);
let updated = [];
let removed = [];
if (timepoint.studyInstanceUids.length) {
Timepoints.update(timepoint._id, {
$set: {
studyInstanceUids: timepoint.studyInstanceUids
}
});
} else {
Timepoints.remove(timepoint._id);
}
// Remove all Measurement Data for this timepoint and study
measurementTools.forEach(tool => {
const filter = {
studyInstanceUid: studyInstanceUid,
timepointId: timepointId
};
MeasurementCollections[tool.id].remove(filter)
});
});
},
removeTimepoint(timepointData) { removeTimepoint(timepointData) {
OHIF.log.info('Removing Timepoint off the Server'); OHIF.log.info('Removing Timepoint from the Server');
OHIF.log.info(JSON.stringify(timepointData, null, 2)); OHIF.log.info(JSON.stringify(timepointData, null, 2));
Timepoints.remove(timepointData); Timepoints.remove(timepointData);
}, },

View File

@ -119,7 +119,7 @@ class MeasurementApi {
} }
}); });
// Update the measurement numbers for the remaning measurements // Update the measurement numbers for the remaining measurements
const updateFilter = _.clone(filter); const updateFilter = _.clone(filter);
updateFilter.measurementNumber = { updateFilter.measurementNumber = {
$gt: measurementNumber $gt: measurementNumber

View File

@ -20,13 +20,13 @@ class TimepointApi {
if (currentTimepointId) { if (currentTimepointId) {
this.currentTimepointId = currentTimepointId; this.currentTimepointId = currentTimepointId;
} }
}
retrieveTimepoints(filter) {
this.timepoints = new Mongo.Collection(null); this.timepoints = new Mongo.Collection(null);
this.timepoints.attachSchema(TimepointSchema); this.timepoints.attachSchema(TimepointSchema);
this.timepoints._debugName = 'Timepoints'; this.timepoints._debugName = 'Timepoints';
}
retrieveTimepoints(filter) {
const retrievalFn = configuration.dataExchange.retrieve; const retrievalFn = configuration.dataExchange.retrieve;
if (!_.isFunction(retrievalFn)) { if (!_.isFunction(retrievalFn)) {
return; return;
@ -59,6 +59,16 @@ class TimepointApi {
storeFn(timepointData).then(() => OHIF.log.info('Timepoint storage completed')); storeFn(timepointData).then(() => OHIF.log.info('Timepoint storage completed'));
} }
disassociateStudy(timepointIds, studyInstanceUid) {
const disassociateFn = configuration.dataExchange.disassociate;
disassociateFn(timepointIds, studyInstanceUid).then(() => {
OHIF.log.info('Disassociation completed')
this.timepoints.remove({});
this.retrieveTimepoints();
});
}
removeTimepoint(timepointId) { removeTimepoint(timepointId) {
const removeFn = configuration.dataExchange.remove; const removeFn = configuration.dataExchange.remove;
if (!_.isFunction(removeFn)) { if (!_.isFunction(removeFn)) {

View File

@ -10,10 +10,12 @@
Measurements related to this Study and Timepoint will be erased. Do you really want to delete this association? Measurements related to this Study and Timepoint will be erased. Do you really want to delete this association?
</div> </div>
<div class="modal-footer"> <div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal" id='btnRemoveAssociationModalCancel'>
Cancel
</button>
<a id="removeTimepointAssociations" type="button" class="btn btn-danger" data-dismiss="modal" <a id="removeTimepointAssociations" type="button" class="btn btn-danger" data-dismiss="modal"
title="Remove Timepoint Association"> Remove title="Remove Timepoint Association"> Remove
</a> </a>
<button type="button" class="btn btn-default" data-dismiss="modal" id='btnRemoVeAssociationModalCancel'>Cancel</button>
</div> </div>
</div> </div>
</div> </div>

View File

@ -2,15 +2,22 @@
{{#dropdownForm}} {{#dropdownForm}}
<li><a id="viewStudies" type="button" title="View Studies">View</a></li> <li><a id="viewStudies" type="button" title="View Studies">View</a></li>
<li class="divider" role="separator"></li> <li class="divider" role="separator"></li>
<!-- {{#link action='associate'}}Associate{{/link}} --> <li>
<li><a id="launchStudyAssociation" title="Launch Study Association">Associate</a></li> <a id="launchStudyAssociation" title="Launch Study Association">Associate</a>
<li><a id="launchRemoveAssociation" type="button" data-toggle="modal" </li>
data-target="#confirmRemoveTimepointAssociation" title="Remove Timepoint Association" <li><a id="launchRemoveAssociation"
>Remove Association</a></li> type="button"
data-toggle="modal"
data-target="#confirmRemoveTimepointAssociation"
title="Remove Timepoint Association">
Remove Association
</a>
</li>
<li class="divider" role="separator"></li> <li class="divider" role="separator"></li>
<li><a id="viewSeriesDetails" type="button" <li>
title="View Series Details" <a id="viewSeriesDetails" type="button"
>View Series Details</a></li> title="View Series Details">View Series Details</a>
</li>
<li class="disabled"><a class="disabled">Anonymize</a></li> <li class="disabled"><a class="disabled">Anonymize</a></li>
<li class="disabled"><a class="disabled">Send</a></li> <li class="disabled"><a class="disabled">Send</a></li>
<li class="divider" role="separator"></li> <li class="divider" role="separator"></li>

View File

@ -22,54 +22,19 @@ function removeTimepointAssociations() {
// Get a Cursor pointing to the selected Studies from the StudyList // Get a Cursor pointing to the selected Studies from the StudyList
const selectedStudies = OHIF.studylist.getSelectedStudies(); const selectedStudies = OHIF.studylist.getSelectedStudies();
// Loop through the Cursor of Selected Studies
selectedStudies.forEach(function(selectedStudy) {
// Find the Timepoint that was previously referenced // Find the Timepoint that was previously referenced
const timepointApi = StudyList.timepointApi; const timepointApi = StudyList.timepointApi;
if (!timepointApi) { if (!timepointApi) {
OHIF.log.error('Remove Study/Timepoint Association: No Timepoint API found.')
return; return;
} }
let timepoint = timepointApi.study(selectedStudy.studyInstanceUid)[0]; // Loop through the Cursor of Selected Studies
if (!timepoint) { selectedStudies.forEach(study => {
return; const studyInstanceUid = study.studyInstanceUid;
} const timepoints = timepointApi.study(studyInstanceUid);
const timepointIds = timepoints.map(t => t.timepointId);
// Find the index of the current studyInstanceUid in the array timepointApi.disassociateStudy(timepointIds, studyInstanceUid);
// of reference studyInstanceUids
const index = timepoint.studyInstanceUids.indexOf(selectedStudy.studyInstanceUid);
if (index < 0) {
return;
}
// Remove the specified studyInstanceUid from the array of associated studyInstanceUids
timepoint.studyInstanceUids.splice(index, 1);
// Check if there are still one or more Studies associated with this Timepoint
if (timepoint.studyInstanceUids.length) {
// Update the Timepoints Collection with this modified array for the
// studyInstanceUids attribute
timepointApi.updateTimepoint(timepoint.timepointId, {
$set: {
studyInstanceUids: timepoint.studyInstanceUids
}
});
// Log
const hipaaEvent = {
eventType: 'modify',
userId: Meteor.userId(),
userName: Meteor.user().profile.fullName,
collectionName: 'Timepoints',
recordId: selectedStudy.timepointId,
patientId: selectedStudy.patientId,
patientName: selectedStudy.patientName
};
HipaaLogger.logEvent(hipaaEvent);
} else {
// If no more Studies are associated with this Timepoint, we should remove it
timepointApi.removeTimepoint(timepoint.timepointId);
}
}); });
} }

View File

@ -12,7 +12,7 @@ Template[defaultTemplate].helpers({
const studyInstanceUid = instance.data.studyInstanceUid; const studyInstanceUid = instance.data.studyInstanceUid;
// TODO: Find a better way to obtain the timepointApi from the viewer.js template // TODO: Find a better way to obtain the timepointApi from the viewer.js template
const timepointApi = OHIF.viewer.timepointApi; const timepointApi = StudyList.timepointApi;
if (!timepointApi) { if (!timepointApi) {
return; return;
} }