Finishing case progress and save behavior

This commit is contained in:
Bruno Alves de Faria 2018-01-26 15:17:26 -02:00
parent abe7691730
commit 45a3cdeaf5
13 changed files with 87 additions and 56 deletions

View File

@ -7,9 +7,6 @@
{{>toolbarSectionTools toolbarButtons=toolbarButtons}}
<div id="toolbarSectionEntry" class="toolbarSectionEntry pull-right rm-l-1 p-x-1">
{{>caseProgress}}
</div>
<div id="toggleMeasurements" class="pull-right m-t-1 rm-x-1">
{{>roundedButtonGroup rightSidebarToggleButtonData}}
</div>

View File

@ -33,38 +33,21 @@ Meteor.startup(() => {
id: 'linkStackScroll',
name: 'Link',
action: OHIF.viewerbase.viewportUtils.linkStackScroll
}, {
id: 'saveMeasurements',
name: 'Save measurements',
hotkey: 'CTRL+S',
action() {
const activeTimepoint = OHIF.measurements.getActiveTimepoint();
if (!activeTimepoint) return;
OHIF.measurements.saveMeasurements(OHIF.viewer.measurementApi, activeTimepoint.timepointId);
}
}];
customCommands.forEach(command => {
_.defaults(OHIF.hotkeys.defaults[contextName], { [command.id]: '' });
_.defaults(OHIF.hotkeys.defaults[contextName], { [command.id]: command.hotkey || '' });
OHIF.commands.register(contextName, command.id, {
name: command.name,
action: command.action || (() => toolManager.setActiveTool(command.id))
});
});
// Add the save command
OHIF.commands.register(contextName, 'storeMeasurements', () => {
// Register the hotkey default
_.defaults(OHIF.hotkeys.defaults[contextName], { storeMeasurements: '' });
// 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 = OHIF.viewer.measurementApi.storeMeasurements();
promise.then(successHandler).catch(errorHandler);
OHIF.ui.showDialog('dialogLoading', {
promise,
text: 'Saving measurement data'
});
return promise;
});
});

View File

@ -246,7 +246,7 @@ class MeasurementApi {
});
}
storeMeasurements() {
storeMeasurements(timepointId) {
const storeFn = configuration.dataExchange.store;
if (!_.isFunction(storeFn)) {
return;
@ -263,7 +263,8 @@ class MeasurementApi {
});
});
const timepoints = this.timepointApi.all();
const timepointFilter = timepointId ? { timepointId } : {};
const timepoints = this.timepointApi.all(timepointFilter);
const timepointIds = timepoints.map(t => t.timepointId);
const patientId = timepoints[0].patientId;
const filter = {

View File

@ -13,7 +13,7 @@ Template.caseProgress.onCreated(() => {
Template.caseProgress.onRendered(() => {
const instance = Template.instance();
const { timepointApi, measurementApi } = instance.data;
const { timepointApi, measurementApi, timepointId } = instance.data;
// Stop here if we have no current timepoint ID (and therefore no defined timepointAPI)
if (!timepointApi) {
@ -22,8 +22,13 @@ Template.caseProgress.onRendered(() => {
}
// Get the current and prior timepoints
const current = timepointApi.current();
const prior = timepointApi.prior();
const current = timepointApi.timepoints.findOne({ timepointId });
const priorFilter = {
latestDate: { $lt: current.latestDate },
patientId: current.patientId
};
const priorSorting = { sort: { latestDate: -1 } };
const prior = timepointApi.timepoints.findOne(priorFilter, priorSorting);
// Stop here if timepoint is locked
if (current && current.isLocked) {

View File

@ -1,4 +1,4 @@
@import "{ohif:design}/app"
@require '{ohif:design}/app'
.caseProgress
transition(all 0.3 ease)
@ -14,7 +14,7 @@
h5
theme('color', '$textPrimaryColor')
line-height: 46px
line-height: 40px
margin: 0
font-size: 15px
font-weight: bold

View File

@ -1,27 +1,27 @@
<template name="radialProgressBar">
<div class="radialProgress">
<svg id="svg"
width="46"
height="46"
viewPort="0 0 50 50"
width="40"
height="40"
viewPort="0 0 40 40"
version="1.1"
xmlns="http://www.w3.org/2000/svg">
<!-- stroke-dasharray is 2 * PI * radius !-->
<circle r="21"
cx="23"
cy="23"
<circle r="18"
cx="20"
cy="20"
fill="transparent"
stroke-dasharray="131.9469"
stroke-dasharray="113.097335529232557"
stroke-dashoffset="0">
</circle>
{{#unless isLocked}}
<circle id="bar"
r="21"
cx="23"
cy="23"
r="18"
cx="20"
cy="20"
fill="transparent"
stroke-dasharray="131.9469"
stroke-dasharray="113.097335529232557"
style="stroke-dashoffset: {{progressRadius}}px;">
</circle>
{{/unless}}

View File

@ -1,3 +1,5 @@
import { Template } from 'meteor/templating';
Template.radialProgressBar.helpers({
progressComplete() {
const instance = Template.instance();
@ -5,9 +7,9 @@ Template.radialProgressBar.helpers({
},
progressRadius() {
var radius = 21 * 2 * Math.PI;
const instance = Template.instance();
var percentLeft = (100 - instance.data.progressPercent) / 100;
const radius = 18 * 2 * Math.PI;
const percentLeft = (100 - instance.data.progressPercent) / 100;
return percentLeft * radius;
}
});

View File

@ -1,6 +1,6 @@
@import "{ohif:design}/app"
@require '{ohif:design}/app'
$circleSize = 46px
$circleSize = 40px
.radialProgress
position: relative
@ -29,6 +29,7 @@ $circleSize = 46px
line-height: $circleSize
left: 50%
position: absolute
text-align: center
top: 50%
transform(translate(-50%, -50%))
width: $circleSize

View File

@ -1,4 +1,4 @@
@import "{ohif:design}/app"
@require '{ohif:design}/app'
#measurementTableContainer
theme('background-color', '$primaryBackgroundColor')
@ -7,7 +7,7 @@
.measurementTableTimepointHeaderRow
display: flex
padding: 2px 2px 0 44px
padding: 0 2px 0 44px
position: relative
.warning-status

View File

@ -6,5 +6,8 @@
<div class="timepointDate">
{{formatDA latestDate "DD-MMM-YY"}}
</div>
<div class="case-progress-container">
{{>caseProgress}}
</div>
</div>
</template>

View File

@ -1,10 +1,12 @@
@import "{ohif:design}/app"
@require '{ohif:design}/app'
.measurementTableTimepointHeader
flex: 1
justify-content: space-around
padding-top: 2px
position: relative
div
.timepointName, .timepointDate
theme('border-left', '%s solid $uiBorderColor' % $uiBorderThickness)
font-weight: 400
padding-left: 12px
@ -20,3 +22,8 @@
font-size: 14px
line-height: 20px
padding-bottom: 6px
.case-progress-container
position: absolute
right: 4px
top: 0

View File

@ -14,6 +14,7 @@ import './hangingProtocolCustomizations';
import './MeasurementHandlers';
import './MeasurementManager';
import './navigateOverLesions';
import './saveMeasurements';
import './syncMeasurementAndToolData';
import './toggleLabelButton';
import './triggerTimepointUnsavedChanges';

View File

@ -0,0 +1,31 @@
import { OHIF } from 'meteor/ohif:core';
OHIF.measurements.saveMeasurements = (measurementApi, timepointId) => {
const { unsavedChanges, notifications, showDialog } = OHIF.ui;
const basePath = `viewer.studyViewer.measurements.${timepointId}`;
// Stop here if there were no changes to the timepoint
if (unsavedChanges.probe(basePath) === 0) return;
// Clear unsaved changes state and display success message
const successHandler = () => {
unsavedChanges.clear(basePath, true);
notifications.success({ text: 'The measurement data was successfully saved' });
};
// Display the error messages
const errorHandler = data => {
showDialog('dialogInfo', Object.assign({ class: 'themed' }, data));
};
// Call the storage method and display a loading overlay
const promise = measurementApi.storeMeasurements(timepointId);
promise.then(successHandler).catch(errorHandler);
showDialog('dialogLoading', {
promise,
text: 'Saving measurement data'
});
// Return the save promise
return promise;
};