@vtex/faststore-plugin-buyer-portal 2.0.7 → 2.0.9

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 (113) hide show
  1. package/.github/workflows/release.yaml +4 -4
  2. package/AGENTS.md +6 -0
  3. package/CHANGELOG.md +30 -1
  4. package/docs/superpowers/plans/2026-06-26-contracts-listing-selection-search-pagination.md +1070 -0
  5. package/docs/superpowers/specs/2026-06-26-contracts-listing-selection-search-pagination-design.md +157 -0
  6. package/package.json +1 -1
  7. package/plugin.config.js +8 -0
  8. package/public/buyer-portal-icons.svg +37 -1
  9. package/specs/001-suma-phase-2/checklists/requirements.md +36 -0
  10. package/specs/001-suma-phase-2/contracts/contracts-api.md +187 -0
  11. package/specs/001-suma-phase-2/contracts/feature-flag.md +91 -0
  12. package/specs/001-suma-phase-2/data-model.md +119 -0
  13. package/specs/001-suma-phase-2/plan.md +123 -0
  14. package/specs/001-suma-phase-2/quickstart.md +156 -0
  15. package/specs/001-suma-phase-2/research.md +150 -0
  16. package/specs/001-suma-phase-2/spec.md +186 -0
  17. package/specs/001-suma-phase-2/tasks.md +253 -0
  18. package/specs/suma-add-contracts.md +224 -0
  19. package/specs/suma-contract-listing.md +295 -0
  20. package/specs/suma-contract-switching.md +201 -0
  21. package/specs/suma-remove-contracts.md +233 -0
  22. package/specs/suma-set-default-contract.md +208 -0
  23. package/src/features/budgets/layouts/BudgetsLayout/BudgetsLayout.tsx +113 -105
  24. package/src/features/buying-policies/components/BasicBuyingPolicyDrawer/BasicBuyingPolicyDrawer.tsx +2 -2
  25. package/src/features/buying-policies/layouts/BuyingPoliciesLayout/BuyingPoliciesLayout.tsx +60 -46
  26. package/src/features/contracts/clients/ContractsClient.ts +45 -0
  27. package/src/features/contracts/components/AddContractsDrawer/AddContractsDrawer.tsx +323 -0
  28. package/src/features/contracts/components/AddContractsDrawer/add-contracts-drawer.scss +282 -0
  29. package/src/features/contracts/components/ConfirmRemoveDrawer/ConfirmRemoveDrawer.tsx +58 -0
  30. package/src/features/contracts/components/ConfirmRemoveDrawer/confirm-remove-drawer.scss +18 -0
  31. package/src/features/contracts/components/ContractListItem/ContractListItem.tsx +120 -0
  32. package/src/features/contracts/components/ContractSelectAllRow/ContractSelectAllRow.tsx +37 -0
  33. package/src/features/contracts/components/ContractSelectAllRow/index.ts +2 -0
  34. package/src/features/contracts/components/ContractSelectionBar/ContractSelectionBar.tsx +47 -0
  35. package/src/features/contracts/components/ContractSelectionBar/index.ts +2 -0
  36. package/src/features/contracts/components/ContractSelectionList/ContractSelectionList.tsx +55 -0
  37. package/src/features/contracts/components/ContractSwitchOverlay/ContractSwitchOverlay.tsx +36 -0
  38. package/src/features/contracts/components/ContractSwitchOverlay/contract-switch-overlay.scss +7 -0
  39. package/src/features/contracts/components/ContractsListHeader/ContractsListHeader.tsx +58 -0
  40. package/src/features/contracts/components/ContractsListHeader/index.ts +2 -0
  41. package/src/features/contracts/components/ErrorRemoveDrawer/ErrorRemoveDrawer.tsx +69 -0
  42. package/src/features/contracts/components/UnableToRemoveContractsDrawer/UnableToRemoveContractsDrawer.tsx +52 -0
  43. package/src/features/contracts/components/UnableToRemoveContractsDrawer/unable-to-remove-contracts-drawer.scss +29 -0
  44. package/src/features/contracts/components/index.ts +14 -0
  45. package/src/features/contracts/hooks/__tests__/contractListingHelpers.test.ts +71 -0
  46. package/src/features/contracts/hooks/__tests__/contractSwitchChannelHelpers.test.ts +32 -0
  47. package/src/features/contracts/hooks/__tests__/useAddContracts.test.ts +63 -0
  48. package/src/features/contracts/hooks/__tests__/useContractSelection.test.ts +72 -0
  49. package/src/features/contracts/hooks/__tests__/useRemoveContracts.test.ts +130 -0
  50. package/src/features/contracts/hooks/__tests__/useSetDefaultContract.test.ts +82 -0
  51. package/src/features/contracts/hooks/contractListingHelpers.ts +45 -0
  52. package/src/features/contracts/hooks/contractSelectionHelpers.ts +28 -0
  53. package/src/features/contracts/hooks/contractSwitchChannelHelpers.ts +9 -0
  54. package/src/features/contracts/hooks/index.ts +19 -0
  55. package/src/features/contracts/hooks/useAddContracts.ts +27 -0
  56. package/src/features/contracts/hooks/useContractListing.ts +71 -0
  57. package/src/features/contracts/hooks/useContractSelection.ts +53 -0
  58. package/src/features/contracts/hooks/useContractSwitchChannel.ts +49 -0
  59. package/src/features/contracts/hooks/useListAvailableContracts.ts +27 -0
  60. package/src/features/contracts/hooks/useRemoveContracts.ts +21 -0
  61. package/src/features/contracts/hooks/useSetDefaultContract.ts +21 -0
  62. package/src/features/contracts/hooks/useSwitchContract.ts +76 -0
  63. package/src/features/contracts/layouts/ContractInformationLayout/ContractInformationLayout.tsx +316 -0
  64. package/src/features/contracts/layouts/ContractListingLayout/ContractListingLayout.tsx +415 -0
  65. package/src/features/contracts/layouts/ContractListingLayout/ContractSettingsNav.tsx +83 -0
  66. package/src/features/contracts/layouts/ContractListingLayout/contract-listing-layout.scss +468 -0
  67. package/src/features/contracts/layouts/ContractListingLayout/utils.ts +4 -0
  68. package/src/features/contracts/layouts/index.ts +8 -0
  69. package/src/features/contracts/services/__tests__/contracts-client.test.ts +148 -0
  70. package/src/features/contracts/services/__tests__/list-attached-contracts.service.test.ts +95 -0
  71. package/src/features/contracts/services/add-contracts.service.ts +27 -0
  72. package/src/features/contracts/services/index.ts +24 -0
  73. package/src/features/contracts/services/list-attached-contracts.service.ts +40 -0
  74. package/src/features/contracts/services/list-available-contracts.service.ts +32 -0
  75. package/src/features/contracts/services/remove-contract.service.ts +27 -0
  76. package/src/features/contracts/services/remove-contracts.service.ts +36 -0
  77. package/src/features/contracts/services/set-default-contract.service.ts +27 -0
  78. package/src/features/contracts/types/ContractData.ts +1 -0
  79. package/src/features/contracts/utils/__tests__/changeContractToken.test.ts +141 -0
  80. package/src/features/contracts/utils/changeContractToken.ts +122 -0
  81. package/src/features/contracts/utils/clearPersistedSessionState.ts +74 -0
  82. package/src/features/org-units/components/OrgUnitDetailsNavbar/OrgUnitDetailsNavbar.tsx +45 -3
  83. package/src/features/org-units/components/OrgUnitDetailsNavbar/org-unit-details-navbar.scss +35 -0
  84. package/src/features/org-units/layouts/OrgUnitsLayout/OrgUnitsLayout.tsx +54 -48
  85. package/src/features/roles/layout/RolesLayout/RolesLayout.tsx +32 -23
  86. package/src/features/shared/components/BuyerPortalProvider/BuyerPortalProvider.tsx +1 -0
  87. package/src/features/shared/components/HeaderInside/HeaderInside.tsx +8 -1
  88. package/src/features/shared/components/HeaderInside/header-inside.scss +9 -0
  89. package/src/features/shared/layouts/BaseTabsLayout/SidebarMenu.tsx +6 -97
  90. package/src/features/shared/layouts/ContractTabsLayout/ContractTabsLayout.tsx +42 -5
  91. package/src/features/shared/layouts/LoadingTabsLayout/LoadingTabsLayout.tsx +1 -1
  92. package/src/features/shared/layouts/SumaPageLayout/FullSidebarNav.tsx +124 -0
  93. package/src/features/shared/layouts/SumaPageLayout/SumaPageLayout.tsx +56 -0
  94. package/src/features/shared/layouts/SumaPageLayout/SumaSidebar.tsx +80 -0
  95. package/src/features/shared/layouts/SumaPageLayout/SumaSidebarDrawer.tsx +48 -0
  96. package/src/features/shared/layouts/SumaPageLayout/index.ts +6 -0
  97. package/src/features/shared/layouts/SumaPageLayout/suma-sidebar-drawer.scss +37 -0
  98. package/src/features/shared/layouts/index.ts +6 -0
  99. package/src/features/shared/services/feature-flags/__tests__/get-feature-flags.service.test.ts +71 -0
  100. package/src/features/shared/services/feature-flags/get-feature-flags.service.ts +1 -0
  101. package/src/features/shared/utils/buyerPortalRoutes.ts +9 -0
  102. package/src/features/shared/utils/constants.ts +1 -1
  103. package/src/features/shared/utils/getSumaListingSidebarLinks.ts +18 -0
  104. package/src/features/shared/utils/index.ts +1 -0
  105. package/src/features/users/layouts/UsersLayout/UsersLayout.tsx +97 -103
  106. package/src/pages/contract-information.tsx +128 -0
  107. package/src/pages/contracts.tsx +104 -0
  108. package/src/pages/home.tsx +10 -6
  109. package/src/pages/org-unit-details.tsx +17 -13
  110. package/src/themes/layouts.scss +2 -0
  111. package/.agents/skills/create-page/SKILL.md +0 -154
  112. package/.agents/skills/create-page/metadata.json +0 -14
  113. package/.specify/memory/constitution.md +0 -83
@@ -9,6 +9,7 @@ import {
9
9
  useQueryParams,
10
10
  } from "../../../shared/hooks";
11
11
  import { FinanceTabsLayout, GlobalLayout } from "../../../shared/layouts";
12
+ import { SumaPageLayout } from "../../../shared/layouts/SumaPageLayout/SumaPageLayout";
12
13
  import { BudgetDeleteDrawer } from "../../components/BudgetDeleteDrawer/BudgetDeleteDrawer";
13
14
  import { BudgetEditNotificationDrawer } from "../../components/BudgetEditNotificationDrawer/BudgetEditNotificationDrawer";
14
15
  import { BudgetsTable } from "../../components/BudgetsTable/BudgetsTable";
@@ -36,6 +37,7 @@ export const BudgetsLayout = ({ data }: BudgetsLayoutProps) => {
36
37
  clientContext: { cookie },
37
38
  currentOrgUnit: orgUnit,
38
39
  currentContract: contract,
40
+ featureFlags,
39
41
  } = useBuyerPortal();
40
42
  const [paginationLoading, setPaginationLoading] = useState<boolean>(false);
41
43
  const [loading, setLoading] = useState<boolean>(false);
@@ -161,118 +163,124 @@ export const BudgetsLayout = ({ data }: BudgetsLayoutProps) => {
161
163
  [page, contract?.id, orgUnit?.id, cookie]
162
164
  );
163
165
 
164
- return (
165
- <GlobalLayout>
166
- <FinanceTabsLayout pageName="Finance and Compliance">
167
- <section data-fs-bp-budgets-layout>
168
- <main data-fs-bp-main>
169
- <HeaderInside title="Budgets">
170
- <HeaderInside.Button onClick={openBudgetDrawer} />
171
- </HeaderInside>
172
-
173
- {budgetContent.length === 0 ? (
174
- <div data-fs-empty-state>
175
- <EmptyState title="No budgets yet" iconName="Paid" />
176
- </div>
177
- ) : (
178
- <section data-fs-bp-budgets-content>
179
- <div data-fs-bp-search-container>
180
- <InternalSearch
181
- textSearch={(searchTerm) =>
182
- searchTerm
183
- ? setQueryString("search", searchTerm)
184
- : removeQueryString("search")
185
- }
186
- />
187
- </div>
188
-
189
- <BudgetsTable
190
- data={budgetContent}
191
- total={Number(total ?? 0)}
192
- onClickAllocationPage={handleAddAllocation}
193
- onClickEditBudget={handleBudgetEditPage}
194
- onClickCreateNotification={handleCreateNotification}
195
- openDeleteDrawer={(budgetId) => {
196
- setSelectedBudgetId(budgetId);
197
- openDeleteDrawer();
198
- }}
199
- loading={loading}
200
- />
166
+ const budgetsSection = (
167
+ <section data-fs-bp-budgets-layout>
168
+ <main data-fs-bp-main>
169
+ <HeaderInside title="Budgets">
170
+ <HeaderInside.Button onClick={openBudgetDrawer} />
171
+ </HeaderInside>
201
172
 
202
- <Pagination
203
- currentCount={budgetContent.length}
204
- total={Number(total ?? 0)}
205
- showMore={loadMore}
206
- loading={paginationLoading}
207
- variant={
208
- budgetContent.length < Number(total)
209
- ? "default"
210
- : "onlyText"
211
- }
212
- />
213
- </section>
214
- )}
215
- </main>
173
+ {budgetContent.length === 0 ? (
174
+ <div data-fs-empty-state>
175
+ <EmptyState title="No budgets yet" iconName="Paid" />
176
+ </div>
177
+ ) : (
178
+ <section data-fs-bp-budgets-content>
179
+ <div data-fs-bp-search-container>
180
+ <InternalSearch
181
+ textSearch={(searchTerm) =>
182
+ searchTerm
183
+ ? setQueryString("search", searchTerm)
184
+ : removeQueryString("search")
185
+ }
186
+ />
187
+ </div>
216
188
 
217
- {isDeleteDrawerOpen && (
218
- <BudgetDeleteDrawer
219
- budgetName={
220
- budgetContent.find((budget) => budget.id === selectedBudgetId)
221
- ?.name ?? ""
222
- }
223
- budgetId={selectedBudgetId}
224
- isOpen={isDeleteDrawerOpen}
225
- orgUnitId={orgUnit?.id ?? ""}
226
- contractId={contract?.id ?? ""}
227
- close={() => {
228
- closeDeleteDrawer();
229
- setSelectedBudgetId("");
189
+ <BudgetsTable
190
+ data={budgetContent}
191
+ total={Number(total ?? 0)}
192
+ onClickAllocationPage={handleAddAllocation}
193
+ onClickEditBudget={handleBudgetEditPage}
194
+ onClickCreateNotification={handleCreateNotification}
195
+ openDeleteDrawer={(budgetId) => {
196
+ setSelectedBudgetId(budgetId);
197
+ openDeleteDrawer();
230
198
  }}
231
- {...deleteDrawerProps}
232
- />
233
- )}
234
- {isAddAllocationDrawerOpen && (
235
- <CreateBudgetAllocationDrawer
236
- {...addAllocationDrawerProps}
237
- allocationList={budgetsAllocation?.data ?? []}
238
- contractId={contract?.id ?? ""}
239
- budgetId={selectedBudgetId}
240
- orgUnitId={orgUnit?.id ?? ""}
241
- isOpen={isAddAllocationDrawerOpen}
199
+ loading={loading}
242
200
  />
243
- )}
244
- {isCreateBudgetDrawerOpen && (
245
- <CreateBudgetDrawer
246
- contractId={contract?.id ?? ""}
247
- unitId={orgUnit?.id ?? ""}
248
- {...createBudgetDrawerProps}
249
- isOpen={isCreateBudgetDrawerOpen}
250
- />
251
- )}
252
201
 
253
- {isEditDrawerOpen && (
254
- <EditBudgetDrawer
255
- {...editDrawerProps}
256
- isOpen={isEditDrawerOpen}
257
- contractId={contract?.id ?? ""}
258
- orgUnitId={orgUnit?.id ?? ""}
259
- budgetId={selectedBudgetId}
260
- initialBudget={budgetsToEdit}
202
+ <Pagination
203
+ currentCount={budgetContent.length}
204
+ total={Number(total ?? 0)}
205
+ showMore={loadMore}
206
+ loading={paginationLoading}
207
+ variant={
208
+ budgetContent.length < Number(total) ? "default" : "onlyText"
209
+ }
261
210
  />
262
- )}
211
+ </section>
212
+ )}
213
+ </main>
263
214
 
264
- {isNotificationDrawerOpen && budgetsToEdit && (
265
- <BudgetEditNotificationDrawer
266
- {...notificationDrawerProps}
267
- isOpen={isNotificationDrawerOpen}
268
- budget={budgetsToEdit}
269
- budgetId={selectedBudgetId}
270
- orgUnitId={orgUnit?.id ?? ""}
271
- contractId={contract?.id ?? ""}
272
- />
273
- )}
274
- </section>
275
- </FinanceTabsLayout>
215
+ {isDeleteDrawerOpen && (
216
+ <BudgetDeleteDrawer
217
+ budgetName={
218
+ budgetContent.find((budget) => budget.id === selectedBudgetId)
219
+ ?.name ?? ""
220
+ }
221
+ budgetId={selectedBudgetId}
222
+ isOpen={isDeleteDrawerOpen}
223
+ orgUnitId={orgUnit?.id ?? ""}
224
+ contractId={contract?.id ?? ""}
225
+ close={() => {
226
+ closeDeleteDrawer();
227
+ setSelectedBudgetId("");
228
+ }}
229
+ {...deleteDrawerProps}
230
+ />
231
+ )}
232
+ {isAddAllocationDrawerOpen && (
233
+ <CreateBudgetAllocationDrawer
234
+ {...addAllocationDrawerProps}
235
+ allocationList={budgetsAllocation?.data ?? []}
236
+ contractId={contract?.id ?? ""}
237
+ budgetId={selectedBudgetId}
238
+ orgUnitId={orgUnit?.id ?? ""}
239
+ isOpen={isAddAllocationDrawerOpen}
240
+ />
241
+ )}
242
+ {isCreateBudgetDrawerOpen && (
243
+ <CreateBudgetDrawer
244
+ contractId={contract?.id ?? ""}
245
+ unitId={orgUnit?.id ?? ""}
246
+ {...createBudgetDrawerProps}
247
+ isOpen={isCreateBudgetDrawerOpen}
248
+ />
249
+ )}
250
+
251
+ {isEditDrawerOpen && (
252
+ <EditBudgetDrawer
253
+ {...editDrawerProps}
254
+ isOpen={isEditDrawerOpen}
255
+ contractId={contract?.id ?? ""}
256
+ orgUnitId={orgUnit?.id ?? ""}
257
+ budgetId={selectedBudgetId}
258
+ initialBudget={budgetsToEdit}
259
+ />
260
+ )}
261
+
262
+ {isNotificationDrawerOpen && budgetsToEdit && (
263
+ <BudgetEditNotificationDrawer
264
+ {...notificationDrawerProps}
265
+ isOpen={isNotificationDrawerOpen}
266
+ budget={budgetsToEdit}
267
+ budgetId={selectedBudgetId}
268
+ orgUnitId={orgUnit?.id ?? ""}
269
+ contractId={contract?.id ?? ""}
270
+ />
271
+ )}
272
+ </section>
273
+ );
274
+
275
+ return (
276
+ <GlobalLayout>
277
+ {featureFlags?.suma ? (
278
+ <SumaPageLayout>{budgetsSection}</SumaPageLayout>
279
+ ) : (
280
+ <FinanceTabsLayout pageName="Finance and Compliance">
281
+ {budgetsSection}
282
+ </FinanceTabsLayout>
283
+ )}
276
284
  </GlobalLayout>
277
285
  );
278
286
  };
@@ -320,8 +320,8 @@ export const BasicBuyingPolicyDrawer = ({
320
320
  onClick={() => {
321
321
  if (
322
322
  !isBudgetCriteria &&
323
- !isAccountingFieldCriteria &&
324
- !isAccountingValueCriteria
323
+ !isAccountingFieldCriteria(criteria) &&
324
+ !isAccountingValueCriteria(criteria)
325
325
  ) {
326
326
  setCriteriaFocused(true);
327
327
  }
@@ -16,6 +16,7 @@ import {
16
16
  useDrawerProps,
17
17
  } from "../../../shared/hooks";
18
18
  import { FinanceTabsLayout, GlobalLayout } from "../../../shared/layouts";
19
+ import { SumaPageLayout } from "../../../shared/layouts/SumaPageLayout/SumaPageLayout";
19
20
  import { buyerPortalRoutes } from "../../../shared/utils/buyerPortalRoutes";
20
21
  import { BuyingPolicyDropdownMenu } from "../../components";
21
22
  import { AddBuyingPolicyDrawer } from "../../components/AddBuyingPolicyDrawer/AddBuyingPolicyDrawer";
@@ -35,7 +36,7 @@ export const BuyingPoliciesLayout = ({
35
36
  search,
36
37
  page,
37
38
  }: BuyingPoliciesLayoutProps) => {
38
- const { currentContract, currentOrgUnit } = useBuyerPortal();
39
+ const { currentContract, currentOrgUnit, featureFlags } = useBuyerPortal();
39
40
 
40
41
  const router = useRouter();
41
42
 
@@ -142,55 +143,68 @@ export const BuyingPoliciesLayout = ({
142
143
  );
143
144
  }
144
145
 
146
+ const buyingPoliciesSection = (
147
+ <section data-fs-buying-policies-section>
148
+ <HeaderInside title="Buying Policies">
149
+ <HeaderInside.Button onClick={openAddBuyingPolicyDrawer} />
150
+ </HeaderInside>
151
+
152
+ <div data-fs-buying-policies-filter>
153
+ <InternalSearch defaultValue={searchTerm} textSearch={setSearchTerm} />
154
+ <Paginator.Counter
155
+ total={totalBuyingPolicies}
156
+ itemsLength={buyingPolicies.length}
157
+ />
158
+ </div>
159
+
160
+ {renderContent()}
161
+
162
+ <div data-fs-bp-buying-policies-paginator>
163
+ {totalBuyingPolicies > buyingPolicies.length ? (
164
+ <Paginator.NextPageButton onClick={increasePage} disabled={isLoading}>
165
+ {isLoading ? "Loading" : "Load More"}
166
+ </Paginator.NextPageButton>
167
+ ) : (
168
+ <span />
169
+ )}
170
+
171
+ <Paginator.Counter
172
+ total={totalBuyingPolicies}
173
+ itemsLength={buyingPolicies.length}
174
+ />
175
+ </div>
176
+ </section>
177
+ );
178
+
145
179
  return (
146
180
  <GlobalLayout>
147
- <FinanceTabsLayout pageName="Finance and Compliance">
148
- <section data-fs-buying-policies-section>
149
- <HeaderInside title="Buying Policies">
150
- <HeaderInside.Button onClick={openAddBuyingPolicyDrawer} />
151
- </HeaderInside>
152
-
153
- <div data-fs-buying-policies-filter>
154
- <InternalSearch
155
- defaultValue={searchTerm}
156
- textSearch={setSearchTerm}
157
- />
158
- <Paginator.Counter
159
- total={totalBuyingPolicies}
160
- itemsLength={buyingPolicies.length}
181
+ {featureFlags?.suma ? (
182
+ <SumaPageLayout>
183
+ {buyingPoliciesSection}
184
+ {isAddBuyingPolicyDrawerOpen && (
185
+ <AddBuyingPolicyDrawer
186
+ orgUnitId={currentOrgUnit?.id ?? ""}
187
+ contractId={currentContract?.id ?? ""}
188
+ isOpen={isAddBuyingPolicyDrawerOpen}
189
+ onCreate={handleRefetchBuyingPolicies}
190
+ {...addBuyingPolicyDrawerProps}
161
191
  />
162
- </div>
163
-
164
- {renderContent()}
165
-
166
- <div data-fs-bp-buying-policies-paginator>
167
- {totalBuyingPolicies > buyingPolicies.length ? (
168
- <Paginator.NextPageButton
169
- onClick={increasePage}
170
- disabled={isLoading}
171
- >
172
- {isLoading ? "Loading" : "Load More"}
173
- </Paginator.NextPageButton>
174
- ) : (
175
- <span />
176
- )}
177
-
178
- <Paginator.Counter
179
- total={totalBuyingPolicies}
180
- itemsLength={buyingPolicies.length}
192
+ )}
193
+ </SumaPageLayout>
194
+ ) : (
195
+ <FinanceTabsLayout pageName="Finance and Compliance">
196
+ {buyingPoliciesSection}
197
+ {isAddBuyingPolicyDrawerOpen && (
198
+ <AddBuyingPolicyDrawer
199
+ orgUnitId={currentOrgUnit?.id ?? ""}
200
+ contractId={currentContract?.id ?? ""}
201
+ isOpen={isAddBuyingPolicyDrawerOpen}
202
+ onCreate={handleRefetchBuyingPolicies}
203
+ {...addBuyingPolicyDrawerProps}
181
204
  />
182
- </div>
183
- </section>
184
- {isAddBuyingPolicyDrawerOpen && (
185
- <AddBuyingPolicyDrawer
186
- orgUnitId={currentOrgUnit?.id ?? ""}
187
- contractId={currentContract?.id ?? ""}
188
- isOpen={isAddBuyingPolicyDrawerOpen}
189
- onCreate={handleRefetchBuyingPolicies}
190
- {...addBuyingPolicyDrawerProps}
191
- />
192
- )}
193
- </FinanceTabsLayout>
205
+ )}
206
+ </FinanceTabsLayout>
207
+ )}
194
208
  </GlobalLayout>
195
209
  );
196
210
  };
@@ -47,6 +47,51 @@ class ContractsClient extends Client {
47
47
  }
48
48
  );
49
49
  }
50
+
51
+ listAttachedContracts(orgUnitId: string, cookie: string) {
52
+ return this.get<{ contracts: ContractData[] }>(
53
+ `units/${orgUnitId}/contracts/attached`,
54
+ {
55
+ headers: { Cookie: cookie },
56
+ params: { details: true },
57
+ }
58
+ );
59
+ }
60
+
61
+ listAvailableContracts(orgUnitId: string, cookie: string) {
62
+ return this.get<{
63
+ ids: string[];
64
+ contracts: Array<{ id: string; name: string }>;
65
+ total: number;
66
+ }>(`units/${orgUnitId}/contracts/available`, {
67
+ headers: { Cookie: cookie },
68
+ params: { details: true },
69
+ });
70
+ }
71
+
72
+ addContracts(orgUnitId: string, ids: string[], cookie: string) {
73
+ return this.post<unknown, { ids: string[] }>(
74
+ `units/${orgUnitId}/contracts/attached`,
75
+ { ids },
76
+ { headers: { Cookie: cookie } }
77
+ );
78
+ }
79
+
80
+ removeContract(orgUnitId: string, contractId: string, cookie: string) {
81
+ return this.request<null, never>({
82
+ url: `units/${orgUnitId}/contracts/attached/${contractId}`,
83
+ method: "DELETE",
84
+ headers: { Cookie: cookie },
85
+ });
86
+ }
87
+
88
+ setDefaultContract(orgUnitId: string, contractId: string, cookie: string) {
89
+ return this.request<null, never>({
90
+ url: `units/${orgUnitId}/contracts/attached/${contractId}/default`,
91
+ method: "PUT",
92
+ headers: { Cookie: cookie },
93
+ });
94
+ }
50
95
  }
51
96
 
52
97
  const contractsClient = new ContractsClient();