diff --git a/src/components/HrTools/PdsGoalCalculator/Setup/SetupStep.tsx b/src/components/HrTools/PdsGoalCalculator/Setup/SetupStep.tsx index 8eec4eccad..fda526e1da 100644 --- a/src/components/HrTools/PdsGoalCalculator/Setup/SetupStep.tsx +++ b/src/components/HrTools/PdsGoalCalculator/Setup/SetupStep.tsx @@ -65,14 +65,10 @@ export const SetupStep: React.FC = () => { .positive(t('Hours Worked must be a positive number')), otherwise: (s) => s.optional().nullable(), }), - benefits: yup.number().when('status', { - is: (val: string) => val !== DesignationSupportStatus.PartTime, - then: (s) => - s - .required(t('Benefits is a required field')) - .positive(t('Benefits must be a positive number')), - otherwise: (s) => s.optional().nullable(), - }), + benefits: yup + .number() + .nullable() + .positive(t('Benefits must be a positive number')), }), [t], ); diff --git a/src/components/HrTools/PdsGoalCalculator/Shared/Autosave/AutosaveTextField.test.tsx b/src/components/HrTools/PdsGoalCalculator/Shared/Autosave/AutosaveTextField.test.tsx index 7e23964a04..4fc885f6c0 100644 --- a/src/components/HrTools/PdsGoalCalculator/Shared/Autosave/AutosaveTextField.test.tsx +++ b/src/components/HrTools/PdsGoalCalculator/Shared/Autosave/AutosaveTextField.test.tsx @@ -1,6 +1,6 @@ import React from 'react'; import { MenuItem } from '@mui/material'; -import { fireEvent, render, waitFor } from '@testing-library/react'; +import { render, waitFor } from '@testing-library/react'; import userEvent from '@testing-library/user-event'; import * as yup from 'yup'; import { @@ -221,28 +221,60 @@ describe('AutosaveTextField', () => { , ); - it('hides validation error for an empty untouched field', async () => { + it('shows validation error for an empty required field on load', async () => { const { findByRole } = renderRequired(); const input = await findByRole('textbox', { name: 'Goal Name' }); await waitFor(() => expect(input).toHaveValue('')); - expect(input).toHaveAccessibleDescription('Enter the goal name'); - expect(input).not.toHaveAttribute('aria-invalid', 'true'); + await waitFor(() => + expect(input).toHaveAccessibleDescription('Goal Name is required'), + ); + expect(input).toHaveAttribute('aria-invalid', 'true'); }); - it('shows validation error after the field is touched', async () => { + it('clears validation error after user fills required field', async () => { const { findByRole } = renderRequired(); const input = await findByRole('textbox', { name: 'Goal Name' }); - await waitFor(() => expect(input).toHaveValue('')); + await waitFor(() => + expect(input).toHaveAttribute('aria-invalid', 'true'), + ); - fireEvent.focus(input); - fireEvent.blur(input); + userEvent.type(input, 'Filled in'); await waitFor(() => - expect(input).toHaveAccessibleDescription('Goal Name is required'), + expect(input).not.toHaveAttribute('aria-invalid', 'true'), + ); + expect(input).toHaveAccessibleDescription('Enter the goal name'); + }); + }); + + describe('optional field', () => { + const optionalSchema = yup.object({ + name: yup.string().nullable(), + }); + + it('does not show validation error for an empty optional field on load', async () => { + const { findByRole } = render( + + + , ); + + const input = await findByRole('textbox', { name: 'Goal Name' }); + await waitFor(() => expect(input).toHaveValue('')); + + expect(input).not.toHaveAttribute('aria-invalid', 'true'); + expect(input).toHaveAccessibleDescription('Enter the goal name'); }); }); diff --git a/src/components/HrTools/PdsGoalCalculator/Shared/Autosave/AutosaveTextField.tsx b/src/components/HrTools/PdsGoalCalculator/Shared/Autosave/AutosaveTextField.tsx index b392f3baf8..a483babfa3 100644 --- a/src/components/HrTools/PdsGoalCalculator/Shared/Autosave/AutosaveTextField.tsx +++ b/src/components/HrTools/PdsGoalCalculator/Shared/Autosave/AutosaveTextField.tsx @@ -1,4 +1,4 @@ -import React, { useState } from 'react'; +import React from 'react'; import { TextField, TextFieldProps } from '@mui/material'; import * as yup from 'yup'; import { DesignationSupportCalculationUpdateInput } from 'src/graphql/types.generated'; @@ -23,11 +23,8 @@ export const AutosaveTextField: React.FC = ({ schema, saveOnChange: props.select, }); - const [touched, setTouched] = useState(false); - const showValidationError = Boolean( - fieldProps.error && (touched || fieldProps.value !== ''), - ); + const showValidationError = Boolean(fieldProps.error); return ( = ({ variant="outlined" {...fieldProps} {...props} - onChange={(event) => { - setTouched(true); - fieldProps.onChange?.(event as React.ChangeEvent); - }} - onBlur={() => { - setTouched(true); - fieldProps.onBlur?.(); - }} disabled={fieldProps.disabled || props.disabled} error={showValidationError || undefined} helperText={ diff --git a/src/components/HrTools/PdsGoalCalculator/Shared/pdsCompletion.test.ts b/src/components/HrTools/PdsGoalCalculator/Shared/pdsCompletion.test.ts index eb9269de4a..80ae21c3b7 100644 --- a/src/components/HrTools/PdsGoalCalculator/Shared/pdsCompletion.test.ts +++ b/src/components/HrTools/PdsGoalCalculator/Shared/pdsCompletion.test.ts @@ -72,8 +72,8 @@ describe('isSetupComplete', () => { expect(isSetupComplete(partTime)).toBe(true); }); - it('requires benefits when status is Full-time', () => { - expect(isSetupComplete({ ...baseCalculation, benefits: null })).toBe(false); + it('does not require benefits when status is Full-time', () => { + expect(isSetupComplete({ ...baseCalculation, benefits: null })).toBe(true); }); }); diff --git a/src/components/HrTools/PdsGoalCalculator/Shared/pdsCompletion.ts b/src/components/HrTools/PdsGoalCalculator/Shared/pdsCompletion.ts index 26fa90ff71..19ae163ca0 100644 --- a/src/components/HrTools/PdsGoalCalculator/Shared/pdsCompletion.ts +++ b/src/components/HrTools/PdsGoalCalculator/Shared/pdsCompletion.ts @@ -1,7 +1,4 @@ -import { - DesignationSupportSalaryType, - DesignationSupportStatus, -} from 'src/graphql/types.generated'; +import { DesignationSupportSalaryType } from 'src/graphql/types.generated'; import { PdsGoalCalculationFieldsFragment } from '../GoalsList/PdsGoalCalculations.generated'; import { PdsSummaryData } from '../calculations/usePdsSummaryData'; @@ -14,15 +11,13 @@ export const isSetupComplete = (calculation: Calculation): boolean => { const isSalaried = calculation.salaryOrHourly === DesignationSupportSalaryType.Salaried; - const isPartTime = calculation.status === DesignationSupportStatus.PartTime; return Boolean( calculation.name && calculation.status && calculation.salaryOrHourly && (calculation.payRate ?? 0) > 0 && - (isSalaried || (calculation.hoursWorkedPerWeek ?? 0) > 0) && - (isPartTime || (calculation.benefits ?? 0) > 0), + (isSalaried || (calculation.hoursWorkedPerWeek ?? 0) > 0), ); };