@vtex/faststore-plugin-buyer-portal 1.3.49 → 1.3.51
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 +56 -40
- package/package.json +1 -1
- package/src/features/addresses/components/CreateAddressSettingsDrawer/CreateAddressSettingsDrawer.tsx +2 -13
- package/src/features/budgets/components/BudgetEditNotificationDrawer/BudgetEditNotificationDrawer.tsx +1 -0
- package/src/features/budgets/components/BudgetNotificationForm/BudgetNotificationForm.tsx +64 -26
- package/src/features/budgets/components/BudgetNotificationForm/budget-notification-form.scss +26 -15
- package/src/features/budgets/components/BudgetUsersTable/BudgetUsersTable.tsx +2 -13
- package/src/features/budgets/components/CreateBudgetDrawer/create-budget-drawer.scss +0 -9
- package/src/features/budgets/components/EditBudgetDrawer/edit-budget-drawer.scss +0 -6
- 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/AutocompleteDropdown/AutocompleteDropdown.tsx +23 -6
- package/src/features/shared/components/AutocompleteDropdown/autocomplete-dropdown.scss +21 -7
- package/src/features/shared/components/BuyerPortalProvider/BuyerPortalProvider.tsx +1 -0
- package/src/features/shared/components/QuantitySelectorWithPercentage/QuantitySelectorWithPercentage.tsx +6 -3
- 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/Table/TableRow/table-row.scss +4 -0
- package/src/features/shared/components/index.ts +5 -0
- package/src/features/shared/utils/constants.ts +1 -1
|
@@ -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
|
);
|
|
@@ -43,6 +43,7 @@ export type AutocompleteDropdownProps<T> = ComponentProps<typeof InputText> & {
|
|
|
43
43
|
renderOption?: (option: T, index: number) => ReactNode;
|
|
44
44
|
onConfirmKeyPress?: (option: T) => void;
|
|
45
45
|
hasError?: boolean;
|
|
46
|
+
isLoading?: boolean;
|
|
46
47
|
shouldOpenOnFocus?: boolean;
|
|
47
48
|
shouldShowArrowDown?: boolean;
|
|
48
49
|
shouldCloseOnSelect?: boolean;
|
|
@@ -57,6 +58,7 @@ export const AutocompleteDropdown = <T,>({
|
|
|
57
58
|
disabled,
|
|
58
59
|
onConfirmKeyPress,
|
|
59
60
|
hasError,
|
|
61
|
+
isLoading = false,
|
|
60
62
|
value,
|
|
61
63
|
helperLabel,
|
|
62
64
|
shouldOpenOnFocus = true,
|
|
@@ -138,6 +140,25 @@ export const AutocompleteDropdown = <T,>({
|
|
|
138
140
|
setIsOpened(false);
|
|
139
141
|
}, []);
|
|
140
142
|
|
|
143
|
+
const getIconElement = () => {
|
|
144
|
+
if (shouldShowArrowDown) {
|
|
145
|
+
return <Icon name="ArrowDropDown" width={20} height={20} />;
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
if (isLoading) {
|
|
149
|
+
return (
|
|
150
|
+
<Icon
|
|
151
|
+
name="LoadingIndicator"
|
|
152
|
+
width={20}
|
|
153
|
+
height={20}
|
|
154
|
+
data-fs-icon-loading="true"
|
|
155
|
+
/>
|
|
156
|
+
);
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
return undefined;
|
|
160
|
+
};
|
|
161
|
+
|
|
141
162
|
useEffect(() => {
|
|
142
163
|
const event = (e: MouseEvent) => {
|
|
143
164
|
const target = e.target as Node;
|
|
@@ -215,11 +236,7 @@ export const AutocompleteDropdown = <T,>({
|
|
|
215
236
|
<InputText
|
|
216
237
|
label={label}
|
|
217
238
|
onKeyDown={handleBackdropKeyDown}
|
|
218
|
-
icon={
|
|
219
|
-
shouldShowArrowDown ? (
|
|
220
|
-
<Icon name="ArrowDropDown" width={20} height={20} />
|
|
221
|
-
) : null
|
|
222
|
-
}
|
|
239
|
+
icon={getIconElement()}
|
|
223
240
|
onChange={onChange}
|
|
224
241
|
disabled={disabled}
|
|
225
242
|
hasError={hasError}
|
|
@@ -229,7 +246,7 @@ export const AutocompleteDropdown = <T,>({
|
|
|
229
246
|
{...props}
|
|
230
247
|
/>
|
|
231
248
|
|
|
232
|
-
{isOpened && options.length > 0 ? (
|
|
249
|
+
{!isLoading && isOpened && options.length > 0 ? (
|
|
233
250
|
<div
|
|
234
251
|
style={{ width: positionStyle.width }}
|
|
235
252
|
data-fs-bp-autocomplete-dropdown-menu={position}
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
@import
|
|
1
|
+
@import '@faststore/ui/src/components/molecules/Dropdown/styles.scss';
|
|
2
2
|
|
|
3
3
|
[data-fs-bp-autocomplete-dropdown] {
|
|
4
4
|
position: relative;
|
|
5
|
-
|
|
6
|
-
&[data-fs-bp-autocomplete-dropdown-only-select=
|
|
5
|
+
|
|
6
|
+
&[data-fs-bp-autocomplete-dropdown-only-select='true'] {
|
|
7
7
|
[data-fs-bp-input-text-input] {
|
|
8
8
|
caret-color: transparent;
|
|
9
9
|
background-color: #ffffff;
|
|
@@ -11,6 +11,20 @@
|
|
|
11
11
|
}
|
|
12
12
|
}
|
|
13
13
|
|
|
14
|
+
[data-fs-icon-loading] {
|
|
15
|
+
&[data-fs-icon-loading='true'] {
|
|
16
|
+
@keyframes rotate {
|
|
17
|
+
from {
|
|
18
|
+
transform: rotate(0deg);
|
|
19
|
+
}
|
|
20
|
+
to {
|
|
21
|
+
transform: rotate(360deg);
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
animation: rotate 2s linear infinite;
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
|
|
14
28
|
[data-fs-bp-autocomplete-dropdown-menu] {
|
|
15
29
|
padding: var(--fs-spacing-1) 0;
|
|
16
30
|
background-color: #fff;
|
|
@@ -22,11 +36,11 @@
|
|
|
22
36
|
|
|
23
37
|
border-radius: calc(var(--fs-border-radius) * 2);
|
|
24
38
|
|
|
25
|
-
&[data-fs-bp-autocomplete-dropdown-menu=
|
|
39
|
+
&[data-fs-bp-autocomplete-dropdown-menu='bottom'] {
|
|
26
40
|
top: calc(100% + var(--fs-spacing-0));
|
|
27
41
|
}
|
|
28
42
|
|
|
29
|
-
&[data-fs-bp-autocomplete-dropdown-menu=
|
|
43
|
+
&[data-fs-bp-autocomplete-dropdown-menu='top'] {
|
|
30
44
|
bottom: calc(100% + var(--fs-spacing-0));
|
|
31
45
|
}
|
|
32
46
|
|
|
@@ -59,12 +73,12 @@
|
|
|
59
73
|
color: var(--fs-color-neutral-7);
|
|
60
74
|
}
|
|
61
75
|
|
|
62
|
-
&[data-fs-bp-autocomplete-dropdown-option-focused=
|
|
76
|
+
&[data-fs-bp-autocomplete-dropdown-option-focused='true'] {
|
|
63
77
|
background-color: #f5f5f5;
|
|
64
78
|
color: #3d3d3d;
|
|
65
79
|
}
|
|
66
80
|
|
|
67
|
-
&[data-fs-bp-autocomplete-dropdown-option-selected=
|
|
81
|
+
&[data-fs-bp-autocomplete-dropdown-option-selected='true'] {
|
|
68
82
|
color: #0366dd;
|
|
69
83
|
}
|
|
70
84
|
|
|
@@ -12,10 +12,11 @@ interface QuantitySelectorWithPercentageParams {
|
|
|
12
12
|
disabled?: boolean;
|
|
13
13
|
onChange?: (value: number) => void;
|
|
14
14
|
onValidateBlur?: (min: number, maxValue: number, quantity: number) => void;
|
|
15
|
-
|
|
16
15
|
formatAsPercent?: boolean;
|
|
17
16
|
allowPercentToggle?: boolean;
|
|
18
17
|
onFormatToggle?: (formatAsPercent: boolean) => void;
|
|
18
|
+
increaseQuantityBy?: number;
|
|
19
|
+
decreaseQuantityBy?: number;
|
|
19
20
|
}
|
|
20
21
|
|
|
21
22
|
const QuantitySelectorWithPercentage = ({
|
|
@@ -29,6 +30,8 @@ const QuantitySelectorWithPercentage = ({
|
|
|
29
30
|
onValidateBlur,
|
|
30
31
|
testId = "fs-quantity-selector",
|
|
31
32
|
formatAsPercent = true,
|
|
33
|
+
increaseQuantityBy = 1,
|
|
34
|
+
decreaseQuantityBy = 1,
|
|
32
35
|
...otherProps
|
|
33
36
|
}: QuantitySelectorWithPercentageParams) => {
|
|
34
37
|
const [quantity, setQuantity] = useState<number>(initial ?? min);
|
|
@@ -61,8 +64,8 @@ const QuantitySelectorWithPercentage = ({
|
|
|
61
64
|
: maxValue;
|
|
62
65
|
};
|
|
63
66
|
|
|
64
|
-
const increase = () => changeQuantity(
|
|
65
|
-
const decrease = () => changeQuantity(-
|
|
67
|
+
const increase = () => changeQuantity(increaseQuantityBy);
|
|
68
|
+
const decrease = () => changeQuantity(-decreaseQuantityBy);
|
|
66
69
|
|
|
67
70
|
const changeQuantity = (delta: number) => {
|
|
68
71
|
const next = validateQuantityBounds(quantity + delta);
|
|
@@ -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,
|