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 ? (
+ }
+ onClick={handleSubmit}
+ disabled={submitCount ? !isValid : false}
+ >
+ {t('Submit')}
+
+ ) : (
+
+
+ }
+ onClick={overrideNext ?? handleNextStep}
+ disabled={disableNext}
+ >
+ {buttonTitle ?? t('Continue')}
+
+
+
+ ))}
{openSubmitModal && (