@vtex/faststore-plugin-buyer-portal 1.1.6 → 1.1.7

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 (34) hide show
  1. package/CHANGELOG.md +1 -0
  2. package/package.json +1 -1
  3. package/src/features/buying-policies/components/AddBuyingPolicyDrawer/AddBuyingPolicyDrawer.tsx +2 -1
  4. package/src/features/buying-policies/components/BasicBuyingPolicyDrawer/BasicBuyingPolicyDrawer.tsx +193 -130
  5. package/src/features/buying-policies/components/BasicBuyingPolicyDrawer/basic-buying-policy-drawer.scss +72 -1
  6. package/src/features/buying-policies/components/BuyingPolicyDropdownMenu/BuyingPolicyDropdownMenu.tsx +1 -1
  7. package/src/features/buying-policies/components/DeleteBuyingPolicyDrawer/DeleteBuyingPolicyDrawer.tsx +17 -14
  8. package/src/features/buying-policies/components/UpdateBuyingPolicyDrawer/UpdateBuyingPolicyDrawer.tsx +4 -4
  9. package/src/features/buying-policies/hooks/useGetBuyingPolicy.ts +1 -1
  10. package/src/features/buying-policies/layouts/BuyingPoliciesLayout/BuyingPoliciesLayout.tsx +60 -24
  11. package/src/features/buying-policies/layouts/BuyingPoliciesLayout/buying-policies-layout.scss +8 -0
  12. package/src/features/buying-policies/layouts/BuyingPolicyDetailsLayout/BuyingPolicyDetailsLayout.tsx +3 -2
  13. package/src/features/buying-policies/layouts/BuyingPolicyDetailsLayout/buying-policy-details-layout.scss +8 -0
  14. package/src/features/buying-policies/services/add-buying-policy.service.ts +14 -8
  15. package/src/features/buying-policies/services/get-buying-policies.service.ts +13 -7
  16. package/src/features/buying-policies/services/get-buying-policy.service.ts +12 -6
  17. package/src/features/buying-policies/services/remove-buying-policy.service.ts +14 -8
  18. package/src/features/buying-policies/services/update-buying-policy.service.ts +26 -9
  19. package/src/features/buying-policies/types/BuyingPolicy.ts +6 -4
  20. package/src/features/buying-policies/utils/buyingPoliciesWorkflowTypes.ts +12 -3
  21. package/src/features/buying-policies/utils/buyingPolicyDefault.ts +2 -1
  22. package/src/features/buying-policies/utils/criteriaHighlightSyntax.tsx +52 -0
  23. package/src/features/org-units/clients/OrgUnitClient.ts +1 -10
  24. package/src/features/org-units/hooks/useSearchOrgUnits.ts +4 -4
  25. package/src/features/org-units/services/index.ts +2 -2
  26. package/src/features/org-units/services/search-org-units-by-name.service.ts +5 -5
  27. package/src/features/shared/components/BasicDropdownMenu/BasicDropdownMenu.tsx +6 -2
  28. package/src/features/shared/components/InputText/InputText.tsx +27 -5
  29. package/src/features/shared/components/VerticalNav/VerticalNavLink.tsx +20 -2
  30. package/src/features/shared/components/VerticalNav/vertical-nav.scss +4 -0
  31. package/src/features/shared/hooks/usePageItems.ts +12 -4
  32. package/src/features/shared/hooks/useQuery.ts +4 -1
  33. package/src/features/shared/utils/isRightFormat.ts +8 -0
  34. package/src/pages/org-units.tsx +2 -2
package/CHANGELOG.md CHANGED
@@ -9,6 +9,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
9
9
 
10
10
  - Address Recipients Add & Delete Feature
11
11
  - Address Recipients Edit Feature
12
+ - Add Buying Policy integration with BFF
12
13
 
13
14
  ### Fixed
14
15
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vtex/faststore-plugin-buyer-portal",
3
- "version": "1.1.6",
3
+ "version": "1.1.7",
4
4
  "description": "A plugin for faststore with buyer portal",
5
5
  "main": "index.js",
6
6
  "dependencies": {
@@ -57,7 +57,8 @@ export const AddBuyingPolicyDrawer = ({
57
57
  onSuccess: handleAddBuyingPolicySuccess,
58
58
  onError: () => {
59
59
  pushToast({
60
- message: "Error adding buying policy",
60
+ message: "An error occurred. Please try again.",
61
+ title: "Error",
61
62
  status: "ERROR",
62
63
  });
63
64
  },
@@ -16,7 +16,7 @@ import {
16
16
  InputText,
17
17
  LevelDivider,
18
18
  } from "../../../shared/components";
19
- import { buyingPolicyOptions, type BuyingPolicy } from "../../types";
19
+ import { type BuyingPolicy } from "../../types";
20
20
  import { OrgUnitInputSearch } from "../../../shared/components/OrgUnitInputSearch/OrgUnitInputSearch";
21
21
  import {
22
22
  BUYING_POLICIES_WORKFLOW_TYPES,
@@ -24,7 +24,15 @@ import {
24
24
  orderFieldsCriteriaOptions,
25
25
  spendingLimitsCriteriaOptions,
26
26
  } from "../../utils";
27
- import { Dropdown, DropdownButton, DropdownItem } from "@faststore/ui";
27
+ import {
28
+ Dropdown,
29
+ DropdownButton,
30
+ DropdownItem,
31
+ Skeleton,
32
+ Tooltip,
33
+ } from "@faststore/ui";
34
+ import { getHighlightedText } from "../../utils/criteriaHighlightSyntax";
35
+ import { BUYING_POLICIES_WORKFLOW_LABELS } from "../../utils/buyingPoliciesWorkflowTypes";
28
36
 
29
37
  const LIMIT_OF_LEVELS = 5;
30
38
 
@@ -46,6 +54,7 @@ export type BasicBuyingPolicyDrawerProps = Omit<
46
54
  initialValues?: BuyingPolicyForm;
47
55
  drawerTitle?: string;
48
56
  saveButtonLabel?: string;
57
+ isDrawerLoading?: boolean;
49
58
  };
50
59
 
51
60
  export const BasicBuyingPolicyDrawer = ({
@@ -54,6 +63,7 @@ export const BasicBuyingPolicyDrawer = ({
54
63
  close,
55
64
  onCreate,
56
65
  isLoading,
66
+ isDrawerLoading,
57
67
  onConfirm,
58
68
  orgUnitId,
59
69
  contractId,
@@ -61,9 +71,10 @@ export const BasicBuyingPolicyDrawer = ({
61
71
  ...props
62
72
  }: BasicBuyingPolicyDrawerProps) => {
63
73
  const [form, setForm] = useState<BuyingPolicyForm>(initialValues);
74
+ const [isTouched, setIsTouched] = useState(false);
64
75
 
65
76
  useEffect(() => {
66
- if (initialValues) {
77
+ if (initialValues && !isTouched) {
67
78
  setForm((prev) => ({
68
79
  ...prev,
69
80
  ...initialValues,
@@ -71,7 +82,7 @@ export const BasicBuyingPolicyDrawer = ({
71
82
  }
72
83
  }, [initialValues]);
73
84
 
74
- const [isTouched, setIsTouched] = useState(false);
85
+ const [criteriaFocused, setCriteriaFocused] = useState(false);
75
86
 
76
87
  const { name, description, criteria, action } = form;
77
88
 
@@ -92,7 +103,9 @@ export const BasicBuyingPolicyDrawer = ({
92
103
  return false;
93
104
  }
94
105
 
95
- if (valueAction.type === BUYING_POLICIES_WORKFLOW_TYPES.SEQUENTIAL) {
106
+ if (
107
+ valueAction.type === BUYING_POLICIES_WORKFLOW_TYPES.SEQUENTIAL_WORKFLOW
108
+ ) {
96
109
  return (
97
110
  valueAction.levels?.length &&
98
111
  valueAction.levels.every((level) => {
@@ -172,28 +185,46 @@ export const BasicBuyingPolicyDrawer = ({
172
185
  Define policy name and description to inform buyers during checkout
173
186
  </h4>
174
187
 
175
- <InputText
176
- label="Name"
177
- value={name}
178
- hasError={isTouched && !name?.trim()}
179
- onChange={(event) => updateField("name", event.target.value)}
180
- />
188
+ {isDrawerLoading ? (
189
+ <Skeleton size={{ width: "100%", height: "3.5rem" }} />
190
+ ) : (
191
+ <InputText
192
+ label="Name"
193
+ value={name}
194
+ hasError={isTouched && !name?.trim()}
195
+ onChange={(event) => updateField("name", event.target.value)}
196
+ />
197
+ )}
181
198
 
182
199
  <ErrorMessage
183
200
  show={isTouched && !name?.trim()}
184
201
  message="Name is required"
185
202
  />
186
203
 
187
- <InputText
188
- label="Description"
189
- value={description}
190
- wrapperProps={{ style: { marginTop: 16, marginBottom: 16 } }}
191
- hasError={isTouched && !description?.trim()}
192
- onChange={(event) => updateField("description", event.target.value)}
193
- />
204
+ {isDrawerLoading ? (
205
+ <Skeleton size={{ width: "100%", height: "3.5rem" }} />
206
+ ) : (
207
+ <InputText
208
+ label="Description"
209
+ value={description}
210
+ wrapperProps={{ style: { marginTop: 16, marginBottom: 16 } }}
211
+ hasError={isTouched && !description?.trim()}
212
+ onChange={(event) => updateField("description", event.target.value)}
213
+ icon={
214
+ <Tooltip
215
+ data-fs-bp-basic-buying-policy-drawer-tooltip
216
+ placement="left-center"
217
+ maxWidth={225}
218
+ content="Describe how this policy works so buyers know why an order may be denied or require approval."
219
+ >
220
+ <Icon name="Info" />
221
+ </Tooltip>
222
+ }
223
+ />
224
+ )}
194
225
 
195
226
  <ErrorMessage
196
- show={isTouched && !name?.trim()}
227
+ show={isTouched && !description?.trim()}
197
228
  message="Description is required"
198
229
  />
199
230
 
@@ -203,120 +234,151 @@ export const BasicBuyingPolicyDrawer = ({
203
234
  <a href="https://jsonata.org/">JSONata</a>
204
235
  </h4>
205
236
 
206
- <InputText
207
- label=""
208
- value={criteria}
209
- wrapperProps={
210
- {
211
- style: { marginTop: 16, marginBottom: 16 },
212
- "data-fs-bp-input-text-criteria": true,
213
- "data-fs-bp-input-text-code": true,
214
- } as DetailedHTMLProps<
215
- HTMLAttributes<HTMLDivElement>,
216
- HTMLDivElement
217
- >
218
- }
219
- hasError={isTouched && !description?.trim()}
220
- onChange={(event) => updateField("criteria", event.target.value)}
221
- />
222
-
223
- <ErrorMessage
224
- show={isTouched && !name?.trim()}
225
- message="Criteria is required"
226
- />
227
-
228
- <div data-fs-bp-criteria-selectors-wrapper>
229
- <Dropdown>
230
- <DropdownButton asChild>
231
- <button data-fs-bp-criteria-selector-trigger type="button">
232
- Set spending limit criteria
233
- </button>
234
- </DropdownButton>
235
- <BasicDropdownMenu>
236
- {spendingLimitsCriteriaOptions.map((option) => (
237
- <DropdownItem
238
- key={option.label}
239
- onClick={() => {
240
- updateField("criteria", option.criteria);
241
- }}
242
- >
243
- {option.label}
244
- </DropdownItem>
245
- ))}
246
- </BasicDropdownMenu>
247
- </Dropdown>
248
-
249
- <Dropdown>
250
- <DropdownButton asChild>
251
- <button type="button" data-fs-bp-criteria-selector-trigger>
252
- Set order field criteria
253
- </button>
254
- </DropdownButton>
255
- <BasicDropdownMenu>
256
- {orderFieldsCriteriaOptions.map((option) => (
257
- <DropdownItem
258
- key={option.label}
259
- onClick={() => {
260
- updateField("criteria", option.criteria);
261
- }}
262
- dismissOnClick
237
+ {isDrawerLoading ? (
238
+ <Skeleton size={{ width: "100%", height: "3.5rem" }} />
239
+ ) : (
240
+ <>
241
+ <div data-fs-bp-basic-buying-policy-criteria-input>
242
+ <InputText
243
+ label={""}
244
+ value={criteria}
245
+ wrapperProps={
246
+ {
247
+ style: { marginTop: 16, marginBottom: 16 },
248
+ "data-fs-bp-input-text-criteria": true,
249
+ "data-fs-bp-input-text-code": true,
250
+ } as DetailedHTMLProps<
251
+ HTMLAttributes<HTMLDivElement>,
252
+ HTMLDivElement
253
+ >
254
+ }
255
+ hasError={isTouched && !criteria?.trim()}
256
+ onChange={(event) =>
257
+ updateField("criteria", event.target.value)
258
+ }
259
+ onBlur={() => setCriteriaFocused(false)}
260
+ isCustomFocused={criteriaFocused}
261
+ />
262
+
263
+ {!criteriaFocused && (
264
+ <div
265
+ data-fs-bp-basic-buying-policy-criteria-input-highlighted
266
+ onClick={() => setCriteriaFocused(true)}
263
267
  >
264
- {option.label}
265
- </DropdownItem>
266
- ))}
267
- </BasicDropdownMenu>
268
- </Dropdown>
269
- </div>
268
+ {criteria ? (
269
+ getHighlightedText(criteria)
270
+ ) : (
271
+ <span data-fs-bp-label>Example: value {">"} 10000</span>
272
+ )}
273
+ </div>
274
+ )}
275
+ </div>
276
+
277
+ <ErrorMessage
278
+ show={isTouched && !criteria?.trim()}
279
+ message="Criteria is required"
280
+ />
281
+
282
+ <div data-fs-bp-criteria-selectors-wrapper>
283
+ <Dropdown>
284
+ <DropdownButton asChild>
285
+ <button data-fs-bp-criteria-selector-trigger type="button">
286
+ Set spending limit criteria
287
+ </button>
288
+ </DropdownButton>
289
+ <BasicDropdownMenu align="left">
290
+ {spendingLimitsCriteriaOptions.map((option) => (
291
+ <DropdownItem
292
+ key={option.label}
293
+ onClick={() => {
294
+ updateField("criteria", option.criteria);
295
+ }}
296
+ >
297
+ <span>{getHighlightedText(option.label)}</span>
298
+ </DropdownItem>
299
+ ))}
300
+ </BasicDropdownMenu>
301
+ </Dropdown>
302
+
303
+ <Dropdown>
304
+ <DropdownButton asChild>
305
+ <button type="button" data-fs-bp-criteria-selector-trigger>
306
+ Set order field criteria
307
+ </button>
308
+ </DropdownButton>
309
+ <BasicDropdownMenu align="left">
310
+ {orderFieldsCriteriaOptions.map((option) => (
311
+ <DropdownItem
312
+ key={option.label}
313
+ onClick={() => {
314
+ updateField("criteria", option.criteria);
315
+ }}
316
+ dismissOnClick
317
+ >
318
+ <span>{getHighlightedText(option.label)}</span>
319
+ </DropdownItem>
320
+ ))}
321
+ </BasicDropdownMenu>
322
+ </Dropdown>
323
+ </div>
324
+ </>
325
+ )}
270
326
 
271
327
  <h3>Action</h3>
272
328
  <h4>Define how orders that meet the criteria will be handled</h4>
329
+ {isDrawerLoading ? (
330
+ <Skeleton size={{ width: "100%", height: "3.5rem" }} />
331
+ ) : (
332
+ <AutocompleteDropdown
333
+ label=""
334
+ wrapperProps={
335
+ {
336
+ "data-fs-bp-input-text-criteria": true,
337
+ } as DetailedHTMLProps<
338
+ HTMLAttributes<HTMLDivElement>,
339
+ HTMLDivElement
340
+ >
341
+ }
342
+ value={BUYING_POLICIES_WORKFLOW_LABELS[action.type]}
343
+ options={
344
+ Object.keys(BUYING_POLICIES_WORKFLOW_LABELS) as Array<
345
+ keyof typeof BUYING_POLICIES_WORKFLOW_LABELS
346
+ >
347
+ }
348
+ onConfirmKeyPress={(option) => {
349
+ updateField("action", {
350
+ type: option,
351
+ levels: [],
352
+ });
353
+ }}
354
+ hasError={isTouched && !action.type?.trim()}
355
+ renderOption={(optionActionType, index) => (
356
+ <AutocompleteDropdown.Item
357
+ key={optionActionType}
358
+ closeOnClick
359
+ index={index}
360
+ isSelected={action.type === optionActionType}
361
+ onClick={() => {
362
+ updateField("action", {
363
+ type: optionActionType,
364
+ levels: [
365
+ {
366
+ id: "",
367
+ name: "",
368
+ },
369
+ ],
370
+ });
371
+ }}
372
+ >
373
+ {BUYING_POLICIES_WORKFLOW_LABELS[optionActionType]}
374
+ </AutocompleteDropdown.Item>
375
+ )}
376
+ />
377
+ )}
273
378
 
274
- <AutocompleteDropdown
275
- label=""
276
- wrapperProps={
277
- {
278
- "data-fs-bp-input-text-criteria": true,
279
- } as DetailedHTMLProps<
280
- HTMLAttributes<HTMLDivElement>,
281
- HTMLDivElement
282
- >
283
- }
284
- value={action.type}
285
- options={[...buyingPolicyOptions]}
286
- onConfirmKeyPress={(option) => {
287
- updateField("action", {
288
- type: option,
289
- levels: [],
290
- });
291
- }}
292
- hasError={isTouched && !action.type?.trim()}
293
- renderOption={(optionActionType, index) => (
294
- <AutocompleteDropdown.Item
295
- key={optionActionType}
296
- closeOnClick
297
- index={index}
298
- isSelected={action.type === optionActionType}
299
- onClick={() => {
300
- updateField("action", {
301
- type: optionActionType,
302
- levels: [
303
- {
304
- id: "",
305
- name: "",
306
- },
307
- ],
308
- });
309
- }}
310
- >
311
- {optionActionType}
312
- </AutocompleteDropdown.Item>
313
- )}
314
- />
315
-
316
- {action.type === BUYING_POLICIES_WORKFLOW_TYPES.BYPASS && (
379
+ {action.type === BUYING_POLICIES_WORKFLOW_TYPES.BYPASS_ALL && (
317
380
  <InputText.Legend>
318
- When this policy is applied, all opther buying policy will be
319
- ignored
381
+ When this policy is applied, all other buying policy will be ignored
320
382
  </InputText.Legend>
321
383
  )}
322
384
 
@@ -325,7 +387,8 @@ export const BasicBuyingPolicyDrawer = ({
325
387
  message="Action is required"
326
388
  />
327
389
 
328
- {form.action.type === BUYING_POLICIES_WORKFLOW_TYPES.SEQUENTIAL && (
390
+ {form.action.type ===
391
+ BUYING_POLICIES_WORKFLOW_TYPES.SEQUENTIAL_WORKFLOW && (
329
392
  <>
330
393
  {form.action.levels?.map((level, index) => (
331
394
  <Fragment key={`${level.id}-${index}`}>
@@ -347,8 +410,8 @@ export const BasicBuyingPolicyDrawer = ({
347
410
  </div>
348
411
 
349
412
  <ErrorMessage
350
- show={isTouched && !name?.trim()}
351
- message="Criteria is required"
413
+ show={isTouched && !level.name?.trim()}
414
+ message="Sequential workflow is required"
352
415
  />
353
416
  </Fragment>
354
417
  ))}
@@ -1,13 +1,27 @@
1
1
  @import "../../../shared/components/BasicDrawer/basic-drawer.scss";
2
2
  @import "../../../shared/components/OrgUnitInputSearch/org-unit-input-search.scss";
3
3
 
4
+ [data-fs-dropdown-menu] {
5
+ [data-fs-dropdown-item] {
6
+ [data-fs-bp-highlight] {
7
+ color: #b521b6;
8
+ }
9
+ }
10
+ }
11
+
4
12
  [data-fs-bp-basic-buying-policy-drawer] {
5
13
  @import "../../../shared/components/InputText/input-text.scss";
6
14
  @import "../../../shared/components/ErrorMessage/error-message.scss";
7
15
  @import "../../../shared/components/LevelDivider/level-divider.scss";
16
+ @import "@faststore/ui/src/components/molecules/Tooltip/styles.scss";
17
+
18
+ &[data-fs-slide-over-size="partial"] {
19
+ max-width: calc(var(--fs-grid-breakpoint-phone) * 3);
20
+ }
8
21
 
9
22
  [data-fs-bp-basic-drawer-body] {
10
23
  padding-bottom: 90px;
24
+
11
25
  h3 {
12
26
  font-weight: var(--fs-text-weight-semibold);
13
27
  font-size: var(--fs-text-size-2);
@@ -52,17 +66,74 @@
52
66
  gap: var(--fs-spacing-2);
53
67
  }
54
68
 
69
+ [data-fs-bp-basic-buying-policy-drawer-tooltip] {
70
+ background-color: #1f1f1f;
71
+ font-weight: var(--fs-text-weight-regular);
72
+ font-size: var(--fs-text-size-0);
73
+ line-height: var(--fs-spacing-3);
74
+ color: #ffffff;
75
+ border-radius: calc(var(--fs-border-radius) * 2);
76
+ padding: var(--fs-spacing-1) var(--fs-spacing-2);
77
+
78
+ [data-fs-tooltip-indicator] {
79
+ border-left-color: #1f1f1f;
80
+ }
81
+ }
82
+
83
+ [data-fs-bp-basic-buying-policy-criteria-input] {
84
+ position: relative;
85
+ [data-fs-bp-basic-buying-policy-criteria-input-highlighted] {
86
+ position: absolute;
87
+ top: 0;
88
+ left: 0;
89
+ width: 100%;
90
+ height: 100%;
91
+ margin: 0;
92
+ background-color: #f5f5f5;
93
+ font-family: "Roboto", monospace;
94
+ font-size: var(--fs-text-size-1);
95
+ border: var(--fs-border-width) solid #d6d6d6;
96
+ padding: calc(var(--fs-spacing-3) + var(--fs-spacing-0))
97
+ var(--fs-spacing-3);
98
+ border-radius: calc(var(--fs-border-radius) * 2);
99
+ text-wrap: nowrap;
100
+ overflow: hidden;
101
+ text-overflow: ellipsis;
102
+ white-space: nowrap;
103
+ cursor: pointer;
104
+
105
+ [data-fs-bp-label] {
106
+ color: #5c5c5c;
107
+ }
108
+
109
+ [data-fs-bp-highlight] {
110
+ color: #b521b6;
111
+ }
112
+
113
+ [data-fs-bp-highlight-string] {
114
+ color: #027b4e;
115
+ }
116
+ }
117
+ }
118
+
55
119
  [data-fs-bp-input-text-criteria] {
56
120
  color: #5c5c5c;
57
121
 
122
+ label {
123
+ font-family: "Roboto", monospace;
124
+ font-size: var(--fs-text-size-1);
125
+ }
126
+
58
127
  &[data-fs-bp-input-text-code] {
59
128
  background-color: #f5f5f5;
129
+ font-family: "Roboto", monospace;
130
+ font-size: var(--fs-text-size-1);
60
131
  }
61
132
 
62
133
  [data-fs-bp-input-text-input] {
63
134
  bottom: 50%;
64
135
  transform: translateY(50%);
65
- font-size: var(--fs-text-size-2);
136
+ font-size: var(--fs-text-size-1);
66
137
  }
67
138
  }
68
139
 
@@ -38,7 +38,7 @@ export const BuyingPolicyDropdownMenu = ({
38
38
 
39
39
  return (
40
40
  <>
41
- <BasicDropdownMenu>
41
+ <BasicDropdownMenu align="right">
42
42
  <DropdownItem
43
43
  onClick={() =>
44
44
  push(
@@ -33,7 +33,7 @@ export const DeleteBuyingPolicyDrawer = ({
33
33
 
34
34
  const handleRemoveSuccess = () => {
35
35
  pushToast({
36
- message: "User successfully edited",
36
+ message: "Buying policy deleted successfully",
37
37
  status: "INFO",
38
38
  });
39
39
  onDelete?.();
@@ -52,23 +52,25 @@ export const DeleteBuyingPolicyDrawer = ({
52
52
  });
53
53
  };
54
54
 
55
- const { removeBuyingPolicy } = useRemoveBuyingPolicy({
56
- onSuccess: handleRemoveSuccess,
57
- onError: () => {
58
- pushToast({
59
- message: "An error occurred while deleting the user",
60
- status: "ERROR",
61
- });
62
- },
63
- });
55
+ const { removeBuyingPolicy, isRemoveBuyingPolicyLoading } =
56
+ useRemoveBuyingPolicy({
57
+ onSuccess: handleRemoveSuccess,
58
+ onError: () => {
59
+ pushToast({
60
+ message: "An error occurred. Please try again.",
61
+ title: "Error",
62
+ status: "ERROR",
63
+ });
64
+ },
65
+ });
64
66
 
65
67
  const isDeleteButtonEnabled =
66
68
  buyingPolicyNameConfirmation === buyingPolicy.name;
67
69
 
68
70
  return (
69
- <BasicDrawer {...otherProps} data-fs-bp-delete-user-drawer close={close}>
70
- <BasicDrawer.Heading title="Delete user" onClose={close} />
71
- <BasicDrawer.Body data-fs-bp-delete-user-drawer-body>
71
+ <BasicDrawer {...otherProps} data-fs-bp-delete-buying-policy-drawer close={close}>
72
+ <BasicDrawer.Heading title="Delete buying policy" onClose={close} />
73
+ <BasicDrawer.Body data-fs-bp-delete-buying-policy-drawer-body>
72
74
  <p>
73
75
  Permanently delete{" "}
74
76
  <a
@@ -105,9 +107,10 @@ export const DeleteBuyingPolicyDrawer = ({
105
107
  Cancel
106
108
  </BasicDrawer.Button>
107
109
  <BasicDrawer.Button
108
- variant="confirm"
110
+ variant="danger"
109
111
  onClick={handleDeleteClick}
110
112
  disabled={!isDeleteButtonEnabled}
113
+ isLoading={isRemoveBuyingPolicyLoading}
111
114
  >
112
115
  Delete
113
116
  </BasicDrawer.Button>
@@ -24,7 +24,7 @@ export const UpdateBuyingPolicyDrawer = ({
24
24
  buyingPolicyId,
25
25
  ...props
26
26
  }: UpdateBuyingPolicyDrawerProps) => {
27
- const { buyingPolicy } = useGetBuyingPolicy(
27
+ const { buyingPolicy, isBuyingPolicyLoading } = useGetBuyingPolicy(
28
28
  buyingPolicyId,
29
29
  orgUnitId,
30
30
  contractId
@@ -64,9 +64,9 @@ export const UpdateBuyingPolicyDrawer = ({
64
64
  useUpdateBuyingPolicy({
65
65
  onSuccess: handleUpdateBuyingPolicySuccess,
66
66
  onError: (err) => {
67
- // TODO: Handle error
68
67
  pushToast({
69
- message: "Error adding buying policy",
68
+ message: "An error occurred. Please try again.",
69
+ title: "Error",
70
70
  status: "ERROR",
71
71
  });
72
72
  },
@@ -78,10 +78,10 @@ export const UpdateBuyingPolicyDrawer = ({
78
78
  saveButtonLabel="Save"
79
79
  close={close}
80
80
  isLoading={isUpdateBuyingPolicyLoading}
81
+ isDrawerLoading={isBuyingPolicyLoading}
81
82
  onConfirm={(form) =>
82
83
  updateBuyingPolicy({
83
84
  buyingPolicyId,
84
-
85
85
  buyingPolicy: {
86
86
  ...form,
87
87
  },
@@ -8,7 +8,7 @@ export const useGetBuyingPolicy = (
8
8
  options?: QueryOptions<AwaitedType<typeof getBuyingPolicyService>>
9
9
  ) => {
10
10
  const { data, error, isLoading, refetch } = useQuery(
11
- `api/buying-policy/${id}`,
11
+ `api/buying-policies/${id}`,
12
12
  ({ cookie }) =>
13
13
  getBuyingPolicyService({
14
14
  orgUnitId,