From 95ea06670ac78246adceb579cb2fc73be41f2510 Mon Sep 17 00:00:00 2001 From: Benjamin Paige Date: Mon, 26 Aug 2024 20:59:03 -0600 Subject: [PATCH] Update and test --- lib/libs/webforms/CS3/v202401.ts | 76 +++++++------------ lib/packages/shared-types/forms.ts | 2 +- .../components/RHF/utils/additionalRules.ts | 49 +++++++----- 3 files changed, 59 insertions(+), 68 deletions(-) diff --git a/lib/libs/webforms/CS3/v202401.ts b/lib/libs/webforms/CS3/v202401.ts index 515eea73e..e5bc0472d 100644 --- a/lib/libs/webforms/CS3/v202401.ts +++ b/lib/libs/webforms/CS3/v202401.ts @@ -1,5 +1,28 @@ import { FormSchema } from "shared-types"; +const ageOptions = [ + { value: "0", label: "0" }, + { value: "1", label: "1" }, + { value: "2", label: "2" }, + { value: "3", label: "3" }, + { value: "4", label: "4" }, + { value: "5", label: "5" }, + { value: "6", label: "6" }, + { value: "7", label: "7" }, + { value: "8", label: "8" }, + { value: "9", label: "9" }, + { value: "10", label: "10" }, + { value: "11", label: "11" }, + { value: "12", label: "12" }, + { value: "13", label: "13" }, + { value: "14", label: "14" }, + { value: "15", label: "15" }, + { value: "16", label: "16" }, + { value: "17", label: "17" }, + { value: "18", label: "18" }, + { value: "19", label: "19" }, +]; + export const v202401: FormSchema = { header: "CS 3: Eligibility for Medicaid expansion program", subheader: "42 CFR 457.320(a)(2) and (3)", @@ -43,36 +66,16 @@ export const v202401: FormSchema = { addtnlRules: [ { type: "noGapsOrOverlapsInSelectOptions", - fieldName: "cs3_inc-standards_age-and-house-inc-range", - message: "All Ages 0 - 19 must be accounted for", + fieldName: "age-and-house-inc-range", + message: + "All ages must be respresented without overlaping", fromField: "from-age", toField: "to-age", - optionsField: "from-age", + options: ageOptions, }, ], props: { - options: [ - { value: "0", label: "0" }, - { value: "1", label: "1" }, - { value: "2", label: "2" }, - { value: "3", label: "3" }, - { value: "4", label: "4" }, - { value: "5", label: "5" }, - { value: "6", label: "6" }, - { value: "7", label: "7" }, - { value: "8", label: "8" }, - { value: "9", label: "9" }, - { value: "10", label: "10" }, - { value: "11", label: "11" }, - { value: "12", label: "12" }, - { value: "13", label: "13" }, - { value: "14", label: "14" }, - { value: "15", label: "15" }, - { value: "16", label: "16" }, - { value: "17", label: "17" }, - { value: "18", label: "18" }, - { value: "19", label: "19" }, - ], + options: ageOptions, }, }, { @@ -85,28 +88,7 @@ export const v202401: FormSchema = { required: "* Required", }, props: { - options: [ - { value: "0", label: "0" }, - { value: "1", label: "1" }, - { value: "2", label: "2" }, - { value: "3", label: "3" }, - { value: "4", label: "4" }, - { value: "5", label: "5" }, - { value: "6", label: "6" }, - { value: "7", label: "7" }, - { value: "8", label: "8" }, - { value: "9", label: "9" }, - { value: "10", label: "10" }, - { value: "11", label: "11" }, - { value: "12", label: "12" }, - { value: "13", label: "13" }, - { value: "14", label: "14" }, - { value: "15", label: "15" }, - { value: "16", label: "16" }, - { value: "17", label: "17" }, - { value: "18", label: "18" }, - { value: "19", label: "19" }, - ], + options: ageOptions, }, }, { diff --git a/lib/packages/shared-types/forms.ts b/lib/packages/shared-types/forms.ts index 5a1bde97b..7a304e98d 100644 --- a/lib/packages/shared-types/forms.ts +++ b/lib/packages/shared-types/forms.ts @@ -39,7 +39,7 @@ export type AdditionalRule = message: string; fromField: string; toField: string; - optionsField: string; + options: { value: string; label: string }[]; }; export type RuleGenerator = ( diff --git a/react-app/src/components/RHF/utils/additionalRules.ts b/react-app/src/components/RHF/utils/additionalRules.ts index 73aba5255..b87d06767 100644 --- a/react-app/src/components/RHF/utils/additionalRules.ts +++ b/react-app/src/components/RHF/utils/additionalRules.ts @@ -8,6 +8,17 @@ export const sortFunctions: { reverseSort: (a, b) => b.localeCompare(a), }; +// New function to sort options from lowest to highest +export function sortOptionsLowestToHighest< + T extends { value: string | number }, +>(options: T[]): T[] { + return [...options].sort((a, b) => { + const aValue = typeof a.value === "string" ? parseFloat(a.value) : a.value; + const bValue = typeof b.value === "string" ? parseFloat(b.value) : b.value; + return aValue - bValue; + }); +} + export function stringCompare( a: { label: string }, b: { label: string }, @@ -82,48 +93,46 @@ export const valReducer = ( case "noGapsOrOverlapsInSelectOptions": return { ...valSet, - [valName]: (value, fields) => { - console.log("value: ", JSON.stringify(value, null, 2)); - console.log("fields: ", JSON.stringify(fields, null, 2)); + [valName]: (_, fields) => { const fieldArray = fields[rule.fieldName]; if (!fieldArray || !Array.isArray(fieldArray)) { - return true; // If the field is not an array, we can't check for gaps + return true; } - const fromField = (rule as any).fromField; - const toField = (rule as any).toField; - const optionsField = (rule as any).optionsField; + const fromField = rule.fromField; + const toField = rule.toField; - const ageRanges = fieldArray.map((item: any) => ({ + const range = fieldArray.map((item: any) => ({ from: parseInt(item[fromField], 10), to: parseInt(item[toField], 10), })); - // Sort the age ranges - ageRanges.sort((a, b) => a.from - b.from); + range.sort((a, b) => a.from - b.from); + const sortedOptions = sortOptionsLowestToHighest(rule.options); - // Get the min and max values from the options - const options = fields[optionsField]?.props?.options || []; - const minValue = parseInt(options[0]?.value, 10); - const maxValue = parseInt(options[options.length - 1]?.value, 10); + const minValue = parseInt(sortedOptions[0]?.value, 10); + const maxValue = parseInt( + sortedOptions[sortedOptions.length - 1]?.value, + 10, + ); // Check for gaps and overlaps - for (let i = 0; i < ageRanges.length; i++) { - if (i === 0 && ageRanges[i].from !== minValue) { + for (let i = 0; i < range.length; i++) { + if (i === 0 && range[i].from !== minValue) { return rule.message; // Gap at the beginning } if (i > 0) { - if (ageRanges[i].from > ageRanges[i - 1].to + 1) { + if (range[i].from > range[i - 1].to + 1) { return rule.message; // Gap between ranges } - if (ageRanges[i].from <= ageRanges[i - 1].to) { - return rule.message; // Overlap between ranges + if (range[i].from <= range[i - 1].to) { + return rule.message; // Overlaping age ranges } } } // Check if the last range ends at the maximum value - if (ageRanges[ageRanges.length - 1].to !== maxValue) { + if (range[range.length - 1].to !== maxValue) { return rule.message; // Gap at the end }