@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.
- package/CHANGELOG.md +67 -0
- package/dist/components/Common/DataView/DataTable/DataTable.js +76 -72
- package/dist/components/Common/DataView/DataTable/DataTable.js.map +1 -1
- package/dist/components/Common/DataView/DataTable/DataTable.module.scss.js +8 -0
- package/dist/components/Common/DataView/DataTable/DataTable.module.scss.js.map +1 -0
- package/dist/components/Common/DataView/useDataView.d.ts +2 -0
- package/dist/components/Common/DataView/useDataView.js.map +1 -1
- package/dist/components/Common/DocumentViewer/DocumentViewer.js +10 -10
- package/dist/components/Common/DocumentViewer/DocumentViewer.js.map +1 -1
- package/dist/components/Common/DocumentViewer/DocumentViewer.module.scss.js +9 -9
- package/dist/components/Common/PaginationControl/PaginationControl.js +11 -10
- package/dist/components/Common/PaginationControl/PaginationControl.js.map +1 -1
- package/dist/components/Common/PaginationControl/PaginationControlTypes.d.ts +1 -1
- package/dist/components/Common/UI/DescriptionList/DescriptionList.js +11 -10
- package/dist/components/Common/UI/DescriptionList/DescriptionList.js.map +1 -1
- package/dist/components/Common/UI/DescriptionList/DescriptionList.module.scss.js +4 -4
- package/dist/components/Common/UI/Input/InputTypes.d.ts +1 -1
- package/dist/components/Common/UI/Input/InputTypes.js.map +1 -1
- package/dist/components/Common/UI/NumberInput/NumberInput.js +51 -48
- package/dist/components/Common/UI/NumberInput/NumberInput.js.map +1 -1
- package/dist/components/Common/VisuallyHidden/VisuallyHidden.d.ts +1 -1
- package/dist/components/Common/VisuallyHidden/VisuallyHidden.js.map +1 -1
- package/dist/components/Company/AssignSignatory/CreateSignatory/useCreateSignatory.js +3 -4
- package/dist/components/Company/AssignSignatory/CreateSignatory/useCreateSignatory.js.map +1 -1
- package/dist/components/Company/AssignSignatory/InviteSignatory/useInviteSignatory.js +3 -4
- package/dist/components/Company/AssignSignatory/InviteSignatory/useInviteSignatory.js.map +1 -1
- package/dist/components/Company/AssignSignatory/useAssignSignatory.js +5 -6
- package/dist/components/Company/AssignSignatory/useAssignSignatory.js.map +1 -1
- package/dist/components/Company/BankAccount/BankAccountForm/context.js +3 -4
- package/dist/components/Company/BankAccount/BankAccountForm/context.js.map +1 -1
- package/dist/components/Company/DocumentSigner/DocumentList/useDocumentList.js +3 -4
- package/dist/components/Company/DocumentSigner/DocumentList/useDocumentList.js.map +1 -1
- package/dist/components/Company/DocumentSigner/shared/useSignCompanyForm/fields.js +4 -4
- package/dist/components/Company/FederalTaxes/useFederalTaxes.js +5 -6
- package/dist/components/Company/FederalTaxes/useFederalTaxes.js.map +1 -1
- package/dist/components/Company/Industry/Context.js +6 -7
- package/dist/components/Company/Industry/Context.js.map +1 -1
- package/dist/components/Company/Locations/LocationForm/useLocationForm.js +3 -4
- package/dist/components/Company/Locations/LocationForm/useLocationForm.js.map +1 -1
- package/dist/components/Company/Locations/LocationsList/useLocationsList.js +3 -4
- package/dist/components/Company/Locations/LocationsList/useLocationsList.js.map +1 -1
- package/dist/components/Company/OnboardingOverview/context.js +3 -4
- package/dist/components/Company/OnboardingOverview/context.js.map +1 -1
- package/dist/components/Company/PaySchedule/shared/usePayScheduleForm/fields.js +5 -5
- package/dist/components/Company/StateTaxes/StateTaxesForm/context.js +3 -4
- package/dist/components/Company/StateTaxes/StateTaxesForm/context.js.map +1 -1
- package/dist/components/Company/StateTaxes/StateTaxesList/context.js +3 -4
- package/dist/components/Company/StateTaxes/StateTaxesList/context.js.map +1 -1
- package/dist/components/Contractor/Address/useAddress.js +5 -6
- package/dist/components/Contractor/Address/useAddress.js.map +1 -1
- package/dist/components/Contractor/Profile/useContractorProfile.js +33 -34
- package/dist/components/Contractor/Profile/useContractorProfile.js.map +1 -1
- package/dist/components/Employee/Compensation/management/EditCompensation/EditCompensation.js +14 -11
- package/dist/components/Employee/Compensation/management/EditCompensation/EditCompensation.js.map +1 -1
- package/dist/components/Employee/Compensation/management/EditPendingCompensation/EditPendingCompensation.js +0 -2
- package/dist/components/Employee/Compensation/management/EditPendingCompensation/EditPendingCompensation.js.map +1 -1
- package/dist/components/Employee/Compensation/management/ManagementCompensationFormBody.js +18 -18
- package/dist/components/Employee/Compensation/management/ManagementCompensationFormBody.js.map +1 -1
- package/dist/components/Employee/Compensation/onboarding/JobsList/JobsListPresentation.js +36 -36
- package/dist/components/Employee/Compensation/onboarding/JobsList/JobsListPresentation.js.map +1 -1
- package/dist/components/Employee/Compensation/shared/useCompensationForm/fields.js +4 -4
- package/dist/components/Employee/Compensation/shared/useCompensationForm/useCompensationForm.js +140 -140
- package/dist/components/Employee/Compensation/shared/useCompensationForm/useCompensationForm.js.map +1 -1
- package/dist/components/Employee/Compensation/shared/useJobForm/fields.js +6 -6
- package/dist/components/Employee/Compensation/shared/useJobForm/useJobForm.d.ts +6 -5
- package/dist/components/Employee/Compensation/shared/useJobForm/useJobForm.js +162 -131
- package/dist/components/Employee/Compensation/shared/useJobForm/useJobForm.js.map +1 -1
- package/dist/components/Employee/Dashboard/BasicDetailsView.js +74 -88
- package/dist/components/Employee/Dashboard/BasicDetailsView.js.map +1 -1
- package/dist/components/Employee/Dashboard/Dashboard.js +53 -51
- package/dist/components/Employee/Dashboard/Dashboard.js.map +1 -1
- package/dist/components/Employee/Dashboard/DocumentsView.js +17 -10
- package/dist/components/Employee/Dashboard/DocumentsView.js.map +1 -1
- package/dist/components/Employee/Dashboard/JobAndPayView.js +383 -357
- package/dist/components/Employee/Dashboard/JobAndPayView.js.map +1 -1
- package/dist/components/Employee/Dashboard/TaxesView.js +114 -101
- package/dist/components/Employee/Dashboard/TaxesView.js.map +1 -1
- package/dist/components/Employee/Dashboard/getPendingCompensationChanges.js +36 -36
- package/dist/components/Employee/Dashboard/getPendingCompensationChanges.js.map +1 -1
- package/dist/components/Employee/Deductions/DeductionsForm/StandardDeductionForm.js +57 -57
- package/dist/components/Employee/Deductions/DeductionsForm/StandardDeductionForm.js.map +1 -1
- package/dist/components/Employee/Deductions/shared/useChildSupportGarnishmentForm/childSupportGarnishmentFormSchema.d.ts +14 -5
- package/dist/components/Employee/Deductions/shared/useChildSupportGarnishmentForm/childSupportGarnishmentFormSchema.js +55 -36
- package/dist/components/Employee/Deductions/shared/useChildSupportGarnishmentForm/childSupportGarnishmentFormSchema.js.map +1 -1
- package/dist/components/Employee/Deductions/shared/useChildSupportGarnishmentForm/fields.js +8 -8
- package/dist/components/Employee/Deductions/shared/useChildSupportGarnishmentForm/useChildSupportGarnishmentForm.js +18 -18
- package/dist/components/Employee/Deductions/shared/useChildSupportGarnishmentForm/useChildSupportGarnishmentForm.js.map +1 -1
- package/dist/components/Employee/Deductions/shared/useDeductionForm/fields.js +4 -4
- package/dist/components/Employee/Deductions/shared/useDeductionForm/useDeductionForm.d.ts +3 -3
- package/dist/components/Employee/Deductions/shared/useDeductionForm/useDeductionForm.js.map +1 -1
- package/dist/components/Employee/Documents/onboarding/DocumentSigner/DocumentList/useDocumentList.js +3 -4
- package/dist/components/Employee/Documents/onboarding/DocumentSigner/DocumentList/useDocumentList.js.map +1 -1
- package/dist/components/Employee/Documents/shared/useSignEmployeeForm/fields.js +1 -1
- package/dist/components/Employee/FederalTaxes/shared/useFederalTaxesForm/fields.js +4 -4
- package/dist/components/Employee/HomeAddress/management/HomeAddressView.js +157 -147
- package/dist/components/Employee/HomeAddress/management/HomeAddressView.js.map +1 -1
- package/dist/components/Employee/HomeAddress/management/useHomeAddressManagement.js +56 -55
- package/dist/components/Employee/HomeAddress/management/useHomeAddressManagement.js.map +1 -1
- package/dist/components/Employee/PaymentMethod/onboarding/BankForm.js +20 -20
- package/dist/components/Employee/PaymentMethod/onboarding/BankForm.js.map +1 -1
- package/dist/components/Employee/PaymentMethod/shared/useBankForm/fields.js +1 -1
- package/dist/components/Employee/PaymentMethod/shared/useSplitPaymentsForm/splitFieldFactory.d.ts +1 -1
- package/dist/components/Employee/PaymentMethod/shared/useSplitPaymentsForm/splitFieldFactory.js +4 -4
- package/dist/components/Employee/PaymentMethod/shared/useSplitPaymentsForm/splitFieldFactory.js.map +1 -1
- package/dist/components/Employee/Profile/shared/useEmployeeDetailsForm/fields.js +8 -8
- package/dist/components/Employee/Profile/shared/useHomeAddressForm/fields.js +5 -5
- package/dist/components/Employee/Profile/shared/useHomeAddressForm/homeAddressSchema.d.ts +0 -1
- package/dist/components/Employee/Profile/shared/useHomeAddressForm/homeAddressSchema.js +11 -12
- package/dist/components/Employee/Profile/shared/useHomeAddressForm/homeAddressSchema.js.map +1 -1
- package/dist/components/Employee/Profile/shared/useHomeAddressForm/homeAddressSchema.test.d.ts +1 -0
- package/dist/components/Employee/Profile/shared/useHomeAddressForm/useHomeAddressForm.d.ts +6 -1
- package/dist/components/Employee/Profile/shared/useHomeAddressForm/useHomeAddressForm.js +95 -94
- package/dist/components/Employee/Profile/shared/useHomeAddressForm/useHomeAddressForm.js.map +1 -1
- package/dist/components/Employee/Profile/shared/useWorkAddressForm/fields.js +4 -4
- package/dist/components/Employee/Profile/shared/useWorkAddressForm/useWorkAddressForm.d.ts +6 -1
- package/dist/components/Employee/Profile/shared/useWorkAddressForm/useWorkAddressForm.js +87 -86
- package/dist/components/Employee/Profile/shared/useWorkAddressForm/useWorkAddressForm.js.map +1 -1
- package/dist/components/Employee/StateTaxes/shared/EmployeeStateTaxesView.js +18 -18
- package/dist/components/Employee/StateTaxes/shared/EmployeeStateTaxesView.js.map +1 -1
- package/dist/components/Employee/StateTaxes/shared/useEmployeeStateTaxesForm/fieldComponents.js +8 -8
- package/dist/components/Employee/Taxes/useTaxes.js +3 -4
- package/dist/components/Employee/Taxes/useTaxes.js.map +1 -1
- package/dist/components/Employee/WorkAddress/management/WorkAddressView.js +5 -1
- package/dist/components/Employee/WorkAddress/management/WorkAddressView.js.map +1 -1
- package/dist/components/Employee/WorkAddress/management/useWorkAddressManagement.js +61 -60
- package/dist/components/Employee/WorkAddress/management/useWorkAddressManagement.js.map +1 -1
- package/dist/components/Payroll/GrossUpModal/GrossUpModal.js +2 -3
- package/dist/components/Payroll/GrossUpModal/GrossUpModal.js.map +1 -1
- package/dist/components/Payroll/usePreparedPayrollData.js +2 -3
- package/dist/components/Payroll/usePreparedPayrollData.js.map +1 -1
- package/dist/components/TimeOff/TimeOffManagement/SelectEmployees/SelectEmployeesHoliday.js +6 -7
- package/dist/components/TimeOff/TimeOffManagement/SelectEmployees/SelectEmployeesHoliday.js.map +1 -1
- package/dist/components/TimeOff/TimeOffManagement/SelectEmployees/SelectEmployeesPresentation.d.ts +1 -1
- package/dist/components/TimeOff/TimeOffManagement/SelectEmployees/SelectEmployeesPresentation.js +52 -68
- package/dist/components/TimeOff/TimeOffManagement/SelectEmployees/SelectEmployeesPresentation.js.map +1 -1
- package/dist/components/TimeOff/TimeOffManagement/SelectEmployees/SelectEmployeesPresentation.module.scss.js +4 -4
- package/dist/components/TimeOff/TimeOffManagement/SelectEmployees/SelectEmployeesPresentationTypes.d.ts +0 -11
- package/dist/components/TimeOff/TimeOffManagement/SelectEmployees/SelectEmployeesTimeOff.js +137 -163
- package/dist/components/TimeOff/TimeOffManagement/SelectEmployees/SelectEmployeesTimeOff.js.map +1 -1
- package/dist/components/TimeOff/TimeOffManagement/SelectEmployees/useSelectEmployeesData.js +36 -35
- package/dist/components/TimeOff/TimeOffManagement/SelectEmployees/useSelectEmployeesData.js.map +1 -1
- package/dist/components/TimeOff/TimeOffPolicyDetail/TimeOffPolicyDetailPresentation.js +34 -34
- package/dist/components/TimeOff/TimeOffPolicyDetail/TimeOffPolicyDetailPresentation.js.map +1 -1
- package/dist/helpers/breadcrumbHelpers.d.ts +1 -1
- package/dist/helpers/breadcrumbHelpers.js.map +1 -1
- package/dist/helpers/federalEin.d.ts +1 -0
- package/dist/helpers/federalEin.js.map +1 -1
- package/dist/helpers/mask.d.ts +8 -4
- package/dist/helpers/mask.js.map +1 -1
- package/dist/helpers/rem.d.ts +2 -1
- package/dist/helpers/rem.js.map +1 -1
- package/dist/hooks/useAsyncError.d.ts +1 -0
- package/dist/hooks/useAsyncError.js.map +1 -1
- package/dist/hooks/useForkRef/useForkRef.d.ts +1 -0
- package/dist/hooks/useForkRef/useForkRef.js.map +1 -1
- package/dist/i18n/I18n.d.ts +9 -1
- package/dist/i18n/I18n.js.map +1 -1
- package/dist/i18n/en/Company.TimeOff.EmployeeTable.json.js +14 -14
- package/dist/i18n/en/Company.TimeOff.SelectEmployees.json.js +12 -18
- package/dist/i18n/en/Company.TimeOff.SelectEmployees.json.js.map +1 -1
- package/dist/i18n/en/Employee.Compensation.json.js +24 -24
- package/dist/i18n/en/Employee.Dashboard.json.js +22 -20
- package/dist/i18n/en/Employee.Dashboard.json.js.map +1 -1
- package/dist/i18n/en/Employee.PaymentMethod.json.js +25 -25
- package/dist/i18n/en/Employee.StateTaxes.json.js +12 -10
- package/dist/i18n/en/Employee.StateTaxes.json.js.map +1 -1
- package/dist/style.css +1 -1
- package/dist/types/hooks.d.ts +1 -1
- package/dist/types/i18next.d.ts +4 -17
- package/dist/types/observability.d.ts +1 -1
- package/package.json +30 -27
- 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":"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"}
|
|
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
|
|
2
|
-
const
|
|
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 =
|
|
5
|
-
return n ?
|
|
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 =
|
|
9
|
-
return n ?
|
|
10
|
-
},
|
|
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
|
|
16
|
-
const
|
|
17
|
-
|
|
18
|
-
const
|
|
19
|
-
(
|
|
20
|
-
const
|
|
21
|
-
return !
|
|
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
|
|
24
|
-
const
|
|
23
|
+
function C(t) {
|
|
24
|
+
const e = p(t.rate);
|
|
25
25
|
return [
|
|
26
26
|
{
|
|
27
27
|
kind: "newJob",
|
|
28
|
-
title: t.title ??
|
|
29
|
-
rate:
|
|
30
|
-
paymentUnit:
|
|
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
|
|
34
|
+
function v(t, e = {}) {
|
|
35
35
|
if (!t?.length) return [];
|
|
36
|
-
const n = e.today ?? /* @__PURE__ */ new Date(),
|
|
37
|
-
for (const
|
|
38
|
-
const
|
|
39
|
-
if (
|
|
40
|
-
const
|
|
41
|
-
for (let
|
|
42
|
-
const
|
|
43
|
-
|
|
44
|
-
compensationUuid:
|
|
45
|
-
jobUuid:
|
|
46
|
-
effectiveDate:
|
|
47
|
-
jobTitle:
|
|
48
|
-
details:
|
|
49
|
-
isNewJob:
|
|
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
|
|
53
|
+
return u.sort((o, a) => o.effectiveDate.localeCompare(a.effectiveDate)), u;
|
|
54
54
|
}
|
|
55
55
|
export {
|
|
56
|
-
|
|
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
|
|
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
|
|
5
|
-
import { Form as
|
|
6
|
-
import { Flex as
|
|
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
|
|
10
|
-
import { BaseLayout as
|
|
11
|
-
import { SDKFormProvider as
|
|
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:
|
|
15
|
-
deduction:
|
|
16
|
-
courtOrdered:
|
|
14
|
+
employeeId: t,
|
|
15
|
+
deduction: o,
|
|
16
|
+
courtOrdered: r,
|
|
17
17
|
garnishmentType: e,
|
|
18
|
-
title:
|
|
19
|
-
onSaved:
|
|
20
|
-
onCancel:
|
|
18
|
+
title: s,
|
|
19
|
+
onSaved: l,
|
|
20
|
+
onCancel: p
|
|
21
21
|
}) {
|
|
22
|
-
const { t:
|
|
23
|
-
employeeId:
|
|
24
|
-
garnishmentId:
|
|
25
|
-
courtOrdered:
|
|
26
|
-
defaultValues:
|
|
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 (
|
|
29
|
-
return /* @__PURE__ */ n(
|
|
30
|
-
const { Fields:
|
|
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:
|
|
35
|
-
Fields:
|
|
36
|
-
Components:
|
|
37
|
-
t:
|
|
38
|
-
title:
|
|
39
|
-
onSaved:
|
|
40
|
-
onCancel:
|
|
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:
|
|
46
|
-
Fields:
|
|
47
|
-
Components:
|
|
45
|
+
form: t,
|
|
46
|
+
Fields: o,
|
|
47
|
+
Components: r,
|
|
48
48
|
t: e,
|
|
49
|
-
title:
|
|
50
|
-
onSaved:
|
|
51
|
-
onCancel:
|
|
49
|
+
title: s,
|
|
50
|
+
onSaved: l,
|
|
51
|
+
onCancel: p
|
|
52
52
|
}) {
|
|
53
|
-
const
|
|
54
|
-
control:
|
|
53
|
+
const u = A({
|
|
54
|
+
control: t.form.hookFormInternals.formMethods.control,
|
|
55
55
|
name: "deductAsPercentage"
|
|
56
|
-
}),
|
|
57
|
-
const
|
|
58
|
-
|
|
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(
|
|
61
|
-
/* @__PURE__ */ n(
|
|
62
|
-
/* @__PURE__ */
|
|
63
|
-
/* @__PURE__ */
|
|
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
|
-
|
|
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
|
-
|
|
72
|
+
o.Recurring,
|
|
73
73
|
{
|
|
74
74
|
label: e("frequencyLabel"),
|
|
75
|
-
getOptionLabel: (
|
|
75
|
+
getOptionLabel: (i) => e(i ? "frequencyRecurringOptionV2" : "frequencyOneTimeOptionV2"),
|
|
76
76
|
validationMessages: { REQUIRED: e("frequencyRequired") }
|
|
77
77
|
}
|
|
78
78
|
),
|
|
79
79
|
/* @__PURE__ */ n(
|
|
80
|
-
|
|
80
|
+
o.DeductAsPercentage,
|
|
81
81
|
{
|
|
82
82
|
label: e("deductionTypeLabelV2"),
|
|
83
|
-
getOptionLabel: (
|
|
83
|
+
getOptionLabel: (i) => e(i ? "deductionTypePercentageOptionV2" : "deductionTypeFixedAmountOption"),
|
|
84
84
|
validationMessages: { REQUIRED: e("deductionTypeRequired") }
|
|
85
85
|
}
|
|
86
86
|
),
|
|
87
87
|
/* @__PURE__ */ n(
|
|
88
|
-
|
|
88
|
+
o.Amount,
|
|
89
89
|
{
|
|
90
90
|
label: e("deductionAmountLabel"),
|
|
91
|
-
format:
|
|
92
|
-
description: e(
|
|
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
|
-
|
|
101
|
+
o.TotalAmount && o.AnnualMaximum && /* @__PURE__ */ c(m, { flexDirection: "column", gap: 20, children: [
|
|
102
102
|
/* @__PURE__ */ n(
|
|
103
|
-
|
|
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
|
-
|
|
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__ */
|
|
129
|
-
/* @__PURE__ */ n(
|
|
130
|
-
/* @__PURE__ */ n(
|
|
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`.
|
|
42
|
-
* `
|
|
43
|
-
*
|
|
44
|
-
*
|
|
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
|
|
3
|
-
import { buildFormSchema as
|
|
4
|
-
import { coerceNaN as
|
|
5
|
-
const
|
|
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
|
-
},
|
|
9
|
+
}, _ = [
|
|
10
10
|
"case_number",
|
|
11
11
|
"order_number",
|
|
12
12
|
"remittance_number"
|
|
13
13
|
];
|
|
14
|
-
function
|
|
15
|
-
const
|
|
16
|
-
if (!
|
|
17
|
-
for (const
|
|
18
|
-
|
|
19
|
-
return
|
|
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
|
|
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
|
-
|
|
30
|
-
e.number().min(0, { message:
|
|
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
|
-
|
|
35
|
-
e.number().min(
|
|
36
|
-
message:
|
|
37
|
-
}).max(
|
|
38
|
-
message:
|
|
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(
|
|
41
|
+
paymentPeriod: e.enum(c)
|
|
42
42
|
};
|
|
43
|
-
function
|
|
44
|
-
mode:
|
|
45
|
-
selectedAgency:
|
|
43
|
+
function h({
|
|
44
|
+
mode: o = "create",
|
|
45
|
+
selectedAgency: n,
|
|
46
|
+
agencyList: t
|
|
46
47
|
} = {}) {
|
|
47
|
-
const
|
|
48
|
-
caseNumber: r
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
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
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
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
|