diff --git a/src/components/HrTools/PdsGoalCalculator/PdsGoalCalculator.test.tsx b/src/components/HrTools/PdsGoalCalculator/PdsGoalCalculator.test.tsx index b2b74c4432..3c61f6b3a1 100644 --- a/src/components/HrTools/PdsGoalCalculator/PdsGoalCalculator.test.tsx +++ b/src/components/HrTools/PdsGoalCalculator/PdsGoalCalculator.test.tsx @@ -97,6 +97,53 @@ describe('PdsGoalCalculator', () => { await waitFor(() => expect(continueButton).not.toBeDisabled()); }); + it('hides the Back button on the first step', async () => { + const { findByRole, queryByRole } = render( + + + , + ); + + await findByRole('button', { name: /continue/i }); + expect(queryByRole('button', { name: /back/i })).not.toBeInTheDocument(); + }); + + it('shows the Back button after advancing past the first step', async () => { + const { findByRole } = render( + + + , + ); + + const continueButton = await findByRole('button', { name: /continue/i }); + await waitFor(() => expect(continueButton).not.toBeDisabled()); + userEvent.click(continueButton); + + expect(await findByRole('button', { name: /back/i })).toBeInTheDocument(); + }); + + it('clicking Back returns to the previous step', async () => { + const { findByRole, queryByRole } = render( + + + , + ); + + const continueButton = await findByRole('button', { name: /continue/i }); + await waitFor(() => expect(continueButton).not.toBeDisabled()); + userEvent.click(continueButton); + + const backButton = await findByRole('button', { name: /back/i }); + userEvent.click(backButton); + + await waitFor(() => + expect(queryByRole('button', { name: /back/i })).not.toBeInTheDocument(), + ); + expect( + await findByRole('heading', { level: 6, name: 'Calculator Setup' }), + ).toBeInTheDocument(); + }); + it('re-enables Continue when switching from Full-time to Part-time hides the only invalid field', async () => { const { findByRole, getByRole, queryByRole } = render( { usePdsGoalCalculator(); const { allValid } = useAutosaveForm(); + const isFirstStep = stepIndex === 0; const isLastStep = stepIndex === steps.length - 1; return ( <> - {!isLastStep && ( - - )} + ); }; diff --git a/src/components/HrTools/Shared/CalculationReports/DirectionButtons/DirectionButtons.test.tsx b/src/components/HrTools/Shared/CalculationReports/DirectionButtons/DirectionButtons.test.tsx index 6ed2ba75fe..540cf55729 100644 --- a/src/components/HrTools/Shared/CalculationReports/DirectionButtons/DirectionButtons.test.tsx +++ b/src/components/HrTools/Shared/CalculationReports/DirectionButtons/DirectionButtons.test.tsx @@ -26,6 +26,7 @@ interface TestComponentProps { buttonTitle?: string; isEdit?: boolean; disableNext?: boolean; + noDiscard?: boolean; } const TestComponent: React.FC = ({ @@ -35,6 +36,7 @@ const TestComponent: React.FC = ({ buttonTitle, isEdit, disableNext, + noDiscard = false, }) => ( = ({ isSubmission={isSubmission} handleNextStep={handleNextStep} handlePreviousStep={handlePreviousStep} - handleDiscard={handleDiscard} + handleDiscard={noDiscard ? undefined : handleDiscard} overrideNext={overrideNext} showBackButton={showBackButton} buttonTitle={buttonTitle} @@ -155,6 +157,53 @@ describe('DirectionButtons', () => { }); }); + it('renders Discard, Back, and Continue in left-to-right order', async () => { + const { findAllByRole } = render(); + + const buttons = await findAllByRole('button'); + expect(buttons).toHaveLength(3); + expect(buttons[0]).toHaveTextContent(/discard/i); + expect(buttons[1]).toHaveTextContent(/back/i); + expect(buttons[2]).toHaveTextContent(/continue/i); + }); + + it('renders Discard, Back, and Submit in left-to-right order during submission', async () => { + const { findAllByRole } = render( + , + ); + + const buttons = await findAllByRole('button'); + expect(buttons).toHaveLength(3); + expect(buttons[0]).toHaveTextContent(/discard/i); + expect(buttons[1]).toHaveTextContent(/back/i); + expect(buttons[2]).toHaveTextContent(/submit/i); + }); + + it('renders Back to the left of Continue when there is no Discard handler', async () => { + const { findAllByRole } = render( + , + ); + + const buttons = await findAllByRole('button'); + expect(buttons).toHaveLength(2); + expect(buttons[0]).toHaveTextContent(/back/i); + expect(buttons[1]).toHaveTextContent(/continue/i); + }); + + it('renders only Continue (right-aligned) when there is no Discard, no Back, and not a submission', async () => { + const { findAllByRole } = render(); + + const buttons = await findAllByRole('button'); + expect(buttons).toHaveLength(1); + expect(buttons[0]).toHaveTextContent(/continue/i); + + // The Continue button's wrapper Box uses `ml: 'auto'` to push it to the + // right edge when no left-side controls are rendered. Walk up from the + // button to confirm that wrapper is the only child of the outer flex row. + const outerRow = buttons[0].closest('.MuiBox-root')?.parentElement; + expect(outerRow?.children).toHaveLength(1); + }); + it('renders Discard Changes button', async () => { const { findByRole, getByRole } = render(); diff --git a/src/components/HrTools/Shared/CalculationReports/DirectionButtons/DirectionButtons.tsx b/src/components/HrTools/Shared/CalculationReports/DirectionButtons/DirectionButtons.tsx index 233779602c..b4266f250c 100644 --- a/src/components/HrTools/Shared/CalculationReports/DirectionButtons/DirectionButtons.tsx +++ b/src/components/HrTools/Shared/CalculationReports/DirectionButtons/DirectionButtons.tsx @@ -17,6 +17,7 @@ interface DirectionButtonsProps { actionRequired?: boolean; overrideNext?: () => void; showBackButton?: boolean; + hideNextButton?: boolean; isEdit?: boolean; additionalApproval?: boolean; splitAsr?: boolean; @@ -43,6 +44,7 @@ export const DirectionButtons: React.FC = ({ isSubmission, overrideNext, showBackButton, + hideNextButton, submitForm, validateForm, submitCount, @@ -90,73 +92,73 @@ export const DirectionButtons: React.FC = ({ setOpenDiscardModal(false); }; - return ( - } sx={{ - mt: 5, - display: 'flex', - justifyContent: - !handleDiscard && !showBackButton && !isSubmission - ? 'flex-end' - : 'space-between', + bgcolor: 'grey.300', + color: 'text.primary', + '&:hover': { + bgcolor: 'grey.400', + }, + fontWeight: 'bold', }} + onClick={handlePreviousStep} > - {handleDiscard && ( - + {t('Back')} + + ); + + return ( + + {(handleDiscard || showBackButton) && ( + + {handleDiscard ? ( + + ) : ( + backButton + )} + )} - - {showBackButton && ( - - )} - {isSubmission ? ( - - ) : ( - - - - - - )} + + {handleDiscard && backButton} + {!hideNextButton && + (isSubmission ? ( + + ) : ( + + + + + + ))} {openSubmitModal && (