LT-253: Added Collection to store Additional Findings in the database. Set up some form components that store temporary UI state

This commit is contained in:
Erik Ziegler committed 2016-07-22 11:12:04 +02:00
1 parent 022c534895
commit 40062e2e9d
35 files changed
+599 -216

No files matched your search

@@ -1,48 +1,34 @@
<template name="additionalMeasurements">
<div id="additionalMeasurements">
<template name="additionalFindings">
<div class="additionalFindings">
<div class="scrollArea">
<div class="section">
<div class="row">
<div class="header">
Additional Findings: Baseline
</div>
<div>
{{ >radioOptionGroup measurableDiseaseButtonData}}
</div>
{{> radioOptionGroup (stateDataWithKey "measurableDisease")}}
</div>
<div class="section">
<div class="row">
<div class="header">
Supplementary Measurements
</div>
<div class="entrySection">
<label>Number of bone lesions</label>
<div>
<select>
<option>0</option>
<option>1-2</option>
<option selected>2-4</option>
<option>>5</option>
</select>
</div>
</div>
<div class="entrySection">
<label>Regions of metastatic disease</label>
<select id="regionsOfMetastaticDisease">
<option>None</option>
<option>Lymph node</option>
</select>
</div>
{{ >radioOptionGroup metastaticDiseaseButtonData}}
{{> selectInput (stateDataWithKey "numberOfBoneLesions")}}
{{> select2Input
key="regionsOfMetastaticDisease"
select2Options=regionsOfMetastaticDiseaseSelect2Options
state=state
currentSchema=currentSchema
}}
{{> radioOptionGroup (stateDataWithKey "tracerRelatedToMetastaticDisease")}}
</div>
<div class="section">
<div class="row">
<div class="header">
Image Quality
</div>
{{ >radioOptionGroup imageQualityButtonData}}
{{ >radioOptionGroup anatomicalCoverageButtonData}}
{{ >radioOptionGroup presenceOfContrastButtonData}}
{{> radioOptionGroup (stateDataWithKey "acceptableImageQuality")}}
{{> radioOptionGroup (stateDataWithKey "adequateAnatomicalCoverage")}}
{{> radioOptionGroup (stateDataWithKey "presenceOfContrast")}}
</div>
<div class="section">
<div class="row">
<div class="header">
Additional Screen Captures
</div>
@@ -57,7 +43,7 @@
</div>
</div>
</div>
<div class="section">
<div class="row">
<div class="header">
Comments
</div>
@@ -0,0 +1,82 @@
import { Template } from 'meteor/templating';
import { ReactiveDict } from 'meteor/reactive-dict';
// TODO: Check why I can't use absolute paths for this? Keeps saying module not found
import { AdditionalFinding } from '../../../both/schema/additionalFinding';
Template.additionalFindings.onCreated(function additionalFindingsOnCreated() {
console.log('additionalFindingsOnCreated');
const instance = Template.instance();
instance.currentSchema = AdditionalFinding;
instance.state = new ReactiveDict();
if (!instance.data.currentTimepointId) {
console.warn('Case has no timepointId');
return;
}
const currentTimepointId = instance.data.currentTimepointId;
if (!currentTimepointId) {
console.warn('No currentTimepointId');
}
console.log(AdditionalFindings.find().fetch());
const additionalFindings = AdditionalFindings.findOne({
timepointId: currentTimepointId
});
if (additionalFindings) {
instance.id = additionalFindings._id;
// Don't store the MongoDB Id in the ReactiveDict
delete additionalFindings._id;
instance.state.set(additionalFindings);
} else {
const defaultData = instance.currentSchema.clean({});
instance.state.set(defaultData);
// Include patientId and timepointId
defaultData.patientId = Session.get('patientId');
defaultData.timepointId = currentTimepointId;
// TODO: Turn this into a Meteor Call to insert it on the server
instance.id = AdditionalFindings.insert(defaultData);
}
});
Template.additionalFindings.onRendered(function additionalFindingsOnRendered() {
const instance = Template.instance();
instance.autorun(() => {
console.log('Updating AdditionalFindings Collection');
console.log(instance.state.all());
// TODO: Turn this into a Meteor Call to update it on the server
let update = instance.state.all();
AdditionalFindings.update(instance.id, {
$set: update
});
});
});
Template.additionalFindings.helpers({
// We need these helper methods
// since we assign them into instance object instead of instance.data
currentSchema() {
return Template.instance().currentSchema;
},
state() {
return Template.instance().state;
},
regionsOfMetastaticDiseaseSelect2Options() {
return {
placeholder: 'Search Regions',
allowClear: true,
multiple: true
};
}
});
@@ -1,6 +1,6 @@
@import "{design}/app"
#additionalMeasurements
.additionalFindings
width: 100%
height: 100%
background-color: #000000
@@ -15,6 +15,10 @@
-webkit-overflow-scrolling: touch
.row
margin-right: 0
margin-left: 0
&::-webkit-scrollbar
display: none
@@ -27,7 +31,47 @@
color: $textPrimaryColor
background-color: $uiGrayDarker
.entrySection
.form-group
padding: 10px
color: $textPrimaryColor
&:not(:last-child)
border-bottom: $uiBorderThickness solid $uiBorderColorDark
h5
font-weight: 300
label
font-size: 14px
font-weight: 100
display: inline-block
padding: 5px
.radio-group
height: 30px
.radio-option
width: 50%
text-align: center
float: left
display: inline-block
padding: 5px
height: 30px
input
float: left
height: 30px
width: 30px
display: inline-block
label
float: left
height: 30px
line-height: 30px
font-size: 14px
font-weight: 100
display: inline-block
#regionsOfMetastaticDisease
width: 285px
height: 30px
@@ -1,87 +0,0 @@
var yesNoOptions = [{
key: 'yes',
text: 'Yes'
}, {
key: 'no',
text: 'No'
}];
Template.additionalMeasurements.onCreated(function additionalMeasurementsOnCreated() {
const instance = this;
instance.measurableDisease = new ReactiveVar();
instance.numberOfBoneLesions = new ReactiveVar();
instance.regionsOfMetastaticDisease = new ReactiveVar();
instance.tracerRelatedToMetastaticDisease = new ReactiveVar();
instance.acceptableImageQuality = new ReactiveVar();
instance.adequateAnatomicalCoverage = new ReactiveVar();
instance.presenceOfContrast = new ReactiveVar();
instance.phaseOfContrast = new ReactiveVar();
instance.measurableDisease.set('absent');
instance.tracerRelatedToMetastaticDisease.set('no');
instance.acceptableImageQuality.set('yes');
instance.adequateAnatomicalCoverage.set('yes');
instance.presenceOfContrast.set('yes');
});
Template.additionalMeasurements.onRendered(function additionalMeasurementsOnRendered() {
const instance = this;
instance.$("#regionsOfMetastaticDisease").select2({
multiple: true
});
});
Template.additionalMeasurements.helpers({
measurableDiseaseButtonData() {
const instance = Template.instance();
return {
text: 'Measurable disease',
value: instance.measurableDisease,
options: [{
key: 'present',
text: 'Present'
}, {
key: 'absent',
text: 'Absent'
}]
};
},
metastaticDiseaseButtonData() {
const instance = Template.instance();
return {
text: 'Tracer related to metastatic disease',
value: instance.tracerRelatedToMetastaticDisease,
options: yesNoOptions
};
},
imageQualityButtonData() {
const instance = Template.instance();
return {
text: 'Acceptable image quality',
value: instance.acceptableImageQuality,
options: yesNoOptions
};
},
anatomicalCoverageButtonData() {
const instance = Template.instance();
return {
text: 'Adequate anatomical coverage',
value: instance.adequateAnatomicalCoverage,
options: yesNoOptions
};
},
presenceOfContrastButtonData() {
const instance = Template.instance();
return {
text: 'Presence of contrast',
value: instance.presenceOfContrast,
options: yesNoOptions
};
}
});
@@ -1,16 +0,0 @@
<template name="radioOptionGroup">
<div class="{{class}} entrySection viewerRadioOptionGroup">
<h5>{{text}}</h5>
<div>
{{#each item in this.options}}
<label>
<input type="radio"
name="{{item.key}}"
data-key="{{item.key}}"
{{inlineIf value.get item.key 'selected'}}/>
{{item.text}}
</label>
{{/each}}
</div>
</div>
</template>
@@ -1,15 +0,0 @@
Template.radioOptionGroup.onRendered(() => {
const instance = Template.instance();
const value = instance.data.value;
if (!value.get()) {
value.set(instance.data.options[0].key);
}
});
Template.radioOptionGroup.events({
'click [data-key]'(event, instance) {
const $element = $(event.currentTarget);
const key = $element.attr('data-key');
instance.data.value.set(key);
}
});
@@ -1,20 +0,0 @@
@import "{design}/app"
.entrySection
padding: 10px
color: $textPrimaryColor
&:not(:last-child)
border-bottom: $uiBorderThickness solid $uiBorderColorDark
h5
font-weight: 300
label
font-size: 14px
font-weight: 100
display: inline-block
padding: 5px
input
margin: 5px
@@ -6,12 +6,12 @@
<div class="mainContent {{#if leftSidebarOpen}}sidebar-left-open{{/if}} {{#if rightSidebarOpen}}sidebar-right-open{{/if}}">
{{>viewerMain}}
</div>
<div class="sidebarMenu sidebar-right {{#if or lesionSidebarOpen additionalMeasurementsSidebarOpen}}sidebar-open{{/if}}">
<div class="sidebarMenu sidebar-right {{#if or lesionSidebarOpen additionalFindingsSidebarOpen}}sidebar-open{{/if}}">
<div class="sidebar-option {{#if lesionSidebarOpen}}active{{/if}}">
{{>lesionTable (extend this)}}
</div>
<div class="sidebar-option {{#if additionalMeasurementsSidebarOpen}}active{{/if}}">
{{>additionalMeasurements (extend this)}}
<div class="sidebar-option {{#if additionalFindingsSidebarOpen}}active{{/if}}">
{{>additionalFindings (extend this)}}
</div>
</div>
</div>
@@ -17,7 +17,7 @@ Template.flexboxLayout.helpers({
return Template.instance().data.state.get('rightSidebar') === 'lesions';
},
additionalMeasurementsSidebarOpen() {
additionalFindingsSidebarOpen() {
return Template.instance().data.state.get('rightSidebar') === 'additional';
},
@@ -4,7 +4,7 @@
display: flex
flex-flow: row nowrap
align-items: stretch
height: 100%
height: calc(100% - 78px);
width: 100%
.sidebarMenu
@@ -34,33 +34,11 @@
{{/if}}
<div class="toolbarSectionEntry pull-right rm-l-1 p-x-1">
{{ >caseProgress }}
{{> caseProgress }}
</div>
<div class="pull-right m-t-1 rm-x-1">
{{>roundedButtonGroup rightSidebarToggleButtonData}}
</div>
<!-- <div class="capsule-group pull-right">
<div id="lesionSidebarToggle" class="capsule-entry">
<div class="svgContainer capsule">
<svg>
<use xlink:href="/packages/lesiontracker/assets/icons.svg#icon-measurements-lesions"></use>
</svg>
</div>
<div class="buttonLabel">
Lesions
</div>
</div>
<div id="additionalMeasurementsSidebarToggle" class="capsule-entry">
<div class="svgContainer capsule">
<svg>
<use xlink:href="/packages/lesiontracker/assets/icons.svg#icon-measurements-additional"></use>
</svg>
</div>
<div class="buttonLabel">
Additional
</div>
</div>
</div> -->
<div id="toggleHUD" class="toolbarSectionButton pull-right rp-x-1 m-t-1 rm-r-3">
<div class="svgContainer">
<svg>
@@ -127,6 +127,7 @@ Template.viewer.onCreated(function() {
instance.subscribe('singlePatientTimepoints', dataContext.studies[0].patientId);
instance.subscribe('singlePatientMeasurements', dataContext.studies[0].patientId);
instance.subscribe('singlePatientImageMeasurements', dataContext.studies[0].patientId);
instance.subscribe('singlePatientAdditionalFindings', dataContext.studies[0].patientId);
var subscriptionsReady = instance.subscriptionsReady();
log.info('autorun viewer.js. Ready: ' + subscriptionsReady);