diff --git a/js/components/cohortbuilder/CohortExpression.js b/js/components/cohortbuilder/CohortExpression.js index e5df5af3a..625de0bbf 100644 --- a/js/components/cohortbuilder/CohortExpression.js +++ b/js/components/cohortbuilder/CohortExpression.js @@ -27,10 +27,28 @@ define(function (require, exports) { self.CensoringCriteria = ko.observableArray(data.CensoringCriteria && data.CensoringCriteria.map(function (criteria) { return CriteriaTypes.GetCriteriaFromObject(criteria, self.ConceptSets); })); - self.CollapseSettings = {CollapseType: ko.observable(data.CollapseSettings && data.CollapseSettings.CollapseType || "ERA"), EraPad: ko.observable(data.CollapseSettings && data.CollapseSettings.EraPad || 0 ) } + self.CollapseSettings = { + CollapseType: ko.observable(data.CollapseSettings && data.CollapseSettings.CollapseType || "ERA"), + EraPad: ko.observable(data.CollapseSettings && data.CollapseSettings.EraPad || 0 ), + EraPadUnitValue: ko.observable(data.CollapseSettings && data.CollapseSettings.EraPadUnitValue || data.CollapseSettings && data.CollapseSettings.EraPad || 0), + EraPadUnit: ko.observable(data.CollapseSettings && data.CollapseSettings.EraPadUnit || 'day') + } self.CensorWindow = ko.observable(new Period(data.CensorWindow)); self.cdmVersionRange = data.cdmVersionRange || null; + + self.CollapseSettings.EraPadUnitValue.subscribe(function (newValue){ + const insertValue = newValue.toString().replace(/[\D\.]/g, ''); + self.CollapseSettings.EraPadUnitValue(insertValue ? Number(insertValue) : 0); + self.CollapseSettings.EraPadUnit() === 'day' && self.CollapseSettings.EraPad(insertValue ? Number(insertValue) : 0); + }) + + self.CollapseSettings.EraPadUnit.subscribe(function (newValue){ + self.CollapseSettings.EraPad(newValue === 'day' ? self.CollapseSettings.EraPadUnitValue() : 0); + }) + + self.UseDatetime = ko.observable(!!data.UseDatetime); + } return CohortExpression; }); \ No newline at end of file diff --git a/js/components/cohortbuilder/CriteriaTypes/Criteria.js b/js/components/cohortbuilder/CriteriaTypes/Criteria.js index e204c5851..ec2407f06 100644 --- a/js/components/cohortbuilder/CriteriaTypes/Criteria.js +++ b/js/components/cohortbuilder/CriteriaTypes/Criteria.js @@ -8,7 +8,7 @@ define(['require', 'knockout', '../InputTypes/Range','conceptpicker/InputTypes/C self.CorrelatedCriteria = ko.observable(data.CorrelatedCriteria && new CriteriaGroup(data.CorrelatedCriteria, conceptSets)); self.DateAdjustment = ko.observable(data.DateAdjustment && new DateAdjustment(data.DateAdjustment)); - + self.IntervalUnit = data.IntervalUnit; } return Criteria; diff --git a/js/components/cohortbuilder/EndStrategies/CustomEraStrategy.js b/js/components/cohortbuilder/EndStrategies/CustomEraStrategy.js index 4a6addddb..17515868f 100644 --- a/js/components/cohortbuilder/EndStrategies/CustomEraStrategy.js +++ b/js/components/cohortbuilder/EndStrategies/CustomEraStrategy.js @@ -6,7 +6,11 @@ define(['knockout'], function (ko) { self.DrugCodesetId = ko.observable(data.DrugCodesetId); self.GapDays = ko.observable(data.GapDays || 0); + self.GapUnit = ko.observable(data.GapUnit || 'day'); + self.GapUnitValue = ko.observable(data.GapUnitValue || 0); self.Offset = ko.observable(data.Offset || 0); + self.OffsetUnitValue = ko.observable(data.OffsetUnitValue || 0); + self.OffsetUnit = ko.observable(data.OffsetUnit || 'day'); self.DaysSupplyOverride = ko.observable(data.DaysSupplyOverride); // set up subscription to update DrugCodesetId if the item is removed from conceptSets @@ -18,6 +22,50 @@ define(['knockout'], function (ko) { } }); }, null, "arrayChange"); + + self.OffsetUnitValue.subscribe(function (newValue){ + const insertValue = newValue.toString().replace(/[\D\.]/g, ''); + self.OffsetUnitValue(insertValue ? Number(insertValue) : 0); + self.OffsetUnit() === 'day' && self.Offset(insertValue ? Number(insertValue) : 0); + }) + + self.OffsetUnit.subscribe(function (newValue){ + self.GapUnit(newValue); + self.Offset(newValue === 'day' ? self.OffsetUnitValue() : 0); + }) + + self.GapUnitValue.subscribe(function (newValue){ + const insertValue = newValue.toString().replace(/[\D\.]/g, ''); + self.GapUnitValue(insertValue ? Number(insertValue) : 0); + self.GapUnit() === 'day' && self.GapDays(insertValue ? Number(insertValue) : 0); + }) + + self.GapUnit.subscribe(function (newValue){ + self.OffsetUnit(newValue); + self.GapDays(newValue === 'day' ? self.GapUnitValue() : 0); + }) + + self.OffsetUnitValue.subscribe(function (newValue){ + const insertValue = newValue.toString().replace(/[\D\.]/g, ''); + self.OffsetUnitValue(insertValue ? Number(insertValue) : 0); + self.OffsetUnit() === 'day' && self.Offset(insertValue ? Number(insertValue) : 0); + }) + + self.OffsetUnit.subscribe(function (newValue){ + self.GapUnit(newValue); + self.Offset(newValue === 'day' ? self.OffsetUnitValue() : 0); + }) + + self.GapUnitValue.subscribe(function (newValue){ + const insertValue = newValue.toString().replace(/[\D\.]/g, ''); + self.GapUnitValue(insertValue ? Number(insertValue) : 0); + self.GapUnit() === 'day' && self.GapDays(insertValue ? Number(insertValue) : 0); + }) + + self.GapUnit.subscribe(function (newValue){ + self.OffsetUnit(newValue); + self.GapDays(newValue === 'day' ? self.GapUnitValue() : 0); + }) } CustomEraStrategy.prototype.toJSON = function () { diff --git a/js/components/cohortbuilder/EndStrategies/DateOffsetStrategy.js b/js/components/cohortbuilder/EndStrategies/DateOffsetStrategy.js index ce5ce53bc..a0c8f8b69 100644 --- a/js/components/cohortbuilder/EndStrategies/DateOffsetStrategy.js +++ b/js/components/cohortbuilder/EndStrategies/DateOffsetStrategy.js @@ -6,6 +6,18 @@ define(['knockout'], function (ko) { self.DateField = ko.observable(data.DateField || "StartDate"); self.Offset = ko.observable(data.Offset || 0); + self.OffsetUnitValue = ko.observable(data.OffsetUnitValue || 0); + self.OffsetUnit = ko.observable(data.OffsetUnit || 'day'); + + self.OffsetUnitValue.subscribe(function (newValue){ + const insertValue = newValue.toString().replace(/[\D\.]/g, ''); + self.OffsetUnitValue(insertValue ? Number(insertValue) : 0); + self.OffsetUnit() === 'day' && self.Offset(insertValue ? Number(insertValue) : 0); + }) + + self.OffsetUnit.subscribe(function (newValue){ + self.Offset(newValue === 'day' ? self.OffsetUnitValue() : 0); + }) } DateOffsetStrategy.prototype.toJSON = function () { diff --git a/js/components/cohortbuilder/InputTypes/DateAdjustment.js b/js/components/cohortbuilder/InputTypes/DateAdjustment.js index f43e38c1c..8fbe4c48f 100644 --- a/js/components/cohortbuilder/InputTypes/DateAdjustment.js +++ b/js/components/cohortbuilder/InputTypes/DateAdjustment.js @@ -8,6 +8,7 @@ define(['knockout'], function (ko) { self.StartOffset = ko.observable(data.StartOffset || 0); self.EndWith = ko.observable(data.EndWith || DateAdjustment.END_DATE); self.EndOffset = ko.observable(data.EndOffset || 0); + } DateAdjustment.START_DATE = "START_DATE"; diff --git a/js/components/cohortbuilder/InputTypes/Window.js b/js/components/cohortbuilder/InputTypes/Window.js index 11c750566..b9506ed76 100644 --- a/js/components/cohortbuilder/InputTypes/Window.js +++ b/js/components/cohortbuilder/InputTypes/Window.js @@ -5,19 +5,74 @@ define(['knockout'], function (ko) { data = data || {}; self.Start = { - Days: ko.observable((data.Start && data.Start.Days) === 0 ? 0 : (data.Start && data.Start.Days) || null), - Coeff: ko.observable((data.Start && data.Start.Coeff) === 0 ? 0 : (data.Start && data.Start.Coeff) || -1) + Days: ko.observable(setDays(data.Start)), + Coeff: ko.observable((data.Start && data.Start.Coeff) === 0 ? 0 : (data.Start && data.Start.Coeff) || -1), + TimeUnit: ko.observable((data.Start && data.Start.TimeUnit) || 'day'), + TimeUnitValue: ko.observable(setTimeUnitValue(data.Start)) }; self.End = { - Days: ko.observable((data.End && data.End.Days) === 0 ? 0 : (data.End && data.End.Days) || null), - Coeff: ko.observable((data.End && data.End.Coeff) === 0 ? 0 : (data.End && data.End.Coeff) || 1) + Days: ko.observable(setDays(data.End)), + Coeff: ko.observable((data.End && data.End.Coeff) === 0 ? 0 : (data.End && data.End.Coeff) || 1), + TimeUnit: ko.observable((data.End && data.End.TimeUnit) || 'day'), + TimeUnitValue: ko.observable(setTimeUnitValue(data.End)) }; self.UseIndexEnd = ko.observable(data.UseIndexEnd || false); self.UseEventEnd = ko.observable(data.UseEventEnd || false); + + self.Start.TimeUnitValue.subscribe(function (newValue){ + const insertValue = newValue ? newValue.toString().replace(/[\D\.]/g, '') : newValue.toString().trim() === '0' ? 0 : null; + self.Start.TimeUnitValue(insertValue === null ? null : Number(insertValue)); + self.Start.TimeUnit() === 'day' && self.Start.Days(insertValue === null ? null : Number(insertValue)); + }) + + self.End.TimeUnitValue.subscribe(function (newValue){ + const insertValue = newValue ? newValue.toString().replace(/[\D\.]/g, '') : newValue.toString().trim() === '0' ? 0 : null; + self.End.TimeUnitValue(insertValue === null ? null : Number(insertValue)); + self.End.TimeUnit() === 'day' && self.End.Days(insertValue === null ? null : Number(insertValue)); + }) + + self.Start.TimeUnit.subscribe(function (newValue){ + self.End.TimeUnit(newValue); + self.Start.Days(newValue === 'day' ? (self.Start.TimeUnitValue() === 'All' ? null : self.Start.TimeUnitValue()) : null); + }) + + self.End.TimeUnit.subscribe(function (newValue){ + self.End.Days(newValue === 'day' ? (self.End.TimeUnitValue() === 'All' ? null : self.End.TimeUnitValue()) : null); + }) } + function setDays(dateValue) { + if (dateValue) { + if (dateValue.Days === 0) { + return 0; + } else if (dateValue.Days) { + return dateValue.Days; + } else if (dateValue.TimeUnitValue === 0) { + return 0; + } else if (dateValue.TimeUnitValue && dateValue.TimeUnitValue !== 'All') { + return dateValue.TimeUnitValue; + } + } + return null; + } + + function setTimeUnitValue(dateValue) { + if (dateValue) { + if (dateValue.TimeUnitValue === 0) { + return 0; + } else if (dateValue.TimeUnitValue && dateValue.TimeUnitValue !== 'All') { + return dateValue.TimeUnitValue; + } else if (dateValue.Days === 0) { + return 0; + } else if (dateValue.Days) { + return dateValue.Days; + } + } + return null; + } + return Window; }); \ No newline at end of file diff --git a/js/components/cohortbuilder/components/CohortExpressionEditor.js b/js/components/cohortbuilder/components/CohortExpressionEditor.js index 118c34fd5..0e9c0f094 100644 --- a/js/components/cohortbuilder/components/CohortExpressionEditor.js +++ b/js/components/cohortbuilder/components/CohortExpressionEditor.js @@ -39,6 +39,11 @@ define([ self.expression = params.expression; self.options = options; + self.useDateTime = ko.observable(self.expression().UseDatetime()); + self.useDateTime.subscribe(function (newValue) { + self.expression().UseDatetime(newValue); + }); + self.showCensorWindow = ko.observable( self.expression().CensorWindow().StartDate() || self.expression().CensorWindow().EndDate() diff --git a/js/components/cohortbuilder/components/CohortExpressionEditor.less b/js/components/cohortbuilder/components/CohortExpressionEditor.less index e58a5f125..41a2d8aa4 100644 --- a/js/components/cohortbuilder/components/CohortExpressionEditor.less +++ b/js/components/cohortbuilder/components/CohortExpressionEditor.less @@ -8,4 +8,10 @@ flex-grow: 1; padding-left: 1rem; } -} \ No newline at end of file +} + +.expression-editor { + &__options-label { + margin-left: 0.5rem; + } +} diff --git a/js/components/cohortbuilder/components/CohortExpressionEditorTemplate.html b/js/components/cohortbuilder/components/CohortExpressionEditorTemplate.html index ead0c21bd..1adf14c7e 100644 --- a/js/components/cohortbuilder/components/CohortExpressionEditorTemplate.html +++ b/js/components/cohortbuilder/components/CohortExpressionEditorTemplate.html @@ -35,6 +35,16 @@ +