@gusto/embedded-react-sdk 0.46.2 → 0.46.3

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 (172) hide show
  1. package/CHANGELOG.md +67 -0
  2. package/dist/components/Common/DataView/DataTable/DataTable.js +76 -72
  3. package/dist/components/Common/DataView/DataTable/DataTable.js.map +1 -1
  4. package/dist/components/Common/DataView/DataTable/DataTable.module.scss.js +8 -0
  5. package/dist/components/Common/DataView/DataTable/DataTable.module.scss.js.map +1 -0
  6. package/dist/components/Common/DataView/useDataView.d.ts +2 -0
  7. package/dist/components/Common/DataView/useDataView.js.map +1 -1
  8. package/dist/components/Common/DocumentViewer/DocumentViewer.js +10 -10
  9. package/dist/components/Common/DocumentViewer/DocumentViewer.js.map +1 -1
  10. package/dist/components/Common/DocumentViewer/DocumentViewer.module.scss.js +9 -9
  11. package/dist/components/Common/PaginationControl/PaginationControl.js +11 -10
  12. package/dist/components/Common/PaginationControl/PaginationControl.js.map +1 -1
  13. package/dist/components/Common/PaginationControl/PaginationControlTypes.d.ts +1 -1
  14. package/dist/components/Common/UI/DescriptionList/DescriptionList.js +11 -10
  15. package/dist/components/Common/UI/DescriptionList/DescriptionList.js.map +1 -1
  16. package/dist/components/Common/UI/DescriptionList/DescriptionList.module.scss.js +4 -4
  17. package/dist/components/Common/UI/Input/InputTypes.d.ts +1 -1
  18. package/dist/components/Common/UI/Input/InputTypes.js.map +1 -1
  19. package/dist/components/Common/UI/NumberInput/NumberInput.js +51 -48
  20. package/dist/components/Common/UI/NumberInput/NumberInput.js.map +1 -1
  21. package/dist/components/Common/VisuallyHidden/VisuallyHidden.d.ts +1 -1
  22. package/dist/components/Common/VisuallyHidden/VisuallyHidden.js.map +1 -1
  23. package/dist/components/Company/AssignSignatory/CreateSignatory/useCreateSignatory.js +3 -4
  24. package/dist/components/Company/AssignSignatory/CreateSignatory/useCreateSignatory.js.map +1 -1
  25. package/dist/components/Company/AssignSignatory/InviteSignatory/useInviteSignatory.js +3 -4
  26. package/dist/components/Company/AssignSignatory/InviteSignatory/useInviteSignatory.js.map +1 -1
  27. package/dist/components/Company/AssignSignatory/useAssignSignatory.js +5 -6
  28. package/dist/components/Company/AssignSignatory/useAssignSignatory.js.map +1 -1
  29. package/dist/components/Company/BankAccount/BankAccountForm/context.js +3 -4
  30. package/dist/components/Company/BankAccount/BankAccountForm/context.js.map +1 -1
  31. package/dist/components/Company/DocumentSigner/DocumentList/useDocumentList.js +3 -4
  32. package/dist/components/Company/DocumentSigner/DocumentList/useDocumentList.js.map +1 -1
  33. package/dist/components/Company/DocumentSigner/shared/useSignCompanyForm/fields.js +4 -4
  34. package/dist/components/Company/FederalTaxes/useFederalTaxes.js +5 -6
  35. package/dist/components/Company/FederalTaxes/useFederalTaxes.js.map +1 -1
  36. package/dist/components/Company/Industry/Context.js +6 -7
  37. package/dist/components/Company/Industry/Context.js.map +1 -1
  38. package/dist/components/Company/Locations/LocationForm/useLocationForm.js +3 -4
  39. package/dist/components/Company/Locations/LocationForm/useLocationForm.js.map +1 -1
  40. package/dist/components/Company/Locations/LocationsList/useLocationsList.js +3 -4
  41. package/dist/components/Company/Locations/LocationsList/useLocationsList.js.map +1 -1
  42. package/dist/components/Company/OnboardingOverview/context.js +3 -4
  43. package/dist/components/Company/OnboardingOverview/context.js.map +1 -1
  44. package/dist/components/Company/PaySchedule/shared/usePayScheduleForm/fields.js +5 -5
  45. package/dist/components/Company/StateTaxes/StateTaxesForm/context.js +3 -4
  46. package/dist/components/Company/StateTaxes/StateTaxesForm/context.js.map +1 -1
  47. package/dist/components/Company/StateTaxes/StateTaxesList/context.js +3 -4
  48. package/dist/components/Company/StateTaxes/StateTaxesList/context.js.map +1 -1
  49. package/dist/components/Contractor/Address/useAddress.js +5 -6
  50. package/dist/components/Contractor/Address/useAddress.js.map +1 -1
  51. package/dist/components/Contractor/Profile/useContractorProfile.js +33 -34
  52. package/dist/components/Contractor/Profile/useContractorProfile.js.map +1 -1
  53. package/dist/components/Employee/Compensation/management/EditCompensation/EditCompensation.js +14 -11
  54. package/dist/components/Employee/Compensation/management/EditCompensation/EditCompensation.js.map +1 -1
  55. package/dist/components/Employee/Compensation/management/EditPendingCompensation/EditPendingCompensation.js +0 -2
  56. package/dist/components/Employee/Compensation/management/EditPendingCompensation/EditPendingCompensation.js.map +1 -1
  57. package/dist/components/Employee/Compensation/management/ManagementCompensationFormBody.js +18 -18
  58. package/dist/components/Employee/Compensation/management/ManagementCompensationFormBody.js.map +1 -1
  59. package/dist/components/Employee/Compensation/onboarding/JobsList/JobsListPresentation.js +36 -36
  60. package/dist/components/Employee/Compensation/onboarding/JobsList/JobsListPresentation.js.map +1 -1
  61. package/dist/components/Employee/Compensation/shared/useCompensationForm/fields.js +4 -4
  62. package/dist/components/Employee/Compensation/shared/useCompensationForm/useCompensationForm.js +140 -140
  63. package/dist/components/Employee/Compensation/shared/useCompensationForm/useCompensationForm.js.map +1 -1
  64. package/dist/components/Employee/Compensation/shared/useJobForm/fields.js +6 -6
  65. package/dist/components/Employee/Compensation/shared/useJobForm/useJobForm.d.ts +6 -5
  66. package/dist/components/Employee/Compensation/shared/useJobForm/useJobForm.js +162 -131
  67. package/dist/components/Employee/Compensation/shared/useJobForm/useJobForm.js.map +1 -1
  68. package/dist/components/Employee/Dashboard/BasicDetailsView.js +74 -88
  69. package/dist/components/Employee/Dashboard/BasicDetailsView.js.map +1 -1
  70. package/dist/components/Employee/Dashboard/Dashboard.js +53 -51
  71. package/dist/components/Employee/Dashboard/Dashboard.js.map +1 -1
  72. package/dist/components/Employee/Dashboard/DocumentsView.js +17 -10
  73. package/dist/components/Employee/Dashboard/DocumentsView.js.map +1 -1
  74. package/dist/components/Employee/Dashboard/JobAndPayView.js +383 -357
  75. package/dist/components/Employee/Dashboard/JobAndPayView.js.map +1 -1
  76. package/dist/components/Employee/Dashboard/TaxesView.js +114 -101
  77. package/dist/components/Employee/Dashboard/TaxesView.js.map +1 -1
  78. package/dist/components/Employee/Dashboard/getPendingCompensationChanges.js +36 -36
  79. package/dist/components/Employee/Dashboard/getPendingCompensationChanges.js.map +1 -1
  80. package/dist/components/Employee/Deductions/DeductionsForm/StandardDeductionForm.js +57 -57
  81. package/dist/components/Employee/Deductions/DeductionsForm/StandardDeductionForm.js.map +1 -1
  82. package/dist/components/Employee/Deductions/shared/useChildSupportGarnishmentForm/childSupportGarnishmentFormSchema.d.ts +14 -5
  83. package/dist/components/Employee/Deductions/shared/useChildSupportGarnishmentForm/childSupportGarnishmentFormSchema.js +55 -36
  84. package/dist/components/Employee/Deductions/shared/useChildSupportGarnishmentForm/childSupportGarnishmentFormSchema.js.map +1 -1
  85. package/dist/components/Employee/Deductions/shared/useChildSupportGarnishmentForm/fields.js +8 -8
  86. package/dist/components/Employee/Deductions/shared/useChildSupportGarnishmentForm/useChildSupportGarnishmentForm.js +18 -18
  87. package/dist/components/Employee/Deductions/shared/useChildSupportGarnishmentForm/useChildSupportGarnishmentForm.js.map +1 -1
  88. package/dist/components/Employee/Deductions/shared/useDeductionForm/fields.js +4 -4
  89. package/dist/components/Employee/Deductions/shared/useDeductionForm/useDeductionForm.d.ts +3 -3
  90. package/dist/components/Employee/Deductions/shared/useDeductionForm/useDeductionForm.js.map +1 -1
  91. package/dist/components/Employee/Documents/onboarding/DocumentSigner/DocumentList/useDocumentList.js +3 -4
  92. package/dist/components/Employee/Documents/onboarding/DocumentSigner/DocumentList/useDocumentList.js.map +1 -1
  93. package/dist/components/Employee/Documents/shared/useSignEmployeeForm/fields.js +1 -1
  94. package/dist/components/Employee/FederalTaxes/shared/useFederalTaxesForm/fields.js +4 -4
  95. package/dist/components/Employee/HomeAddress/management/HomeAddressView.js +157 -147
  96. package/dist/components/Employee/HomeAddress/management/HomeAddressView.js.map +1 -1
  97. package/dist/components/Employee/HomeAddress/management/useHomeAddressManagement.js +56 -55
  98. package/dist/components/Employee/HomeAddress/management/useHomeAddressManagement.js.map +1 -1
  99. package/dist/components/Employee/PaymentMethod/onboarding/BankForm.js +20 -20
  100. package/dist/components/Employee/PaymentMethod/onboarding/BankForm.js.map +1 -1
  101. package/dist/components/Employee/PaymentMethod/shared/useBankForm/fields.js +1 -1
  102. package/dist/components/Employee/PaymentMethod/shared/useSplitPaymentsForm/splitFieldFactory.d.ts +1 -1
  103. package/dist/components/Employee/PaymentMethod/shared/useSplitPaymentsForm/splitFieldFactory.js +4 -4
  104. package/dist/components/Employee/PaymentMethod/shared/useSplitPaymentsForm/splitFieldFactory.js.map +1 -1
  105. package/dist/components/Employee/Profile/shared/useEmployeeDetailsForm/fields.js +8 -8
  106. package/dist/components/Employee/Profile/shared/useHomeAddressForm/fields.js +5 -5
  107. package/dist/components/Employee/Profile/shared/useHomeAddressForm/homeAddressSchema.d.ts +0 -1
  108. package/dist/components/Employee/Profile/shared/useHomeAddressForm/homeAddressSchema.js +11 -12
  109. package/dist/components/Employee/Profile/shared/useHomeAddressForm/homeAddressSchema.js.map +1 -1
  110. package/dist/components/Employee/Profile/shared/useHomeAddressForm/homeAddressSchema.test.d.ts +1 -0
  111. package/dist/components/Employee/Profile/shared/useHomeAddressForm/useHomeAddressForm.d.ts +6 -1
  112. package/dist/components/Employee/Profile/shared/useHomeAddressForm/useHomeAddressForm.js +95 -94
  113. package/dist/components/Employee/Profile/shared/useHomeAddressForm/useHomeAddressForm.js.map +1 -1
  114. package/dist/components/Employee/Profile/shared/useWorkAddressForm/fields.js +4 -4
  115. package/dist/components/Employee/Profile/shared/useWorkAddressForm/useWorkAddressForm.d.ts +6 -1
  116. package/dist/components/Employee/Profile/shared/useWorkAddressForm/useWorkAddressForm.js +87 -86
  117. package/dist/components/Employee/Profile/shared/useWorkAddressForm/useWorkAddressForm.js.map +1 -1
  118. package/dist/components/Employee/StateTaxes/shared/EmployeeStateTaxesView.js +18 -18
  119. package/dist/components/Employee/StateTaxes/shared/EmployeeStateTaxesView.js.map +1 -1
  120. package/dist/components/Employee/StateTaxes/shared/useEmployeeStateTaxesForm/fieldComponents.js +8 -8
  121. package/dist/components/Employee/Taxes/useTaxes.js +3 -4
  122. package/dist/components/Employee/Taxes/useTaxes.js.map +1 -1
  123. package/dist/components/Employee/WorkAddress/management/WorkAddressView.js +5 -1
  124. package/dist/components/Employee/WorkAddress/management/WorkAddressView.js.map +1 -1
  125. package/dist/components/Employee/WorkAddress/management/useWorkAddressManagement.js +61 -60
  126. package/dist/components/Employee/WorkAddress/management/useWorkAddressManagement.js.map +1 -1
  127. package/dist/components/Payroll/GrossUpModal/GrossUpModal.js +2 -3
  128. package/dist/components/Payroll/GrossUpModal/GrossUpModal.js.map +1 -1
  129. package/dist/components/Payroll/usePreparedPayrollData.js +2 -3
  130. package/dist/components/Payroll/usePreparedPayrollData.js.map +1 -1
  131. package/dist/components/TimeOff/TimeOffManagement/SelectEmployees/SelectEmployeesHoliday.js +6 -7
  132. package/dist/components/TimeOff/TimeOffManagement/SelectEmployees/SelectEmployeesHoliday.js.map +1 -1
  133. package/dist/components/TimeOff/TimeOffManagement/SelectEmployees/SelectEmployeesPresentation.d.ts +1 -1
  134. package/dist/components/TimeOff/TimeOffManagement/SelectEmployees/SelectEmployeesPresentation.js +52 -68
  135. package/dist/components/TimeOff/TimeOffManagement/SelectEmployees/SelectEmployeesPresentation.js.map +1 -1
  136. package/dist/components/TimeOff/TimeOffManagement/SelectEmployees/SelectEmployeesPresentation.module.scss.js +4 -4
  137. package/dist/components/TimeOff/TimeOffManagement/SelectEmployees/SelectEmployeesPresentationTypes.d.ts +0 -11
  138. package/dist/components/TimeOff/TimeOffManagement/SelectEmployees/SelectEmployeesTimeOff.js +137 -163
  139. package/dist/components/TimeOff/TimeOffManagement/SelectEmployees/SelectEmployeesTimeOff.js.map +1 -1
  140. package/dist/components/TimeOff/TimeOffManagement/SelectEmployees/useSelectEmployeesData.js +36 -35
  141. package/dist/components/TimeOff/TimeOffManagement/SelectEmployees/useSelectEmployeesData.js.map +1 -1
  142. package/dist/components/TimeOff/TimeOffPolicyDetail/TimeOffPolicyDetailPresentation.js +34 -34
  143. package/dist/components/TimeOff/TimeOffPolicyDetail/TimeOffPolicyDetailPresentation.js.map +1 -1
  144. package/dist/helpers/breadcrumbHelpers.d.ts +1 -1
  145. package/dist/helpers/breadcrumbHelpers.js.map +1 -1
  146. package/dist/helpers/federalEin.d.ts +1 -0
  147. package/dist/helpers/federalEin.js.map +1 -1
  148. package/dist/helpers/mask.d.ts +8 -4
  149. package/dist/helpers/mask.js.map +1 -1
  150. package/dist/helpers/rem.d.ts +2 -1
  151. package/dist/helpers/rem.js.map +1 -1
  152. package/dist/hooks/useAsyncError.d.ts +1 -0
  153. package/dist/hooks/useAsyncError.js.map +1 -1
  154. package/dist/hooks/useForkRef/useForkRef.d.ts +1 -0
  155. package/dist/hooks/useForkRef/useForkRef.js.map +1 -1
  156. package/dist/i18n/I18n.d.ts +9 -1
  157. package/dist/i18n/I18n.js.map +1 -1
  158. package/dist/i18n/en/Company.TimeOff.EmployeeTable.json.js +14 -14
  159. package/dist/i18n/en/Company.TimeOff.SelectEmployees.json.js +12 -18
  160. package/dist/i18n/en/Company.TimeOff.SelectEmployees.json.js.map +1 -1
  161. package/dist/i18n/en/Employee.Compensation.json.js +24 -24
  162. package/dist/i18n/en/Employee.Dashboard.json.js +22 -20
  163. package/dist/i18n/en/Employee.Dashboard.json.js.map +1 -1
  164. package/dist/i18n/en/Employee.PaymentMethod.json.js +25 -25
  165. package/dist/i18n/en/Employee.StateTaxes.json.js +12 -10
  166. package/dist/i18n/en/Employee.StateTaxes.json.js.map +1 -1
  167. package/dist/style.css +1 -1
  168. package/dist/types/hooks.d.ts +1 -1
  169. package/dist/types/i18next.d.ts +4 -17
  170. package/dist/types/observability.d.ts +1 -1
  171. package/package.json +30 -27
  172. package/dist/components/Employee/Dashboard/CompensationCard.d.ts +0 -13
@@ -1 +1 @@
1
- {"version":3,"file":"TaxesView.js","sources":["../../../../src/components/Employee/Dashboard/TaxesView.tsx"],"sourcesContent":["import { useTranslation } from 'react-i18next'\nimport type { GetV1EmployeesEmployeeIdFederalTaxesResponse } from '@gusto/embedded-api/models/operations/getv1employeesemployeeidfederaltaxes'\nimport type { GetV1EmployeesEmployeeIdStateTaxesResponse } from '@gusto/embedded-api/models/operations/getv1employeesemployeeidstatetaxes'\nimport type { EmployeeStateTaxQuestion } from '@gusto/embedded-api/models/components/employeestatetaxquestion'\nimport { useEmployeeTaxes } from './hooks'\nimport { Flex } from '@/components/Common/Flex/Flex'\nimport { useComponentContext } from '@/contexts/ComponentAdapter/useComponentContext'\nimport { Loading } from '@/components/Common'\nimport { BaseLayout } from '@/components/Base/Base'\nimport useNumberFormatter from '@/hooks/useNumberFormatter'\n\ntype EmployeeFederalTax = NonNullable<\n GetV1EmployeesEmployeeIdFederalTaxesResponse['employeeFederalTax']\n>\ntype EmployeeStateTax = NonNullable<\n GetV1EmployeesEmployeeIdStateTaxesResponse['employeeStateTaxesList']\n>[number]\n\nexport interface TaxesViewProps {\n federalTaxes?: EmployeeFederalTax\n stateTaxes?: EmployeeStateTax[]\n /** Loads both cards. Override per-card via `isFederalTaxesLoading` /\n * `isStateTaxesLoading` when the queries resolve independently. */\n isLoading?: boolean\n isFederalTaxesLoading?: boolean\n isStateTaxesLoading?: boolean\n onEditFederalTaxes?: () => void\n onEditStateTaxes?: () => void\n}\n\nexport interface TaxesViewWithDataProps {\n employeeId: string\n /** Receives the federal-tax record so the parent can preserve the\n * existing event payload (`{ employeeId, federalTaxes }`). */\n onEditFederalTaxes?: (federalTaxes: EmployeeFederalTax | undefined) => void\n onEditStateTaxes?: () => void\n}\n\n/**\n * Tab-mounted container for the Taxes tab. Owns the `useEmployeeTaxes`\n * fetch so federal/state tax requests only fire when the tab is mounted.\n * Federal and state queries run independently — each card paints its\n * own skeleton + content as data arrives.\n */\nexport function TaxesViewWithData({\n employeeId,\n onEditFederalTaxes,\n onEditStateTaxes,\n}: TaxesViewWithDataProps) {\n const taxes = useEmployeeTaxes({ employeeId })\n\n const federalTaxes = taxes.data.employeeFederalTax\n return (\n <BaseLayout error={taxes.errorHandling.errors}>\n <TaxesView\n federalTaxes={federalTaxes}\n stateTaxes={taxes.data.employeeStateTaxesList}\n isFederalTaxesLoading={taxes.status.isFederalTaxesLoading}\n isStateTaxesLoading={taxes.status.isStateTaxesLoading}\n onEditFederalTaxes={() => onEditFederalTaxes?.(federalTaxes)}\n onEditStateTaxes={onEditStateTaxes}\n />\n </BaseLayout>\n )\n}\n\nexport function TaxesView({\n federalTaxes,\n stateTaxes,\n isLoading = false,\n isFederalTaxesLoading = isLoading,\n isStateTaxesLoading = isLoading,\n onEditFederalTaxes,\n onEditStateTaxes,\n}: TaxesViewProps) {\n const { t } = useTranslation('Employee.Dashboard')\n const Components = useComponentContext()\n const formatCurrency = useNumberFormatter('currency')\n\n // Helper function to format state tax answer values\n const formatStateTaxAnswer = (\n question: EmployeeStateTaxQuestion,\n answer: string | number | boolean,\n ) => {\n // For Select type questions, look up the label from options\n if (\n question.inputQuestionFormat.type === 'Select' &&\n question.inputQuestionFormat.options &&\n question.inputQuestionFormat.options.length > 0\n ) {\n const option = question.inputQuestionFormat.options.find(opt => opt.value === answer)\n if (option?.label) {\n return option.label\n }\n }\n\n // For numeric values, only format as currency for Currency questions\n if (typeof answer === 'number') {\n if (question.inputQuestionFormat.type === 'Currency') {\n return formatCurrency(answer)\n }\n return answer\n }\n\n // For string currency values (like \"0.0\")\n if (typeof answer === 'string' && !isNaN(parseFloat(answer))) {\n const numValue = parseFloat(answer)\n // Check if this looks like a currency (has decimal point or question type is Currency)\n if (question.inputQuestionFormat.type === 'Currency') {\n return formatCurrency(numValue)\n }\n // For non-currency numeric strings, return as-is\n return answer\n }\n\n // For boolean values\n if (typeof answer === 'boolean') {\n return answer ? t('common.yes') : t('common.no')\n }\n\n // Default: return string value as-is\n return answer\n }\n\n return (\n <Flex flexDirection=\"column\" gap={24}>\n <Components.Box\n header={\n <Components.BoxHeader\n title={t('taxes.federal.title')}\n action={\n <Components.Button\n variant=\"secondary\"\n onClick={onEditFederalTaxes}\n isDisabled={isFederalTaxesLoading}\n >\n {t('taxes.federal.editCta')}\n </Components.Button>\n }\n />\n }\n >\n <Flex flexDirection=\"column\" gap={16}>\n {isFederalTaxesLoading ? (\n <Loading />\n ) : federalTaxes ? (\n <Flex flexDirection=\"column\" gap={12}>\n {federalTaxes.filingStatus && (\n <Flex flexDirection=\"column\" gap={0}>\n <Components.Text variant=\"supporting\">\n {t('taxes.federal.filingStatus')}\n </Components.Text>\n <Components.Text>{federalTaxes.filingStatus}</Components.Text>\n </Flex>\n )}\n\n {'twoJobs' in federalTaxes && federalTaxes.twoJobs !== null && (\n <Flex flexDirection=\"column\" gap={0}>\n <Components.Text variant=\"supporting\">\n {t('taxes.federal.multipleJobs')}\n </Components.Text>\n <Components.Text>\n {federalTaxes.twoJobs ? t('common.yes') : t('common.no')}\n </Components.Text>\n </Flex>\n )}\n\n {'dependentsAmount' in federalTaxes && federalTaxes.dependentsAmount && (\n <Flex flexDirection=\"column\" gap={0}>\n <Components.Text variant=\"supporting\">\n {t('taxes.federal.dependentsAndOtherCredits')}\n </Components.Text>\n <Components.Text>\n {formatCurrency(parseFloat(federalTaxes.dependentsAmount))}\n </Components.Text>\n </Flex>\n )}\n\n {'otherIncome' in federalTaxes && federalTaxes.otherIncome && (\n <Flex flexDirection=\"column\" gap={0}>\n <Components.Text variant=\"supporting\">\n {t('taxes.federal.otherIncome')}\n </Components.Text>\n <Components.Text>\n {formatCurrency(parseFloat(federalTaxes.otherIncome))}\n </Components.Text>\n </Flex>\n )}\n\n {'deductions' in federalTaxes && federalTaxes.deductions && (\n <Flex flexDirection=\"column\" gap={0}>\n <Components.Text variant=\"supporting\">\n {t('taxes.federal.deductions')}\n </Components.Text>\n <Components.Text>\n {formatCurrency(parseFloat(federalTaxes.deductions))}\n </Components.Text>\n </Flex>\n )}\n\n {'extraWithholding' in federalTaxes && federalTaxes.extraWithholding && (\n <Flex flexDirection=\"column\" gap={0}>\n <Components.Text variant=\"supporting\">\n {t('taxes.federal.extraWithholding')}\n </Components.Text>\n <Components.Text>\n {formatCurrency(parseFloat(federalTaxes.extraWithholding))}\n </Components.Text>\n </Flex>\n )}\n </Flex>\n ) : null}\n </Flex>\n </Components.Box>\n\n <Components.Box\n header={\n <Components.BoxHeader\n title={t('taxes.state.title')}\n action={\n <Components.Button\n variant=\"secondary\"\n onClick={onEditStateTaxes}\n isDisabled={isStateTaxesLoading}\n >\n {t('taxes.state.editCta')}\n </Components.Button>\n }\n />\n }\n >\n <Flex flexDirection=\"column\" gap={16}>\n {isStateTaxesLoading ? (\n <Loading />\n ) : stateTaxes && stateTaxes.length > 0 ? (\n <Flex flexDirection=\"column\" gap={24}>\n {stateTaxes.map((stateTax, index) => (\n <Flex key={stateTax.state || index} flexDirection=\"column\" gap={16}>\n <Components.Heading as=\"h4\">{stateTax.state}</Components.Heading>\n\n {stateTax.questions && stateTax.questions.length > 0 && (\n <Flex flexDirection=\"column\" gap={12}>\n {stateTax.questions.map((question, qIndex) => {\n const answer = question.answers[0]?.value\n if (answer === null || answer === undefined) return null\n\n return (\n <Flex key={question.key || qIndex} flexDirection=\"column\" gap={0}>\n <Components.Text variant=\"supporting\">{question.label}</Components.Text>\n <Components.Text>\n {formatStateTaxAnswer(question, answer)}\n </Components.Text>\n </Flex>\n )\n })}\n </Flex>\n )}\n </Flex>\n ))}\n </Flex>\n ) : (\n <Components.Text>{t('taxes.state.noStateTaxes')}</Components.Text>\n )}\n </Flex>\n </Components.Box>\n </Flex>\n )\n}\n"],"names":["TaxesViewWithData","employeeId","onEditFederalTaxes","onEditStateTaxes","taxes","useEmployeeTaxes","federalTaxes","jsx","BaseLayout","TaxesView","stateTaxes","isLoading","isFederalTaxesLoading","isStateTaxesLoading","t","useTranslation","Components","useComponentContext","formatCurrency","useNumberFormatter","formatStateTaxAnswer","question","answer","option","opt","numValue","jsxs","Flex","Loading","stateTax","index","qIndex"],"mappings":";;;;;;;;;;AA4CO,SAASA,EAAkB;AAAA,EAChC,YAAAC;AAAA,EACA,oBAAAC;AAAA,EACA,kBAAAC;AACF,GAA2B;AACzB,QAAMC,IAAQC,EAAiB,EAAE,YAAAJ,GAAY,GAEvCK,IAAeF,EAAM,KAAK;AAChC,SACE,gBAAAG,EAACC,GAAA,EAAW,OAAOJ,EAAM,cAAc,QACrC,UAAA,gBAAAG;AAAA,IAACE;AAAA,IAAA;AAAA,MACC,cAAAH;AAAA,MACA,YAAYF,EAAM,KAAK;AAAA,MACvB,uBAAuBA,EAAM,OAAO;AAAA,MACpC,qBAAqBA,EAAM,OAAO;AAAA,MAClC,oBAAoB,MAAMF,IAAqBI,CAAY;AAAA,MAC3D,kBAAAH;AAAA,IAAA;AAAA,EAAA,GAEJ;AAEJ;AAEO,SAASM,EAAU;AAAA,EACxB,cAAAH;AAAA,EACA,YAAAI;AAAA,EACA,WAAAC,IAAY;AAAA,EACZ,uBAAAC,IAAwBD;AAAA,EACxB,qBAAAE,IAAsBF;AAAA,EACtB,oBAAAT;AAAA,EACA,kBAAAC;AACF,GAAmB;AACjB,QAAM,EAAE,GAAAW,EAAA,IAAMC,EAAe,oBAAoB,GAC3CC,IAAaC,EAAA,GACbC,IAAiBC,EAAmB,UAAU,GAG9CC,IAAuB,CAC3BC,GACAC,MACG;AAEH,QACED,EAAS,oBAAoB,SAAS,YACtCA,EAAS,oBAAoB,WAC7BA,EAAS,oBAAoB,QAAQ,SAAS,GAC9C;AACA,YAAME,IAASF,EAAS,oBAAoB,QAAQ,KAAK,CAAAG,MAAOA,EAAI,UAAUF,CAAM;AACpF,UAAIC,GAAQ;AACV,eAAOA,EAAO;AAAA,IAElB;AAGA,QAAI,OAAOD,KAAW;AACpB,aAAID,EAAS,oBAAoB,SAAS,aACjCH,EAAeI,CAAM,IAEvBA;AAIT,QAAI,OAAOA,KAAW,YAAY,CAAC,MAAM,WAAWA,CAAM,CAAC,GAAG;AAC5D,YAAMG,IAAW,WAAWH,CAAM;AAElC,aAAID,EAAS,oBAAoB,SAAS,aACjCH,EAAeO,CAAQ,IAGzBH;AAAA,IACT;AAGA,WAAI,OAAOA,KAAW,YACJR,EAATQ,IAAW,eAAkB,WAAN,IAIzBA;AAAA,EACT;AAEA,SACE,gBAAAI,EAACC,GAAA,EAAK,eAAc,UAAS,KAAK,IAChC,UAAA;AAAA,IAAA,gBAAApB;AAAA,MAACS,EAAW;AAAA,MAAX;AAAA,QACC,QACE,gBAAAT;AAAA,UAACS,EAAW;AAAA,UAAX;AAAA,YACC,OAAOF,EAAE,qBAAqB;AAAA,YAC9B,QACE,gBAAAP;AAAA,cAACS,EAAW;AAAA,cAAX;AAAA,gBACC,SAAQ;AAAA,gBACR,SAASd;AAAA,gBACT,YAAYU;AAAA,gBAEX,YAAE,uBAAuB;AAAA,cAAA;AAAA,YAAA;AAAA,UAC5B;AAAA,QAAA;AAAA,QAKN,4BAACe,GAAA,EAAK,eAAc,UAAS,KAAK,IAC/B,UAAAf,IACC,gBAAAL,EAACqB,GAAA,EAAQ,IACPtB,IACF,gBAAAoB,EAACC,GAAA,EAAK,eAAc,UAAS,KAAK,IAC/B,UAAA;AAAA,UAAArB,EAAa,gBACZ,gBAAAoB,EAACC,GAAA,EAAK,eAAc,UAAS,KAAK,GAChC,UAAA;AAAA,YAAA,gBAAApB,EAACS,EAAW,MAAX,EAAgB,SAAQ,cACtB,UAAAF,EAAE,4BAA4B,GACjC;AAAA,YACA,gBAAAP,EAACS,EAAW,MAAX,EAAiB,YAAa,aAAA,CAAa;AAAA,UAAA,GAC9C;AAAA,UAGD,aAAaV,KAAgBA,EAAa,YAAY,0BACpDqB,GAAA,EAAK,eAAc,UAAS,KAAK,GAChC,UAAA;AAAA,YAAA,gBAAApB,EAACS,EAAW,MAAX,EAAgB,SAAQ,cACtB,UAAAF,EAAE,4BAA4B,GACjC;AAAA,YACA,gBAAAP,EAACS,EAAW,MAAX,EACE,UAAAV,EAAa,UAAUQ,EAAE,YAAY,IAAIA,EAAE,WAAW,EAAA,CACzD;AAAA,UAAA,GACF;AAAA,UAGD,sBAAsBR,KAAgBA,EAAa,sCACjDqB,GAAA,EAAK,eAAc,UAAS,KAAK,GAChC,UAAA;AAAA,YAAA,gBAAApB,EAACS,EAAW,MAAX,EAAgB,SAAQ,cACtB,UAAAF,EAAE,yCAAyC,GAC9C;AAAA,YACA,gBAAAP,EAACS,EAAW,MAAX,EACE,YAAe,WAAWV,EAAa,gBAAgB,CAAC,EAAA,CAC3D;AAAA,UAAA,GACF;AAAA,UAGD,iBAAiBA,KAAgBA,EAAa,iCAC5CqB,GAAA,EAAK,eAAc,UAAS,KAAK,GAChC,UAAA;AAAA,YAAA,gBAAApB,EAACS,EAAW,MAAX,EAAgB,SAAQ,cACtB,UAAAF,EAAE,2BAA2B,GAChC;AAAA,YACA,gBAAAP,EAACS,EAAW,MAAX,EACE,YAAe,WAAWV,EAAa,WAAW,CAAC,EAAA,CACtD;AAAA,UAAA,GACF;AAAA,UAGD,gBAAgBA,KAAgBA,EAAa,gCAC3CqB,GAAA,EAAK,eAAc,UAAS,KAAK,GAChC,UAAA;AAAA,YAAA,gBAAApB,EAACS,EAAW,MAAX,EAAgB,SAAQ,cACtB,UAAAF,EAAE,0BAA0B,GAC/B;AAAA,YACA,gBAAAP,EAACS,EAAW,MAAX,EACE,YAAe,WAAWV,EAAa,UAAU,CAAC,EAAA,CACrD;AAAA,UAAA,GACF;AAAA,UAGD,sBAAsBA,KAAgBA,EAAa,sCACjDqB,GAAA,EAAK,eAAc,UAAS,KAAK,GAChC,UAAA;AAAA,YAAA,gBAAApB,EAACS,EAAW,MAAX,EAAgB,SAAQ,cACtB,UAAAF,EAAE,gCAAgC,GACrC;AAAA,YACA,gBAAAP,EAACS,EAAW,MAAX,EACE,YAAe,WAAWV,EAAa,gBAAgB,CAAC,EAAA,CAC3D;AAAA,UAAA,EAAA,CACF;AAAA,QAAA,EAAA,CAEJ,IACE,KAAA,CACN;AAAA,MAAA;AAAA,IAAA;AAAA,IAGF,gBAAAC;AAAA,MAACS,EAAW;AAAA,MAAX;AAAA,QACC,QACE,gBAAAT;AAAA,UAACS,EAAW;AAAA,UAAX;AAAA,YACC,OAAOF,EAAE,mBAAmB;AAAA,YAC5B,QACE,gBAAAP;AAAA,cAACS,EAAW;AAAA,cAAX;AAAA,gBACC,SAAQ;AAAA,gBACR,SAASb;AAAA,gBACT,YAAYU;AAAA,gBAEX,YAAE,qBAAqB;AAAA,cAAA;AAAA,YAAA;AAAA,UAC1B;AAAA,QAAA;AAAA,QAKN,UAAA,gBAAAN,EAACoB,GAAA,EAAK,eAAc,UAAS,KAAK,IAC/B,UAAAd,IACC,gBAAAN,EAACqB,GAAA,EAAQ,IACPlB,KAAcA,EAAW,SAAS,IACpC,gBAAAH,EAACoB,GAAA,EAAK,eAAc,UAAS,KAAK,IAC/B,UAAAjB,EAAW,IAAI,CAACmB,GAAUC,MACzB,gBAAAJ,EAACC,GAAA,EAAmC,eAAc,UAAS,KAAK,IAC9D,UAAA;AAAA,UAAA,gBAAApB,EAACS,EAAW,SAAX,EAAmB,IAAG,MAAM,YAAS,OAAM;AAAA,UAE3Ca,EAAS,aAAaA,EAAS,UAAU,SAAS,KACjD,gBAAAtB,EAACoB,GAAA,EAAK,eAAc,UAAS,KAAK,IAC/B,UAAAE,EAAS,UAAU,IAAI,CAACR,GAAUU,MAAW;AAC5C,kBAAMT,IAASD,EAAS,QAAQ,CAAC,GAAG;AACpC,mBAAIC,KAAW,OAAqC,OAGlD,gBAAAI,EAACC,GAAA,EAAkC,eAAc,UAAS,KAAK,GAC7D,UAAA;AAAA,cAAA,gBAAApB,EAACS,EAAW,MAAX,EAAgB,SAAQ,cAAc,YAAS,OAAM;AAAA,gCACrDA,EAAW,MAAX,EACE,UAAAI,EAAqBC,GAAUC,CAAM,EAAA,CACxC;AAAA,YAAA,KAJSD,EAAS,OAAOU,CAK3B;AAAA,UAEJ,CAAC,EAAA,CACH;AAAA,QAAA,EAAA,GAlBOF,EAAS,SAASC,CAoB7B,CACD,EAAA,CACH,IAEA,gBAAAvB,EAACS,EAAW,MAAX,EAAiB,UAAAF,EAAE,0BAA0B,GAAE,EAAA,CAEpD;AAAA,MAAA;AAAA,IAAA;AAAA,EACF,GACF;AAEJ;"}
1
+ {"version":3,"file":"TaxesView.js","sources":["../../../../src/components/Employee/Dashboard/TaxesView.tsx"],"sourcesContent":["import { useTranslation } from 'react-i18next'\nimport type { GetV1EmployeesEmployeeIdFederalTaxesResponse } from '@gusto/embedded-api/models/operations/getv1employeesemployeeidfederaltaxes'\nimport type { GetV1EmployeesEmployeeIdStateTaxesResponse } from '@gusto/embedded-api/models/operations/getv1employeesemployeeidstatetaxes'\nimport type { EmployeeStateTaxQuestion } from '@gusto/embedded-api/models/components/employeestatetaxquestion'\nimport { useEmployeeTaxes } from './hooks'\nimport { Flex } from '@/components/Common/Flex/Flex'\nimport { useComponentContext } from '@/contexts/ComponentAdapter/useComponentContext'\nimport { Loading } from '@/components/Common'\nimport { BaseLayout } from '@/components/Base/Base'\nimport useNumberFormatter from '@/hooks/useNumberFormatter'\n\ntype EmployeeFederalTax = NonNullable<\n GetV1EmployeesEmployeeIdFederalTaxesResponse['employeeFederalTax']\n>\ntype EmployeeStateTax = NonNullable<\n GetV1EmployeesEmployeeIdStateTaxesResponse['employeeStateTaxesList']\n>[number]\n\nexport interface TaxesViewProps {\n federalTaxes?: EmployeeFederalTax\n stateTaxes?: EmployeeStateTax[]\n /** Loads both cards. Override per-card via `isFederalTaxesLoading` /\n * `isStateTaxesLoading` when the queries resolve independently. */\n isLoading?: boolean\n isFederalTaxesLoading?: boolean\n isStateTaxesLoading?: boolean\n onEditFederalTaxes?: () => void\n onEditStateTaxes?: () => void\n}\n\nexport interface TaxesViewWithDataProps {\n employeeId: string\n /** Receives the federal-tax record so the parent can preserve the\n * existing event payload (`{ employeeId, federalTaxes }`). */\n onEditFederalTaxes?: (federalTaxes: EmployeeFederalTax | undefined) => void\n onEditStateTaxes?: () => void\n}\n\n/**\n * Tab-mounted container for the Taxes tab. Owns the `useEmployeeTaxes`\n * fetch so federal/state tax requests only fire when the tab is mounted.\n * Federal and state queries run independently — each card paints its\n * own skeleton + content as data arrives.\n */\nexport function TaxesViewWithData({\n employeeId,\n onEditFederalTaxes,\n onEditStateTaxes,\n}: TaxesViewWithDataProps) {\n const taxes = useEmployeeTaxes({ employeeId })\n\n const federalTaxes = taxes.data.employeeFederalTax\n return (\n <BaseLayout error={taxes.errorHandling.errors}>\n <TaxesView\n federalTaxes={federalTaxes}\n stateTaxes={taxes.data.employeeStateTaxesList}\n isFederalTaxesLoading={taxes.status.isFederalTaxesLoading}\n isStateTaxesLoading={taxes.status.isStateTaxesLoading}\n onEditFederalTaxes={() => onEditFederalTaxes?.(federalTaxes)}\n onEditStateTaxes={onEditStateTaxes}\n />\n </BaseLayout>\n )\n}\n\nexport function TaxesView({\n federalTaxes,\n stateTaxes,\n isLoading = false,\n isFederalTaxesLoading = isLoading,\n isStateTaxesLoading = isLoading,\n onEditFederalTaxes,\n onEditStateTaxes,\n}: TaxesViewProps) {\n const { t } = useTranslation('Employee.Dashboard')\n const { t: tCommon } = useTranslation('common')\n const Components = useComponentContext()\n const formatCurrency = useNumberFormatter('currency')\n\n const stateTaxesHaveAnyQuestions = !!stateTaxes?.some(s => (s.questions?.length ?? 0) > 0)\n\n // Helper function to format state tax answer values\n const formatStateTaxAnswer = (\n question: EmployeeStateTaxQuestion,\n answer: string | number | boolean,\n ) => {\n // For Select type questions, look up the label from options\n if (\n question.inputQuestionFormat.type === 'Select' &&\n question.inputQuestionFormat.options &&\n question.inputQuestionFormat.options.length > 0\n ) {\n const option = question.inputQuestionFormat.options.find(opt => opt.value === answer)\n if (option?.label) {\n return option.label\n }\n }\n\n // For numeric values, only format as currency for Currency questions\n if (typeof answer === 'number') {\n if (question.inputQuestionFormat.type === 'Currency') {\n return formatCurrency(answer)\n }\n return answer\n }\n\n // For string currency values (like \"0.0\")\n if (typeof answer === 'string' && !isNaN(parseFloat(answer))) {\n const numValue = parseFloat(answer)\n // Check if this looks like a currency (has decimal point or question type is Currency)\n if (question.inputQuestionFormat.type === 'Currency') {\n return formatCurrency(numValue)\n }\n // For non-currency numeric strings, return as-is\n return answer\n }\n\n // For boolean values\n if (typeof answer === 'boolean') {\n return answer ? t('common.yes') : t('common.no')\n }\n\n // Default: return string value as-is\n return answer\n }\n\n const emptyPlaceholder = <span aria-label={t('listEmptyPlaceholder')}>–</span>\n\n return (\n <Flex flexDirection=\"column\" gap={24}>\n <Components.Box\n header={\n <Components.BoxHeader\n title={t('taxes.federal.title')}\n action={\n <Components.Button\n variant=\"secondary\"\n onClick={onEditFederalTaxes}\n isDisabled={isFederalTaxesLoading}\n >\n {t('taxes.federal.editCta')}\n </Components.Button>\n }\n />\n }\n >\n <Flex flexDirection=\"column\" gap={16}>\n {isFederalTaxesLoading ? (\n <Loading />\n ) : federalTaxes ? (\n <Components.DescriptionList\n items={[\n {\n term: t('taxes.federal.filingStatus'),\n description: federalTaxes.filingStatus || emptyPlaceholder,\n },\n {\n term: t('taxes.federal.multipleJobs'),\n description:\n 'twoJobs' in federalTaxes && federalTaxes.twoJobs !== null\n ? federalTaxes.twoJobs\n ? t('common.yes')\n : t('common.no')\n : emptyPlaceholder,\n },\n {\n term: t('taxes.federal.dependentsAndOtherCredits'),\n description:\n 'dependentsAmount' in federalTaxes && federalTaxes.dependentsAmount\n ? formatCurrency(parseFloat(federalTaxes.dependentsAmount))\n : emptyPlaceholder,\n },\n {\n term: t('taxes.federal.otherIncome'),\n description:\n 'otherIncome' in federalTaxes && federalTaxes.otherIncome\n ? formatCurrency(parseFloat(federalTaxes.otherIncome))\n : emptyPlaceholder,\n },\n {\n term: t('taxes.federal.deductions'),\n description:\n 'deductions' in federalTaxes && federalTaxes.deductions\n ? formatCurrency(parseFloat(federalTaxes.deductions))\n : emptyPlaceholder,\n },\n {\n term: t('taxes.federal.extraWithholding'),\n description:\n 'extraWithholding' in federalTaxes && federalTaxes.extraWithholding\n ? formatCurrency(parseFloat(federalTaxes.extraWithholding))\n : emptyPlaceholder,\n },\n ]}\n />\n ) : null}\n </Flex>\n </Components.Box>\n\n <Components.Box\n header={\n <Components.BoxHeader\n title={t('taxes.state.title')}\n action={\n isStateTaxesLoading || stateTaxesHaveAnyQuestions ? (\n <Components.Button\n variant=\"secondary\"\n onClick={onEditStateTaxes}\n isDisabled={isStateTaxesLoading}\n >\n {t('taxes.state.editCta')}\n </Components.Button>\n ) : undefined\n }\n />\n }\n >\n <Flex flexDirection=\"column\" gap={16}>\n {isStateTaxesLoading ? (\n <Loading />\n ) : stateTaxes && stateTaxes.length > 0 ? (\n <Flex flexDirection=\"column\" gap={24}>\n {stateTaxes.map((stateTax, index) => {\n const stateName = stateTax.state\n ? tCommon(`statesHash.${stateTax.state}`, stateTax.state)\n : ''\n const hasQuestions = (stateTax.questions?.length ?? 0) > 0\n return (\n <Flex key={stateTax.state || index} flexDirection=\"column\" gap={16}>\n {stateName ? (\n <Components.Heading as=\"h4\">{stateName}</Components.Heading>\n ) : null}\n\n {hasQuestions ? (\n <Components.DescriptionList\n items={stateTax.questions!.map(question => {\n const answer = question.answers[0]?.value\n return {\n term: question.label,\n description:\n answer === null || answer === undefined\n ? emptyPlaceholder\n : formatStateTaxAnswer(question, answer),\n }\n })}\n />\n ) : (\n <Components.Text variant=\"supporting\">\n {t('taxes.state.noWithholdingForState')}\n </Components.Text>\n )}\n </Flex>\n )\n })}\n </Flex>\n ) : (\n <Components.Text>{t('taxes.state.noStateTaxes')}</Components.Text>\n )}\n </Flex>\n </Components.Box>\n </Flex>\n )\n}\n"],"names":["TaxesViewWithData","employeeId","onEditFederalTaxes","onEditStateTaxes","taxes","useEmployeeTaxes","federalTaxes","jsx","BaseLayout","TaxesView","stateTaxes","isLoading","isFederalTaxesLoading","isStateTaxesLoading","t","useTranslation","tCommon","Components","useComponentContext","formatCurrency","useNumberFormatter","stateTaxesHaveAnyQuestions","s","formatStateTaxAnswer","question","answer","option","opt","numValue","emptyPlaceholder","jsxs","Flex","Loading","stateTax","index","stateName","hasQuestions"],"mappings":"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"}
@@ -1,58 +1,58 @@
1
- import { normalizeToDate as w } from "../../../helpers/dateFormatting.js";
2
- const D = (t) => new Date(t.getFullYear(), t.getMonth(), t.getDate()), C = (t, e) => {
1
+ import { normalizeToDate as h } from "../../../helpers/dateFormatting.js";
2
+ const g = (t) => new Date(t.getFullYear(), t.getMonth(), t.getDate()), w = (t, e) => {
3
3
  if (!t) return !1;
4
- const n = w(t);
5
- return n ? D(n) > e : !1;
4
+ const n = h(t);
5
+ return n ? g(n) > e : !1;
6
6
  }, b = (t, e) => {
7
7
  if (!t) return !1;
8
- const n = w(t);
9
- return n ? D(n) <= e : !1;
10
- }, g = (t) => {
8
+ const n = h(t);
9
+ return n ? g(n) <= e : !1;
10
+ }, p = (t) => {
11
11
  if (t === void 0 || t === "") return null;
12
12
  const e = Number(t);
13
13
  return Number.isFinite(e) ? e : null;
14
14
  };
15
- function y(t, e, n) {
16
- const a = [], c = t.title ?? n, i = e.title ?? n;
17
- i && c !== i && a.push({ kind: "titleChange", title: i });
18
- const l = g(t.rate), o = g(e.rate), d = t.paymentUnit, f = e.paymentUnit;
19
- (o !== null && o !== l || f !== void 0 && f !== d) && o !== null && f && a.push({ kind: "payChange", rate: o, paymentUnit: f }), e.flsaStatus && e.flsaStatus !== t.flsaStatus && a.push({ kind: "flsaChange", flsaStatus: e.flsaStatus });
20
- const u = t.adjustForMinimumWage ?? !1, m = e.adjustForMinimumWage ?? !1, h = t.minimumWages?.[0], p = e.minimumWages?.[0];
21
- return !u && m ? a.push({ kind: "minWageEnabled", wage: p?.wage ?? null }) : u && !m ? a.push({ kind: "minWageDisabled" }) : u && m && (h?.uuid !== p?.uuid || h?.wage !== p?.wage) && a.push({ kind: "minWageChanged", wage: p?.wage ?? null }), a;
15
+ function y(t, e) {
16
+ const n = [], d = t.title ?? null, u = e.title ?? null;
17
+ u && d !== u && n.push({ kind: "titleChange", title: u });
18
+ const o = p(t.rate), a = p(e.rate), r = t.paymentUnit, l = e.paymentUnit;
19
+ (a !== null && a !== o || l !== void 0 && l !== r) && a !== null && l && n.push({ kind: "payChange", rate: a, paymentUnit: l }), e.flsaStatus && e.flsaStatus !== t.flsaStatus && n.push({ kind: "flsaChange", flsaStatus: e.flsaStatus });
20
+ const i = t.adjustForMinimumWage ?? !1, s = e.adjustForMinimumWage ?? !1, f = t.minimumWages?.[0], c = e.minimumWages?.[0];
21
+ return !i && s ? n.push({ kind: "minWageEnabled", wage: c?.wage ?? null }) : i && !s ? n.push({ kind: "minWageDisabled" }) : i && s && (f?.uuid !== c?.uuid || f?.wage !== c?.wage) && n.push({ kind: "minWageChanged", wage: c?.wage ?? null }), n;
22
22
  }
23
- function U(t, e) {
24
- const n = g(t.rate);
23
+ function C(t) {
24
+ const e = p(t.rate);
25
25
  return [
26
26
  {
27
27
  kind: "newJob",
28
- title: t.title ?? e,
29
- rate: n,
30
- paymentUnit: n !== null && t.paymentUnit ? t.paymentUnit : null
28
+ title: t.title ?? null,
29
+ rate: e,
30
+ paymentUnit: e !== null && t.paymentUnit ? t.paymentUnit : null
31
31
  }
32
32
  ];
33
33
  }
34
- function k(t, e = {}) {
34
+ function v(t, e = {}) {
35
35
  if (!t?.length) return [];
36
- const n = e.today ?? /* @__PURE__ */ new Date(), a = D(n), c = [];
37
- for (const i of t) {
38
- const l = i.compensations ?? [], o = l.filter((s) => C(s.effectiveDate, a)).slice().sort((s, r) => (s.effectiveDate ?? "").localeCompare(r.effectiveDate ?? ""));
39
- if (o.length === 0) continue;
40
- const d = i.currentCompensationUuid ? l.find((s) => s.uuid === i.currentCompensationUuid) : void 0, f = d && b(d.effectiveDate, a) ? d : null;
41
- for (let s = 0; s < o.length; s++) {
42
- const r = o[s], u = s === 0 ? f : o[s - 1], m = u ? y(u, r, i.title) : U(r, i.title);
43
- c.push({
44
- compensationUuid: r.uuid,
45
- jobUuid: i.uuid,
46
- effectiveDate: r.effectiveDate,
47
- jobTitle: i.title,
48
- details: m,
49
- isNewJob: u === null
36
+ const n = e.today ?? /* @__PURE__ */ new Date(), d = g(n), u = [];
37
+ for (const o of t) {
38
+ const a = o.compensations ?? [], r = a.filter((i) => w(i.effectiveDate, d)).slice().sort((i, s) => (i.effectiveDate ?? "").localeCompare(s.effectiveDate ?? ""));
39
+ if (r.length === 0) continue;
40
+ const l = o.currentCompensationUuid ? a.find((i) => i.uuid === o.currentCompensationUuid) : void 0, m = l && b(l.effectiveDate, d) ? l : null, D = m?.title ?? r[0]?.title ?? null;
41
+ for (let i = 0; i < r.length; i++) {
42
+ const s = r[i], f = i === 0 ? m : r[i - 1], c = f ? y(f, s) : C(s);
43
+ u.push({
44
+ compensationUuid: s.uuid,
45
+ jobUuid: o.uuid,
46
+ effectiveDate: s.effectiveDate,
47
+ jobTitle: D,
48
+ details: c,
49
+ isNewJob: f === null
50
50
  });
51
51
  }
52
52
  }
53
- return c.sort((i, l) => i.effectiveDate.localeCompare(l.effectiveDate)), c;
53
+ return u.sort((o, a) => o.effectiveDate.localeCompare(a.effectiveDate)), u;
54
54
  }
55
55
  export {
56
- k as getPendingCompensationChanges
56
+ v as getPendingCompensationChanges
57
57
  };
58
58
  //# sourceMappingURL=getPendingCompensationChanges.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"getPendingCompensationChanges.js","sources":["../../../../src/components/Employee/Dashboard/getPendingCompensationChanges.ts"],"sourcesContent":["import type { Compensation } from '@gusto/embedded-api/models/components/compensation'\nimport type { FlsaStatusType } from '@gusto/embedded-api/models/components/flsastatustype'\nimport type { Job } from '@gusto/embedded-api/models/components/job'\nimport { normalizeToDate } from '@/helpers/dateFormatting'\n\nexport type PendingChangeDetail =\n | { kind: 'titleChange'; title: string }\n | { kind: 'payChange'; rate: number; paymentUnit: string }\n | { kind: 'flsaChange'; flsaStatus: FlsaStatusType }\n | { kind: 'minWageEnabled'; wage: string | null }\n | { kind: 'minWageDisabled' }\n | { kind: 'minWageChanged'; wage: string | null }\n | {\n kind: 'newJob'\n title: string | null\n rate: number | null\n paymentUnit: string | null\n }\n\nexport interface PendingCompensationChange {\n compensationUuid: string\n jobUuid: string\n effectiveDate: string\n jobTitle: string | null\n details: PendingChangeDetail[]\n /**\n * True when the job has no current (on-or-before-today) compensation —\n * i.e., the job itself hasn't started yet. The UI renders a \"Pending\"\n * badge rather than a change alert in this case.\n */\n isNewJob: boolean\n}\n\nconst startOfLocalDay = (d: Date) => new Date(d.getFullYear(), d.getMonth(), d.getDate())\n\nconst isAfterToday = (effectiveDate: string | undefined, todayStart: Date): boolean => {\n if (!effectiveDate) return false\n const parsed = normalizeToDate(effectiveDate)\n if (!parsed) return false\n return startOfLocalDay(parsed) > todayStart\n}\n\nconst isOnOrBeforeToday = (effectiveDate: string | undefined, todayStart: Date): boolean => {\n if (!effectiveDate) return false\n const parsed = normalizeToDate(effectiveDate)\n if (!parsed) return false\n return startOfLocalDay(parsed) <= todayStart\n}\n\nconst numericRate = (rate: string | undefined): number | null => {\n if (rate === undefined || rate === '') return null\n const n = Number(rate)\n return Number.isFinite(n) ? n : null\n}\n\nfunction buildExistingJobDetails(\n baseline: Compensation,\n future: Compensation,\n jobTitle: string | null,\n): PendingChangeDetail[] {\n const details: PendingChangeDetail[] = []\n\n const baseTitle = baseline.title ?? jobTitle\n const futureTitle = future.title ?? jobTitle\n if (futureTitle && baseTitle !== futureTitle) {\n details.push({ kind: 'titleChange', title: futureTitle })\n }\n\n const baseRate = numericRate(baseline.rate)\n const futureRate = numericRate(future.rate)\n const baseUnit = baseline.paymentUnit\n const futureUnit = future.paymentUnit\n const rateDiffers = futureRate !== null && futureRate !== baseRate\n const unitDiffers = futureUnit !== undefined && futureUnit !== baseUnit\n if ((rateDiffers || unitDiffers) && futureRate !== null && futureUnit) {\n details.push({ kind: 'payChange', rate: futureRate, paymentUnit: futureUnit })\n }\n\n if (future.flsaStatus && future.flsaStatus !== baseline.flsaStatus) {\n details.push({ kind: 'flsaChange', flsaStatus: future.flsaStatus })\n }\n\n const baseAdj = baseline.adjustForMinimumWage ?? false\n const futureAdj = future.adjustForMinimumWage ?? false\n const baseMw = baseline.minimumWages?.[0]\n const futureMw = future.minimumWages?.[0]\n\n if (!baseAdj && futureAdj) {\n details.push({ kind: 'minWageEnabled', wage: futureMw?.wage ?? null })\n } else if (baseAdj && !futureAdj) {\n details.push({ kind: 'minWageDisabled' })\n } else if (baseAdj && futureAdj) {\n if (baseMw?.uuid !== futureMw?.uuid || baseMw?.wage !== futureMw?.wage) {\n details.push({ kind: 'minWageChanged', wage: futureMw?.wage ?? null })\n }\n }\n\n return details\n}\n\nfunction buildNewJobDetails(future: Compensation, jobTitle: string | null): PendingChangeDetail[] {\n const rate = numericRate(future.rate)\n return [\n {\n kind: 'newJob',\n title: future.title ?? jobTitle,\n rate,\n paymentUnit: rate !== null && future.paymentUnit ? future.paymentUnit : null,\n },\n ]\n}\n\n/**\n * Returns the pending compensation changes for an employee, flattened across\n * all jobs and sorted globally by `effectiveDate` ascending.\n *\n * A pending change is any `Compensation` whose `effectiveDate` is strictly\n * after today (local midnight). When a single job has multiple future-dated\n * compensations stacked, each is returned in chronological order and the diff\n * details for the N+1th comp are computed against the Nth (rather than the\n * job's current compensation) so the bullets remain meaningful end-to-end.\n *\n * The helper returns structured deltas (a discriminated union per detail) so\n * the consuming UI is responsible for formatting them via i18n / pay-rate\n * helpers. This keeps the helper pure and trivially unit-testable.\n */\nexport function getPendingCompensationChanges(\n jobs: Job[] | undefined,\n options: { today?: Date } = {},\n): PendingCompensationChange[] {\n if (!jobs?.length) return []\n\n const now = options.today ?? new Date()\n const todayStart = startOfLocalDay(now)\n const results: PendingCompensationChange[] = []\n\n for (const job of jobs) {\n const comps = job.compensations ?? []\n\n const futureComps = comps\n .filter(c => isAfterToday(c.effectiveDate, todayStart))\n .slice()\n .sort((a, b) => (a.effectiveDate ?? '').localeCompare(b.effectiveDate ?? ''))\n\n if (futureComps.length === 0) continue\n\n const referencedCurrent = job.currentCompensationUuid\n ? comps.find(c => c.uuid === job.currentCompensationUuid)\n : undefined\n const currentComp =\n referencedCurrent && isOnOrBeforeToday(referencedCurrent.effectiveDate, todayStart)\n ? referencedCurrent\n : null\n\n for (let i = 0; i < futureComps.length; i++) {\n const future = futureComps[i]!\n const baseline = i === 0 ? currentComp : futureComps[i - 1]!\n\n const details = baseline\n ? buildExistingJobDetails(baseline, future, job.title)\n : buildNewJobDetails(future, job.title)\n\n results.push({\n compensationUuid: future.uuid,\n jobUuid: job.uuid,\n effectiveDate: future.effectiveDate!,\n jobTitle: job.title,\n details,\n isNewJob: baseline === null,\n })\n }\n }\n\n results.sort((a, b) => a.effectiveDate.localeCompare(b.effectiveDate))\n\n return results\n}\n"],"names":["startOfLocalDay","d","isAfterToday","effectiveDate","todayStart","parsed","normalizeToDate","isOnOrBeforeToday","numericRate","rate","n","buildExistingJobDetails","baseline","future","jobTitle","details","baseTitle","futureTitle","baseRate","futureRate","baseUnit","futureUnit","baseAdj","futureAdj","baseMw","futureMw","buildNewJobDetails","getPendingCompensationChanges","jobs","options","now","results","job","comps","futureComps","c","a","b","referencedCurrent","currentComp","i"],"mappings":"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"}
1
+ {"version":3,"file":"getPendingCompensationChanges.js","sources":["../../../../src/components/Employee/Dashboard/getPendingCompensationChanges.ts"],"sourcesContent":["import type { Compensation } from '@gusto/embedded-api/models/components/compensation'\nimport type { FlsaStatusType } from '@gusto/embedded-api/models/components/flsastatustype'\nimport type { Job } from '@gusto/embedded-api/models/components/job'\nimport { normalizeToDate } from '@/helpers/dateFormatting'\n\nexport type PendingChangeDetail =\n | { kind: 'titleChange'; title: string }\n | { kind: 'payChange'; rate: number; paymentUnit: string }\n | { kind: 'flsaChange'; flsaStatus: FlsaStatusType }\n | { kind: 'minWageEnabled'; wage: string | null }\n | { kind: 'minWageDisabled' }\n | { kind: 'minWageChanged'; wage: string | null }\n | {\n kind: 'newJob'\n title: string | null\n rate: number | null\n paymentUnit: string | null\n }\n\nexport interface PendingCompensationChange {\n compensationUuid: string\n jobUuid: string\n effectiveDate: string\n jobTitle: string | null\n details: PendingChangeDetail[]\n /**\n * True when the job has no current (on-or-before-today) compensation —\n * i.e., the job itself hasn't started yet. The UI renders a \"Pending\"\n * badge rather than a change alert in this case.\n */\n isNewJob: boolean\n}\n\nconst startOfLocalDay = (d: Date) => new Date(d.getFullYear(), d.getMonth(), d.getDate())\n\nconst isAfterToday = (effectiveDate: string | undefined, todayStart: Date): boolean => {\n if (!effectiveDate) return false\n const parsed = normalizeToDate(effectiveDate)\n if (!parsed) return false\n return startOfLocalDay(parsed) > todayStart\n}\n\nconst isOnOrBeforeToday = (effectiveDate: string | undefined, todayStart: Date): boolean => {\n if (!effectiveDate) return false\n const parsed = normalizeToDate(effectiveDate)\n if (!parsed) return false\n return startOfLocalDay(parsed) <= todayStart\n}\n\nconst numericRate = (rate: string | undefined): number | null => {\n if (rate === undefined || rate === '') return null\n const n = Number(rate)\n return Number.isFinite(n) ? n : null\n}\n\nfunction buildExistingJobDetails(\n baseline: Compensation,\n future: Compensation,\n): PendingChangeDetail[] {\n const details: PendingChangeDetail[] = []\n\n // Title diffs come straight from `compensation.title` — that's where the\n // value lives in the API. A future comp that doesn't carry a title (e.g.\n // a pay-only change) leaves `future.title` undefined; the `futureTitle &&`\n // guard prevents that case from emitting a spurious title change.\n const baseTitle = baseline.title ?? null\n const futureTitle = future.title ?? null\n if (futureTitle && baseTitle !== futureTitle) {\n details.push({ kind: 'titleChange', title: futureTitle })\n }\n\n const baseRate = numericRate(baseline.rate)\n const futureRate = numericRate(future.rate)\n const baseUnit = baseline.paymentUnit\n const futureUnit = future.paymentUnit\n const rateDiffers = futureRate !== null && futureRate !== baseRate\n const unitDiffers = futureUnit !== undefined && futureUnit !== baseUnit\n if ((rateDiffers || unitDiffers) && futureRate !== null && futureUnit) {\n details.push({ kind: 'payChange', rate: futureRate, paymentUnit: futureUnit })\n }\n\n if (future.flsaStatus && future.flsaStatus !== baseline.flsaStatus) {\n details.push({ kind: 'flsaChange', flsaStatus: future.flsaStatus })\n }\n\n const baseAdj = baseline.adjustForMinimumWage ?? false\n const futureAdj = future.adjustForMinimumWage ?? false\n const baseMw = baseline.minimumWages?.[0]\n const futureMw = future.minimumWages?.[0]\n\n if (!baseAdj && futureAdj) {\n details.push({ kind: 'minWageEnabled', wage: futureMw?.wage ?? null })\n } else if (baseAdj && !futureAdj) {\n details.push({ kind: 'minWageDisabled' })\n } else if (baseAdj && futureAdj) {\n if (baseMw?.uuid !== futureMw?.uuid || baseMw?.wage !== futureMw?.wage) {\n details.push({ kind: 'minWageChanged', wage: futureMw?.wage ?? null })\n }\n }\n\n return details\n}\n\nfunction buildNewJobDetails(future: Compensation): PendingChangeDetail[] {\n const rate = numericRate(future.rate)\n return [\n {\n kind: 'newJob',\n title: future.title ?? null,\n rate,\n paymentUnit: rate !== null && future.paymentUnit ? future.paymentUnit : null,\n },\n ]\n}\n\n/**\n * Returns the pending compensation changes for an employee, flattened across\n * all jobs and sorted globally by `effectiveDate` ascending.\n *\n * A pending change is any `Compensation` whose `effectiveDate` is strictly\n * after today (local midnight). When a single job has multiple future-dated\n * compensations stacked, each is returned in chronological order and the diff\n * details for the N+1th comp are computed against the Nth (rather than the\n * job's current compensation) so the bullets remain meaningful end-to-end.\n *\n * The helper returns structured deltas (a discriminated union per detail) so\n * the consuming UI is responsible for formatting them via i18n / pay-rate\n * helpers. This keeps the helper pure and trivially unit-testable.\n */\nexport function getPendingCompensationChanges(\n jobs: Job[] | undefined,\n options: { today?: Date } = {},\n): PendingCompensationChange[] {\n if (!jobs?.length) return []\n\n const now = options.today ?? new Date()\n const todayStart = startOfLocalDay(now)\n const results: PendingCompensationChange[] = []\n\n for (const job of jobs) {\n const comps = job.compensations ?? []\n\n const futureComps = comps\n .filter(c => isAfterToday(c.effectiveDate, todayStart))\n .slice()\n .sort((a, b) => (a.effectiveDate ?? '').localeCompare(b.effectiveDate ?? ''))\n\n if (futureComps.length === 0) continue\n\n const referencedCurrent = job.currentCompensationUuid\n ? comps.find(c => c.uuid === job.currentCompensationUuid)\n : undefined\n const currentComp =\n referencedCurrent && isOnOrBeforeToday(referencedCurrent.effectiveDate, todayStart)\n ? referencedCurrent\n : null\n\n // Title lives on compensation; `job.title` is a denormalized snapshot of\n // the primary comp's title and can lag behind comp-level edits on\n // secondaries (and on primaries until the server resyncs). For UI strings\n // that contextualize a change (\"Compensation for X will change on...\"),\n // use the title from the currently-in-effect comp; for a job that hasn't\n // started yet (`currentComp === null`), fall back to the first future\n // comp's title — that's the title the job is starting with.\n const displayTitle = currentComp?.title ?? futureComps[0]?.title ?? null\n\n for (let i = 0; i < futureComps.length; i++) {\n const future = futureComps[i]!\n const baseline = i === 0 ? currentComp : futureComps[i - 1]!\n\n const details = baseline\n ? buildExistingJobDetails(baseline, future)\n : buildNewJobDetails(future)\n\n results.push({\n compensationUuid: future.uuid,\n jobUuid: job.uuid,\n effectiveDate: future.effectiveDate!,\n jobTitle: displayTitle,\n details,\n isNewJob: baseline === null,\n })\n }\n }\n\n results.sort((a, b) => a.effectiveDate.localeCompare(b.effectiveDate))\n\n return results\n}\n"],"names":["startOfLocalDay","d","isAfterToday","effectiveDate","todayStart","parsed","normalizeToDate","isOnOrBeforeToday","numericRate","rate","n","buildExistingJobDetails","baseline","future","details","baseTitle","futureTitle","baseRate","futureRate","baseUnit","futureUnit","baseAdj","futureAdj","baseMw","futureMw","buildNewJobDetails","getPendingCompensationChanges","jobs","options","now","results","job","comps","futureComps","c","a","b","referencedCurrent","currentComp","displayTitle"],"mappings":"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"}
@@ -1,95 +1,95 @@
1
- import { jsx as n, jsxs as a } from "react/jsx-runtime";
1
+ import { jsx as n, jsxs as c } from "react/jsx-runtime";
2
2
  import { useTranslation as f } from "react-i18next";
3
3
  import { useWatch as A } from "react-hook-form";
4
- import { useDeductionForm as b } from "../shared/useDeductionForm/useDeductionForm.js";
5
- import { Form as D } from "../../../Common/Form/Form.js";
6
- import { Flex as u } from "../../../Common/Flex/Flex.js";
4
+ import { useDeductionForm as D } from "../shared/useDeductionForm/useDeductionForm.js";
5
+ import { Form as b } from "../../../Common/Form/Form.js";
6
+ import { Flex as m } from "../../../Common/Flex/Flex.js";
7
7
  import "classnames";
8
8
  import "../../../../shared/constants.js";
9
- import { ActionsLayout as y } from "../../../Common/ActionsLayout/ActionsLayout.js";
10
- import { BaseLayout as p } from "../../../Base/Base.js";
11
- import { SDKFormProvider as h } from "../../../../partner-hook-utils/form/SDKFormProvider.js";
9
+ import { ActionsLayout as h } from "../../../Common/ActionsLayout/ActionsLayout.js";
10
+ import { BaseLayout as g } from "../../../Base/Base.js";
11
+ import { SDKFormProvider as y } from "../../../../partner-hook-utils/form/SDKFormProvider.js";
12
12
  import { useComponentContext as R } from "../../../../contexts/ComponentAdapter/useComponentContext.js";
13
13
  function S({
14
- employeeId: r,
15
- deduction: i,
16
- courtOrdered: t,
14
+ employeeId: t,
15
+ deduction: o,
16
+ courtOrdered: r,
17
17
  garnishmentType: e,
18
- title: m,
19
- onSaved: d,
20
- onCancel: l
18
+ title: s,
19
+ onSaved: l,
20
+ onCancel: p
21
21
  }) {
22
- const { t: c } = f("Employee.Deductions"), s = R(), o = b({
23
- employeeId: r,
24
- garnishmentId: i?.uuid,
25
- courtOrdered: t,
26
- defaultValues: t && e ? { garnishmentType: e } : void 0
22
+ const { t: u } = f("Employee.Deductions"), d = R(), a = D({
23
+ employeeId: t,
24
+ garnishmentId: o?.uuid,
25
+ courtOrdered: r,
26
+ defaultValues: r && e ? { garnishmentType: e } : void 0
27
27
  });
28
- if (o.isLoading)
29
- return /* @__PURE__ */ n(p, { isLoading: !0, error: o.errorHandling.errors });
30
- const { Fields: g } = o.form;
28
+ if (a.isLoading)
29
+ return /* @__PURE__ */ n(g, { isLoading: !0, error: a.errorHandling.errors });
30
+ const { Fields: i } = a.form;
31
31
  return /* @__PURE__ */ n(
32
32
  x,
33
33
  {
34
- form: o,
35
- Fields: g,
36
- Components: s,
37
- t: c,
38
- title: m,
39
- onSaved: d,
40
- onCancel: l
34
+ form: a,
35
+ Fields: i,
36
+ Components: d,
37
+ t: u,
38
+ title: s,
39
+ onSaved: l,
40
+ onCancel: p
41
41
  }
42
42
  );
43
43
  }
44
44
  function x({
45
- form: r,
46
- Fields: i,
47
- Components: t,
45
+ form: t,
46
+ Fields: o,
47
+ Components: r,
48
48
  t: e,
49
- title: m,
50
- onSaved: d,
51
- onCancel: l
49
+ title: s,
50
+ onSaved: l,
51
+ onCancel: p
52
52
  }) {
53
- const c = A({
54
- control: r.form.hookFormInternals.formMethods.control,
53
+ const u = A({
54
+ control: t.form.hookFormInternals.formMethods.control,
55
55
  name: "deductAsPercentage"
56
- }), s = async () => {
57
- const o = await r.actions.onSubmit();
58
- o && d(o.data, o.mode);
56
+ }), d = u === !0 || u === "true", a = async () => {
57
+ const i = await t.actions.onSubmit();
58
+ i && l(i.data, i.mode);
59
59
  };
60
- return /* @__PURE__ */ n(p, { error: r.errorHandling.errors, children: /* @__PURE__ */ n(h, { formHookResult: r, children: /* @__PURE__ */ n(D, { onSubmit: s, children: /* @__PURE__ */ a(u, { flexDirection: "column", gap: 32, children: [
61
- /* @__PURE__ */ n(t.Heading, { as: "h3", children: m }),
62
- /* @__PURE__ */ a(u, { flexDirection: "column", gap: 20, children: [
63
- /* @__PURE__ */ a(u, { flexDirection: "column", gap: 20, children: [
60
+ return /* @__PURE__ */ n(g, { error: t.errorHandling.errors, children: /* @__PURE__ */ n(y, { formHookResult: t, children: /* @__PURE__ */ n(b, { onSubmit: a, children: /* @__PURE__ */ c(m, { flexDirection: "column", gap: 32, children: [
61
+ /* @__PURE__ */ n(r.Heading, { as: "h3", children: s }),
62
+ /* @__PURE__ */ c(m, { flexDirection: "column", gap: 20, children: [
63
+ /* @__PURE__ */ c(m, { flexDirection: "column", gap: 20, children: [
64
64
  /* @__PURE__ */ n(
65
- i.Description,
65
+ o.Description,
66
66
  {
67
67
  label: e("descriptionLabelV2"),
68
68
  validationMessages: { REQUIRED: e("descriptionRequired") }
69
69
  }
70
70
  ),
71
71
  /* @__PURE__ */ n(
72
- i.Recurring,
72
+ o.Recurring,
73
73
  {
74
74
  label: e("frequencyLabel"),
75
- getOptionLabel: (o) => e(o ? "frequencyRecurringOptionV2" : "frequencyOneTimeOptionV2"),
75
+ getOptionLabel: (i) => e(i ? "frequencyRecurringOptionV2" : "frequencyOneTimeOptionV2"),
76
76
  validationMessages: { REQUIRED: e("frequencyRequired") }
77
77
  }
78
78
  ),
79
79
  /* @__PURE__ */ n(
80
- i.DeductAsPercentage,
80
+ o.DeductAsPercentage,
81
81
  {
82
82
  label: e("deductionTypeLabelV2"),
83
- getOptionLabel: (o) => e(o ? "deductionTypePercentageOptionV2" : "deductionTypeFixedAmountOption"),
83
+ getOptionLabel: (i) => e(i ? "deductionTypePercentageOptionV2" : "deductionTypeFixedAmountOption"),
84
84
  validationMessages: { REQUIRED: e("deductionTypeRequired") }
85
85
  }
86
86
  ),
87
87
  /* @__PURE__ */ n(
88
- i.Amount,
88
+ o.Amount,
89
89
  {
90
90
  label: e("deductionAmountLabel"),
91
- format: c ? "percent" : "currency",
92
- description: e(c ? "deductionAmountDescriptionPercentage" : "deductionAmountDescriptionFixed"),
91
+ format: d ? "percent" : "currency",
92
+ description: e(d ? "deductionAmountDescriptionPercentage" : "deductionAmountDescriptionFixed"),
93
93
  min: 0,
94
94
  validationMessages: {
95
95
  REQUIRED: e("amountRequired"),
@@ -98,9 +98,9 @@ function x({
98
98
  }
99
99
  )
100
100
  ] }),
101
- i.TotalAmount && i.AnnualMaximum && /* @__PURE__ */ a(u, { flexDirection: "column", gap: 20, children: [
101
+ o.TotalAmount && o.AnnualMaximum && /* @__PURE__ */ c(m, { flexDirection: "column", gap: 20, children: [
102
102
  /* @__PURE__ */ n(
103
- i.TotalAmount,
103
+ o.TotalAmount,
104
104
  {
105
105
  label: e("totalAmountLabel"),
106
106
  description: e("totalAmountDescription"),
@@ -112,7 +112,7 @@ function x({
112
112
  }
113
113
  ),
114
114
  /* @__PURE__ */ n(
115
- i.AnnualMaximum,
115
+ o.AnnualMaximum,
116
116
  {
117
117
  label: e("annualMaxLabel"),
118
118
  description: e("annualMaxDescription"),
@@ -125,9 +125,9 @@ function x({
125
125
  )
126
126
  ] })
127
127
  ] }),
128
- /* @__PURE__ */ a(y, { children: [
129
- /* @__PURE__ */ n(t.Button, { variant: "secondary", type: "button", onClick: l, children: e("cancelCta") }),
130
- /* @__PURE__ */ n(t.Button, { type: "submit", isLoading: r.status.isPending, children: e("saveCta") })
128
+ /* @__PURE__ */ c(h, { children: [
129
+ /* @__PURE__ */ n(r.Button, { variant: "secondary", type: "button", onClick: p, children: e("cancelCta") }),
130
+ /* @__PURE__ */ n(r.Button, { type: "submit", isLoading: t.status.isPending, children: e("saveCta") })
131
131
  ] })
132
132
  ] }) }) }) });
133
133
  }
@@ -1 +1 @@
1
- {"version":3,"file":"StandardDeductionForm.js","sources":["../../../../../src/components/Employee/Deductions/DeductionsForm/StandardDeductionForm.tsx"],"sourcesContent":["import { useTranslation } from 'react-i18next'\nimport { useWatch } from 'react-hook-form'\nimport type {\n Garnishment,\n GarnishmentType,\n} from '@gusto/embedded-api/models/components/garnishment'\nimport type { Control } from 'react-hook-form'\nimport { useDeductionForm } from '../shared/useDeductionForm'\nimport type { DeductionFormData } from '../shared/useDeductionForm'\nimport { Form } from '@/components/Common/Form'\nimport { ActionsLayout } from '@/components/Common'\nimport { Flex } from '@/components/Common/Flex/Flex'\nimport { BaseLayout } from '@/components/Base/Base'\nimport { SDKFormProvider } from '@/partner-hook-utils/form/SDKFormProvider'\nimport { useComponentContext } from '@/contexts/ComponentAdapter/useComponentContext'\n\ninterface StandardDeductionFormProps {\n employeeId: string\n deduction: Garnishment | null\n /** Court-ordered garnishments require `garnishmentType`. Custom deductions don't. */\n courtOrdered: boolean\n /** Only meaningful when `courtOrdered: true`. Selects the garnishment type\n * on create. Ignored in edit mode (the existing type is preserved). */\n garnishmentType?: GarnishmentType\n /** Section heading shown above the form. The parent picker is responsible\n * for translating the garnishment-type label so this component doesn't\n * need to repeat the labels mapping. */\n title: string\n onSaved: (deduction: Garnishment, mode: 'create' | 'update') => void\n onCancel: () => void\n}\n\nexport function StandardDeductionForm({\n employeeId,\n deduction,\n courtOrdered,\n garnishmentType,\n title,\n onSaved,\n onCancel,\n}: StandardDeductionFormProps) {\n const { t } = useTranslation('Employee.Deductions')\n const Components = useComponentContext()\n\n const form = useDeductionForm({\n employeeId,\n garnishmentId: deduction?.uuid,\n courtOrdered,\n defaultValues: courtOrdered && garnishmentType ? { garnishmentType } : undefined,\n })\n\n if (form.isLoading) {\n return <BaseLayout isLoading error={form.errorHandling.errors} />\n }\n\n const { Fields } = form.form\n return (\n <ReadyForm\n form={form}\n Fields={Fields}\n Components={Components}\n t={t}\n title={title}\n onSaved={onSaved}\n onCancel={onCancel}\n />\n )\n}\n\n// Split into a child component so we can call `useWatch` on the form's control\n// only once the hook is in its ready state (the control reference exists then).\nfunction ReadyForm({\n form,\n Fields,\n Components,\n t,\n title,\n onSaved,\n onCancel,\n}: {\n form: Extract<ReturnType<typeof useDeductionForm>, { isLoading: false }>\n Fields: Extract<ReturnType<typeof useDeductionForm>, { isLoading: false }>['form']['Fields']\n Components: ReturnType<typeof useComponentContext>\n t: ReturnType<typeof useTranslation<'Employee.Deductions'>>['t']\n title: string\n onSaved: (deduction: Garnishment, mode: 'create' | 'update') => void\n onCancel: () => void\n}) {\n // useWatch subscribes to changes; getValues only reads once. We need the\n // subscription because `Fields.Amount`'s `format` and `description` props\n // need to re-render when the user toggles Percentage / Fixed amount.\n const watchedDeductAsPercentage = useWatch({\n control: form.form.hookFormInternals.formMethods.control as Control<DeductionFormData>,\n name: 'deductAsPercentage',\n })\n\n const handleSubmit = async () => {\n const result = await form.actions.onSubmit()\n if (result) onSaved(result.data, result.mode)\n }\n\n return (\n <BaseLayout error={form.errorHandling.errors}>\n <SDKFormProvider formHookResult={form}>\n <Form onSubmit={handleSubmit}>\n <Flex flexDirection=\"column\" gap={32}>\n <Components.Heading as=\"h3\">{title}</Components.Heading>\n <Flex flexDirection=\"column\" gap={20}>\n <Flex flexDirection=\"column\" gap={20}>\n <Fields.Description\n label={t('descriptionLabelV2')}\n validationMessages={{ REQUIRED: t('descriptionRequired') }}\n />\n <Fields.Recurring\n label={t('frequencyLabel')}\n getOptionLabel={(value: boolean) =>\n value ? t('frequencyRecurringOptionV2') : t('frequencyOneTimeOptionV2')\n }\n validationMessages={{ REQUIRED: t('frequencyRequired') }}\n />\n <Fields.DeductAsPercentage\n label={t('deductionTypeLabelV2')}\n getOptionLabel={(value: boolean) =>\n value\n ? t('deductionTypePercentageOptionV2')\n : t('deductionTypeFixedAmountOption')\n }\n validationMessages={{ REQUIRED: t('deductionTypeRequired') }}\n />\n <Fields.Amount\n label={t('deductionAmountLabel')}\n format={watchedDeductAsPercentage ? 'percent' : 'currency'}\n description={\n watchedDeductAsPercentage\n ? t('deductionAmountDescriptionPercentage')\n : t('deductionAmountDescriptionFixed')\n }\n min={0}\n validationMessages={{\n REQUIRED: t('amountRequired'),\n NEGATIVE_AMOUNT: t('amountNonNegative'),\n }}\n />\n </Flex>\n {Fields.TotalAmount && Fields.AnnualMaximum && (\n <Flex flexDirection=\"column\" gap={20}>\n <Fields.TotalAmount\n label={t('totalAmountLabel')}\n description={t('totalAmountDescription')}\n format=\"currency\"\n min={0}\n validationMessages={{\n NEGATIVE_AMOUNT: t('amountNonNegative'),\n }}\n />\n <Fields.AnnualMaximum\n label={t('annualMaxLabel')}\n description={t('annualMaxDescription')}\n format=\"currency\"\n min={0}\n validationMessages={{\n NEGATIVE_AMOUNT: t('amountNonNegative'),\n }}\n />\n </Flex>\n )}\n </Flex>\n <ActionsLayout>\n <Components.Button variant=\"secondary\" type=\"button\" onClick={onCancel}>\n {t('cancelCta')}\n </Components.Button>\n <Components.Button type=\"submit\" isLoading={form.status.isPending}>\n {t('saveCta')}\n </Components.Button>\n </ActionsLayout>\n </Flex>\n </Form>\n </SDKFormProvider>\n </BaseLayout>\n )\n}\n"],"names":["StandardDeductionForm","employeeId","deduction","courtOrdered","garnishmentType","title","onSaved","onCancel","t","useTranslation","Components","useComponentContext","form","useDeductionForm","BaseLayout","Fields","jsx","ReadyForm","watchedDeductAsPercentage","useWatch","handleSubmit","result","SDKFormProvider","Form","jsxs","Flex","value","ActionsLayout"],"mappings":"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"}
1
+ {"version":3,"file":"StandardDeductionForm.js","sources":["../../../../../src/components/Employee/Deductions/DeductionsForm/StandardDeductionForm.tsx"],"sourcesContent":["import { useTranslation } from 'react-i18next'\nimport { useWatch } from 'react-hook-form'\nimport type {\n Garnishment,\n GarnishmentType,\n} from '@gusto/embedded-api/models/components/garnishment'\nimport type { Control } from 'react-hook-form'\nimport { useDeductionForm } from '../shared/useDeductionForm'\nimport type { DeductionFormData } from '../shared/useDeductionForm'\nimport { Form } from '@/components/Common/Form'\nimport { ActionsLayout } from '@/components/Common'\nimport { Flex } from '@/components/Common/Flex/Flex'\nimport { BaseLayout } from '@/components/Base/Base'\nimport { SDKFormProvider } from '@/partner-hook-utils/form/SDKFormProvider'\nimport { useComponentContext } from '@/contexts/ComponentAdapter/useComponentContext'\n\ninterface StandardDeductionFormProps {\n employeeId: string\n deduction: Garnishment | null\n /** Court-ordered garnishments require `garnishmentType`. Custom deductions don't. */\n courtOrdered: boolean\n /** Only meaningful when `courtOrdered: true`. Selects the garnishment type\n * on create. Ignored in edit mode (the existing type is preserved). */\n garnishmentType?: GarnishmentType\n /** Section heading shown above the form. The parent picker is responsible\n * for translating the garnishment-type label so this component doesn't\n * need to repeat the labels mapping. */\n title: string\n onSaved: (deduction: Garnishment, mode: 'create' | 'update') => void\n onCancel: () => void\n}\n\nexport function StandardDeductionForm({\n employeeId,\n deduction,\n courtOrdered,\n garnishmentType,\n title,\n onSaved,\n onCancel,\n}: StandardDeductionFormProps) {\n const { t } = useTranslation('Employee.Deductions')\n const Components = useComponentContext()\n\n const form = useDeductionForm({\n employeeId,\n garnishmentId: deduction?.uuid,\n courtOrdered,\n defaultValues: courtOrdered && garnishmentType ? { garnishmentType } : undefined,\n })\n\n if (form.isLoading) {\n return <BaseLayout isLoading error={form.errorHandling.errors} />\n }\n\n const { Fields } = form.form\n return (\n <ReadyForm\n form={form}\n Fields={Fields}\n Components={Components}\n t={t}\n title={title}\n onSaved={onSaved}\n onCancel={onCancel}\n />\n )\n}\n\n// Split into a child component so we can call `useWatch` on the form's control\n// only once the hook is in its ready state (the control reference exists then).\nfunction ReadyForm({\n form,\n Fields,\n Components,\n t,\n title,\n onSaved,\n onCancel,\n}: {\n form: Extract<ReturnType<typeof useDeductionForm>, { isLoading: false }>\n Fields: Extract<ReturnType<typeof useDeductionForm>, { isLoading: false }>['form']['Fields']\n Components: ReturnType<typeof useComponentContext>\n t: ReturnType<typeof useTranslation<'Employee.Deductions'>>['t']\n title: string\n onSaved: (deduction: Garnishment, mode: 'create' | 'update') => void\n onCancel: () => void\n}) {\n // useWatch subscribes to changes; getValues only reads once. We need the\n // subscription because `Fields.Amount`'s `format` and `description` props\n // need to re-render when the user toggles Percentage / Fixed amount.\n // The RadioGroup's options carry string values (`'true'`/`'false'`), which\n // round-trip into form state as strings — only `coerceStringBoolean` in the\n // zod preprocessor turns them into actual booleans at validation time. So\n // here we explicitly compare against both shapes; `Boolean('false')` would\n // be truthy and surface the wrong copy under the Amount field.\n const watchedDeductAsPercentageRaw = useWatch({\n control: form.form.hookFormInternals.formMethods.control as Control<DeductionFormData>,\n name: 'deductAsPercentage',\n }) as boolean | 'true' | 'false' | undefined\n const watchedDeductAsPercentage =\n watchedDeductAsPercentageRaw === true || watchedDeductAsPercentageRaw === 'true'\n\n const handleSubmit = async () => {\n const result = await form.actions.onSubmit()\n if (result) onSaved(result.data, result.mode)\n }\n\n return (\n <BaseLayout error={form.errorHandling.errors}>\n <SDKFormProvider formHookResult={form}>\n <Form onSubmit={handleSubmit}>\n <Flex flexDirection=\"column\" gap={32}>\n <Components.Heading as=\"h3\">{title}</Components.Heading>\n <Flex flexDirection=\"column\" gap={20}>\n <Flex flexDirection=\"column\" gap={20}>\n <Fields.Description\n label={t('descriptionLabelV2')}\n validationMessages={{ REQUIRED: t('descriptionRequired') }}\n />\n <Fields.Recurring\n label={t('frequencyLabel')}\n getOptionLabel={(value: boolean) =>\n value ? t('frequencyRecurringOptionV2') : t('frequencyOneTimeOptionV2')\n }\n validationMessages={{ REQUIRED: t('frequencyRequired') }}\n />\n <Fields.DeductAsPercentage\n label={t('deductionTypeLabelV2')}\n getOptionLabel={(value: boolean) =>\n value\n ? t('deductionTypePercentageOptionV2')\n : t('deductionTypeFixedAmountOption')\n }\n validationMessages={{ REQUIRED: t('deductionTypeRequired') }}\n />\n <Fields.Amount\n label={t('deductionAmountLabel')}\n format={watchedDeductAsPercentage ? 'percent' : 'currency'}\n description={\n watchedDeductAsPercentage\n ? t('deductionAmountDescriptionPercentage')\n : t('deductionAmountDescriptionFixed')\n }\n min={0}\n validationMessages={{\n REQUIRED: t('amountRequired'),\n NEGATIVE_AMOUNT: t('amountNonNegative'),\n }}\n />\n </Flex>\n {Fields.TotalAmount && Fields.AnnualMaximum && (\n <Flex flexDirection=\"column\" gap={20}>\n <Fields.TotalAmount\n label={t('totalAmountLabel')}\n description={t('totalAmountDescription')}\n format=\"currency\"\n min={0}\n validationMessages={{\n NEGATIVE_AMOUNT: t('amountNonNegative'),\n }}\n />\n <Fields.AnnualMaximum\n label={t('annualMaxLabel')}\n description={t('annualMaxDescription')}\n format=\"currency\"\n min={0}\n validationMessages={{\n NEGATIVE_AMOUNT: t('amountNonNegative'),\n }}\n />\n </Flex>\n )}\n </Flex>\n <ActionsLayout>\n <Components.Button variant=\"secondary\" type=\"button\" onClick={onCancel}>\n {t('cancelCta')}\n </Components.Button>\n <Components.Button type=\"submit\" isLoading={form.status.isPending}>\n {t('saveCta')}\n </Components.Button>\n </ActionsLayout>\n </Flex>\n </Form>\n </SDKFormProvider>\n </BaseLayout>\n )\n}\n"],"names":["StandardDeductionForm","employeeId","deduction","courtOrdered","garnishmentType","title","onSaved","onCancel","t","useTranslation","Components","useComponentContext","form","useDeductionForm","BaseLayout","Fields","jsx","ReadyForm","watchedDeductAsPercentageRaw","useWatch","watchedDeductAsPercentage","handleSubmit","result","SDKFormProvider","Form","jsxs","Flex","value","ActionsLayout"],"mappings":"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"}
@@ -38,14 +38,23 @@ export type ChildSupportGarnishmentFormOutputs = ChildSupportGarnishmentFormData
38
38
  interface ChildSupportGarnishmentFormSchemaOptions {
39
39
  mode?: 'create' | 'update';
40
40
  /**
41
- * The agency record matching the currently selected `state`. The agency's
42
- * `requiredAttributes` determine which of `caseNumber` / `orderNumber` /
43
- * `remittanceNumber` are required. When omitted (no agency selected yet),
44
- * all three are optional.
41
+ * The agency record matching the currently selected `state`. Used only when
42
+ * `agencyList` is not provided `requiredAttributes` are pinned to this
43
+ * single agency, so the schema must be rebuilt whenever the user picks a
44
+ * different state. Prefer passing `agencyList` instead so requiredness
45
+ * tracks the form's `state` value dynamically.
45
46
  */
46
47
  selectedAgency?: Agencies | null;
48
+ /**
49
+ * Full list of agencies. When provided, the schema's requiredness for
50
+ * `caseNumber` / `orderNumber` / `remittanceNumber` is computed at validation
51
+ * time by looking up the agency whose `state` matches the form's `state`
52
+ * value — so a single schema instance stays correct as the user changes
53
+ * states. Takes precedence over `selectedAgency`.
54
+ */
55
+ agencyList?: readonly Agencies[];
47
56
  }
48
- export declare function createChildSupportGarnishmentFormSchema({ mode, selectedAgency, }?: ChildSupportGarnishmentFormSchemaOptions): import('../../../../../partner-hook-utils/form/buildFormSchema').BuildFormSchemaResult<{
57
+ export declare function createChildSupportGarnishmentFormSchema({ mode, selectedAgency, agencyList, }?: ChildSupportGarnishmentFormSchemaOptions): import('../../../../../partner-hook-utils/form/buildFormSchema').BuildFormSchemaResult<{
49
58
  state: z.ZodString;
50
59
  fipsCode: z.ZodString;
51
60
  caseNumber: z.ZodString;
@@ -1,24 +1,24 @@
1
1
  import { z as e } from "zod";
2
- import { PaymentPeriod as i } from "@gusto/embedded-api/models/components/garnishmentchildsupport";
3
- import { buildFormSchema as a } from "../../../../../partner-hook-utils/form/buildFormSchema.js";
4
- import { coerceNaN as o } from "../../../../../partner-hook-utils/form/preprocessors.js";
5
- const s = {
2
+ import { PaymentPeriod as c } from "@gusto/embedded-api/models/components/garnishmentchildsupport";
3
+ import { buildFormSchema as d } from "../../../../../partner-hook-utils/form/buildFormSchema.js";
4
+ import { coerceNaN as u } from "../../../../../partner-hook-utils/form/preprocessors.js";
5
+ const i = {
6
6
  REQUIRED: "REQUIRED",
7
7
  NEGATIVE_AMOUNT: "NEGATIVE_AMOUNT",
8
8
  PERCENT_OUT_OF_RANGE: "PERCENT_OUT_OF_RANGE"
9
- }, u = [
9
+ }, _ = [
10
10
  "case_number",
11
11
  "order_number",
12
12
  "remittance_number"
13
13
  ];
14
- function E(n) {
15
- const t = /* @__PURE__ */ new Set();
16
- if (!n?.requiredAttributes) return t;
17
- for (const r of n.requiredAttributes)
18
- r.key && u.includes(r.key) && t.add(r.key);
19
- return t;
14
+ function a(o) {
15
+ const n = /* @__PURE__ */ new Set();
16
+ if (!o?.requiredAttributes) return n;
17
+ for (const t of o.requiredAttributes)
18
+ t.key && _.includes(t.key) && n.add(t.key);
19
+ return n;
20
20
  }
21
- const c = 0, _ = 100, d = {
21
+ const N = 0, b = 100, R = {
22
22
  state: e.string(),
23
23
  fipsCode: e.string(),
24
24
  caseNumber: e.string(),
@@ -26,39 +26,58 @@ const c = 0, _ = 100, d = {
26
26
  remittanceNumber: e.string(),
27
27
  // Currency cap on the pay-period — required, ≥ 0.
28
28
  payPeriodMaximum: e.preprocess(
29
- o(0),
30
- e.number().min(0, { message: s.NEGATIVE_AMOUNT })
29
+ u(0),
30
+ e.number().min(0, { message: i.NEGATIVE_AMOUNT })
31
31
  ),
32
32
  // Percentage of paycheck, 0-100. Required.
33
33
  amount: e.preprocess(
34
- o(0),
35
- e.number().min(c, {
36
- message: s.PERCENT_OUT_OF_RANGE
37
- }).max(_, {
38
- message: s.PERCENT_OUT_OF_RANGE
34
+ u(0),
35
+ e.number().min(N, {
36
+ message: i.PERCENT_OUT_OF_RANGE
37
+ }).max(b, {
38
+ message: i.PERCENT_OUT_OF_RANGE
39
39
  })
40
40
  ),
41
- paymentPeriod: e.enum(i)
41
+ paymentPeriod: e.enum(c)
42
42
  };
43
- function p({
44
- mode: n = "create",
45
- selectedAgency: t
43
+ function h({
44
+ mode: o = "create",
45
+ selectedAgency: n,
46
+ agencyList: t
46
47
  } = {}) {
47
- const r = E(t), m = {
48
- caseNumber: r.has("case_number") ? "always" : "never",
49
- orderNumber: r.has("order_number") ? "always" : "never",
50
- remittanceNumber: r.has("remittance_number") ? "always" : "never"
51
- };
52
- return a(d, {
53
- requiredFieldsConfig: m,
54
- requiredErrorCode: s.REQUIRED,
55
- mode: n
48
+ const E = t ? {
49
+ caseNumber: (r) => {
50
+ const s = r.state;
51
+ return a(t.find((m) => m.state === s)).has("case_number");
52
+ },
53
+ orderNumber: (r) => {
54
+ const s = r.state;
55
+ return a(t.find((m) => m.state === s)).has("order_number");
56
+ },
57
+ remittanceNumber: (r) => {
58
+ const s = r.state;
59
+ return a(t.find((m) => m.state === s)).has(
60
+ "remittance_number"
61
+ );
62
+ }
63
+ } : (() => {
64
+ const r = a(n);
65
+ return {
66
+ caseNumber: r.has("case_number") ? "always" : "never",
67
+ orderNumber: r.has("order_number") ? "always" : "never",
68
+ remittanceNumber: r.has("remittance_number") ? "always" : "never"
69
+ };
70
+ })();
71
+ return d(R, {
72
+ requiredFieldsConfig: E,
73
+ requiredErrorCode: i.REQUIRED,
74
+ mode: o
56
75
  });
57
76
  }
58
77
  export {
59
- s as ChildSupportGarnishmentFormErrorCodes,
60
- u as SUPPORTED_REQUIRED_ATTR_KEYS,
61
- p as createChildSupportGarnishmentFormSchema,
62
- E as getRequiredAttrKeys
78
+ i as ChildSupportGarnishmentFormErrorCodes,
79
+ _ as SUPPORTED_REQUIRED_ATTR_KEYS,
80
+ h as createChildSupportGarnishmentFormSchema,
81
+ a as getRequiredAttrKeys
63
82
  };
64
83
  //# sourceMappingURL=childSupportGarnishmentFormSchema.js.map