From 62f102617f1b08c24e6e380f7cfeeb04e7703975 Mon Sep 17 00:00:00 2001 From: Erik Ziegler Date: Mon, 15 Aug 2016 11:29:49 +0200 Subject: [PATCH] Fixes for current case status and Lesion Tracker measurement table behaviour (LT-248) --- .../lesiontracker/client/api/measurement.js | 102 ++++++++++++++++++ .../{lib => client}/api/timepoint.js | 42 ++++++-- .../components/caseProgress/caseProgress.js | 40 +++---- .../components/lesionTable/lesionTable.js | 12 +-- .../lesionTableHUD/lesionTableHUD.js | 2 +- .../lesionTableHeaderRow.html | 4 +- .../lesionTableHeaderRow.js | 43 +++++--- .../lesionTableHeaderRow.styl | 8 +- .../lesionTableView/lesionTableView.html | 15 ++- .../lesionTableView/lesionTableView.js | 35 +++--- .../radialProgressBar/radialProgressBar.styl | 2 +- .../studyAssociationTable.html | 2 +- .../toolbarSection/toolbarSection.js | 5 +- .../client/components/viewer/viewer.js | 16 ++- .../lib/handleMeasurementAdded.js | 3 +- .../lib/handleMeasurementRemoved.js | 2 +- Packages/lesiontracker/package.js | 3 +- 17 files changed, 244 insertions(+), 92 deletions(-) create mode 100644 Packages/lesiontracker/client/api/measurement.js rename Packages/lesiontracker/{lib => client}/api/timepoint.js (74%) diff --git a/Packages/lesiontracker/client/api/measurement.js b/Packages/lesiontracker/client/api/measurement.js new file mode 100644 index 000000000..f0e4336d9 --- /dev/null +++ b/Packages/lesiontracker/client/api/measurement.js @@ -0,0 +1,102 @@ +const hasValueAtTimepoint = timepointId => { + return measurement => { + if (measurement.timepoints[timepointId]) { + return true; + } + }; +}; + +const hasNoValueAtTimepoint = timepointId => { + return measurement => { + if (measurement.timepoints[timepointId] === undefined) { + return true; + } + }; +}; + +export const MeasurementApi = { + sortOptions: { + sort: { + lesionNumberAbsolute: 1 + } + }, + + // Return all Measurements + all(withPriors=false) { + let data = Measurements.find({}, this.sortOptions).fetch(); + + // If we don't have a prior for this Timepoint, + // this filter, we should just return all of the + // available Non-Targets measurements + if (this.priorTimepointId && withPriors === true) { + return data.filter(hasValueAtTimepoint(this.priorTimepointId)) + } + + return data; + }, + + unmarked() { + const withPriors = true; + return this.all(withPriors).filter(hasNoValueAtTimepoint(this.currentTimepointId));; + }, + + unmarkedTargets() { + const withPriors = true; + return this.targets(withPriors).filter(hasNoValueAtTimepoint(this.currentTimepointId));; + }, + + unmarkedNonTargets() { + const withPriors = true; + return this.nonTargets(withPriors).filter(hasNoValueAtTimepoint(this.currentTimepointId));; + }, + + // Return only Target Measurements + targets(withPriors=false) { + let data = Measurements.find({ + isTarget: true + }, this.sortOptions).fetch(); + + // If we don't have a prior for this Timepoint, + // this filter, we should just return all of the + // available Non-Targets measurements + if (this.priorTimepointId && withPriors === true) { + return data.filter(hasValueAtTimepoint(this.priorTimepointId)) + } + + return data; + }, + + // Return only Non-Target Measurements + nonTargets(withPriors=false) { + let data = Measurements.find({ + isTarget: false + }, this.sortOptions).fetch(); + + // If we don't have a prior for this Timepoint, + // this filter, we should just return all of the + // available Non-Targets measurements + if (this.priorTimepointId && withPriors === true) { + return data.filter(hasValueAtTimepoint(this.priorTimepointId)) + } + + return data; + }, + + // Return only New Lesions + newLesions() { + // If we are current editing a Baseline we won't have any priors, so newLesions + // should return an empty array. + if (!this.priorTimepointId) { + return []; + } + + // Find only lesions that have no value at the previous timepoint + return this.all().filter(hasNoValueAtTimepoint(this.priorTimepointId)); + }, + + firstLesion() { + return Measurements.findOne({ + target: true + }, this.sortOptions); + } +}; diff --git a/Packages/lesiontracker/lib/api/timepoint.js b/Packages/lesiontracker/client/api/timepoint.js similarity index 74% rename from Packages/lesiontracker/lib/api/timepoint.js rename to Packages/lesiontracker/client/api/timepoint.js index 21b5beb1f..5499da0ee 100644 --- a/Packages/lesiontracker/lib/api/timepoint.js +++ b/Packages/lesiontracker/client/api/timepoint.js @@ -19,12 +19,42 @@ class TimepointApi { return this.timepoints.find().fetch(); } - // Return only the current and prior timepoints - latest() { - const options = { - limit: 2 - }; - return this.timepoints.find({}, options).fetch(); + // Return only the current timepoint + current() { + return this.timepoints.findOne({ + timepointId: this.currentTimepointId + }); + } + + prior() { + const latestDate = this.current().latestDate; + return this.timepoints.findOne({ + latestDate: { + $lt: latestDate + } + }, { + sort: { + latestDate: -1 + }, + }); + } + + // Return only the current and prior Timepoints + currentAndPrior() { + let timepoints = [this.current()]; + const prior = this.prior(); + if (prior) { + timepoints.push(prior); + } + + return timepoints; + } + + // Return only the baseline timepoint + baseline() { + return this.timepoints.findOne({ + timepointType: 'baseline' + }); } // Return only the key timepoints (current, prior, nadir and baseline) diff --git a/Packages/lesiontracker/client/components/caseProgress/caseProgress.js b/Packages/lesiontracker/client/components/caseProgress/caseProgress.js index c5a630ea9..0f7303aa8 100644 --- a/Packages/lesiontracker/client/components/caseProgress/caseProgress.js +++ b/Packages/lesiontracker/client/components/caseProgress/caseProgress.js @@ -1,45 +1,37 @@ +import { MeasurementApi } from 'meteor/lesiontracker/client/api/measurement'; + Template.caseProgress.onCreated(() => { const instance = Template.instance(); instance.progressPercent = new ReactiveVar(); instance.progressText = new ReactiveVar(); instance.isLocked = new ReactiveVar(); - - if (!instance.data.currentTimepointId) { + + const current = instance.data.timepointApi.current(); + if (!current.timepointId) { console.warn('Case has no timepointId'); return; } - const currentTimepointId = instance.data.currentTimepointId; - const timepoint = Timepoints.findOne({ - timepointId: currentTimepointId - }); + instance.isLocked.set(current.isLocked); - const timepointType = timepoint.timepointType; + // Retrieve the initial number of targets left to measure at this + // follow-up. Note that this is done outside of the reactive function + // below so that new lesions don't change the initial target count. + const withPriors = true; + const totalTargets = MeasurementApi.targets(withPriors).length; - instance.isLocked.set(timepoint.isLocked); - - if (timepointType === 'baseline') { + // If we're currently reviewing a Baseline timepoint, don't do any + // progress measurement. + if (current.timepointType === 'baseline') { instance.progressPercent.set(100); } else { - // Retrieve the initial number of targets left to measure at this - // follow-up. Note that this is done outside of the reactive function - // below so that new lesions don't change the initial target count. - const totalTargets = Measurements.find({ - isTarget: true - }).count(); - // Setup a reactive function to update the progress whenever // a measurement is made instance.autorun(() => { // Obtain the number of Measurements for which the current Timepoint has // no Measurement data - let numRemainingMeasurements = 0; - Measurements.find().forEach(measurement => { - if (!measurement.timepoints[currentTimepointId]) { - numRemainingMeasurements++; - } - }); + const numRemainingMeasurements = MeasurementApi.unmarked().length; // Update the Case Progress text with the remaining measurement count instance.progressText.set(numRemainingMeasurements); @@ -67,7 +59,7 @@ Template.caseProgress.helpers({ }, progressComplete() { - let progressPercent = Template.instance().progressPercent.get(); + const progressPercent = Template.instance().progressPercent.get(); return progressPercent === 100; } }); diff --git a/Packages/lesiontracker/client/components/lesionTable/lesionTable.js b/Packages/lesiontracker/client/components/lesionTable/lesionTable.js index 1e8e1e210..cc4b6f417 100644 --- a/Packages/lesiontracker/client/components/lesionTable/lesionTable.js +++ b/Packages/lesiontracker/client/components/lesionTable/lesionTable.js @@ -1,3 +1,5 @@ +import { MeasurementApi } from 'meteor/lesiontracker/client/api/measurement'; + Template.lesionTable.onCreated(() => { const instance = Template.instance(); @@ -13,7 +15,7 @@ Template.lesionTable.onCreated(() => { if (tableLayout === 'key') { timepoints = instance.data.timepointApi.key(); } else { - timepoints = instance.data.timepointApi.latest(); + timepoints = instance.data.timepointApi.currentAndPrior(); } // Return key timepoints @@ -47,14 +49,10 @@ Session.setDefault('NewSeriesLoaded', false); Template.lesionTable.onRendered(() => { // Find the first measurement by Lesion Number - var firstLesion = Measurements.findOne({}, { - sort: { - lesionNumber: 1 - } - }); + const firstLesion = MeasurementApi.firstLesion(); // Create an object to store the ContentId inside - var templateData = { + const templateData = { contentId: Session.get('activeContentId') }; diff --git a/Packages/lesiontracker/client/components/lesionTableHUD/lesionTableHUD.js b/Packages/lesiontracker/client/components/lesionTableHUD/lesionTableHUD.js index 6fb869383..3a019ac97 100644 --- a/Packages/lesiontracker/client/components/lesionTableHUD/lesionTableHUD.js +++ b/Packages/lesiontracker/client/components/lesionTableHUD/lesionTableHUD.js @@ -1,7 +1,7 @@ Template.lesionTableHUD.onCreated(() => { const instance = Template.instance(); - instance.data.timepoints = new ReactiveVar(instance.data.timepointApi.latest()); + instance.data.timepoints = new ReactiveVar(instance.data.timepointApi.currentAndPrior()); }); Template.lesionTableHUD.onRendered(() => { diff --git a/Packages/lesiontracker/client/components/lesionTableHeaderRow/lesionTableHeaderRow.html b/Packages/lesiontracker/client/components/lesionTableHeaderRow/lesionTableHeaderRow.html index 055b6f2b3..bef8e048a 100644 --- a/Packages/lesiontracker/client/components/lesionTableHeaderRow/lesionTableHeaderRow.html +++ b/Packages/lesiontracker/client/components/lesionTableHeaderRow/lesionTableHeaderRow.html @@ -1,14 +1,16 @@