diff --git a/Packages/ohif-lesiontracker/client/compatibility/deleteLesionKeyboardTool.js b/Packages/ohif-lesiontracker/client/compatibility/deleteLesionKeyboardTool.js index 226c18082..c7bffaebb 100644 --- a/Packages/ohif-lesiontracker/client/compatibility/deleteLesionKeyboardTool.js +++ b/Packages/ohif-lesiontracker/client/compatibility/deleteLesionKeyboardTool.js @@ -110,6 +110,9 @@ function keyDownCallback(event, eventData) { nearbyToolData.toolType, eventData.element ); + + // Notify that viewer suffered changes + OHIF.measurements.triggerTimepointUnsavedChanges('deleted'); }).catch(unlock); } } diff --git a/Packages/ohif-measurements/client/components/caseProgress/caseProgress.html b/Packages/ohif-measurements/client/components/caseProgress/caseProgress.html index 497935bcc..a5fef7dfc 100644 --- a/Packages/ohif-measurements/client/components/caseProgress/caseProgress.html +++ b/Packages/ohif-measurements/client/components/caseProgress/caseProgress.html @@ -8,8 +8,5 @@ {{/if}} {{/if}} -
- {{#button class='btn p-x-2' action='save' disabled=(isFinishDisabled)}}Save{{/button}} -
{{/form}} diff --git a/Packages/ohif-measurements/client/components/caseProgress/caseProgress.js b/Packages/ohif-measurements/client/components/caseProgress/caseProgress.js index f421da1c3..45286f9d9 100644 --- a/Packages/ohif-measurements/client/components/caseProgress/caseProgress.js +++ b/Packages/ohif-measurements/client/components/caseProgress/caseProgress.js @@ -1,7 +1,5 @@ import { Template } from 'meteor/templating'; import { ReactiveVar } from 'meteor/reactive-var'; -import { Session } from 'meteor/session'; -import { Tracker } from 'meteor/tracker'; import { OHIF } from 'meteor/ohif:core'; Template.caseProgress.onCreated(() => { @@ -11,48 +9,6 @@ Template.caseProgress.onCreated(() => { instance.progressText = new ReactiveVar(); instance.isLocked = 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(() => { @@ -178,16 +134,5 @@ Template.caseProgress.helpers({ const progressPercent = instance.progressPercent.get(); 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; } }); diff --git a/Packages/ohif-measurements/client/components/measurementTable/measurementTableRow/measurementTableRow.js b/Packages/ohif-measurements/client/components/measurementTable/measurementTableRow/measurementTableRow.js index faa7c4346..0367e1b04 100644 --- a/Packages/ohif-measurements/client/components/measurementTable/measurementTableRow/measurementTableRow.js +++ b/Packages/ohif-measurements/client/components/measurementTable/measurementTableRow/measurementTableRow.js @@ -94,10 +94,7 @@ Template.measurementTableRow.events({ _.each($('.imageViewerViewport'), element => cornerstone.updateImage(element)); // Notify that viewer suffered changes - const { timepointId } = measurement; - const basePath = 'viewer.studyViewer.measurements'; - const timepointPath = timepointId ? `.${timepointId}` : ''; - OHIF.ui.unsavedChanges.set(`${basePath}${timepointPath}.deleted`); + OHIF.measurements.triggerTimepointUnsavedChanges('deleted'); }); } }); diff --git a/Packages/ohif-measurements/client/lib/MeasurementHandlers/handleChildMeasurementAdded.js b/Packages/ohif-measurements/client/lib/MeasurementHandlers/handleChildMeasurementAdded.js index b6eeaf3ee..65c425808 100644 --- a/Packages/ohif-measurements/client/lib/MeasurementHandlers/handleChildMeasurementAdded.js +++ b/Packages/ohif-measurements/client/lib/MeasurementHandlers/handleChildMeasurementAdded.js @@ -89,9 +89,6 @@ export default function ({ instance, eventData, tool, toolGroupId, toolGroup }) }); } - // Signal unsaved changes - const { timepointId } = Collection.findOne(measurementData._id); - const basePath = 'viewer.studyViewer.measurements'; - const timepointPath = timepointId ? `.${timepointId}` : ''; - OHIF.ui.unsavedChanges.set(`${basePath}${timepointPath}.${eventData.toolType}`); + // Notify that viewer suffered changes + OHIF.measurements.triggerTimepointUnsavedChanges(eventData.toolType); } diff --git a/Packages/ohif-measurements/client/lib/MeasurementHandlers/handleChildMeasurementModified.js b/Packages/ohif-measurements/client/lib/MeasurementHandlers/handleChildMeasurementModified.js index b5b4e593e..b84a2f2f3 100644 --- a/Packages/ohif-measurements/client/lib/MeasurementHandlers/handleChildMeasurementModified.js +++ b/Packages/ohif-measurements/client/lib/MeasurementHandlers/handleChildMeasurementModified.js @@ -35,9 +35,6 @@ export default function ({ instance, eventData, tool, toolGroupId, toolGroup }) // Update the measurement in the collection Collection.update(measurement._id, { $set: { [tool.attribute]: childMeasurement } }); - // Signal unsaved changes - const { timepointId } = Collection.findOne(measurementData._id); - const basePath = 'viewer.studyViewer.measurements'; - const timepointPath = timepointId ? `.${timepointId}` : ''; - OHIF.ui.unsavedChanges.set(`${basePath}${timepointPath}.${eventData.toolType}`); + // Notify that viewer suffered changes + OHIF.measurements.triggerTimepointUnsavedChanges(eventData.toolType); } diff --git a/Packages/ohif-measurements/client/lib/MeasurementHandlers/handleChildMeasurementRemoved.js b/Packages/ohif-measurements/client/lib/MeasurementHandlers/handleChildMeasurementRemoved.js index d30f4d7ab..bb738fda4 100644 --- a/Packages/ohif-measurements/client/lib/MeasurementHandlers/handleChildMeasurementRemoved.js +++ b/Packages/ohif-measurements/client/lib/MeasurementHandlers/handleChildMeasurementRemoved.js @@ -35,9 +35,6 @@ export default function ({ instance, eventData, tool, toolGroupId, toolGroup }) // Repaint the images on all viewports without the removed measurements _.each($('.imageViewerViewport'), element => cornerstone.updateImage(element)); - // Signal unsaved changes - const { timepointId } = Collection.findOne(measurementData._id); - const basePath = 'viewer.studyViewer.measurements'; - const timepointPath = timepointId ? `.${timepointId}` : ''; - OHIF.ui.unsavedChanges.set(`${basePath}${timepointPath}.${eventData.toolType}`); + // Notify that viewer suffered changes + OHIF.measurements.triggerTimepointUnsavedChanges(eventData.toolType); } diff --git a/Packages/ohif-measurements/client/lib/MeasurementHandlers/handleSingleMeasurementAdded.js b/Packages/ohif-measurements/client/lib/MeasurementHandlers/handleSingleMeasurementAdded.js index 27b14c214..d1b78eb2b 100644 --- a/Packages/ohif-measurements/client/lib/MeasurementHandlers/handleSingleMeasurementAdded.js +++ b/Packages/ohif-measurements/client/lib/MeasurementHandlers/handleSingleMeasurementAdded.js @@ -48,9 +48,6 @@ export default function ({ instance, eventData, tool }) { cornerstone.updateImage(OHIF.viewerbase.viewportUtils.getActiveViewportElement()); }); - // Signal unsaved changes - const { timepointId } = Collection.findOne(measurementData._id); - const basePath = 'viewer.studyViewer.measurements'; - const timepointPath = timepointId ? `.${timepointId}` : ''; - OHIF.ui.unsavedChanges.set(`${basePath}${timepointPath}.${eventData.toolType}`); + // Notify that viewer suffered changes + OHIF.measurements.triggerTimepointUnsavedChanges(eventData.toolType); } diff --git a/Packages/ohif-measurements/client/lib/MeasurementHandlers/handleSingleMeasurementModified.js b/Packages/ohif-measurements/client/lib/MeasurementHandlers/handleSingleMeasurementModified.js index d689e656e..223fc990e 100644 --- a/Packages/ohif-measurements/client/lib/MeasurementHandlers/handleSingleMeasurementModified.js +++ b/Packages/ohif-measurements/client/lib/MeasurementHandlers/handleSingleMeasurementModified.js @@ -37,9 +37,6 @@ export default function ({ instance, eventData, tool, toolGroupId, toolGroup }) // Update the measurement in the collection Collection.update(measurementId, { $set: measurement }); - // Signal unsaved changes - const { timepointId } = Collection.findOne(measurementData._id); - const basePath = 'viewer.studyViewer.measurements'; - const timepointPath = timepointId ? `.${timepointId}` : ''; - OHIF.ui.unsavedChanges.set(`${basePath}${timepointPath}.${eventData.toolType}`); + // Notify that viewer suffered changes + OHIF.measurements.triggerTimepointUnsavedChanges(eventData.toolType); } diff --git a/Packages/ohif-measurements/client/lib/MeasurementHandlers/handleSingleMeasurementRemoved.js b/Packages/ohif-measurements/client/lib/MeasurementHandlers/handleSingleMeasurementRemoved.js index 0d70db365..77136c9cf 100644 --- a/Packages/ohif-measurements/client/lib/MeasurementHandlers/handleSingleMeasurementRemoved.js +++ b/Packages/ohif-measurements/client/lib/MeasurementHandlers/handleSingleMeasurementRemoved.js @@ -32,8 +32,6 @@ export default function({ instance, eventData, tool, toolGroupId, toolGroup }) { // Repaint the images on all viewports without the removed measurements _.each($('.imageViewerViewport'), element => cornerstone.updateImage(element)); - // Signal unsaved changes - const basePath = 'viewer.studyViewer.measurements'; - const timepointPath = timepointId ? `.${timepointId}` : ''; - OHIF.ui.unsavedChanges.set(`${basePath}${timepointPath}.${eventData.toolType}`); + // Notify that viewer suffered changes + OHIF.measurements.triggerTimepointUnsavedChanges(eventData.toolType); } diff --git a/Packages/ohif-measurements/client/lib/getActiveTimepoint.js b/Packages/ohif-measurements/client/lib/getActiveTimepoint.js new file mode 100644 index 000000000..8d37f4363 --- /dev/null +++ b/Packages/ohif-measurements/client/lib/getActiveTimepoint.js @@ -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]; +}; diff --git a/Packages/ohif-measurements/client/lib/index.js b/Packages/ohif-measurements/client/lib/index.js index 0440fbac6..3e490ae55 100644 --- a/Packages/ohif-measurements/client/lib/index.js +++ b/Packages/ohif-measurements/client/lib/index.js @@ -4,6 +4,7 @@ import './clearCornerstoneToolState'; import './deactivateAllToolData'; import './exportPdf'; import './findAndRenderDisplaySet'; +import './getActiveTimepoint'; import './getImageDataUrl'; import './getMeasurementsGroupedByNumber'; import './getLocationLabel'; @@ -15,3 +16,4 @@ import './MeasurementManager'; import './navigateOverLesions'; import './syncMeasurementAndToolData'; import './toggleLabelButton'; +import './triggerTimepointUnsavedChanges'; diff --git a/Packages/ohif-measurements/client/lib/toggleLabelButton.js b/Packages/ohif-measurements/client/lib/toggleLabelButton.js index 6c5a041c8..162284dac 100644 --- a/Packages/ohif-measurements/client/lib/toggleLabelButton.js +++ b/Packages/ohif-measurements/client/lib/toggleLabelButton.js @@ -60,10 +60,7 @@ OHIF.measurements.toggleLabelButton = options => { options.measurement.description = description; // Notify that viewer suffered changes - const { timepointId } = measurement; - const basePath = 'viewer.studyViewer.measurements'; - const timepointPath = timepointId ? `.${timepointId}` : ''; - OHIF.ui.unsavedChanges.set(`${basePath}${timepointPath}.renamed`); + OHIF.measurements.triggerTimepointUnsavedChanges('renamed'); } }; buttonView = Blaze.renderWithData(Template.measureFlow, data, document.body); diff --git a/Packages/ohif-measurements/client/lib/triggerTimepointUnsavedChanges.js b/Packages/ohif-measurements/client/lib/triggerTimepointUnsavedChanges.js new file mode 100644 index 000000000..c14375431 --- /dev/null +++ b/Packages/ohif-measurements/client/lib/triggerTimepointUnsavedChanges.js @@ -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}`); +}; diff --git a/Packages/ohif-viewerbase/client/lib/panelNavigation.js b/Packages/ohif-viewerbase/client/lib/panelNavigation.js index 64c89cd62..f5397afc3 100644 --- a/Packages/ohif-viewerbase/client/lib/panelNavigation.js +++ b/Packages/ohif-viewerbase/client/lib/panelNavigation.js @@ -8,13 +8,13 @@ const loadPreviousActivePanel = () => { let currentIndex = Session.get('activeViewport'); currentIndex--; - const viewports = $('.imageViewerViewport'); - const numViewports = viewports.length; + const $viewports = $('.imageViewerViewport'); + const numViewports = $viewports.length; if (currentIndex < 0) { currentIndex = numViewports - 1; } - const element = viewports.get(currentIndex); + const element = $viewports.get(currentIndex); if (!element) { return; } @@ -27,13 +27,13 @@ const loadNextActivePanel = () => { let currentIndex = Session.get('activeViewport'); currentIndex++; - const viewports = $('.imageViewerViewport'); - const numViewports = viewports.length; + const $viewports = $('.imageViewerViewport'); + const numViewports = $viewports.length; if (currentIndex >= numViewports) { currentIndex = 0; } - const element = viewports.get(currentIndex); + const element = $viewports.get(currentIndex); if (!element) { return; } diff --git a/Packages/ohif-viewerbase/client/lib/setActiveViewport.js b/Packages/ohif-viewerbase/client/lib/setActiveViewport.js index 1452d46fb..f78ab348b 100644 --- a/Packages/ohif-viewerbase/client/lib/setActiveViewport.js +++ b/Packages/ohif-viewerbase/client/lib/setActiveViewport.js @@ -8,24 +8,30 @@ import { displayReferenceLines } from './displayReferenceLines'; /** * 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) { - 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'); return; } - const viewerports = $('.imageViewerViewport'); - const viewportIndex = viewerports.index(element); - const jQueryElement = $(element); - OHIF.log.info(`setActiveViewport setting viewport index: ${viewportIndex}`); // 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 - jQueryElement.trigger('OHIFBeforeActivateViewport'); + $element.trigger('OHIFBeforeActivateViewport'); } // 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 $('#imageViewerViewports .viewportContainer').removeClass('active'); - jQueryElement.parents('.viewportContainer').addClass('active'); + $element.parents('.viewportContainer').addClass('active'); // Finally, enable stack prefetching and hide the reference lines from // 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) // 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); StudyPrefetcher.getInstance().prefetch(); @@ -63,10 +69,10 @@ export function setActiveViewport(element) { // Set the div to focused, so keypress events are handled //$(element).focus(); //.focus() event breaks in FF&IE - jQueryElement.triggerHandler('focus'); + $element.triggerHandler('focus'); // Trigger OHIFAfterActivateViewport event on activated instance // for compatibility with other systems - jQueryElement.trigger('OHIFAfterActivateViewport'); + $element.trigger('OHIFAfterActivateViewport'); }