LT-92: Displaying global nonconformities warnings

This commit is contained in:
Bruno Alves de Faria 2017-01-17 16:40:51 -02:00
parent db4792b3de
commit efa18aeb1d
7 changed files with 77 additions and 21 deletions

View File

@ -6,6 +6,13 @@
</div>
{{/if}}
<div class="measurementTableTimepointHeaderRow">
{{#if hasWarnings}}
<div class="warning-status">
<svg>
<use xlink:href={{absoluteUrl "packages/ohif_viewerbase/assets/icons.svg#icon-ui-warning"}}></use>
</svg>
</div>
{{/if}}
{{#each timepoint in this.timepoints.get}}
{{>measurementTableTimepointHeader (clone this timepoint)}}
{{/each}}

View File

@ -1,6 +1,7 @@
import { OHIF } from 'meteor/ohif:core';
import { Template } from 'meteor/templating';
import { ReactiveVar } from 'meteor/reactive-var';
import { _ } from 'meteor/underscore';
import { OHIF } from 'meteor/ohif:core';
Template.measurementTable.onCreated(() => {
const instance = Template.instance();
@ -18,7 +19,7 @@ Template.measurementTable.onCreated(() => {
timepoints = [];
} else if (tableLayout === 'key') {
timepoints = instance.data.timepointApi.key();
} else {
} else {
timepoints = instance.data.timepointApi.currentAndPrior();
}
@ -49,6 +50,10 @@ Template.measurementTable.onRendered(() => {
});
Template.measurementTable.helpers({
hasWarnings() {
return Template.instance().data.conformanceCriteria.nonconformities.get();
},
buttonGroupData() {
const instance = Template.instance();
return {
@ -63,3 +68,19 @@ Template.measurementTable.helpers({
};
}
});
Template.measurementTable.events({
'click .warning-status'(event, instance) {
const nonconformities = instance.data.conformanceCriteria.nonconformities.get();
const messages = [];
_.each(nonconformities, nonconformity => messages.push(nonconformity.message));
OHIF.ui.showDialog('measurementTableWarningsDialog', {
messages,
position: {
x: event.clientX,
y: event.clientY
}
});
}
});

View File

@ -8,6 +8,35 @@
.measurementTableTimepointHeaderRow
display: flex
padding: 2px 2px 0 44px
position: relative
.warning-status
theme('border', '2px solid $uiYellow')
border-radius: 16px
cursor: pointer
height: 32px
left: 0
margin: 4px 6px
position: absolute
top: 0
transition(border-color 0.3s ease)
width: 32px
&:hover
theme('border-color', '$hoverColor')
svg
theme('fill', '$hoverColor')
svg
theme('fill', '$uiYellow')
height: 20px
left: 50%
position: absolute
top: 2px
transform(translateX(-50%) scale(0.9))
transition(all 0.3s ease)
width: 22px
.measurementTableLayoutChanger
margin: 0 auto

View File

@ -9,11 +9,11 @@ Template.measurementTableRow.onCreated(() => {
const measurementTypeId = instance.data.rowItem.measurementTypeId;
const measurementNumber = instance.data.rowItem.measurementNumber;
const groupedNonConformities = instance.data.conformanceCriteria.groupedNonConformities.get() || {};
const nonConformitiesByMeasurementTypeId = groupedNonConformities[measurementTypeId] || {};
const nonConformitiesByMeasurementNumbers = nonConformitiesByMeasurementTypeId.measurementNumbers || {};
const nonConformitiesByMeasurementNumber = nonConformitiesByMeasurementNumbers[measurementNumber] || {};
const nonconformitiesByMeasurementTypeId = groupedNonConformities[measurementTypeId] || {};
const nonconformitiesByMeasurementNumbers = nonconformitiesByMeasurementTypeId.measurementNumbers || {};
const nonconformitiesByMeasurementNumber = nonconformitiesByMeasurementNumbers[measurementNumber] || {};
return nonConformitiesByMeasurementNumber.messages || [];
return nonconformitiesByMeasurementNumber.messages || [];
};
});
@ -27,7 +27,6 @@ Template.measurementTableRow.events({
'click .measurementRowSidebar .warning-icon'(event, instance) {
event.stopPropagation();
OHIF.ui.showDialog('measurementTableWarningsDialog', {
title: 'Criteria Nonconformities',
messages: instance.getWarningMessages(),
position: {
x: event.clientX,

View File

@ -1,5 +1,5 @@
<template name="measurementTableWarningsDialog">
{{#dialogSimple (extend this dialogClass='modal-sm')}}
{{#dialogSimple (extend this dialogClass='modal-sm' title='Criteria nonconformities')}}
<ol>
{{#each message in this.messages}}
<li>{{message}}</li>

View File

@ -10,7 +10,7 @@ class ConformanceCriteria {
constructor(measurementApi, timepointApi) {
this.measurementApi = measurementApi;
this.timepointApi = timepointApi;
this.nonConformities = new ReactiveVar();
this.nonconformities = new ReactiveVar();
this.groupedNonConformities = new ReactiveVar();
const validate = _.debounce(trialCriteriaType => {
@ -35,22 +35,22 @@ class ConformanceCriteria {
const resultBoth = this.validateTimepoint('both', trialCriteriaType, mergedData);
const resultBaseline = this.validateTimepoint('baseline', trialCriteriaType, baselineData);
const resultFollowup = this.validateTimepoint('followup', trialCriteriaType, followupData);
const nonConformities = resultBaseline.concat(resultFollowup).concat(resultBoth);
const groupedNonConformities = this.groupNonConformities(nonConformities);
const nonconformities = resultBaseline.concat(resultFollowup).concat(resultBoth);
const groupedNonConformities = this.groupNonConformities(nonconformities);
// Keep both? Group the data only on viewer/measurementTable views?
// Work with not grouped data (worse lookup performance on measurementTableRow)?
this.nonConformities.set(nonConformities);
this.nonconformities.set(nonconformities);
this.groupedNonConformities.set(groupedNonConformities);
return nonConformities;
return nonconformities;
}
groupNonConformities(nonConformities) {
groupNonConformities(nonconformities) {
const groups = {};
const toolsGroupsMap = this.measurementApi.toolsGroupsMap;
nonConformities.forEach(nonConformity => {
nonconformities.forEach(nonConformity => {
if (nonConformity.isGlobal) {
groups.globals = groups.globals || { messages: [] };
groups.globals.messages.push(nonConformity.message);
@ -83,14 +83,14 @@ class ConformanceCriteria {
validateTimepoint(timepointId, trialCriteriaType, data) {
const evaluators = this.getEvaluators(timepointId, trialCriteriaType);
let nonConformities = [];
let nonconformities = [];
evaluators.forEach(evaluator => {
const result = evaluator.evaluate(data);
nonConformities = nonConformities.concat(result);
nonconformities = nonconformities.concat(result);
});
return nonConformities;
return nonconformities;
}
getEvaluators(timepointId, trialCriteriaType) {

View File

@ -58,14 +58,14 @@ export class CriteriaEvaluator {
}
evaluate(data) {
const nonConformities = [];
const nonconformities = [];
this.criteria.forEach(criterion => {
const criterionResult = criterion.evaluate(data);
if (!criterionResult.passed) {
nonConformities.push(criterionResult);
nonconformities.push(criterionResult);
}
});
return nonConformities;
return nonconformities;
}
}