@gusto/embedded-react-sdk 0.55.0 → 0.55.2

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 (174) hide show
  1. package/CHANGELOG.md +36 -0
  2. package/dist/components/Common/TaxInputs/TaxInputs.js +65 -64
  3. package/dist/components/Common/TaxInputs/TaxInputs.js.map +1 -1
  4. package/dist/components/Common/UI/Select/Select.module.scss.js +5 -5
  5. package/dist/components/Contractor/Payments/CreateHistoricalPayment/CreateHistoricalPayment.d.ts +4 -2
  6. package/dist/components/Contractor/Payments/CreateHistoricalPayment/CreateHistoricalPayment.js +148 -117
  7. package/dist/components/Contractor/Payments/CreateHistoricalPayment/CreateHistoricalPayment.js.map +1 -1
  8. package/dist/components/Contractor/Payments/CreatePayment/PreviewPresentation.js +56 -55
  9. package/dist/components/Contractor/Payments/CreatePayment/PreviewPresentation.js.map +1 -1
  10. package/dist/components/Contractor/Payments/CreatePaymentFlow/CreatePaymentFlow.d.ts +1 -1
  11. package/dist/components/Contractor/Payments/CreatePaymentFlow/CreatePaymentFlow.js +15 -12
  12. package/dist/components/Contractor/Payments/CreatePaymentFlow/CreatePaymentFlow.js.map +1 -1
  13. package/dist/components/Contractor/Payments/HistoricalPaymentFlow/HistoricalPaymentFlow.d.ts +69 -0
  14. package/dist/components/Contractor/Payments/HistoricalPaymentFlow/HistoricalPaymentFlow.js +48 -0
  15. package/dist/components/Contractor/Payments/HistoricalPaymentFlow/HistoricalPaymentFlow.js.map +1 -0
  16. package/dist/components/Contractor/Payments/HistoricalPaymentFlow/HistoricalPaymentFlowComponents.d.ts +20 -0
  17. package/dist/components/Contractor/Payments/HistoricalPaymentFlow/HistoricalPaymentFlowComponents.js +25 -0
  18. package/dist/components/Contractor/Payments/HistoricalPaymentFlow/HistoricalPaymentFlowComponents.js.map +1 -0
  19. package/dist/components/Contractor/Payments/HistoricalPaymentFlow/historicalPaymentMachine.d.ts +20 -0
  20. package/dist/components/Contractor/Payments/HistoricalPaymentFlow/historicalPaymentMachine.js +24 -0
  21. package/dist/components/Contractor/Payments/HistoricalPaymentFlow/historicalPaymentMachine.js.map +1 -0
  22. package/dist/components/Contractor/Payments/HistoricalPaymentFlow/index.d.ts +2 -0
  23. package/dist/components/Contractor/Payments/HistoricalPaymentSummary/HistoricalPaymentSummary.js +16 -15
  24. package/dist/components/Contractor/Payments/HistoricalPaymentSummary/HistoricalPaymentSummary.js.map +1 -1
  25. package/dist/components/Contractor/Payments/PaymentFlow/PaymentFlowComponents.d.ts +2 -0
  26. package/dist/components/Contractor/Payments/PaymentFlow/PaymentFlowComponents.js +36 -23
  27. package/dist/components/Contractor/Payments/PaymentFlow/PaymentFlowComponents.js.map +1 -1
  28. package/dist/components/Contractor/Payments/PaymentFlow/paymentStateMachine.d.ts +10 -8
  29. package/dist/components/Contractor/Payments/PaymentFlow/paymentStateMachine.js +46 -25
  30. package/dist/components/Contractor/Payments/PaymentFlow/paymentStateMachine.js.map +1 -1
  31. package/dist/components/Contractor/Payments/PaymentHistory/PaymentHistoryPresentation.js +53 -52
  32. package/dist/components/Contractor/Payments/PaymentHistory/PaymentHistoryPresentation.js.map +1 -1
  33. package/dist/components/Contractor/Payments/PaymentStatement/PaymentStatementPresentation.js +37 -47
  34. package/dist/components/Contractor/Payments/PaymentStatement/PaymentStatementPresentation.js.map +1 -1
  35. package/dist/components/Contractor/Payments/PaymentsList/PaymentsList.js +47 -44
  36. package/dist/components/Contractor/Payments/PaymentsList/PaymentsList.js.map +1 -1
  37. package/dist/components/Contractor/Payments/PaymentsList/PaymentsListPresentation.d.ts +2 -1
  38. package/dist/components/Contractor/Payments/PaymentsList/PaymentsListPresentation.js +65 -53
  39. package/dist/components/Contractor/Payments/PaymentsList/PaymentsListPresentation.js.map +1 -1
  40. package/dist/components/Contractor/Payments/PaymentsList/PaymentsListPresentation.module.scss.js +6 -4
  41. package/dist/components/Contractor/Payments/PaymentsList/PaymentsListPresentation.module.scss.js.map +1 -1
  42. package/dist/components/Contractor/Payments/ViewPaymentFlow/ViewPaymentFlow.d.ts +1 -1
  43. package/dist/components/Contractor/Payments/ViewPaymentFlow/ViewPaymentFlow.js +22 -19
  44. package/dist/components/Contractor/Payments/ViewPaymentFlow/ViewPaymentFlow.js.map +1 -1
  45. package/dist/components/Contractor/Payments/shared/PaymentSummaryBlock/PaymentSummaryBlock.d.ts +2 -8
  46. package/dist/components/Contractor/Payments/shared/PaymentSummaryBlock/PaymentSummaryBlock.js +43 -42
  47. package/dist/components/Contractor/Payments/shared/PaymentSummaryBlock/PaymentSummaryBlock.js.map +1 -1
  48. package/dist/components/Contractor/Payments/shared/paymentAmounts.d.ts +32 -0
  49. package/dist/components/Contractor/Payments/shared/paymentAmounts.js +11 -0
  50. package/dist/components/Contractor/Payments/shared/paymentAmounts.js.map +1 -0
  51. package/dist/components/Contractor/Payments/shared/paymentAmounts.test.d.ts +1 -0
  52. package/dist/components/Contractor/Payments/shared/usePaymentAmountsEditor.d.ts +13 -4
  53. package/dist/components/Contractor/Payments/shared/usePaymentAmountsEditor.js +43 -38
  54. package/dist/components/Contractor/Payments/shared/usePaymentAmountsEditor.js.map +1 -1
  55. package/dist/components/Contractor/exports/contractorManagement.d.ts +1 -0
  56. package/dist/components/Contractor/exports/contractorManagement.js +34 -32
  57. package/dist/components/Contractor/exports/contractorManagement.js.map +1 -1
  58. package/dist/components/Contractor/shared/SelectContractors/SelectContractors.d.ts +6 -1
  59. package/dist/components/Contractor/shared/SelectContractors/SelectContractors.js +13 -12
  60. package/dist/components/Contractor/shared/SelectContractors/SelectContractors.js.map +1 -1
  61. package/dist/components/Contractor/shared/SelectContractors/useSelectContractors.d.ts +5 -1
  62. package/dist/components/Contractor/shared/SelectContractors/useSelectContractors.js +34 -32
  63. package/dist/components/Contractor/shared/SelectContractors/useSelectContractors.js.map +1 -1
  64. package/dist/components/Payroll/PayrollConfiguration/PayrollConfiguration.d.ts +7 -0
  65. package/dist/components/Payroll/PayrollConfiguration/PayrollConfiguration.js +191 -153
  66. package/dist/components/Payroll/PayrollConfiguration/PayrollConfiguration.js.map +1 -1
  67. package/dist/components/Payroll/PayrollConfiguration/usePayrollConfigurationData.d.ts +1 -0
  68. package/dist/components/Payroll/PayrollConfiguration/usePayrollConfigurationData.js +87 -81
  69. package/dist/components/Payroll/PayrollConfiguration/usePayrollConfigurationData.js.map +1 -1
  70. package/dist/components/Payroll/PayrollExecutionFlow/PayrollExecutionFlow.d.ts +1 -0
  71. package/dist/components/Payroll/PayrollExecutionFlow/PayrollExecutionFlow.js.map +1 -1
  72. package/dist/components/Payroll/PayrollExecutionFlow/payrollExecutionMachine.js +73 -48
  73. package/dist/components/Payroll/PayrollExecutionFlow/payrollExecutionMachine.js.map +1 -1
  74. package/dist/components/Payroll/PayrollFlow/PayrollFlow.d.ts +1 -1
  75. package/dist/components/Payroll/PayrollFlow/PayrollFlow.js +22 -20
  76. package/dist/components/Payroll/PayrollFlow/PayrollFlow.js.map +1 -1
  77. package/dist/components/Payroll/PayrollFlow/PayrollFlowComponents.d.ts +3 -0
  78. package/dist/components/Payroll/PayrollFlow/PayrollFlowComponents.js +22 -20
  79. package/dist/components/Payroll/PayrollFlow/PayrollFlowComponents.js.map +1 -1
  80. package/dist/components/Payroll/PayrollLanding/PayrollLanding.d.ts +2 -0
  81. package/dist/components/Payroll/PayrollLanding/PayrollLanding.js +34 -26
  82. package/dist/components/Payroll/PayrollLanding/PayrollLanding.js.map +1 -1
  83. package/dist/components/Payroll/PayrollLanding/PayrollLandingFlowComponents.d.ts +4 -0
  84. package/dist/components/Payroll/PayrollLanding/PayrollLandingFlowComponents.js +51 -43
  85. package/dist/components/Payroll/PayrollLanding/PayrollLandingFlowComponents.js.map +1 -1
  86. package/dist/components/Payroll/PayrollList/PayrollList.d.ts +2 -0
  87. package/dist/components/Payroll/PayrollList/PayrollList.js +48 -47
  88. package/dist/components/Payroll/PayrollList/PayrollList.js.map +1 -1
  89. package/dist/components/Payroll/PayrollList/PayrollListPresentation.d.ts +2 -1
  90. package/dist/components/Payroll/PayrollList/PayrollListPresentation.js +44 -43
  91. package/dist/components/Payroll/PayrollList/PayrollListPresentation.js.map +1 -1
  92. package/dist/components/Payroll/PayrollOverview/PayrollOverview.d.ts +7 -0
  93. package/dist/components/Payroll/PayrollOverview/PayrollOverview.js +115 -112
  94. package/dist/components/Payroll/PayrollOverview/PayrollOverview.js.map +1 -1
  95. package/dist/components/Payroll/PayrollOverview/PayrollOverviewPresentation.d.ts +2 -1
  96. package/dist/components/Payroll/PayrollOverview/PayrollOverviewPresentation.js +94 -103
  97. package/dist/components/Payroll/PayrollOverview/PayrollOverviewPresentation.js.map +1 -1
  98. package/dist/components/Payroll/PayrollReceipts/PayrollReceipts.js +22 -16
  99. package/dist/components/Payroll/PayrollReceipts/PayrollReceipts.js.map +1 -1
  100. package/dist/components/Payroll/PayrollReceipts/PayrollReceiptsPresentation.js +58 -49
  101. package/dist/components/Payroll/PayrollReceipts/PayrollReceiptsPresentation.js.map +1 -1
  102. package/dist/components/Payroll/PrintChecks/PrintChecks.d.ts +21 -0
  103. package/dist/components/Payroll/PrintChecks/PrintChecks.js +68 -0
  104. package/dist/components/Payroll/PrintChecks/PrintChecks.js.map +1 -0
  105. package/dist/components/Payroll/PrintChecks/PrintChecksBanner/PrintChecksBanner.d.ts +9 -0
  106. package/dist/components/Payroll/PrintChecks/PrintChecksBanner/PrintChecksBanner.js +34 -0
  107. package/dist/components/Payroll/PrintChecks/PrintChecksBanner/PrintChecksBanner.js.map +1 -0
  108. package/dist/components/Payroll/PrintChecks/PrintChecksBanner/index.d.ts +1 -0
  109. package/dist/components/Payroll/PrintChecks/PrintChecksComponents.d.ts +48 -0
  110. package/dist/components/Payroll/PrintChecks/PrintChecksComponents.js +26 -0
  111. package/dist/components/Payroll/PrintChecks/PrintChecksComponents.js.map +1 -0
  112. package/dist/components/Payroll/PrintChecks/PrintChecksFailure/PrintChecksFailure.d.ts +14 -0
  113. package/dist/components/Payroll/PrintChecks/PrintChecksFailure/PrintChecksFailure.js +47 -0
  114. package/dist/components/Payroll/PrintChecks/PrintChecksFailure/PrintChecksFailure.js.map +1 -0
  115. package/dist/components/Payroll/PrintChecks/PrintChecksFailure/index.d.ts +1 -0
  116. package/dist/components/Payroll/PrintChecks/PrintChecksForm/PrintChecksForm.d.ts +16 -0
  117. package/dist/components/Payroll/PrintChecks/PrintChecksForm/PrintChecksForm.js +144 -0
  118. package/dist/components/Payroll/PrintChecks/PrintChecksForm/PrintChecksForm.js.map +1 -0
  119. package/dist/components/Payroll/PrintChecks/PrintChecksForm/index.d.ts +1 -0
  120. package/dist/components/Payroll/PrintChecks/PrintChecksSummary/PrintChecksSummary.d.ts +14 -0
  121. package/dist/components/Payroll/PrintChecks/PrintChecksSummary/PrintChecksSummary.js +39 -0
  122. package/dist/components/Payroll/PrintChecks/PrintChecksSummary/PrintChecksSummary.js.map +1 -0
  123. package/dist/components/Payroll/PrintChecks/PrintChecksSummary/index.d.ts +1 -0
  124. package/dist/components/Payroll/PrintChecks/index.d.ts +2 -0
  125. package/dist/components/Payroll/PrintChecks/printChecksStateMachine.d.ts +33 -0
  126. package/dist/components/Payroll/PrintChecks/printChecksStateMachine.js +93 -0
  127. package/dist/components/Payroll/PrintChecks/printChecksStateMachine.js.map +1 -0
  128. package/dist/components/Payroll/PrintChecks/types.d.ts +14 -0
  129. package/dist/components/Payroll/index.d.ts +2 -0
  130. package/dist/components/Payroll/index.js +26 -24
  131. package/dist/components/Payroll/index.js.map +1 -1
  132. package/dist/contexts/GustoProvider/GustoProviderCustomUIAdapter.d.ts +6 -0
  133. package/dist/contexts/GustoProvider/GustoProviderCustomUIAdapter.js +36 -34
  134. package/dist/contexts/GustoProvider/GustoProviderCustomUIAdapter.js.map +1 -1
  135. package/dist/contexts/UnstableFeaturesProvider/UnstableFeaturesProvider.d.ts +22 -0
  136. package/dist/contexts/UnstableFeaturesProvider/UnstableFeaturesProvider.js +14 -0
  137. package/dist/contexts/UnstableFeaturesProvider/UnstableFeaturesProvider.js.map +1 -0
  138. package/dist/contexts/UnstableFeaturesProvider/WithUnstableFeature.d.ts +19 -0
  139. package/dist/contexts/UnstableFeaturesProvider/WithUnstableFeature.js +8 -0
  140. package/dist/contexts/UnstableFeaturesProvider/WithUnstableFeature.js.map +1 -0
  141. package/dist/contexts/UnstableFeaturesProvider/useUnstableFeature.d.ts +41 -0
  142. package/dist/contexts/UnstableFeaturesProvider/useUnstableFeature.js +14 -0
  143. package/dist/contexts/UnstableFeaturesProvider/useUnstableFeature.js.map +1 -0
  144. package/dist/contexts/index.d.ts +1 -0
  145. package/dist/i18n/I18n.js +4 -0
  146. package/dist/i18n/I18n.js.map +1 -1
  147. package/dist/i18n/en/Contractor.Payments.CreateHistoricalPayment.json.js +34 -32
  148. package/dist/i18n/en/Contractor.Payments.CreateHistoricalPayment.json.js.map +1 -1
  149. package/dist/i18n/en/Contractor.Payments.PaymentsList.json.js +20 -18
  150. package/dist/i18n/en/Contractor.Payments.PaymentsList.json.js.map +1 -1
  151. package/dist/i18n/en/Payroll.PayrollConfiguration.json.js +9 -9
  152. package/dist/i18n/en/Payroll.PayrollOverview.json.js +38 -38
  153. package/dist/i18n/en/Payroll.PayrollReceipts.json.js +2 -2
  154. package/dist/i18n/en/Payroll.PrintChecksBanner.json.js +14 -0
  155. package/dist/i18n/en/Payroll.PrintChecksBanner.json.js.map +1 -0
  156. package/dist/i18n/en/Payroll.PrintChecksFailure.json.js +12 -0
  157. package/dist/i18n/en/Payroll.PrintChecksFailure.json.js.map +1 -0
  158. package/dist/i18n/en/Payroll.PrintChecksForm.json.js +28 -0
  159. package/dist/i18n/en/Payroll.PrintChecksForm.json.js.map +1 -0
  160. package/dist/i18n/en/Payroll.PrintChecksSummary.json.js +14 -0
  161. package/dist/i18n/en/Payroll.PrintChecksSummary.json.js.map +1 -0
  162. package/dist/i18n/en/common.json.d.ts +0 -21
  163. package/dist/i18n/types.d.ts +75 -9
  164. package/dist/models/external.d.ts +3 -0
  165. package/dist/partner-hook-utils/form/buildFormSchema.js +60 -54
  166. package/dist/partner-hook-utils/form/buildFormSchema.js.map +1 -1
  167. package/dist/shared/constants.d.ts +30 -0
  168. package/dist/shared/constants.js +62 -50
  169. package/dist/shared/constants.js.map +1 -1
  170. package/dist/style.css +1 -1
  171. package/dist/test-utils/renderWithProviders.d.ts +4 -1
  172. package/dist/test-utils/tableQueries.d.ts +9 -0
  173. package/docs/guides/endpoint-inventory.json +33 -0
  174. package/package.json +18 -18
@@ -3,6 +3,11 @@ export interface SelectContractorsProps {
3
3
  companyId: string;
4
4
  /** Called with the currently selected contractor ids whenever the selection changes. */
5
5
  onSelectionChange: (selectedIds: string[]) => void;
6
+ /**
7
+ * Seeds selection state on mount. Pass the caller's own previously-selected ids to survive
8
+ * this component unmounting and remounting (e.g. behind a "Back" button).
9
+ */
10
+ initialSelectedIds?: Iterable<string>;
6
11
  /** Overrides the default empty-state title shown when no contractors match. */
7
12
  emptyStateTitle?: string;
8
13
  /** Overrides the default empty-state description shown when no contractors match. */
@@ -16,4 +21,4 @@ export interface SelectContractorsProps {
16
21
  *
17
22
  * @internal
18
23
  */
19
- export declare function SelectContractors({ companyId, onSelectionChange, emptyStateTitle, emptyStateDescription, }: SelectContractorsProps): import("react").JSX.Element;
24
+ export declare function SelectContractors({ companyId, onSelectionChange, initialSelectedIds, emptyStateTitle, emptyStateDescription, }: SelectContractorsProps): import("react").JSX.Element;
@@ -1,23 +1,24 @@
1
1
  import { jsx as o } from "react/jsx-runtime";
2
- import { useMemo as i, useEffect as d } from "react";
3
- import { useSelectContractors as u } from "./useSelectContractors.js";
4
- import { SelectContractorsPresentation as m } from "./SelectContractorsPresentation.js";
2
+ import { useMemo as d, useEffect as u } from "react";
3
+ import { useSelectContractors as m } from "./useSelectContractors.js";
4
+ import { SelectContractorsPresentation as f } from "./SelectContractorsPresentation.js";
5
5
  import { BaseLayout as s } from "../../../Base/Base.js";
6
6
  import "../../../Base/useBase.js";
7
- function I({
7
+ function L({
8
8
  companyId: a,
9
9
  onSelectionChange: n,
10
- emptyStateTitle: c,
11
- emptyStateDescription: l
10
+ initialSelectedIds: c,
11
+ emptyStateTitle: l,
12
+ emptyStateDescription: i
12
13
  }) {
13
- const e = u(a), r = e.isLoading ? null : [...e.selectedIds].sort().join(","), t = i(
14
+ const e = m(a, c), r = e.isLoading ? null : [...e.selectedIds].sort().join(","), t = d(
14
15
  () => r === null ? null : r.split(",").filter(Boolean),
15
16
  [r]
16
17
  );
17
- return d(() => {
18
+ return u(() => {
18
19
  t !== null && n(t);
19
20
  }, [t, n]), e.isLoading ? /* @__PURE__ */ o(s, { isLoading: !0, error: e.errorHandling.errors }) : /* @__PURE__ */ o(s, { error: e.errorHandling.errors, children: /* @__PURE__ */ o(
20
- m,
21
+ f,
21
22
  {
22
23
  contractors: e.data.contractors,
23
24
  selectedIds: e.selectedIds,
@@ -28,12 +29,12 @@ function I({
28
29
  onSearchClear: e.actions.onSearchClear,
29
30
  pagination: e.pagination,
30
31
  isFetching: e.status.isFetching,
31
- emptyStateTitle: c,
32
- emptyStateDescription: l
32
+ emptyStateTitle: l,
33
+ emptyStateDescription: i
33
34
  }
34
35
  ) });
35
36
  }
36
37
  export {
37
- I as SelectContractors
38
+ L as SelectContractors
38
39
  };
39
40
  //# sourceMappingURL=SelectContractors.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"SelectContractors.js","sources":["../../../../../src/components/Contractor/shared/SelectContractors/SelectContractors.tsx"],"sourcesContent":["import { useEffect, useMemo } from 'react'\nimport { useSelectContractors } from './useSelectContractors'\nimport { SelectContractorsPresentation } from './SelectContractorsPresentation'\nimport { BaseLayout } from '@/components/Base'\n\n/** @internal */\nexport interface SelectContractorsProps {\n companyId: string\n /** Called with the currently selected contractor ids whenever the selection changes. */\n onSelectionChange: (selectedIds: string[]) => void\n /** Overrides the default empty-state title shown when no contractors match. */\n emptyStateTitle?: string\n /** Overrides the default empty-state description shown when no contractors match. */\n emptyStateDescription?: string\n}\n\n/**\n * Multi-select contractor table. Fetches and filters eligible contractors via\n * {@link useSelectContractors} and reports the current selection through\n * `onSelectionChange` rather than emitting an SDK event — the composing\n * screen is responsible for translating the selection into its own events.\n *\n * @internal\n */\nexport function SelectContractors({\n companyId,\n onSelectionChange,\n emptyStateTitle,\n emptyStateDescription,\n}: SelectContractorsProps) {\n const result = useSelectContractors(companyId)\n\n const selectedIdsKey = result.isLoading ? null : [...result.selectedIds].sort().join(',')\n\n const selectedIds = useMemo(\n () => (selectedIdsKey === null ? null : selectedIdsKey.split(',').filter(Boolean)),\n [selectedIdsKey],\n )\n\n useEffect(() => {\n if (selectedIds === null) return\n onSelectionChange(selectedIds)\n }, [selectedIds, onSelectionChange])\n\n if (result.isLoading) {\n return <BaseLayout isLoading error={result.errorHandling.errors} />\n }\n\n return (\n <BaseLayout error={result.errorHandling.errors}>\n <SelectContractorsPresentation\n contractors={result.data.contractors}\n selectedIds={result.selectedIds}\n searchValue={result.searchValue}\n onSelect={result.actions.onSelect}\n onSelectAll={result.actions.onSelectAll}\n onSearchChange={result.actions.onSearchChange}\n onSearchClear={result.actions.onSearchClear}\n pagination={result.pagination}\n isFetching={result.status.isFetching}\n emptyStateTitle={emptyStateTitle}\n emptyStateDescription={emptyStateDescription}\n />\n </BaseLayout>\n )\n}\n"],"names":["SelectContractors","companyId","onSelectionChange","emptyStateTitle","emptyStateDescription","result","useSelectContractors","selectedIdsKey","selectedIds","useMemo","useEffect","BaseLayout","jsx","SelectContractorsPresentation"],"mappings":";;;;;;AAwBO,SAASA,EAAkB;AAAA,EAChC,WAAAC;AAAA,EACA,mBAAAC;AAAA,EACA,iBAAAC;AAAA,EACA,uBAAAC;AACF,GAA2B;AACzB,QAAMC,IAASC,EAAqBL,CAAS,GAEvCM,IAAiBF,EAAO,YAAY,OAAO,CAAC,GAAGA,EAAO,WAAW,EAAE,OAAO,KAAK,GAAG,GAElFG,IAAcC;AAAA,IAClB,MAAOF,MAAmB,OAAO,OAAOA,EAAe,MAAM,GAAG,EAAE,OAAO,OAAO;AAAA,IAChF,CAACA,CAAc;AAAA,EAAA;AAQjB,SALAG,EAAU,MAAM;AACd,IAAIF,MAAgB,QACpBN,EAAkBM,CAAW;AAAA,EAC/B,GAAG,CAACA,GAAaN,CAAiB,CAAC,GAE/BG,EAAO,8BACDM,GAAA,EAAW,WAAS,IAAC,OAAON,EAAO,cAAc,QAAQ,IAIjE,gBAAAO,EAACD,GAAA,EAAW,OAAON,EAAO,cAAc,QACtC,UAAA,gBAAAO;AAAA,IAACC;AAAA,IAAA;AAAA,MACC,aAAaR,EAAO,KAAK;AAAA,MACzB,aAAaA,EAAO;AAAA,MACpB,aAAaA,EAAO;AAAA,MACpB,UAAUA,EAAO,QAAQ;AAAA,MACzB,aAAaA,EAAO,QAAQ;AAAA,MAC5B,gBAAgBA,EAAO,QAAQ;AAAA,MAC/B,eAAeA,EAAO,QAAQ;AAAA,MAC9B,YAAYA,EAAO;AAAA,MACnB,YAAYA,EAAO,OAAO;AAAA,MAC1B,iBAAAF;AAAA,MACA,uBAAAC;AAAA,IAAA;AAAA,EAAA,GAEJ;AAEJ;"}
1
+ {"version":3,"file":"SelectContractors.js","sources":["../../../../../src/components/Contractor/shared/SelectContractors/SelectContractors.tsx"],"sourcesContent":["import { useEffect, useMemo } from 'react'\nimport { useSelectContractors } from './useSelectContractors'\nimport { SelectContractorsPresentation } from './SelectContractorsPresentation'\nimport { BaseLayout } from '@/components/Base'\n\n/** @internal */\nexport interface SelectContractorsProps {\n companyId: string\n /** Called with the currently selected contractor ids whenever the selection changes. */\n onSelectionChange: (selectedIds: string[]) => void\n /**\n * Seeds selection state on mount. Pass the caller's own previously-selected ids to survive\n * this component unmounting and remounting (e.g. behind a \"Back\" button).\n */\n initialSelectedIds?: Iterable<string>\n /** Overrides the default empty-state title shown when no contractors match. */\n emptyStateTitle?: string\n /** Overrides the default empty-state description shown when no contractors match. */\n emptyStateDescription?: string\n}\n\n/**\n * Multi-select contractor table. Fetches and filters eligible contractors via\n * {@link useSelectContractors} and reports the current selection through\n * `onSelectionChange` rather than emitting an SDK event — the composing\n * screen is responsible for translating the selection into its own events.\n *\n * @internal\n */\nexport function SelectContractors({\n companyId,\n onSelectionChange,\n initialSelectedIds,\n emptyStateTitle,\n emptyStateDescription,\n}: SelectContractorsProps) {\n const result = useSelectContractors(companyId, initialSelectedIds)\n\n const selectedIdsKey = result.isLoading ? null : [...result.selectedIds].sort().join(',')\n\n const selectedIds = useMemo(\n () => (selectedIdsKey === null ? null : selectedIdsKey.split(',').filter(Boolean)),\n [selectedIdsKey],\n )\n\n useEffect(() => {\n if (selectedIds === null) return\n onSelectionChange(selectedIds)\n }, [selectedIds, onSelectionChange])\n\n if (result.isLoading) {\n return <BaseLayout isLoading error={result.errorHandling.errors} />\n }\n\n return (\n <BaseLayout error={result.errorHandling.errors}>\n <SelectContractorsPresentation\n contractors={result.data.contractors}\n selectedIds={result.selectedIds}\n searchValue={result.searchValue}\n onSelect={result.actions.onSelect}\n onSelectAll={result.actions.onSelectAll}\n onSearchChange={result.actions.onSearchChange}\n onSearchClear={result.actions.onSearchClear}\n pagination={result.pagination}\n isFetching={result.status.isFetching}\n emptyStateTitle={emptyStateTitle}\n emptyStateDescription={emptyStateDescription}\n />\n </BaseLayout>\n )\n}\n"],"names":["SelectContractors","companyId","onSelectionChange","initialSelectedIds","emptyStateTitle","emptyStateDescription","result","useSelectContractors","selectedIdsKey","selectedIds","useMemo","useEffect","BaseLayout","jsx","SelectContractorsPresentation"],"mappings":";;;;;;AA6BO,SAASA,EAAkB;AAAA,EAChC,WAAAC;AAAA,EACA,mBAAAC;AAAA,EACA,oBAAAC;AAAA,EACA,iBAAAC;AAAA,EACA,uBAAAC;AACF,GAA2B;AACzB,QAAMC,IAASC,EAAqBN,GAAWE,CAAkB,GAE3DK,IAAiBF,EAAO,YAAY,OAAO,CAAC,GAAGA,EAAO,WAAW,EAAE,OAAO,KAAK,GAAG,GAElFG,IAAcC;AAAA,IAClB,MAAOF,MAAmB,OAAO,OAAOA,EAAe,MAAM,GAAG,EAAE,OAAO,OAAO;AAAA,IAChF,CAACA,CAAc;AAAA,EAAA;AAQjB,SALAG,EAAU,MAAM;AACd,IAAIF,MAAgB,QACpBP,EAAkBO,CAAW;AAAA,EAC/B,GAAG,CAACA,GAAaP,CAAiB,CAAC,GAE/BI,EAAO,8BACDM,GAAA,EAAW,WAAS,IAAC,OAAON,EAAO,cAAc,QAAQ,IAIjE,gBAAAO,EAACD,GAAA,EAAW,OAAON,EAAO,cAAc,QACtC,UAAA,gBAAAO;AAAA,IAACC;AAAA,IAAA;AAAA,MACC,aAAaR,EAAO,KAAK;AAAA,MACzB,aAAaA,EAAO;AAAA,MACpB,aAAaA,EAAO;AAAA,MACpB,UAAUA,EAAO,QAAQ;AAAA,MACzB,aAAaA,EAAO,QAAQ;AAAA,MAC5B,gBAAgBA,EAAO,QAAQ;AAAA,MAC/B,eAAeA,EAAO,QAAQ;AAAA,MAC9B,YAAYA,EAAO;AAAA,MACnB,YAAYA,EAAO,OAAO;AAAA,MAC1B,iBAAAF;AAAA,MACA,uBAAAC;AAAA,IAAA;AAAA,EAAA,GAEJ;AAEJ;"}
@@ -53,6 +53,10 @@ export type UseSelectContractorsResult = HookLoadingResult | UseSelectContractor
53
53
  * all pages, not just the current page slice — "select all" means every
54
54
  * matching contractor, including ones scrolled off-screen.
55
55
  *
56
+ * `initialSelectedIds` seeds selection state and is only read on mount. Pass the caller's own
57
+ * previously-selected ids here to survive an unmount/remount (e.g. a "Back" button that swaps
58
+ * this component out for another screen and back).
59
+ *
56
60
  * @internal
57
61
  */
58
- export declare function useSelectContractors(companyId: string): UseSelectContractorsResult;
62
+ export declare function useSelectContractors(companyId: string, initialSelectedIds?: Iterable<string>): UseSelectContractorsResult;
@@ -1,49 +1,51 @@
1
- import { useState as y, useMemo as I, useCallback as C } from "react";
2
- import { useContractorsList as _, buildContractorsListQuery as N } from "@gusto/embedded-api/react-query/contractorsList";
3
- import { useGustoEmbeddedContext as O } from "@gusto/embedded-api/react-query/_context";
4
- import { useQueries as v } from "@tanstack/react-query";
5
- import { useClientPagination as D } from "../../../../hooks/useClientPagination/useClientPagination.js";
6
- import { composeErrorHandler as G } from "../../../../partner-hook-utils/composeErrorHandler.js";
7
- import { ContractorOnboardingStatus as Q } from "../../../../shared/constants.js";
8
- import { getContractorDisplayName as H } from "../helpers.js";
1
+ import { useState as I, useMemo as _, useCallback as C } from "react";
2
+ import { useContractorsList as N, buildContractorsListQuery as O } from "@gusto/embedded-api/react-query/contractorsList";
3
+ import { useGustoEmbeddedContext as v } from "@gusto/embedded-api/react-query/_context";
4
+ import { useQueries as D } from "@tanstack/react-query";
5
+ import { useClientPagination as G } from "../../../../hooks/useClientPagination/useClientPagination.js";
6
+ import { composeErrorHandler as Q } from "../../../../partner-hook-utils/composeErrorHandler.js";
7
+ import { ContractorOnboardingStatus as H } from "../../../../shared/constants.js";
8
+ import { getContractorDisplayName as U } from "../helpers.js";
9
9
  const h = 100;
10
- function U(e) {
11
- return e.isActive && e.onboardingStatus === Q.ONBOARDING_COMPLETED;
10
+ function V(e) {
11
+ return e.isActive && e.onboardingStatus === H.ONBOARDING_COMPLETED;
12
12
  }
13
13
  function S(e, u) {
14
- return H(e).toLowerCase().includes(u.toLowerCase());
14
+ return U(e).toLowerCase().includes(u.toLowerCase());
15
15
  }
16
- function J(e) {
17
- const u = O(), [P, l] = y(() => /* @__PURE__ */ new Set()), d = _({
16
+ function K(e, u) {
17
+ const P = v(), [b, l] = I(
18
+ () => new Set(u)
19
+ ), d = N({
18
20
  companyUuid: e,
19
21
  page: 1,
20
22
  per: h
21
- }), { data: n, isFetching: g } = d, b = Number(n?.httpMeta.response.headers.get("x-total-pages") ?? 1), a = v({
22
- queries: Array.from({ length: Math.max(0, b - 1) }, (t, o) => ({
23
- ...N(u, {
23
+ }), { data: n, isFetching: g } = d, w = Number(n?.httpMeta.response.headers.get("x-total-pages") ?? 1), a = D({
24
+ queries: Array.from({ length: Math.max(0, w - 1) }, (t, o) => ({
25
+ ...O(P, {
24
26
  companyUuid: e,
25
27
  page: o + 2,
26
28
  per: h
27
29
  }),
28
30
  enabled: !!n
29
31
  }))
30
- }), w = !n && g || a.some((t) => !t.data && t.isFetching), m = G([d, ...a]), s = I(() => n ? [
32
+ }), E = !n && g || a.some((t) => !t.data && t.isFetching), m = Q([d, ...a]), s = _(() => n ? [
31
33
  ...n.contractors ?? [],
32
34
  ...a.flatMap((o) => o.data?.contractors ?? [])
33
- ].filter(U) : [], [n, a]), {
34
- data: E,
35
- pagination: L,
35
+ ].filter(V) : [], [n, a]), {
36
+ data: L,
37
+ pagination: A,
36
38
  searchValue: c,
37
39
  actions: f
38
- } = D(s, {
40
+ } = G(s, {
39
41
  searchPredicate: S,
40
42
  defaultItemsPerPage: 25
41
- }), A = g || a.some((t) => t.isFetching), x = new Set(s.map((t) => t.uuid)), F = new Set([...P].filter((t) => x.has(t))), M = C((t, o) => {
43
+ }), x = g || a.some((t) => t.isFetching), F = new Set(s.map((t) => t.uuid)), M = new Set([...b].filter((t) => F.has(t))), R = C((t, o) => {
42
44
  l((i) => {
43
45
  const r = new Set(i);
44
46
  return o ? r.add(t.uuid) : r.delete(t.uuid), r;
45
47
  });
46
- }, []), R = C(
48
+ }, []), y = C(
47
49
  (t) => {
48
50
  const o = c ? s.filter((i) => S(i, c)) : s;
49
51
  l((i) => {
@@ -55,20 +57,20 @@ function J(e) {
55
57
  },
56
58
  [s, c]
57
59
  );
58
- return w ? {
60
+ return E ? {
59
61
  isLoading: !0,
60
62
  errorHandling: m
61
63
  } : {
62
64
  isLoading: !1,
63
- data: { contractors: E },
64
- status: { isFetching: A },
65
+ data: { contractors: L },
66
+ status: { isFetching: x },
65
67
  eligibleCount: s.length,
66
- selectedIds: F,
67
- pagination: L,
68
+ selectedIds: M,
69
+ pagination: A,
68
70
  searchValue: c,
69
71
  actions: {
70
- onSelect: M,
71
- onSelectAll: R,
72
+ onSelect: R,
73
+ onSelectAll: y,
72
74
  onSearchChange: f.onSearchChange,
73
75
  onSearchClear: f.onSearchClear
74
76
  },
@@ -76,7 +78,7 @@ function J(e) {
76
78
  };
77
79
  }
78
80
  export {
79
- U as isEligibleContractor,
80
- J as useSelectContractors
81
+ V as isEligibleContractor,
82
+ K as useSelectContractors
81
83
  };
82
84
  //# sourceMappingURL=useSelectContractors.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"useSelectContractors.js","sources":["../../../../../src/components/Contractor/shared/SelectContractors/useSelectContractors.ts"],"sourcesContent":["import { useCallback, useMemo, useState } from 'react'\nimport {\n buildContractorsListQuery,\n useContractorsList,\n} from '@gusto/embedded-api/react-query/contractorsList'\nimport { useGustoEmbeddedContext } from '@gusto/embedded-api/react-query/_context'\nimport { useQueries } from '@tanstack/react-query'\nimport type { Contractor } from '@gusto/embedded-api/models/components/contractor'\nimport { useClientPagination } from '@/hooks/useClientPagination/useClientPagination'\nimport { composeErrorHandler } from '@/partner-hook-utils/composeErrorHandler'\nimport { ContractorOnboardingStatus } from '@/shared/constants'\nimport type { HookLoadingResult, BaseHookReady } from '@/partner-hook-utils/types'\nimport type { PaginationControlProps } from '@/components/Common/PaginationControl/PaginationControlTypes'\nimport { getContractorDisplayName } from '@/components/Contractor/shared/helpers'\n\nconst SERVER_MAX_PER_PAGE = 100\n\n/** @internal */\nexport function isEligibleContractor(contractor: Contractor): boolean {\n return (\n contractor.isActive &&\n contractor.onboardingStatus === ContractorOnboardingStatus.ONBOARDING_COMPLETED\n )\n}\n\nfunction matchesContractorSearch(contractor: Contractor, query: string): boolean {\n return getContractorDisplayName(contractor).toLowerCase().includes(query.toLowerCase())\n}\n\n/**\n * Ready state of {@link useSelectContractors}.\n *\n * @internal\n */\nexport interface UseSelectContractorsReady extends BaseHookReady<\n { contractors: Contractor[] },\n { isFetching: boolean }\n> {\n /**\n * Count of eligible (active + onboarded) contractors across every page.\n * Unaffected by the current search — see `pagination.totalCount` for the\n * eligible-and-search-matching count instead.\n */\n eligibleCount: number\n /**\n * Currently selected contractor uuids. Always a subset of the current\n * eligible contractors: uuids for contractors that become ineligible or\n * disappear from the list on a refetch are dropped automatically.\n */\n selectedIds: Set<string>\n /** Pagination controls for the client-paginated, search-filtered contractor list. */\n pagination: PaginationControlProps\n /** Current search value. */\n searchValue: string\n /** Selection and search actions. */\n actions: {\n /** Selects or deselects a single contractor. */\n onSelect: (contractor: Contractor, checked: boolean) => void\n /** Selects or deselects every eligible contractor in the current search scope, across all pages. */\n onSelectAll: (checked: boolean) => void\n /** Updates the search value. */\n onSearchChange: (value: string) => void\n /** Clears the search value. */\n onSearchClear: () => void\n }\n}\n\n/** @internal */\nexport type UseSelectContractorsResult = HookLoadingResult | UseSelectContractorsReady\n\n/**\n * Fetches every contractor page up front, filters to active + onboarded\n * contractors, and owns client-side pagination, search, and selection state\n * over the result.\n *\n * @remarks\n * `actions.onSelectAll` scopes to the full eligible, search-filtered list across\n * all pages, not just the current page slice — \"select all\" means every\n * matching contractor, including ones scrolled off-screen.\n *\n * @internal\n */\nexport function useSelectContractors(companyId: string): UseSelectContractorsResult {\n const gustoClient = useGustoEmbeddedContext()\n const [rawSelectedIds, setRawSelectedIds] = useState<Set<string>>(() => new Set())\n\n const firstPageQuery = useContractorsList({\n companyUuid: companyId,\n page: 1,\n per: SERVER_MAX_PER_PAGE,\n })\n const { data: firstPage, isFetching: isFirstPageFetching } = firstPageQuery\n\n const totalServerPages = Number(firstPage?.httpMeta.response.headers.get('x-total-pages') ?? 1)\n\n // No explicit concurrency cap: typical embedded customers are <100\n // contractors (one server page, zero extra requests). For larger companies\n // the browser's per-origin connection limit (~6) acts as the natural\n // ceiling. If this ever needs to support thousands of contractors,\n // reconsider — either a server-side eligibility filter or a paginated\n // fetch-as-you-scroll strategy would be the right escape hatches.\n const restPageResults = useQueries({\n queries: Array.from({ length: Math.max(0, totalServerPages - 1) }, (_, i) => ({\n ...buildContractorsListQuery(gustoClient, {\n companyUuid: companyId,\n page: i + 2,\n per: SERVER_MAX_PER_PAGE,\n }),\n enabled: !!firstPage,\n })),\n })\n\n const isLoading =\n (!firstPage && isFirstPageFetching) || restPageResults.some(r => !r.data && r.isFetching)\n\n const errorHandling = composeErrorHandler([firstPageQuery, ...restPageResults])\n\n const eligibleContractors = useMemo<Contractor[]>(() => {\n if (!firstPage) return []\n const contractors = [\n ...(firstPage.contractors ?? []),\n ...restPageResults.flatMap(r => r.data?.contractors ?? []),\n ]\n return contractors.filter(isEligibleContractor)\n }, [firstPage, restPageResults])\n\n const {\n data: filteredContractors,\n pagination,\n searchValue,\n actions: paginationActions,\n } = useClientPagination(eligibleContractors, {\n searchPredicate: matchesContractorSearch,\n defaultItemsPerPage: 25,\n })\n\n const isFetching = isFirstPageFetching || restPageResults.some(r => r.isFetching)\n\n const validContractorIds = new Set(eligibleContractors.map(contractor => contractor.uuid))\n const selectedIds = new Set([...rawSelectedIds].filter(uuid => validContractorIds.has(uuid)))\n\n const onSelect = useCallback((contractor: Contractor, checked: boolean) => {\n setRawSelectedIds(prev => {\n const next = new Set(prev)\n if (checked) next.add(contractor.uuid)\n else next.delete(contractor.uuid)\n return next\n })\n }, [])\n\n const onSelectAll = useCallback(\n (checked: boolean) => {\n const scope = searchValue\n ? eligibleContractors.filter(contractor => matchesContractorSearch(contractor, searchValue))\n : eligibleContractors\n setRawSelectedIds(prev => {\n const next = new Set(prev)\n for (const contractor of scope) {\n if (checked) next.add(contractor.uuid)\n else next.delete(contractor.uuid)\n }\n return next\n })\n },\n [eligibleContractors, searchValue],\n )\n\n if (isLoading) {\n return {\n isLoading: true,\n errorHandling,\n }\n }\n\n return {\n isLoading: false,\n data: { contractors: filteredContractors },\n status: { isFetching },\n eligibleCount: eligibleContractors.length,\n selectedIds,\n pagination,\n searchValue,\n actions: {\n onSelect,\n onSelectAll,\n onSearchChange: paginationActions.onSearchChange,\n onSearchClear: paginationActions.onSearchClear,\n },\n errorHandling,\n }\n}\n"],"names":["SERVER_MAX_PER_PAGE","isEligibleContractor","contractor","ContractorOnboardingStatus","matchesContractorSearch","query","getContractorDisplayName","useSelectContractors","companyId","gustoClient","useGustoEmbeddedContext","rawSelectedIds","setRawSelectedIds","useState","firstPageQuery","useContractorsList","firstPage","isFirstPageFetching","totalServerPages","restPageResults","useQueries","_","i","buildContractorsListQuery","isLoading","r","errorHandling","composeErrorHandler","eligibleContractors","useMemo","filteredContractors","pagination","searchValue","paginationActions","useClientPagination","isFetching","validContractorIds","selectedIds","uuid","onSelect","useCallback","checked","prev","next","onSelectAll","scope"],"mappings":"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"}
1
+ {"version":3,"file":"useSelectContractors.js","sources":["../../../../../src/components/Contractor/shared/SelectContractors/useSelectContractors.ts"],"sourcesContent":["import { useCallback, useMemo, useState } from 'react'\nimport {\n buildContractorsListQuery,\n useContractorsList,\n} from '@gusto/embedded-api/react-query/contractorsList'\nimport { useGustoEmbeddedContext } from '@gusto/embedded-api/react-query/_context'\nimport { useQueries } from '@tanstack/react-query'\nimport type { Contractor } from '@gusto/embedded-api/models/components/contractor'\nimport { useClientPagination } from '@/hooks/useClientPagination/useClientPagination'\nimport { composeErrorHandler } from '@/partner-hook-utils/composeErrorHandler'\nimport { ContractorOnboardingStatus } from '@/shared/constants'\nimport type { HookLoadingResult, BaseHookReady } from '@/partner-hook-utils/types'\nimport type { PaginationControlProps } from '@/components/Common/PaginationControl/PaginationControlTypes'\nimport { getContractorDisplayName } from '@/components/Contractor/shared/helpers'\n\nconst SERVER_MAX_PER_PAGE = 100\n\n/** @internal */\nexport function isEligibleContractor(contractor: Contractor): boolean {\n return (\n contractor.isActive &&\n contractor.onboardingStatus === ContractorOnboardingStatus.ONBOARDING_COMPLETED\n )\n}\n\nfunction matchesContractorSearch(contractor: Contractor, query: string): boolean {\n return getContractorDisplayName(contractor).toLowerCase().includes(query.toLowerCase())\n}\n\n/**\n * Ready state of {@link useSelectContractors}.\n *\n * @internal\n */\nexport interface UseSelectContractorsReady extends BaseHookReady<\n { contractors: Contractor[] },\n { isFetching: boolean }\n> {\n /**\n * Count of eligible (active + onboarded) contractors across every page.\n * Unaffected by the current search — see `pagination.totalCount` for the\n * eligible-and-search-matching count instead.\n */\n eligibleCount: number\n /**\n * Currently selected contractor uuids. Always a subset of the current\n * eligible contractors: uuids for contractors that become ineligible or\n * disappear from the list on a refetch are dropped automatically.\n */\n selectedIds: Set<string>\n /** Pagination controls for the client-paginated, search-filtered contractor list. */\n pagination: PaginationControlProps\n /** Current search value. */\n searchValue: string\n /** Selection and search actions. */\n actions: {\n /** Selects or deselects a single contractor. */\n onSelect: (contractor: Contractor, checked: boolean) => void\n /** Selects or deselects every eligible contractor in the current search scope, across all pages. */\n onSelectAll: (checked: boolean) => void\n /** Updates the search value. */\n onSearchChange: (value: string) => void\n /** Clears the search value. */\n onSearchClear: () => void\n }\n}\n\n/** @internal */\nexport type UseSelectContractorsResult = HookLoadingResult | UseSelectContractorsReady\n\n/**\n * Fetches every contractor page up front, filters to active + onboarded\n * contractors, and owns client-side pagination, search, and selection state\n * over the result.\n *\n * @remarks\n * `actions.onSelectAll` scopes to the full eligible, search-filtered list across\n * all pages, not just the current page slice — \"select all\" means every\n * matching contractor, including ones scrolled off-screen.\n *\n * `initialSelectedIds` seeds selection state and is only read on mount. Pass the caller's own\n * previously-selected ids here to survive an unmount/remount (e.g. a \"Back\" button that swaps\n * this component out for another screen and back).\n *\n * @internal\n */\nexport function useSelectContractors(\n companyId: string,\n initialSelectedIds?: Iterable<string>,\n): UseSelectContractorsResult {\n const gustoClient = useGustoEmbeddedContext()\n const [rawSelectedIds, setRawSelectedIds] = useState<Set<string>>(\n () => new Set(initialSelectedIds),\n )\n\n const firstPageQuery = useContractorsList({\n companyUuid: companyId,\n page: 1,\n per: SERVER_MAX_PER_PAGE,\n })\n const { data: firstPage, isFetching: isFirstPageFetching } = firstPageQuery\n\n const totalServerPages = Number(firstPage?.httpMeta.response.headers.get('x-total-pages') ?? 1)\n\n // No explicit concurrency cap: typical embedded customers are <100\n // contractors (one server page, zero extra requests). For larger companies\n // the browser's per-origin connection limit (~6) acts as the natural\n // ceiling. If this ever needs to support thousands of contractors,\n // reconsider — either a server-side eligibility filter or a paginated\n // fetch-as-you-scroll strategy would be the right escape hatches.\n const restPageResults = useQueries({\n queries: Array.from({ length: Math.max(0, totalServerPages - 1) }, (_, i) => ({\n ...buildContractorsListQuery(gustoClient, {\n companyUuid: companyId,\n page: i + 2,\n per: SERVER_MAX_PER_PAGE,\n }),\n enabled: !!firstPage,\n })),\n })\n\n const isLoading =\n (!firstPage && isFirstPageFetching) || restPageResults.some(r => !r.data && r.isFetching)\n\n const errorHandling = composeErrorHandler([firstPageQuery, ...restPageResults])\n\n const eligibleContractors = useMemo<Contractor[]>(() => {\n if (!firstPage) return []\n const contractors = [\n ...(firstPage.contractors ?? []),\n ...restPageResults.flatMap(r => r.data?.contractors ?? []),\n ]\n return contractors.filter(isEligibleContractor)\n }, [firstPage, restPageResults])\n\n const {\n data: filteredContractors,\n pagination,\n searchValue,\n actions: paginationActions,\n } = useClientPagination(eligibleContractors, {\n searchPredicate: matchesContractorSearch,\n defaultItemsPerPage: 25,\n })\n\n const isFetching = isFirstPageFetching || restPageResults.some(r => r.isFetching)\n\n const validContractorIds = new Set(eligibleContractors.map(contractor => contractor.uuid))\n const selectedIds = new Set([...rawSelectedIds].filter(uuid => validContractorIds.has(uuid)))\n\n const onSelect = useCallback((contractor: Contractor, checked: boolean) => {\n setRawSelectedIds(prev => {\n const next = new Set(prev)\n if (checked) next.add(contractor.uuid)\n else next.delete(contractor.uuid)\n return next\n })\n }, [])\n\n const onSelectAll = useCallback(\n (checked: boolean) => {\n const scope = searchValue\n ? eligibleContractors.filter(contractor => matchesContractorSearch(contractor, searchValue))\n : eligibleContractors\n setRawSelectedIds(prev => {\n const next = new Set(prev)\n for (const contractor of scope) {\n if (checked) next.add(contractor.uuid)\n else next.delete(contractor.uuid)\n }\n return next\n })\n },\n [eligibleContractors, searchValue],\n )\n\n if (isLoading) {\n return {\n isLoading: true,\n errorHandling,\n }\n }\n\n return {\n isLoading: false,\n data: { contractors: filteredContractors },\n status: { isFetching },\n eligibleCount: eligibleContractors.length,\n selectedIds,\n pagination,\n searchValue,\n actions: {\n onSelect,\n onSelectAll,\n onSearchChange: paginationActions.onSearchChange,\n onSearchClear: paginationActions.onSearchClear,\n },\n errorHandling,\n }\n}\n"],"names":["SERVER_MAX_PER_PAGE","isEligibleContractor","contractor","ContractorOnboardingStatus","matchesContractorSearch","query","getContractorDisplayName","useSelectContractors","companyId","initialSelectedIds","gustoClient","useGustoEmbeddedContext","rawSelectedIds","setRawSelectedIds","useState","firstPageQuery","useContractorsList","firstPage","isFirstPageFetching","totalServerPages","restPageResults","useQueries","_","i","buildContractorsListQuery","isLoading","r","errorHandling","composeErrorHandler","eligibleContractors","useMemo","filteredContractors","pagination","searchValue","paginationActions","useClientPagination","isFetching","validContractorIds","selectedIds","uuid","onSelect","useCallback","checked","prev","next","onSelectAll","scope"],"mappings":"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"}
@@ -19,6 +19,12 @@ export interface PayrollConfigurationProps extends BaseComponentInterface<'Payro
19
19
  * Handles the configuration phase of payroll processing, allowing users to review and modify employee compensation before calculating the payroll.
20
20
  *
21
21
  * @remarks
22
+ * If the payroll turns out to already be processed (e.g. another actor submitted it while this
23
+ * screen was open), this component emits `runPayroll/alreadyProcessed` and then renders
24
+ * {@link PayrollOverview} in its place — the read-only breakdown with the gated "Cancel payroll"
25
+ * action — instead of the configuration table. Events from that delegated view (e.g.
26
+ * `runPayroll/cancelled`) are emitted through this component's own `onEvent`.
27
+ *
22
28
  * Emits the following events:
23
29
  *
24
30
  * @events
@@ -28,6 +34,7 @@ export interface PayrollConfigurationProps extends BaseComponentInterface<'Payro
28
34
  * | `runPayroll/employee/skip` | An employee is skipped or unskipped for this payroll | `{ employeeId }` |
29
35
  * | `runPayroll/employee/saved` | Employee compensation changes are persisted | `{ payrollPrepared }` |
30
36
  * | `runPayroll/calculated` | Payroll calculation completes successfully | `{ payrollId, alert, payPeriod }` |
37
+ * | `runPayroll/alreadyProcessed` | The payroll turns out to already be processed while configuring it | `{ payrollId, alert, payPeriod }` |
31
38
  * | `runPayroll/processingFailed` | Payroll calculation fails or times out | — |
32
39
  * | `runPayroll/blockers/viewAll` | The "view all blockers" affordance is selected | — |
33
40
  * | `runPayroll/grossUp/selected` | The set-net-earnings menu item is selected for an employee | `{ employeeUuid }` |