@vtex/faststore-plugin-buyer-portal 1.3.50 → 1.3.52
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +58 -41
- package/package.json +1 -1
- package/src/features/addresses/components/CreateAddressSettingsDrawer/CreateAddressSettingsDrawer.tsx +2 -13
- package/src/features/credit-cards/components/CreditCardSettingsDrawer/CreditCardSettingsDrawer.tsx +45 -56
- package/src/features/credit-cards/layouts/CreditCardsLayout/CreditCardLayout.tsx +18 -0
- package/src/features/custom-fields/components/CustomFieldSettingsDrawer/CustomFieldSettingsDrawer.tsx +225 -49
- package/src/features/payment-methods/components/PaymentMethodSettingsDrawer/PaymentMethodSettingsDrawer.tsx +78 -0
- package/src/features/payment-methods/components/index.ts +4 -0
- package/src/features/payment-methods/layouts/PaymentMethodsLayout/PaymentMethodsLayout.tsx +19 -0
- package/src/features/product-assortment/components/CollectionsSettingsDrawer/CollectionsSettingsDrawer.tsx +77 -0
- package/src/features/product-assortment/components/index.tsx +4 -0
- package/src/features/product-assortment/layouts/ProductAssortmentLayout/ProductAssortmentLayout.tsx +22 -1
- package/src/features/shared/components/SettingsDrawer/SettingsDrawerListType.tsx +28 -16
- package/src/features/shared/components/SettingsDrawer/listTypeOptions.ts +23 -0
- package/src/features/shared/components/index.ts +5 -0
- package/src/features/shared/layouts/LoadingTabsLayout/LoadingTabsLayout.tsx +0 -13
- package/src/features/shared/utils/constants.ts +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -7,9 +7,26 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
7
7
|
|
|
8
8
|
## [Unreleased]
|
|
9
9
|
|
|
10
|
+
## [1.3.52] - 2026-01-06
|
|
11
|
+
|
|
12
|
+
### Fixed
|
|
13
|
+
|
|
14
|
+
- Removed settings object from LoadingTabs
|
|
15
|
+
|
|
16
|
+
## [1.3.51] - 2026-01-05
|
|
17
|
+
|
|
18
|
+
### Added
|
|
19
|
+
|
|
20
|
+
- Add Settings Drawers for Credit Cards, Payment Methods and Collections
|
|
21
|
+
- Implement `CreditCardSettingsDrawer` component for credit cards scope configuration
|
|
22
|
+
- Implement `PaymentMethodSettingsDrawer` component for payment methods scope configuration
|
|
23
|
+
- Implement `CollectionsSettingsDrawer` component for product assortment scope configuration
|
|
24
|
+
- Integrate settings drawers with respective layout pages
|
|
25
|
+
|
|
10
26
|
## [1.3.50] - 2025-12-19
|
|
11
27
|
|
|
12
28
|
### Changed
|
|
29
|
+
|
|
13
30
|
- Introduces several improvements and refactorings to the budget notification drawer, focusing on user experience.
|
|
14
31
|
|
|
15
32
|
## [1.3.49] - 2025-12-19
|
|
@@ -28,7 +45,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
28
45
|
- Alternative Login Keys:
|
|
29
46
|
- Add auth setup drawer
|
|
30
47
|
- Update AddUserDrawer to support username
|
|
31
|
-
|
|
48
|
+
|
|
32
49
|
## [1.3.46] - 2025-12-19
|
|
33
50
|
|
|
34
51
|
### Fixed
|
|
@@ -38,16 +55,19 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
38
55
|
## [1.3.45] - 2025-12-17
|
|
39
56
|
|
|
40
57
|
### Fixed
|
|
58
|
+
|
|
41
59
|
- Remove AwaitedType imports
|
|
42
60
|
|
|
43
61
|
## [1.3.44] - 2025-12-16
|
|
44
62
|
|
|
45
63
|
### Fixed
|
|
64
|
+
|
|
46
65
|
- Remove AwaitedType export that was breaking the application build
|
|
47
66
|
|
|
48
67
|
## [1.3.43] - 2025-12-16
|
|
49
68
|
|
|
50
69
|
### Fixed
|
|
70
|
+
|
|
51
71
|
- Update maskPhoneNumber to include country DDI
|
|
52
72
|
- Send only phone digits to API in Users and Recipients pages
|
|
53
73
|
- Show masked phone in layout and forms in Users and Recipients pages
|
|
@@ -67,6 +87,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
67
87
|
|
|
68
88
|
## [1.3.40] - 2025-12-09
|
|
69
89
|
|
|
90
|
+
### Fixed
|
|
91
|
+
|
|
70
92
|
- Fix e2e auth flow
|
|
71
93
|
|
|
72
94
|
## [1.3.39] - 2025-12-09
|
|
@@ -84,7 +106,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
84
106
|
|
|
85
107
|
## [1.3.37] - 2025-12-04
|
|
86
108
|
|
|
87
|
-
|
|
109
|
+
### Changed
|
|
88
110
|
|
|
89
111
|
- Allow Credit Card CVV to accept 4 digits
|
|
90
112
|
|
|
@@ -102,12 +124,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
102
124
|
|
|
103
125
|
## [1.3.34] - 2025-12-01
|
|
104
126
|
|
|
127
|
+
### Added
|
|
128
|
+
|
|
105
129
|
- Add generic `SettingsDrawer` component with `ListType` subcomponent for scope configuration
|
|
106
130
|
- Add Scope Config API integration (`useGetScopeConfig`, `useSetScopeConfig` hooks)
|
|
107
131
|
- Integrate Settings Drawer with Address Settings page
|
|
108
|
-
|
|
109
|
-
### Added
|
|
110
|
-
|
|
111
132
|
- Add DK Docs
|
|
112
133
|
|
|
113
134
|
### Fixed
|
|
@@ -311,6 +332,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
311
332
|
|
|
312
333
|
## [1.3.4] - 2025-10-16
|
|
313
334
|
|
|
335
|
+
### Fixed
|
|
336
|
+
|
|
314
337
|
- Error boundary:
|
|
315
338
|
- Updating the authentication loader to provide detailed error context.
|
|
316
339
|
|
|
@@ -422,21 +445,25 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
422
445
|
- Add CHANGELOG file
|
|
423
446
|
- Add README file
|
|
424
447
|
|
|
425
|
-
[unreleased]: https://github.com/vtex/faststore-plugin-buyer-portal/compare/v1.3.
|
|
426
|
-
[1.
|
|
427
|
-
[1.
|
|
428
|
-
[1.
|
|
429
|
-
[1.3.
|
|
430
|
-
[1.3.
|
|
431
|
-
[1.3.
|
|
432
|
-
[1.3.
|
|
433
|
-
[1.3.
|
|
434
|
-
[1.3.
|
|
435
|
-
[1.3.
|
|
436
|
-
[1.3.
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
448
|
+
[unreleased]: https://github.com/vtex/faststore-plugin-buyer-portal/compare/v1.3.52...HEAD
|
|
449
|
+
[1.3.52]: https://github.com/vtex/faststore-plugin-buyer-portal/compare/v1.3.51...v1.3.52
|
|
450
|
+
[1.3.51]: https://github.com/vtex/faststore-plugin-buyer-portal/compare/v1.3.50...v1.3.51
|
|
451
|
+
[1.3.50]: https://github.com/vtex/faststore-plugin-buyer-portal/compare/v1.3.49...v1.3.50
|
|
452
|
+
[1.3.49]: https://github.com/vtex/faststore-plugin-buyer-portal/compare/v1.3.48...v1.3.49
|
|
453
|
+
[1.3.48]: https://github.com/vtex/faststore-plugin-buyer-portal/compare/v1.3.47...v1.3.48
|
|
454
|
+
[1.3.47]: https://github.com/vtex/faststore-plugin-buyer-portal/compare/v1.3.46...v1.3.47
|
|
455
|
+
[1.3.46]: https://github.com/vtex/faststore-plugin-buyer-portal/compare/v1.3.45...v1.3.46
|
|
456
|
+
[1.3.45]: https://github.com/vtex/faststore-plugin-buyer-portal/compare/v1.3.44...v1.3.45
|
|
457
|
+
[1.3.44]: https://github.com/vtex/faststore-plugin-buyer-portal/compare/v1.3.43...v1.3.44
|
|
458
|
+
[1.3.43]: https://github.com/vtex/faststore-plugin-buyer-portal/compare/v1.3.42...v1.3.43
|
|
459
|
+
[1.3.42]: https://github.com/vtex/faststore-plugin-buyer-portal/releases/tag/1.3.42
|
|
460
|
+
[1.3.41]: https://github.com/vtex/faststore-plugin-buyer-portal/compare/v1.3.40...v1.3.41
|
|
461
|
+
[1.3.40]: https://github.com/vtex/faststore-plugin-buyer-portal/compare/v1.3.39...v1.3.40
|
|
462
|
+
[1.3.39]: https://github.com/vtex/faststore-plugin-buyer-portal/compare/v1.3.38...v1.3.39
|
|
463
|
+
[1.3.38]: https://github.com/vtex/faststore-plugin-buyer-portal/compare/v1.3.37...v1.3.38
|
|
464
|
+
[1.3.37]: https://github.com/vtex/faststore-plugin-buyer-portal/compare/v1.3.36...v1.3.37
|
|
465
|
+
[1.3.36]: https://github.com/vtex/faststore-plugin-buyer-portal/compare/v1.3.35...v1.3.36
|
|
466
|
+
[1.3.35]: https://github.com/vtex/faststore-plugin-buyer-portal/releases/tag/1.3.35
|
|
440
467
|
[1.3.34]: https://github.com/vtex/faststore-plugin-buyer-portal/compare/v1.3.33...v1.3.34
|
|
441
468
|
[1.3.33]: https://github.com/vtex/faststore-plugin-buyer-portal/compare/v1.3.32...v1.3.33
|
|
442
469
|
[1.3.32]: https://github.com/vtex/faststore-plugin-buyer-portal/compare/v1.3.31...v1.3.32
|
|
@@ -460,24 +487,14 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
460
487
|
[1.3.14]: https://github.com/vtex/faststore-plugin-buyer-portal/compare/v1.3.13...v1.3.14
|
|
461
488
|
[1.3.13]: https://github.com/vtex/faststore-plugin-buyer-portal/compare/v1.3.12...v1.3.13
|
|
462
489
|
[1.3.12]: https://github.com/vtex/faststore-plugin-buyer-portal/compare/v1.3.11...v1.3.12
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
[1.3.
|
|
468
|
-
[1.3.
|
|
469
|
-
[1.3.
|
|
470
|
-
[1.3.
|
|
471
|
-
[1.3.
|
|
472
|
-
[1.
|
|
473
|
-
[1.3
|
|
474
|
-
|
|
475
|
-
[1.3.50]: https://github.com/vtex/faststore-plugin-buyer-portal/compare/v1.3.49...v1.3.50
|
|
476
|
-
[1.3.49]: https://github.com/vtex/faststore-plugin-buyer-portal/compare/v1.3.48...v1.3.49
|
|
477
|
-
[1.3.48]: https://github.com/vtex/faststore-plugin-buyer-portal/compare/v1.3.47...v1.3.48
|
|
478
|
-
[1.3.47]: https://github.com/vtex/faststore-plugin-buyer-portal/compare/v1.3.46...v1.3.47
|
|
479
|
-
[1.3.46]: https://github.com/vtex/faststore-plugin-buyer-portal/compare/v1.3.45...v1.3.46
|
|
480
|
-
[1.3.45]: https://github.com/vtex/faststore-plugin-buyer-portal/compare/v1.3.44...v1.3.45
|
|
481
|
-
[1.3.44]: https://github.com/vtex/faststore-plugin-buyer-portal/compare/v1.3.43...v1.3.44
|
|
482
|
-
[1.3.43]: https://github.com/vtex/faststore-plugin-buyer-portal/compare/v1.3.42...v1.3.43
|
|
483
|
-
[1.3.42]: https://github.com/vtex/faststore-plugin-buyer-portal/releases/tag/1.3.42
|
|
490
|
+
[1.3.11]: https://github.com/vtex/faststore-plugin-buyer-portal/releases/tag/1.3.11
|
|
491
|
+
[1.3.9]: https://github.com/vtex/faststore-plugin-buyer-portal/compare/v1.3.8...v1.3.9
|
|
492
|
+
[1.3.8]: https://github.com/vtex/faststore-plugin-buyer-portal/compare/v1.3.7...v1.3.8
|
|
493
|
+
[1.3.7]: https://github.com/vtex/faststore-plugin-buyer-portal/releases/tag/1.3.7
|
|
494
|
+
[1.3.6]: https://github.com/vtex/faststore-plugin-buyer-portal/releases/tag/1.3.6
|
|
495
|
+
[1.3.5]: https://github.com/vtex/faststore-plugin-buyer-portal/releases/tag/1.3.5
|
|
496
|
+
[1.3.4]: https://github.com/vtex/faststore-plugin-buyer-portal/releases/tag/1.3.4
|
|
497
|
+
[1.3.3]: https://github.com/vtex/faststore-plugin-buyer-portal/releases/tag/1.3.3
|
|
498
|
+
[1.3.2]: https://github.com/vtex/faststore-plugin-buyer-portal/releases/tag/1.3.2
|
|
499
|
+
[1.2.4]: https://github.com/vtex/faststore-plugin-buyer-portal/releases/tag/1.2.4
|
|
500
|
+
[1.2.3]: https://github.com/vtex/faststore-plugin-buyer-portal/releases/tag/1.2.3
|
package/package.json
CHANGED
|
@@ -7,10 +7,9 @@ import { useUI, Skeleton } from "@faststore/ui";
|
|
|
7
7
|
import {
|
|
8
8
|
type BasicDrawerProps,
|
|
9
9
|
AutocompleteDropdown,
|
|
10
|
-
DEFAULT_LIST_TYPE_OPTIONS,
|
|
11
10
|
Icon,
|
|
12
|
-
ListTypeOption,
|
|
13
11
|
SettingsDrawer,
|
|
12
|
+
createListTypeOptions,
|
|
14
13
|
} from "../../../shared/components";
|
|
15
14
|
import { OptionSelected } from "../../../shared/components/OptionSelected/OptionSelected";
|
|
16
15
|
import { SearchHighlight } from "../../../shared/components/SearchHighlight/SearchHighlight";
|
|
@@ -31,17 +30,7 @@ export type CreateAddressSettingsDrawerProps = Omit<
|
|
|
31
30
|
onUpdate?: () => void;
|
|
32
31
|
};
|
|
33
32
|
|
|
34
|
-
export const ADDRESS_LIST_TYPE_OPTIONS
|
|
35
|
-
{
|
|
36
|
-
...DEFAULT_LIST_TYPE_OPTIONS[0],
|
|
37
|
-
description: "Manage a unique list of addresses for this organization.",
|
|
38
|
-
},
|
|
39
|
-
{
|
|
40
|
-
...DEFAULT_LIST_TYPE_OPTIONS[1],
|
|
41
|
-
description:
|
|
42
|
-
"Use the shared list of addresses defined by the contract. Updates are automatic.",
|
|
43
|
-
},
|
|
44
|
-
];
|
|
33
|
+
export const ADDRESS_LIST_TYPE_OPTIONS = createListTypeOptions("addresses");
|
|
45
34
|
|
|
46
35
|
export const CreateAddressSettingsDrawer = ({
|
|
47
36
|
close,
|
package/src/features/credit-cards/components/CreditCardSettingsDrawer/CreditCardSettingsDrawer.tsx
CHANGED
|
@@ -6,11 +6,10 @@ import { useUI } from "@faststore/ui";
|
|
|
6
6
|
|
|
7
7
|
import {
|
|
8
8
|
type BasicDrawerProps,
|
|
9
|
-
|
|
10
|
-
|
|
9
|
+
SettingsDrawer,
|
|
10
|
+
createListTypeOptions,
|
|
11
11
|
} from "../../../shared/components";
|
|
12
|
-
|
|
13
|
-
import type { CreditCard } from "../../types";
|
|
12
|
+
import { useSetScopeConfig, SCOPE_KEYS } from "../../../shared/hooks";
|
|
14
13
|
|
|
15
14
|
export type CreditCardSettingsDrawerProps = Omit<
|
|
16
15
|
BasicDrawerProps,
|
|
@@ -19,70 +18,60 @@ export type CreditCardSettingsDrawerProps = Omit<
|
|
|
19
18
|
readonly?: boolean;
|
|
20
19
|
};
|
|
21
20
|
|
|
21
|
+
const CREDIT_CARD_LIST_TYPE_OPTIONS = createListTypeOptions("credit cards");
|
|
22
|
+
|
|
22
23
|
export const CreditCardSettingsDrawer = ({
|
|
23
24
|
close,
|
|
24
|
-
...
|
|
25
|
+
...otherProps
|
|
25
26
|
}: CreditCardSettingsDrawerProps) => {
|
|
26
27
|
const { pushToast } = useUI();
|
|
27
|
-
|
|
28
28
|
const router = useRouter();
|
|
29
|
-
|
|
29
|
+
|
|
30
|
+
const [listType, setListType] = useState<"sync" | "custom">("custom");
|
|
31
|
+
|
|
32
|
+
const { setScopeConfig, isSetScopeConfigLoading } = useSetScopeConfig({
|
|
33
|
+
onSuccess: () => {
|
|
34
|
+
pushToast({
|
|
35
|
+
message: "Scope configuration updated successfully",
|
|
36
|
+
status: "INFO",
|
|
37
|
+
});
|
|
38
|
+
close();
|
|
39
|
+
},
|
|
40
|
+
onError: () => {
|
|
41
|
+
pushToast({
|
|
42
|
+
message: "Failed to update scope configuration",
|
|
43
|
+
status: "ERROR",
|
|
44
|
+
});
|
|
45
|
+
},
|
|
46
|
+
});
|
|
30
47
|
|
|
31
48
|
const handleConfirmClick = () => {
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
49
|
+
setScopeConfig({
|
|
50
|
+
customerId: router.query.contractId as string,
|
|
51
|
+
unitId: router.query.orgUnitId as string,
|
|
52
|
+
scopeName: SCOPE_KEYS.CREDIT_CARDS,
|
|
53
|
+
type: listType,
|
|
35
54
|
});
|
|
36
|
-
router.reload();
|
|
37
|
-
close();
|
|
38
55
|
};
|
|
39
56
|
|
|
40
|
-
const hasCardInformation = () => {
|
|
41
|
-
return (
|
|
42
|
-
newCard.cardholder &&
|
|
43
|
-
newCard.cardLabel &&
|
|
44
|
-
newCard.cvv &&
|
|
45
|
-
newCard.expirationDate &&
|
|
46
|
-
newCard.number
|
|
47
|
-
);
|
|
48
|
-
};
|
|
49
|
-
|
|
50
|
-
const isConfirmButtonEnabled = hasCardInformation();
|
|
51
|
-
|
|
52
57
|
return (
|
|
53
|
-
<
|
|
54
|
-
|
|
58
|
+
<SettingsDrawer
|
|
59
|
+
title="Credit cards settings"
|
|
60
|
+
{...otherProps}
|
|
55
61
|
close={close}
|
|
56
|
-
{
|
|
62
|
+
onPrimaryAction={handleConfirmClick}
|
|
63
|
+
isPrimaryButtonLoading={isSetScopeConfigLoading}
|
|
64
|
+
scopeName={SCOPE_KEYS.CREDIT_CARDS}
|
|
65
|
+
onDismiss={close}
|
|
66
|
+
data-fs-bp-edit-credit-card-settings-drawer
|
|
57
67
|
>
|
|
58
|
-
<
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
wrapperProps={{ style: { marginTop: 16 } }}
|
|
67
|
-
onChange={(event) =>
|
|
68
|
-
setNewCard({ ...newCard, cardLabel: event.target.value })
|
|
69
|
-
}
|
|
70
|
-
/>
|
|
71
|
-
</BasicDrawer.Body>
|
|
72
|
-
|
|
73
|
-
<BasicDrawer.Footer>
|
|
74
|
-
<BasicDrawer.Button variant="ghost" onClick={close}>
|
|
75
|
-
Cancel
|
|
76
|
-
</BasicDrawer.Button>
|
|
77
|
-
<BasicDrawer.Button
|
|
78
|
-
variant="confirm"
|
|
79
|
-
disabled={!isConfirmButtonEnabled}
|
|
80
|
-
onClick={handleConfirmClick}
|
|
81
|
-
isLoading={false}
|
|
82
|
-
>
|
|
83
|
-
Save
|
|
84
|
-
</BasicDrawer.Button>
|
|
85
|
-
</BasicDrawer.Footer>
|
|
86
|
-
</BasicDrawer>
|
|
68
|
+
<SettingsDrawer.ListType
|
|
69
|
+
title="List type"
|
|
70
|
+
name="credit-card-list-type"
|
|
71
|
+
value={listType}
|
|
72
|
+
onChange={setListType}
|
|
73
|
+
options={CREDIT_CARD_LIST_TYPE_OPTIONS}
|
|
74
|
+
/>
|
|
75
|
+
</SettingsDrawer>
|
|
87
76
|
);
|
|
88
77
|
};
|
|
@@ -19,6 +19,7 @@ import {
|
|
|
19
19
|
CreateCreditCardDrawer,
|
|
20
20
|
CreditCardDropdownMenu,
|
|
21
21
|
} from "../../components";
|
|
22
|
+
import { CreditCardSettingsDrawer } from "../../components/CreditCardSettingsDrawer/CreditCardSettingsDrawer";
|
|
22
23
|
import { useChangeCardScope } from "../../hooks";
|
|
23
24
|
import { useGetCreditCards } from "../../hooks/useGetCreditCards";
|
|
24
25
|
|
|
@@ -35,6 +36,12 @@ export const CreditCardLayout = ({ data }: CreditCardsLayoutProps) => {
|
|
|
35
36
|
...createDrawerProps
|
|
36
37
|
} = useDrawerProps();
|
|
37
38
|
|
|
39
|
+
const {
|
|
40
|
+
open: openCreateCreditCardSettingsDrawer,
|
|
41
|
+
isOpen: isCreateCreditCardSettingsDrawerOpen,
|
|
42
|
+
...createCreditCardSettingsDrawerProps
|
|
43
|
+
} = useDrawerProps();
|
|
44
|
+
|
|
38
45
|
const {
|
|
39
46
|
currentOrgUnit: orgUnit,
|
|
40
47
|
currentUser: user,
|
|
@@ -137,6 +144,11 @@ export const CreditCardLayout = ({ data }: CreditCardsLayoutProps) => {
|
|
|
137
144
|
>
|
|
138
145
|
<section data-fs-credit-card-section>
|
|
139
146
|
<HeaderInside title="Credit cards">
|
|
147
|
+
<HeaderInside.Button
|
|
148
|
+
iconName="EditSettings"
|
|
149
|
+
style={{ backgroundColor: "transparent", color: "#1f1f1f" }}
|
|
150
|
+
onClick={openCreateCreditCardSettingsDrawer}
|
|
151
|
+
/>
|
|
140
152
|
<HeaderInside.Button onClick={openCreateDrawer} />
|
|
141
153
|
</HeaderInside>
|
|
142
154
|
{data.length === 0 ? (
|
|
@@ -173,6 +185,12 @@ export const CreditCardLayout = ({ data }: CreditCardsLayoutProps) => {
|
|
|
173
185
|
isOpen={isCreateCreditCardDrawerOpen}
|
|
174
186
|
/>
|
|
175
187
|
)}
|
|
188
|
+
{isCreateCreditCardSettingsDrawerOpen && (
|
|
189
|
+
<CreditCardSettingsDrawer
|
|
190
|
+
isOpen={isCreateCreditCardSettingsDrawerOpen}
|
|
191
|
+
{...createCreditCardSettingsDrawerProps}
|
|
192
|
+
/>
|
|
193
|
+
)}
|
|
176
194
|
</section>
|
|
177
195
|
</ContractTabsLayout>
|
|
178
196
|
</GlobalLayout>
|
|
@@ -1,10 +1,19 @@
|
|
|
1
|
-
import { useState } from "react";
|
|
1
|
+
import { useEffect, useMemo, useState } from "react";
|
|
2
2
|
|
|
3
|
-
import { useUI } from "@faststore/ui";
|
|
3
|
+
import { RadioGroup, RadioOption, useUI } from "@faststore/ui";
|
|
4
4
|
|
|
5
|
-
import {
|
|
6
|
-
|
|
7
|
-
|
|
5
|
+
import {
|
|
6
|
+
AutocompleteDropdown,
|
|
7
|
+
SettingsDrawer,
|
|
8
|
+
type BasicDrawerProps,
|
|
9
|
+
createListTypeOptions,
|
|
10
|
+
} from "../../../shared/components";
|
|
11
|
+
import { CustomFieldSelectedCardItem } from "../../../shared/components/CustomField/selected-card-item/CustomFieldSelectedCardItem";
|
|
12
|
+
import {
|
|
13
|
+
useBuyerPortal,
|
|
14
|
+
useDebounce,
|
|
15
|
+
useSetScopeConfig,
|
|
16
|
+
} from "../../../shared/hooks";
|
|
8
17
|
import {
|
|
9
18
|
useAddDefaultValue,
|
|
10
19
|
useCustomFieldValues,
|
|
@@ -15,6 +24,12 @@ import {
|
|
|
15
24
|
import { useCustomFieldSettings } from "../../../shared/hooks/custom-field/useCustomFieldSettings";
|
|
16
25
|
import { CustomFieldData } from "../../types";
|
|
17
26
|
|
|
27
|
+
type FormState = {
|
|
28
|
+
level: string;
|
|
29
|
+
required: boolean;
|
|
30
|
+
defaultValue: CustomFieldData | null;
|
|
31
|
+
};
|
|
32
|
+
|
|
18
33
|
export interface CustomFieldSettingsDrawerProps
|
|
19
34
|
extends Omit<BasicDrawerProps, "children"> {
|
|
20
35
|
contractId: string;
|
|
@@ -30,6 +45,8 @@ export function CustomFieldSettingsDrawer({
|
|
|
30
45
|
unitId,
|
|
31
46
|
close,
|
|
32
47
|
refetch,
|
|
48
|
+
loading = false,
|
|
49
|
+
onDismiss,
|
|
33
50
|
...props
|
|
34
51
|
}: CustomFieldSettingsDrawerProps) {
|
|
35
52
|
const {
|
|
@@ -40,8 +57,23 @@ export function CustomFieldSettingsDrawer({
|
|
|
40
57
|
CustomFieldData[]
|
|
41
58
|
>([]);
|
|
42
59
|
const [search, setSearch] = useState<string>("");
|
|
60
|
+
const [formData, setFormData] = useState<FormState>({
|
|
61
|
+
level: "",
|
|
62
|
+
required: false,
|
|
63
|
+
defaultValue: null,
|
|
64
|
+
});
|
|
65
|
+
const [autoCompleteValue, setAutocompleteValue] = useState<string>("");
|
|
66
|
+
const [listType, setListType] = useState<"sync" | "custom">("custom");
|
|
43
67
|
|
|
44
68
|
const debouncedSearchValue = useDebounce(search, 200);
|
|
69
|
+
const customFieldScopeName = useMemo(
|
|
70
|
+
() => `custom-fields/${customField}`,
|
|
71
|
+
[customField]
|
|
72
|
+
);
|
|
73
|
+
const customFieldPlural = useMemo(
|
|
74
|
+
() => `${customField.toLowerCase()}s`,
|
|
75
|
+
[customField]
|
|
76
|
+
);
|
|
45
77
|
|
|
46
78
|
const {
|
|
47
79
|
data: customFieldSettings,
|
|
@@ -72,7 +104,7 @@ export function CustomFieldSettingsDrawer({
|
|
|
72
104
|
|
|
73
105
|
const {
|
|
74
106
|
mutate: updateCustomFieldSettings,
|
|
75
|
-
isLoading:
|
|
107
|
+
isLoading: isLoadingUpdateCustomFieldSettings,
|
|
76
108
|
} = useUpdateCustomFieldSettings({
|
|
77
109
|
options: {
|
|
78
110
|
onSuccess: () =>
|
|
@@ -114,6 +146,14 @@ export function CustomFieldSettingsDrawer({
|
|
|
114
146
|
},
|
|
115
147
|
});
|
|
116
148
|
|
|
149
|
+
const { setScopeConfig, isSetScopeConfigLoading } = useSetScopeConfig({
|
|
150
|
+
onError: () =>
|
|
151
|
+
pushToast({
|
|
152
|
+
status: "ERROR",
|
|
153
|
+
message: "Failed to update scope configuration",
|
|
154
|
+
}),
|
|
155
|
+
});
|
|
156
|
+
|
|
117
157
|
useCustomFieldValues({
|
|
118
158
|
keys: `default-values/options/${debouncedSearchValue}`,
|
|
119
159
|
data: {
|
|
@@ -140,63 +180,199 @@ export function CustomFieldSettingsDrawer({
|
|
|
140
180
|
},
|
|
141
181
|
});
|
|
142
182
|
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
183
|
+
const listTypeOptions = useMemo(
|
|
184
|
+
() => createListTypeOptions(customFieldPlural),
|
|
185
|
+
[customFieldPlural]
|
|
186
|
+
);
|
|
187
|
+
|
|
188
|
+
useEffect(() => {
|
|
189
|
+
setFormData({
|
|
190
|
+
level: customFieldSettings?.level ?? "",
|
|
191
|
+
required: !!customFieldSettings?.required,
|
|
192
|
+
defaultValue: defaultValueData
|
|
193
|
+
? { ...defaultValueData, isDefault: true }
|
|
194
|
+
: null,
|
|
195
|
+
});
|
|
196
|
+
}, [customFieldSettings, defaultValueData]);
|
|
197
|
+
|
|
198
|
+
const handleClose = () => {
|
|
199
|
+
onDismiss?.();
|
|
200
|
+
close();
|
|
201
|
+
setSearch("");
|
|
202
|
+
setAutocompleteValue("");
|
|
203
|
+
};
|
|
204
|
+
|
|
205
|
+
const handleSave = async () => {
|
|
206
|
+
if (formData.defaultValue) {
|
|
149
207
|
await updateDefaultValue({
|
|
150
208
|
contractId,
|
|
151
209
|
customField,
|
|
152
|
-
customFieldValueId:
|
|
210
|
+
customFieldValueId: formData.defaultValue.id,
|
|
153
211
|
unitId,
|
|
154
212
|
});
|
|
155
213
|
} else {
|
|
156
214
|
await removeDefaultValue({ contractId, customField, unitId });
|
|
157
215
|
}
|
|
158
216
|
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
217
|
+
await Promise.all([
|
|
218
|
+
updateCustomFieldSettings({
|
|
219
|
+
cookie,
|
|
220
|
+
data: {
|
|
221
|
+
contractId,
|
|
222
|
+
unitId,
|
|
223
|
+
customField,
|
|
224
|
+
level: formData.level,
|
|
225
|
+
required: formData.required,
|
|
226
|
+
},
|
|
227
|
+
}),
|
|
228
|
+
setScopeConfig({
|
|
229
|
+
customerId: contractId,
|
|
163
230
|
unitId,
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
231
|
+
scopeName: customFieldScopeName,
|
|
232
|
+
type: listType,
|
|
233
|
+
}),
|
|
234
|
+
]);
|
|
235
|
+
|
|
236
|
+
handleClose();
|
|
237
|
+
refetch();
|
|
238
|
+
};
|
|
239
|
+
|
|
240
|
+
const isSavingSettings =
|
|
241
|
+
isLoadingUpdateDefaultValue ||
|
|
242
|
+
isLoadingRemoveDefaultValue ||
|
|
243
|
+
isLoadingUpdateCustomFieldSettings ||
|
|
244
|
+
isSetScopeConfigLoading ||
|
|
245
|
+
loading;
|
|
246
|
+
|
|
247
|
+
const isPrimaryButtonDisabled =
|
|
248
|
+
(!formData.defaultValue?.id && !!autoCompleteValue) || isSavingSettings;
|
|
170
249
|
|
|
171
250
|
if (isLoading || isLoadingDefaultValue || error) return null;
|
|
172
251
|
|
|
173
252
|
return (
|
|
174
|
-
<
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
}
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
onSave={async ({ level, required, defaultValue }) => {
|
|
187
|
-
await onSave(level, required, defaultValue);
|
|
188
|
-
close();
|
|
189
|
-
refetch();
|
|
190
|
-
}}
|
|
191
|
-
loading={
|
|
192
|
-
isLoadingUpdateDefaultValue ||
|
|
193
|
-
isLoadingRemoveDefaultValue ||
|
|
194
|
-
isLoadginUpdateCustomFieldSettings
|
|
195
|
-
}
|
|
196
|
-
onSearch={setSearch}
|
|
197
|
-
customFieldOptions={customFieldOptions}
|
|
198
|
-
customFieldLabel={customField}
|
|
253
|
+
<SettingsDrawer
|
|
254
|
+
title={`${customField} settings`}
|
|
255
|
+
close={close}
|
|
256
|
+
onPrimaryAction={handleSave}
|
|
257
|
+
onSecondaryAction={handleClose}
|
|
258
|
+
onDismiss={handleClose}
|
|
259
|
+
isPrimaryButtonLoading={isSavingSettings}
|
|
260
|
+
isPrimaryButtonDisabled={isPrimaryButtonDisabled}
|
|
261
|
+
scopeName={customFieldScopeName}
|
|
262
|
+
customerId={contractId}
|
|
263
|
+
unitId={unitId}
|
|
264
|
+
data-bp-custom-fields-settings-drawer
|
|
199
265
|
{...props}
|
|
200
|
-
|
|
266
|
+
>
|
|
267
|
+
<div data-bp-settings-drawer-body>
|
|
268
|
+
<p>
|
|
269
|
+
Set how buyers in this unit should enter {customField}s during
|
|
270
|
+
checkout
|
|
271
|
+
</p>
|
|
272
|
+
|
|
273
|
+
<SettingsDrawer.ListType
|
|
274
|
+
title="List type"
|
|
275
|
+
name={`${customField}-list-type`}
|
|
276
|
+
value={listType}
|
|
277
|
+
onChange={setListType}
|
|
278
|
+
options={listTypeOptions}
|
|
279
|
+
/>
|
|
280
|
+
|
|
281
|
+
<form data-bp-custom-fields-settings-drawer-form>
|
|
282
|
+
<div>
|
|
283
|
+
<h4>Input level</h4>
|
|
284
|
+
<RadioGroup
|
|
285
|
+
name="inputLevel"
|
|
286
|
+
selectedValue={formData.level}
|
|
287
|
+
onChange={(e) => {
|
|
288
|
+
setFormData((curr) => ({
|
|
289
|
+
...curr,
|
|
290
|
+
level: e.target.value,
|
|
291
|
+
}));
|
|
292
|
+
}}
|
|
293
|
+
>
|
|
294
|
+
<RadioOption value="order" label="Order level" name="inputLevel">
|
|
295
|
+
Order level
|
|
296
|
+
</RadioOption>
|
|
297
|
+
|
|
298
|
+
<RadioOption value="item" label="Item level" name="inputLevel">
|
|
299
|
+
Item level
|
|
300
|
+
</RadioOption>
|
|
301
|
+
</RadioGroup>
|
|
302
|
+
</div>
|
|
303
|
+
|
|
304
|
+
<div>
|
|
305
|
+
<h4>Input requirement</h4>
|
|
306
|
+
<RadioGroup
|
|
307
|
+
name="requirement"
|
|
308
|
+
selectedValue={formData.required.toString()}
|
|
309
|
+
onChange={(e) => {
|
|
310
|
+
setFormData((curr) => ({
|
|
311
|
+
...curr,
|
|
312
|
+
required: e.target.value === "true",
|
|
313
|
+
}));
|
|
314
|
+
}}
|
|
315
|
+
>
|
|
316
|
+
<RadioOption value="true" label="Required" name="requirement">
|
|
317
|
+
Required
|
|
318
|
+
</RadioOption>
|
|
319
|
+
|
|
320
|
+
<RadioOption value="false" label="Optional" name="requirement">
|
|
321
|
+
Optional
|
|
322
|
+
</RadioOption>
|
|
323
|
+
</RadioGroup>
|
|
324
|
+
</div>
|
|
325
|
+
|
|
326
|
+
<div data-bp-settings-drawer-autocomplete-dropdown-container>
|
|
327
|
+
<h4>Default {customField}</h4>
|
|
328
|
+
<span>Select the default {customField} for this unit.</span>
|
|
329
|
+
|
|
330
|
+
{formData.defaultValue?.id ? (
|
|
331
|
+
<CustomFieldSelectedCardItem
|
|
332
|
+
text={formData.defaultValue.value}
|
|
333
|
+
onCancel={() => {
|
|
334
|
+
setFormData((curr) => ({
|
|
335
|
+
...curr,
|
|
336
|
+
defaultValue: null,
|
|
337
|
+
}));
|
|
338
|
+
setAutocompleteValue("");
|
|
339
|
+
setSearch("");
|
|
340
|
+
}}
|
|
341
|
+
/>
|
|
342
|
+
) : (
|
|
343
|
+
<AutocompleteDropdown
|
|
344
|
+
label=""
|
|
345
|
+
value={autoCompleteValue}
|
|
346
|
+
options={customFieldOptions}
|
|
347
|
+
shouldOpenOnFocus={false}
|
|
348
|
+
autoComplete="off"
|
|
349
|
+
shouldShowArrowDown={false}
|
|
350
|
+
onChange={(v) => {
|
|
351
|
+
setAutocompleteValue(v.target.value);
|
|
352
|
+
setSearch(v.target.value);
|
|
353
|
+
}}
|
|
354
|
+
placeholder={`Search by ${customField} name`}
|
|
355
|
+
renderOption={(option, index) => (
|
|
356
|
+
<AutocompleteDropdown.Item
|
|
357
|
+
key={option.id}
|
|
358
|
+
closeOnClick
|
|
359
|
+
index={index}
|
|
360
|
+
isSelected={formData.defaultValue?.id === option?.id}
|
|
361
|
+
onClick={() => {
|
|
362
|
+
setFormData((curr) => ({
|
|
363
|
+
...curr,
|
|
364
|
+
defaultValue: option,
|
|
365
|
+
}));
|
|
366
|
+
}}
|
|
367
|
+
>
|
|
368
|
+
{option?.value}
|
|
369
|
+
</AutocompleteDropdown.Item>
|
|
370
|
+
)}
|
|
371
|
+
/>
|
|
372
|
+
)}
|
|
373
|
+
</div>
|
|
374
|
+
</form>
|
|
375
|
+
</div>
|
|
376
|
+
</SettingsDrawer>
|
|
201
377
|
);
|
|
202
378
|
}
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import { useState } from "react";
|
|
2
|
+
|
|
3
|
+
import { useRouter } from "next/router";
|
|
4
|
+
|
|
5
|
+
import { useUI } from "@faststore/ui";
|
|
6
|
+
|
|
7
|
+
import {
|
|
8
|
+
type BasicDrawerProps,
|
|
9
|
+
SettingsDrawer,
|
|
10
|
+
createListTypeOptions,
|
|
11
|
+
} from "../../../shared/components";
|
|
12
|
+
import { useSetScopeConfig, SCOPE_KEYS } from "../../../shared/hooks";
|
|
13
|
+
|
|
14
|
+
export type PaymentMethodSettingsDrawerProps = Omit<
|
|
15
|
+
BasicDrawerProps,
|
|
16
|
+
"children"
|
|
17
|
+
> & {
|
|
18
|
+
readonly?: boolean;
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
const PAYMENT_METHOD_LIST_TYPE_OPTIONS =
|
|
22
|
+
createListTypeOptions("payment methods");
|
|
23
|
+
|
|
24
|
+
export const PaymentMethodSettingsDrawer = ({
|
|
25
|
+
close,
|
|
26
|
+
...otherProps
|
|
27
|
+
}: PaymentMethodSettingsDrawerProps) => {
|
|
28
|
+
const { pushToast } = useUI();
|
|
29
|
+
const router = useRouter();
|
|
30
|
+
|
|
31
|
+
const [listType, setListType] = useState<"sync" | "custom">("custom");
|
|
32
|
+
|
|
33
|
+
const { setScopeConfig, isSetScopeConfigLoading } = useSetScopeConfig({
|
|
34
|
+
onSuccess: () => {
|
|
35
|
+
pushToast({
|
|
36
|
+
message: "Scope configuration updated successfully",
|
|
37
|
+
status: "INFO",
|
|
38
|
+
});
|
|
39
|
+
close();
|
|
40
|
+
},
|
|
41
|
+
onError: () => {
|
|
42
|
+
pushToast({
|
|
43
|
+
message: "Failed to update scope configuration",
|
|
44
|
+
status: "ERROR",
|
|
45
|
+
});
|
|
46
|
+
},
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
const handleConfirmClick = () => {
|
|
50
|
+
setScopeConfig({
|
|
51
|
+
customerId: router.query.contractId as string,
|
|
52
|
+
unitId: router.query.orgUnitId as string,
|
|
53
|
+
scopeName: SCOPE_KEYS.PAYMENT_SYSTEMS,
|
|
54
|
+
type: listType,
|
|
55
|
+
});
|
|
56
|
+
};
|
|
57
|
+
|
|
58
|
+
return (
|
|
59
|
+
<SettingsDrawer
|
|
60
|
+
title="Payment method settings"
|
|
61
|
+
{...otherProps}
|
|
62
|
+
close={close}
|
|
63
|
+
onPrimaryAction={handleConfirmClick}
|
|
64
|
+
isPrimaryButtonLoading={isSetScopeConfigLoading}
|
|
65
|
+
scopeName={SCOPE_KEYS.PAYMENT_SYSTEMS}
|
|
66
|
+
onDismiss={close}
|
|
67
|
+
data-fs-bp-payment-method-settings-drawer
|
|
68
|
+
>
|
|
69
|
+
<SettingsDrawer.ListType
|
|
70
|
+
title="List type"
|
|
71
|
+
name="payment-method-list-type"
|
|
72
|
+
value={listType}
|
|
73
|
+
onChange={setListType}
|
|
74
|
+
options={PAYMENT_METHOD_LIST_TYPE_OPTIONS}
|
|
75
|
+
/>
|
|
76
|
+
</SettingsDrawer>
|
|
77
|
+
);
|
|
78
|
+
};
|
|
@@ -2,3 +2,7 @@ export { AddPaymentMethodsDrawer } from "./AddPaymentMethodsDrawer/AddPaymentMet
|
|
|
2
2
|
export { RemovePaymentMethodsDrawer } from "./RemovePaymentMethodsDrawer/RemovePaymentMethodsDrawer";
|
|
3
3
|
export { RemoveMethodButton } from "./RemoveMethodButton/RemoveMethodButton";
|
|
4
4
|
export { SearchPaymentMethods } from "./SearchPaymentMethods/SearchPaymentMethods";
|
|
5
|
+
export {
|
|
6
|
+
PaymentMethodSettingsDrawer,
|
|
7
|
+
type PaymentMethodSettingsDrawerProps,
|
|
8
|
+
} from "./PaymentMethodSettingsDrawer/PaymentMethodSettingsDrawer";
|
|
@@ -19,6 +19,7 @@ import {
|
|
|
19
19
|
AddPaymentMethodsDrawer,
|
|
20
20
|
RemoveMethodButton,
|
|
21
21
|
RemovePaymentMethodsDrawer,
|
|
22
|
+
PaymentMethodSettingsDrawer,
|
|
22
23
|
} from "../../components";
|
|
23
24
|
import { useRemovePaymentMethod } from "../../hooks/useRemovePaymentMethodSubmit";
|
|
24
25
|
|
|
@@ -66,6 +67,12 @@ export const PaymentMethodsLayout = ({
|
|
|
66
67
|
...addDrawerProps
|
|
67
68
|
} = useDrawerProps();
|
|
68
69
|
|
|
70
|
+
const {
|
|
71
|
+
open: openPaymentMethodSettingsDrawer,
|
|
72
|
+
isOpen: isPaymentMethodSettingsDrawerOpen,
|
|
73
|
+
...paymentMethodSettingsDrawerProps
|
|
74
|
+
} = useDrawerProps();
|
|
75
|
+
|
|
69
76
|
const {
|
|
70
77
|
open: openRemoveDrawer,
|
|
71
78
|
isOpen: isRemovePaymentMethodDrawerOpen,
|
|
@@ -153,6 +160,11 @@ export const PaymentMethodsLayout = ({
|
|
|
153
160
|
>
|
|
154
161
|
<section data-fs-payment-methods-section>
|
|
155
162
|
<HeaderInside title="Payment methods">
|
|
163
|
+
<HeaderInside.Button
|
|
164
|
+
iconName="EditSettings"
|
|
165
|
+
style={{ backgroundColor: "transparent", color: "#1f1f1f" }}
|
|
166
|
+
onClick={openPaymentMethodSettingsDrawer}
|
|
167
|
+
/>
|
|
156
168
|
<ConditionalTooltip
|
|
157
169
|
condition={allPaymentMethodsSelected}
|
|
158
170
|
placement="left-center"
|
|
@@ -227,6 +239,13 @@ export const PaymentMethodsLayout = ({
|
|
|
227
239
|
/>
|
|
228
240
|
)}
|
|
229
241
|
|
|
242
|
+
{isPaymentMethodSettingsDrawerOpen && (
|
|
243
|
+
<PaymentMethodSettingsDrawer
|
|
244
|
+
isOpen={isPaymentMethodSettingsDrawerOpen}
|
|
245
|
+
{...paymentMethodSettingsDrawerProps}
|
|
246
|
+
/>
|
|
247
|
+
)}
|
|
248
|
+
|
|
230
249
|
{isRemovePaymentMethodDrawerOpen && selectedMethod && (
|
|
231
250
|
<RemovePaymentMethodsDrawer
|
|
232
251
|
{...removeDrawerProps}
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import { useState } from "react";
|
|
2
|
+
|
|
3
|
+
import { useRouter } from "next/router";
|
|
4
|
+
|
|
5
|
+
import { useUI } from "@faststore/ui";
|
|
6
|
+
|
|
7
|
+
import {
|
|
8
|
+
type BasicDrawerProps,
|
|
9
|
+
SettingsDrawer,
|
|
10
|
+
createListTypeOptions,
|
|
11
|
+
} from "../../../shared/components";
|
|
12
|
+
import { useSetScopeConfig, SCOPE_KEYS } from "../../../shared/hooks";
|
|
13
|
+
|
|
14
|
+
export type CollectionsSettingsDrawerProps = Omit<
|
|
15
|
+
BasicDrawerProps,
|
|
16
|
+
"children"
|
|
17
|
+
> & {
|
|
18
|
+
readonly?: boolean;
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
const COLLECTIONS_LIST_TYPE_OPTIONS = createListTypeOptions("collections");
|
|
22
|
+
|
|
23
|
+
export const CollectionsSettingsDrawer = ({
|
|
24
|
+
close,
|
|
25
|
+
...otherProps
|
|
26
|
+
}: CollectionsSettingsDrawerProps) => {
|
|
27
|
+
const { pushToast } = useUI();
|
|
28
|
+
const router = useRouter();
|
|
29
|
+
|
|
30
|
+
const [listType, setListType] = useState<"sync" | "custom">("custom");
|
|
31
|
+
|
|
32
|
+
const { setScopeConfig, isSetScopeConfigLoading } = useSetScopeConfig({
|
|
33
|
+
onSuccess: () => {
|
|
34
|
+
pushToast({
|
|
35
|
+
message: "Scope configuration updated successfully",
|
|
36
|
+
status: "INFO",
|
|
37
|
+
});
|
|
38
|
+
close();
|
|
39
|
+
},
|
|
40
|
+
onError: () => {
|
|
41
|
+
pushToast({
|
|
42
|
+
message: "Failed to update scope configuration",
|
|
43
|
+
status: "ERROR",
|
|
44
|
+
});
|
|
45
|
+
},
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
const handleConfirmClick = () => {
|
|
49
|
+
setScopeConfig({
|
|
50
|
+
customerId: router.query.contractId as string,
|
|
51
|
+
unitId: router.query.orgUnitId as string,
|
|
52
|
+
scopeName: SCOPE_KEYS.COLLECTIONS,
|
|
53
|
+
type: listType,
|
|
54
|
+
});
|
|
55
|
+
};
|
|
56
|
+
|
|
57
|
+
return (
|
|
58
|
+
<SettingsDrawer
|
|
59
|
+
title="Collections settings"
|
|
60
|
+
{...otherProps}
|
|
61
|
+
close={close}
|
|
62
|
+
onPrimaryAction={handleConfirmClick}
|
|
63
|
+
isPrimaryButtonLoading={isSetScopeConfigLoading}
|
|
64
|
+
scopeName={SCOPE_KEYS.COLLECTIONS}
|
|
65
|
+
onDismiss={close}
|
|
66
|
+
data-fs-bp-collections-settings-drawer
|
|
67
|
+
>
|
|
68
|
+
<SettingsDrawer.ListType
|
|
69
|
+
title="List type"
|
|
70
|
+
name="collections-list-type"
|
|
71
|
+
value={listType}
|
|
72
|
+
onChange={setListType}
|
|
73
|
+
options={COLLECTIONS_LIST_TYPE_OPTIONS}
|
|
74
|
+
/>
|
|
75
|
+
</SettingsDrawer>
|
|
76
|
+
);
|
|
77
|
+
};
|
|
@@ -1,2 +1,6 @@
|
|
|
1
1
|
export { AddProductAssortmentDrawer } from "./AddProductAssortmentDrawer/AddProductAssortmentDrawer";
|
|
2
2
|
export { AddProductAssortmentDrawerTable } from "./table/AddProductAssortmentDrawerTable";
|
|
3
|
+
export {
|
|
4
|
+
CollectionsSettingsDrawer,
|
|
5
|
+
type CollectionsSettingsDrawerProps,
|
|
6
|
+
} from "./CollectionsSettingsDrawer/CollectionsSettingsDrawer";
|
package/src/features/product-assortment/layouts/ProductAssortmentLayout/ProductAssortmentLayout.tsx
CHANGED
|
@@ -14,7 +14,10 @@ import {
|
|
|
14
14
|
usePageItems,
|
|
15
15
|
} from "../../../shared/hooks";
|
|
16
16
|
import { ContractTabsLayout, GlobalLayout } from "../../../shared/layouts";
|
|
17
|
-
import {
|
|
17
|
+
import {
|
|
18
|
+
AddProductAssortmentDrawer,
|
|
19
|
+
CollectionsSettingsDrawer,
|
|
20
|
+
} from "../../components";
|
|
18
21
|
import { ProductAssortmentTable } from "../../components/ProductAssortmentTable/ProductAssortmentTable";
|
|
19
22
|
import { useGetProductAssortment } from "../../hooks/useGetProductAssortment";
|
|
20
23
|
import { useGetProductAssortmentFromContract } from "../../hooks/useGetProductAssortmentFromContract";
|
|
@@ -92,6 +95,12 @@ export const ProductAssortmentLayout = ({
|
|
|
92
95
|
...addProductAssortmentDrawerProps
|
|
93
96
|
} = useDrawerProps();
|
|
94
97
|
|
|
98
|
+
const {
|
|
99
|
+
open: openCollectionsSettingsDrawer,
|
|
100
|
+
isOpen: isCollectionsSettingsDrawerOpen,
|
|
101
|
+
...collectionsSettingsDrawerProps
|
|
102
|
+
} = useDrawerProps();
|
|
103
|
+
|
|
95
104
|
const hasAllAssortment = drawerProductAssortment.items.length === 0;
|
|
96
105
|
const isEmpty = productAssortment.length === 0;
|
|
97
106
|
|
|
@@ -123,6 +132,11 @@ export const ProductAssortmentLayout = ({
|
|
|
123
132
|
>
|
|
124
133
|
<section data-fs-bp-product-assortment-container>
|
|
125
134
|
<HeaderInside title="Product assortment">
|
|
135
|
+
<HeaderInside.Button
|
|
136
|
+
iconName="EditSettings"
|
|
137
|
+
style={{ backgroundColor: "transparent", color: "#1f1f1f" }}
|
|
138
|
+
onClick={openCollectionsSettingsDrawer}
|
|
139
|
+
/>
|
|
126
140
|
{!isContractEmpty &&
|
|
127
141
|
(hasAllAssortment ? (
|
|
128
142
|
<Tooltip
|
|
@@ -222,6 +236,13 @@ export const ProductAssortmentLayout = ({
|
|
|
222
236
|
{...addProductAssortmentDrawerProps}
|
|
223
237
|
/>
|
|
224
238
|
)}
|
|
239
|
+
|
|
240
|
+
{isCollectionsSettingsDrawerOpen && (
|
|
241
|
+
<CollectionsSettingsDrawer
|
|
242
|
+
isOpen={isCollectionsSettingsDrawerOpen}
|
|
243
|
+
{...collectionsSettingsDrawerProps}
|
|
244
|
+
/>
|
|
245
|
+
)}
|
|
225
246
|
</ContractTabsLayout>
|
|
226
247
|
</GlobalLayout>
|
|
227
248
|
);
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import React, { useState } from "react";
|
|
2
2
|
|
|
3
|
-
import { RadioGroup, RadioOption } from "@faststore/ui";
|
|
3
|
+
import { RadioGroup, RadioOption, Skeleton } from "@faststore/ui";
|
|
4
4
|
|
|
5
5
|
import { useGetScopeConfig } from "../../hooks";
|
|
6
6
|
|
|
@@ -80,21 +80,33 @@ export const SettingsDrawerListType = ({
|
|
|
80
80
|
return (
|
|
81
81
|
<div data-fs-bp-settings-drawer-list-type>
|
|
82
82
|
<h4 data-fs-bp-settings-drawer-list-type-title>{title}</h4>
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
<
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
83
|
+
{isLoading ? (
|
|
84
|
+
<div data-fs-bp-settings-drawer-list-type-skeleton>
|
|
85
|
+
{options.map((option) => (
|
|
86
|
+
<div key={option.value} data-fs-bp-settings-drawer-list-type-option>
|
|
87
|
+
<Skeleton size={{ width: "100%", height: "3.5rem" }} />
|
|
88
|
+
</div>
|
|
89
|
+
))}
|
|
90
|
+
</div>
|
|
91
|
+
) : (
|
|
92
|
+
<RadioGroup name={name} selectedValue={value} onChange={handleChange}>
|
|
93
|
+
{options.map((option) => (
|
|
94
|
+
<div key={option.value} data-fs-bp-settings-drawer-list-type-option>
|
|
95
|
+
<RadioOption
|
|
96
|
+
value={option.value}
|
|
97
|
+
label={option.label}
|
|
98
|
+
name={name}
|
|
99
|
+
disabled={disabled || isLoading}
|
|
100
|
+
>
|
|
101
|
+
{option.label}
|
|
102
|
+
</RadioOption>
|
|
103
|
+
<p data-fs-bp-settings-drawer-list-type-description>
|
|
104
|
+
{option.description}
|
|
105
|
+
</p>
|
|
106
|
+
</div>
|
|
107
|
+
))}
|
|
108
|
+
</RadioGroup>
|
|
109
|
+
)}
|
|
98
110
|
</div>
|
|
99
111
|
);
|
|
100
112
|
};
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import {
|
|
2
|
+
DEFAULT_LIST_TYPE_OPTIONS,
|
|
3
|
+
type ListTypeOption,
|
|
4
|
+
} from "./SettingsDrawerListType";
|
|
5
|
+
|
|
6
|
+
export const getCustomListDescription = (entityPlural: string) =>
|
|
7
|
+
`Manage a unique list of ${entityPlural} for this organization.`;
|
|
8
|
+
|
|
9
|
+
export const getSharedListDescription = (entityPlural: string) =>
|
|
10
|
+
`Use the shared list of ${entityPlural} defined by the contract. Updates are automatic.`;
|
|
11
|
+
|
|
12
|
+
export const createListTypeOptions = (
|
|
13
|
+
entityPlural: string
|
|
14
|
+
): ListTypeOption[] => [
|
|
15
|
+
{
|
|
16
|
+
...DEFAULT_LIST_TYPE_OPTIONS[0],
|
|
17
|
+
description: getCustomListDescription(entityPlural),
|
|
18
|
+
},
|
|
19
|
+
{
|
|
20
|
+
...DEFAULT_LIST_TYPE_OPTIONS[1],
|
|
21
|
+
description: getSharedListDescription(entityPlural),
|
|
22
|
+
},
|
|
23
|
+
];
|
|
@@ -14,6 +14,11 @@ export {
|
|
|
14
14
|
type SettingsDrawerListTypeProps,
|
|
15
15
|
DEFAULT_LIST_TYPE_OPTIONS,
|
|
16
16
|
} from "./SettingsDrawer/SettingsDrawer";
|
|
17
|
+
export {
|
|
18
|
+
createListTypeOptions,
|
|
19
|
+
getCustomListDescription,
|
|
20
|
+
getSharedListDescription,
|
|
21
|
+
} from "./SettingsDrawer/listTypeOptions";
|
|
17
22
|
export {
|
|
18
23
|
BasicDropdownMenu,
|
|
19
24
|
type BasicDropdownMenuProps,
|
|
@@ -124,19 +124,6 @@ export const LoadingTabsLayout = ({ children }: LoadingTabsLayoutProps) => {
|
|
|
124
124
|
name: "",
|
|
125
125
|
},
|
|
126
126
|
},
|
|
127
|
-
settings: {
|
|
128
|
-
userIdentification: {
|
|
129
|
-
userName: false,
|
|
130
|
-
email: false,
|
|
131
|
-
phone: false,
|
|
132
|
-
},
|
|
133
|
-
authenticationMethods: {
|
|
134
|
-
method: "PASSWORD",
|
|
135
|
-
},
|
|
136
|
-
"2FA": {
|
|
137
|
-
verificationCode: false,
|
|
138
|
-
},
|
|
139
|
-
},
|
|
140
127
|
}}
|
|
141
128
|
/>
|
|
142
129
|
);
|