Adding separate save buttons for measurements
This commit is contained in:
parent
5dc2f8dc9c
commit
7da787c3f8
@ -110,6 +110,9 @@ function keyDownCallback(event, eventData) {
|
|||||||
nearbyToolData.toolType,
|
nearbyToolData.toolType,
|
||||||
eventData.element
|
eventData.element
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// Notify that viewer suffered changes
|
||||||
|
OHIF.measurements.triggerTimepointUnsavedChanges('deleted');
|
||||||
}).catch(unlock);
|
}).catch(unlock);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -8,8 +8,5 @@
|
|||||||
</div>
|
</div>
|
||||||
{{/if}}
|
{{/if}}
|
||||||
{{/if}}
|
{{/if}}
|
||||||
<div class="caseProgressStatus">
|
|
||||||
{{#button class='btn p-x-2' action='save' disabled=(isFinishDisabled)}}Save{{/button}}
|
|
||||||
</div>
|
|
||||||
{{/form}}
|
{{/form}}
|
||||||
</template>
|
</template>
|
||||||
|
|||||||
@ -1,7 +1,5 @@
|
|||||||
import { Template } from 'meteor/templating';
|
import { Template } from 'meteor/templating';
|
||||||
import { ReactiveVar } from 'meteor/reactive-var';
|
import { ReactiveVar } from 'meteor/reactive-var';
|
||||||
import { Session } from 'meteor/session';
|
|
||||||
import { Tracker } from 'meteor/tracker';
|
|
||||||
import { OHIF } from 'meteor/ohif:core';
|
import { OHIF } from 'meteor/ohif:core';
|
||||||
|
|
||||||
Template.caseProgress.onCreated(() => {
|
Template.caseProgress.onCreated(() => {
|
||||||
@ -11,48 +9,6 @@ Template.caseProgress.onCreated(() => {
|
|||||||
instance.progressText = new ReactiveVar();
|
instance.progressText = new ReactiveVar();
|
||||||
instance.isLocked = new ReactiveVar(false);
|
instance.isLocked = new ReactiveVar(false);
|
||||||
instance.isFollowUp = new ReactiveVar(false);
|
instance.isFollowUp = new ReactiveVar(false);
|
||||||
instance.path = 'viewer.studyViewer.measurements';
|
|
||||||
instance.saveObserver = new Tracker.Dependency();
|
|
||||||
|
|
||||||
instance.api = {
|
|
||||||
save() {
|
|
||||||
// Clear signaled unsaved changes...
|
|
||||||
const successHandler = () => {
|
|
||||||
OHIF.ui.unsavedChanges.clear(`${instance.path}.*`);
|
|
||||||
instance.saveObserver.changed();
|
|
||||||
};
|
|
||||||
|
|
||||||
// Display the error messages
|
|
||||||
const errorHandler = data => {
|
|
||||||
OHIF.ui.showDialog('dialogInfo', Object.assign({ class: 'themed' }, data));
|
|
||||||
};
|
|
||||||
|
|
||||||
const promise = instance.data.measurementApi.storeMeasurements();
|
|
||||||
promise.then(successHandler).catch(errorHandler);
|
|
||||||
OHIF.ui.showDialog('dialogLoading', {
|
|
||||||
promise,
|
|
||||||
text: 'Saving measurement data'
|
|
||||||
});
|
|
||||||
|
|
||||||
return promise;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
instance.unsavedChangesHandler = () => {
|
|
||||||
const isNotDisabled = !instance.$('.js-finish-case').hasClass('disabled');
|
|
||||||
if (isNotDisabled && instance.progressPercent.get() === 100) {
|
|
||||||
instance.api.save();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// Attach handler for unsaved changes dialog...
|
|
||||||
OHIF.ui.unsavedChanges.attachHandler(instance.path, 'save', instance.unsavedChangesHandler);
|
|
||||||
});
|
|
||||||
|
|
||||||
Template.caseProgress.onDestroyed(() => {
|
|
||||||
const instance = Template.instance();
|
|
||||||
// Remove unsaved changes handler after this view has been destroyed...
|
|
||||||
OHIF.ui.unsavedChanges.removeHandler(instance.path, 'save', instance.unsavedChangesHandler);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
Template.caseProgress.onRendered(() => {
|
Template.caseProgress.onRendered(() => {
|
||||||
@ -178,16 +134,5 @@ Template.caseProgress.helpers({
|
|||||||
|
|
||||||
const progressPercent = instance.progressPercent.get();
|
const progressPercent = instance.progressPercent.get();
|
||||||
return progressPercent === 100;
|
return progressPercent === 100;
|
||||||
},
|
|
||||||
|
|
||||||
isFinishDisabled() {
|
|
||||||
const instance = Template.instance();
|
|
||||||
|
|
||||||
// Run this computation on save or every time any measurement / timepoint suffer changes
|
|
||||||
OHIF.ui.unsavedChanges.depend();
|
|
||||||
instance.saveObserver.depend();
|
|
||||||
Session.get('LayoutManagerUpdated');
|
|
||||||
|
|
||||||
return OHIF.ui.unsavedChanges.probe('viewer.*') === 0;
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
@ -94,10 +94,7 @@ Template.measurementTableRow.events({
|
|||||||
_.each($('.imageViewerViewport'), element => cornerstone.updateImage(element));
|
_.each($('.imageViewerViewport'), element => cornerstone.updateImage(element));
|
||||||
|
|
||||||
// Notify that viewer suffered changes
|
// Notify that viewer suffered changes
|
||||||
const { timepointId } = measurement;
|
OHIF.measurements.triggerTimepointUnsavedChanges('deleted');
|
||||||
const basePath = 'viewer.studyViewer.measurements';
|
|
||||||
const timepointPath = timepointId ? `.${timepointId}` : '';
|
|
||||||
OHIF.ui.unsavedChanges.set(`${basePath}${timepointPath}.deleted`);
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
@ -89,9 +89,6 @@ export default function ({ instance, eventData, tool, toolGroupId, toolGroup })
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// Signal unsaved changes
|
// Notify that viewer suffered changes
|
||||||
const { timepointId } = Collection.findOne(measurementData._id);
|
OHIF.measurements.triggerTimepointUnsavedChanges(eventData.toolType);
|
||||||
const basePath = 'viewer.studyViewer.measurements';
|
|
||||||
const timepointPath = timepointId ? `.${timepointId}` : '';
|
|
||||||
OHIF.ui.unsavedChanges.set(`${basePath}${timepointPath}.${eventData.toolType}`);
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -35,9 +35,6 @@ export default function ({ instance, eventData, tool, toolGroupId, toolGroup })
|
|||||||
// Update the measurement in the collection
|
// Update the measurement in the collection
|
||||||
Collection.update(measurement._id, { $set: { [tool.attribute]: childMeasurement } });
|
Collection.update(measurement._id, { $set: { [tool.attribute]: childMeasurement } });
|
||||||
|
|
||||||
// Signal unsaved changes
|
// Notify that viewer suffered changes
|
||||||
const { timepointId } = Collection.findOne(measurementData._id);
|
OHIF.measurements.triggerTimepointUnsavedChanges(eventData.toolType);
|
||||||
const basePath = 'viewer.studyViewer.measurements';
|
|
||||||
const timepointPath = timepointId ? `.${timepointId}` : '';
|
|
||||||
OHIF.ui.unsavedChanges.set(`${basePath}${timepointPath}.${eventData.toolType}`);
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -35,9 +35,6 @@ export default function ({ instance, eventData, tool, toolGroupId, toolGroup })
|
|||||||
// Repaint the images on all viewports without the removed measurements
|
// Repaint the images on all viewports without the removed measurements
|
||||||
_.each($('.imageViewerViewport'), element => cornerstone.updateImage(element));
|
_.each($('.imageViewerViewport'), element => cornerstone.updateImage(element));
|
||||||
|
|
||||||
// Signal unsaved changes
|
// Notify that viewer suffered changes
|
||||||
const { timepointId } = Collection.findOne(measurementData._id);
|
OHIF.measurements.triggerTimepointUnsavedChanges(eventData.toolType);
|
||||||
const basePath = 'viewer.studyViewer.measurements';
|
|
||||||
const timepointPath = timepointId ? `.${timepointId}` : '';
|
|
||||||
OHIF.ui.unsavedChanges.set(`${basePath}${timepointPath}.${eventData.toolType}`);
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -48,9 +48,6 @@ export default function ({ instance, eventData, tool }) {
|
|||||||
cornerstone.updateImage(OHIF.viewerbase.viewportUtils.getActiveViewportElement());
|
cornerstone.updateImage(OHIF.viewerbase.viewportUtils.getActiveViewportElement());
|
||||||
});
|
});
|
||||||
|
|
||||||
// Signal unsaved changes
|
// Notify that viewer suffered changes
|
||||||
const { timepointId } = Collection.findOne(measurementData._id);
|
OHIF.measurements.triggerTimepointUnsavedChanges(eventData.toolType);
|
||||||
const basePath = 'viewer.studyViewer.measurements';
|
|
||||||
const timepointPath = timepointId ? `.${timepointId}` : '';
|
|
||||||
OHIF.ui.unsavedChanges.set(`${basePath}${timepointPath}.${eventData.toolType}`);
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -37,9 +37,6 @@ export default function ({ instance, eventData, tool, toolGroupId, toolGroup })
|
|||||||
// Update the measurement in the collection
|
// Update the measurement in the collection
|
||||||
Collection.update(measurementId, { $set: measurement });
|
Collection.update(measurementId, { $set: measurement });
|
||||||
|
|
||||||
// Signal unsaved changes
|
// Notify that viewer suffered changes
|
||||||
const { timepointId } = Collection.findOne(measurementData._id);
|
OHIF.measurements.triggerTimepointUnsavedChanges(eventData.toolType);
|
||||||
const basePath = 'viewer.studyViewer.measurements';
|
|
||||||
const timepointPath = timepointId ? `.${timepointId}` : '';
|
|
||||||
OHIF.ui.unsavedChanges.set(`${basePath}${timepointPath}.${eventData.toolType}`);
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -32,8 +32,6 @@ export default function({ instance, eventData, tool, toolGroupId, toolGroup }) {
|
|||||||
// Repaint the images on all viewports without the removed measurements
|
// Repaint the images on all viewports without the removed measurements
|
||||||
_.each($('.imageViewerViewport'), element => cornerstone.updateImage(element));
|
_.each($('.imageViewerViewport'), element => cornerstone.updateImage(element));
|
||||||
|
|
||||||
// Signal unsaved changes
|
// Notify that viewer suffered changes
|
||||||
const basePath = 'viewer.studyViewer.measurements';
|
OHIF.measurements.triggerTimepointUnsavedChanges(eventData.toolType);
|
||||||
const timepointPath = timepointId ? `.${timepointId}` : '';
|
|
||||||
OHIF.ui.unsavedChanges.set(`${basePath}${timepointPath}.${eventData.toolType}`);
|
|
||||||
}
|
}
|
||||||
|
|||||||
13
Packages/ohif-measurements/client/lib/getActiveTimepoint.js
Normal file
13
Packages/ohif-measurements/client/lib/getActiveTimepoint.js
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
import { Session } from 'meteor/session';
|
||||||
|
import { OHIF } from 'meteor/ohif:core';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Extensible method to get the timepoint of the active viewport
|
||||||
|
*
|
||||||
|
* @returns {Object} - Timepoint data for the active viewport
|
||||||
|
*/
|
||||||
|
OHIF.measurements.getActiveTimepoint = () => {
|
||||||
|
const activeViewportIndex = Session.get('activeViewport');
|
||||||
|
const { studyInstanceUid } = OHIF.viewerbase.layoutManager.viewportData[activeViewportIndex];
|
||||||
|
return OHIF.viewer.timepointApi.study(studyInstanceUid)[0];
|
||||||
|
};
|
||||||
@ -4,6 +4,7 @@ import './clearCornerstoneToolState';
|
|||||||
import './deactivateAllToolData';
|
import './deactivateAllToolData';
|
||||||
import './exportPdf';
|
import './exportPdf';
|
||||||
import './findAndRenderDisplaySet';
|
import './findAndRenderDisplaySet';
|
||||||
|
import './getActiveTimepoint';
|
||||||
import './getImageDataUrl';
|
import './getImageDataUrl';
|
||||||
import './getMeasurementsGroupedByNumber';
|
import './getMeasurementsGroupedByNumber';
|
||||||
import './getLocationLabel';
|
import './getLocationLabel';
|
||||||
@ -15,3 +16,4 @@ import './MeasurementManager';
|
|||||||
import './navigateOverLesions';
|
import './navigateOverLesions';
|
||||||
import './syncMeasurementAndToolData';
|
import './syncMeasurementAndToolData';
|
||||||
import './toggleLabelButton';
|
import './toggleLabelButton';
|
||||||
|
import './triggerTimepointUnsavedChanges';
|
||||||
|
|||||||
@ -60,10 +60,7 @@ OHIF.measurements.toggleLabelButton = options => {
|
|||||||
options.measurement.description = description;
|
options.measurement.description = description;
|
||||||
|
|
||||||
// Notify that viewer suffered changes
|
// Notify that viewer suffered changes
|
||||||
const { timepointId } = measurement;
|
OHIF.measurements.triggerTimepointUnsavedChanges('renamed');
|
||||||
const basePath = 'viewer.studyViewer.measurements';
|
|
||||||
const timepointPath = timepointId ? `.${timepointId}` : '';
|
|
||||||
OHIF.ui.unsavedChanges.set(`${basePath}${timepointPath}.renamed`);
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
buttonView = Blaze.renderWithData(Template.measureFlow, data, document.body);
|
buttonView = Blaze.renderWithData(Template.measureFlow, data, document.body);
|
||||||
|
|||||||
@ -0,0 +1,15 @@
|
|||||||
|
import { OHIF } from 'meteor/ohif:core';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Extensible method to trigger unsaved changes on the active timepoint
|
||||||
|
*
|
||||||
|
* @param {String} subpath - The unsaved changes subpath that will come after the timepoint ID
|
||||||
|
*/
|
||||||
|
OHIF.measurements.triggerTimepointUnsavedChanges = (subpath='changed') => {
|
||||||
|
const basePath = 'viewer.studyViewer.measurements';
|
||||||
|
const activeTimepoint = OHIF.measurements.getActiveTimepoint();
|
||||||
|
if (!activeTimepoint) return;
|
||||||
|
const { timepointId } = activeTimepoint;
|
||||||
|
const timepointPath = timepointId ? `.${timepointId}` : '';
|
||||||
|
OHIF.ui.unsavedChanges.set(`${basePath}${timepointPath}.${subpath}`);
|
||||||
|
};
|
||||||
@ -8,13 +8,13 @@ const loadPreviousActivePanel = () => {
|
|||||||
let currentIndex = Session.get('activeViewport');
|
let currentIndex = Session.get('activeViewport');
|
||||||
currentIndex--;
|
currentIndex--;
|
||||||
|
|
||||||
const viewports = $('.imageViewerViewport');
|
const $viewports = $('.imageViewerViewport');
|
||||||
const numViewports = viewports.length;
|
const numViewports = $viewports.length;
|
||||||
if (currentIndex < 0) {
|
if (currentIndex < 0) {
|
||||||
currentIndex = numViewports - 1;
|
currentIndex = numViewports - 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
const element = viewports.get(currentIndex);
|
const element = $viewports.get(currentIndex);
|
||||||
if (!element) {
|
if (!element) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -27,13 +27,13 @@ const loadNextActivePanel = () => {
|
|||||||
let currentIndex = Session.get('activeViewport');
|
let currentIndex = Session.get('activeViewport');
|
||||||
currentIndex++;
|
currentIndex++;
|
||||||
|
|
||||||
const viewports = $('.imageViewerViewport');
|
const $viewports = $('.imageViewerViewport');
|
||||||
const numViewports = viewports.length;
|
const numViewports = $viewports.length;
|
||||||
if (currentIndex >= numViewports) {
|
if (currentIndex >= numViewports) {
|
||||||
currentIndex = 0;
|
currentIndex = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
const element = viewports.get(currentIndex);
|
const element = $viewports.get(currentIndex);
|
||||||
if (!element) {
|
if (!element) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -8,24 +8,30 @@ import { displayReferenceLines } from './displayReferenceLines';
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets a viewport element active
|
* Sets a viewport element active
|
||||||
* @param {node} element DOM element to be activated
|
* @param {node} element DOM element to be activated or viewportIndex
|
||||||
*/
|
*/
|
||||||
export function setActiveViewport(element) {
|
export function setActiveViewport(element) {
|
||||||
if (!element) {
|
const $viewerports = $('.imageViewerViewport');
|
||||||
|
|
||||||
|
let viewportIndex;
|
||||||
|
if (typeof element === 'number') {
|
||||||
|
viewportIndex = element;
|
||||||
|
} else {
|
||||||
|
viewportIndex = $viewerports.index(element);
|
||||||
|
}
|
||||||
|
|
||||||
|
const $element = $viewerports.eq(viewportIndex);
|
||||||
|
if (!$element.length) {
|
||||||
OHIF.log.info('setActiveViewport element does not exist');
|
OHIF.log.info('setActiveViewport element does not exist');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const viewerports = $('.imageViewerViewport');
|
|
||||||
const viewportIndex = viewerports.index(element);
|
|
||||||
const jQueryElement = $(element);
|
|
||||||
|
|
||||||
OHIF.log.info(`setActiveViewport setting viewport index: ${viewportIndex}`);
|
OHIF.log.info(`setActiveViewport setting viewport index: ${viewportIndex}`);
|
||||||
|
|
||||||
// If viewport is not active
|
// If viewport is not active
|
||||||
if(!jQueryElement.parents('.viewportContainer').hasClass('active')) {
|
if (!$element.parents('.viewportContainer').hasClass('active')) {
|
||||||
// Trigger an event for compatibility with other systems
|
// Trigger an event for compatibility with other systems
|
||||||
jQueryElement.trigger('OHIFBeforeActivateViewport');
|
$element.trigger('OHIFBeforeActivateViewport');
|
||||||
}
|
}
|
||||||
|
|
||||||
// When an OHIFActivateViewport event is fired, update the Meteor Session
|
// When an OHIFActivateViewport event is fired, update the Meteor Session
|
||||||
@ -42,15 +48,15 @@ export function setActiveViewport(element) {
|
|||||||
|
|
||||||
// Add the 'active' class to the parent container to highlight the active viewport
|
// Add the 'active' class to the parent container to highlight the active viewport
|
||||||
$('#imageViewerViewports .viewportContainer').removeClass('active');
|
$('#imageViewerViewports .viewportContainer').removeClass('active');
|
||||||
jQueryElement.parents('.viewportContainer').addClass('active');
|
$element.parents('.viewportContainer').addClass('active');
|
||||||
|
|
||||||
// Finally, enable stack prefetching and hide the reference lines from
|
// Finally, enable stack prefetching and hide the reference lines from
|
||||||
// the newly activated viewport that has a canvas
|
// the newly activated viewport that has a canvas
|
||||||
|
|
||||||
if (jQueryElement.find('canvas').length) {
|
if ($element.find('canvas').length) {
|
||||||
// Cornerstone Tools compare DOM elements (check getEnabledElement cornerstone function)
|
// Cornerstone Tools compare DOM elements (check getEnabledElement cornerstone function)
|
||||||
// so we can't pass a jQuery object as an argument, otherwise it throws an excepetion
|
// so we can't pass a jQuery object as an argument, otherwise it throws an excepetion
|
||||||
const domElement = jQueryElement.get(0);
|
const domElement = $element.get(0);
|
||||||
displayReferenceLines(domElement);
|
displayReferenceLines(domElement);
|
||||||
StudyPrefetcher.getInstance().prefetch();
|
StudyPrefetcher.getInstance().prefetch();
|
||||||
|
|
||||||
@ -63,10 +69,10 @@ export function setActiveViewport(element) {
|
|||||||
// Set the div to focused, so keypress events are handled
|
// Set the div to focused, so keypress events are handled
|
||||||
//$(element).focus();
|
//$(element).focus();
|
||||||
//.focus() event breaks in FF&IE
|
//.focus() event breaks in FF&IE
|
||||||
jQueryElement.triggerHandler('focus');
|
$element.triggerHandler('focus');
|
||||||
|
|
||||||
// Trigger OHIFAfterActivateViewport event on activated instance
|
// Trigger OHIFAfterActivateViewport event on activated instance
|
||||||
// for compatibility with other systems
|
// for compatibility with other systems
|
||||||
jQueryElement.trigger('OHIFAfterActivateViewport');
|
$element.trigger('OHIFAfterActivateViewport');
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user