@vtex/faststore-plugin-buyer-portal 1.3.46 → 1.3.48
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 +14 -1
- package/package.json +1 -1
- package/public/buyer-portal-icons.svg +35 -13
- package/src/features/org-units/clients/OrgUnitClient.ts +17 -0
- package/src/features/org-units/components/AddAllToOrgUnitDropdown/AddAllToOrgUnitDropdown.tsx +2 -2
- package/src/features/org-units/components/AuthSetupDrawer/AuthSetupDrawer.tsx +346 -0
- package/src/features/org-units/components/AuthSetupDrawer/auth-setup-drawer.scss +138 -0
- package/src/features/org-units/components/AuthSetupDrawer/index.ts +1 -0
- package/src/features/org-units/components/OrgUnitDetailsDropdownMenu/OrgUnitDetailsDropdownMenu.tsx +80 -0
- package/src/features/org-units/components/OrgUnitDetailsDropdownMenu/index.ts +4 -0
- package/src/features/org-units/components/OrgUnitsDropdownMenu/OrgUnitsDropdownMenu.tsx +2 -2
- package/src/features/org-units/components/index.ts +8 -0
- package/src/features/org-units/hooks/index.ts +2 -0
- package/src/features/org-units/hooks/useGetOrgUnitSettings.ts +20 -0
- package/src/features/org-units/hooks/useOrgUnitByUser.ts +4 -1
- package/src/features/org-units/hooks/useUpdateOrgUnitSettings.ts +27 -0
- package/src/features/org-units/layouts/OrgUnitDetailsLayout/OrgUnitDetailsLayout.tsx +22 -1
- package/src/features/org-units/layouts/OrgUnitDetailsLayout/org-units-details.scss +1 -0
- package/src/features/org-units/services/get-org-unit-settings.service.ts +13 -0
- package/src/features/org-units/services/index.ts +8 -0
- package/src/features/org-units/services/update-org-unit-settings.service.ts +17 -0
- package/src/features/org-units/types/OrgUnitSettings.ts +25 -0
- package/src/features/org-units/types/index.ts +2 -0
- package/src/features/product-assortment/hooks/useGetProductAssortment.ts +52 -0
- package/src/features/product-assortment/hooks/useGetProductAssortmentFromContract.ts +35 -0
- package/src/features/product-assortment/layouts/ProductAssortmentLayout/ProductAssortmentLayout.tsx +55 -12
- package/src/features/product-assortment/layouts/ProductAssortmentLayout/product-assortment-layout.scss +1 -1
- package/src/features/product-assortment/types/index.ts +6 -14
- package/src/features/shared/components/BuyerPortalProvider/BuyerPortalProvider.tsx +5 -0
- package/src/features/shared/components/Toast/Toast.tsx +43 -2
- package/src/features/shared/components/Toast/toast.scss +23 -5
- package/src/features/shared/components/index.ts +1 -0
- package/src/features/shared/hooks/usePageItems.ts +2 -2
- package/src/features/shared/layouts/ContractTabsLayout/ContractTabsLayout.tsx +1 -0
- package/src/features/shared/layouts/LoadingTabsLayout/LoadingTabsLayout.tsx +13 -0
- package/src/features/shared/utils/constants.ts +2 -2
- package/src/features/shared/utils/withBuyerPortal.tsx +4 -1
- package/src/features/users/clients/UsersClient.ts +105 -4
- package/src/features/users/components/CreateUserDrawer/CreateUserDrawer.tsx +1 -1
- package/src/features/users/components/CreateUserDrawerSelector/CreateUserDrawerSelector.tsx +20 -0
- package/src/features/users/components/CreateUserDrawerWithUsername/CreateUserDrawerWithUsername.tsx +696 -0
- package/src/features/users/components/CreateUserDrawerWithUsername/create-user-drawer-with-username.scss +116 -0
- package/src/features/users/components/UserDropdownMenu/user-dropdown-menu.scss +1 -0
- package/src/features/users/components/UsersCard/UsersCard.tsx +2 -2
- package/src/features/users/components/index.ts +5 -0
- package/src/features/users/hooks/index.ts +2 -0
- package/src/features/users/hooks/useAddUserToOrgUnit.ts +12 -5
- package/src/features/users/hooks/useResetPassword.ts +39 -0
- package/src/features/users/hooks/useValidateUsername.ts +38 -0
- package/src/features/users/layouts/UserDetailsLayout/UserDetailsLayout.tsx +10 -0
- package/src/features/users/layouts/UsersLayout/UsersLayout.tsx +55 -10
- package/src/features/users/layouts/UsersLayout/users-layout.scss +19 -0
- package/src/features/users/services/add-user-to-org-unit.service.ts +8 -6
- package/src/features/users/services/get-users-by-org-unit-id.service.ts +1 -0
- package/src/features/users/services/index.ts +10 -0
- package/src/features/users/services/reset-password.service.ts +24 -0
- package/src/features/users/services/validate-username.service.ts +25 -0
- package/src/features/users/types/UserData.ts +1 -0
- package/src/features/users/types/UserDataService.ts +1 -0
- package/src/pages/org-unit-details.tsx +20 -2
- package/src/pages/productAssortment.tsx +61 -65
|
@@ -4,6 +4,42 @@ import { useUI } from "@faststore/ui";
|
|
|
4
4
|
|
|
5
5
|
import { Icon } from "../Icon";
|
|
6
6
|
|
|
7
|
+
const LINK_REGEX = /\[([^\]]+)\]\(([^)]+)\)/g;
|
|
8
|
+
|
|
9
|
+
function parseMessageWithLinks(message: string): (string | JSX.Element)[] {
|
|
10
|
+
const parts: (string | JSX.Element)[] = [];
|
|
11
|
+
let lastIndex = 0;
|
|
12
|
+
let match;
|
|
13
|
+
|
|
14
|
+
while ((match = LINK_REGEX.exec(message)) !== null) {
|
|
15
|
+
if (match.index > lastIndex) {
|
|
16
|
+
parts.push(message.slice(lastIndex, match.index));
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
const [, linkText, url] = match;
|
|
20
|
+
|
|
21
|
+
parts.push(
|
|
22
|
+
<a
|
|
23
|
+
key={match.index}
|
|
24
|
+
href={url}
|
|
25
|
+
target="_blank"
|
|
26
|
+
rel="noopener noreferrer"
|
|
27
|
+
data-fs-bp-toast-link
|
|
28
|
+
>
|
|
29
|
+
{linkText}
|
|
30
|
+
</a>
|
|
31
|
+
);
|
|
32
|
+
|
|
33
|
+
lastIndex = match.index + match[0].length;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
if (lastIndex < message.length) {
|
|
37
|
+
parts.push(message.slice(lastIndex));
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
return parts;
|
|
41
|
+
}
|
|
42
|
+
|
|
7
43
|
function Toast() {
|
|
8
44
|
const { toasts, popToast } = useUI();
|
|
9
45
|
const toast = toasts[toasts.length - 1];
|
|
@@ -39,9 +75,14 @@ function Toast() {
|
|
|
39
75
|
>
|
|
40
76
|
<div data-fs-bp-toast-content>
|
|
41
77
|
{toast.title && <p data-fs-bp-toast-title>{toast.title}</p>}
|
|
42
|
-
<p
|
|
78
|
+
<p
|
|
79
|
+
data-fs-bp-toast-message
|
|
80
|
+
data-fs-bp-toast-message-has-title={!!toast.title}
|
|
81
|
+
>
|
|
82
|
+
{parseMessageWithLinks(toast.message)}
|
|
83
|
+
</p>
|
|
84
|
+
{!!toast.icon && toast.icon}
|
|
43
85
|
</div>
|
|
44
|
-
{!!toast.icon && toast.icon}
|
|
45
86
|
<button type="button" data-fs-bp-toast-dismiss onClick={popToast}>
|
|
46
87
|
<Icon name="Close" width={10} height={10} />
|
|
47
88
|
</button>
|
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
--fs-toast-border-color: transparent;
|
|
17
17
|
|
|
18
18
|
--fs-toast-shadow: 0 0.063rem 0.188rem rgba(0, 0, 0, 0.1);
|
|
19
|
-
--fs-toast-bkg-color: #
|
|
19
|
+
--fs-toast-bkg-color: #1f1f1f;
|
|
20
20
|
|
|
21
21
|
--fs-toast-transition-property: var(--fs-transition-property);
|
|
22
22
|
--fs-toast-transition-timing: var(--fs-transition-timing);
|
|
@@ -93,6 +93,7 @@
|
|
|
93
93
|
[data-fs-bp-toast-content] {
|
|
94
94
|
display: block;
|
|
95
95
|
overflow: hidden;
|
|
96
|
+
padding: var(--fs-spacing-1) var(--fs-spacing-2);
|
|
96
97
|
}
|
|
97
98
|
|
|
98
99
|
[data-fs-icon] {
|
|
@@ -115,27 +116,44 @@
|
|
|
115
116
|
}
|
|
116
117
|
|
|
117
118
|
[data-fs-bp-toast-view-button] {
|
|
118
|
-
color:
|
|
119
|
+
color: var(--fs-bp-color-neutral-0);
|
|
119
120
|
font-weight: var(--fs-text-weight-semibold);
|
|
120
121
|
font-size: var(--fs-text-size-1);
|
|
121
122
|
line-height: calc(var(--fs-spacing-4) - var(--fs-spacing-0));
|
|
122
123
|
cursor: pointer;
|
|
124
|
+
padding: 0;
|
|
125
|
+
margin-top: var(--fs-spacing-1);
|
|
123
126
|
}
|
|
124
127
|
|
|
125
128
|
[data-fs-bp-toast-title] {
|
|
126
|
-
margin-left: var(--fs-toast-title-margin-left);
|
|
127
129
|
overflow: hidden;
|
|
128
130
|
font-size: var(--fs-toast-title-size);
|
|
129
131
|
font-weight: var(--fs-toast-title-weight);
|
|
130
132
|
line-height: var(--fs-toast-title-line-height);
|
|
133
|
+
margin-bottom: var(--fs-spacing-0);
|
|
131
134
|
}
|
|
132
135
|
|
|
133
136
|
[data-fs-bp-toast-message] {
|
|
134
|
-
margin-left: var(--fs-toast-message-margin-left);
|
|
135
137
|
overflow: hidden;
|
|
136
|
-
font-weight:
|
|
138
|
+
font-weight: var(--fs-bp-weight-regular);
|
|
137
139
|
font-size: var(--fs-text-size-1);
|
|
138
140
|
line-height: calc(var(--fs-spacing-3) + var(--fs-spacing-0));
|
|
141
|
+
color: var(--fs-bp-color-neutral-0);
|
|
142
|
+
|
|
143
|
+
&[data-fs-bp-toast-message-has-title="true"] {
|
|
144
|
+
color: var(--fs-bp-color-neutral-5);
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
[data-fs-bp-toast-link] {
|
|
148
|
+
color: var(--fs-bp-color-neutral-0);
|
|
149
|
+
text-decoration: none;
|
|
150
|
+
transition: opacity var(--fs-toast-transition-timing)
|
|
151
|
+
var(--fs-toast-transition-function);
|
|
152
|
+
|
|
153
|
+
&:hover {
|
|
154
|
+
opacity: 0.8;
|
|
155
|
+
}
|
|
156
|
+
}
|
|
139
157
|
}
|
|
140
158
|
|
|
141
159
|
[data-fs-bp-toast-dismiss] {
|
|
@@ -37,6 +37,8 @@ export const usePageItems = <T>({
|
|
|
37
37
|
const [searchTerm, setSearchTerm] = useState(search ?? "");
|
|
38
38
|
const [isLoading, setIsLoading] = useState(false);
|
|
39
39
|
|
|
40
|
+
const { setQueryStrings, setQueryString } = useQueryParams();
|
|
41
|
+
|
|
40
42
|
useDebounce(searchTerm, DEBOUNCE_TIMEOUT, {
|
|
41
43
|
onDebounce: (value) => {
|
|
42
44
|
setIsLoading(true);
|
|
@@ -54,8 +56,6 @@ export const usePageItems = <T>({
|
|
|
54
56
|
},
|
|
55
57
|
});
|
|
56
58
|
|
|
57
|
-
const { setQueryStrings, setQueryString } = useQueryParams();
|
|
58
|
-
|
|
59
59
|
useEffect(() => {
|
|
60
60
|
setItems([]);
|
|
61
61
|
}, [search]);
|
|
@@ -124,6 +124,19 @@ 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
|
+
},
|
|
127
140
|
}}
|
|
128
141
|
/>
|
|
129
142
|
);
|
|
@@ -2,7 +2,7 @@ export const AUT_COOKIE_KEY = "VtexIdclientAutCookie";
|
|
|
2
2
|
// PROD URL
|
|
3
3
|
export const API_URL = (checkoutUrl: string, operation?: string) =>
|
|
4
4
|
`${checkoutUrl}/_v/store-front/${operation}`;
|
|
5
|
-
// DEV URL - CHANGE BEFORE MERGE
|
|
5
|
+
// // DEV URL - CHANGE BEFORE MERGE
|
|
6
6
|
// export const API_URL = (checkoutUrl?: string, operation?: string) =>
|
|
7
7
|
// `https://{{workspace}}--b2bfaststoredev.myvtex.com/_v/store-front/${operation}`;
|
|
8
8
|
|
|
@@ -22,4 +22,4 @@ export const SCOPE_KEYS = {
|
|
|
22
22
|
CREDIT_CARDS: "creditCards",
|
|
23
23
|
} as const;
|
|
24
24
|
|
|
25
|
-
export const CURRENT_VERSION = "1.3.
|
|
25
|
+
export const CURRENT_VERSION = "1.3.48";
|
|
@@ -16,7 +16,10 @@ export const withBuyerPortal = <T extends Record<string, unknown>>(
|
|
|
16
16
|
const { context, ...componentProps } = props;
|
|
17
17
|
|
|
18
18
|
return (
|
|
19
|
-
<BuyerPortalProvider
|
|
19
|
+
<BuyerPortalProvider
|
|
20
|
+
featureFlags={{ enableUsernameCreation: true }}
|
|
21
|
+
{...context}
|
|
22
|
+
>
|
|
20
23
|
<Component {...(componentProps as unknown as T)} />
|
|
21
24
|
</BuyerPortalProvider>
|
|
22
25
|
);
|
|
@@ -57,8 +57,9 @@ class UsersClient extends Client {
|
|
|
57
57
|
props: {
|
|
58
58
|
orgUnitId: string;
|
|
59
59
|
role: number[];
|
|
60
|
-
email
|
|
61
|
-
name
|
|
60
|
+
email?: string;
|
|
61
|
+
name?: string;
|
|
62
|
+
userName: string;
|
|
62
63
|
},
|
|
63
64
|
cookie: string
|
|
64
65
|
) {
|
|
@@ -78,8 +79,9 @@ class UsersClient extends Client {
|
|
|
78
79
|
{
|
|
79
80
|
orgUnitId: string;
|
|
80
81
|
role: number[];
|
|
81
|
-
email
|
|
82
|
-
name
|
|
82
|
+
email?: string;
|
|
83
|
+
name?: string;
|
|
84
|
+
userName: string;
|
|
83
85
|
}
|
|
84
86
|
>(
|
|
85
87
|
`units/${orgUnitId}/users`,
|
|
@@ -96,6 +98,54 @@ class UsersClient extends Client {
|
|
|
96
98
|
);
|
|
97
99
|
}
|
|
98
100
|
|
|
101
|
+
addUserToOrgUnitV2(
|
|
102
|
+
props: {
|
|
103
|
+
orgUnitId: string;
|
|
104
|
+
role: number[];
|
|
105
|
+
email?: string;
|
|
106
|
+
name?: string;
|
|
107
|
+
phone?: string;
|
|
108
|
+
userName: string;
|
|
109
|
+
},
|
|
110
|
+
cookie: string
|
|
111
|
+
) {
|
|
112
|
+
const { orgUnitId, ...data } = props;
|
|
113
|
+
|
|
114
|
+
return this.post<
|
|
115
|
+
{
|
|
116
|
+
message:
|
|
117
|
+
| "User already exists and is attached to a unit"
|
|
118
|
+
| "User Created, Sucessfully attached to Org Unit";
|
|
119
|
+
user: {
|
|
120
|
+
id: string;
|
|
121
|
+
email: string;
|
|
122
|
+
name: string;
|
|
123
|
+
};
|
|
124
|
+
accessToken?: string;
|
|
125
|
+
},
|
|
126
|
+
{
|
|
127
|
+
orgUnitId: string;
|
|
128
|
+
role: number[];
|
|
129
|
+
email?: string;
|
|
130
|
+
name?: string;
|
|
131
|
+
phone?: string;
|
|
132
|
+
userName: string;
|
|
133
|
+
}
|
|
134
|
+
>(
|
|
135
|
+
`v2/units/${orgUnitId}/users`,
|
|
136
|
+
{
|
|
137
|
+
...data,
|
|
138
|
+
orgUnitId,
|
|
139
|
+
},
|
|
140
|
+
{
|
|
141
|
+
headers: {
|
|
142
|
+
Cookie: cookie,
|
|
143
|
+
},
|
|
144
|
+
ignoreContentType: true,
|
|
145
|
+
}
|
|
146
|
+
);
|
|
147
|
+
}
|
|
148
|
+
|
|
99
149
|
removeUserFromOrgUnit(
|
|
100
150
|
props: {
|
|
101
151
|
orgUnitId: string;
|
|
@@ -169,6 +219,57 @@ class UsersClient extends Client {
|
|
|
169
219
|
}
|
|
170
220
|
);
|
|
171
221
|
}
|
|
222
|
+
|
|
223
|
+
validateUsername(
|
|
224
|
+
props: {
|
|
225
|
+
orgUnitId: string;
|
|
226
|
+
userName: string;
|
|
227
|
+
},
|
|
228
|
+
cookie: string
|
|
229
|
+
) {
|
|
230
|
+
const { orgUnitId, userName } = props;
|
|
231
|
+
|
|
232
|
+
return this.post<
|
|
233
|
+
{
|
|
234
|
+
valid: boolean;
|
|
235
|
+
userNameSuggestions?: string[];
|
|
236
|
+
},
|
|
237
|
+
{
|
|
238
|
+
userName: string;
|
|
239
|
+
}
|
|
240
|
+
>(
|
|
241
|
+
`units/${orgUnitId}/users/validate`,
|
|
242
|
+
{
|
|
243
|
+
userName,
|
|
244
|
+
},
|
|
245
|
+
{
|
|
246
|
+
headers: {
|
|
247
|
+
Cookie: cookie,
|
|
248
|
+
},
|
|
249
|
+
}
|
|
250
|
+
);
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
resetPassword(
|
|
254
|
+
props: {
|
|
255
|
+
orgUnitId: string;
|
|
256
|
+
userId: string;
|
|
257
|
+
},
|
|
258
|
+
cookie: string
|
|
259
|
+
) {
|
|
260
|
+
const { orgUnitId, userId } = props;
|
|
261
|
+
|
|
262
|
+
return this.post<
|
|
263
|
+
{
|
|
264
|
+
accessCode: string;
|
|
265
|
+
},
|
|
266
|
+
null
|
|
267
|
+
>(`units/${orgUnitId}/users/${userId}/reset-password`, null, {
|
|
268
|
+
headers: {
|
|
269
|
+
Cookie: cookie,
|
|
270
|
+
},
|
|
271
|
+
});
|
|
272
|
+
}
|
|
172
273
|
}
|
|
173
274
|
|
|
174
275
|
const usersClient = new UsersClient();
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { useBuyerPortal } from "../../../shared/hooks";
|
|
2
|
+
import {
|
|
3
|
+
CreateUserDrawer,
|
|
4
|
+
type CreateUserDrawerProps,
|
|
5
|
+
} from "../CreateUserDrawer/CreateUserDrawer";
|
|
6
|
+
import { CreateUserDrawerWithUsername } from "../CreateUserDrawerWithUsername/CreateUserDrawerWithUsername";
|
|
7
|
+
|
|
8
|
+
export type CreateUserDrawerSelectorProps = CreateUserDrawerProps;
|
|
9
|
+
|
|
10
|
+
export const CreateUserDrawerSelector = (
|
|
11
|
+
props: CreateUserDrawerSelectorProps
|
|
12
|
+
) => {
|
|
13
|
+
const { featureFlags } = useBuyerPortal();
|
|
14
|
+
|
|
15
|
+
if (featureFlags?.enableUsernameCreation) {
|
|
16
|
+
return <CreateUserDrawerWithUsername {...props} />;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
return <CreateUserDrawer {...props} />;
|
|
20
|
+
};
|