@gusto/embedded-react-sdk 0.56.4 → 0.56.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (101) hide show
  1. package/CHANGELOG.md +13 -0
  2. package/dist/components/Common/DocumentEmbed/DocumentEmbed.js +18 -0
  3. package/dist/components/Common/DocumentEmbed/DocumentEmbed.js.map +1 -0
  4. package/dist/components/Common/DocumentViewer/DocumentViewer.js +35 -29
  5. package/dist/components/Common/DocumentViewer/DocumentViewer.js.map +1 -1
  6. package/dist/components/Company/AssignSignatory/CreateSignatory/useCreateSignatory.js +6 -3
  7. package/dist/components/Company/AssignSignatory/CreateSignatory/useCreateSignatory.js.map +1 -1
  8. package/dist/components/Company/AssignSignatory/InviteSignatory/useInviteSignatory.js +6 -3
  9. package/dist/components/Company/AssignSignatory/InviteSignatory/useInviteSignatory.js.map +1 -1
  10. package/dist/components/Company/AssignSignatory/useAssignSignatory.js +8 -5
  11. package/dist/components/Company/AssignSignatory/useAssignSignatory.js.map +1 -1
  12. package/dist/components/Company/BankAccount/BankAccountForm/context.js +6 -3
  13. package/dist/components/Company/BankAccount/BankAccountForm/context.js.map +1 -1
  14. package/dist/components/Company/DocumentSigner/DocumentList/useDocumentList.js +6 -3
  15. package/dist/components/Company/DocumentSigner/DocumentList/useDocumentList.js.map +1 -1
  16. package/dist/components/Company/FederalTaxes/useFederalTaxes.js +11 -8
  17. package/dist/components/Company/FederalTaxes/useFederalTaxes.js.map +1 -1
  18. package/dist/components/Company/Industry/Context.js +9 -6
  19. package/dist/components/Company/Industry/Context.js.map +1 -1
  20. package/dist/components/Company/Locations/LocationForm/useLocationForm.js +6 -3
  21. package/dist/components/Company/Locations/LocationForm/useLocationForm.js.map +1 -1
  22. package/dist/components/Company/Locations/LocationsList/useLocationsList.js +6 -3
  23. package/dist/components/Company/Locations/LocationsList/useLocationsList.js.map +1 -1
  24. package/dist/components/Company/OnboardingOverview/context.js +6 -3
  25. package/dist/components/Company/OnboardingOverview/context.js.map +1 -1
  26. package/dist/components/Company/StateTaxes/StateTaxesForm/context.js +6 -3
  27. package/dist/components/Company/StateTaxes/StateTaxesForm/context.js.map +1 -1
  28. package/dist/components/Company/StateTaxes/StateTaxesList/context.js +6 -3
  29. package/dist/components/Company/StateTaxes/StateTaxesList/context.js.map +1 -1
  30. package/dist/components/Company/StateTaxes/TaxRateManagement/context.js +6 -3
  31. package/dist/components/Company/StateTaxes/TaxRateManagement/context.js.map +1 -1
  32. package/dist/components/Contractor/ContractorList/management/ManagementContractorList.js +64 -61
  33. package/dist/components/Contractor/ContractorList/management/ManagementContractorList.js.map +1 -1
  34. package/dist/components/Contractor/ContractorList/management/ManagementContractorListView.js +133 -134
  35. package/dist/components/Contractor/ContractorList/management/ManagementContractorListView.js.map +1 -1
  36. package/dist/components/Contractor/ContractorListFlow/ContractorListFlow.js.map +1 -1
  37. package/dist/components/Contractor/ContractorListFlow/ContractorListFlowComponents.js +22 -9
  38. package/dist/components/Contractor/ContractorListFlow/ContractorListFlowComponents.js.map +1 -1
  39. package/dist/components/Contractor/ContractorListFlow/contractorListStateMachine.js +51 -20
  40. package/dist/components/Contractor/ContractorListFlow/contractorListStateMachine.js.map +1 -1
  41. package/dist/components/Contractor/Dismissal/Dismissal.js +77 -0
  42. package/dist/components/Contractor/Dismissal/Dismissal.js.map +1 -0
  43. package/dist/components/Contractor/Dismissal/DismissalPresentation.js +57 -0
  44. package/dist/components/Contractor/Dismissal/DismissalPresentation.js.map +1 -0
  45. package/dist/components/Contractor/Dismissal/useDismissal/useDismissal.js +44 -0
  46. package/dist/components/Contractor/Dismissal/useDismissal/useDismissal.js.map +1 -0
  47. package/dist/components/Contractor/Payments/PaymentStatement/PaymentStatementPresentation.js +45 -41
  48. package/dist/components/Contractor/Payments/PaymentStatement/PaymentStatementPresentation.js.map +1 -1
  49. package/dist/components/Contractor/exports/contractorManagement.js +56 -54
  50. package/dist/components/Contractor/exports/contractorManagement.js.map +1 -1
  51. package/dist/components/Employee/Documents/onboarding/DocumentSigner/DocumentList/useDocumentList.js +6 -3
  52. package/dist/components/Employee/Documents/onboarding/DocumentSigner/DocumentList/useDocumentList.js.map +1 -1
  53. package/dist/components/Payroll/GrossUpModal/GrossUpModal.js +3 -2
  54. package/dist/components/Payroll/GrossUpModal/GrossUpModal.js.map +1 -1
  55. package/dist/components/Payroll/PayrollEditEmployee/PayrollEditEmployeePresentation.js +201 -196
  56. package/dist/components/Payroll/PayrollEditEmployee/PayrollEditEmployeePresentation.js.map +1 -1
  57. package/dist/components/Payroll/PayrollEditEmployee/shared/usePayrollEditEmployeeForm/fields.js +55 -52
  58. package/dist/components/Payroll/PayrollEditEmployee/shared/usePayrollEditEmployeeForm/fields.js.map +1 -1
  59. package/dist/components/Payroll/PayrollEditEmployee/shared/usePayrollEditEmployeeForm/payrollEditEmployeeSchema.js +38 -29
  60. package/dist/components/Payroll/PayrollEditEmployee/shared/usePayrollEditEmployeeForm/payrollEditEmployeeSchema.js.map +1 -1
  61. package/dist/components/Payroll/PayrollExecutionFlow/payrollExecutionMachine.js +17 -14
  62. package/dist/components/Payroll/PayrollExecutionFlow/payrollExecutionMachine.js.map +1 -1
  63. package/dist/components/Payroll/UNSTABLE_PayrollEditEmployee/UNSTABLE_PayrollEditEmployee.js +72 -68
  64. package/dist/components/Payroll/UNSTABLE_PayrollEditEmployee/UNSTABLE_PayrollEditEmployee.js.map +1 -1
  65. package/dist/components/Payroll/usePreparedPayrollData.js +10 -7
  66. package/dist/components/Payroll/usePreparedPayrollData.js.map +1 -1
  67. package/dist/contexts/ComponentAdapter/useComponentContext.js.map +1 -1
  68. package/dist/i18n/I18n.js +1 -0
  69. package/dist/i18n/I18n.js.map +1 -1
  70. package/dist/i18n/en/Contractor.Dismissal.json.js +20 -0
  71. package/dist/i18n/en/Contractor.Dismissal.json.js.map +1 -0
  72. package/dist/i18n/en/Contractor.Payments.PaymentStatement.json.js +2 -2
  73. package/dist/i18n/en/Payroll.PayrollEditEmployee.json.js +38 -38
  74. package/dist/i18n/en/Payroll.UNSTABLE_PayrollEditEmployee.json.js +31 -31
  75. package/dist/i18n/en/common.json.js +37 -35
  76. package/dist/i18n/en/common.json.js.map +1 -1
  77. package/dist/package.json.js +1 -1
  78. package/dist/shared/constants.js +1 -0
  79. package/dist/shared/constants.js.map +1 -1
  80. package/dist/src/components/Common/DocumentEmbed/DocumentEmbed.d.ts +3 -0
  81. package/dist/src/components/Common/DocumentEmbed/DocumentEmbedTypes.d.ts +25 -0
  82. package/dist/src/components/Common/DocumentEmbed/index.d.ts +2 -0
  83. package/dist/src/components/Contractor/ContractorList/management/ManagementContractorList.d.ts +2 -0
  84. package/dist/src/components/Contractor/ContractorList/management/ManagementContractorListView.d.ts +3 -1
  85. package/dist/src/components/Contractor/ContractorListFlow/ContractorListFlow.d.ts +6 -4
  86. package/dist/src/components/Contractor/ContractorListFlow/ContractorListFlowComponents.d.ts +2 -0
  87. package/dist/src/components/Contractor/ContractorListFlow/contractorListStateMachine.d.ts +1 -0
  88. package/dist/src/components/Contractor/ContractorListFlow/contractorListStateMachine.test.d.ts +1 -0
  89. package/dist/src/components/Contractor/Dismissal/Dismissal.d.ts +45 -0
  90. package/dist/src/components/Contractor/Dismissal/DismissalPresentation.d.ts +17 -0
  91. package/dist/src/components/Contractor/Dismissal/useDismissal/useDismissal.d.ts +41 -0
  92. package/dist/src/components/Contractor/Dismissal/useDismissal/useDismissal.test.d.ts +1 -0
  93. package/dist/src/components/Contractor/exports/contractorManagement.d.ts +1 -0
  94. package/dist/src/components/Payroll/PayrollEditEmployee/shared/usePayrollEditEmployeeForm/payrollEditEmployeeSchema.d.ts +19 -0
  95. package/dist/src/contexts/ComponentAdapter/componentAdapterTypes.d.ts +1 -0
  96. package/dist/src/contexts/ComponentAdapter/useComponentContext.d.ts +5 -2
  97. package/dist/src/i18n/en/common.json.d.ts +3 -0
  98. package/dist/src/i18n/types.d.ts +47 -0
  99. package/dist/src/shared/constants.d.ts +2 -0
  100. package/docs/guides/endpoint-inventory.json +18 -0
  101. package/package.json +1 -1
@@ -1 +1 @@
1
- {"version":3,"file":"PayrollEditEmployeePresentation.js","sources":["../../../../src/components/Payroll/PayrollEditEmployee/PayrollEditEmployeePresentation.tsx"],"sourcesContent":["import { FormProvider, useFieldArray, useForm, useWatch } from 'react-hook-form'\nimport { useMemo, useRef, useState } from 'react'\nimport classNames from 'classnames'\nimport type { Employee } from '@gusto/embedded-api/models/components/employee'\nimport type {\n FixedCompensations,\n PayrollEmployeeCompensationsType,\n PayrollEmployeeCompensationsTypePaidTimeOff,\n Reimbursements as Reimbursement,\n} from '@gusto/embedded-api/models/components/payrollemployeecompensationstype'\nimport { PayrollEmployeeCompensationsTypePaymentMethod } from '@gusto/embedded-api/models/components/payrollemployeecompensationstype'\nimport type { PayrollFixedCompensationTypesType } from '@gusto/embedded-api/models/components/payrollfixedcompensationtypestype'\nimport type { PayScheduleShow as PayScheduleObject } from '@gusto/embedded-api/models/components/payscheduleshow'\nimport { useTranslation } from 'react-i18next'\nimport { z } from 'zod'\nimport { zodResolver } from '@hookform/resolvers/zod'\nimport styles from './PayrollEditEmployeePresentation.module.scss'\nimport { TimeOffField, PayoutTimeOffField } from './TimeOffField'\nimport {\n Flex,\n Grid,\n TextInputField,\n RadioGroupField,\n DataView,\n useDataView,\n EmptyData,\n} from '@/components/Common'\nimport { useComponentContext } from '@/contexts/ComponentAdapter/useComponentContext'\nimport { useI18n } from '@/i18n'\nimport { Form } from '@/components/Common/Form'\nimport {\n formatNumberAsCurrency,\n firstLastName,\n stripLeadingZeros,\n} from '@/helpers/formattedStrings'\nimport { getAdditionalEarningsCompensations, calculateGrossPay } from '@/components/Payroll/helpers'\nimport { PayrollCategory, isOffCyclePayroll } from '@/components/Payroll/payrollTypes'\nimport {\n COMPENSATION_NAME_DOUBLE_OVERTIME,\n COMPENSATION_NAME_OVERTIME,\n COMPENSATION_NAME_REGULAR_HOURS,\n HOURS_COMPENSATION_NAMES,\n EXCLUDED_ADDITIONAL_EARNINGS,\n COMPENSATION_NAME_REIMBURSEMENT,\n COMPENSATION_NAME_BONUS,\n COMPENSATION_NAME_PAYCHECK_TIPS,\n COMPENSATION_NAME_CORRECTION_PAYMENT,\n COMPENSATION_NAME_COMMISSION,\n COMPENSATION_NAME_CASH_TIPS,\n} from '@/shared/constants'\nimport useContainerBreakpoints from '@/hooks/useContainerBreakpoints/useContainerBreakpoints'\nimport PlusCircleIcon from '@/assets/icons/plus-circle.svg?react'\nimport TrashCanSvg from '@/assets/icons/trashcan.svg?react'\n\ninterface PayrollEditEmployeeProps {\n /** CSS class name applied to the root element. */\n className?: string\n onSave: (updatedCompensation: PayrollEmployeeCompensationsType) => void\n onCancel: () => void\n employee: Employee\n employeeCompensation?: PayrollEmployeeCompensationsType\n isPending?: boolean\n fixedCompensationTypes: PayrollFixedCompensationTypesType[]\n payPeriodStartDate?: string\n paySchedule?: PayScheduleObject\n payrollCategory?: PayrollCategory\n withReimbursements?: boolean\n hasDirectDepositSetup?: boolean\n}\n\nconst ReimbursementFormSchema = z.object({\n uuid: z.string().nullable().optional(),\n description: z.string(),\n amount: z.string(),\n recurring: z.boolean().optional(),\n})\n\nconst DraftReimbursementSchema = z.object({\n description: z.string(),\n amount: z.string().refine(\n val => {\n const num = parseFloat(val)\n return !Number.isNaN(num) && num > 0\n },\n { message: 'validations.reimbursementAmount' },\n ),\n})\n\n// A native `min={0}` only constrains the stepper: it does not stop a typed \"-50\", and the\n// SDK's <form> is noValidate so the browser never enforces it either. Negative amounts\n// therefore reached the platform and came back only as a submit-time error (SDK-1285).\n// Applied via z.record below, this covers every additional earning -- correction payment\n// included -- because they all share the fixedCompensations record.\nconst nonNegativeAmountSchema = z\n .string()\n .optional()\n .refine(val => !val || parseFloat(val) >= 0, { message: 'validations.negativeAmount' })\n\nconst PayrollEditEmployeeFormSchema = z.object({\n hourlyCompensations: z.record(z.string(), z.record(z.string(), z.string().optional())),\n timeOffCompensations: z.record(z.string(), z.string().optional()),\n finalPayoutCompensations: z.record(z.string(), z.string().optional()),\n fixedCompensations: z.record(z.string(), nonNegativeAmountSchema),\n reimbursements: z.array(ReimbursementFormSchema),\n paymentMethod: z.enum(PayrollEmployeeCompensationsTypePaymentMethod).optional(),\n})\n\n/** @internal */\nexport type PayrollEditEmployeeFormValues = z.infer<typeof PayrollEditEmployeeFormSchema>\n\nconst buildCompensationFromFormData = (\n formData: PayrollEditEmployeeFormValues,\n employeeCompensation: PayrollEmployeeCompensationsType | undefined,\n timeOff: PayrollEmployeeCompensationsTypePaidTimeOff[],\n primaryJobUuid?: string,\n payrollCategory: PayrollCategory = PayrollCategory.Regular,\n): PayrollEmployeeCompensationsType => {\n const updatedCompensation = {\n ...employeeCompensation,\n paymentMethod: formData.paymentMethod,\n }\n\n updatedCompensation.hourlyCompensations = employeeCompensation?.hourlyCompensations?.map(\n compensation => {\n const hours =\n compensation.jobUuid && compensation.name\n ? formData.hourlyCompensations[compensation.jobUuid]?.[compensation.name]\n : undefined\n return hours\n ? {\n ...compensation,\n hours,\n }\n : compensation\n },\n )\n\n updatedCompensation.paidTimeOff = timeOff.map(timeOffEntry => {\n const isDismissal = payrollCategory === PayrollCategory.Dismissal\n const { finalPayoutUnusedHoursInput: _, ...timeOffWithoutPayout } = timeOffEntry\n\n if (isDismissal) {\n const finalPayout =\n formData.finalPayoutCompensations[timeOffEntry.name!] ??\n timeOffEntry.finalPayoutUnusedHoursInput\n return {\n ...timeOffEntry,\n hours: formData.timeOffCompensations[timeOffEntry.name!] || '0',\n ...(finalPayout != null ? { finalPayoutUnusedHoursInput: finalPayout || '0' } : {}),\n }\n }\n\n return {\n ...timeOffWithoutPayout,\n hours: formData.timeOffCompensations[timeOffEntry.name!] || '0',\n }\n })\n\n // Off-cycle payrolls today use the legacy single Reimbursement field in fixed_compensations\n // because the backend feature flag `emb_off_cycle_disable_named_reimbursements` (default: true,\n // expected removal 2026-09-01) rejects named entries in the itemized `reimbursements[]` array.\n // TODO(post-2026-09-01): once that flag is removed, unify on the itemized path for all categories.\n const usesItemizedReimbursements = !isOffCyclePayroll(payrollCategory)\n\n const updatedFixedCompensations: FixedCompensations[] = []\n\n Object.entries(formData.fixedCompensations).forEach(([fixedCompensationName, formAmount]) => {\n const isReimbursementEntry =\n fixedCompensationName.toLowerCase() === COMPENSATION_NAME_REIMBURSEMENT.toLowerCase()\n\n // Regular payrolls write reimbursements via the itemized array; never let the legacy\n // fixed_compensations entry slip through (the backend rejects it on v2025-11-15+).\n if (isReimbursementEntry && usesItemizedReimbursements) {\n return\n }\n\n const existingFixedCompensation = employeeCompensation?.fixedCompensations?.find(\n fixedCompensation =>\n fixedCompensation.name?.toLowerCase() === fixedCompensationName.toLowerCase(),\n )\n\n // Clearing the field means \"no additional earning\". For an entry that already has a\n // saved amount we have to send an explicit 0: omitting it leaves the previously saved\n // value in place server-side, so the box looked empty while the old amount survived\n // the save (SDK-1284). This makes clearing behave exactly like typing 0. An entry with\n // no saved compensation stays omitted -- there is nothing to zero out.\n const resolvedAmount = formAmount === '' && existingFixedCompensation ? '0' : formAmount\n\n if (resolvedAmount !== undefined && resolvedAmount !== '') {\n if (existingFixedCompensation) {\n updatedFixedCompensations.push({\n name: existingFixedCompensation.name,\n jobUuid: existingFixedCompensation.jobUuid,\n amount: resolvedAmount,\n })\n } else if (parseFloat(resolvedAmount) !== 0) {\n updatedFixedCompensations.push({\n name: fixedCompensationName,\n jobUuid: primaryJobUuid,\n amount: resolvedAmount,\n })\n }\n }\n })\n\n updatedCompensation.fixedCompensations = updatedFixedCompensations\n\n if (usesItemizedReimbursements) {\n updatedCompensation.reimbursements = formData.reimbursements.map(reimbursement => ({\n amount: reimbursement.amount,\n description:\n reimbursement.description.trim() === '' ? null : reimbursement.description.trim(),\n uuid: reimbursement.uuid ?? null,\n recurring: reimbursement.recurring,\n }))\n } else {\n // Off-cycle: ensure no itemized array leaks through. The container also strips this defensively.\n updatedCompensation.reimbursements = []\n }\n\n return updatedCompensation\n}\n\n/** @internal */\nexport const PayrollEditEmployeePresentation = ({\n className,\n onSave,\n onCancel,\n employee,\n employeeCompensation,\n isPending = false,\n fixedCompensationTypes,\n payPeriodStartDate,\n paySchedule,\n payrollCategory = PayrollCategory.Regular,\n withReimbursements = true,\n hasDirectDepositSetup = true,\n}: PayrollEditEmployeeProps) => {\n const { Button, ButtonIcon, Heading, Text } = useComponentContext()\n\n const { t } = useTranslation('Payroll.PayrollEditEmployee')\n useI18n('Payroll.PayrollEditEmployee')\n\n const primaryJob = employee.jobs?.find(job => job.primary)\n const primaryJobHasHourlyCompensations = employeeCompensation?.hourlyCompensations?.some(\n c => c.jobUuid === primaryJob?.uuid,\n )\n const hourlyJobs = primaryJob && primaryJobHasHourlyCompensations ? [primaryJob] : []\n\n const containerRef = useRef<HTMLDivElement>(null)\n const breakpoints = useContainerBreakpoints({\n ref: containerRef,\n })\n const isSmallOrGreater = breakpoints.includes('small')\n\n employeeCompensation?.hourlyCompensations?.forEach(compensation => {\n const job = employee.jobs?.find(job => job.uuid === compensation.jobUuid)\n if (job && !hourlyJobs.find(hourlyJob => hourlyJob.uuid === job.uuid)) {\n hourlyJobs.push(job)\n }\n })\n\n const timeOff = (employeeCompensation?.paidTimeOff || []).filter(entry => entry.name)\n\n const additionalEarnings = getAdditionalEarningsCompensations({\n flsaStatus: primaryJob?.compensations?.[0]?.flsaStatus,\n existingFixedCompensations: employeeCompensation?.fixedCompensations || [],\n primaryJobUuid: primaryJob?.uuid,\n fixedCompensationTypes,\n excludedTypes: EXCLUDED_ADDITIONAL_EARNINGS,\n })\n\n // Off-cycle payrolls use the legacy single Reimbursement field in fixed_compensations because\n // the backend `emb_off_cycle_disable_named_reimbursements` flag (default: true, expected\n // removal 2026-09-01) rejects named entries in the itemized `reimbursements[]` array.\n // TODO(post-2026-09-01): unify on the itemized path once that flag is removed.\n const usesItemizedReimbursements = !isOffCyclePayroll(payrollCategory)\n\n const initialReimbursements: Reimbursement[] = useMemo(\n () =>\n withReimbursements && usesItemizedReimbursements\n ? (employeeCompensation?.reimbursements ?? [])\n : [],\n [withReimbursements, usesItemizedReimbursements, employeeCompensation?.reimbursements],\n )\n\n const existingReimbursementFixedCompensation = useMemo(\n () =>\n employeeCompensation?.fixedCompensations?.find(\n comp => comp.name?.toLowerCase() === COMPENSATION_NAME_REIMBURSEMENT.toLowerCase(),\n ),\n [employeeCompensation?.fixedCompensations],\n )\n\n const showLegacyReimbursementField =\n withReimbursements && !usesItemizedReimbursements && Boolean(primaryJob?.uuid)\n\n const findMatchingCompensation = (jobUuid: string, compensationName: string) => {\n return employeeCompensation?.hourlyCompensations?.find(\n compensation =>\n compensation.jobUuid === jobUuid &&\n compensation.name?.toLowerCase() === compensationName.toLowerCase(),\n )\n }\n\n const getCompensationLabel = (compensationName?: string) => {\n switch (compensationName) {\n case COMPENSATION_NAME_REGULAR_HOURS:\n return t('compensationNames.regularHours')\n case COMPENSATION_NAME_OVERTIME:\n return t('compensationNames.overtime')\n case COMPENSATION_NAME_DOUBLE_OVERTIME:\n return t('compensationNames.doubleOvertime')\n default:\n return compensationName\n }\n }\n\n const getFixedCompensationLabel = (compensationName?: string) => {\n switch (compensationName) {\n case COMPENSATION_NAME_BONUS:\n return t('fixedCompensationNames.bonus')\n case COMPENSATION_NAME_PAYCHECK_TIPS:\n return t('fixedCompensationNames.paycheckTips')\n case COMPENSATION_NAME_CORRECTION_PAYMENT:\n return t('fixedCompensationNames.correctionPayment')\n case COMPENSATION_NAME_COMMISSION:\n return t('fixedCompensationNames.commission')\n case COMPENSATION_NAME_CASH_TIPS:\n return t('fixedCompensationNames.cashTips')\n case COMPENSATION_NAME_REIMBURSEMENT:\n return t('fixedCompensationNames.reimbursement')\n default:\n return compensationName\n }\n }\n\n const resolveDefaultPaymentMethod = () => {\n const preparedPaymentMethod = employeeCompensation?.paymentMethod\n\n if (!preparedPaymentMethod) {\n return hasDirectDepositSetup\n ? PayrollEmployeeCompensationsTypePaymentMethod.DirectDeposit\n : PayrollEmployeeCompensationsTypePaymentMethod.Check\n }\n\n if (\n !hasDirectDepositSetup &&\n preparedPaymentMethod === PayrollEmployeeCompensationsTypePaymentMethod.DirectDeposit\n ) {\n return PayrollEmployeeCompensationsTypePaymentMethod.Check\n }\n\n return preparedPaymentMethod\n }\n\n const defaultValues = {\n hourlyCompensations: (() => {\n const hourlyCompensations: PayrollEditEmployeeFormValues['hourlyCompensations'] = {}\n\n hourlyJobs.forEach(hourlyJob => {\n HOURS_COMPENSATION_NAMES.forEach(compensationName => {\n const matchingCompensation = findMatchingCompensation(hourlyJob.uuid, compensationName)\n if (matchingCompensation) {\n if (!hourlyCompensations[hourlyJob.uuid]) {\n hourlyCompensations[hourlyJob.uuid] = {}\n }\n hourlyCompensations[hourlyJob.uuid]![matchingCompensation.name!] =\n matchingCompensation.hours ? parseFloat(matchingCompensation.hours).toString() : ''\n }\n })\n })\n\n return hourlyCompensations\n })(),\n\n timeOffCompensations: (() => {\n const timeOffCompensations: PayrollEditEmployeeFormValues['timeOffCompensations'] = {}\n\n timeOff.forEach(timeOffCompensation => {\n timeOffCompensations[timeOffCompensation.name!] = timeOffCompensation.hours\n ? parseFloat(timeOffCompensation.hours).toString()\n : ''\n })\n\n return timeOffCompensations\n })(),\n\n finalPayoutCompensations: (() => {\n const finalPayoutCompensations: PayrollEditEmployeeFormValues['finalPayoutCompensations'] = {}\n\n timeOff.forEach(timeOffCompensation => {\n finalPayoutCompensations[timeOffCompensation.name!] =\n timeOffCompensation.finalPayoutUnusedHoursInput ?? '0'\n })\n\n return finalPayoutCompensations\n })(),\n\n fixedCompensations: (() => {\n const fixedCompensations: PayrollEditEmployeeFormValues['fixedCompensations'] = {}\n\n additionalEarnings.forEach(fixedComp => {\n fixedCompensations[fixedComp.name!] = fixedComp.amount ?? ''\n })\n\n if (showLegacyReimbursementField) {\n fixedCompensations[COMPENSATION_NAME_REIMBURSEMENT] =\n existingReimbursementFixedCompensation?.amount ?? '0.00'\n }\n\n return fixedCompensations\n })(),\n\n reimbursements: initialReimbursements.map(reimbursement => ({\n uuid: reimbursement.uuid ?? null,\n description: reimbursement.description ?? '',\n amount: reimbursement.amount,\n recurring: reimbursement.recurring ?? false,\n })),\n\n paymentMethod: resolveDefaultPaymentMethod(),\n }\n\n const formHandlers = useForm<PayrollEditEmployeeFormValues>({\n resolver: zodResolver(PayrollEditEmployeeFormSchema),\n defaultValues,\n })\n\n const {\n fields: reimbursementFields,\n append: appendReimbursement,\n remove: removeReimbursement,\n update: updateReimbursement,\n } = useFieldArray({\n control: formHandlers.control,\n name: 'reimbursements',\n })\n\n const handleRemoveReimbursement = (index: number) => {\n const field = reimbursementFields[index]\n if (!field) return\n\n if (field.uuid) {\n updateReimbursement(index, { ...field, amount: '0' })\n } else {\n removeReimbursement(index)\n }\n }\n\n type VisibleReimbursementRow = (typeof reimbursementFields)[number] & {\n originalIndex: number\n }\n\n const visibleReimbursementRows: VisibleReimbursementRow[] = reimbursementFields\n .map((field, originalIndex) => ({ ...field, originalIndex }))\n .filter(row => parseFloat(row.amount || '0') !== 0)\n\n const [isAddingReimbursement, setIsAddingReimbursement] = useState(false)\n\n type DraftReimbursementValues = z.infer<typeof DraftReimbursementSchema>\n\n const draftForm = useForm<DraftReimbursementValues>({\n resolver: zodResolver(DraftReimbursementSchema),\n defaultValues: { description: '', amount: '' },\n })\n\n const resetReimbursementDraft = () => {\n setIsAddingReimbursement(false)\n draftForm.reset()\n }\n\n const onDraftReimbursementValid = (data: DraftReimbursementValues) => {\n const parsedAmount = parseFloat(data.amount)\n appendReimbursement({\n uuid: null,\n description: data.description.trim(),\n amount: parsedAmount.toFixed(2),\n recurring: false,\n })\n resetReimbursementDraft()\n }\n\n const reimbursementDataViewProps = useDataView<VisibleReimbursementRow>({\n data: visibleReimbursementRows,\n columns: [\n {\n key: 'description',\n title: t('reimbursementDescriptionColumn'),\n render: row => row.description.trim() || t('reimbursementUnnamedFallback'),\n },\n {\n key: 'amount',\n title: t('reimbursementAmountColumn'),\n justify: 'end',\n render: row => formatNumberAsCurrency(parseFloat(row.amount || '0')),\n },\n {\n key: 'recurring',\n title: t('reimbursementTypeColumn'),\n render: row =>\n row.recurring ? t('reimbursementTypeRecurring') : t('reimbursementTypeOneTime'),\n },\n ],\n itemMenu: row => {\n if (row.recurring) return null\n const displayDescription = row.description.trim() || t('reimbursementUnnamedFallback')\n return (\n <ButtonIcon\n variant=\"tertiary\"\n onClick={() => {\n handleRemoveReimbursement(row.originalIndex)\n }}\n aria-label={t('removeReimbursementLabel', { description: displayDescription })}\n >\n <TrashCanSvg aria-hidden />\n </ButtonIcon>\n )\n },\n emptyState: () => (\n <EmptyData title={t('reimbursementEmptyTitle')}>\n <Button\n variant=\"secondary\"\n onClick={() => {\n setIsAddingReimbursement(true)\n }}\n icon={<PlusCircleIcon aria-hidden />}\n >\n {t('addReimbursementCta')}\n </Button>\n </EmptyData>\n ),\n })\n\n const watchedFormData = useWatch({\n control: formHandlers.control,\n })\n\n const currentGrossPay = useMemo(() => {\n try {\n const hourlyCompensations: Record<string, Record<string, string | undefined>> = {}\n if (watchedFormData.hourlyCompensations) {\n Object.entries(watchedFormData.hourlyCompensations).forEach(([jobId, compensations]) => {\n if (compensations) {\n hourlyCompensations[jobId] = compensations\n }\n })\n }\n\n const reimbursementsWithDefaults: PayrollEditEmployeeFormValues['reimbursements'] = (\n watchedFormData.reimbursements ?? []\n ).map(reimbursement => ({\n uuid: reimbursement.uuid ?? null,\n description: reimbursement.description ?? '',\n amount: reimbursement.amount ?? '0',\n recurring: reimbursement.recurring,\n }))\n\n const formDataWithDefaults: PayrollEditEmployeeFormValues = {\n hourlyCompensations,\n timeOffCompensations: watchedFormData.timeOffCompensations || {},\n finalPayoutCompensations: watchedFormData.finalPayoutCompensations || {},\n fixedCompensations: watchedFormData.fixedCompensations || {},\n reimbursements: reimbursementsWithDefaults,\n paymentMethod: watchedFormData.paymentMethod,\n }\n\n const updatedCompensation = buildCompensationFromFormData(\n formDataWithDefaults,\n employeeCompensation,\n (employeeCompensation?.paidTimeOff || []).filter(entry => entry.name),\n primaryJob?.uuid,\n payrollCategory,\n )\n\n return calculateGrossPay(\n updatedCompensation,\n employee,\n payPeriodStartDate,\n paySchedule,\n payrollCategory,\n )\n } catch {\n return employeeCompensation\n ? calculateGrossPay(\n employeeCompensation,\n employee,\n payPeriodStartDate,\n paySchedule,\n payrollCategory,\n )\n : 0\n }\n }, [\n watchedFormData,\n employeeCompensation,\n primaryJob?.uuid,\n employee,\n payPeriodStartDate,\n paySchedule,\n payrollCategory,\n ])\n\n const employeeName = firstLastName({\n first_name: employee.firstName,\n last_name: employee.lastName,\n })\n\n const onSubmit = (data: PayrollEditEmployeeFormValues) => {\n const updatedCompensation = buildCompensationFromFormData(\n data,\n employeeCompensation,\n timeOff,\n primaryJob?.uuid,\n payrollCategory,\n )\n onSave(updatedCompensation)\n }\n\n const formattedCurrentGrossPay = formatNumberAsCurrency(currentGrossPay || 0)\n\n const actions = (\n <Flex\n flexDirection={isSmallOrGreater ? 'row' : 'column'}\n justifyContent={isSmallOrGreater ? 'flex-end' : 'normal'}\n alignItems={isSmallOrGreater ? 'flex-start' : 'stretch'}\n gap={12}\n >\n <Button variant=\"secondary\" onClick={onCancel} title={t('cancelCta')}>\n {t('cancelCta')}\n </Button>\n <Button\n onClick={formHandlers.handleSubmit(onSubmit)}\n title={t('saveCta')}\n isLoading={isPending}\n >\n {t('saveCta')}\n </Button>\n </Flex>\n )\n\n return (\n <div ref={containerRef} className={classNames(styles.container, className)}>\n <div\n className={`${styles.headerSection} ${!isSmallOrGreater ? styles.headerSectionSticky : ''}`}\n >\n <Flex justifyContent=\"space-between\">\n <Flex flexDirection=\"column\" alignItems=\"stretch\" gap={isSmallOrGreater ? 8 : 2}>\n <Heading as=\"h1\" styledAs={isSmallOrGreater ? 'h2' : 'h4'}>\n {t('pageTitle', { employeeName })}\n </Heading>\n {isSmallOrGreater ? (\n <Flex flexDirection=\"column\" gap={6}>\n <Heading as=\"h2\" styledAs=\"h3\">\n {formattedCurrentGrossPay}\n </Heading>\n <Text className={styles.grossPayLabel}>{t('grossPayLabel')}</Text>\n </Flex>\n ) : (\n <Heading as=\"h2\" styledAs=\"h6\" className={styles.grossPayLabel}>\n {t('grossPayLabelMobile', { grossPay: formattedCurrentGrossPay })}\n </Heading>\n )}\n </Flex>\n {isSmallOrGreater && actions}\n </Flex>\n </div>\n <FormProvider {...formHandlers}>\n <Form>\n {hourlyJobs.length > 0 && (\n <div className={styles.fieldGroup}>\n <Heading as=\"h3\">{t('regularHoursTitle')}</Heading>\n {hourlyJobs.map(hourlyJob => (\n <Flex key={hourlyJob.uuid} flexDirection=\"column\" gap={8}>\n {hourlyJobs.length > 1 && <Heading as=\"h4\">{hourlyJob.title}</Heading>}\n <Grid gridTemplateColumns={{ base: '1fr', small: [320, 320] }} gap={20}>\n {HOURS_COMPENSATION_NAMES.map(compensationName => {\n const employeeHourlyCompensation = findMatchingCompensation(\n hourlyJob.uuid,\n compensationName,\n )\n if (employeeHourlyCompensation) {\n return (\n <TextInputField\n key={compensationName}\n type=\"number\"\n min={0}\n transform={stripLeadingZeros}\n adornmentEnd={t('hoursUnit')}\n label={getCompensationLabel(compensationName)}\n name={`hourlyCompensations.${hourlyJob.uuid}.${employeeHourlyCompensation.name}`}\n />\n )\n }\n })}\n </Grid>\n </Flex>\n ))}\n </div>\n )}\n {timeOff.length > 0 && (\n <div className={styles.fieldGroup}>\n <Heading as=\"h3\" styledAs=\"h4\">\n {payrollCategory === PayrollCategory.Dismissal\n ? t('timeOffTitleDismissal')\n : t('timeOffTitle')}\n </Heading>\n <Grid gridTemplateColumns={{ base: '1fr', small: [320, 320] }} gap={20}>\n {timeOff.map(timeOffEntry => (\n <TimeOffField\n key={timeOffEntry.name}\n timeOff={timeOffEntry}\n employee={employee}\n />\n ))}\n </Grid>\n </div>\n )}\n {payrollCategory === PayrollCategory.Dismissal && timeOff.length > 0 && (\n <div className={styles.fieldGroup}>\n <Flex flexDirection=\"column\" gap={4}>\n <Heading as=\"h3\" styledAs=\"h4\">\n {t('finalPayoutTitle')}\n </Heading>\n <Text variant=\"supporting\">{t('finalPayoutDescription')}</Text>\n </Flex>\n <Grid gridTemplateColumns={{ base: '1fr', small: [320, 320] }} gap={20}>\n {timeOff.map(timeOffEntry => (\n <PayoutTimeOffField\n key={`payout-${timeOffEntry.name}`}\n timeOff={timeOffEntry}\n employee={employee}\n />\n ))}\n </Grid>\n </div>\n )}\n {additionalEarnings.length > 0 && (\n <div className={styles.fieldGroup}>\n <Heading as=\"h3\" styledAs=\"h4\">\n {t('additionalEarningsTitle')}\n </Heading>\n <Grid\n gridTemplateColumns={{ base: '1fr', small: [320, 320], large: [320, 320, 320] }}\n gap={20}\n >\n {additionalEarnings.map(fixedCompensation => (\n <TextInputField\n key={fixedCompensation.name}\n type=\"number\"\n min={0}\n transform={stripLeadingZeros}\n adornmentStart=\"$\"\n label={getFixedCompensationLabel(fixedCompensation.name)}\n name={`fixedCompensations.${fixedCompensation.name}`}\n // useField only surfaces this once react-hook-form has flagged the\n // field, and the schema's only rule here is the negative-amount check.\n errorMessage={t('validations.negativeAmount')}\n />\n ))}\n </Grid>\n </div>\n )}\n {showLegacyReimbursementField && (\n <div className={styles.fieldGroup}>\n <Heading as=\"h3\" styledAs=\"h4\">\n {t('reimbursementTitle')}\n </Heading>\n <Grid gridTemplateColumns={{ base: '1fr', small: [320, 320] }} gap={20}>\n <TextInputField\n type=\"number\"\n min={0}\n transform={stripLeadingZeros}\n adornmentStart=\"$\"\n label={getFixedCompensationLabel(COMPENSATION_NAME_REIMBURSEMENT)}\n name={`fixedCompensations.${COMPENSATION_NAME_REIMBURSEMENT}`}\n errorMessage={t('validations.negativeAmount')}\n />\n </Grid>\n </div>\n )}\n {withReimbursements && usesItemizedReimbursements && (\n <div className={styles.fieldGroup}>\n <Heading as=\"h3\" styledAs=\"h4\">\n {t('reimbursementTitle')}\n </Heading>\n {!(visibleReimbursementRows.length === 0 && isAddingReimbursement) && (\n <DataView label={t('reimbursementsTableLabel')} {...reimbursementDataViewProps} />\n )}\n {isAddingReimbursement ? (\n <FormProvider {...draftForm}>\n <Flex flexDirection=\"column\" gap={12}>\n <Grid gridTemplateColumns={{ base: '1fr', small: [320, 320] }} gap={20}>\n <TextInputField\n name=\"description\"\n label={t('reimbursementDescriptionLabel')}\n placeholder={t('reimbursementDescriptionPlaceholder')}\n />\n <TextInputField\n name=\"amount\"\n type=\"number\"\n min={0}\n transform={stripLeadingZeros}\n adornmentStart=\"$\"\n isRequired\n label={t('reimbursementAmountLabel')}\n errorMessage={t('validations.reimbursementAmount')}\n />\n </Grid>\n <Flex gap={12}>\n <Button onClick={draftForm.handleSubmit(onDraftReimbursementValid)}>\n {t('saveReimbursementCta')}\n </Button>\n <Button variant=\"secondary\" onClick={resetReimbursementDraft}>\n {t('cancelReimbursementCta')}\n </Button>\n </Flex>\n </Flex>\n </FormProvider>\n ) : (\n visibleReimbursementRows.length > 0 && (\n <div>\n <Button\n variant=\"secondary\"\n onClick={() => {\n setIsAddingReimbursement(true)\n }}\n title={t('addReimbursementLink')}\n icon={<PlusCircleIcon aria-hidden />}\n >\n {t('addReimbursementLink')}\n </Button>\n </div>\n )\n )}\n </div>\n )}\n {hasDirectDepositSetup && (\n <div className={styles.fieldGroup}>\n <Heading as=\"h3\" styledAs=\"h4\">\n {t('paymentMethodTitle')}\n </Heading>\n <RadioGroupField\n name=\"paymentMethod\"\n isRequired\n label={t('paymentMethodLabel')}\n description={t('paymentMethodDescription')}\n options={[\n {\n value: PayrollEmployeeCompensationsTypePaymentMethod.DirectDeposit,\n label: t('paymentMethodOptions.directDeposit'),\n },\n {\n value: PayrollEmployeeCompensationsTypePaymentMethod.Check,\n label: t('paymentMethodOptions.check'),\n },\n ]}\n />\n </div>\n )}\n </Form>\n {!isSmallOrGreater && actions}\n </FormProvider>\n </div>\n )\n}\n"],"names":["ReimbursementFormSchema","z","DraftReimbursementSchema","val","num","nonNegativeAmountSchema","PayrollEditEmployeeFormSchema","PayrollEmployeeCompensationsTypePaymentMethod","buildCompensationFromFormData","formData","employeeCompensation","timeOff","primaryJobUuid","payrollCategory","PayrollCategory","updatedCompensation","compensation","hours","timeOffEntry","isDismissal","_","timeOffWithoutPayout","finalPayout","usesItemizedReimbursements","isOffCyclePayroll","updatedFixedCompensations","fixedCompensationName","formAmount","COMPENSATION_NAME_REIMBURSEMENT","existingFixedCompensation","fixedCompensation","resolvedAmount","reimbursement","PayrollEditEmployeePresentation","className","onSave","onCancel","employee","isPending","fixedCompensationTypes","payPeriodStartDate","paySchedule","withReimbursements","hasDirectDepositSetup","Button","ButtonIcon","Heading","Text","useComponentContext","t","useTranslation","useI18n","primaryJob","job","primaryJobHasHourlyCompensations","c","hourlyJobs","containerRef","useRef","isSmallOrGreater","useContainerBreakpoints","hourlyJob","entry","additionalEarnings","getAdditionalEarningsCompensations","EXCLUDED_ADDITIONAL_EARNINGS","initialReimbursements","useMemo","existingReimbursementFixedCompensation","comp","showLegacyReimbursementField","findMatchingCompensation","jobUuid","compensationName","getCompensationLabel","COMPENSATION_NAME_REGULAR_HOURS","COMPENSATION_NAME_OVERTIME","COMPENSATION_NAME_DOUBLE_OVERTIME","getFixedCompensationLabel","COMPENSATION_NAME_BONUS","COMPENSATION_NAME_PAYCHECK_TIPS","COMPENSATION_NAME_CORRECTION_PAYMENT","COMPENSATION_NAME_COMMISSION","COMPENSATION_NAME_CASH_TIPS","resolveDefaultPaymentMethod","preparedPaymentMethod","defaultValues","hourlyCompensations","HOURS_COMPENSATION_NAMES","matchingCompensation","timeOffCompensations","timeOffCompensation","finalPayoutCompensations","fixedCompensations","fixedComp","formHandlers","useForm","zodResolver","reimbursementFields","appendReimbursement","removeReimbursement","updateReimbursement","useFieldArray","handleRemoveReimbursement","index","field","visibleReimbursementRows","originalIndex","row","isAddingReimbursement","setIsAddingReimbursement","useState","draftForm","resetReimbursementDraft","onDraftReimbursementValid","data","parsedAmount","reimbursementDataViewProps","useDataView","formatNumberAsCurrency","displayDescription","jsx","TrashCanSvg","EmptyData","PlusCircleIcon","watchedFormData","useWatch","currentGrossPay","jobId","compensations","reimbursementsWithDefaults","formDataWithDefaults","calculateGrossPay","employeeName","firstLastName","onSubmit","formattedCurrentGrossPay","actions","jsxs","Flex","classNames","styles","FormProvider","Form","Grid","employeeHourlyCompensation","TextInputField","stripLeadingZeros","TimeOffField","PayoutTimeOffField","DataView","RadioGroupField"],"mappings":"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"}
1
+ {"version":3,"file":"PayrollEditEmployeePresentation.js","sources":["../../../../src/components/Payroll/PayrollEditEmployee/PayrollEditEmployeePresentation.tsx"],"sourcesContent":["import { FormProvider, useFieldArray, useForm, useWatch } from 'react-hook-form'\nimport { useMemo, useRef, useState } from 'react'\nimport classNames from 'classnames'\nimport type { Employee } from '@gusto/embedded-api/models/components/employee'\nimport type {\n FixedCompensations,\n PayrollEmployeeCompensationsType,\n PayrollEmployeeCompensationsTypePaidTimeOff,\n Reimbursements as Reimbursement,\n} from '@gusto/embedded-api/models/components/payrollemployeecompensationstype'\nimport { PayrollEmployeeCompensationsTypePaymentMethod } from '@gusto/embedded-api/models/components/payrollemployeecompensationstype'\nimport type { PayrollFixedCompensationTypesType } from '@gusto/embedded-api/models/components/payrollfixedcompensationtypestype'\nimport type { PayScheduleShow as PayScheduleObject } from '@gusto/embedded-api/models/components/payscheduleshow'\nimport { useTranslation } from 'react-i18next'\nimport { z } from 'zod'\nimport { zodResolver } from '@hookform/resolvers/zod'\nimport styles from './PayrollEditEmployeePresentation.module.scss'\nimport { TimeOffField, PayoutTimeOffField } from './TimeOffField'\nimport {\n Flex,\n Grid,\n TextInputField,\n RadioGroupField,\n DataView,\n useDataView,\n EmptyData,\n} from '@/components/Common'\nimport { useComponentContext } from '@/contexts/ComponentAdapter/useComponentContext'\nimport { useI18n } from '@/i18n'\nimport { Form } from '@/components/Common/Form'\nimport {\n formatNumberAsCurrency,\n firstLastName,\n stripLeadingZeros,\n} from '@/helpers/formattedStrings'\nimport { getAdditionalEarningsCompensations, calculateGrossPay } from '@/components/Payroll/helpers'\nimport { PayrollCategory, isOffCyclePayroll } from '@/components/Payroll/payrollTypes'\nimport {\n COMPENSATION_NAME_DOUBLE_OVERTIME,\n COMPENSATION_NAME_OVERTIME,\n COMPENSATION_NAME_REGULAR_HOURS,\n HOURS_COMPENSATION_NAMES,\n EXCLUDED_ADDITIONAL_EARNINGS,\n COMPENSATION_NAME_REIMBURSEMENT,\n COMPENSATION_NAME_BONUS,\n COMPENSATION_NAME_PAYCHECK_TIPS,\n COMPENSATION_NAME_CORRECTION_PAYMENT,\n COMPENSATION_NAME_COMMISSION,\n COMPENSATION_NAME_CASH_TIPS,\n} from '@/shared/constants'\nimport useContainerBreakpoints from '@/hooks/useContainerBreakpoints/useContainerBreakpoints'\nimport PlusCircleIcon from '@/assets/icons/plus-circle.svg?react'\nimport TrashCanSvg from '@/assets/icons/trashcan.svg?react'\n\ninterface PayrollEditEmployeeProps {\n /** CSS class name applied to the root element. */\n className?: string\n onSave: (updatedCompensation: PayrollEmployeeCompensationsType) => void\n onCancel: () => void\n employee: Employee\n employeeCompensation?: PayrollEmployeeCompensationsType\n isPending?: boolean\n fixedCompensationTypes: PayrollFixedCompensationTypesType[]\n payPeriodStartDate?: string\n paySchedule?: PayScheduleObject\n payrollCategory?: PayrollCategory\n withReimbursements?: boolean\n hasDirectDepositSetup?: boolean\n}\n\nconst ReimbursementFormSchema = z.object({\n uuid: z.string().nullable().optional(),\n description: z.string(),\n amount: z.string(),\n recurring: z.boolean().optional(),\n})\n\n// Mirrors the server's fixed reimbursement cap (payroll_core_data's\n// Reimbursements::MAX_AMOUNT) so an over-limit value is caught inline instead\n// of round-tripping to a 422.\nconst MAX_REIMBURSEMENT_AMOUNT = 1_000_000\n\nconst DraftReimbursementSchema = z.object({\n description: z.string(),\n amount: z\n .string()\n .refine(\n val => {\n const num = parseFloat(val)\n return !Number.isNaN(num) && num > 0\n },\n { message: 'validations.reimbursementAmount' },\n )\n .refine(val => parseFloat(val) <= MAX_REIMBURSEMENT_AMOUNT, {\n message: 'validations.maxReimbursementAmount',\n }),\n})\n\n// A native `min={0}` only constrains the stepper: it does not stop a typed \"-50\", and the\n// SDK's <form> is noValidate so the browser never enforces it either. Negative amounts\n// therefore reached the platform and came back only as a submit-time error (SDK-1285).\n// Applied via z.record below, this covers every additional earning -- correction payment\n// included -- because they all share the fixedCompensations record.\nconst nonNegativeAmountSchema = z\n .string()\n .optional()\n .refine(val => !val || parseFloat(val) >= 0, { message: 'validations.negativeAmount' })\n\n// Mirrors the server's fixed hours cap (draft_payrolls' MAX_HOURS) so an\n// over-limit value is caught inline instead of round-tripping to a 422.\nconst MAX_HOURS = 99_999\n\nconst hoursAmountSchema = z\n .string()\n .optional()\n .refine(val => !val || parseFloat(val) <= MAX_HOURS, { message: 'validations.maxHours' })\n\nconst PayrollEditEmployeeFormSchema = z.object({\n hourlyCompensations: z.record(z.string(), z.record(z.string(), hoursAmountSchema)),\n timeOffCompensations: z.record(z.string(), z.string().optional()),\n finalPayoutCompensations: z.record(z.string(), z.string().optional()),\n fixedCompensations: z.record(z.string(), nonNegativeAmountSchema),\n reimbursements: z.array(ReimbursementFormSchema),\n paymentMethod: z.enum(PayrollEmployeeCompensationsTypePaymentMethod).optional(),\n})\n\n/** @internal */\nexport type PayrollEditEmployeeFormValues = z.infer<typeof PayrollEditEmployeeFormSchema>\n\nconst buildCompensationFromFormData = (\n formData: PayrollEditEmployeeFormValues,\n employeeCompensation: PayrollEmployeeCompensationsType | undefined,\n timeOff: PayrollEmployeeCompensationsTypePaidTimeOff[],\n primaryJobUuid?: string,\n payrollCategory: PayrollCategory = PayrollCategory.Regular,\n): PayrollEmployeeCompensationsType => {\n const updatedCompensation = {\n ...employeeCompensation,\n paymentMethod: formData.paymentMethod,\n }\n\n updatedCompensation.hourlyCompensations = employeeCompensation?.hourlyCompensations?.map(\n compensation => {\n const hours =\n compensation.jobUuid && compensation.name\n ? formData.hourlyCompensations[compensation.jobUuid]?.[compensation.name]\n : undefined\n return hours\n ? {\n ...compensation,\n hours,\n }\n : compensation\n },\n )\n\n updatedCompensation.paidTimeOff = timeOff.map(timeOffEntry => {\n const isDismissal = payrollCategory === PayrollCategory.Dismissal\n const { finalPayoutUnusedHoursInput: _, ...timeOffWithoutPayout } = timeOffEntry\n\n if (isDismissal) {\n const finalPayout =\n formData.finalPayoutCompensations[timeOffEntry.name!] ??\n timeOffEntry.finalPayoutUnusedHoursInput\n return {\n ...timeOffEntry,\n hours: formData.timeOffCompensations[timeOffEntry.name!] || '0',\n ...(finalPayout != null ? { finalPayoutUnusedHoursInput: finalPayout || '0' } : {}),\n }\n }\n\n return {\n ...timeOffWithoutPayout,\n hours: formData.timeOffCompensations[timeOffEntry.name!] || '0',\n }\n })\n\n // Off-cycle payrolls today use the legacy single Reimbursement field in fixed_compensations\n // because the backend feature flag `emb_off_cycle_disable_named_reimbursements` (default: true,\n // expected removal 2026-09-01) rejects named entries in the itemized `reimbursements[]` array.\n // TODO(post-2026-09-01): once that flag is removed, unify on the itemized path for all categories.\n const usesItemizedReimbursements = !isOffCyclePayroll(payrollCategory)\n\n const updatedFixedCompensations: FixedCompensations[] = []\n\n Object.entries(formData.fixedCompensations).forEach(([fixedCompensationName, formAmount]) => {\n const isReimbursementEntry =\n fixedCompensationName.toLowerCase() === COMPENSATION_NAME_REIMBURSEMENT.toLowerCase()\n\n // Regular payrolls write reimbursements via the itemized array; never let the legacy\n // fixed_compensations entry slip through (the backend rejects it on v2025-11-15+).\n if (isReimbursementEntry && usesItemizedReimbursements) {\n return\n }\n\n const existingFixedCompensation = employeeCompensation?.fixedCompensations?.find(\n fixedCompensation =>\n fixedCompensation.name?.toLowerCase() === fixedCompensationName.toLowerCase(),\n )\n\n // Clearing the field means \"no additional earning\". For an entry that already has a\n // saved amount we have to send an explicit 0: omitting it leaves the previously saved\n // value in place server-side, so the box looked empty while the old amount survived\n // the save (SDK-1284). This makes clearing behave exactly like typing 0. An entry with\n // no saved compensation stays omitted -- there is nothing to zero out.\n const resolvedAmount = formAmount === '' && existingFixedCompensation ? '0' : formAmount\n\n if (resolvedAmount !== undefined && resolvedAmount !== '') {\n if (existingFixedCompensation) {\n updatedFixedCompensations.push({\n name: existingFixedCompensation.name,\n jobUuid: existingFixedCompensation.jobUuid,\n amount: resolvedAmount,\n })\n } else if (parseFloat(resolvedAmount) !== 0) {\n updatedFixedCompensations.push({\n name: fixedCompensationName,\n jobUuid: primaryJobUuid,\n amount: resolvedAmount,\n })\n }\n }\n })\n\n updatedCompensation.fixedCompensations = updatedFixedCompensations\n\n if (usesItemizedReimbursements) {\n updatedCompensation.reimbursements = formData.reimbursements.map(reimbursement => ({\n amount: reimbursement.amount,\n description:\n reimbursement.description.trim() === '' ? null : reimbursement.description.trim(),\n uuid: reimbursement.uuid ?? null,\n recurring: reimbursement.recurring,\n }))\n } else {\n // Off-cycle: ensure no itemized array leaks through. The container also strips this defensively.\n updatedCompensation.reimbursements = []\n }\n\n return updatedCompensation\n}\n\n/** @internal */\nexport const PayrollEditEmployeePresentation = ({\n className,\n onSave,\n onCancel,\n employee,\n employeeCompensation,\n isPending = false,\n fixedCompensationTypes,\n payPeriodStartDate,\n paySchedule,\n payrollCategory = PayrollCategory.Regular,\n withReimbursements = true,\n hasDirectDepositSetup = true,\n}: PayrollEditEmployeeProps) => {\n const { Button, ButtonIcon, Heading, Text } = useComponentContext()\n\n const { t } = useTranslation('Payroll.PayrollEditEmployee')\n useI18n('Payroll.PayrollEditEmployee')\n\n const primaryJob = employee.jobs?.find(job => job.primary)\n const primaryJobHasHourlyCompensations = employeeCompensation?.hourlyCompensations?.some(\n c => c.jobUuid === primaryJob?.uuid,\n )\n const hourlyJobs = primaryJob && primaryJobHasHourlyCompensations ? [primaryJob] : []\n\n const containerRef = useRef<HTMLDivElement>(null)\n const breakpoints = useContainerBreakpoints({\n ref: containerRef,\n })\n const isSmallOrGreater = breakpoints.includes('small')\n\n employeeCompensation?.hourlyCompensations?.forEach(compensation => {\n const job = employee.jobs?.find(job => job.uuid === compensation.jobUuid)\n if (job && !hourlyJobs.find(hourlyJob => hourlyJob.uuid === job.uuid)) {\n hourlyJobs.push(job)\n }\n })\n\n const timeOff = (employeeCompensation?.paidTimeOff || []).filter(entry => entry.name)\n\n const additionalEarnings = getAdditionalEarningsCompensations({\n flsaStatus: primaryJob?.compensations?.[0]?.flsaStatus,\n existingFixedCompensations: employeeCompensation?.fixedCompensations || [],\n primaryJobUuid: primaryJob?.uuid,\n fixedCompensationTypes,\n excludedTypes: EXCLUDED_ADDITIONAL_EARNINGS,\n })\n\n // Off-cycle payrolls use the legacy single Reimbursement field in fixed_compensations because\n // the backend `emb_off_cycle_disable_named_reimbursements` flag (default: true, expected\n // removal 2026-09-01) rejects named entries in the itemized `reimbursements[]` array.\n // TODO(post-2026-09-01): unify on the itemized path once that flag is removed.\n const usesItemizedReimbursements = !isOffCyclePayroll(payrollCategory)\n\n const initialReimbursements: Reimbursement[] = useMemo(\n () =>\n withReimbursements && usesItemizedReimbursements\n ? (employeeCompensation?.reimbursements ?? [])\n : [],\n [withReimbursements, usesItemizedReimbursements, employeeCompensation?.reimbursements],\n )\n\n const existingReimbursementFixedCompensation = useMemo(\n () =>\n employeeCompensation?.fixedCompensations?.find(\n comp => comp.name?.toLowerCase() === COMPENSATION_NAME_REIMBURSEMENT.toLowerCase(),\n ),\n [employeeCompensation?.fixedCompensations],\n )\n\n const showLegacyReimbursementField =\n withReimbursements && !usesItemizedReimbursements && Boolean(primaryJob?.uuid)\n\n const findMatchingCompensation = (jobUuid: string, compensationName: string) => {\n return employeeCompensation?.hourlyCompensations?.find(\n compensation =>\n compensation.jobUuid === jobUuid &&\n compensation.name?.toLowerCase() === compensationName.toLowerCase(),\n )\n }\n\n const getCompensationLabel = (compensationName?: string) => {\n switch (compensationName) {\n case COMPENSATION_NAME_REGULAR_HOURS:\n return t('compensationNames.regularHours')\n case COMPENSATION_NAME_OVERTIME:\n return t('compensationNames.overtime')\n case COMPENSATION_NAME_DOUBLE_OVERTIME:\n return t('compensationNames.doubleOvertime')\n default:\n return compensationName\n }\n }\n\n const getFixedCompensationLabel = (compensationName?: string) => {\n switch (compensationName) {\n case COMPENSATION_NAME_BONUS:\n return t('fixedCompensationNames.bonus')\n case COMPENSATION_NAME_PAYCHECK_TIPS:\n return t('fixedCompensationNames.paycheckTips')\n case COMPENSATION_NAME_CORRECTION_PAYMENT:\n return t('fixedCompensationNames.correctionPayment')\n case COMPENSATION_NAME_COMMISSION:\n return t('fixedCompensationNames.commission')\n case COMPENSATION_NAME_CASH_TIPS:\n return t('fixedCompensationNames.cashTips')\n case COMPENSATION_NAME_REIMBURSEMENT:\n return t('fixedCompensationNames.reimbursement')\n default:\n return compensationName\n }\n }\n\n const resolveDefaultPaymentMethod = () => {\n const preparedPaymentMethod = employeeCompensation?.paymentMethod\n\n if (!preparedPaymentMethod) {\n return hasDirectDepositSetup\n ? PayrollEmployeeCompensationsTypePaymentMethod.DirectDeposit\n : PayrollEmployeeCompensationsTypePaymentMethod.Check\n }\n\n if (\n !hasDirectDepositSetup &&\n preparedPaymentMethod === PayrollEmployeeCompensationsTypePaymentMethod.DirectDeposit\n ) {\n return PayrollEmployeeCompensationsTypePaymentMethod.Check\n }\n\n return preparedPaymentMethod\n }\n\n const defaultValues = {\n hourlyCompensations: (() => {\n const hourlyCompensations: PayrollEditEmployeeFormValues['hourlyCompensations'] = {}\n\n hourlyJobs.forEach(hourlyJob => {\n HOURS_COMPENSATION_NAMES.forEach(compensationName => {\n const matchingCompensation = findMatchingCompensation(hourlyJob.uuid, compensationName)\n if (matchingCompensation) {\n if (!hourlyCompensations[hourlyJob.uuid]) {\n hourlyCompensations[hourlyJob.uuid] = {}\n }\n hourlyCompensations[hourlyJob.uuid]![matchingCompensation.name!] =\n matchingCompensation.hours ? parseFloat(matchingCompensation.hours).toString() : ''\n }\n })\n })\n\n return hourlyCompensations\n })(),\n\n timeOffCompensations: (() => {\n const timeOffCompensations: PayrollEditEmployeeFormValues['timeOffCompensations'] = {}\n\n timeOff.forEach(timeOffCompensation => {\n timeOffCompensations[timeOffCompensation.name!] = timeOffCompensation.hours\n ? parseFloat(timeOffCompensation.hours).toString()\n : ''\n })\n\n return timeOffCompensations\n })(),\n\n finalPayoutCompensations: (() => {\n const finalPayoutCompensations: PayrollEditEmployeeFormValues['finalPayoutCompensations'] = {}\n\n timeOff.forEach(timeOffCompensation => {\n finalPayoutCompensations[timeOffCompensation.name!] =\n timeOffCompensation.finalPayoutUnusedHoursInput ?? '0'\n })\n\n return finalPayoutCompensations\n })(),\n\n fixedCompensations: (() => {\n const fixedCompensations: PayrollEditEmployeeFormValues['fixedCompensations'] = {}\n\n additionalEarnings.forEach(fixedComp => {\n fixedCompensations[fixedComp.name!] = fixedComp.amount ?? ''\n })\n\n if (showLegacyReimbursementField) {\n fixedCompensations[COMPENSATION_NAME_REIMBURSEMENT] =\n existingReimbursementFixedCompensation?.amount ?? '0.00'\n }\n\n return fixedCompensations\n })(),\n\n reimbursements: initialReimbursements.map(reimbursement => ({\n uuid: reimbursement.uuid ?? null,\n description: reimbursement.description ?? '',\n amount: reimbursement.amount,\n recurring: reimbursement.recurring ?? false,\n })),\n\n paymentMethod: resolveDefaultPaymentMethod(),\n }\n\n const formHandlers = useForm<PayrollEditEmployeeFormValues>({\n resolver: zodResolver(PayrollEditEmployeeFormSchema),\n defaultValues,\n })\n\n const {\n fields: reimbursementFields,\n append: appendReimbursement,\n remove: removeReimbursement,\n update: updateReimbursement,\n } = useFieldArray({\n control: formHandlers.control,\n name: 'reimbursements',\n })\n\n const handleRemoveReimbursement = (index: number) => {\n const field = reimbursementFields[index]\n if (!field) return\n\n if (field.uuid) {\n updateReimbursement(index, { ...field, amount: '0' })\n } else {\n removeReimbursement(index)\n }\n }\n\n type VisibleReimbursementRow = (typeof reimbursementFields)[number] & {\n originalIndex: number\n }\n\n const visibleReimbursementRows: VisibleReimbursementRow[] = reimbursementFields\n .map((field, originalIndex) => ({ ...field, originalIndex }))\n .filter(row => parseFloat(row.amount || '0') !== 0)\n\n const [isAddingReimbursement, setIsAddingReimbursement] = useState(false)\n\n type DraftReimbursementValues = z.infer<typeof DraftReimbursementSchema>\n\n const draftForm = useForm<DraftReimbursementValues>({\n resolver: zodResolver(DraftReimbursementSchema),\n defaultValues: { description: '', amount: '' },\n })\n\n const resetReimbursementDraft = () => {\n setIsAddingReimbursement(false)\n draftForm.reset()\n }\n\n const onDraftReimbursementValid = (data: DraftReimbursementValues) => {\n const parsedAmount = parseFloat(data.amount)\n appendReimbursement({\n uuid: null,\n description: data.description.trim(),\n amount: parsedAmount.toFixed(2),\n recurring: false,\n })\n resetReimbursementDraft()\n }\n\n const reimbursementDataViewProps = useDataView<VisibleReimbursementRow>({\n data: visibleReimbursementRows,\n columns: [\n {\n key: 'description',\n title: t('reimbursementDescriptionColumn'),\n render: row => row.description.trim() || t('reimbursementUnnamedFallback'),\n },\n {\n key: 'amount',\n title: t('reimbursementAmountColumn'),\n justify: 'end',\n render: row => formatNumberAsCurrency(parseFloat(row.amount || '0')),\n },\n {\n key: 'recurring',\n title: t('reimbursementTypeColumn'),\n render: row =>\n row.recurring ? t('reimbursementTypeRecurring') : t('reimbursementTypeOneTime'),\n },\n ],\n itemMenu: row => {\n if (row.recurring) return null\n const displayDescription = row.description.trim() || t('reimbursementUnnamedFallback')\n return (\n <ButtonIcon\n variant=\"tertiary\"\n onClick={() => {\n handleRemoveReimbursement(row.originalIndex)\n }}\n aria-label={t('removeReimbursementLabel', { description: displayDescription })}\n >\n <TrashCanSvg aria-hidden />\n </ButtonIcon>\n )\n },\n emptyState: () => (\n <EmptyData title={t('reimbursementEmptyTitle')}>\n <Button\n variant=\"secondary\"\n onClick={() => {\n setIsAddingReimbursement(true)\n }}\n icon={<PlusCircleIcon aria-hidden />}\n >\n {t('addReimbursementCta')}\n </Button>\n </EmptyData>\n ),\n })\n\n const watchedFormData = useWatch({\n control: formHandlers.control,\n })\n\n const currentGrossPay = useMemo(() => {\n try {\n const hourlyCompensations: Record<string, Record<string, string | undefined>> = {}\n if (watchedFormData.hourlyCompensations) {\n Object.entries(watchedFormData.hourlyCompensations).forEach(([jobId, compensations]) => {\n if (compensations) {\n hourlyCompensations[jobId] = compensations\n }\n })\n }\n\n const reimbursementsWithDefaults: PayrollEditEmployeeFormValues['reimbursements'] = (\n watchedFormData.reimbursements ?? []\n ).map(reimbursement => ({\n uuid: reimbursement.uuid ?? null,\n description: reimbursement.description ?? '',\n amount: reimbursement.amount ?? '0',\n recurring: reimbursement.recurring,\n }))\n\n const formDataWithDefaults: PayrollEditEmployeeFormValues = {\n hourlyCompensations,\n timeOffCompensations: watchedFormData.timeOffCompensations || {},\n finalPayoutCompensations: watchedFormData.finalPayoutCompensations || {},\n fixedCompensations: watchedFormData.fixedCompensations || {},\n reimbursements: reimbursementsWithDefaults,\n paymentMethod: watchedFormData.paymentMethod,\n }\n\n const updatedCompensation = buildCompensationFromFormData(\n formDataWithDefaults,\n employeeCompensation,\n (employeeCompensation?.paidTimeOff || []).filter(entry => entry.name),\n primaryJob?.uuid,\n payrollCategory,\n )\n\n return calculateGrossPay(\n updatedCompensation,\n employee,\n payPeriodStartDate,\n paySchedule,\n payrollCategory,\n )\n } catch {\n return employeeCompensation\n ? calculateGrossPay(\n employeeCompensation,\n employee,\n payPeriodStartDate,\n paySchedule,\n payrollCategory,\n )\n : 0\n }\n }, [\n watchedFormData,\n employeeCompensation,\n primaryJob?.uuid,\n employee,\n payPeriodStartDate,\n paySchedule,\n payrollCategory,\n ])\n\n const employeeName = firstLastName({\n first_name: employee.firstName,\n last_name: employee.lastName,\n })\n\n const onSubmit = (data: PayrollEditEmployeeFormValues) => {\n const updatedCompensation = buildCompensationFromFormData(\n data,\n employeeCompensation,\n timeOff,\n primaryJob?.uuid,\n payrollCategory,\n )\n onSave(updatedCompensation)\n }\n\n const formattedCurrentGrossPay = formatNumberAsCurrency(currentGrossPay || 0)\n\n const actions = (\n <Flex\n flexDirection={isSmallOrGreater ? 'row' : 'column'}\n justifyContent={isSmallOrGreater ? 'flex-end' : 'normal'}\n alignItems={isSmallOrGreater ? 'flex-start' : 'stretch'}\n gap={12}\n >\n <Button variant=\"secondary\" onClick={onCancel} title={t('cancelCta')}>\n {t('cancelCta')}\n </Button>\n <Button\n onClick={formHandlers.handleSubmit(onSubmit)}\n title={t('saveCta')}\n isLoading={isPending}\n >\n {t('saveCta')}\n </Button>\n </Flex>\n )\n\n return (\n <div ref={containerRef} className={classNames(styles.container, className)}>\n <div\n className={`${styles.headerSection} ${!isSmallOrGreater ? styles.headerSectionSticky : ''}`}\n >\n <Flex justifyContent=\"space-between\">\n <Flex flexDirection=\"column\" alignItems=\"stretch\" gap={isSmallOrGreater ? 8 : 2}>\n <Heading as=\"h1\" styledAs={isSmallOrGreater ? 'h2' : 'h4'}>\n {t('pageTitle', { employeeName })}\n </Heading>\n {isSmallOrGreater ? (\n <Flex flexDirection=\"column\" gap={6}>\n <Heading as=\"h2\" styledAs=\"h3\">\n {formattedCurrentGrossPay}\n </Heading>\n <Text className={styles.grossPayLabel}>{t('grossPayLabel')}</Text>\n </Flex>\n ) : (\n <Heading as=\"h2\" styledAs=\"h6\" className={styles.grossPayLabel}>\n {t('grossPayLabelMobile', { grossPay: formattedCurrentGrossPay })}\n </Heading>\n )}\n </Flex>\n {isSmallOrGreater && actions}\n </Flex>\n </div>\n <FormProvider {...formHandlers}>\n <Form>\n {hourlyJobs.length > 0 && (\n <div className={styles.fieldGroup}>\n <Heading as=\"h3\">{t('regularHoursTitle')}</Heading>\n {hourlyJobs.map(hourlyJob => (\n <Flex key={hourlyJob.uuid} flexDirection=\"column\" gap={8}>\n {hourlyJobs.length > 1 && <Heading as=\"h4\">{hourlyJob.title}</Heading>}\n <Grid gridTemplateColumns={{ base: '1fr', small: [320, 320] }} gap={20}>\n {HOURS_COMPENSATION_NAMES.map(compensationName => {\n const employeeHourlyCompensation = findMatchingCompensation(\n hourlyJob.uuid,\n compensationName,\n )\n if (employeeHourlyCompensation) {\n return (\n <TextInputField\n key={compensationName}\n type=\"number\"\n min={0}\n max={MAX_HOURS}\n transform={stripLeadingZeros}\n adornmentEnd={t('hoursUnit')}\n label={getCompensationLabel(compensationName)}\n name={`hourlyCompensations.${hourlyJob.uuid}.${employeeHourlyCompensation.name}`}\n errorMessage={t('validations.maxHours')}\n />\n )\n }\n })}\n </Grid>\n </Flex>\n ))}\n </div>\n )}\n {timeOff.length > 0 && (\n <div className={styles.fieldGroup}>\n <Heading as=\"h3\" styledAs=\"h4\">\n {payrollCategory === PayrollCategory.Dismissal\n ? t('timeOffTitleDismissal')\n : t('timeOffTitle')}\n </Heading>\n <Grid gridTemplateColumns={{ base: '1fr', small: [320, 320] }} gap={20}>\n {timeOff.map(timeOffEntry => (\n <TimeOffField\n key={timeOffEntry.name}\n timeOff={timeOffEntry}\n employee={employee}\n />\n ))}\n </Grid>\n </div>\n )}\n {payrollCategory === PayrollCategory.Dismissal && timeOff.length > 0 && (\n <div className={styles.fieldGroup}>\n <Flex flexDirection=\"column\" gap={4}>\n <Heading as=\"h3\" styledAs=\"h4\">\n {t('finalPayoutTitle')}\n </Heading>\n <Text variant=\"supporting\">{t('finalPayoutDescription')}</Text>\n </Flex>\n <Grid gridTemplateColumns={{ base: '1fr', small: [320, 320] }} gap={20}>\n {timeOff.map(timeOffEntry => (\n <PayoutTimeOffField\n key={`payout-${timeOffEntry.name}`}\n timeOff={timeOffEntry}\n employee={employee}\n />\n ))}\n </Grid>\n </div>\n )}\n {additionalEarnings.length > 0 && (\n <div className={styles.fieldGroup}>\n <Heading as=\"h3\" styledAs=\"h4\">\n {t('additionalEarningsTitle')}\n </Heading>\n <Grid\n gridTemplateColumns={{ base: '1fr', small: [320, 320], large: [320, 320, 320] }}\n gap={20}\n >\n {additionalEarnings.map(fixedCompensation => (\n <TextInputField\n key={fixedCompensation.name}\n type=\"number\"\n min={0}\n transform={stripLeadingZeros}\n adornmentStart=\"$\"\n label={getFixedCompensationLabel(fixedCompensation.name)}\n name={`fixedCompensations.${fixedCompensation.name}`}\n // useField only surfaces this once react-hook-form has flagged the\n // field, and the schema's only rule here is the negative-amount check.\n errorMessage={t('validations.negativeAmount')}\n />\n ))}\n </Grid>\n </div>\n )}\n {showLegacyReimbursementField && (\n <div className={styles.fieldGroup}>\n <Heading as=\"h3\" styledAs=\"h4\">\n {t('reimbursementTitle')}\n </Heading>\n <Grid gridTemplateColumns={{ base: '1fr', small: [320, 320] }} gap={20}>\n <TextInputField\n type=\"number\"\n min={0}\n transform={stripLeadingZeros}\n adornmentStart=\"$\"\n label={getFixedCompensationLabel(COMPENSATION_NAME_REIMBURSEMENT)}\n name={`fixedCompensations.${COMPENSATION_NAME_REIMBURSEMENT}`}\n errorMessage={t('validations.negativeAmount')}\n />\n </Grid>\n </div>\n )}\n {withReimbursements && usesItemizedReimbursements && (\n <div className={styles.fieldGroup}>\n <Heading as=\"h3\" styledAs=\"h4\">\n {t('reimbursementTitle')}\n </Heading>\n {!(visibleReimbursementRows.length === 0 && isAddingReimbursement) && (\n <DataView label={t('reimbursementsTableLabel')} {...reimbursementDataViewProps} />\n )}\n {isAddingReimbursement ? (\n <FormProvider {...draftForm}>\n <Flex flexDirection=\"column\" gap={12}>\n <Grid gridTemplateColumns={{ base: '1fr', small: [320, 320] }} gap={20}>\n <TextInputField\n name=\"description\"\n label={t('reimbursementDescriptionLabel')}\n placeholder={t('reimbursementDescriptionPlaceholder')}\n />\n <TextInputField\n name=\"amount\"\n type=\"number\"\n min={0}\n max={MAX_REIMBURSEMENT_AMOUNT}\n transform={stripLeadingZeros}\n adornmentStart=\"$\"\n isRequired\n label={t('reimbursementAmountLabel')}\n errorMessage={\n draftForm.formState.errors.amount?.message ===\n 'validations.maxReimbursementAmount'\n ? t('validations.maxReimbursementAmount')\n : t('validations.reimbursementAmount')\n }\n />\n </Grid>\n <Flex gap={12}>\n <Button onClick={draftForm.handleSubmit(onDraftReimbursementValid)}>\n {t('saveReimbursementCta')}\n </Button>\n <Button variant=\"secondary\" onClick={resetReimbursementDraft}>\n {t('cancelReimbursementCta')}\n </Button>\n </Flex>\n </Flex>\n </FormProvider>\n ) : (\n visibleReimbursementRows.length > 0 && (\n <div>\n <Button\n variant=\"secondary\"\n onClick={() => {\n setIsAddingReimbursement(true)\n }}\n title={t('addReimbursementLink')}\n icon={<PlusCircleIcon aria-hidden />}\n >\n {t('addReimbursementLink')}\n </Button>\n </div>\n )\n )}\n </div>\n )}\n {hasDirectDepositSetup && (\n <div className={styles.fieldGroup}>\n <Heading as=\"h3\" styledAs=\"h4\">\n {t('paymentMethodTitle')}\n </Heading>\n <RadioGroupField\n name=\"paymentMethod\"\n isRequired\n label={t('paymentMethodLabel')}\n description={t('paymentMethodDescription')}\n options={[\n {\n value: PayrollEmployeeCompensationsTypePaymentMethod.DirectDeposit,\n label: t('paymentMethodOptions.directDeposit'),\n },\n {\n value: PayrollEmployeeCompensationsTypePaymentMethod.Check,\n label: t('paymentMethodOptions.check'),\n },\n ]}\n />\n </div>\n )}\n </Form>\n {!isSmallOrGreater && actions}\n </FormProvider>\n </div>\n )\n}\n"],"names":["ReimbursementFormSchema","z","MAX_REIMBURSEMENT_AMOUNT","DraftReimbursementSchema","val","num","nonNegativeAmountSchema","MAX_HOURS","hoursAmountSchema","PayrollEditEmployeeFormSchema","PayrollEmployeeCompensationsTypePaymentMethod","buildCompensationFromFormData","formData","employeeCompensation","timeOff","primaryJobUuid","payrollCategory","PayrollCategory","updatedCompensation","compensation","hours","timeOffEntry","isDismissal","_","timeOffWithoutPayout","finalPayout","usesItemizedReimbursements","isOffCyclePayroll","updatedFixedCompensations","fixedCompensationName","formAmount","COMPENSATION_NAME_REIMBURSEMENT","existingFixedCompensation","fixedCompensation","resolvedAmount","reimbursement","PayrollEditEmployeePresentation","className","onSave","onCancel","employee","isPending","fixedCompensationTypes","payPeriodStartDate","paySchedule","withReimbursements","hasDirectDepositSetup","Button","ButtonIcon","Heading","Text","useComponentContext","t","useTranslation","useI18n","primaryJob","job","primaryJobHasHourlyCompensations","c","hourlyJobs","containerRef","useRef","isSmallOrGreater","useContainerBreakpoints","hourlyJob","entry","additionalEarnings","getAdditionalEarningsCompensations","EXCLUDED_ADDITIONAL_EARNINGS","initialReimbursements","useMemo","existingReimbursementFixedCompensation","comp","showLegacyReimbursementField","findMatchingCompensation","jobUuid","compensationName","getCompensationLabel","COMPENSATION_NAME_REGULAR_HOURS","COMPENSATION_NAME_OVERTIME","COMPENSATION_NAME_DOUBLE_OVERTIME","getFixedCompensationLabel","COMPENSATION_NAME_BONUS","COMPENSATION_NAME_PAYCHECK_TIPS","COMPENSATION_NAME_CORRECTION_PAYMENT","COMPENSATION_NAME_COMMISSION","COMPENSATION_NAME_CASH_TIPS","resolveDefaultPaymentMethod","preparedPaymentMethod","defaultValues","hourlyCompensations","HOURS_COMPENSATION_NAMES","matchingCompensation","timeOffCompensations","timeOffCompensation","finalPayoutCompensations","fixedCompensations","fixedComp","formHandlers","useForm","zodResolver","reimbursementFields","appendReimbursement","removeReimbursement","updateReimbursement","useFieldArray","handleRemoveReimbursement","index","field","visibleReimbursementRows","originalIndex","row","isAddingReimbursement","setIsAddingReimbursement","useState","draftForm","resetReimbursementDraft","onDraftReimbursementValid","data","parsedAmount","reimbursementDataViewProps","useDataView","formatNumberAsCurrency","displayDescription","jsx","TrashCanSvg","EmptyData","PlusCircleIcon","watchedFormData","useWatch","currentGrossPay","jobId","compensations","reimbursementsWithDefaults","formDataWithDefaults","calculateGrossPay","employeeName","firstLastName","onSubmit","formattedCurrentGrossPay","actions","jsxs","Flex","classNames","styles","FormProvider","Form","Grid","employeeHourlyCompensation","TextInputField","stripLeadingZeros","TimeOffField","PayoutTimeOffField","DataView","RadioGroupField"],"mappings":"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"}
@@ -1,52 +1,54 @@
1
- import { jsx as y } from "react/jsx-runtime";
2
- import { TextInputField as U } from "../../../../Common/Fields/TextInputField/TextInputField.js";
3
- import { useFieldErrorMessage as M } from "../../../../../partner-hook-utils/form/useFieldErrorMessage.js";
4
- import { PayrollCategory as N } from "../../../payrollTypes.js";
5
- import { COMPENSATION_NAME_OVERTIME as I, COMPENSATION_NAME_DOUBLE_OVERTIME as v } from "../../../../../shared/constants.js";
6
- import { stripLeadingZeros as x } from "../../../../../helpers/formattedStrings.js";
7
- import { RadioGroupHookField as R } from "../../../../../partner-hook-utils/form/fields/RadioGroupHookField.js";
8
- function q(t) {
1
+ import { jsx as E } from "react/jsx-runtime";
2
+ import { MAX_HOURS as D, MAX_REIMBURSEMENT_AMOUNT as R } from "./payrollEditEmployeeSchema.js";
3
+ import { TextInputField as j } from "../../../../Common/Fields/TextInputField/TextInputField.js";
4
+ import { useFieldErrorMessage as I } from "../../../../../partner-hook-utils/form/useFieldErrorMessage.js";
5
+ import { PayrollCategory as P } from "../../../payrollTypes.js";
6
+ import { COMPENSATION_NAME_OVERTIME as _, COMPENSATION_NAME_DOUBLE_OVERTIME as v } from "../../../../../shared/constants.js";
7
+ import { stripLeadingZeros as S } from "../../../../../helpers/formattedStrings.js";
8
+ import { RadioGroupHookField as x } from "../../../../../partner-hook-utils/form/fields/RadioGroupHookField.js";
9
+ function J(t) {
9
10
  return !Array.isArray(t);
10
11
  }
11
- function d(t, o) {
12
- return function(m) {
13
- const l = M(
12
+ function d(t, o, r) {
13
+ return function(l) {
14
+ const m = I(
14
15
  t,
15
16
  o
16
17
  );
17
- return /* @__PURE__ */ y(
18
- U,
18
+ return /* @__PURE__ */ E(
19
+ j,
19
20
  {
20
- ...m,
21
+ ...l,
21
22
  name: t,
22
23
  type: "number",
23
24
  min: 0,
24
- transform: x,
25
- errorMessage: l
25
+ max: r,
26
+ transform: S,
27
+ errorMessage: m
26
28
  }
27
29
  );
28
30
  };
29
31
  }
30
32
  function C() {
31
33
  return function(o) {
32
- return /* @__PURE__ */ y(R, { ...o, name: "paymentMethod" });
34
+ return /* @__PURE__ */ E(x, { ...o, name: "paymentMethod" });
33
35
  };
34
36
  }
35
- function _(t) {
37
+ function k(t) {
36
38
  return function(r) {
37
- return /* @__PURE__ */ y(U, { ...r, name: t });
39
+ return /* @__PURE__ */ E(j, { ...r, name: t });
38
40
  };
39
41
  }
40
- function z(t) {
42
+ function K(t) {
41
43
  return {
42
- Description: _("reimbursementDraft.description"),
43
- Amount: d("reimbursementDraft.amount", t)
44
+ Description: k("reimbursementDraft.description"),
45
+ Amount: d("reimbursementDraft.amount", t, R)
44
46
  };
45
47
  }
46
- function k(t, o) {
48
+ function H(t, o) {
47
49
  return t == null ? null : parseFloat(t) - (parseFloat(o ?? "") || 0);
48
50
  }
49
- function j(t, o, r, m, l, s) {
51
+ function U(t, o, r, s, l, m) {
50
52
  const f = t.filter(
51
53
  (n) => !!n.jobUuid && !!n.name
52
54
  ), a = (n, i, u) => ({
@@ -56,10 +58,11 @@ function j(t, o, r, m, l, s) {
56
58
  ...u ? { workweekStart: i } : {},
57
59
  Field: d(
58
60
  `${r}.${n.jobUuid}.${n.name}.${i}`,
59
- s
61
+ m,
62
+ r === "hours" ? D : void 0
60
63
  )
61
64
  });
62
- if (o.length > 1 && m && l) {
65
+ if (o.length > 1 && s && l) {
63
66
  const n = {};
64
67
  for (const i of o)
65
68
  n[i.startDate] = f.map((u) => a(u, i.startDate, !0));
@@ -68,35 +71,35 @@ function j(t, o, r, m, l, s) {
68
71
  const c = o[0]?.startDate ?? "";
69
72
  return f.map((n) => a(n, c, !1));
70
73
  }
71
- function J({
74
+ function Q({
72
75
  employeeCompensation: t,
73
76
  fixedCompensations: o,
74
77
  workweeks: r,
75
- payrollCategory: m,
78
+ payrollCategory: s,
76
79
  hasDirectDepositSetup: l,
77
- overtimeEarningNames: s,
80
+ overtimeEarningNames: m,
78
81
  isOvertimeEligible: f,
79
82
  withOvertime: a,
80
83
  jobTitlesByUuid: c,
81
84
  timeOffAccrualByName: n,
82
85
  errorMessages: i
83
86
  }) {
84
- const u = t?.hourlyCompensations ?? [], E = o.filter(
85
- (e) => e.name != null && s.has(e.name)
87
+ const u = t?.hourlyCompensations ?? [], y = o.filter(
88
+ (e) => e.name != null && m.has(e.name)
86
89
  ), O = o.filter(
87
- (e) => e.name == null || !s.has(e.name)
90
+ (e) => e.name == null || !m.has(e.name)
88
91
  ), p = [];
89
- for (const e of [...u, ...E])
92
+ for (const e of [...u, ...y])
90
93
  e.jobUuid && !p.includes(e.jobUuid) && p.push(e.jobUuid);
91
- const h = (e) => e === I || e === v, g = p.map((e) => {
94
+ const M = (e) => e === _ || e === v, h = p.map((e) => {
92
95
  const $ = u.filter(
93
96
  (b) => b.jobUuid === e
94
- ), A = a ? $ : $.filter((b) => !h(b.name));
97
+ ), g = a ? $ : $.filter((b) => !M(b.name));
95
98
  return {
96
99
  jobUuid: e,
97
100
  title: c.get(e),
98
- hours: j(
99
- A,
101
+ hours: U(
102
+ g,
100
103
  r,
101
104
  "hours",
102
105
  f,
@@ -104,14 +107,14 @@ function J({
104
107
  i
105
108
  )
106
109
  };
107
- }), B = j(
108
- E,
110
+ }), A = U(
111
+ y,
109
112
  r,
110
113
  "overtimeIncludedEarnings",
111
114
  f,
112
115
  a,
113
116
  i
114
- ), D = O.filter(
117
+ ), T = O.filter(
115
118
  (e) => !!e.jobUuid && !!e.name
116
119
  ).map((e) => ({
117
120
  key: `${e.jobUuid}:${e.name}`,
@@ -120,31 +123,31 @@ function J({
120
123
  `overtimeExcludedEarnings.${e.jobUuid}.${e.name}`,
121
124
  i
122
125
  )
123
- })), F = (t?.paidTimeOff ?? []).filter((e) => e.name), P = F.map((e) => ({
126
+ })), F = (t?.paidTimeOff ?? []).filter((e) => e.name), B = F.map((e) => ({
124
127
  key: `timeOff:${e.name}`,
125
128
  name: e.name,
126
129
  Field: d(`timeOff.${e.name}`, i),
127
130
  // Seeded from the initial entered hours; the hook recomputes it live.
128
- remaining: k(n.get(e.name), e.hours)
129
- })), T = m === N.Dismissal ? F.map((e) => ({
131
+ remaining: H(n.get(e.name), e.hours)
132
+ })), N = s === P.Dismissal ? F.map((e) => ({
130
133
  key: `finalPayout:${e.name}`,
131
134
  name: e.name,
132
135
  Field: d(`finalPayout.${e.name}`, i),
133
136
  remaining: null
134
137
  })) : void 0;
135
138
  return {
136
- jobs: g,
137
- overtimeIncludedEarnings: B,
138
- overtimeExcludedEarnings: D,
139
- timeOff: P,
140
- finalPayout: T,
139
+ jobs: h,
140
+ overtimeIncludedEarnings: A,
141
+ overtimeExcludedEarnings: T,
142
+ timeOff: B,
143
+ finalPayout: N,
141
144
  paymentMethod: l ? C() : void 0
142
145
  };
143
146
  }
144
147
  export {
145
- k as computeTimeOffRemaining,
146
- J as createPayrollEditEmployeeFields,
147
- z as createReimbursementDraftFields,
148
- q as isSplitByWorkweek
148
+ H as computeTimeOffRemaining,
149
+ Q as createPayrollEditEmployeeFields,
150
+ K as createReimbursementDraftFields,
151
+ J as isSplitByWorkweek
149
152
  };
150
153
  //# sourceMappingURL=fields.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"fields.js","sources":["../../../../../../src/components/Payroll/PayrollEditEmployee/shared/usePayrollEditEmployeeForm/fields.tsx"],"sourcesContent":["import type { ComponentType } from 'react'\nimport type { PayrollEmployeeCompensationsType } from '@gusto/embedded-api/models/components/payrollemployeecompensationstype'\nimport type { PayrollUpdatePaymentMethod } from '@gusto/embedded-api/models/components/payrollupdate'\nimport type { NormalizedWorkweek } from './payrollEditEmployeeHelpers'\nimport type { PayrollEditEmployeeErrorCode } from './payrollEditEmployeeSchema'\nimport { TextInputField } from '@/components/Common/Fields/TextInputField/TextInputField'\nimport { useFieldErrorMessage } from '@/partner-hook-utils/form/useFieldErrorMessage'\nimport { RadioGroupHookField } from '@/partner-hook-utils/form/fields'\nimport type { RadioGroupHookFieldProps } from '@/partner-hook-utils/form/fields/RadioGroupHookField'\nimport type { HookFieldProps, ValidationMessages } from '@/partner-hook-utils/types'\nimport type { TextInputProps } from '@/components/Common/UI/TextInput/TextInputTypes'\nimport { PayrollCategory } from '@/components/Payroll/payrollTypes'\nimport { COMPENSATION_NAME_DOUBLE_OVERTIME, COMPENSATION_NAME_OVERTIME } from '@/shared/constants'\nimport { stripLeadingZeros } from '@/helpers/formattedStrings'\n\n/**\n * Display copy for each validation error code a bound field can surface, so the\n * consumer supplies error text once (keyed by code) rather than reconstructing\n * form paths or hardcoding which rule each field can fail. Partial: a missing\n * code falls back to the raw error code.\n *\n * @public\n */\nexport type PayrollEditEmployeeErrorMessages = Partial<Record<PayrollEditEmployeeErrorCode, string>>\n\n/**\n * Presentation props accepted by a bound numeric field in the payroll editor.\n *\n * @remarks\n * The hook binds the react-hook-form `name`, forces `type=\"number\"`, and\n * resolves the field's own validation message internally; the UI supplies copy\n * and layout props (label, adornments, `shouldVisuallyHideLabel`, required\n * state, `description`).\n *\n * @public\n */\nexport type PayrollEditEmployeeFieldProps = Omit<\n TextInputProps,\n 'name' | 'value' | 'onChange' | 'isInvalid' | 'type' | 'min' | 'errorMessage'\n>\n\n/**\n * A numeric field component pre-bound by the hook to a specific form path.\n *\n * @public\n */\nexport type PayrollEditEmployeeFieldComponent = ComponentType<PayrollEditEmployeeFieldProps>\n\n/**\n * Presentation props accepted by the bound payment-method field.\n *\n * @remarks\n * The hook binds the `name` and publishes the option values on\n * `fieldsMetadata.paymentMethod`; the UI passes `getOptionLabel` to translate\n * each {@link PayrollUpdatePaymentMethod} value, rather than passing `options`.\n *\n * @public\n */\nexport type PayrollEditEmployeePaymentMethodFieldProps = HookFieldProps<\n RadioGroupHookFieldProps<never, PayrollUpdatePaymentMethod>\n>\n\n/**\n * The payment-method radio field component pre-bound by the hook.\n *\n * @public\n */\nexport type PayrollEditEmployeePaymentMethodField =\n ComponentType<PayrollEditEmployeePaymentMethodFieldProps>\n\n/**\n * One hours input within the hours section.\n *\n * @remarks\n * `key` is an opaque, stable React key. `jobUuid`, `name`, and (when the pay\n * period is multi-workweek) `workweekStart` are reach-in handles the UI uses to\n * group and label entries. When the section is a flat array, `workweekStart` is\n * omitted (single-workweek degenerate case); when it is a `Record` keyed by\n * workweek start, each entry carries its `workweekStart`.\n *\n * @public\n */\nexport interface HourEntry {\n /** Opaque, stable React key. */\n key: string\n /** The job this hours line belongs to. */\n jobUuid: string\n /** The compensation name (e.g. the API hours-compensation name). */\n name: string\n /** The workweek start date (`YYYY-MM-DD`) when the section is workweek-keyed. */\n workweekStart?: string\n /** Field component pre-bound to this entry's form path. */\n Field: PayrollEditEmployeeFieldComponent\n}\n\n/**\n * One earning input, used by the additional-earnings section.\n *\n * @remarks\n * Same shape as {@link HourEntry}. Whether an earning feeds the overtime\n * (regular rate of pay) calculation is decided by the hook, which sorts it into\n * the workweek-breakdown additional-earnings section or the flat other\n * section. The UI just renders whichever section an entry appears in.\n *\n * @public\n */\nexport type EarningEntry = HourEntry\n\n/**\n * One time-off or final-payout input.\n *\n * @remarks\n * Time off is never workweek-breakdown, so this section is always a flat array.\n *\n * @public\n */\nexport interface TimeOffEntry {\n /** Opaque, stable React key. */\n key: string\n /** The time-off policy compensation name. */\n name: string\n /** Field component pre-bound to this entry's form path. */\n Field: PayrollEditEmployeeFieldComponent\n /**\n * The policy's remaining balance after the entered hours are subtracted,\n * recomputed live as the user edits. `null` when the policy has no tracked\n * accrual balance (e.g. final-payout rows). Feed it into the field's own\n * `description` to render it as the input's help text.\n */\n remaining: number | null\n}\n\n/**\n * One entry in the flat `overtimeExcludedEarnings` section.\n *\n * @remarks\n * Intentionally opaque: `overtimeExcludedEarnings` collects earnings that are not overtime-affecting\n * and whose input type the partner does not need to reason about. Render each\n * entry's `Field` keyed by `key`; use `id` as a reach-in handle for labeling.\n *\n * @public\n */\nexport interface OtherEntry {\n /** Opaque, stable React key. */\n key: string\n /** Reach-in handle identifying the underlying earning (its compensation name). */\n id: string\n /** Field component pre-bound to this entry's form path. */\n Field: PayrollEditEmployeeFieldComponent\n}\n\n/**\n * A single job's hours section.\n *\n * @remarks\n * An employee can hold multiple jobs, each with its own hourly lines. `hours` is\n * either a flat `Entry[]` (single-workweek, or an overtime-ineligible employee)\n * OR a `Record<workweekStart, Entry[]>` (multi-workweek and overtime-eligible).\n * The value type is the signal — array is flat, object is split by workweek; use\n * {@link isSplitByWorkweek} to discriminate. `title` is the job's display title\n * (entity data, not copy) for rendering a per-job heading. Earnings are not\n * job-scoped: they live in the employee-level `overtimeIncludedEarnings` and\n * `overtimeExcludedEarnings` sections on {@link PayrollEditEmployeeFields}.\n *\n * @public\n */\nexport interface JobFields {\n /** The job identifier. */\n jobUuid: string\n /** The job's display title, when available, for a per-job heading. */\n title?: string\n /**\n * Hours inputs for this job. Excludes Overtime/Double-overtime rows while\n * `data.withOvertime` is `false`.\n */\n hours: HourEntry[] | Record<string, HourEntry[]>\n}\n\n/**\n * Presentation props accepted by a bound reimbursement description (text) field.\n *\n * @remarks\n * The hook binds the react-hook-form `name` internally; the UI supplies copy and\n * layout props (label, placeholder, `shouldVisuallyHideLabel`).\n *\n * @public\n */\nexport type ReimbursementDescriptionFieldProps = Omit<\n TextInputProps,\n 'name' | 'value' | 'onChange' | 'isInvalid' | 'type'\n>\n\n/**\n * The draft \"add reimbursement\" field group exposed on\n * `form.Fields.reimbursementDraft`.\n *\n * @remarks\n * A single in-progress row the UI reveals when the user starts adding a\n * reimbursement. `Description` and `Amount` bind to `reimbursementDraft.description`\n * / `reimbursementDraft.amount`. The UI shows them while `form.reimbursementDraft.isAdding`\n * is `true`, then calls `actions.saveReimbursement` (commits to the list) or\n * `actions.cancelReimbursement` (discards). Committed rows are rendered from\n * `data.reimbursements`, not from bound fields.\n *\n * @public\n */\nexport interface ReimbursementDraftFields {\n /** Description field pre-bound to the draft's form path. */\n Description: ComponentType<ReimbursementDescriptionFieldProps>\n /** Amount field pre-bound to the draft's form path. */\n Amount: PayrollEditEmployeeFieldComponent\n}\n\n/**\n * A committed reimbursement row for display in the consumer's table.\n *\n * @remarks\n * Exposed on `data.reimbursements`, seeded from the employee's existing\n * reimbursements and appended to as the user saves drafts. Display-only: the UI\n * renders `description`, `amount`, and the recurring/one-time `type`, plus a\n * remove control wired to `actions.removeReimbursement(index)`. `index` is the\n * row's position in the underlying form array (the removal handle); `uuid` is\n * present for rows that already exist server-side.\n *\n * @public\n */\nexport interface ReimbursementRow {\n /** Opaque, stable React key. */\n key: string\n /** The row's index in the reimbursements form array; pass to `removeReimbursement`. */\n index: number\n /** The reimbursement's server UUID, when it already exists. */\n uuid?: string\n /** The reimbursement description (may be blank; the UI supplies a fallback). */\n description: string\n /** The reimbursement amount as a decimal string. */\n amount: string\n /** Whether this reimbursement recurs. Recurring rows are managed outside payroll. */\n recurring: boolean\n}\n\n/**\n * The render-ready field collections exposed on `form.Fields`.\n *\n * @remarks\n * Hours are grouped under `jobs`, one entry per job, so multi-job employees\n * render correctly. All earnings and the remaining sections are employee-scoped\n * and stay top-level: `overtimeIncludedEarnings` (overtime-affecting) and\n * `overtimeExcludedEarnings` (non-overtime) each render as a single section spanning every\n * job, alongside time off, final payout, payment method, and reimbursements.\n *\n * @public\n */\nexport interface PayrollEditEmployeeFields {\n /** Per-job hours sections; one entry per job. */\n jobs: JobFields[]\n /**\n * Overtime-affecting earnings across all jobs, as a single employee-level\n * section. Flat `Entry[]` when unsplit, or `Record<workweekStart, Entry[]>`\n * when split by workweek; use {@link isSplitByWorkweek} to discriminate.\n */\n overtimeIncludedEarnings: EarningEntry[] | Record<string, EarningEntry[]>\n /** Non-overtime earnings (e.g. tips), always flat; opaque render entries. */\n overtimeExcludedEarnings: OtherEntry[]\n /** Time-off inputs (never workweek-breakdown). */\n timeOff: TimeOffEntry[]\n /** Final-payout inputs, present only for dismissal payrolls. */\n finalPayout?: TimeOffEntry[]\n /** Payment-method selector, present only when the employee has direct deposit set up. */\n paymentMethod?: PayrollEditEmployeePaymentMethodField\n /**\n * The draft \"add reimbursement\" field group, present only for itemized\n * (non-off-cycle) payrolls. Render while `form.reimbursementDraft.isAdding` is\n * `true`; committed rows come from `data.reimbursements`.\n */\n reimbursementDraft?: ReimbursementDraftFields\n}\n\n/**\n * Discriminates a workweek-breakdown section: `false` for the flat\n * (single-workweek) `Entry[]` form, `true` for the workweek-keyed\n * `Record<workweekStart, Entry[]>` form.\n *\n * @typeParam TEntry - The section's entry type.\n * @param section - A `form.Fields` section that may be flat or workweek-keyed.\n * @returns `true` when the section is keyed by workweek start date.\n * @public\n */\nexport function isSplitByWorkweek<TEntry>(\n section: TEntry[] | Record<string, TEntry[]>,\n): section is Record<string, TEntry[]> {\n return !Array.isArray(section)\n}\n\n// ── Bound field factories ──────────────────────────────────────────────\n\nfunction createNumberField(\n name: string,\n errorMessages?: PayrollEditEmployeeErrorMessages,\n): PayrollEditEmployeeFieldComponent {\n return function BoundNumberField(props: PayrollEditEmployeeFieldProps) {\n // The field resolves its own validation copy from its bound path, so the\n // consumer supplies error copy once (keyed by code) and never reconstructs\n // form paths or guesses which rule a field can fail. name, type, min,\n // transform, and errorMessage are applied after the spread so callers can't\n // override the binding or the non-negative numeric contract via custom props.\n const errorMessage = useFieldErrorMessage(\n name,\n errorMessages as ValidationMessages<PayrollEditEmployeeErrorCode> | undefined,\n )\n return (\n <TextInputField\n {...props}\n name={name}\n type=\"number\"\n min={0}\n transform={stripLeadingZeros}\n errorMessage={errorMessage}\n />\n )\n }\n}\n\nfunction createPaymentMethodField(): PayrollEditEmployeePaymentMethodField {\n return function BoundPaymentMethodField(props: PayrollEditEmployeePaymentMethodFieldProps) {\n return (\n <RadioGroupHookField<never, PayrollUpdatePaymentMethod> {...props} name=\"paymentMethod\" />\n )\n }\n}\n\nfunction createTextField(name: string): ComponentType<ReimbursementDescriptionFieldProps> {\n return function BoundTextField(props: ReimbursementDescriptionFieldProps) {\n return <TextInputField {...props} name={name} />\n }\n}\n\n/**\n * Builds the draft \"add reimbursement\" field group, binding its Description and\n * Amount fields to the `reimbursementDraft` form path.\n *\n * @param errorMessages - Copy for each validation error code, baked into the amount field so it self-resolves.\n * @returns The pre-bound draft field group for `form.Fields.reimbursementDraft`.\n * @internal\n */\nexport function createReimbursementDraftFields(\n errorMessages?: PayrollEditEmployeeErrorMessages,\n): ReimbursementDraftFields {\n return {\n Description: createTextField('reimbursementDraft.description'),\n Amount: createNumberField('reimbursementDraft.amount', errorMessages),\n }\n}\n\n// ── Builders ───────────────────────────────────────────────────────────\n\n/** @internal */\nexport interface CreatePayrollEditEmployeeFieldsOptions {\n employeeCompensation: PayrollEmployeeCompensationsType | undefined\n /**\n * Fixed compensations to render, already merged with blank placeholders for\n * every company earning type (see `resolveEditableFixedCompensations`).\n */\n fixedCompensations: NonNullable<PayrollEmployeeCompensationsType['fixedCompensations']>\n workweeks: NormalizedWorkweek[]\n payrollCategory: PayrollCategory\n hasDirectDepositSetup: boolean\n /** Names of earning types included in the regular-rate-of-pay overtime calculation. */\n overtimeEarningNames: Set<string>\n /** Whether the employee is overtime-eligible (nonexempt family). Gates per-workweek splitting. */\n isOvertimeEligible: boolean\n /**\n * Gates per-workweek splitting\n * alongside `isOvertimeEligible`, and whether Overtime/Double-overtime rows\n * are included in `hours`.\n */\n withOvertime: boolean\n /** Job title lookup by job UUID, for per-job section headings. */\n jobTitlesByUuid: Map<string, string>\n /** Accrual balance by time-off policy name, for the remaining-balance display. */\n timeOffAccrualByName: Map<string, string>\n /** Copy for each validation error code, baked into every bound field so it self-resolves. */\n errorMessages?: PayrollEditEmployeeErrorMessages\n}\n\n/**\n * A time-off policy's remaining balance: its accrual balance minus the entered\n * hours. `null` when the policy has no tracked accrual balance (final-payout\n * rows). Shared by the field builder (seeding the initial value) and the hook\n * (recomputing it live as the user edits).\n *\n * @param accrualBalance - The policy's accrual balance, or `undefined` when untracked.\n * @param enteredHours - The currently entered hours for the policy.\n * @returns The remaining balance, or `null` when untracked.\n * @internal\n */\nexport function computeTimeOffRemaining(\n accrualBalance: string | undefined,\n enteredHours: string | null | undefined,\n): number | null {\n if (accrualBalance == null) return null\n return parseFloat(accrualBalance) - (parseFloat(enteredHours ?? '') || 0)\n}\n\nfunction buildBreakdownSection(\n compensations: Array<{ jobUuid?: string; name?: string }>,\n workweeks: NormalizedWorkweek[],\n pathPrefix: 'hours' | 'overtimeIncludedEarnings',\n isOvertimeEligible: boolean,\n withOvertime: boolean,\n errorMessages: PayrollEditEmployeeErrorMessages | undefined,\n): HourEntry[] | Record<string, HourEntry[]> {\n const rows = compensations.filter(\n (compensation): compensation is { jobUuid: string; name: string } =>\n Boolean(compensation.jobUuid) && Boolean(compensation.name),\n )\n\n const toEntry = (\n row: { jobUuid: string; name: string },\n weekStart: string,\n includeWorkweek: boolean,\n ): HourEntry => ({\n key: includeWorkweek ? `${row.jobUuid}:${row.name}:${weekStart}` : `${row.jobUuid}:${row.name}`,\n jobUuid: row.jobUuid,\n name: row.name,\n ...(includeWorkweek ? { workweekStart: weekStart } : {}),\n Field: createNumberField(\n `${pathPrefix}.${row.jobUuid}.${row.name}.${weekStart}`,\n errorMessages,\n ),\n })\n\n // Split into per-workweek columns only for overtime-eligible employees while\n // `withOvertime` is on; workweek breakdowns exist solely to compute overtime\n // premiums, so an ineligible employee renders flat even on a multi-workweek\n // payroll, and an eligible one stays flat until `withOvertime` is set.\n if (workweeks.length > 1 && isOvertimeEligible && withOvertime) {\n const byWeek: Record<string, HourEntry[]> = {}\n for (const workweek of workweeks) {\n byWeek[workweek.startDate] = rows.map(row => toEntry(row, workweek.startDate, true))\n }\n return byWeek\n }\n\n const weekStart = workweeks[0]?.startDate ?? ''\n return rows.map(row => toEntry(row, weekStart, false))\n}\n\n/**\n * Builds the render-ready {@link PayrollEditEmployeeFields} from the prepared\n * compensation.\n *\n * @remarks\n * Hours and overtime-affecting earnings are grouped per job into `jobs` (a job\n * appears if it has hourly lines or overtime-affecting earnings). Fixed\n * compensations are split by whether their earning type is included in the\n * regular-rate-of-pay overtime calculation (`overtimeEarningNames`): included\n * earnings become each job's additional earnings, the rest become the flat,\n * employee-level `overtimeExcludedEarnings` section. Time off comes from the paid-time-off list,\n * final payout is added only for dismissal payrolls, and the payment-method\n * selector appears only when direct deposit is set up.\n *\n * @param options - The prepared compensation, normalized workweeks, payroll category, direct-deposit flag, overtime earning names, eligibility, the `withOvertime` flag, job titles, time-off accrual balances and entered values, and error copy.\n * @returns The populated field collections.\n * @internal\n */\nexport function createPayrollEditEmployeeFields({\n employeeCompensation,\n fixedCompensations,\n workweeks,\n payrollCategory,\n hasDirectDepositSetup,\n overtimeEarningNames,\n isOvertimeEligible,\n withOvertime,\n jobTitlesByUuid,\n timeOffAccrualByName,\n errorMessages,\n}: CreatePayrollEditEmployeeFieldsOptions): PayrollEditEmployeeFields {\n const hourlyCompensations = employeeCompensation?.hourlyCompensations ?? []\n const overtimeAffecting = fixedCompensations.filter(\n compensation => compensation.name != null && overtimeEarningNames.has(compensation.name),\n )\n const nonOvertime = fixedCompensations.filter(\n compensation => compensation.name == null || !overtimeEarningNames.has(compensation.name),\n )\n\n // A job appears if it has hourly lines or overtime-affecting earnings, in first\n // appearance order across those two sources.\n const jobUuids: string[] = []\n for (const compensation of [...hourlyCompensations, ...overtimeAffecting]) {\n if (compensation.jobUuid && !jobUuids.includes(compensation.jobUuid)) {\n jobUuids.push(compensation.jobUuid)\n }\n }\n\n const isOvertimeName = (name: string | null | undefined) =>\n name === COMPENSATION_NAME_OVERTIME || name === COMPENSATION_NAME_DOUBLE_OVERTIME\n\n const jobs: JobFields[] = jobUuids.map(jobUuid => {\n const jobHourlyCompensations = hourlyCompensations.filter(\n compensation => compensation.jobUuid === jobUuid,\n )\n // Overtime/Double-overtime rows stay out of `hours` entirely while\n // `withOvertime` is off — their underlying form values are untouched\n // (still whatever the prepared compensation carried), so hiding the row\n // can't lose or corrupt data. Driven by the single, employee-level flag —\n // no per-job hidden state.\n const visibleHourlyCompensations = withOvertime\n ? jobHourlyCompensations\n : jobHourlyCompensations.filter(compensation => !isOvertimeName(compensation.name))\n\n return {\n jobUuid,\n title: jobTitlesByUuid.get(jobUuid),\n hours: buildBreakdownSection(\n visibleHourlyCompensations,\n workweeks,\n 'hours',\n isOvertimeEligible,\n withOvertime,\n errorMessages,\n ),\n }\n })\n\n // Overtime-affecting earnings render as one employee-level section spanning\n // every job. Each entry keeps its per-job form path\n // (`overtimeIncludedEarnings.<jobUuid>.<name>`), so the flat section still binds and\n // submits per job.\n const overtimeIncludedEarnings = buildBreakdownSection(\n overtimeAffecting,\n workweeks,\n 'overtimeIncludedEarnings',\n isOvertimeEligible,\n withOvertime,\n errorMessages,\n )\n\n const overtimeExcludedEarnings: OtherEntry[] = nonOvertime\n .filter(\n (compensation): compensation is { jobUuid: string; name: string } =>\n Boolean(compensation.jobUuid) && Boolean(compensation.name),\n )\n .map(compensation => ({\n key: `${compensation.jobUuid}:${compensation.name}`,\n id: compensation.name,\n Field: createNumberField(\n `overtimeExcludedEarnings.${compensation.jobUuid}.${compensation.name}`,\n errorMessages,\n ),\n }))\n\n const timeOffRows = (employeeCompensation?.paidTimeOff ?? []).filter(entry => entry.name)\n const timeOff: TimeOffEntry[] = timeOffRows.map(entry => ({\n key: `timeOff:${entry.name!}`,\n name: entry.name!,\n Field: createNumberField(`timeOff.${entry.name!}`, errorMessages),\n // Seeded from the initial entered hours; the hook recomputes it live.\n remaining: computeTimeOffRemaining(timeOffAccrualByName.get(entry.name!), entry.hours),\n }))\n\n // Final-payout rows never show a remaining balance.\n const finalPayout =\n payrollCategory === PayrollCategory.Dismissal\n ? timeOffRows.map(entry => ({\n key: `finalPayout:${entry.name!}`,\n name: entry.name!,\n Field: createNumberField(`finalPayout.${entry.name!}`, errorMessages),\n remaining: null,\n }))\n : undefined\n\n return {\n jobs,\n overtimeIncludedEarnings,\n overtimeExcludedEarnings,\n timeOff,\n finalPayout,\n paymentMethod: hasDirectDepositSetup ? createPaymentMethodField() : undefined,\n }\n}\n"],"names":["isSplitByWorkweek","section","createNumberField","name","errorMessages","props","errorMessage","useFieldErrorMessage","jsx","TextInputField","stripLeadingZeros","createPaymentMethodField","RadioGroupHookField","createTextField","createReimbursementDraftFields","computeTimeOffRemaining","accrualBalance","enteredHours","buildBreakdownSection","compensations","workweeks","pathPrefix","isOvertimeEligible","withOvertime","rows","compensation","toEntry","row","weekStart","includeWorkweek","byWeek","workweek","createPayrollEditEmployeeFields","employeeCompensation","fixedCompensations","payrollCategory","hasDirectDepositSetup","overtimeEarningNames","jobTitlesByUuid","timeOffAccrualByName","hourlyCompensations","overtimeAffecting","nonOvertime","jobUuids","isOvertimeName","COMPENSATION_NAME_OVERTIME","COMPENSATION_NAME_DOUBLE_OVERTIME","jobs","jobUuid","jobHourlyCompensations","visibleHourlyCompensations","overtimeIncludedEarnings","overtimeExcludedEarnings","timeOffRows","entry","timeOff","finalPayout","PayrollCategory"],"mappings":"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"}
1
+ {"version":3,"file":"fields.js","sources":["../../../../../../src/components/Payroll/PayrollEditEmployee/shared/usePayrollEditEmployeeForm/fields.tsx"],"sourcesContent":["import type { ComponentType } from 'react'\nimport type { PayrollEmployeeCompensationsType } from '@gusto/embedded-api/models/components/payrollemployeecompensationstype'\nimport type { PayrollUpdatePaymentMethod } from '@gusto/embedded-api/models/components/payrollupdate'\nimport type { NormalizedWorkweek } from './payrollEditEmployeeHelpers'\nimport {\n MAX_HOURS,\n MAX_REIMBURSEMENT_AMOUNT,\n type PayrollEditEmployeeErrorCode,\n} from './payrollEditEmployeeSchema'\nimport { TextInputField } from '@/components/Common/Fields/TextInputField/TextInputField'\nimport { useFieldErrorMessage } from '@/partner-hook-utils/form/useFieldErrorMessage'\nimport { RadioGroupHookField } from '@/partner-hook-utils/form/fields'\nimport type { RadioGroupHookFieldProps } from '@/partner-hook-utils/form/fields/RadioGroupHookField'\nimport type { HookFieldProps, ValidationMessages } from '@/partner-hook-utils/types'\nimport type { TextInputProps } from '@/components/Common/UI/TextInput/TextInputTypes'\nimport { PayrollCategory } from '@/components/Payroll/payrollTypes'\nimport { COMPENSATION_NAME_DOUBLE_OVERTIME, COMPENSATION_NAME_OVERTIME } from '@/shared/constants'\nimport { stripLeadingZeros } from '@/helpers/formattedStrings'\n\n/**\n * Display copy for each validation error code a bound field can surface, so the\n * consumer supplies error text once (keyed by code) rather than reconstructing\n * form paths or hardcoding which rule each field can fail. Partial: a missing\n * code falls back to the raw error code.\n *\n * @public\n */\nexport type PayrollEditEmployeeErrorMessages = Partial<Record<PayrollEditEmployeeErrorCode, string>>\n\n/**\n * Presentation props accepted by a bound numeric field in the payroll editor.\n *\n * @remarks\n * The hook binds the react-hook-form `name`, forces `type=\"number\"`, and\n * resolves the field's own validation message internally; the UI supplies copy\n * and layout props (label, adornments, `shouldVisuallyHideLabel`, required\n * state, `description`).\n *\n * @public\n */\nexport type PayrollEditEmployeeFieldProps = Omit<\n TextInputProps,\n 'name' | 'value' | 'onChange' | 'isInvalid' | 'type' | 'min' | 'errorMessage'\n>\n\n/**\n * A numeric field component pre-bound by the hook to a specific form path.\n *\n * @public\n */\nexport type PayrollEditEmployeeFieldComponent = ComponentType<PayrollEditEmployeeFieldProps>\n\n/**\n * Presentation props accepted by the bound payment-method field.\n *\n * @remarks\n * The hook binds the `name` and publishes the option values on\n * `fieldsMetadata.paymentMethod`; the UI passes `getOptionLabel` to translate\n * each {@link PayrollUpdatePaymentMethod} value, rather than passing `options`.\n *\n * @public\n */\nexport type PayrollEditEmployeePaymentMethodFieldProps = HookFieldProps<\n RadioGroupHookFieldProps<never, PayrollUpdatePaymentMethod>\n>\n\n/**\n * The payment-method radio field component pre-bound by the hook.\n *\n * @public\n */\nexport type PayrollEditEmployeePaymentMethodField =\n ComponentType<PayrollEditEmployeePaymentMethodFieldProps>\n\n/**\n * One hours input within the hours section.\n *\n * @remarks\n * `key` is an opaque, stable React key. `jobUuid`, `name`, and (when the pay\n * period is multi-workweek) `workweekStart` are reach-in handles the UI uses to\n * group and label entries. When the section is a flat array, `workweekStart` is\n * omitted (single-workweek degenerate case); when it is a `Record` keyed by\n * workweek start, each entry carries its `workweekStart`.\n *\n * @public\n */\nexport interface HourEntry {\n /** Opaque, stable React key. */\n key: string\n /** The job this hours line belongs to. */\n jobUuid: string\n /** The compensation name (e.g. the API hours-compensation name). */\n name: string\n /** The workweek start date (`YYYY-MM-DD`) when the section is workweek-keyed. */\n workweekStart?: string\n /** Field component pre-bound to this entry's form path. */\n Field: PayrollEditEmployeeFieldComponent\n}\n\n/**\n * One earning input, used by the additional-earnings section.\n *\n * @remarks\n * Same shape as {@link HourEntry}. Whether an earning feeds the overtime\n * (regular rate of pay) calculation is decided by the hook, which sorts it into\n * the workweek-breakdown additional-earnings section or the flat other\n * section. The UI just renders whichever section an entry appears in.\n *\n * @public\n */\nexport type EarningEntry = HourEntry\n\n/**\n * One time-off or final-payout input.\n *\n * @remarks\n * Time off is never workweek-breakdown, so this section is always a flat array.\n *\n * @public\n */\nexport interface TimeOffEntry {\n /** Opaque, stable React key. */\n key: string\n /** The time-off policy compensation name. */\n name: string\n /** Field component pre-bound to this entry's form path. */\n Field: PayrollEditEmployeeFieldComponent\n /**\n * The policy's remaining balance after the entered hours are subtracted,\n * recomputed live as the user edits. `null` when the policy has no tracked\n * accrual balance (e.g. final-payout rows). Feed it into the field's own\n * `description` to render it as the input's help text.\n */\n remaining: number | null\n}\n\n/**\n * One entry in the flat `overtimeExcludedEarnings` section.\n *\n * @remarks\n * Intentionally opaque: `overtimeExcludedEarnings` collects earnings that are not overtime-affecting\n * and whose input type the partner does not need to reason about. Render each\n * entry's `Field` keyed by `key`; use `id` as a reach-in handle for labeling.\n *\n * @public\n */\nexport interface OtherEntry {\n /** Opaque, stable React key. */\n key: string\n /** Reach-in handle identifying the underlying earning (its compensation name). */\n id: string\n /** Field component pre-bound to this entry's form path. */\n Field: PayrollEditEmployeeFieldComponent\n}\n\n/**\n * A single job's hours section.\n *\n * @remarks\n * An employee can hold multiple jobs, each with its own hourly lines. `hours` is\n * either a flat `Entry[]` (single-workweek, or an overtime-ineligible employee)\n * OR a `Record<workweekStart, Entry[]>` (multi-workweek and overtime-eligible).\n * The value type is the signal — array is flat, object is split by workweek; use\n * {@link isSplitByWorkweek} to discriminate. `title` is the job's display title\n * (entity data, not copy) for rendering a per-job heading. Earnings are not\n * job-scoped: they live in the employee-level `overtimeIncludedEarnings` and\n * `overtimeExcludedEarnings` sections on {@link PayrollEditEmployeeFields}.\n *\n * @public\n */\nexport interface JobFields {\n /** The job identifier. */\n jobUuid: string\n /** The job's display title, when available, for a per-job heading. */\n title?: string\n /**\n * Hours inputs for this job. Excludes Overtime/Double-overtime rows while\n * `data.withOvertime` is `false`.\n */\n hours: HourEntry[] | Record<string, HourEntry[]>\n}\n\n/**\n * Presentation props accepted by a bound reimbursement description (text) field.\n *\n * @remarks\n * The hook binds the react-hook-form `name` internally; the UI supplies copy and\n * layout props (label, placeholder, `shouldVisuallyHideLabel`).\n *\n * @public\n */\nexport type ReimbursementDescriptionFieldProps = Omit<\n TextInputProps,\n 'name' | 'value' | 'onChange' | 'isInvalid' | 'type'\n>\n\n/**\n * The draft \"add reimbursement\" field group exposed on\n * `form.Fields.reimbursementDraft`.\n *\n * @remarks\n * A single in-progress row the UI reveals when the user starts adding a\n * reimbursement. `Description` and `Amount` bind to `reimbursementDraft.description`\n * / `reimbursementDraft.amount`. The UI shows them while `form.reimbursementDraft.isAdding`\n * is `true`, then calls `actions.saveReimbursement` (commits to the list) or\n * `actions.cancelReimbursement` (discards). Committed rows are rendered from\n * `data.reimbursements`, not from bound fields.\n *\n * @public\n */\nexport interface ReimbursementDraftFields {\n /** Description field pre-bound to the draft's form path. */\n Description: ComponentType<ReimbursementDescriptionFieldProps>\n /** Amount field pre-bound to the draft's form path. */\n Amount: PayrollEditEmployeeFieldComponent\n}\n\n/**\n * A committed reimbursement row for display in the consumer's table.\n *\n * @remarks\n * Exposed on `data.reimbursements`, seeded from the employee's existing\n * reimbursements and appended to as the user saves drafts. Display-only: the UI\n * renders `description`, `amount`, and the recurring/one-time `type`, plus a\n * remove control wired to `actions.removeReimbursement(index)`. `index` is the\n * row's position in the underlying form array (the removal handle); `uuid` is\n * present for rows that already exist server-side.\n *\n * @public\n */\nexport interface ReimbursementRow {\n /** Opaque, stable React key. */\n key: string\n /** The row's index in the reimbursements form array; pass to `removeReimbursement`. */\n index: number\n /** The reimbursement's server UUID, when it already exists. */\n uuid?: string\n /** The reimbursement description (may be blank; the UI supplies a fallback). */\n description: string\n /** The reimbursement amount as a decimal string. */\n amount: string\n /** Whether this reimbursement recurs. Recurring rows are managed outside payroll. */\n recurring: boolean\n}\n\n/**\n * The render-ready field collections exposed on `form.Fields`.\n *\n * @remarks\n * Hours are grouped under `jobs`, one entry per job, so multi-job employees\n * render correctly. All earnings and the remaining sections are employee-scoped\n * and stay top-level: `overtimeIncludedEarnings` (overtime-affecting) and\n * `overtimeExcludedEarnings` (non-overtime) each render as a single section spanning every\n * job, alongside time off, final payout, payment method, and reimbursements.\n *\n * @public\n */\nexport interface PayrollEditEmployeeFields {\n /** Per-job hours sections; one entry per job. */\n jobs: JobFields[]\n /**\n * Overtime-affecting earnings across all jobs, as a single employee-level\n * section. Flat `Entry[]` when unsplit, or `Record<workweekStart, Entry[]>`\n * when split by workweek; use {@link isSplitByWorkweek} to discriminate.\n */\n overtimeIncludedEarnings: EarningEntry[] | Record<string, EarningEntry[]>\n /** Non-overtime earnings (e.g. tips), always flat; opaque render entries. */\n overtimeExcludedEarnings: OtherEntry[]\n /** Time-off inputs (never workweek-breakdown). */\n timeOff: TimeOffEntry[]\n /** Final-payout inputs, present only for dismissal payrolls. */\n finalPayout?: TimeOffEntry[]\n /** Payment-method selector, present only when the employee has direct deposit set up. */\n paymentMethod?: PayrollEditEmployeePaymentMethodField\n /**\n * The draft \"add reimbursement\" field group, present only for itemized\n * (non-off-cycle) payrolls. Render while `form.reimbursementDraft.isAdding` is\n * `true`; committed rows come from `data.reimbursements`.\n */\n reimbursementDraft?: ReimbursementDraftFields\n}\n\n/**\n * Discriminates a workweek-breakdown section: `false` for the flat\n * (single-workweek) `Entry[]` form, `true` for the workweek-keyed\n * `Record<workweekStart, Entry[]>` form.\n *\n * @typeParam TEntry - The section's entry type.\n * @param section - A `form.Fields` section that may be flat or workweek-keyed.\n * @returns `true` when the section is keyed by workweek start date.\n * @public\n */\nexport function isSplitByWorkweek<TEntry>(\n section: TEntry[] | Record<string, TEntry[]>,\n): section is Record<string, TEntry[]> {\n return !Array.isArray(section)\n}\n\n// ── Bound field factories ──────────────────────────────────────────────\n\nfunction createNumberField(\n name: string,\n errorMessages?: PayrollEditEmployeeErrorMessages,\n max?: number,\n): PayrollEditEmployeeFieldComponent {\n return function BoundNumberField(props: PayrollEditEmployeeFieldProps) {\n // The field resolves its own validation copy from its bound path, so the\n // consumer supplies error copy once (keyed by code) and never reconstructs\n // form paths or guesses which rule a field can fail. name, type, min, max,\n // transform, and errorMessage are applied after the spread so callers can't\n // override the binding or the numeric contract via custom props.\n const errorMessage = useFieldErrorMessage(\n name,\n errorMessages as ValidationMessages<PayrollEditEmployeeErrorCode> | undefined,\n )\n return (\n <TextInputField\n {...props}\n name={name}\n type=\"number\"\n min={0}\n max={max}\n transform={stripLeadingZeros}\n errorMessage={errorMessage}\n />\n )\n }\n}\n\nfunction createPaymentMethodField(): PayrollEditEmployeePaymentMethodField {\n return function BoundPaymentMethodField(props: PayrollEditEmployeePaymentMethodFieldProps) {\n return (\n <RadioGroupHookField<never, PayrollUpdatePaymentMethod> {...props} name=\"paymentMethod\" />\n )\n }\n}\n\nfunction createTextField(name: string): ComponentType<ReimbursementDescriptionFieldProps> {\n return function BoundTextField(props: ReimbursementDescriptionFieldProps) {\n return <TextInputField {...props} name={name} />\n }\n}\n\n/**\n * Builds the draft \"add reimbursement\" field group, binding its Description and\n * Amount fields to the `reimbursementDraft` form path.\n *\n * @param errorMessages - Copy for each validation error code, baked into the amount field so it self-resolves.\n * @returns The pre-bound draft field group for `form.Fields.reimbursementDraft`.\n * @internal\n */\nexport function createReimbursementDraftFields(\n errorMessages?: PayrollEditEmployeeErrorMessages,\n): ReimbursementDraftFields {\n return {\n Description: createTextField('reimbursementDraft.description'),\n Amount: createNumberField('reimbursementDraft.amount', errorMessages, MAX_REIMBURSEMENT_AMOUNT),\n }\n}\n\n// ── Builders ───────────────────────────────────────────────────────────\n\n/** @internal */\nexport interface CreatePayrollEditEmployeeFieldsOptions {\n employeeCompensation: PayrollEmployeeCompensationsType | undefined\n /**\n * Fixed compensations to render, already merged with blank placeholders for\n * every company earning type (see `resolveEditableFixedCompensations`).\n */\n fixedCompensations: NonNullable<PayrollEmployeeCompensationsType['fixedCompensations']>\n workweeks: NormalizedWorkweek[]\n payrollCategory: PayrollCategory\n hasDirectDepositSetup: boolean\n /** Names of earning types included in the regular-rate-of-pay overtime calculation. */\n overtimeEarningNames: Set<string>\n /** Whether the employee is overtime-eligible (nonexempt family). Gates per-workweek splitting. */\n isOvertimeEligible: boolean\n /**\n * Gates per-workweek splitting\n * alongside `isOvertimeEligible`, and whether Overtime/Double-overtime rows\n * are included in `hours`.\n */\n withOvertime: boolean\n /** Job title lookup by job UUID, for per-job section headings. */\n jobTitlesByUuid: Map<string, string>\n /** Accrual balance by time-off policy name, for the remaining-balance display. */\n timeOffAccrualByName: Map<string, string>\n /** Copy for each validation error code, baked into every bound field so it self-resolves. */\n errorMessages?: PayrollEditEmployeeErrorMessages\n}\n\n/**\n * A time-off policy's remaining balance: its accrual balance minus the entered\n * hours. `null` when the policy has no tracked accrual balance (final-payout\n * rows). Shared by the field builder (seeding the initial value) and the hook\n * (recomputing it live as the user edits).\n *\n * @param accrualBalance - The policy's accrual balance, or `undefined` when untracked.\n * @param enteredHours - The currently entered hours for the policy.\n * @returns The remaining balance, or `null` when untracked.\n * @internal\n */\nexport function computeTimeOffRemaining(\n accrualBalance: string | undefined,\n enteredHours: string | null | undefined,\n): number | null {\n if (accrualBalance == null) return null\n return parseFloat(accrualBalance) - (parseFloat(enteredHours ?? '') || 0)\n}\n\nfunction buildBreakdownSection(\n compensations: Array<{ jobUuid?: string; name?: string }>,\n workweeks: NormalizedWorkweek[],\n pathPrefix: 'hours' | 'overtimeIncludedEarnings',\n isOvertimeEligible: boolean,\n withOvertime: boolean,\n errorMessages: PayrollEditEmployeeErrorMessages | undefined,\n): HourEntry[] | Record<string, HourEntry[]> {\n const rows = compensations.filter(\n (compensation): compensation is { jobUuid: string; name: string } =>\n Boolean(compensation.jobUuid) && Boolean(compensation.name),\n )\n\n const toEntry = (\n row: { jobUuid: string; name: string },\n weekStart: string,\n includeWorkweek: boolean,\n ): HourEntry => ({\n key: includeWorkweek ? `${row.jobUuid}:${row.name}:${weekStart}` : `${row.jobUuid}:${row.name}`,\n jobUuid: row.jobUuid,\n name: row.name,\n ...(includeWorkweek ? { workweekStart: weekStart } : {}),\n Field: createNumberField(\n `${pathPrefix}.${row.jobUuid}.${row.name}.${weekStart}`,\n errorMessages,\n pathPrefix === 'hours' ? MAX_HOURS : undefined,\n ),\n })\n\n // Split into per-workweek columns only for overtime-eligible employees while\n // `withOvertime` is on; workweek breakdowns exist solely to compute overtime\n // premiums, so an ineligible employee renders flat even on a multi-workweek\n // payroll, and an eligible one stays flat until `withOvertime` is set.\n if (workweeks.length > 1 && isOvertimeEligible && withOvertime) {\n const byWeek: Record<string, HourEntry[]> = {}\n for (const workweek of workweeks) {\n byWeek[workweek.startDate] = rows.map(row => toEntry(row, workweek.startDate, true))\n }\n return byWeek\n }\n\n const weekStart = workweeks[0]?.startDate ?? ''\n return rows.map(row => toEntry(row, weekStart, false))\n}\n\n/**\n * Builds the render-ready {@link PayrollEditEmployeeFields} from the prepared\n * compensation.\n *\n * @remarks\n * Hours and overtime-affecting earnings are grouped per job into `jobs` (a job\n * appears if it has hourly lines or overtime-affecting earnings). Fixed\n * compensations are split by whether their earning type is included in the\n * regular-rate-of-pay overtime calculation (`overtimeEarningNames`): included\n * earnings become each job's additional earnings, the rest become the flat,\n * employee-level `overtimeExcludedEarnings` section. Time off comes from the paid-time-off list,\n * final payout is added only for dismissal payrolls, and the payment-method\n * selector appears only when direct deposit is set up.\n *\n * @param options - The prepared compensation, normalized workweeks, payroll category, direct-deposit flag, overtime earning names, eligibility, the `withOvertime` flag, job titles, time-off accrual balances and entered values, and error copy.\n * @returns The populated field collections.\n * @internal\n */\nexport function createPayrollEditEmployeeFields({\n employeeCompensation,\n fixedCompensations,\n workweeks,\n payrollCategory,\n hasDirectDepositSetup,\n overtimeEarningNames,\n isOvertimeEligible,\n withOvertime,\n jobTitlesByUuid,\n timeOffAccrualByName,\n errorMessages,\n}: CreatePayrollEditEmployeeFieldsOptions): PayrollEditEmployeeFields {\n const hourlyCompensations = employeeCompensation?.hourlyCompensations ?? []\n const overtimeAffecting = fixedCompensations.filter(\n compensation => compensation.name != null && overtimeEarningNames.has(compensation.name),\n )\n const nonOvertime = fixedCompensations.filter(\n compensation => compensation.name == null || !overtimeEarningNames.has(compensation.name),\n )\n\n // A job appears if it has hourly lines or overtime-affecting earnings, in first\n // appearance order across those two sources.\n const jobUuids: string[] = []\n for (const compensation of [...hourlyCompensations, ...overtimeAffecting]) {\n if (compensation.jobUuid && !jobUuids.includes(compensation.jobUuid)) {\n jobUuids.push(compensation.jobUuid)\n }\n }\n\n const isOvertimeName = (name: string | null | undefined) =>\n name === COMPENSATION_NAME_OVERTIME || name === COMPENSATION_NAME_DOUBLE_OVERTIME\n\n const jobs: JobFields[] = jobUuids.map(jobUuid => {\n const jobHourlyCompensations = hourlyCompensations.filter(\n compensation => compensation.jobUuid === jobUuid,\n )\n // Overtime/Double-overtime rows stay out of `hours` entirely while\n // `withOvertime` is off — their underlying form values are untouched\n // (still whatever the prepared compensation carried), so hiding the row\n // can't lose or corrupt data. Driven by the single, employee-level flag —\n // no per-job hidden state.\n const visibleHourlyCompensations = withOvertime\n ? jobHourlyCompensations\n : jobHourlyCompensations.filter(compensation => !isOvertimeName(compensation.name))\n\n return {\n jobUuid,\n title: jobTitlesByUuid.get(jobUuid),\n hours: buildBreakdownSection(\n visibleHourlyCompensations,\n workweeks,\n 'hours',\n isOvertimeEligible,\n withOvertime,\n errorMessages,\n ),\n }\n })\n\n // Overtime-affecting earnings render as one employee-level section spanning\n // every job. Each entry keeps its per-job form path\n // (`overtimeIncludedEarnings.<jobUuid>.<name>`), so the flat section still binds and\n // submits per job.\n const overtimeIncludedEarnings = buildBreakdownSection(\n overtimeAffecting,\n workweeks,\n 'overtimeIncludedEarnings',\n isOvertimeEligible,\n withOvertime,\n errorMessages,\n )\n\n const overtimeExcludedEarnings: OtherEntry[] = nonOvertime\n .filter(\n (compensation): compensation is { jobUuid: string; name: string } =>\n Boolean(compensation.jobUuid) && Boolean(compensation.name),\n )\n .map(compensation => ({\n key: `${compensation.jobUuid}:${compensation.name}`,\n id: compensation.name,\n Field: createNumberField(\n `overtimeExcludedEarnings.${compensation.jobUuid}.${compensation.name}`,\n errorMessages,\n ),\n }))\n\n const timeOffRows = (employeeCompensation?.paidTimeOff ?? []).filter(entry => entry.name)\n const timeOff: TimeOffEntry[] = timeOffRows.map(entry => ({\n key: `timeOff:${entry.name!}`,\n name: entry.name!,\n Field: createNumberField(`timeOff.${entry.name!}`, errorMessages),\n // Seeded from the initial entered hours; the hook recomputes it live.\n remaining: computeTimeOffRemaining(timeOffAccrualByName.get(entry.name!), entry.hours),\n }))\n\n // Final-payout rows never show a remaining balance.\n const finalPayout =\n payrollCategory === PayrollCategory.Dismissal\n ? timeOffRows.map(entry => ({\n key: `finalPayout:${entry.name!}`,\n name: entry.name!,\n Field: createNumberField(`finalPayout.${entry.name!}`, errorMessages),\n remaining: null,\n }))\n : undefined\n\n return {\n jobs,\n overtimeIncludedEarnings,\n overtimeExcludedEarnings,\n timeOff,\n finalPayout,\n paymentMethod: hasDirectDepositSetup ? createPaymentMethodField() : undefined,\n }\n}\n"],"names":["isSplitByWorkweek","section","createNumberField","name","errorMessages","max","props","errorMessage","useFieldErrorMessage","jsx","TextInputField","stripLeadingZeros","createPaymentMethodField","RadioGroupHookField","createTextField","createReimbursementDraftFields","MAX_REIMBURSEMENT_AMOUNT","computeTimeOffRemaining","accrualBalance","enteredHours","buildBreakdownSection","compensations","workweeks","pathPrefix","isOvertimeEligible","withOvertime","rows","compensation","toEntry","row","weekStart","includeWorkweek","MAX_HOURS","byWeek","workweek","createPayrollEditEmployeeFields","employeeCompensation","fixedCompensations","payrollCategory","hasDirectDepositSetup","overtimeEarningNames","jobTitlesByUuid","timeOffAccrualByName","hourlyCompensations","overtimeAffecting","nonOvertime","jobUuids","isOvertimeName","COMPENSATION_NAME_OVERTIME","COMPENSATION_NAME_DOUBLE_OVERTIME","jobs","jobUuid","jobHourlyCompensations","visibleHourlyCompensations","overtimeIncludedEarnings","overtimeExcludedEarnings","timeOffRows","entry","timeOff","finalPayout","PayrollCategory"],"mappings":"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"}