@vtex/faststore-plugin-buyer-portal 1.3.37 → 1.3.39

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.
Files changed (26) hide show
  1. package/CHANGELOG.md +16 -1
  2. package/package.json +1 -1
  3. package/src/features/payment-methods/clients/PaymentMethodsClient.ts +9 -4
  4. package/src/features/payment-methods/components/AddPaymentMethodsDrawer/AddPaymentMethodsDrawer.tsx +75 -10
  5. package/src/features/payment-methods/components/AddPaymentMethodsDrawer/add-payment-methods-drawer.scss +17 -0
  6. package/src/features/payment-methods/hooks/useDebouncedSearchPaymentMethods.ts +4 -4
  7. package/src/features/payment-methods/hooks/useGetPaymentMethodsByUnitId.ts +2 -3
  8. package/src/features/payment-methods/layouts/PaymentMethodsLayout/PaymentMethodsLayout.tsx +82 -59
  9. package/src/features/payment-methods/layouts/PaymentMethodsLayout/payment-methods-layout.scss +147 -122
  10. package/src/features/payment-methods/services/get-payment-methods-by-unit-id.service.ts +7 -5
  11. package/src/features/payment-methods/types/PaymentMethod.ts +7 -0
  12. package/src/features/payment-methods/types/index.ts +1 -1
  13. package/src/features/product-assortment/clients/ProductAssortmentClient.ts +14 -9
  14. package/src/features/product-assortment/components/AddProductAssortmentDrawer/AddProductAssortmentDrawer.tsx +73 -28
  15. package/src/features/product-assortment/components/AddProductAssortmentDrawer/add-product-assortment-drawer.scss +4 -0
  16. package/src/features/product-assortment/components/ProductAssortmentTable/ProductAssortmentTable.tsx +2 -2
  17. package/src/features/product-assortment/hooks/index.ts +3 -0
  18. package/src/features/product-assortment/hooks/useGetProductAssortments.ts +35 -0
  19. package/src/features/product-assortment/layouts/ProductAssortmentLayout/ProductAssortmentLayout.tsx +67 -27
  20. package/src/features/product-assortment/services/get-product-assortment-from-contract.service.ts +4 -5
  21. package/src/features/product-assortment/services/get-product-assortment-from-scope.service.ts +9 -4
  22. package/src/features/product-assortment/services/index.ts +4 -0
  23. package/src/features/product-assortment/types/index.ts +19 -14
  24. package/src/features/shared/utils/constants.ts +1 -1
  25. package/src/pages/payment-methods.tsx +23 -4
  26. package/src/pages/productAssortment.tsx +18 -17
@@ -14,7 +14,7 @@ import { ProductAssortmentTable } from "../../components/ProductAssortmentTable/
14
14
 
15
15
  import type {
16
16
  ProductAssortmentLayoutProps,
17
- ScopeProductAssortment,
17
+ ProductAssortmentWithAdditionalInformation,
18
18
  } from "../../types";
19
19
 
20
20
  export const ProductAssortmentLayout = ({
@@ -36,20 +36,37 @@ export const ProductAssortmentLayout = ({
36
36
  searchTerm,
37
37
  setSearchTerm,
38
38
  increasePage,
39
- } = usePageItems<ScopeProductAssortment>({
40
- initialItems: initialProductAssortment,
39
+ decreasePage,
40
+ } = usePageItems<ProductAssortmentWithAdditionalInformation>({
41
+ initialItems: initialProductAssortment.items,
41
42
  search,
42
43
  page,
43
44
  });
44
45
 
46
+ const isLastPage =
47
+ initialProductAssortment.paging.pages === page ||
48
+ initialProductAssortment.paging.pages === 0;
49
+
45
50
  const {
46
51
  open: openAddProductAssortmentDrawer,
47
52
  isOpen: isOpenAddProductAssortmentDrawer,
48
53
  ...addProductAssortmentDrawerProps
49
54
  } = useDrawerProps();
50
55
 
51
- const enabledAssortment = productAssortment.filter((p) => p.isEnabled);
52
- const hasAllAssortment = drawerProductAssortment.length === 0;
56
+ //const enabledAssortment = productAssortment.filter((p) => p.isEnabled);
57
+ const hasAllAssortment = drawerProductAssortment.items.length === 0;
58
+ const isEmpty = productAssortment.length === 0;
59
+
60
+ const renderEmpty = () => (
61
+ <EmptyState
62
+ title="No results found"
63
+ description={
64
+ searchTerm.length > 0
65
+ ? "Try using different terms"
66
+ : "No Product Assorments found"
67
+ }
68
+ />
69
+ );
53
70
 
54
71
  return (
55
72
  <GlobalLayout>
@@ -102,39 +119,62 @@ export const ProductAssortmentLayout = ({
102
119
  textSearch={setSearchTerm}
103
120
  />
104
121
  <Paginator.Counter
105
- total={enabledAssortment.length}
106
- itemsLength={enabledAssortment.length}
122
+ total={initialProductAssortment.paging.total}
123
+ itemsLength={
124
+ isLastPage
125
+ ? initialProductAssortment.paging.total
126
+ : page * initialProductAssortment.paging.perPage
127
+ }
107
128
  />
108
129
  </div>
109
130
 
110
- <section>
111
- <ProductAssortmentTable productAssortment={productAssortment} />
131
+ {!isLoading && productAssortment.length === 0 ? (
132
+ renderEmpty()
133
+ ) : (
134
+ <section>
135
+ <ProductAssortmentTable
136
+ productAssortment={productAssortment}
137
+ />
112
138
 
113
- <div data-fs-bp-product-assortment-paginator>
114
- {enabledAssortment.length > productAssortment.length ? (
115
- <Paginator.NextPageButton
116
- onClick={increasePage}
117
- disabled={isLoading}
118
- >
119
- {isLoading ? "Loading" : "Load More"}
120
- </Paginator.NextPageButton>
121
- ) : (
122
- <span />
123
- )}
139
+ <div data-fs-bp-product-assortment-paginator>
140
+ {initialProductAssortment.paging.page > 1 ? (
141
+ <Paginator.NextPageButton
142
+ onClick={decreasePage}
143
+ disabled={isLoading}
144
+ >
145
+ {isLoading ? "Loading" : "Previous Page"}
146
+ </Paginator.NextPageButton>
147
+ ) : (
148
+ <></>
149
+ )}
150
+ {!isLastPage && !isEmpty ? (
151
+ <Paginator.NextPageButton
152
+ onClick={increasePage}
153
+ disabled={isLoading}
154
+ >
155
+ {isLoading ? "Loading" : "Next Page"}
156
+ </Paginator.NextPageButton>
157
+ ) : (
158
+ <></>
159
+ )}
124
160
 
125
- <Paginator.Counter
126
- total={enabledAssortment.length}
127
- itemsLength={enabledAssortment.length}
128
- />
129
- </div>
130
- </section>
161
+ <Paginator.Counter
162
+ total={initialProductAssortment.paging.total}
163
+ itemsLength={
164
+ isLastPage
165
+ ? initialProductAssortment.paging.total
166
+ : page * initialProductAssortment.paging.perPage
167
+ }
168
+ />
169
+ </div>
170
+ </section>
171
+ )}
131
172
  </div>
132
173
  )}
133
174
  </section>
134
175
 
135
176
  {isOpenAddProductAssortmentDrawer && (
136
177
  <AddProductAssortmentDrawer
137
- productAssortment={drawerProductAssortment}
138
178
  isOpen={isOpenAddProductAssortmentDrawer}
139
179
  {...addProductAssortmentDrawerProps}
140
180
  />
@@ -2,12 +2,11 @@ import { productAssortmentClient } from "../clients/ProductAssortmentClient";
2
2
 
3
3
  export const getProductAssortmentFromContractService = async (
4
4
  params: Parameters<
5
- typeof productAssortmentClient.getProductAssortmentFromContract
5
+ typeof productAssortmentClient.getProductAssortmentsInfoInContract
6
6
  >[0]
7
7
  ) => {
8
- const data = await productAssortmentClient.getProductAssortmentFromContract(
9
- params
10
- );
8
+ const data =
9
+ await productAssortmentClient.getProductAssortmentsInfoInContract(params);
11
10
 
12
- return data;
11
+ return data.paging;
13
12
  };
@@ -1,11 +1,16 @@
1
1
  import { isRightFormat } from "../../shared/utils/isRightFormat";
2
2
  import { productAssortmentClient } from "../clients/ProductAssortmentClient";
3
+ import { GetProductAssortmentFromContractResponse } from "../types";
3
4
 
4
- export const getProductAssortmentFromScopeService = async (
5
+ export interface GetProductAssortmentFromScopeServiceProps {
5
6
  args: Parameters<
6
7
  typeof productAssortmentClient.getProductAssortmentListInScope
7
- >[0]
8
- ) => {
8
+ >[0];
9
+ }
10
+
11
+ export const getProductAssortmentFromScopeService = async ({
12
+ args,
13
+ }: GetProductAssortmentFromScopeServiceProps) => {
9
14
  try {
10
15
  const data = await productAssortmentClient.getProductAssortmentListInScope(
11
16
  args
@@ -19,7 +24,7 @@ export const getProductAssortmentFromScopeService = async (
19
24
  isRightFormat(err) &&
20
25
  err.message.startsWith("No Product assortment found for the name")
21
26
  ) {
22
- return [];
27
+ return {} as GetProductAssortmentFromContractResponse;
23
28
  }
24
29
  }
25
30
 
@@ -0,0 +1,4 @@
1
+ export {
2
+ getProductAssortmentFromScopeService,
3
+ type GetProductAssortmentFromScopeServiceProps,
4
+ } from "./get-product-assortment-from-scope.service";
@@ -9,19 +9,26 @@ export type ProductAssortmentSummary = {
9
9
  name: string;
10
10
  };
11
11
 
12
- export type ContractProductAssortment = ProductAssortmentSummary & {
13
- isEnabled: boolean;
14
- };
15
- export type ScopeProductAssortment = ProductAssortmentSummary & {
16
- isEnabled: boolean;
12
+ export type ProductAssortmentWithAdditionalInformation =
13
+ ProductAssortmentSummary & {
14
+ isEnabled: boolean;
15
+ };
16
+
17
+ export type PageControl = {
18
+ page: number;
19
+ perPage: number;
20
+ total: number;
21
+ pages: number;
22
+ limit: number;
17
23
  };
18
24
 
19
25
  export type GetProductAssortmentFromContractResponse = {
20
- collections: Array<ContractProductAssortment>;
26
+ items: Array<ProductAssortmentWithAdditionalInformation>;
27
+ paging: PageControl;
21
28
  };
22
29
 
23
30
  export type GetProductAssortmentFromScopeResponse = {
24
- collections: Array<ScopeProductAssortment>;
31
+ collections: Array<ProductAssortmentWithAdditionalInformation>;
25
32
  };
26
33
 
27
34
  export type AddProductAssortmentResponse = {
@@ -34,9 +41,7 @@ export type AddProductAssortmentPayload = Array<{ name: string }>;
34
41
  export type AddProductAssortmentDrawerProps = Omit<
35
42
  BasicDrawerProps,
36
43
  "children"
37
- > & {
38
- productAssortment: ScopeProductAssortment[];
39
- };
44
+ >;
40
45
 
41
46
  export type RemoveProductAssortmentDrawerProps = Omit<
42
47
  BasicDrawerProps,
@@ -50,16 +55,16 @@ export interface ProductAssortmentSelectedProps {
50
55
  }
51
56
 
52
57
  export type ProductAssortmentLayoutProps = {
53
- initialProductAssortment: ScopeProductAssortment[];
54
- drawerProductAssortment: ScopeProductAssortment[];
58
+ initialProductAssortment: GetProductAssortmentFromContractResponse;
59
+ drawerProductAssortment: GetProductAssortmentFromContractResponse;
55
60
  page: number;
56
61
  search: string;
57
62
  isContractEmpty: boolean;
58
63
  };
59
64
 
60
65
  export type ProductAssortmentData = {
61
- productAssortment: ScopeProductAssortment[];
62
- drawerProductAssortment: ScopeProductAssortment[];
66
+ productAssortment: GetProductAssortmentFromContractResponse;
67
+ drawerProductAssortment: GetProductAssortmentFromContractResponse;
63
68
  isContractEmpty: boolean;
64
69
  search: string;
65
70
  page: number;
@@ -13,4 +13,4 @@ export const LOCAL_STORAGE_LOCATION_EDIT_KEY = "bp_hide_edit_location_confirm";
13
13
  export const LOCAL_STORAGE_RECIPIENT_EDIT_KEY =
14
14
  "bp_hide_edit_recipient_confirm";
15
15
 
16
- export const CURRENT_VERSION = "1.3.37";
16
+ export const CURRENT_VERSION = "1.3.39";
@@ -13,18 +13,20 @@ import {
13
13
  withLoaderErrorBoundary,
14
14
  withAuthLoader,
15
15
  withProviders,
16
+ getValidPage,
16
17
  } from "../features/shared/utils";
17
18
  import { getUserByIdService } from "../features/users/services";
18
19
 
19
20
  import type { ContractData } from "../features/contracts/types";
20
21
  import type { OrgUnitBasicData } from "../features/org-units/types";
21
- import type { PaymentMethodData } from "../features/payment-methods/types";
22
+ import type { PaginatedPaymentMethod } from "../features/payment-methods/types";
22
23
  import type { AuthRouteProps, LoaderData } from "../features/shared/types";
23
24
  import type { UserData } from "../features/users/types";
24
25
 
25
26
  export type PaymentMethodsPageData = {
26
- data: PaymentMethodData[];
27
+ data: PaginatedPaymentMethod;
27
28
  search?: string;
29
+ totalPaymentMethods: number;
28
30
  context: {
29
31
  currentContract: ContractData | null;
30
32
  clientContext: ClientContext;
@@ -38,12 +40,15 @@ export type PaymentMethodsPageData = {
38
40
  export type PaymentMethodsPageQuery = GetPaymentMethodsByUnitIdServiceProps & {
39
41
  orgUnitId: string;
40
42
  contractId: string;
43
+ page: string;
41
44
  };
42
45
 
43
46
  const loaderFunction = async (
44
47
  data: LoaderData<PaymentMethodsPageQuery>
45
48
  ): Promise<AuthRouteProps<PaymentMethodsPageData>> => {
46
- const { contractId, orgUnitId, search } = data.query;
49
+ const { contractId, orgUnitId, search, page: pageString } = data.query;
50
+
51
+ const page = getValidPage(pageString);
47
52
 
48
53
  return withAuthLoader(data, async ({ cookie, userId, ...clientContext }) => {
49
54
  const currentOrgUnit = await getOrgUnitBasicDataService({
@@ -63,11 +68,21 @@ const loaderFunction = async (
63
68
  customerId: contractId,
64
69
  unitId: currentOrgUnit.id,
65
70
  cookie,
71
+ search,
72
+ page,
73
+ filterByScope: true,
74
+ });
75
+
76
+ const contractPaymentMethods = await getPaymentMethodsByUnitIdService({
77
+ customerId: contractId,
78
+ unitId: currentOrgUnit.id,
79
+ cookie,
66
80
  });
67
81
 
68
82
  return {
69
83
  data: paymentMethods,
70
84
  search: search ?? "",
85
+ totalPaymentMethods: contractPaymentMethods.paging.total,
71
86
  context: {
72
87
  clientContext: { cookie, userId, ...clientContext },
73
88
  currentOrgUnit,
@@ -85,6 +100,7 @@ export const loader = withLoaderErrorBoundary(loaderFunction, {
85
100
 
86
101
  const PaymentMethodsPage = ({
87
102
  data,
103
+ totalPaymentMethods,
88
104
  hasError,
89
105
  error,
90
106
  }: PaymentMethodsPageData) => (
@@ -92,7 +108,10 @@ const PaymentMethodsPage = ({
92
108
  {hasError ? (
93
109
  <ErrorTabsLayout error={error} />
94
110
  ) : (
95
- <PaymentMethodsLayout data={data} />
111
+ <PaymentMethodsLayout
112
+ data={data}
113
+ totalPaymentMethods={totalPaymentMethods}
114
+ />
96
115
  )}
97
116
  </>
98
117
  );
@@ -31,22 +31,26 @@ const loaderFunction = async (
31
31
  getContractDetailsService({ contractId, cookie, unitId: orgUnitId }),
32
32
  ]);
33
33
 
34
- const [enabledAssortment, allAssortment, contractAssortment] =
34
+ const [enabledAssortment, notAddedAssortments, contractAssortment] =
35
35
  await Promise.all([
36
36
  getProductAssortmentFromScopeService({
37
- cookie,
38
- contractId,
39
- unitId: orgUnitId,
40
- filterByScope: true,
41
- name: search,
42
- page,
37
+ args: {
38
+ cookie,
39
+ contractId,
40
+ unitId: orgUnitId,
41
+ filterByScope: true,
42
+ name: search,
43
+ page,
44
+ },
43
45
  }),
44
46
  getProductAssortmentFromScopeService({
45
- cookie,
46
- contractId,
47
- unitId: orgUnitId,
48
- filterByScope: false,
49
- page: 1,
47
+ args: {
48
+ cookie,
49
+ contractId,
50
+ unitId: orgUnitId,
51
+ filterByScope: false,
52
+ page: 1,
53
+ },
50
54
  }),
51
55
  getProductAssortmentFromContractService({
52
56
  contractId,
@@ -56,14 +60,11 @@ const loaderFunction = async (
56
60
  ]);
57
61
 
58
62
  const isContractEmpty =
59
- !Array.isArray(contractAssortment) || contractAssortment?.length === 0;
60
- const drawerProductAssortment = allAssortment.filter(
61
- (col) => !col.isEnabled
62
- );
63
+ !contractAssortment || contractAssortment.total === 0;
63
64
 
64
65
  return {
65
66
  productAssortment: enabledAssortment,
66
- drawerProductAssortment,
67
+ drawerProductAssortment: notAddedAssortments,
67
68
  isContractEmpty,
68
69
  search,
69
70
  page,