diff --git a/pages/accountLists/[accountListId]/reports/housingAllowance/[requestId].page.tsx b/pages/accountLists/[accountListId]/reports/housingAllowance/[requestId].page.tsx
index ff93fe8a63..84df44fb76 100644
--- a/pages/accountLists/[accountListId]/reports/housingAllowance/[requestId].page.tsx
+++ b/pages/accountLists/[accountListId]/reports/housingAllowance/[requestId].page.tsx
@@ -6,8 +6,12 @@ import { styled } from '@mui/material/styles';
import { useTranslation } from 'react-i18next';
import { blockImpersonatingNonDevelopers } from 'pages/api/utils/pagePropsHelpers';
import { SidePanelsLayout } from 'src/components/Layouts/SidePanelsLayout';
+import { DynamicExpensesClaim } from 'src/components/Reports/MinisterHousingAllowance/DynamicExpensesClaim/DynamicExpensesClaim';
import { RequestPage } from 'src/components/Reports/MinisterHousingAllowance/RequestPage/RequestPage';
-import { MinisterHousingAllowanceProvider } from 'src/components/Reports/MinisterHousingAllowance/Shared/Context/MinisterHousingAllowanceContext';
+import {
+ MinisterHousingAllowanceProvider,
+ useMinisterHousingAllowance,
+} from 'src/components/Reports/MinisterHousingAllowance/Shared/Context/MinisterHousingAllowanceContext';
import { PageEnum } from 'src/components/Reports/Shared/CalculationReports/Shared/sharedTypes';
import { SimpleScreenOnly } from 'src/components/Reports/styledComponents';
import {
@@ -23,11 +27,61 @@ const RequestPageWrapper = styled(Box)(({ theme }) => ({
backgroundColor: theme.palette.common.white,
}));
+interface HousingAllowanceRequestContentProps {
+ isNavListOpen: boolean;
+ onNavListToggle: () => void;
+}
+
+const HousingAllowanceRequestContent: React.FC<
+ HousingAllowanceRequestContentProps
+> = ({ isNavListOpen, onNavListToggle }) => {
+ const { t } = useTranslation();
+ const { isRightPanelOpen } = useMinisterHousingAllowance();
+
+ return (
+
+ }
+ leftOpen={isNavListOpen}
+ leftWidth="290px"
+ mainContent={
+ <>
+
+
+
+
+ >
+ }
+ rightPanel={isRightPanelOpen ? : undefined}
+ rightOpen={isRightPanelOpen}
+ rightWidth="35%"
+ />
+ );
+};
+
const HousingAllowanceRequestPage: React.FC = () => {
const { t } = useTranslation();
const router = useRouter();
const { requestId, mode } = router.query;
+ const [isNavListOpen, setIsNavListOpen] = useState(false);
+
+ const handleNavListToggle = () => {
+ setIsNavListOpen(!isNavListOpen);
+ };
+
if (!requestId) {
return ;
}
@@ -54,49 +108,21 @@ const HousingAllowanceRequestPage: React.FC = () => {
mode: pageType,
});
- const [isNavListOpen, setIsNavListOpen] = useState(false);
-
- const handleNavListToggle = () => {
- setIsNavListOpen(!isNavListOpen);
- };
-
return (
<>
{title}
-
- }
- leftOpen={isNavListOpen}
- leftWidth="290px"
- mainContent={
- <>
-
-
-
-
-
-
- >
- }
- />
+
+
+
>
);
diff --git a/pages/accountLists/[accountListId]/reports/housingAllowance/index.page.tsx b/pages/accountLists/[accountListId]/reports/housingAllowance/index.page.tsx
index 38a5834b55..676309a256 100644
--- a/pages/accountLists/[accountListId]/reports/housingAllowance/index.page.tsx
+++ b/pages/accountLists/[accountListId]/reports/housingAllowance/index.page.tsx
@@ -4,8 +4,12 @@ import { useTranslation } from 'react-i18next';
import { blockImpersonatingNonDevelopers } from 'pages/api/utils/pagePropsHelpers';
import { SidePanelsLayout } from 'src/components/Layouts/SidePanelsLayout';
import Loading from 'src/components/Loading';
+import { DynamicExpensesClaim } from 'src/components/Reports/MinisterHousingAllowance/DynamicExpensesClaim/DynamicExpensesClaim';
import { MinisterHousingAllowanceReport } from 'src/components/Reports/MinisterHousingAllowance/MinisterHousingAllowance';
-import { MinisterHousingAllowanceProvider } from 'src/components/Reports/MinisterHousingAllowance/Shared/Context/MinisterHousingAllowanceContext';
+import {
+ MinisterHousingAllowanceProvider,
+ useMinisterHousingAllowance,
+} from 'src/components/Reports/MinisterHousingAllowance/Shared/Context/MinisterHousingAllowanceContext';
import { NoStaffAccount } from 'src/components/Reports/Shared/NoStaffAccount/NoStaffAccount';
import { useStaffAccountQuery } from 'src/components/Reports/StaffAccount.generated';
import {
@@ -20,6 +24,49 @@ import {
import { ReportPageWrapper } from 'src/components/Shared/styledComponents/ReportPageWrapper';
import useGetAppSettings from 'src/hooks/useGetAppSettings';
+interface MinisterHousingAllowanceContentProps {
+ isNavListOpen: boolean;
+ onNavListToggle: () => void;
+}
+
+const MinisterHousingAllowanceContent: React.FC<
+ MinisterHousingAllowanceContentProps
+> = ({ isNavListOpen, onNavListToggle }) => {
+ const { t } = useTranslation();
+ const { isRightPanelOpen } = useMinisterHousingAllowance();
+
+ return (
+
+ }
+ leftOpen={isNavListOpen}
+ leftWidth="290px"
+ headerHeight={multiPageHeaderHeight}
+ mainContent={
+ <>
+
+
+ >
+ }
+ rightPanel={isRightPanelOpen ? : undefined}
+ rightOpen={isRightPanelOpen}
+ rightWidth="35%"
+ />
+ );
+};
+
const MinisterHousingAllowancePage: React.FC = () => {
const { t } = useTranslation();
const { appName } = useGetAppSettings();
@@ -38,33 +85,12 @@ const MinisterHousingAllowancePage: React.FC = () => {
{staffAccountData?.staffAccount?.id ? (
-
- }
- leftOpen={isNavListOpen}
- leftWidth="290px"
- headerHeight={multiPageHeaderHeight}
- mainContent={
- <>
-
-
-
-
- >
- }
- />
+
+
+
) : loading ? (
diff --git a/src/components/Reports/MinisterHousingAllowance/DynamicExpensesClaim/DynamicExpensesClaim.tsx b/src/components/Reports/MinisterHousingAllowance/DynamicExpensesClaim/DynamicExpensesClaim.tsx
new file mode 100644
index 0000000000..5743aef4e1
--- /dev/null
+++ b/src/components/Reports/MinisterHousingAllowance/DynamicExpensesClaim/DynamicExpensesClaim.tsx
@@ -0,0 +1,11 @@
+import dynamic from 'next/dynamic';
+import { DynamicComponentPlaceholder } from 'src/components/DynamicPlaceholders/DynamicComponentPlaceholder';
+
+export const preloadExpensesClaim = () =>
+ import(/* webpackChunkName: "ExpensesClaim" */ './ExpensesClaim').then(
+ ({ ExpensesClaim }) => ExpensesClaim,
+ );
+
+export const DynamicExpensesClaim = dynamic(preloadExpensesClaim, {
+ loading: DynamicComponentPlaceholder,
+});
diff --git a/src/components/Reports/MinisterHousingAllowance/DynamicExpensesClaim/ExpensesClaim.test.tsx b/src/components/Reports/MinisterHousingAllowance/DynamicExpensesClaim/ExpensesClaim.test.tsx
new file mode 100644
index 0000000000..4f720108e0
--- /dev/null
+++ b/src/components/Reports/MinisterHousingAllowance/DynamicExpensesClaim/ExpensesClaim.test.tsx
@@ -0,0 +1,54 @@
+import React from 'react';
+import { ThemeProvider } from '@mui/material/styles';
+import { render } from '@testing-library/react';
+import userEvent from '@testing-library/user-event';
+import { GqlMockedProvider } from '__tests__/util/graphqlMocking';
+import theme from 'src/theme';
+import {
+ ContextType,
+ MinisterHousingAllowanceContext,
+} from '../Shared/Context/MinisterHousingAllowanceContext';
+import { ExpensesClaim } from './ExpensesClaim';
+
+const setIsRightPanelOpen = jest.fn();
+
+interface TestComponentProps {
+ contextValue?: Partial;
+}
+
+const TestComponent: React.FC = ({ contextValue }) => (
+
+
+
+
+
+
+
+);
+
+describe('ExpensesClaim', () => {
+ it('renders component', () => {
+ const { getByText, getByTestId } = render(
+ ,
+ );
+
+ expect(
+ getByText('What expenses can I claim on my MHA?'),
+ ).toBeInTheDocument();
+ expect(getByTestId('CloseIcon')).toBeInTheDocument();
+ expect(getByText('Allowable Expenses for MHA')).toBeInTheDocument();
+ });
+
+ it('closes the panel when close icon is clicked', async () => {
+ const { getByTestId } = render(
+ ,
+ );
+
+ const closeIcon = getByTestId('CloseIcon');
+ userEvent.click(closeIcon);
+
+ expect(setIsRightPanelOpen).toHaveBeenCalledWith(false);
+ });
+});
diff --git a/src/components/Reports/MinisterHousingAllowance/DynamicExpensesClaim/ExpensesClaim.tsx b/src/components/Reports/MinisterHousingAllowance/DynamicExpensesClaim/ExpensesClaim.tsx
new file mode 100644
index 0000000000..1848b57eda
--- /dev/null
+++ b/src/components/Reports/MinisterHousingAllowance/DynamicExpensesClaim/ExpensesClaim.tsx
@@ -0,0 +1,33 @@
+import React from 'react';
+import { Close, RequestPageSharp } from '@mui/icons-material';
+import { Box, Container, IconButton, Typography } from '@mui/material';
+import { useTranslation } from 'react-i18next';
+import theme from 'src/theme';
+import { useMinisterHousingAllowance } from '../Shared/Context/MinisterHousingAllowanceContext';
+
+export const ExpensesClaim: React.FC = () => {
+ const { t } = useTranslation();
+ const { setIsRightPanelOpen } = useMinisterHousingAllowance();
+
+ return (
+
+
+
+ {t('What expenses can I claim on my MHA?')}
+
+ setIsRightPanelOpen(false)}>
+
+
+
+
+
+
+
+
+ {t('Allowable Expenses for MHA')}
+
+
+
+
+ );
+};
diff --git a/src/components/Reports/MinisterHousingAllowance/Shared/Context/MinisterHousingAllowanceContext.tsx b/src/components/Reports/MinisterHousingAllowance/Shared/Context/MinisterHousingAllowanceContext.tsx
index 8fd2142579..7850ba7c92 100644
--- a/src/components/Reports/MinisterHousingAllowance/Shared/Context/MinisterHousingAllowanceContext.tsx
+++ b/src/components/Reports/MinisterHousingAllowance/Shared/Context/MinisterHousingAllowanceContext.tsx
@@ -50,6 +50,8 @@ export type ContextType = {
spouseHcmData?: HcmData | null;
preferredName: string;
spousePreferredName: string;
+ isRightPanelOpen: boolean;
+ setIsRightPanelOpen: Dispatch>;
requestData?:
| MinistryHousingAllowanceRequestQuery['ministryHousingAllowanceRequest']
@@ -112,6 +114,7 @@ export const MinisterHousingAllowanceProvider: React.FC = ({
} = useStepList(FormEnum.MHA, type);
const [isComplete, setIsComplete] = useState(false);
+ const [isRightPanelOpen, setIsRightPanelOpen] = useState(false);
const steps = useMemo(() => {
if (!isComplete) {
@@ -205,6 +208,8 @@ export const MinisterHousingAllowanceProvider: React.FC = ({
isPrint,
setIsPrint,
setIsComplete,
+ isRightPanelOpen,
+ setIsRightPanelOpen,
requestData: requestData?.ministryHousingAllowanceRequest ?? null,
requestError,
requestId,
@@ -231,6 +236,8 @@ export const MinisterHousingAllowanceProvider: React.FC = ({
isPrint,
setIsPrint,
setIsComplete,
+ isRightPanelOpen,
+ setIsRightPanelOpen,
requestData,
requestError,
requestId,
diff --git a/src/components/Reports/MinisterHousingAllowance/Steps/StepOne/AboutForm.test.tsx b/src/components/Reports/MinisterHousingAllowance/Steps/StepOne/AboutForm.test.tsx
index d6071b7596..649205dbb0 100644
--- a/src/components/Reports/MinisterHousingAllowance/Steps/StepOne/AboutForm.test.tsx
+++ b/src/components/Reports/MinisterHousingAllowance/Steps/StepOne/AboutForm.test.tsx
@@ -1,30 +1,41 @@
import React from 'react';
import { ThemeProvider } from '@mui/material/styles';
import { render } from '@testing-library/react';
+import userEvent from '@testing-library/user-event';
import { Formik } from 'formik';
import TestRouter from '__tests__/util/TestRouter';
import { GqlMockedProvider } from '__tests__/util/graphqlMocking';
import { PageEnum } from 'src/components/Reports/Shared/CalculationReports/Shared/sharedTypes';
import theme from 'src/theme';
-import { MinisterHousingAllowanceProvider } from '../../Shared/Context/MinisterHousingAllowanceContext';
+import {
+ ContextType,
+ MinisterHousingAllowanceContext,
+} from '../../Shared/Context/MinisterHousingAllowanceContext';
import { AboutForm } from './AboutForm';
const submit = jest.fn();
+const setIsRightPanelOpen = jest.fn();
const boardApprovedAt = '2024-09-15';
const availabilityDate = '2024-10-01';
-const TestComponent: React.FC = () => (
+interface TestComponentProps {
+ contextValue?: Partial;
+}
+
+const TestComponent: React.FC = ({ contextValue }) => (
-
+
-
+
@@ -32,7 +43,9 @@ const TestComponent: React.FC = () => (
describe('AboutForm', () => {
it('renders form and formatted dates', () => {
- const { getByText, getByRole } = render();
+ const { getByText, getByRole } = render(
+ ,
+ );
expect(
getByRole('heading', { name: 'About this Form' }),
@@ -47,4 +60,20 @@ describe('AboutForm', () => {
expect(getByRole('button', { name: 'Continue' })).toBeInTheDocument();
});
+
+ it('should open right panel when link is clicked', async () => {
+ const { findByText } = render(
+ ,
+ );
+
+ const link = await findByText(/what expenses can i claim on my mha/i);
+ userEvent.click(link);
+
+ expect(setIsRightPanelOpen).toHaveBeenCalledWith(true);
+ });
});
diff --git a/src/components/Reports/MinisterHousingAllowance/Steps/StepOne/AboutForm.tsx b/src/components/Reports/MinisterHousingAllowance/Steps/StepOne/AboutForm.tsx
index 947b5d711f..0c8be71ad4 100644
--- a/src/components/Reports/MinisterHousingAllowance/Steps/StepOne/AboutForm.tsx
+++ b/src/components/Reports/MinisterHousingAllowance/Steps/StepOne/AboutForm.tsx
@@ -20,10 +20,11 @@ export const AboutForm: React.FC = ({
const { t } = useTranslation();
const locale = useLocale();
- const { handleNextStep, handlePreviousStep } = useMinisterHousingAllowance();
+ const { handleNextStep, handlePreviousStep, setIsRightPanelOpen } =
+ useMinisterHousingAllowance();
// TODO: "newRequestAboutForm" value needs to be added to translation files to see all values
- // TODO: Get correct link for "Salary Calculation Form" and "What expenses can I claim on my MHA?"
+ // TODO: Get correct link for "Salary Calculation Form"
const nextYear = DateTime.now().year + 1;
@@ -101,7 +102,11 @@ export const AboutForm: React.FC = ({
fontSize="medium"
sx={{ verticalAlign: 'middle', opacity: 0.56 }}
/>{' '}
-
+ setIsRightPanelOpen(true)}
+ >
What expenses can I claim on my MHA?
diff --git a/src/components/Reports/MinisterHousingAllowance/Steps/StepThree/Calculation.test.tsx b/src/components/Reports/MinisterHousingAllowance/Steps/StepThree/Calculation.test.tsx
index 6a26d376e9..7c3e479caf 100644
--- a/src/components/Reports/MinisterHousingAllowance/Steps/StepThree/Calculation.test.tsx
+++ b/src/components/Reports/MinisterHousingAllowance/Steps/StepThree/Calculation.test.tsx
@@ -22,6 +22,7 @@ const mutationSpy = jest.fn();
const setHasCalcValues = jest.fn();
const setIsPrint = jest.fn();
const updateMutation = jest.fn();
+const setIsRightPanelOpen = jest.fn();
interface TestComponentProps {
contextValue: Partial;
@@ -351,6 +352,26 @@ describe('Calculation', () => {
);
});
+ it('should open right panel when link is clicked', async () => {
+ const { findByText } = render(
+ ,
+ );
+
+ const link = await findByText(/what expenses can i claim on my mha/i);
+ userEvent.click(link);
+
+ expect(setIsRightPanelOpen).toHaveBeenCalledWith(true);
+ });
+
describe('isViewPage behavior', () => {
it('renders view only mode', () => {
const { getByRole, queryByRole, getByText } = render(
diff --git a/src/components/Reports/MinisterHousingAllowance/Steps/StepThree/Calculation.tsx b/src/components/Reports/MinisterHousingAllowance/Steps/StepThree/Calculation.tsx
index b5128f56d2..8c1f6518b3 100644
--- a/src/components/Reports/MinisterHousingAllowance/Steps/StepThree/Calculation.tsx
+++ b/src/components/Reports/MinisterHousingAllowance/Steps/StepThree/Calculation.tsx
@@ -113,6 +113,7 @@ export const Calculation: React.FC = ({
requestData,
updateMutation,
userHcmData,
+ setIsRightPanelOpen,
} = useMinisterHousingAllowance();
const updateCheckbox = (value: boolean) =>
@@ -281,7 +282,13 @@ export const Calculation: React.FC = ({
fontSize="medium"
sx={{ verticalAlign: 'middle', opacity: 0.56 }}
/>{' '}
-
+ {
+ setIsRightPanelOpen(true);
+ }}
+ >
What expenses can I claim on my MHA?