@vtex/faststore-plugin-buyer-portal 1.3.4 → 1.3.6
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 +22 -3
- package/cypress/constants.ts +2 -0
- package/cypress/integration/organizational-units.test.ts +1 -1
- package/cypress/integration/{collections.test.ts → product-assortment.test.ts} +54 -50
- package/cypress/integration/profile.test.ts +1 -1
- package/cypress/integration/users.test.ts +9 -0
- package/package.json +1 -1
- package/plugin.config.js +2 -2
- package/src/features/budgets/components/BudgetRemainingBalance/BudgetRemainingBalance.tsx +1 -1
- package/src/features/{collections/clients/CollectionsClient.ts → product-assortment/clients/ProductAssortmentClient.ts} +18 -20
- package/src/features/product-assortment/components/AddProductAssortmentDrawer/AddProductAssortmentDrawer.tsx +144 -0
- package/src/features/{collections/components/AddCollectionsDrawer/add-collections-drawer.scss → product-assortment/components/AddProductAssortmentDrawer/add-product-assortment-drawer.scss} +9 -10
- package/src/features/product-assortment/components/ProductAssortmentTable/ProductAssortmentTable.tsx +99 -0
- package/src/features/product-assortment/components/ProductAssortmentTable/product-assortment-table.scss +45 -0
- package/src/features/{collections/components/RemoveCollectionDrawer/RemoveCollectionDrawer.tsx → product-assortment/components/RemoveProductAssortmentDrawer/RemoveProductAssortmentDrawer.tsx} +21 -20
- package/src/features/product-assortment/components/RemoveProductAssortmentDrawer/remove-product-assortment-drawer.scss +9 -0
- package/src/features/product-assortment/components/index.tsx +2 -0
- package/src/features/{collections/components/table/AddCollectionsDrawerTable.tsx → product-assortment/components/table/AddProductAssortmentDrawerTable.tsx} +9 -9
- package/src/features/product-assortment/components/table/add-product-assortment-drawer-table.scss +14 -0
- package/src/features/product-assortment/hooks/useAddProductAssortmentToScope.ts +25 -0
- package/src/features/product-assortment/hooks/useRemoveProductAssortmentFromScope.ts +26 -0
- package/src/features/{collections/layouts/CollectionsLayout/CollectionsLayout.tsx → product-assortment/layouts/ProductAssortmentLayout/ProductAssortmentLayout.tsx} +43 -49
- package/src/features/{collections/layouts/CollectionsLayout/collections-layout.scss → product-assortment/layouts/ProductAssortmentLayout/product-assortment-layout.scss} +7 -7
- package/src/features/product-assortment/layouts/index.ts +1 -0
- package/src/features/product-assortment/services/add-product-assortment-to-scope.service.ts +16 -0
- package/src/features/product-assortment/services/get-product-assortment-from-contract.service.ts +13 -0
- package/src/features/product-assortment/services/get-product-assortment-from-scope.service.ts +28 -0
- package/src/features/product-assortment/services/remove-product-assortment-from-scope.ts +9 -0
- package/src/features/product-assortment/types/index.ts +80 -0
- package/src/features/shared/utils/buyerPortalRoutes.ts +5 -2
- package/src/features/shared/utils/constants.ts +1 -1
- package/src/features/shared/utils/getContractSettingsLinks.ts +2 -2
- package/src/features/shared/utils/routeLayoutMapping.ts +2 -2
- package/src/features/users/clients/UsersClient.ts +2 -0
- package/src/features/users/components/CreateUserDrawer/CreateUserDrawer.tsx +19 -2
- package/src/features/users/components/UpdateUserDrawer/UpdateUserDrawer.tsx +31 -5
- package/src/features/users/components/UserDropdownMenu/UserDropdownMenu.tsx +1 -1
- package/src/features/users/layouts/UserDetailsLayout/UserDetailsLayout.tsx +8 -0
- package/src/features/users/services/add-user-to-org-unit.service.ts +1 -0
- package/src/features/users/services/get-user-by-id.service.ts +2 -1
- package/src/features/users/services/update-user.service.ts +3 -0
- package/src/features/users/types/UserData.ts +1 -0
- package/src/features/users/types/UserDataService.ts +1 -0
- package/src/pages/{collections.tsx → productAssortment.tsx} +30 -51
- package/src/themes/layouts.scss +2 -2
- package/src/features/collections/components/AddCollectionsDrawer/AddCollectionsDrawer.tsx +0 -146
- package/src/features/collections/components/CollectionsTable/CollectionsTable.tsx +0 -94
- package/src/features/collections/components/CollectionsTable/collections-table.scss +0 -140
- package/src/features/collections/components/RemoveCollectionDrawer/remove-collection-drawer.scss +0 -15
- package/src/features/collections/components/index.tsx +0 -5
- package/src/features/collections/components/table/add-collections-drawer-table.scss +0 -71
- package/src/features/collections/hooks/useAddCollectionsToScope.ts +0 -23
- package/src/features/collections/hooks/useGetCollectionsFromContract.ts +0 -26
- package/src/features/collections/hooks/useGetCollectionsFromScope.ts +0 -27
- package/src/features/collections/hooks/useRemoveCollectionsFromScope.ts +0 -26
- package/src/features/collections/layouts/index.ts +0 -4
- package/src/features/collections/services/add-collections-to-scope.service.ts +0 -15
- package/src/features/collections/services/get-collections-from-contract.service.ts +0 -9
- package/src/features/collections/services/get-collections-from-scope.service.ts +0 -24
- package/src/features/collections/services/remove-collections-from-scope.ts +0 -7
- package/src/features/collections/types/index.ts +0 -20
package/src/features/product-assortment/services/get-product-assortment-from-contract.service.ts
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { productAssortmentClient } from "../clients/ProductAssortmentClient";
|
|
2
|
+
|
|
3
|
+
export const getProductAssortmentFromContractService = async (
|
|
4
|
+
params: Parameters<
|
|
5
|
+
typeof productAssortmentClient.getProductAssortmentFromContract
|
|
6
|
+
>[0]
|
|
7
|
+
) => {
|
|
8
|
+
const data = await productAssortmentClient.getProductAssortmentFromContract(
|
|
9
|
+
params
|
|
10
|
+
);
|
|
11
|
+
|
|
12
|
+
return data;
|
|
13
|
+
};
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { isRightFormat } from "../../shared/utils/isRightFormat";
|
|
2
|
+
import { productAssortmentClient } from "../clients/ProductAssortmentClient";
|
|
3
|
+
|
|
4
|
+
export const getProductAssortmentFromScopeService = async (
|
|
5
|
+
args: Parameters<
|
|
6
|
+
typeof productAssortmentClient.getProductAssortmentListInScope
|
|
7
|
+
>[0]
|
|
8
|
+
) => {
|
|
9
|
+
try {
|
|
10
|
+
const data = await productAssortmentClient.getProductAssortmentListInScope(
|
|
11
|
+
args
|
|
12
|
+
);
|
|
13
|
+
|
|
14
|
+
return data;
|
|
15
|
+
} catch (error) {
|
|
16
|
+
if (error instanceof Error) {
|
|
17
|
+
const err = JSON.parse(error.message) as unknown;
|
|
18
|
+
if (
|
|
19
|
+
isRightFormat(err) &&
|
|
20
|
+
err.message.startsWith("No Product assortment found for the name")
|
|
21
|
+
) {
|
|
22
|
+
return [];
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
throw error;
|
|
27
|
+
}
|
|
28
|
+
};
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { productAssortmentClient } from "../clients/ProductAssortmentClient";
|
|
2
|
+
|
|
3
|
+
export const removeProductAssortmentFromScopeService = async (
|
|
4
|
+
params: Parameters<
|
|
5
|
+
typeof productAssortmentClient.removeProductAssortmentFromScope
|
|
6
|
+
>[0]
|
|
7
|
+
) => {
|
|
8
|
+
await productAssortmentClient.removeProductAssortmentFromScope(params);
|
|
9
|
+
};
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
import type { ContractData } from "../../contracts/types";
|
|
2
|
+
import type { OrgUnitBasicData } from "../../org-units/types";
|
|
3
|
+
import type { BasicDrawerProps } from "../../shared/components";
|
|
4
|
+
import type { ErrorBoundaryProps } from "../../shared/components/ErrorBoundary/types";
|
|
5
|
+
import type { ClientContext } from "../../shared/utils";
|
|
6
|
+
|
|
7
|
+
export type ProductAssortmentSummary = {
|
|
8
|
+
id: string;
|
|
9
|
+
name: string;
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
export type ContractProductAssortment = ProductAssortmentSummary & {
|
|
13
|
+
isEnabled: boolean;
|
|
14
|
+
};
|
|
15
|
+
export type ScopeProductAssortment = ProductAssortmentSummary & {
|
|
16
|
+
isEnabled: boolean;
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
export type GetProductAssortmentFromContractResponse = {
|
|
20
|
+
collections: Array<ContractProductAssortment>;
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
export type GetProductAssortmentFromScopeResponse = {
|
|
24
|
+
collections: Array<ScopeProductAssortment>;
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
export type AddProductAssortmentResponse = {
|
|
28
|
+
message: string;
|
|
29
|
+
addedCollections: string[];
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
export type AddProductAssortmentPayload = Array<{ name: string }>;
|
|
33
|
+
|
|
34
|
+
export type AddProductAssortmentDrawerProps = Omit<
|
|
35
|
+
BasicDrawerProps,
|
|
36
|
+
"children"
|
|
37
|
+
> & {
|
|
38
|
+
productAssortment: ScopeProductAssortment[];
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
export type RemoveProductAssortmentDrawerProps = Omit<
|
|
42
|
+
BasicDrawerProps,
|
|
43
|
+
"children"
|
|
44
|
+
> & {
|
|
45
|
+
productAssortment: ProductAssortmentSelectedProps;
|
|
46
|
+
};
|
|
47
|
+
export interface ProductAssortmentSelectedProps {
|
|
48
|
+
id: string;
|
|
49
|
+
name: string;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
export type ProductAssortmentLayoutProps = {
|
|
53
|
+
initialProductAssortment: ScopeProductAssortment[];
|
|
54
|
+
drawerProductAssortment: ScopeProductAssortment[];
|
|
55
|
+
page: number;
|
|
56
|
+
search: string;
|
|
57
|
+
isContractEmpty: boolean;
|
|
58
|
+
};
|
|
59
|
+
|
|
60
|
+
export type ProductAssortmentData = {
|
|
61
|
+
productAssortment: ScopeProductAssortment[];
|
|
62
|
+
drawerProductAssortment: ScopeProductAssortment[];
|
|
63
|
+
isContractEmpty: boolean;
|
|
64
|
+
search: string;
|
|
65
|
+
page: number;
|
|
66
|
+
context: {
|
|
67
|
+
clientContext: ClientContext;
|
|
68
|
+
currentOrgUnit: OrgUnitBasicData;
|
|
69
|
+
currentContract: ContractData | null;
|
|
70
|
+
};
|
|
71
|
+
hasError?: boolean;
|
|
72
|
+
error?: ErrorBoundaryProps;
|
|
73
|
+
};
|
|
74
|
+
|
|
75
|
+
export type ProductAssortmentQuery = {
|
|
76
|
+
orgUnitId: string;
|
|
77
|
+
contractId: string;
|
|
78
|
+
search: string;
|
|
79
|
+
page: string;
|
|
80
|
+
};
|
|
@@ -45,8 +45,11 @@ export const buyerPortalRoutes = {
|
|
|
45
45
|
creditCards: (params: { orgUnitId: string; contractId: string }) =>
|
|
46
46
|
replaceParams(`${base}/credit-cards/[orgUnitId]/[contractId]`, params),
|
|
47
47
|
|
|
48
|
-
|
|
49
|
-
replaceParams(
|
|
48
|
+
productAssortment: (params: { orgUnitId: string; contractId: string }) =>
|
|
49
|
+
replaceParams(
|
|
50
|
+
`${base}/product-assortment/[orgUnitId]/[contractId]`,
|
|
51
|
+
params
|
|
52
|
+
),
|
|
50
53
|
|
|
51
54
|
poNumbers: (params: { orgUnitId: string; contractId: string }) =>
|
|
52
55
|
replaceParams(`${base}/po-numbers/[orgUnitId]/[contractId]`, params),
|
|
@@ -24,8 +24,8 @@ export const getContractSettingsLinks = ({
|
|
|
24
24
|
link: buyerPortalRoutes.creditCards({ orgUnitId, contractId }),
|
|
25
25
|
},
|
|
26
26
|
{
|
|
27
|
-
name: "
|
|
28
|
-
link: buyerPortalRoutes.
|
|
27
|
+
name: "Product assortment",
|
|
28
|
+
link: buyerPortalRoutes.productAssortment({ orgUnitId, contractId }),
|
|
29
29
|
},
|
|
30
30
|
{
|
|
31
31
|
name: "PO numbers",
|
|
@@ -37,10 +37,10 @@ export const ROUTE_TABS_LAYOUT_MAPPING: Record<string, RouteTabsLayoutConfig> =
|
|
|
37
37
|
pageName: "Contract",
|
|
38
38
|
pageTitle: "Credit Cards",
|
|
39
39
|
},
|
|
40
|
-
"/pvt/organization-account/
|
|
40
|
+
"/pvt/organization-account/product-assortment/[orgUnitId]/[contractId]": {
|
|
41
41
|
layout: "ContractTabsLayout",
|
|
42
42
|
pageName: "Contract",
|
|
43
|
-
pageTitle: "
|
|
43
|
+
pageTitle: "Product assortment",
|
|
44
44
|
},
|
|
45
45
|
"/pvt/organization-account/po-numbers/[orgUnitId]/[contractId]": {
|
|
46
46
|
layout: "ContractTabsLayout",
|
|
@@ -142,6 +142,7 @@ class UsersClient extends Client {
|
|
|
142
142
|
props: {
|
|
143
143
|
orgUnitId: string;
|
|
144
144
|
userId: string;
|
|
145
|
+
phone?: string;
|
|
145
146
|
name?: string;
|
|
146
147
|
role?: string;
|
|
147
148
|
},
|
|
@@ -153,6 +154,7 @@ class UsersClient extends Client {
|
|
|
153
154
|
unknown,
|
|
154
155
|
{
|
|
155
156
|
name?: string;
|
|
157
|
+
phone?: string;
|
|
156
158
|
role?: string;
|
|
157
159
|
}
|
|
158
160
|
>(
|
|
@@ -13,6 +13,7 @@ import {
|
|
|
13
13
|
InputText,
|
|
14
14
|
} from "../../../shared/components";
|
|
15
15
|
import { buyerPortalRoutes } from "../../../shared/utils/buyerPortalRoutes";
|
|
16
|
+
import { maskPhoneNumber } from "../../../shared/utils/phoneNumber";
|
|
16
17
|
import { useAddUserToOrgUnit } from "../../hooks";
|
|
17
18
|
|
|
18
19
|
export type CreateUserDrawerProps = Omit<BasicDrawerProps, "children"> & {
|
|
@@ -49,16 +50,18 @@ export const CreateUserDrawer = ({
|
|
|
49
50
|
const [form, setForm] = useState<{
|
|
50
51
|
name: string;
|
|
51
52
|
email: string;
|
|
53
|
+
phone: string;
|
|
52
54
|
roles: number[];
|
|
53
55
|
}>({
|
|
54
56
|
name: "",
|
|
55
57
|
email: "",
|
|
58
|
+
phone: "",
|
|
56
59
|
roles: [],
|
|
57
60
|
});
|
|
58
61
|
|
|
59
62
|
const [isTouched, setIsTouched] = useState(false);
|
|
60
63
|
|
|
61
|
-
const { name, email, roles } = form;
|
|
64
|
+
const { name, email, roles, phone } = form;
|
|
62
65
|
|
|
63
66
|
const updateField = (
|
|
64
67
|
field: keyof typeof form,
|
|
@@ -122,7 +125,7 @@ export const CreateUserDrawer = ({
|
|
|
122
125
|
});
|
|
123
126
|
|
|
124
127
|
const isAllFieldsFilled = Object.keys(form).every((key) => {
|
|
125
|
-
if (key === "roles") {
|
|
128
|
+
if (key === "roles" || key === "phone") {
|
|
126
129
|
return true; // allow empty roles
|
|
127
130
|
}
|
|
128
131
|
|
|
@@ -140,6 +143,7 @@ export const CreateUserDrawer = ({
|
|
|
140
143
|
addUserToOrgUnit({
|
|
141
144
|
name,
|
|
142
145
|
email,
|
|
146
|
+
phone: phone ?? "",
|
|
143
147
|
roles,
|
|
144
148
|
orgUnitId,
|
|
145
149
|
});
|
|
@@ -154,6 +158,7 @@ export const CreateUserDrawer = ({
|
|
|
154
158
|
setForm({
|
|
155
159
|
name: "",
|
|
156
160
|
email: "",
|
|
161
|
+
phone: "",
|
|
157
162
|
roles: [],
|
|
158
163
|
});
|
|
159
164
|
};
|
|
@@ -225,6 +230,18 @@ export const CreateUserDrawer = ({
|
|
|
225
230
|
message="Email is required"
|
|
226
231
|
/>
|
|
227
232
|
|
|
233
|
+
<InputText
|
|
234
|
+
label="Phone number (optional)"
|
|
235
|
+
value={phone}
|
|
236
|
+
onChange={(event) =>
|
|
237
|
+
// TODO: Update this when implementing i18n
|
|
238
|
+
updateField(
|
|
239
|
+
"phone",
|
|
240
|
+
maskPhoneNumber(event.target.value, "USA")
|
|
241
|
+
)
|
|
242
|
+
}
|
|
243
|
+
/>
|
|
244
|
+
|
|
228
245
|
<div data-fs-bp-create-user-roles>
|
|
229
246
|
<span data-fs-bp-create-user-roles-label>Roles</span>
|
|
230
247
|
|
|
@@ -10,10 +10,11 @@ import {
|
|
|
10
10
|
ErrorMessage,
|
|
11
11
|
InputText,
|
|
12
12
|
} from "../../../shared/components";
|
|
13
|
+
import { maskPhoneNumber } from "../../../shared/utils/phoneNumber";
|
|
13
14
|
import { useGetUserById, useUpdateUser } from "../../hooks";
|
|
14
15
|
|
|
15
16
|
export type UpdateUserDrawerProps = Omit<BasicDrawerProps, "children"> & {
|
|
16
|
-
|
|
17
|
+
onUpdate?: () => void;
|
|
17
18
|
orgUnitId: string;
|
|
18
19
|
userId: string;
|
|
19
20
|
rolesOptions: RoleData[] | null;
|
|
@@ -21,7 +22,7 @@ export type UpdateUserDrawerProps = Omit<BasicDrawerProps, "children"> & {
|
|
|
21
22
|
|
|
22
23
|
export const UpdateUserDrawer = ({
|
|
23
24
|
close,
|
|
24
|
-
|
|
25
|
+
onUpdate,
|
|
25
26
|
userId,
|
|
26
27
|
orgUnitId,
|
|
27
28
|
rolesOptions,
|
|
@@ -36,6 +37,7 @@ export const UpdateUserDrawer = ({
|
|
|
36
37
|
setForm({
|
|
37
38
|
name: data?.name ?? "",
|
|
38
39
|
email: data?.email ?? "",
|
|
40
|
+
phone: data?.phone ?? "",
|
|
39
41
|
roles: data?.roles ? data.roles : [],
|
|
40
42
|
});
|
|
41
43
|
},
|
|
@@ -51,16 +53,18 @@ export const UpdateUserDrawer = ({
|
|
|
51
53
|
const [form, setForm] = useState<{
|
|
52
54
|
name: string;
|
|
53
55
|
email: string;
|
|
56
|
+
phone: string;
|
|
54
57
|
roles: string[];
|
|
55
58
|
}>({
|
|
56
59
|
name: "",
|
|
57
60
|
email: "",
|
|
61
|
+
phone: "",
|
|
58
62
|
roles: [],
|
|
59
63
|
});
|
|
60
64
|
|
|
61
65
|
const [isTouched, setIsTouched] = useState(false);
|
|
62
66
|
|
|
63
|
-
const { name, email, roles } = form;
|
|
67
|
+
const { name, email, roles, phone } = form;
|
|
64
68
|
|
|
65
69
|
const updateField = (field: keyof typeof form, value: string | string[]) => {
|
|
66
70
|
setForm((prev) => ({
|
|
@@ -74,7 +78,7 @@ export const UpdateUserDrawer = ({
|
|
|
74
78
|
message: "User successfully updated",
|
|
75
79
|
status: "INFO",
|
|
76
80
|
});
|
|
77
|
-
|
|
81
|
+
onUpdate?.();
|
|
78
82
|
close();
|
|
79
83
|
};
|
|
80
84
|
|
|
@@ -99,7 +103,7 @@ export const UpdateUserDrawer = ({
|
|
|
99
103
|
});
|
|
100
104
|
|
|
101
105
|
const isAllFieldsFilled = Object.keys(form).every((key) => {
|
|
102
|
-
if (key === "roles") {
|
|
106
|
+
if (key === "roles" || key === "phone") {
|
|
103
107
|
return true; // allow empty roles
|
|
104
108
|
}
|
|
105
109
|
|
|
@@ -129,6 +133,7 @@ export const UpdateUserDrawer = ({
|
|
|
129
133
|
updateUser({
|
|
130
134
|
userId,
|
|
131
135
|
name,
|
|
136
|
+
phone,
|
|
132
137
|
roles,
|
|
133
138
|
orgUnitId,
|
|
134
139
|
});
|
|
@@ -186,6 +191,27 @@ export const UpdateUserDrawer = ({
|
|
|
186
191
|
message="Email is required"
|
|
187
192
|
/>
|
|
188
193
|
|
|
194
|
+
{isUserLoading ? (
|
|
195
|
+
<Skeleton
|
|
196
|
+
size={{ width: "100%", height: "3.5rem" }}
|
|
197
|
+
style={{
|
|
198
|
+
marginTop: "1rem",
|
|
199
|
+
marginBottom: "1rem",
|
|
200
|
+
width: "100%",
|
|
201
|
+
height: "3.5rem",
|
|
202
|
+
}}
|
|
203
|
+
/>
|
|
204
|
+
) : (
|
|
205
|
+
<InputText
|
|
206
|
+
label="Phone number (optional)"
|
|
207
|
+
value={phone}
|
|
208
|
+
onChange={(event) =>
|
|
209
|
+
// TODO: Update this when implementing i18n
|
|
210
|
+
updateField("phone", maskPhoneNumber(event.target.value, "USA"))
|
|
211
|
+
}
|
|
212
|
+
/>
|
|
213
|
+
)}
|
|
214
|
+
|
|
189
215
|
<div data-fs-bp-update-user-roles>
|
|
190
216
|
<span data-fs-bp-update-user-roles-label>Roles</span>
|
|
191
217
|
{rolesOptions &&
|
|
@@ -80,6 +80,13 @@ export const UserDetailsLayout = ({
|
|
|
80
80
|
|
|
81
81
|
<hr data-fs-user-details-divider />
|
|
82
82
|
|
|
83
|
+
<div data-fs-user-details-row>
|
|
84
|
+
<span data-fs-user-details-row-label>Phone number</span>
|
|
85
|
+
<span data-fs-user-details-row-value>{user?.phone}</span>
|
|
86
|
+
</div>
|
|
87
|
+
|
|
88
|
+
<hr data-fs-user-details-divider />
|
|
89
|
+
|
|
83
90
|
<div data-fs-user-details-row>
|
|
84
91
|
<span data-fs-user-details-row-label>Email</span>
|
|
85
92
|
<a href={`mailto:${user?.email}`} data-fs-user-details-row-value>
|
|
@@ -133,6 +140,7 @@ export const UserDetailsLayout = ({
|
|
|
133
140
|
userId={user?.id ?? ""}
|
|
134
141
|
orgUnitId={currentOrgUnit?.id ?? ""}
|
|
135
142
|
isOpen={isUpdateUserDrawerOpen}
|
|
143
|
+
onUpdate={() => location.reload()}
|
|
136
144
|
{...updateUserDrawerProps}
|
|
137
145
|
/>
|
|
138
146
|
)}
|
|
@@ -12,7 +12,7 @@ export const getUserByIdService = async ({
|
|
|
12
12
|
cookie: string;
|
|
13
13
|
}): Promise<UserData | null> => {
|
|
14
14
|
try {
|
|
15
|
-
const { email, name, orgUnit, role } = await usersClient.getUserById(
|
|
15
|
+
const { email, name, phone, orgUnit, role } = await usersClient.getUserById(
|
|
16
16
|
orgUnitId,
|
|
17
17
|
userId,
|
|
18
18
|
cookie
|
|
@@ -23,6 +23,7 @@ export const getUserByIdService = async ({
|
|
|
23
23
|
roles: role ? role : [],
|
|
24
24
|
id: userId,
|
|
25
25
|
email: email ?? "",
|
|
26
|
+
phone: phone ?? "",
|
|
26
27
|
orgUnit: {
|
|
27
28
|
name: orgUnit,
|
|
28
29
|
},
|
|
@@ -4,6 +4,7 @@ export type UpdateUserServiceProps = {
|
|
|
4
4
|
orgUnitId: string;
|
|
5
5
|
userId: string;
|
|
6
6
|
name?: string;
|
|
7
|
+
phone?: string;
|
|
7
8
|
roles?: string[];
|
|
8
9
|
cookie: string;
|
|
9
10
|
};
|
|
@@ -13,6 +14,7 @@ export const updateUserService = async ({
|
|
|
13
14
|
userId,
|
|
14
15
|
cookie,
|
|
15
16
|
name,
|
|
17
|
+
phone = "",
|
|
16
18
|
roles,
|
|
17
19
|
}: UpdateUserServiceProps) => {
|
|
18
20
|
return usersClient.updateUser(
|
|
@@ -20,6 +22,7 @@ export const updateUserService = async ({
|
|
|
20
22
|
orgUnitId,
|
|
21
23
|
userId,
|
|
22
24
|
name,
|
|
25
|
+
phone,
|
|
23
26
|
role: roles?.join(",") || undefined,
|
|
24
27
|
},
|
|
25
28
|
cookie
|
|
@@ -1,49 +1,26 @@
|
|
|
1
|
-
import { CollectionsLayout } from "../features/collections/layouts";
|
|
2
|
-
import { getCollectionsFromContractService } from "../features/collections/services/get-collections-from-contract.service";
|
|
3
|
-
import { getCollectionsFromScopeService } from "../features/collections/services/get-collections-from-scope.service";
|
|
4
|
-
import { ScopeCollection } from "../features/collections/types";
|
|
5
1
|
import { getContractDetailsService } from "../features/contracts/services";
|
|
6
|
-
import { ContractData } from "../features/contracts/types";
|
|
7
2
|
import { getOrgUnitBasicDataService } from "../features/org-units/services";
|
|
3
|
+
import { ProductAssortmentLayout } from "../features/product-assortment/layouts";
|
|
4
|
+
import { getProductAssortmentFromContractService } from "../features/product-assortment/services/get-product-assortment-from-contract.service";
|
|
5
|
+
import { getProductAssortmentFromScopeService } from "../features/product-assortment/services/get-product-assortment-from-scope.service";
|
|
8
6
|
import { withErrorBoundary } from "../features/shared/components";
|
|
9
|
-
import { ErrorBoundaryProps } from "../features/shared/components/ErrorBoundary/types";
|
|
10
7
|
import { ErrorTabsLayout } from "../features/shared/layouts/ErrorTabsLayout/ErrorTabsLayout";
|
|
11
8
|
import {
|
|
12
|
-
type ClientContext,
|
|
13
9
|
getValidPage,
|
|
14
10
|
withLoaderErrorBoundary,
|
|
15
11
|
withAuthLoader,
|
|
16
12
|
withProviders,
|
|
17
13
|
} from "../features/shared/utils";
|
|
18
14
|
|
|
19
|
-
import type {
|
|
15
|
+
import type {
|
|
16
|
+
ProductAssortmentData,
|
|
17
|
+
ProductAssortmentQuery,
|
|
18
|
+
} from "../features/product-assortment/types";
|
|
20
19
|
import type { AuthRouteProps, LoaderData } from "../features/shared/types";
|
|
21
20
|
|
|
22
|
-
export type CollectionsData = {
|
|
23
|
-
collections: ScopeCollection[];
|
|
24
|
-
drawerCollections: ScopeCollection[];
|
|
25
|
-
isContractEmpty: boolean;
|
|
26
|
-
search: string;
|
|
27
|
-
page: number;
|
|
28
|
-
context: {
|
|
29
|
-
clientContext: ClientContext;
|
|
30
|
-
currentOrgUnit: OrgUnitBasicData;
|
|
31
|
-
currentContract: ContractData | null;
|
|
32
|
-
};
|
|
33
|
-
hasError?: boolean;
|
|
34
|
-
error?: ErrorBoundaryProps;
|
|
35
|
-
};
|
|
36
|
-
|
|
37
|
-
export type CollectionsQuery = {
|
|
38
|
-
orgUnitId: string;
|
|
39
|
-
contractId: string;
|
|
40
|
-
search: string;
|
|
41
|
-
page: string;
|
|
42
|
-
};
|
|
43
|
-
|
|
44
21
|
const loaderFunction = async (
|
|
45
|
-
data: LoaderData<
|
|
46
|
-
): Promise<AuthRouteProps<
|
|
22
|
+
data: LoaderData<ProductAssortmentQuery>
|
|
23
|
+
): Promise<AuthRouteProps<ProductAssortmentData>> => {
|
|
47
24
|
const { contractId, orgUnitId, search = "", page: pageString } = data.query;
|
|
48
25
|
|
|
49
26
|
const page = getValidPage(pageString);
|
|
@@ -54,9 +31,9 @@ const loaderFunction = async (
|
|
|
54
31
|
getContractDetailsService({ contractId, cookie, unitId: orgUnitId }),
|
|
55
32
|
]);
|
|
56
33
|
|
|
57
|
-
const [
|
|
34
|
+
const [enabledAssortment, allAssortment, contractAssortment] =
|
|
58
35
|
await Promise.all([
|
|
59
|
-
|
|
36
|
+
getProductAssortmentFromScopeService({
|
|
60
37
|
cookie,
|
|
61
38
|
contractId,
|
|
62
39
|
unitId: orgUnitId,
|
|
@@ -64,14 +41,14 @@ const loaderFunction = async (
|
|
|
64
41
|
name: search,
|
|
65
42
|
page,
|
|
66
43
|
}),
|
|
67
|
-
|
|
44
|
+
getProductAssortmentFromScopeService({
|
|
68
45
|
cookie,
|
|
69
46
|
contractId,
|
|
70
47
|
unitId: orgUnitId,
|
|
71
48
|
filterByScope: false,
|
|
72
49
|
page: 1,
|
|
73
50
|
}),
|
|
74
|
-
|
|
51
|
+
getProductAssortmentFromContractService({
|
|
75
52
|
contractId,
|
|
76
53
|
cookie,
|
|
77
54
|
unitId: orgUnitId,
|
|
@@ -79,12 +56,14 @@ const loaderFunction = async (
|
|
|
79
56
|
]);
|
|
80
57
|
|
|
81
58
|
const isContractEmpty =
|
|
82
|
-
!Array.isArray(
|
|
83
|
-
const
|
|
59
|
+
!Array.isArray(contractAssortment) || contractAssortment?.length === 0;
|
|
60
|
+
const drawerProductAssortment = allAssortment.filter(
|
|
61
|
+
(col) => !col.isEnabled
|
|
62
|
+
);
|
|
84
63
|
|
|
85
64
|
return {
|
|
86
|
-
|
|
87
|
-
|
|
65
|
+
productAssortment: enabledAssortment,
|
|
66
|
+
drawerProductAssortment,
|
|
88
67
|
isContractEmpty,
|
|
89
68
|
search,
|
|
90
69
|
page,
|
|
@@ -98,28 +77,28 @@ const loaderFunction = async (
|
|
|
98
77
|
};
|
|
99
78
|
|
|
100
79
|
export const loader = withLoaderErrorBoundary(loaderFunction, {
|
|
101
|
-
componentName: "
|
|
80
|
+
componentName: "ProductAssortmentPage",
|
|
102
81
|
redirectToError: true,
|
|
103
82
|
});
|
|
104
83
|
|
|
105
|
-
const
|
|
106
|
-
|
|
107
|
-
|
|
84
|
+
const ProductAssortmentPage = ({
|
|
85
|
+
productAssortment,
|
|
86
|
+
drawerProductAssortment,
|
|
108
87
|
isContractEmpty,
|
|
109
88
|
page,
|
|
110
89
|
search,
|
|
111
90
|
hasError,
|
|
112
91
|
error,
|
|
113
|
-
}:
|
|
92
|
+
}: ProductAssortmentData) => (
|
|
114
93
|
<>
|
|
115
94
|
{hasError ? (
|
|
116
95
|
<ErrorTabsLayout error={error} />
|
|
117
96
|
) : (
|
|
118
|
-
<
|
|
97
|
+
<ProductAssortmentLayout
|
|
119
98
|
page={page}
|
|
120
99
|
search={search}
|
|
121
|
-
|
|
122
|
-
|
|
100
|
+
initialProductAssortment={productAssortment}
|
|
101
|
+
drawerProductAssortment={drawerProductAssortment}
|
|
123
102
|
isContractEmpty={isContractEmpty}
|
|
124
103
|
/>
|
|
125
104
|
)}
|
|
@@ -127,10 +106,10 @@ const CollectionsPage = ({
|
|
|
127
106
|
);
|
|
128
107
|
|
|
129
108
|
export default withProviders(
|
|
130
|
-
withErrorBoundary(
|
|
109
|
+
withErrorBoundary(ProductAssortmentPage, {
|
|
131
110
|
tags: {
|
|
132
|
-
component: "
|
|
133
|
-
errorType: "
|
|
111
|
+
component: "ProductAssortmentPage",
|
|
112
|
+
errorType: "product_assortment_error",
|
|
134
113
|
},
|
|
135
114
|
})
|
|
136
115
|
);
|
package/src/themes/layouts.scss
CHANGED
|
@@ -22,8 +22,8 @@
|
|
|
22
22
|
@import "../features/org-units/layouts/OrgUnitsLayout/org-units-layout.scss";
|
|
23
23
|
@import "../features/org-units/layouts/OrgUnitDetailsLayout/org-units-details.scss";
|
|
24
24
|
|
|
25
|
-
//
|
|
26
|
-
@import "../features/
|
|
25
|
+
// Product Assortment
|
|
26
|
+
@import "../features/product-assortment/layouts/ProductAssortmentLayout/product-assortment-layout.scss";
|
|
27
27
|
|
|
28
28
|
// Credit Cards
|
|
29
29
|
@import "../features/credit-cards/layouts/CreditCardsLayout/credit-card-layout.scss";
|