@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
|
@@ -1,25 +1,24 @@
|
|
|
1
|
-
|
|
2
|
-
@import "../../components/table/add-collections-drawer-table.scss";
|
|
3
|
-
|
|
4
|
-
[data-fs-bp-add-collections-drawer] {
|
|
5
|
-
@import "../../../shared/components/InputText/input-text.scss";
|
|
1
|
+
[data-fs-bp-add-product-assortment-drawer] {
|
|
6
2
|
@import "@faststore/ui/src/components/atoms/Button/styles.scss";
|
|
3
|
+
@import "../../../shared/components/BasicDrawer/basic-drawer.scss";
|
|
4
|
+
@import "../../../shared/components/InputText/input-text.scss";
|
|
7
5
|
@import "../../../shared/components/InternalSearch/internal-search.scss";
|
|
8
6
|
@import "../../../shared/components/ErrorMessage/error-message.scss";
|
|
9
7
|
@import "../../../shared/components/Paginator/paginator.scss";
|
|
8
|
+
@import "../../components/table/add-product-assortment-drawer-table.scss";
|
|
10
9
|
|
|
11
10
|
&[data-fs-bp-basic-drawer] {
|
|
12
11
|
max-width: 60rem !important;
|
|
13
12
|
width: 100%;
|
|
14
13
|
}
|
|
15
14
|
|
|
16
|
-
[data-fs-bp-add-
|
|
15
|
+
[data-fs-bp-add-product-assortment-text-drawer] {
|
|
17
16
|
display: block;
|
|
18
17
|
color: var(--fs-color-neutral-5);
|
|
19
18
|
margin-bottom: 1.25rem;
|
|
20
19
|
}
|
|
21
20
|
|
|
22
|
-
[data-fs-bp-add-
|
|
21
|
+
[data-fs-bp-add-product-assortment-wrapper] {
|
|
23
22
|
display: flex;
|
|
24
23
|
align-items: center;
|
|
25
24
|
justify-content: space-between;
|
|
@@ -36,7 +35,7 @@
|
|
|
36
35
|
}
|
|
37
36
|
}
|
|
38
37
|
|
|
39
|
-
[data-fs-bp-add-
|
|
38
|
+
[data-fs-bp-add-product-assortment-drawer-empty-state] {
|
|
40
39
|
display: flex;
|
|
41
40
|
flex-direction: column;
|
|
42
41
|
justify-content: center;
|
|
@@ -53,7 +52,7 @@
|
|
|
53
52
|
}
|
|
54
53
|
}
|
|
55
54
|
|
|
56
|
-
[data-fs-bp-drawer-
|
|
55
|
+
[data-fs-bp-drawer-product-assortment-paginator] {
|
|
57
56
|
display: flex;
|
|
58
57
|
align-items: center;
|
|
59
58
|
justify-content: space-between;
|
|
@@ -61,7 +60,7 @@
|
|
|
61
60
|
padding: var(--fs-spacing-2) 0;
|
|
62
61
|
}
|
|
63
62
|
|
|
64
|
-
[data-fs-bp-add-
|
|
63
|
+
[data-fs-bp-add-product-assortment-drawer-footer] {
|
|
65
64
|
justify-content: end;
|
|
66
65
|
gap: 1.25rem;
|
|
67
66
|
}
|
package/src/features/product-assortment/components/ProductAssortmentTable/ProductAssortmentTable.tsx
ADDED
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
import { useState } from "react";
|
|
2
|
+
|
|
3
|
+
import { useSearchParams } from "next/navigation";
|
|
4
|
+
|
|
5
|
+
import { IconButton, Tooltip } from "@faststore/ui";
|
|
6
|
+
|
|
7
|
+
import { Icon, Table } from "../../../shared/components";
|
|
8
|
+
import { getTableColumns } from "../../../shared/components/Table/utils/tableColumns";
|
|
9
|
+
import { useDrawerProps } from "../../../shared/hooks";
|
|
10
|
+
import { RemoveProductAssortmentDrawer } from "../RemoveProductAssortmentDrawer/RemoveProductAssortmentDrawer";
|
|
11
|
+
|
|
12
|
+
import type {
|
|
13
|
+
ProductAssortmentSelectedProps,
|
|
14
|
+
ScopeProductAssortment,
|
|
15
|
+
} from "../../types";
|
|
16
|
+
|
|
17
|
+
export function ProductAssortmentTable({
|
|
18
|
+
productAssortment,
|
|
19
|
+
}: {
|
|
20
|
+
productAssortment: ScopeProductAssortment[];
|
|
21
|
+
}) {
|
|
22
|
+
const [assortmentSelected, setAssortmentSelected] =
|
|
23
|
+
useState<ProductAssortmentSelectedProps | null>();
|
|
24
|
+
|
|
25
|
+
const {
|
|
26
|
+
open: openRemoveProductAssortmentDrawer,
|
|
27
|
+
isOpen: isRemoveProductAssortmentDrawerOpen,
|
|
28
|
+
...removeProductAssortmentDrawerProps
|
|
29
|
+
} = useDrawerProps();
|
|
30
|
+
|
|
31
|
+
const searchParams = useSearchParams();
|
|
32
|
+
|
|
33
|
+
const searchTerm = searchParams.get("search");
|
|
34
|
+
|
|
35
|
+
const enabledAssortment = productAssortment.filter(
|
|
36
|
+
(a) =>
|
|
37
|
+
a.isEnabled &&
|
|
38
|
+
(!searchTerm ||
|
|
39
|
+
(searchTerm && a.name.toLowerCase().includes(searchTerm.toString())))
|
|
40
|
+
);
|
|
41
|
+
const removeDisabled = enabledAssortment.length === 1;
|
|
42
|
+
const removeTooltipContent = removeDisabled
|
|
43
|
+
? "This product assortment can’t be removed. Each unit must have at least one active product assortment. Add another one to proceed with the removal."
|
|
44
|
+
: "Remove from unit";
|
|
45
|
+
|
|
46
|
+
function handleRemoveSelectedAssortment(
|
|
47
|
+
productAssortment: ProductAssortmentSelectedProps
|
|
48
|
+
) {
|
|
49
|
+
setAssortmentSelected(productAssortment);
|
|
50
|
+
openRemoveProductAssortmentDrawer();
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
const columns = getTableColumns({ actionsLength: 1 });
|
|
54
|
+
|
|
55
|
+
return (
|
|
56
|
+
<div data-fs-bp-product-assortment-table>
|
|
57
|
+
<Table layoutFixed>
|
|
58
|
+
<Table.Head columns={columns} />
|
|
59
|
+
<Table.Body>
|
|
60
|
+
{productAssortment.map((item) => (
|
|
61
|
+
<Table.Row
|
|
62
|
+
iconName="Shapes"
|
|
63
|
+
title={item.name}
|
|
64
|
+
key={item.id}
|
|
65
|
+
iconSize={24}
|
|
66
|
+
searchTerm={searchTerm ?? undefined}
|
|
67
|
+
actionIcons={
|
|
68
|
+
<Tooltip
|
|
69
|
+
content={removeTooltipContent}
|
|
70
|
+
placement={"left-center"}
|
|
71
|
+
>
|
|
72
|
+
<IconButton
|
|
73
|
+
data-fs-product-assortment-row-action-button
|
|
74
|
+
icon={<Icon name={"MinusCircle"} width={20} height={20} />}
|
|
75
|
+
aria-label="Remove product assortment"
|
|
76
|
+
disabled={removeDisabled}
|
|
77
|
+
onClick={() =>
|
|
78
|
+
handleRemoveSelectedAssortment({
|
|
79
|
+
id: item.id,
|
|
80
|
+
name: item.name,
|
|
81
|
+
})
|
|
82
|
+
}
|
|
83
|
+
/>
|
|
84
|
+
</Tooltip>
|
|
85
|
+
}
|
|
86
|
+
/>
|
|
87
|
+
))}
|
|
88
|
+
</Table.Body>
|
|
89
|
+
</Table>
|
|
90
|
+
{assortmentSelected && (
|
|
91
|
+
<RemoveProductAssortmentDrawer
|
|
92
|
+
isOpen={isRemoveProductAssortmentDrawerOpen}
|
|
93
|
+
productAssortment={assortmentSelected}
|
|
94
|
+
{...removeProductAssortmentDrawerProps}
|
|
95
|
+
/>
|
|
96
|
+
)}
|
|
97
|
+
</div>
|
|
98
|
+
);
|
|
99
|
+
}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
[data-fs-bp-product-assortment-table] {
|
|
2
|
+
@import "@faststore/ui/src/components/molecules/Tooltip/styles.scss";
|
|
3
|
+
@import "../AddProductAssortmentDrawer/add-product-assortment-drawer.scss";
|
|
4
|
+
@import "../../../shared/components/Table/table.scss";
|
|
5
|
+
|
|
6
|
+
width: 100%;
|
|
7
|
+
|
|
8
|
+
[data-fs-tooltip] {
|
|
9
|
+
--fs-tooltip-background: #1f1f1f;
|
|
10
|
+
border-bottom: none;
|
|
11
|
+
text-wrap: balance;
|
|
12
|
+
text-align: justify;
|
|
13
|
+
|
|
14
|
+
[data-fs-tooltip-placement="left-center"] {
|
|
15
|
+
[data-fs-tooltip-indicator="true"] {
|
|
16
|
+
margin-left: -0.1%;
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
[data-fs-tooltip-placement="top-center"] {
|
|
20
|
+
[data-fs-tooltip-indicator="true"] {
|
|
21
|
+
margin-top: -1%;
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
[data-fs-product-assortment-row-action-button] {
|
|
27
|
+
width: var(--fs-spacing-6);
|
|
28
|
+
height: var(--fs-spacing-6);
|
|
29
|
+
display: inline-flex;
|
|
30
|
+
border-radius: var(--fs-border-radius-pill);
|
|
31
|
+
justify-content: center;
|
|
32
|
+
align-items: center;
|
|
33
|
+
|
|
34
|
+
&:hover:not(:disabled) {
|
|
35
|
+
background-color: #ebebeb;
|
|
36
|
+
cursor: pointer;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
[data-fs-button-icon] {
|
|
40
|
+
display: block;
|
|
41
|
+
width: calc(var(--fs-spacing-4) - var(--fs-spacing-0));
|
|
42
|
+
height: calc(var(--fs-spacing-4) - var(--fs-spacing-0));
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
}
|
|
@@ -2,35 +2,32 @@ import { useRouter } from "next/router";
|
|
|
2
2
|
|
|
3
3
|
import { Link, useUI } from "@faststore/ui";
|
|
4
4
|
|
|
5
|
-
import { BasicDrawer
|
|
5
|
+
import { BasicDrawer } from "../../../shared/components";
|
|
6
6
|
import { useBuyerPortal } from "../../../shared/hooks";
|
|
7
|
-
import {
|
|
8
|
-
import { CollectionSelectedProps } from "../../layouts/CollectionsLayout/CollectionsLayout";
|
|
7
|
+
import { useRemoveProductAssortmentFromScope } from "../../hooks/useRemoveProductAssortmentFromScope";
|
|
9
8
|
|
|
10
|
-
|
|
11
|
-
collection: CollectionSelectedProps;
|
|
12
|
-
};
|
|
9
|
+
import type { RemoveProductAssortmentDrawerProps } from "../../types";
|
|
13
10
|
|
|
14
|
-
export function
|
|
11
|
+
export function RemoveProductAssortmentDrawer({
|
|
15
12
|
close,
|
|
16
|
-
|
|
13
|
+
productAssortment,
|
|
17
14
|
...props
|
|
18
|
-
}:
|
|
15
|
+
}: RemoveProductAssortmentDrawerProps) {
|
|
19
16
|
const { pushToast } = useUI();
|
|
20
17
|
|
|
21
18
|
const { reload } = useRouter();
|
|
22
|
-
const
|
|
19
|
+
const removeAssortmentMutation = useRemoveProductAssortmentFromScope();
|
|
23
20
|
const { currentOrgUnit, currentContract } = useBuyerPortal();
|
|
24
21
|
|
|
25
22
|
async function handleSuccess() {
|
|
26
|
-
await
|
|
27
|
-
|
|
23
|
+
await removeAssortmentMutation.mutate({
|
|
24
|
+
productAssortmentId: productAssortment.id,
|
|
28
25
|
unitId: currentOrgUnit?.id ?? "",
|
|
29
26
|
contractId: currentContract?.id ?? "",
|
|
30
27
|
});
|
|
31
28
|
|
|
32
29
|
pushToast({
|
|
33
|
-
message: "
|
|
30
|
+
message: "Product assortment access removed successfully",
|
|
34
31
|
status: "INFO",
|
|
35
32
|
});
|
|
36
33
|
close();
|
|
@@ -39,34 +36,38 @@ export function RemoveCollectionDrawer({
|
|
|
39
36
|
}
|
|
40
37
|
|
|
41
38
|
return (
|
|
42
|
-
<BasicDrawer
|
|
39
|
+
<BasicDrawer
|
|
40
|
+
data-fs-bp-remove-product-assortment-drawer
|
|
41
|
+
close={close}
|
|
42
|
+
{...props}
|
|
43
|
+
>
|
|
43
44
|
<BasicDrawer.Heading
|
|
44
|
-
title="Remove
|
|
45
|
+
title="Remove product assortment from unit"
|
|
45
46
|
onClose={close}
|
|
46
47
|
/>
|
|
47
48
|
|
|
48
49
|
<BasicDrawer.Body>
|
|
49
50
|
<span>
|
|
50
|
-
Remove <Link href="#">{
|
|
51
|
+
Remove <Link href="#">{productAssortment.name}</Link> contract from
|
|
51
52
|
<Link href="#"> {currentOrgUnit?.name}</Link> organizational unit?
|
|
52
53
|
</span>
|
|
53
54
|
<span>
|
|
54
55
|
This action will prevent users in this unit from accessing this
|
|
55
|
-
|
|
56
|
+
product assortment during store navigation and checkout.
|
|
56
57
|
</span>
|
|
57
58
|
</BasicDrawer.Body>
|
|
58
59
|
|
|
59
|
-
<BasicDrawer.Footer data-fs-bp-add-
|
|
60
|
+
<BasicDrawer.Footer data-fs-bp-add-product-assortment-drawer-footer>
|
|
60
61
|
<BasicDrawer.Button
|
|
61
62
|
variant="ghost"
|
|
62
|
-
disabled={
|
|
63
|
+
disabled={removeAssortmentMutation.isLoading}
|
|
63
64
|
onClick={close}
|
|
64
65
|
>
|
|
65
66
|
Cancel
|
|
66
67
|
</BasicDrawer.Button>
|
|
67
68
|
<BasicDrawer.Button
|
|
68
69
|
variant="confirm"
|
|
69
|
-
isLoading={
|
|
70
|
+
isLoading={removeAssortmentMutation.isLoading}
|
|
70
71
|
onClick={handleSuccess}
|
|
71
72
|
>
|
|
72
73
|
Confirm
|
|
@@ -9,21 +9,21 @@ import {
|
|
|
9
9
|
import { Checkbox } from "@faststore/ui";
|
|
10
10
|
|
|
11
11
|
import { Table } from "../../../shared/components";
|
|
12
|
-
import { CollectionsSummary } from "../../types";
|
|
13
12
|
|
|
14
13
|
import type { TableColumn } from "../../../shared/components/Table/TableHead/TableHead";
|
|
14
|
+
import type { ProductAssortmentSummary } from "../../types";
|
|
15
15
|
|
|
16
|
-
interface
|
|
16
|
+
interface AddProductAssortmentDrawerTableProps {
|
|
17
17
|
loading?: boolean;
|
|
18
|
-
data:
|
|
19
|
-
onChange: Dispatch<SetStateAction<
|
|
18
|
+
data: ProductAssortmentSummary[];
|
|
19
|
+
onChange: Dispatch<SetStateAction<ProductAssortmentSummary[]>>;
|
|
20
20
|
}
|
|
21
21
|
|
|
22
|
-
export const
|
|
22
|
+
export const AddProductAssortmentDrawerTable = ({
|
|
23
23
|
data,
|
|
24
24
|
loading,
|
|
25
25
|
onChange,
|
|
26
|
-
}:
|
|
26
|
+
}: AddProductAssortmentDrawerTableProps) => {
|
|
27
27
|
const [selectedIds, setSelectedIds] = useState<string[]>([]);
|
|
28
28
|
|
|
29
29
|
const allIds = useMemo(() => data.map((item) => item.id), [data]);
|
|
@@ -57,7 +57,7 @@ export const AddCollectionsDrawerTable = ({
|
|
|
57
57
|
size: "2.5rem",
|
|
58
58
|
label: (
|
|
59
59
|
<Checkbox
|
|
60
|
-
data-fs-bp-
|
|
60
|
+
data-fs-bp-product-assortment-checkbox
|
|
61
61
|
checked={allSelected}
|
|
62
62
|
partial={partiallySelected}
|
|
63
63
|
onChange={handleSelectAll}
|
|
@@ -73,7 +73,7 @@ export const AddCollectionsDrawerTable = ({
|
|
|
73
73
|
];
|
|
74
74
|
|
|
75
75
|
return (
|
|
76
|
-
<div data-fs-bp-add-
|
|
76
|
+
<div data-fs-bp-add-product-assortment-drawer-table>
|
|
77
77
|
<Table layoutFixed>
|
|
78
78
|
<Table.Head columns={columns} />
|
|
79
79
|
<Table.Body>
|
|
@@ -90,7 +90,7 @@ export const AddCollectionsDrawerTable = ({
|
|
|
90
90
|
prependColumns={
|
|
91
91
|
<Table.Cell align="center">
|
|
92
92
|
<Checkbox
|
|
93
|
-
data-fs-bp-
|
|
93
|
+
data-fs-bp-product-assortment-checkbox
|
|
94
94
|
checked={selectedIds.includes(option.id)}
|
|
95
95
|
onChange={() => handleSelect(option.id)}
|
|
96
96
|
/>
|
package/src/features/product-assortment/components/table/add-product-assortment-drawer-table.scss
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
[data-fs-bp-add-product-assortment-drawer-table] {
|
|
2
|
+
@import "@faststore/ui/src/components/atoms/Checkbox/styles.scss";
|
|
3
|
+
@import "../../../shared/components/Table/table.scss";
|
|
4
|
+
|
|
5
|
+
margin-top: 1.25rem;
|
|
6
|
+
|
|
7
|
+
[data-fs-tooltip] {
|
|
8
|
+
--fs-tooltip-background: #1f1f1f;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
[data-fs-bp-product-assortment-checkbox] {
|
|
12
|
+
margin: 0 auto;
|
|
13
|
+
}
|
|
14
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { MutationOptions, useMutation } from "../../shared/hooks";
|
|
2
|
+
import { addProductAssortmentToScopeService } from "../services/add-product-assortment-to-scope.service";
|
|
3
|
+
|
|
4
|
+
export const useAddProductAssortmentToScope = (
|
|
5
|
+
options?: MutationOptions<
|
|
6
|
+
AwaitedType<typeof addProductAssortmentToScopeService>
|
|
7
|
+
>
|
|
8
|
+
) => {
|
|
9
|
+
const mutation = useMutation<
|
|
10
|
+
AwaitedType<typeof addProductAssortmentToScopeService>,
|
|
11
|
+
Omit<
|
|
12
|
+
Parameters<typeof addProductAssortmentToScopeService>[0],
|
|
13
|
+
"cookie" | "customerId"
|
|
14
|
+
>
|
|
15
|
+
>(
|
|
16
|
+
(variables, clientContext) =>
|
|
17
|
+
addProductAssortmentToScopeService({
|
|
18
|
+
...variables,
|
|
19
|
+
cookie: clientContext.cookie,
|
|
20
|
+
}),
|
|
21
|
+
options
|
|
22
|
+
);
|
|
23
|
+
|
|
24
|
+
return mutation;
|
|
25
|
+
};
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { MutationOptions, useMutation } from "../../shared/hooks";
|
|
2
|
+
import { removeProductAssortmentFromScopeService } from "../services/remove-product-assortment-from-scope";
|
|
3
|
+
|
|
4
|
+
export const useRemoveProductAssortmentFromScope = (
|
|
5
|
+
options?: MutationOptions<
|
|
6
|
+
AwaitedType<typeof removeProductAssortmentFromScopeService>
|
|
7
|
+
>
|
|
8
|
+
) => {
|
|
9
|
+
const mutation = useMutation<
|
|
10
|
+
AwaitedType<typeof removeProductAssortmentFromScopeService>,
|
|
11
|
+
Omit<
|
|
12
|
+
Parameters<typeof removeProductAssortmentFromScopeService>[0],
|
|
13
|
+
"cookie" | "customerId"
|
|
14
|
+
>
|
|
15
|
+
>(
|
|
16
|
+
(variables, clientContext) =>
|
|
17
|
+
removeProductAssortmentFromScopeService({
|
|
18
|
+
...variables,
|
|
19
|
+
|
|
20
|
+
cookie: clientContext.cookie,
|
|
21
|
+
}),
|
|
22
|
+
options
|
|
23
|
+
);
|
|
24
|
+
|
|
25
|
+
return mutation;
|
|
26
|
+
};
|
|
@@ -9,30 +9,21 @@ import { EmptyState } from "../../../shared/components/EmptyState/EmptyState";
|
|
|
9
9
|
import { useBuyerPortal, usePageItems } from "../../../shared/hooks";
|
|
10
10
|
import { useDrawerProps } from "../../../shared/hooks";
|
|
11
11
|
import { ContractTabsLayout, GlobalLayout } from "../../../shared/layouts";
|
|
12
|
-
import {
|
|
13
|
-
import {
|
|
14
|
-
import { ScopeCollection } from "../../types";
|
|
12
|
+
import { AddProductAssortmentDrawer } from "../../components";
|
|
13
|
+
import { ProductAssortmentTable } from "../../components/ProductAssortmentTable/ProductAssortmentTable";
|
|
15
14
|
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
}
|
|
15
|
+
import type {
|
|
16
|
+
ProductAssortmentLayoutProps,
|
|
17
|
+
ScopeProductAssortment,
|
|
18
|
+
} from "../../types";
|
|
20
19
|
|
|
21
|
-
export
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
page: number;
|
|
25
|
-
search: string;
|
|
26
|
-
isContractEmpty: boolean;
|
|
27
|
-
};
|
|
28
|
-
|
|
29
|
-
export const CollectionsLayout = ({
|
|
30
|
-
initialCollections,
|
|
31
|
-
drawerCollections,
|
|
20
|
+
export const ProductAssortmentLayout = ({
|
|
21
|
+
initialProductAssortment,
|
|
22
|
+
drawerProductAssortment,
|
|
32
23
|
isContractEmpty,
|
|
33
24
|
page,
|
|
34
25
|
search,
|
|
35
|
-
}:
|
|
26
|
+
}: ProductAssortmentLayoutProps) => {
|
|
36
27
|
const {
|
|
37
28
|
currentOrgUnit: orgUnit,
|
|
38
29
|
currentUser: user,
|
|
@@ -41,24 +32,24 @@ export const CollectionsLayout = ({
|
|
|
41
32
|
|
|
42
33
|
const {
|
|
43
34
|
isLoading,
|
|
44
|
-
items:
|
|
35
|
+
items: productAssortment,
|
|
45
36
|
searchTerm,
|
|
46
37
|
setSearchTerm,
|
|
47
38
|
increasePage,
|
|
48
|
-
} = usePageItems<
|
|
49
|
-
initialItems:
|
|
39
|
+
} = usePageItems<ScopeProductAssortment>({
|
|
40
|
+
initialItems: initialProductAssortment,
|
|
50
41
|
search,
|
|
51
42
|
page,
|
|
52
43
|
});
|
|
53
44
|
|
|
54
45
|
const {
|
|
55
|
-
open:
|
|
56
|
-
isOpen:
|
|
57
|
-
...
|
|
46
|
+
open: openAddProductAssortmentDrawer,
|
|
47
|
+
isOpen: isOpenAddProductAssortmentDrawer,
|
|
48
|
+
...addProductAssortmentDrawerProps
|
|
58
49
|
} = useDrawerProps();
|
|
59
50
|
|
|
60
|
-
const
|
|
61
|
-
const
|
|
51
|
+
const enabledAssortment = productAssortment.filter((p) => p.isEnabled);
|
|
52
|
+
const hasAllAssortment = drawerProductAssortment.length === 0;
|
|
62
53
|
|
|
63
54
|
return (
|
|
64
55
|
<GlobalLayout>
|
|
@@ -74,22 +65,25 @@ export const CollectionsLayout = ({
|
|
|
74
65
|
role: user?.role ?? "",
|
|
75
66
|
}}
|
|
76
67
|
>
|
|
77
|
-
<section data-fs-bp-
|
|
78
|
-
<HeaderInside title="
|
|
68
|
+
<section data-fs-bp-product-assortment-container>
|
|
69
|
+
<HeaderInside title="Product assortment">
|
|
79
70
|
{!isContractEmpty &&
|
|
80
|
-
(
|
|
71
|
+
(hasAllAssortment ? (
|
|
81
72
|
<Tooltip
|
|
82
73
|
content={
|
|
83
|
-
"All available
|
|
74
|
+
"All available product assortment have already been added to this organizational unit"
|
|
84
75
|
}
|
|
85
76
|
placement={"left-center"}
|
|
86
77
|
>
|
|
87
|
-
<HeaderInside.Button
|
|
78
|
+
<HeaderInside.Button
|
|
79
|
+
aria-label="Add product assortment"
|
|
80
|
+
disabled
|
|
81
|
+
/>
|
|
88
82
|
</Tooltip>
|
|
89
83
|
) : (
|
|
90
84
|
<HeaderInside.Button
|
|
91
|
-
aria-label="Add
|
|
92
|
-
onClick={
|
|
85
|
+
aria-label="Add product assortment"
|
|
86
|
+
onClick={openAddProductAssortmentDrawer}
|
|
93
87
|
/>
|
|
94
88
|
))}
|
|
95
89
|
</HeaderInside>
|
|
@@ -97,27 +91,27 @@ export const CollectionsLayout = ({
|
|
|
97
91
|
{isContractEmpty ? (
|
|
98
92
|
<EmptyState
|
|
99
93
|
iconName="Shapes"
|
|
100
|
-
title="This contract has no assigned
|
|
94
|
+
title="This contract has no assigned product assortment."
|
|
101
95
|
description="This means it has access to the entire product catalog of the store."
|
|
102
96
|
/>
|
|
103
97
|
) : (
|
|
104
|
-
<div data-fs-bp-
|
|
105
|
-
<div data-fs-
|
|
98
|
+
<div data-fs-bp-product-assortment-layout>
|
|
99
|
+
<div data-fs-product-assortment-filter>
|
|
106
100
|
<InternalSearch
|
|
107
101
|
defaultValue={searchTerm}
|
|
108
102
|
textSearch={setSearchTerm}
|
|
109
103
|
/>
|
|
110
104
|
<Paginator.Counter
|
|
111
|
-
total={
|
|
112
|
-
itemsLength={
|
|
105
|
+
total={enabledAssortment.length}
|
|
106
|
+
itemsLength={enabledAssortment.length}
|
|
113
107
|
/>
|
|
114
108
|
</div>
|
|
115
109
|
|
|
116
110
|
<section>
|
|
117
|
-
<
|
|
111
|
+
<ProductAssortmentTable productAssortment={productAssortment} />
|
|
118
112
|
|
|
119
|
-
<div data-fs-bp-
|
|
120
|
-
{
|
|
113
|
+
<div data-fs-bp-product-assortment-paginator>
|
|
114
|
+
{enabledAssortment.length > productAssortment.length ? (
|
|
121
115
|
<Paginator.NextPageButton
|
|
122
116
|
onClick={increasePage}
|
|
123
117
|
disabled={isLoading}
|
|
@@ -129,8 +123,8 @@ export const CollectionsLayout = ({
|
|
|
129
123
|
)}
|
|
130
124
|
|
|
131
125
|
<Paginator.Counter
|
|
132
|
-
total={
|
|
133
|
-
itemsLength={
|
|
126
|
+
total={enabledAssortment.length}
|
|
127
|
+
itemsLength={enabledAssortment.length}
|
|
134
128
|
/>
|
|
135
129
|
</div>
|
|
136
130
|
</section>
|
|
@@ -138,11 +132,11 @@ export const CollectionsLayout = ({
|
|
|
138
132
|
)}
|
|
139
133
|
</section>
|
|
140
134
|
|
|
141
|
-
{
|
|
142
|
-
<
|
|
143
|
-
|
|
144
|
-
isOpen={
|
|
145
|
-
{...
|
|
135
|
+
{isOpenAddProductAssortmentDrawer && (
|
|
136
|
+
<AddProductAssortmentDrawer
|
|
137
|
+
productAssortment={drawerProductAssortment}
|
|
138
|
+
isOpen={isOpenAddProductAssortmentDrawer}
|
|
139
|
+
{...addProductAssortmentDrawerProps}
|
|
146
140
|
/>
|
|
147
141
|
)}
|
|
148
142
|
</ContractTabsLayout>
|
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
@import "../../components/
|
|
2
|
-
@import "../../components/
|
|
1
|
+
@import "../../components/RemoveProductAssortmentDrawer/remove-product-assortment-drawer.scss";
|
|
2
|
+
@import "../../components/AddProductAssortmentDrawer/add-product-assortment-drawer.scss";
|
|
3
3
|
|
|
4
|
-
[data-fs-bp-
|
|
4
|
+
[data-fs-bp-product-assortment-container] {
|
|
5
5
|
@import "@faststore/ui/src/components/molecules/Tooltip/styles.scss";
|
|
6
6
|
@import "@faststore/ui/src/components/molecules/Table/styles.scss";
|
|
7
7
|
|
|
8
|
-
@import "../../components/
|
|
8
|
+
@import "../../components/ProductAssortmentTable/product-assortment-table.scss";
|
|
9
9
|
|
|
10
10
|
@import "../../../shared/components/InternalSearch/internal-search.scss";
|
|
11
11
|
@import "../../../shared/components/HeaderInside/header-inside.scss";
|
|
@@ -41,7 +41,7 @@
|
|
|
41
41
|
}
|
|
42
42
|
}
|
|
43
43
|
|
|
44
|
-
[data-fs-bp-
|
|
44
|
+
[data-fs-bp-product-assortment-layout] {
|
|
45
45
|
display: flex;
|
|
46
46
|
flex-direction: column;
|
|
47
47
|
gap: calc(var(--fs-spacing-3) + var(--fs-spacing-0));
|
|
@@ -56,7 +56,7 @@
|
|
|
56
56
|
}
|
|
57
57
|
}
|
|
58
58
|
|
|
59
|
-
[data-fs-
|
|
59
|
+
[data-fs-product-assortment-filter] {
|
|
60
60
|
display: flex;
|
|
61
61
|
justify-content: space-between;
|
|
62
62
|
align-items: center;
|
|
@@ -73,7 +73,7 @@
|
|
|
73
73
|
}
|
|
74
74
|
}
|
|
75
75
|
|
|
76
|
-
[data-fs-bp-
|
|
76
|
+
[data-fs-bp-product-assortment-paginator] {
|
|
77
77
|
display: flex;
|
|
78
78
|
align-items: center;
|
|
79
79
|
justify-content: space-between;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { ProductAssortmentLayout } from "./ProductAssortmentLayout/ProductAssortmentLayout";
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { productAssortmentClient } from "../clients/ProductAssortmentClient";
|
|
2
|
+
|
|
3
|
+
import type { AddProductAssortmentPayload } from "../types";
|
|
4
|
+
|
|
5
|
+
export const addProductAssortmentToScopeService = async (params: {
|
|
6
|
+
contractId: string;
|
|
7
|
+
cookie: string;
|
|
8
|
+
unitId: string;
|
|
9
|
+
data: AddProductAssortmentPayload;
|
|
10
|
+
}) => {
|
|
11
|
+
const response = await productAssortmentClient.addProductAssortmentToScope(
|
|
12
|
+
params
|
|
13
|
+
);
|
|
14
|
+
|
|
15
|
+
return response;
|
|
16
|
+
};
|