Skip to content

Commit f9395e4

Browse files
authored
Merge pull request #1783 from CruGlobal/MPDX-9596
MPDX-9596 - PDS Goal Calc: Disable sidepanel icons until Settings section complete
2 parents 2d20393 + 6b0f1cd commit f9395e4

7 files changed

Lines changed: 90 additions & 16 deletions

File tree

src/components/HrTools/PdsGoalCalculator/PdsGoalCalculator.test.tsx

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -204,7 +204,11 @@ describe('PdsGoalCalculator', () => {
204204
</PdsGoalCalculatorTestWrapper>,
205205
);
206206

207-
userEvent.click(await findByRole('button', { name: 'Summary Report' }));
207+
const summaryButton = await findByRole('button', {
208+
name: 'Summary Report',
209+
});
210+
await waitFor(() => expect(summaryButton).toBeEnabled());
211+
userEvent.click(summaryButton);
208212

209213
const finishButton = await findByRole('button', {
210214
name: /Finish & Apply Goal/i,

src/components/HrTools/PdsGoalCalculator/PdsGoalCalculator.tsx

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -128,13 +128,11 @@ const MainContent: React.FC = () => {
128128

129129
export const PdsGoalCalculator: React.FC = () => {
130130
return (
131-
<PdsGoalCalculatorLayout
132-
sectionListPanel={<CurrentSectionList />}
133-
mainContent={
134-
<AutosaveForm>
135-
<MainContent />
136-
</AutosaveForm>
137-
}
138-
/>
131+
<AutosaveForm>
132+
<PdsGoalCalculatorLayout
133+
sectionListPanel={<CurrentSectionList />}
134+
mainContent={<MainContent />}
135+
/>
136+
</AutosaveForm>
139137
);
140138
};

src/components/HrTools/PdsGoalCalculator/PdsGoalCalculatorTestWrapper.tsx

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import { SnackbarProvider } from 'notistack';
66
import { DeepPartial } from 'ts-essentials';
77
import TestRouter from '__tests__/util/TestRouter';
88
import { GqlMockedProvider, gqlMock } from '__tests__/util/graphqlMocking';
9+
import { AutosaveForm } from 'src/components/Shared/Autosave/AutosaveForm';
910
import { GetUserQuery } from 'src/components/User/GetUser.generated';
1011
import {
1112
DesignationSupportFormType,
@@ -285,12 +286,16 @@ export const PdsGoalCalculatorTestWrapper = <
285286
)}
286287
onCall={onCall}
287288
>
288-
{withProvider ? (
289-
<PdsGoalCalculatorProvider>{children}</PdsGoalCalculatorProvider>
290-
) : (
291-
// eslint-disable-next-line react/jsx-no-useless-fragment
292-
<>{children}</>
293-
)}
289+
<AutosaveForm>
290+
{withProvider ? (
291+
<PdsGoalCalculatorProvider>
292+
{children}
293+
</PdsGoalCalculatorProvider>
294+
) : (
295+
// eslint-disable-next-line react/jsx-no-useless-fragment
296+
<>{children}</>
297+
)}
298+
</AutosaveForm>
294299
</GqlMockedProvider>
295300
</SnackbarProvider>
296301
</TestRouter>

src/components/HrTools/PdsGoalCalculator/Shared/PdsGoalCalculatorLayout.test.tsx

Lines changed: 40 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import React from 'react';
2-
import { render } from '@testing-library/react';
2+
import { render, waitFor } from '@testing-library/react';
3+
import { PdsGoalCalculator } from '../PdsGoalCalculator';
34
import { PdsGoalCalculatorTestWrapper } from '../PdsGoalCalculatorTestWrapper';
45
import { PdsGoalCalculatorLayout } from './PdsGoalCalculatorLayout';
56

@@ -35,6 +36,44 @@ describe('PdsGoalCalculatorLayout', () => {
3536
expect(progressIndicator).toHaveAttribute('aria-valuenow', '25');
3637
});
3738

39+
it('disables non-Setup icons when setup is incomplete', async () => {
40+
const { findByRole } = render(
41+
<PdsGoalCalculatorTestWrapper calculationMock={{ payRate: 0 }}>
42+
<PdsGoalCalculatorLayout
43+
sectionListPanel={<div>Section List</div>}
44+
mainContent={<div>Main Content</div>}
45+
/>
46+
</PdsGoalCalculatorTestWrapper>,
47+
);
48+
49+
expect(
50+
await findByRole('button', { name: 'Reimbursable Expenses' }),
51+
).toBeDisabled();
52+
expect(await findByRole('button', { name: 'Support Item' })).toBeDisabled();
53+
expect(
54+
await findByRole('button', { name: 'Summary Report' }),
55+
).toBeDisabled();
56+
// Setup icon is always enabled
57+
expect(await findByRole('button', { name: 'Settings' })).toBeEnabled();
58+
});
59+
60+
it('enables all icons when setup is complete', async () => {
61+
const { getByRole } = render(
62+
<PdsGoalCalculatorTestWrapper>
63+
<PdsGoalCalculator />
64+
</PdsGoalCalculatorTestWrapper>,
65+
);
66+
67+
await waitFor(() => {
68+
expect(getByRole('button', { name: 'Settings' })).toBeEnabled();
69+
expect(
70+
getByRole('button', { name: 'Reimbursable Expenses' }),
71+
).toBeEnabled();
72+
expect(getByRole('button', { name: 'Support Item' })).toBeEnabled();
73+
expect(getByRole('button', { name: 'Summary Report' })).toBeEnabled();
74+
});
75+
});
76+
3877
it('shows an indeterminate progress indicator while calculation is loading', async () => {
3978
const { findByRole } = render(
4079
<PdsGoalCalculatorTestWrapper>

src/components/HrTools/PdsGoalCalculator/Shared/PdsGoalCalculatorLayout.tsx

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
11
import React from 'react';
22
import { useTranslation } from 'react-i18next';
3+
import { useAutosaveForm } from 'src/components/Shared/Autosave/AutosaveForm';
34
import { useAccountListId } from 'src/hooks/useAccountListId';
45
import { PanelLayout } from '../../Shared/CalculationReports/PanelLayout/PanelLayout';
56
import { PanelTypeEnum } from '../../Shared/CalculationReports/Shared/sharedTypes';
67
import { PdsGoalCalculatorStepEnum } from '../PdsGoalCalculatorHelper';
78
import { usePdsGoalCalculator } from './PdsGoalCalculatorContext';
9+
import { isSetupComplete } from './pdsCompletion';
810

911
interface PdsGoalCalculatorLayoutProps {
1012
sectionListPanel: React.ReactNode;
@@ -19,6 +21,7 @@ export const PdsGoalCalculatorLayout: React.FC<
1921
const {
2022
steps,
2123
currentStep,
24+
calculation,
2225
handleStepChange,
2326
isDrawerOpen,
2427
setDrawerOpen,
@@ -27,6 +30,10 @@ export const PdsGoalCalculatorLayout: React.FC<
2730
calculationLoading,
2831
} = usePdsGoalCalculator();
2932

33+
const setupComplete = isSetupComplete(calculation);
34+
const { allValid } = useAutosaveForm();
35+
const isSetupValid = setupComplete && allValid;
36+
3037
const handleStepIconClick = (step: PdsGoalCalculatorStepEnum) => {
3138
if (currentStep.step === step) {
3239
toggleDrawer();
@@ -41,6 +48,7 @@ export const PdsGoalCalculatorLayout: React.FC<
4148
icon: step.icon,
4249
label: step.title,
4350
isActive: currentStep.step === step.step,
51+
disabled: !isSetupValid && step.step !== PdsGoalCalculatorStepEnum.Setup,
4452
onClick: () => handleStepIconClick(step.step),
4553
}));
4654

src/components/HrTools/Shared/CalculationReports/PanelLayout/PanelLayout.test.tsx

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -212,6 +212,24 @@ describe('PanelLayout', () => {
212212
expect(queryByRole('progressbar')).not.toBeInTheDocument();
213213
});
214214

215+
it('disables an icon button when disabled is true', () => {
216+
const disabledIcons: IconPanelItem[] = [
217+
{
218+
key: 'disabled-icon',
219+
icon: <HomeIcon />,
220+
label: 'Disabled Icon',
221+
disabled: true,
222+
onClick: jest.fn(),
223+
},
224+
];
225+
226+
const { getByRole } = render(
227+
<TestComponent panelType={PanelTypeEnum.Other} icons={disabledIcons} />,
228+
);
229+
230+
expect(getByRole('button', { name: 'Disabled Icon' })).toBeDisabled();
231+
});
232+
215233
it('handles empty icon panel items gracefully', () => {
216234
const { getByTestId, queryAllByRole } = render(
217235
<TestComponent

src/components/HrTools/Shared/CalculationReports/PanelLayout/PanelLayout.tsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ export interface IconPanelItem {
2020
icon: React.ReactNode;
2121
label: string;
2222
isActive?: boolean;
23+
disabled?: boolean;
2324
onClick: () => void;
2425
}
2526

@@ -144,6 +145,7 @@ export const PanelLayout: React.FC<PanelLayoutProps> = ({
144145
key={item.key}
145146
aria-label={item.label}
146147
aria-current={item.isActive ? 'step' : undefined}
148+
disabled={item.disabled}
147149
sx={{
148150
color: item.isActive
149151
? theme.palette.mpdxBlue.main

0 commit comments

Comments
 (0)