diff --git a/src/components/Payroll/PayrollFlow/payrollStateMachine.ts b/src/components/Payroll/PayrollFlow/payrollStateMachine.ts index 6c4e16bdc..4c4ceeeb3 100644 --- a/src/components/Payroll/PayrollFlow/payrollStateMachine.ts +++ b/src/components/Payroll/PayrollFlow/payrollStateMachine.ts @@ -48,7 +48,7 @@ export const payrollFlowBreadcrumbsNodes: BreadcrumbNodes = { parent: null, item: { id: 'landing', - label: 'labels.breadcrumbLabel', + label: 'breadcrumbs.landing', namespace: 'Payroll.PayrollLanding', onNavigate: ((ctx: PayrollFlowContextInterface) => ({ ...ctx, @@ -90,6 +90,14 @@ export const payrollFlowBreadcrumbsNodes: BreadcrumbNodes = { })) as (context: unknown) => unknown, }, }, + submittedOverview: { + parent: 'landing', + item: { + id: 'submittedOverview', + label: 'breadcrumbs.overview', + namespace: 'Payroll.PayrollLanding', + }, + }, editEmployee: { parent: 'configuration', item: { @@ -106,6 +114,14 @@ export const payrollFlowBreadcrumbsNodes: BreadcrumbNodes = { namespace: 'Payroll.PayrollReceipts', }, }, + submittedReceipts: { + parent: 'landing', + item: { + id: 'submittedReceipts', + label: 'breadcrumbs.receipt', + namespace: 'Payroll.PayrollLanding', + }, + }, blockers: { parent: 'landing', item: { @@ -300,7 +316,23 @@ export const payrollMachine = { }, ), ), - + transition( + componentEvents.RUN_PAYROLL_PROCESSED, + 'submittedOverview', + reduce((ctx: PayrollFlowContextInterface): PayrollFlowContextInterface => { + return { + ...updateBreadcrumbs('submittedOverview', ctx, { + startDate: ctx.payPeriod?.startDate ?? '', + endDate: ctx.payPeriod?.endDate ?? '', + }), + component: PayrollOverviewContextual, + ctaConfig: { + labelKey: 'exitFlowCta', + namespace: 'Payroll.PayrollOverview', + }, + } + }), + ), transition( componentEvents.RUN_PAYROLL_RECEIPT_GET, 'receipts', @@ -330,6 +362,45 @@ export const payrollMachine = { ), exitFlowTransition, ), + submittedOverview: state( + breadcrumbNavigateTransition('landing'), + transition( + componentEvents.RUN_PAYROLL_RECEIPT_GET, + 'submittedReceipts', + reduce((ctx: PayrollFlowContextInterface): PayrollFlowContextInterface => { + return { + ...updateBreadcrumbs('submittedReceipts', ctx, { + startDate: ctx.payPeriod?.startDate ?? '', + endDate: ctx.payPeriod?.endDate ?? '', + }), + component: PayrollReceiptsContextual, + progressBarType: 'breadcrumbs', + alerts: undefined, + ctaConfig: { + labelKey: 'exitFlowCta', + namespace: 'Payroll.PayrollReceipts', + }, + } + }), + ), + transition( + componentEvents.RUN_PAYROLL_CANCELLED, + 'landing', + reduce( + createReducer({ + component: PayrollLandingContextual, + progressBarType: null, + alerts: undefined, + currentBreadcrumbId: 'landing', + }), + ), + ), + exitFlowTransition, + ), + submittedReceipts: state( + breadcrumbNavigateTransition('landing'), + exitFlowTransition, + ), editEmployee: state( breadcrumbNavigateTransition('landing'), breadcrumbNavigateTransition('configuration'), diff --git a/src/components/Payroll/PayrollHistory/PayrollHistory.test.tsx b/src/components/Payroll/PayrollHistory/PayrollHistory.test.tsx index f4d8e5f3d..9ae642341 100644 --- a/src/components/Payroll/PayrollHistory/PayrollHistory.test.tsx +++ b/src/components/Payroll/PayrollHistory/PayrollHistory.test.tsx @@ -161,6 +161,8 @@ describe('PayrollHistory', () => { // Verify the correct event was emitted expect(onEvent).toHaveBeenCalledWith(componentEvents.RUN_PAYROLL_SUMMARY_VIEWED, { payrollId: 'payroll-1', + startDate: '2024-12-01', + endDate: '2024-12-15', }) }) @@ -182,6 +184,8 @@ describe('PayrollHistory', () => { expect(onEvent).toHaveBeenCalledWith(componentEvents.RUN_PAYROLL_RECEIPT_VIEWED, { payrollId: 'payroll-1', + startDate: '2024-12-01', + endDate: '2024-12-15', }) }) diff --git a/src/components/Payroll/PayrollHistory/PayrollHistory.tsx b/src/components/Payroll/PayrollHistory/PayrollHistory.tsx index d3f6dcd75..435e97bc4 100644 --- a/src/components/Payroll/PayrollHistory/PayrollHistory.tsx +++ b/src/components/Payroll/PayrollHistory/PayrollHistory.tsx @@ -77,12 +77,12 @@ export const Root = ({ onEvent, companyId, dictionary }: PayrollHistoryProps) => const payrollHistory = payrollsData.payrollList || [] - const handleViewSummary = (payrollId: string) => { - onEvent(componentEvents.RUN_PAYROLL_SUMMARY_VIEWED, { payrollId }) + const handleViewSummary = (payrollId: string, startDate?: string, endDate?: string) => { + onEvent(componentEvents.RUN_PAYROLL_SUMMARY_VIEWED, { payrollId, startDate, endDate }) } - const handleViewReceipt = (payrollId: string) => { - onEvent(componentEvents.RUN_PAYROLL_RECEIPT_VIEWED, { payrollId }) + const handleViewReceipt = (payrollId: string, startDate?: string, endDate?: string) => { + onEvent(componentEvents.RUN_PAYROLL_RECEIPT_VIEWED, { payrollId, startDate, endDate }) } const handleCancelPayroll = async (item: Payroll) => { diff --git a/src/components/Payroll/PayrollHistory/PayrollHistoryPresentation.tsx b/src/components/Payroll/PayrollHistory/PayrollHistoryPresentation.tsx index ca63ec3e1..e27fae82f 100644 --- a/src/components/Payroll/PayrollHistory/PayrollHistoryPresentation.tsx +++ b/src/components/Payroll/PayrollHistory/PayrollHistoryPresentation.tsx @@ -21,8 +21,8 @@ interface PayrollHistoryPresentationProps { wireInRequests: WireInRequest[] selectedTimeFilter: TimeFilterOption onTimeFilterChange: (value: TimeFilterOption) => void - onViewSummary: (payrollId: string) => void - onViewReceipt: (payrollId: string) => void + onViewSummary: (payrollId: string, startDate?: string, endDate?: string) => void + onViewReceipt: (payrollId: string, startDate?: string, endDate?: string) => void onCancelPayroll: (item: Payroll) => void cancelDialogItem: Payroll | null onCancelDialogOpen: (item: Payroll) => void @@ -140,14 +140,14 @@ export const PayrollHistoryPresentation = ({ label: t('menu.viewSummary'), icon: , onClick: () => { - onViewSummary(payrollId) + onViewSummary(payrollId, item.payPeriod?.startDate, item.payPeriod?.endDate) }, }, { label: t('menu.viewReceipt'), icon: , onClick: () => { - onViewReceipt(payrollId) + onViewReceipt(payrollId, item.payPeriod?.startDate, item.payPeriod?.endDate) }, }, ] diff --git a/src/components/Payroll/PayrollLanding/PayrollLanding.test.tsx b/src/components/Payroll/PayrollLanding/PayrollLanding.test.tsx index d826bb0a7..6e3c1179d 100644 --- a/src/components/Payroll/PayrollLanding/PayrollLanding.test.tsx +++ b/src/components/Payroll/PayrollLanding/PayrollLanding.test.tsx @@ -222,6 +222,8 @@ describe('PayrollLanding', () => { componentEvents.RUN_PAYROLL_SUMMARY_VIEWED, { payrollId: 'payroll-1', + startDate: '2024-12-01', + endDate: '2024-12-15', }, ) await waitFor(() => { @@ -257,7 +259,7 @@ describe('PayrollLanding', () => { // Verify the event was emitted to parent expect(defaultProps.onEvent).toHaveBeenCalledWith( componentEvents.RUN_PAYROLL_RECEIPT_VIEWED, - { payrollId: 'payroll-1' }, + { payrollId: 'payroll-1', startDate: '2024-12-01', endDate: '2024-12-15' }, ) }) }) diff --git a/src/components/Payroll/PayrollLanding/PayrollLanding.tsx b/src/components/Payroll/PayrollLanding/PayrollLanding.tsx index b33d43c8d..ca4964c90 100644 --- a/src/components/Payroll/PayrollLanding/PayrollLanding.tsx +++ b/src/components/Payroll/PayrollLanding/PayrollLanding.tsx @@ -1,7 +1,7 @@ import { useMemo } from 'react' import { createMachine } from 'robot3' import type { ConfirmWireDetailsComponentType } from '../ConfirmWireDetails/ConfirmWireDetails' -import { payrollLandingMachine } from './payrollLandingStateMachine' +import { payrollLandingMachine, payrollLandingBreadcrumbNodes } from './payrollLandingStateMachine' import { PayrollLandingTabsContextual, type PayrollLandingFlowContextInterface, @@ -11,6 +11,7 @@ import { Flow } from '@/components/Flow/Flow' import type { BaseComponentInterface } from '@/components/Base/Base' import { BaseComponent } from '@/components/Base/Base' import { useComponentDictionary } from '@/i18n' +import { buildBreadcrumbs } from '@/helpers/breadcrumbHelpers' interface PayrollLandingProps extends BaseComponentInterface<'Payroll.PayrollLanding'> { companyId: string @@ -47,6 +48,9 @@ export function PayrollLandingFlow({ selectedTab: 'run-payroll', withReimbursements, ConfirmWireDetailsComponent, + breadcrumbs: buildBreadcrumbs(payrollLandingBreadcrumbNodes), + currentBreadcrumbId: 'tabs', + progressBarType: null, }), ), [companyId, withReimbursements, ConfirmWireDetailsComponent], diff --git a/src/components/Payroll/PayrollLanding/PayrollLandingFlowComponents.tsx b/src/components/Payroll/PayrollLanding/PayrollLandingFlowComponents.tsx index af57ed701..f000df11d 100644 --- a/src/components/Payroll/PayrollLanding/PayrollLandingFlowComponents.tsx +++ b/src/components/Payroll/PayrollLanding/PayrollLandingFlowComponents.tsx @@ -31,6 +31,8 @@ export interface PayrollLandingFlowContextInterface extends FlowContextInterface selectedTab?: string withReimbursements: boolean ConfirmWireDetailsComponent?: ConfirmWireDetailsComponentType + startDate?: string + endDate?: string } export function PayrollLandingTabsContextual() { diff --git a/src/components/Payroll/PayrollLanding/payrollLandingStateMachine.ts b/src/components/Payroll/PayrollLanding/payrollLandingStateMachine.ts index 9b3cf5226..84ddd9085 100644 --- a/src/components/Payroll/PayrollLanding/payrollLandingStateMachine.ts +++ b/src/components/Payroll/PayrollLanding/payrollLandingStateMachine.ts @@ -7,19 +7,63 @@ import { } from './PayrollLandingFlowComponents' import { componentEvents } from '@/shared/constants' import type { MachineEventType, MachineTransition } from '@/types/Helpers' +import type { BreadcrumbNodes } from '@/components/Common/FlowBreadcrumbs/FlowBreadcrumbsTypes' +import { updateBreadcrumbs } from '@/helpers/breadcrumbHelpers' +import { createBreadcrumbNavigateTransition } from '@/components/Common/FlowBreadcrumbs/breadcrumbTransitionHelpers' type EventPayloads = { [componentEvents.RUN_PAYROLL_RECEIPT_VIEWED]: { payrollId: string + startDate?: string + endDate?: string } [componentEvents.RUN_PAYROLL_SUMMARY_VIEWED]: { payrollId: string + startDate?: string + endDate?: string } [componentEvents.RUN_PAYROLL_RECEIPT_GET]: { payrollId: string } } +export const payrollLandingBreadcrumbNodes: BreadcrumbNodes = { + tabs: { + parent: null, + item: { + id: 'tabs', + label: 'breadcrumbs.landing', + namespace: 'Payroll.PayrollLanding', + onNavigate: ((ctx: PayrollLandingFlowContextInterface) => ({ + ...ctx, + currentBreadcrumbId: 'tabs', + progressBarType: null, + component: PayrollLandingTabsContextual, + payrollUuid: undefined, + previousState: undefined, + startDate: undefined, + endDate: undefined, + })) as (context: unknown) => unknown, + }, + }, + overview: { + parent: 'tabs', + item: { + id: 'overview', + label: 'breadcrumbs.overview', + namespace: 'Payroll.PayrollLanding', + }, + }, + receipt: { + parent: 'tabs', + item: { + id: 'receipt', + label: 'breadcrumbs.receipt', + namespace: 'Payroll.PayrollLanding', + }, + }, +} as const + const createReducer = (props: Partial) => { return (ctx: PayrollLandingFlowContextInterface): PayrollLandingFlowContextInterface => ({ ...ctx, @@ -27,6 +71,9 @@ const createReducer = (props: Partial) => { }) } +const breadcrumbNavigateTransition = + createBreadcrumbNavigateTransition() + export const payrollLandingMachine = { tabs: state( transition( @@ -37,11 +84,17 @@ export const payrollLandingMachine = { ctx: PayrollLandingFlowContextInterface, ev: MachineEventType, ): PayrollLandingFlowContextInterface => ({ - ...ctx, + ...updateBreadcrumbs('receipt', ctx, { + startDate: ev.payload.startDate ?? '', + endDate: ev.payload.endDate ?? '', + }), component: PayrollLandingReceiptsContextual, payrollUuid: ev.payload.payrollId, previousState: 'tabs', - selectedTab: 'payroll-history', // Receipt viewed from payroll history tab + selectedTab: 'payroll-history', + progressBarType: 'breadcrumbs', + startDate: ev.payload.startDate, + endDate: ev.payload.endDate, }), ), ), @@ -53,16 +106,23 @@ export const payrollLandingMachine = { ctx: PayrollLandingFlowContextInterface, ev: MachineEventType, ): PayrollLandingFlowContextInterface => ({ - ...ctx, + ...updateBreadcrumbs('overview', ctx, { + startDate: ev.payload.startDate ?? '', + endDate: ev.payload.endDate ?? '', + }), component: PayrollLandingOverviewContextual, payrollUuid: ev.payload.payrollId, previousState: 'tabs', - selectedTab: 'payroll-history', // Summary viewed from payroll history tab + selectedTab: 'payroll-history', + progressBarType: 'breadcrumbs', + startDate: ev.payload.startDate, + endDate: ev.payload.endDate, }), ), ), ), overview: state( + breadcrumbNavigateTransition('tabs'), transition( componentEvents.RUN_PAYROLL_BACK, 'tabs', @@ -71,7 +131,10 @@ export const payrollLandingMachine = { component: PayrollLandingTabsContextual, payrollUuid: undefined, previousState: undefined, - // Preserve selectedTab when going back to tabs + progressBarType: null, + currentBreadcrumbId: 'tabs', + startDate: undefined, + endDate: undefined, }), ), ), @@ -84,23 +147,33 @@ export const payrollLandingMachine = { ev: MachineEventType, ): PayrollLandingFlowContextInterface => { return { - ...ctx, + ...updateBreadcrumbs('receipt', ctx, { + startDate: ctx.startDate ?? '', + endDate: ctx.endDate ?? '', + }), component: PayrollLandingReceiptsContextual, payrollUuid: ev.payload.payrollId, previousState: 'overview', + progressBarType: 'breadcrumbs', } }, ), ), ), receipt: state( + breadcrumbNavigateTransition('tabs'), transition( componentEvents.RUN_PAYROLL_BACK, 'overview', reduce( - createReducer({ + (ctx: PayrollLandingFlowContextInterface): PayrollLandingFlowContextInterface => ({ + ...updateBreadcrumbs('overview', ctx, { + startDate: ctx.startDate ?? '', + endDate: ctx.endDate ?? '', + }), component: PayrollLandingOverviewContextual, previousState: 'tabs', + progressBarType: 'breadcrumbs', }), ), guard((ctx: PayrollLandingFlowContextInterface) => { @@ -115,6 +188,10 @@ export const payrollLandingMachine = { component: PayrollLandingTabsContextual, payrollUuid: undefined, previousState: undefined, + progressBarType: null, + currentBreadcrumbId: 'tabs', + startDate: undefined, + endDate: undefined, }), ), guard((ctx: PayrollLandingFlowContextInterface) => { diff --git a/src/i18n/en/Payroll.PayrollLanding.json b/src/i18n/en/Payroll.PayrollLanding.json index 5676c81a3..b88fea135 100644 --- a/src/i18n/en/Payroll.PayrollLanding.json +++ b/src/i18n/en/Payroll.PayrollLanding.json @@ -7,7 +7,11 @@ "tabNavigation": "Payroll navigation" }, "labels": { - "loading": "Loading payroll data...", - "breadcrumbLabel": "Run Payroll" + "loading": "Loading payroll data..." + }, + "breadcrumbs": { + "landing": "Run payroll", + "overview": "Summary for {{startDate}}-{{endDate}}", + "receipt": "Payroll receipt for {{startDate}}-{{endDate}}" } } diff --git a/src/types/i18next.d.ts b/src/types/i18next.d.ts index 5e952bc41..b9783d9e7 100644 --- a/src/types/i18next.d.ts +++ b/src/types/i18next.d.ts @@ -1471,7 +1471,11 @@ export interface PayrollPayrollLanding{ }; "labels":{ "loading":string; -"breadcrumbLabel":string; +}; +"breadcrumbs":{ +"landing":string; +"overview":string; +"receipt":string; }; }; export interface PayrollPayrollList{