From c3138a8f1ea2b1ea43c6ada7434aaee41d704c6d Mon Sep 17 00:00:00 2001 From: Katelyn Grimes Date: Thu, 12 Feb 2026 13:28:21 -0500 Subject: [PATCH 1/2] Fix validation by removing enable reinitialize --- .../Shared/useAdditionalSalaryRequestForm.ts | 1 - .../SharedComponents/ValidationAlert.tsx | 20 ++++++++++++------- 2 files changed, 13 insertions(+), 8 deletions(-) diff --git a/src/components/Reports/AdditionalSalaryRequest/Shared/useAdditionalSalaryRequestForm.ts b/src/components/Reports/AdditionalSalaryRequest/Shared/useAdditionalSalaryRequestForm.ts index 97e28ae0ff..f19527a36d 100644 --- a/src/components/Reports/AdditionalSalaryRequest/Shared/useAdditionalSalaryRequestForm.ts +++ b/src/components/Reports/AdditionalSalaryRequest/Shared/useAdditionalSalaryRequestForm.ts @@ -267,7 +267,6 @@ export const useAdditionalSalaryRequestForm = ( initialValues, validationSchema, onSubmit, - enableReinitialize: true, validateOnMount: true, }); diff --git a/src/components/Reports/AdditionalSalaryRequest/SharedComponents/ValidationAlert.tsx b/src/components/Reports/AdditionalSalaryRequest/SharedComponents/ValidationAlert.tsx index 028c55f1e8..281b6c5eb2 100644 --- a/src/components/Reports/AdditionalSalaryRequest/SharedComponents/ValidationAlert.tsx +++ b/src/components/Reports/AdditionalSalaryRequest/SharedComponents/ValidationAlert.tsx @@ -8,7 +8,7 @@ import { fieldConfig } from '../Shared/useAdditionalSalaryRequestForm'; export const ValidationAlert: React.FC = () => { const { t } = useTranslation(); - const { submitCount, isValid, values, errors } = + const { submitCount, values, errors } = useFormikContext(); const { salaryInfo, isInternational } = useAdditionalSalaryRequest(); @@ -35,19 +35,25 @@ export const ValidationAlert: React.FC = () => { .map(({ label }) => t(label)); }, [submitCount, salaryInfo, isInternational, values, t]); - if (!submitCount || isValid) { + // Additional info is the only field required (when a user exceeds their cap) + const hasRequiredErrors = Object.keys(errors).some( + (key) => key === 'additionalInfo', + ); + + const hasErrors = + hasRequiredErrors || + exceedingLimitFields.length > 0 || + !!errors.totalAdditionalSalaryRequested; + + if (!submitCount || !hasErrors) { return null; } - const hasFieldErrors = Object.keys(errors).some( - (key) => key !== 'totalAdditionalSalaryRequested', - ); - return ( {t('Your form is missing information.')}
    - {hasFieldErrors && ( + {hasRequiredErrors && (
  • {t('Please enter a value for all required fields.')}
  • )} {exceedingLimitFields.length > 0 && ( From 0c55aa8ee5b2888e45752d8390eb7e59e7471143 Mon Sep 17 00:00:00 2001 From: Katelyn Grimes Date: Thu, 12 Feb 2026 15:52:06 -0500 Subject: [PATCH 2/2] Added useRef to store real initial values --- .../useAdditionalSalaryRequestForm.test.tsx | 20 +++++++ .../Shared/useAdditionalSalaryRequestForm.ts | 59 ++++++++++--------- .../SharedComponents/ValidationAlert.tsx | 6 +- 3 files changed, 54 insertions(+), 31 deletions(-) diff --git a/src/components/Reports/AdditionalSalaryRequest/Shared/useAdditionalSalaryRequestForm.test.tsx b/src/components/Reports/AdditionalSalaryRequest/Shared/useAdditionalSalaryRequestForm.test.tsx index 6e3500f3c8..85173f6754 100644 --- a/src/components/Reports/AdditionalSalaryRequest/Shared/useAdditionalSalaryRequestForm.test.tsx +++ b/src/components/Reports/AdditionalSalaryRequest/Shared/useAdditionalSalaryRequestForm.test.tsx @@ -435,6 +435,26 @@ describe('useAdditionalSalaryRequestForm', () => { expect(errors.childrenCollegeEducation).toContain('$21,000.00'); }); + it('should accept empty string for currency fields', async () => { + const { result } = renderHook( + () => + useAdditionalSalaryRequestForm({ + ...defaultFormValues, + adoption: '', + phoneNumber: '555-123-4567', + emailAddress: 'test@example.com', + }), + { wrapper: TestWrapper }, + ); + + let errors: Record = {}; + await act(async () => { + errors = await result.current.validateForm(); + }); + + expect(errors.adoption).toBeUndefined(); + }); + it('should validate additional info when exceedsCap is true', async () => { const { result } = renderHook( () => diff --git a/src/components/Reports/AdditionalSalaryRequest/Shared/useAdditionalSalaryRequestForm.ts b/src/components/Reports/AdditionalSalaryRequest/Shared/useAdditionalSalaryRequestForm.ts index f19527a36d..f49c0acc4b 100644 --- a/src/components/Reports/AdditionalSalaryRequest/Shared/useAdditionalSalaryRequestForm.ts +++ b/src/components/Reports/AdditionalSalaryRequest/Shared/useAdditionalSalaryRequestForm.ts @@ -95,7 +95,7 @@ export const useAdditionalSalaryRequestForm = ( const createCurrencyValidation = useCallback( (fieldName: string, max?: number) => { - let schema = amount(fieldName, t); + let schema = amount(fieldName, t).nullable(); if (max !== null && max !== undefined) { schema = schema.max( max, @@ -121,33 +121,36 @@ export const useAdditionalSalaryRequestForm = ( emailAddress: user?.staffInfo?.emailAddress || '', } as CompleteFormValues; - const initialValues: CompleteFormValues = useMemo(() => { - if (providedInitialValues) { - return providedInitialValues; - } + const initialValuesRef = useRef(null); - const request = requestData?.latestAdditionalSalaryRequest; - if (!request) { - return defaultInitialValues; + if (!initialValuesRef.current) { + if (providedInitialValues) { + initialValuesRef.current = providedInitialValues; + } else { + const request = requestData?.latestAdditionalSalaryRequest; + if (request) { + initialValuesRef.current = { + ...Object.fromEntries( + fieldConfig.map(({ key }) => [ + key, + String((request[key as keyof typeof request] as number) ?? ''), + ]), + ), + deductTaxDeferredPercent: request.deductTaxDeferredPercent || false, + deductRothPercent: request.deductRothPercent || false, + phoneNumber: + request.phoneNumber || user?.staffInfo?.primaryPhoneNumber || '', + emailAddress: + request.emailAddress || user?.staffInfo?.emailAddress || '', + totalAdditionalSalaryRequested: + request.totalAdditionalSalaryRequested || '', + additionalInfo: request.additionalInfo || '', + } as CompleteFormValues; + } } + } - return { - ...Object.fromEntries( - fieldConfig.map(({ key }) => [ - key, - String((request[key as keyof typeof request] as number) ?? ''), - ]), - ), - deductTaxDeferredPercent: request.deductTaxDeferredPercent || false, - deductRothPercent: request.deductRothPercent || false, - phoneNumber: - request.phoneNumber || user?.staffInfo?.primaryPhoneNumber || '', - emailAddress: request.emailAddress || user?.staffInfo?.emailAddress || '', - totalAdditionalSalaryRequested: - request.totalAdditionalSalaryRequested || '', - additionalInfo: request.additionalInfo || '', - } as CompleteFormValues; - }, [providedInitialValues, requestData?.latestAdditionalSalaryRequest, user]); + const initialValues = initialValuesRef.current ?? defaultInitialValues; const getMaxForField = useCallback( (field: (typeof fieldConfig)[number]): number | undefined => { @@ -188,12 +191,11 @@ export const useAdditionalSalaryRequestForm = ( function () { const total = getTotal(this.parent as CompleteFormValues); - if (total > 0) { + if (total >= 0) { lastValidTotalRef.current = total; } - const stableTotal = total > 0 ? total : lastValidTotalRef.current; - return stableTotal <= primaryAccountBalance; + return lastValidTotalRef.current <= primaryAccountBalance; }, ), additionalInfo: yup @@ -267,6 +269,7 @@ export const useAdditionalSalaryRequestForm = ( initialValues, validationSchema, onSubmit, + enableReinitialize: true, validateOnMount: true, }); diff --git a/src/components/Reports/AdditionalSalaryRequest/SharedComponents/ValidationAlert.tsx b/src/components/Reports/AdditionalSalaryRequest/SharedComponents/ValidationAlert.tsx index 281b6c5eb2..0f6fae809c 100644 --- a/src/components/Reports/AdditionalSalaryRequest/SharedComponents/ValidationAlert.tsx +++ b/src/components/Reports/AdditionalSalaryRequest/SharedComponents/ValidationAlert.tsx @@ -35,9 +35,8 @@ export const ValidationAlert: React.FC = () => { .map(({ label }) => t(label)); }, [submitCount, salaryInfo, isInternational, values, t]); - // Additional info is the only field required (when a user exceeds their cap) - const hasRequiredErrors = Object.keys(errors).some( - (key) => key === 'additionalInfo', + const hasRequiredErrors = Object.keys(errors).some((key) => + ['phoneNumber', 'emailAddress', 'additionalInfo'].includes(key), ); const hasErrors = @@ -60,6 +59,7 @@ export const ValidationAlert: React.FC = () => {
  • {t('The following fields exceed their limits: {{fields}}', { fields: exceedingLimitFields.join(', '), + interpolation: { escapeValue: false }, })}
  • )}