LT-92: Displaying global nonconformities warnings
This commit is contained in:
parent
db4792b3de
commit
efa18aeb1d
@ -6,6 +6,13 @@
|
|||||||
</div>
|
</div>
|
||||||
{{/if}}
|
{{/if}}
|
||||||
<div class="measurementTableTimepointHeaderRow">
|
<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}}
|
{{#each timepoint in this.timepoints.get}}
|
||||||
{{>measurementTableTimepointHeader (clone this timepoint)}}
|
{{>measurementTableTimepointHeader (clone this timepoint)}}
|
||||||
{{/each}}
|
{{/each}}
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
import { OHIF } from 'meteor/ohif:core';
|
|
||||||
import { Template } from 'meteor/templating';
|
import { Template } from 'meteor/templating';
|
||||||
import { ReactiveVar } from 'meteor/reactive-var';
|
import { ReactiveVar } from 'meteor/reactive-var';
|
||||||
|
import { _ } from 'meteor/underscore';
|
||||||
|
import { OHIF } from 'meteor/ohif:core';
|
||||||
|
|
||||||
Template.measurementTable.onCreated(() => {
|
Template.measurementTable.onCreated(() => {
|
||||||
const instance = Template.instance();
|
const instance = Template.instance();
|
||||||
@ -18,7 +19,7 @@ Template.measurementTable.onCreated(() => {
|
|||||||
timepoints = [];
|
timepoints = [];
|
||||||
} else if (tableLayout === 'key') {
|
} else if (tableLayout === 'key') {
|
||||||
timepoints = instance.data.timepointApi.key();
|
timepoints = instance.data.timepointApi.key();
|
||||||
} else {
|
} else {
|
||||||
timepoints = instance.data.timepointApi.currentAndPrior();
|
timepoints = instance.data.timepointApi.currentAndPrior();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -49,6 +50,10 @@ Template.measurementTable.onRendered(() => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
Template.measurementTable.helpers({
|
Template.measurementTable.helpers({
|
||||||
|
hasWarnings() {
|
||||||
|
return Template.instance().data.conformanceCriteria.nonconformities.get();
|
||||||
|
},
|
||||||
|
|
||||||
buttonGroupData() {
|
buttonGroupData() {
|
||||||
const instance = Template.instance();
|
const instance = Template.instance();
|
||||||
return {
|
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
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|||||||
@ -8,6 +8,35 @@
|
|||||||
.measurementTableTimepointHeaderRow
|
.measurementTableTimepointHeaderRow
|
||||||
display: flex
|
display: flex
|
||||||
padding: 2px 2px 0 44px
|
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
|
.measurementTableLayoutChanger
|
||||||
margin: 0 auto
|
margin: 0 auto
|
||||||
|
|||||||
@ -9,11 +9,11 @@ Template.measurementTableRow.onCreated(() => {
|
|||||||
const measurementTypeId = instance.data.rowItem.measurementTypeId;
|
const measurementTypeId = instance.data.rowItem.measurementTypeId;
|
||||||
const measurementNumber = instance.data.rowItem.measurementNumber;
|
const measurementNumber = instance.data.rowItem.measurementNumber;
|
||||||
const groupedNonConformities = instance.data.conformanceCriteria.groupedNonConformities.get() || {};
|
const groupedNonConformities = instance.data.conformanceCriteria.groupedNonConformities.get() || {};
|
||||||
const nonConformitiesByMeasurementTypeId = groupedNonConformities[measurementTypeId] || {};
|
const nonconformitiesByMeasurementTypeId = groupedNonConformities[measurementTypeId] || {};
|
||||||
const nonConformitiesByMeasurementNumbers = nonConformitiesByMeasurementTypeId.measurementNumbers || {};
|
const nonconformitiesByMeasurementNumbers = nonconformitiesByMeasurementTypeId.measurementNumbers || {};
|
||||||
const nonConformitiesByMeasurementNumber = nonConformitiesByMeasurementNumbers[measurementNumber] || {};
|
const nonconformitiesByMeasurementNumber = nonconformitiesByMeasurementNumbers[measurementNumber] || {};
|
||||||
|
|
||||||
return nonConformitiesByMeasurementNumber.messages || [];
|
return nonconformitiesByMeasurementNumber.messages || [];
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -27,7 +27,6 @@ Template.measurementTableRow.events({
|
|||||||
'click .measurementRowSidebar .warning-icon'(event, instance) {
|
'click .measurementRowSidebar .warning-icon'(event, instance) {
|
||||||
event.stopPropagation();
|
event.stopPropagation();
|
||||||
OHIF.ui.showDialog('measurementTableWarningsDialog', {
|
OHIF.ui.showDialog('measurementTableWarningsDialog', {
|
||||||
title: 'Criteria Nonconformities',
|
|
||||||
messages: instance.getWarningMessages(),
|
messages: instance.getWarningMessages(),
|
||||||
position: {
|
position: {
|
||||||
x: event.clientX,
|
x: event.clientX,
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
<template name="measurementTableWarningsDialog">
|
<template name="measurementTableWarningsDialog">
|
||||||
{{#dialogSimple (extend this dialogClass='modal-sm')}}
|
{{#dialogSimple (extend this dialogClass='modal-sm' title='Criteria nonconformities')}}
|
||||||
<ol>
|
<ol>
|
||||||
{{#each message in this.messages}}
|
{{#each message in this.messages}}
|
||||||
<li>{{message}}</li>
|
<li>{{message}}</li>
|
||||||
|
|||||||
@ -10,7 +10,7 @@ class ConformanceCriteria {
|
|||||||
constructor(measurementApi, timepointApi) {
|
constructor(measurementApi, timepointApi) {
|
||||||
this.measurementApi = measurementApi;
|
this.measurementApi = measurementApi;
|
||||||
this.timepointApi = timepointApi;
|
this.timepointApi = timepointApi;
|
||||||
this.nonConformities = new ReactiveVar();
|
this.nonconformities = new ReactiveVar();
|
||||||
this.groupedNonConformities = new ReactiveVar();
|
this.groupedNonConformities = new ReactiveVar();
|
||||||
|
|
||||||
const validate = _.debounce(trialCriteriaType => {
|
const validate = _.debounce(trialCriteriaType => {
|
||||||
@ -35,22 +35,22 @@ class ConformanceCriteria {
|
|||||||
const resultBoth = this.validateTimepoint('both', trialCriteriaType, mergedData);
|
const resultBoth = this.validateTimepoint('both', trialCriteriaType, mergedData);
|
||||||
const resultBaseline = this.validateTimepoint('baseline', trialCriteriaType, baselineData);
|
const resultBaseline = this.validateTimepoint('baseline', trialCriteriaType, baselineData);
|
||||||
const resultFollowup = this.validateTimepoint('followup', trialCriteriaType, followupData);
|
const resultFollowup = this.validateTimepoint('followup', trialCriteriaType, followupData);
|
||||||
const nonConformities = resultBaseline.concat(resultFollowup).concat(resultBoth);
|
const nonconformities = resultBaseline.concat(resultFollowup).concat(resultBoth);
|
||||||
const groupedNonConformities = this.groupNonConformities(nonConformities);
|
const groupedNonConformities = this.groupNonConformities(nonconformities);
|
||||||
|
|
||||||
// Keep both? Group the data only on viewer/measurementTable views?
|
// Keep both? Group the data only on viewer/measurementTable views?
|
||||||
// Work with not grouped data (worse lookup performance on measurementTableRow)?
|
// Work with not grouped data (worse lookup performance on measurementTableRow)?
|
||||||
this.nonConformities.set(nonConformities);
|
this.nonconformities.set(nonconformities);
|
||||||
this.groupedNonConformities.set(groupedNonConformities);
|
this.groupedNonConformities.set(groupedNonConformities);
|
||||||
|
|
||||||
return nonConformities;
|
return nonconformities;
|
||||||
}
|
}
|
||||||
|
|
||||||
groupNonConformities(nonConformities) {
|
groupNonConformities(nonconformities) {
|
||||||
const groups = {};
|
const groups = {};
|
||||||
const toolsGroupsMap = this.measurementApi.toolsGroupsMap;
|
const toolsGroupsMap = this.measurementApi.toolsGroupsMap;
|
||||||
|
|
||||||
nonConformities.forEach(nonConformity => {
|
nonconformities.forEach(nonConformity => {
|
||||||
if (nonConformity.isGlobal) {
|
if (nonConformity.isGlobal) {
|
||||||
groups.globals = groups.globals || { messages: [] };
|
groups.globals = groups.globals || { messages: [] };
|
||||||
groups.globals.messages.push(nonConformity.message);
|
groups.globals.messages.push(nonConformity.message);
|
||||||
@ -83,14 +83,14 @@ class ConformanceCriteria {
|
|||||||
|
|
||||||
validateTimepoint(timepointId, trialCriteriaType, data) {
|
validateTimepoint(timepointId, trialCriteriaType, data) {
|
||||||
const evaluators = this.getEvaluators(timepointId, trialCriteriaType);
|
const evaluators = this.getEvaluators(timepointId, trialCriteriaType);
|
||||||
let nonConformities = [];
|
let nonconformities = [];
|
||||||
|
|
||||||
evaluators.forEach(evaluator => {
|
evaluators.forEach(evaluator => {
|
||||||
const result = evaluator.evaluate(data);
|
const result = evaluator.evaluate(data);
|
||||||
nonConformities = nonConformities.concat(result);
|
nonconformities = nonconformities.concat(result);
|
||||||
});
|
});
|
||||||
|
|
||||||
return nonConformities;
|
return nonconformities;
|
||||||
}
|
}
|
||||||
|
|
||||||
getEvaluators(timepointId, trialCriteriaType) {
|
getEvaluators(timepointId, trialCriteriaType) {
|
||||||
|
|||||||
@ -58,14 +58,14 @@ export class CriteriaEvaluator {
|
|||||||
}
|
}
|
||||||
|
|
||||||
evaluate(data) {
|
evaluate(data) {
|
||||||
const nonConformities = [];
|
const nonconformities = [];
|
||||||
this.criteria.forEach(criterion => {
|
this.criteria.forEach(criterion => {
|
||||||
const criterionResult = criterion.evaluate(data);
|
const criterionResult = criterion.evaluate(data);
|
||||||
if (!criterionResult.passed) {
|
if (!criterionResult.passed) {
|
||||||
nonConformities.push(criterionResult);
|
nonconformities.push(criterionResult);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
return nonConformities;
|
return nonconformities;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user