UNPKG

terra-clinical-onset-picker

Version:

The terra-clinical-onset-picker component provides users a way to enter or select an approximate date for use in onset scenarios.

184 lines (165 loc) 7.69 kB
import moment from 'moment'; const maxWeeks = 8; const maxMonths = 24; const PrecisionOptions = { ONAT: 'on/at', ABOUT: 'about', BEFORE: 'before', AFTER: 'after', UNKNOWN: 'unknown', }; const DATE_FORMAT = 'YYYY-MM-DD'; class OnsetUtils { /* * Create object to pass to SelectField for month options * Filters out months before birth or after the current date. */ static allowedMonths(intl, birthdate, year) { const start = moment(birthdate); const end = moment(); let possibleMonths = [{ value: '0', display: intl.formatMessage({ id: 'Terra.onsetPicker.january' }) }, { value: '1', display: intl.formatMessage({ id: 'Terra.onsetPicker.february' }) }, { value: '2', display: intl.formatMessage({ id: 'Terra.onsetPicker.march' }) }, { value: '3', display: intl.formatMessage({ id: 'Terra.onsetPicker.april' }) }, { value: '4', display: intl.formatMessage({ id: 'Terra.onsetPicker.may' }) }, { value: '5', display: intl.formatMessage({ id: 'Terra.onsetPicker.june' }) }, { value: '6', display: intl.formatMessage({ id: 'Terra.onsetPicker.july' }) }, { value: '7', display: intl.formatMessage({ id: 'Terra.onsetPicker.august' }) }, { value: '8', display: intl.formatMessage({ id: 'Terra.onsetPicker.september' }) }, { value: '9', display: intl.formatMessage({ id: 'Terra.onsetPicker.october' }) }, { value: '10', display: intl.formatMessage({ id: 'Terra.onsetPicker.november' }) }, { value: '11', display: intl.formatMessage({ id: 'Terra.onsetPicker.december' }) }]; if (start.year().toString() === year || start.year() === end.year()) { possibleMonths = possibleMonths.filter(month => month.value > start.month()); } if (end.year().toString() === year || start.year() === end.year()) { possibleMonths = possibleMonths.filter(month => month.value <= end.month()); } return possibleMonths; } /* * Create object to pass to SelectField for year options. * Populates birth year to current year. */ static allowedYears(granularity, month, birthdate) { let start = moment(birthdate).year(); if ((granularity === 'month' && month <= moment(birthdate).month()) || granularity === 'year') { start += 1; } let end = moment().year(); if ((granularity === 'month' && month > moment().month())) { end -= 1; } if (month > moment().month() && start === end && granularity !== 'month') { start = ''; end = ''; } return Array((end - start) + 1).fill(undefined).map((x, idx) => { const year = start + idx; return { value: start !== '' ? year.toString() : '', display: start !== '' ? year.toString() : '' }; }); } /** * Calulcates maximum number allowed for each age duration. * Will use the lesser of power of two or the difference between birth for week/month. * Power of two for maximum weeks/months (8 weeks = 2 months, 24 months = 2 years) */ static allowedAge(birthdate, ageUnit) { const birthMoment = moment(birthdate).startOf('day'); // startOf to clear time from values const currentMoment = moment().startOf('day'); switch (ageUnit) { case 'years': return currentMoment.diff(birthMoment, 'years'); case 'months': { const monthDiff = currentMoment.diff(birthMoment, 'months'); return monthDiff > maxMonths ? maxMonths : monthDiff; } default: { const weekDiff = currentMoment.diff(birthMoment, 'weeks'); return weekDiff > maxWeeks ? maxWeeks : weekDiff; } } } /* * Create object to pass to SelectField for age unit options. * Does not add durations that are not possible based on birth. */ static allowedAgeUnits(birthdate, intl) { const ageMoment = moment(birthdate).startOf('day'); // startOf to clear time from values const currentMoment = moment().startOf('day'); if (currentMoment.diff(ageMoment, 'weeks') === 0) { return []; } const ageUnits = [{ value: 'weeks', display: intl.formatMessage({ id: 'Terra.onsetPicker.agePrecisionWeek' }) }]; // Do not add month option if less than a month old if (currentMoment.diff(ageMoment, 'months') > 0) { ageUnits.push({ value: 'months', display: intl.formatMessage({ id: 'Terra.onsetPicker.agePrecisionMonth' }) }); } // Do not add year option if less than a year old if (currentMoment.diff(ageMoment, 'years') > 0) { ageUnits.push({ value: 'years', display: intl.formatMessage({ id: 'Terra.onsetPicker.agePrecisionYear' }) }); } return ageUnits; } /** * Converts onset date to a age value with lowest possible age unit (weeks, then months, then years). */ static onsetToAge(birthdate, onsetDate) { if (onsetDate === undefined) { return { age: undefined, ageUnit: undefined }; } const birthMoment = moment(birthdate).startOf('day'); // startOf to clear time from values const onsetMoment = onsetDate.startOf('day'); const yearDiff = onsetMoment.diff(birthMoment, 'years'); const monthDiff = onsetMoment.diff(birthMoment, 'months'); const weekDiff = onsetMoment.diff(birthMoment, 'weeks'); const dayDiff = onsetMoment.diff(birthMoment, 'days'); const onset = onsetMoment.format(DATE_FORMAT); let addYear = ''; let addMonth = ''; if (birthMoment.format(DATE_FORMAT) === moment().year(birthMoment.year()).month(birthMoment.month()).endOf('month') .format(DATE_FORMAT) && (onsetMoment.subtract(1, 'days').daysInMonth() < birthMoment.daysInMonth())) { addYear = moment(birthMoment).add(yearDiff, 'years').add(1, 'days').format(DATE_FORMAT); addMonth = moment(birthMoment).add(monthDiff, 'months').add(1, 'days').format(DATE_FORMAT); } else { addYear = moment(birthMoment).add(yearDiff, 'years').format(DATE_FORMAT); addMonth = moment(birthMoment).add(monthDiff, 'months').format(DATE_FORMAT); } if (monthDiff > 24 && monthDiff % 12 === 0 && addYear === onset) { return { age: yearDiff, ageUnit: 'years' }; } if (monthDiff <= 24 && addMonth === onset) { return { age: monthDiff, ageUnit: 'months' }; } if (weekDiff <= 8 && dayDiff % 7 === 0) { return { age: weekDiff, ageUnit: 'weeks' }; } return { age: undefined, ageUnit: undefined }; } /** * Returns a translated set of precisions to be used in the precision SelectField. */ static allowedPrecisions(intl, precisionSet) { const precisions = []; for (let i = 0; i < precisionSet.length; i += 1) { switch (precisionSet[i]) { case PrecisionOptions.ONAT: precisions.push({ value: PrecisionOptions.ONAT, display: intl.formatMessage({ id: 'Terra.onsetPicker.precisionOnAt' }) }); break; case PrecisionOptions.ABOUT: precisions.push({ value: PrecisionOptions.ABOUT, display: intl.formatMessage({ id: 'Terra.onsetPicker.precisionAbout' }) }); break; case PrecisionOptions.BEFORE: precisions.push({ value: PrecisionOptions.BEFORE, display: intl.formatMessage({ id: 'Terra.onsetPicker.precisionBefore' }) }); break; case PrecisionOptions.AFTER: precisions.push({ value: PrecisionOptions.AFTER, display: intl.formatMessage({ id: 'Terra.onsetPicker.precisionAfter' }) }); break; case PrecisionOptions.UNKNOWN: precisions.push({ value: PrecisionOptions.UNKNOWN, display: intl.formatMessage({ id: 'Terra.onsetPicker.precisionUnknown' }) }); break; default: break; } } return precisions; } } OnsetUtils.PrecisionOptions = PrecisionOptions; export default OnsetUtils;