@riosst100/pwa-marketplace 2.3.2 → 2.3.4
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/package.json +1 -1
- package/src/components/ProductContent/index.js +1 -0
- package/src/components/ProductContent/productContent.js +234 -0
- package/src/components/SellerDetail/sellerDetail.js +1 -1
- package/src/components/SellerProducts/productContent.js +238 -0
- package/src/components/SellerProducts/sellerProducts.js +109 -46
- package/src/overwrites/peregrine/lib/talons/RootComponents/Category/useCategory.js +4 -0
- package/src/overwrites/venia-ui/lib/RootComponents/Category/categoryContent.js +2 -0
- package/src/overwrites/venia-ui/lib/components/MegaMenu/submenuColumn.js +4 -52
- package/src/talons/ProductContent/index.js +1 -0
- package/src/talons/ProductContent/productContent.gql.js +98 -0
- package/src/talons/ProductContent/useProductContent.js +192 -0
- package/src/talons/SellerProducts/categoryFragments.gql.js +103 -0
- package/src/talons/SellerProducts/index.js +2 -0
- package/src/talons/SellerProducts/productContent.gql.js +98 -0
- package/src/talons/SellerProducts/sellerProducts.gql.js +63 -0
- package/src/talons/SellerProducts/useProductContent.js +194 -0
- package/src/talons/SellerProducts/useSellerProducts.js +264 -0
|
@@ -0,0 +1,194 @@
|
|
|
1
|
+
import React, { useEffect, useMemo } from 'react';
|
|
2
|
+
import { useLazyQuery, useQuery } from '@apollo/client';
|
|
3
|
+
|
|
4
|
+
import mergeOperations from '@magento/peregrine/lib/util/shallowMerge';
|
|
5
|
+
import { useEventingContext } from '@magento/peregrine/lib/context/eventing';
|
|
6
|
+
|
|
7
|
+
import DEFAULT_OPERATIONS from './productContent.gql';
|
|
8
|
+
|
|
9
|
+
export const useProductContent = props => {
|
|
10
|
+
const { sellerId, data, pageSize = 6 } = props;
|
|
11
|
+
|
|
12
|
+
const operations = mergeOperations(DEFAULT_OPERATIONS, props.operations);
|
|
13
|
+
|
|
14
|
+
const {
|
|
15
|
+
getCategoryContentQuery,
|
|
16
|
+
getProductFiltersByCategoryQuery,
|
|
17
|
+
getCategoryAvailableSortMethodsQuery,
|
|
18
|
+
getStoreConfigQuery
|
|
19
|
+
} = operations;
|
|
20
|
+
|
|
21
|
+
const placeholderItems = Array.from({ length: pageSize }).fill(null);
|
|
22
|
+
|
|
23
|
+
// console.log(getStoreConfigQuery)
|
|
24
|
+
|
|
25
|
+
const { data: storeConfigData } = useQuery(getStoreConfigQuery, {
|
|
26
|
+
fetchPolicy: 'cache-and-network'
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
// return '';
|
|
30
|
+
|
|
31
|
+
const virtualCategoryFilters = useMemo(() => {
|
|
32
|
+
if (storeConfigData) {
|
|
33
|
+
const data = storeConfigData.storeConfig.custommarketplace_plp_filters_virtualcategory;
|
|
34
|
+
return data ? data.split(',') : [];
|
|
35
|
+
}
|
|
36
|
+
}, [storeConfigData]);
|
|
37
|
+
|
|
38
|
+
const [getFilters, { data: filterData }] = useLazyQuery(
|
|
39
|
+
getProductFiltersByCategoryQuery,
|
|
40
|
+
{
|
|
41
|
+
fetchPolicy: 'cache-and-network',
|
|
42
|
+
nextFetchPolicy: 'cache-first'
|
|
43
|
+
}
|
|
44
|
+
);
|
|
45
|
+
|
|
46
|
+
const [getSortMethods, { data: sortData }] = useLazyQuery(
|
|
47
|
+
getCategoryAvailableSortMethodsQuery,
|
|
48
|
+
{
|
|
49
|
+
fetchPolicy: 'cache-and-network',
|
|
50
|
+
nextFetchPolicy: 'cache-first'
|
|
51
|
+
}
|
|
52
|
+
);
|
|
53
|
+
|
|
54
|
+
const { data: categoryData, loading: categoryLoading } = useQuery(
|
|
55
|
+
getCategoryContentQuery,
|
|
56
|
+
{
|
|
57
|
+
fetchPolicy: 'cache-and-network',
|
|
58
|
+
nextFetchPolicy: 'cache-first',
|
|
59
|
+
skip: !sellerId,
|
|
60
|
+
variables: {
|
|
61
|
+
id: sellerId
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
);
|
|
65
|
+
|
|
66
|
+
const [, { dispatch }] = useEventingContext();
|
|
67
|
+
|
|
68
|
+
useEffect(() => {
|
|
69
|
+
if (sellerId) {
|
|
70
|
+
getFilters({
|
|
71
|
+
variables: {
|
|
72
|
+
categoryIdFilter: {
|
|
73
|
+
eq: sellerId
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
});
|
|
77
|
+
}
|
|
78
|
+
}, [sellerId, getFilters]);
|
|
79
|
+
|
|
80
|
+
useEffect(() => {
|
|
81
|
+
if (sellerId) {
|
|
82
|
+
getSortMethods({
|
|
83
|
+
variables: {
|
|
84
|
+
categoryIdFilter: {
|
|
85
|
+
in: sellerId
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
});
|
|
89
|
+
}
|
|
90
|
+
}, [sellerId, getSortMethods]);
|
|
91
|
+
|
|
92
|
+
console.log('data')
|
|
93
|
+
console.log(data)
|
|
94
|
+
|
|
95
|
+
const rawFilters = filterData ? filterData.products.aggregations : null;
|
|
96
|
+
const items = data ? data.items : placeholderItems;
|
|
97
|
+
const category = null;
|
|
98
|
+
const children = null;
|
|
99
|
+
// const category =
|
|
100
|
+
// categoryData && categoryData.categories.items.length
|
|
101
|
+
// ? categoryData.categories.items[0]
|
|
102
|
+
// : null;
|
|
103
|
+
// const children =
|
|
104
|
+
// categoryData && categoryData.categories.items.length
|
|
105
|
+
// ? categoryData.categories.items[0].children
|
|
106
|
+
// : null;
|
|
107
|
+
|
|
108
|
+
const filters = [];
|
|
109
|
+
|
|
110
|
+
rawFilters && rawFilters.map((filter, index) => {
|
|
111
|
+
|
|
112
|
+
const filterOptions = [];
|
|
113
|
+
let label = filter.label;
|
|
114
|
+
if (filter.attribute_code == "category_uid") {
|
|
115
|
+
children && children.map((category, index) => {
|
|
116
|
+
filterOptions.push({
|
|
117
|
+
'label': category.name,
|
|
118
|
+
'value': category.uid,
|
|
119
|
+
'path': category.url_path
|
|
120
|
+
});
|
|
121
|
+
});
|
|
122
|
+
|
|
123
|
+
label = category ? category.name : label;
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
const newFilter = {
|
|
127
|
+
attribute_code: filter.attribute_code,
|
|
128
|
+
count: filter.count,
|
|
129
|
+
label: label,
|
|
130
|
+
position: filter.position,
|
|
131
|
+
options: filterOptions.length ? filterOptions : filter.options
|
|
132
|
+
};
|
|
133
|
+
|
|
134
|
+
filters.push(newFilter);
|
|
135
|
+
});
|
|
136
|
+
|
|
137
|
+
const attributesBlock = null;
|
|
138
|
+
const parent = null;
|
|
139
|
+
const categoryName = null;
|
|
140
|
+
const categoryDescription = null;
|
|
141
|
+
|
|
142
|
+
// const attributesBlock = categoryData && categoryData.categories.items.length
|
|
143
|
+
// ? categoryData.categories.items[0].attributes_block
|
|
144
|
+
// : null;
|
|
145
|
+
// const parent =
|
|
146
|
+
// categoryData && categoryData.categories.items.length
|
|
147
|
+
// ? categoryData.categories.items[0].parent
|
|
148
|
+
// : null;
|
|
149
|
+
const totalPagesFromData = data
|
|
150
|
+
? data.page_info.total_pages
|
|
151
|
+
: null;
|
|
152
|
+
const totalCount = data ? data.total_count : null;
|
|
153
|
+
|
|
154
|
+
// const categoryName =
|
|
155
|
+
// categoryData && categoryData.categories.items.length
|
|
156
|
+
// ? categoryData.categories.items[0].name
|
|
157
|
+
// : null;
|
|
158
|
+
// const categoryDescription =
|
|
159
|
+
// categoryData && categoryData.categories.items.length
|
|
160
|
+
// ? categoryData.categories.items[0].description
|
|
161
|
+
// : null;
|
|
162
|
+
const availableSortMethods = sortData
|
|
163
|
+
? sortData.products.sort_fields.options
|
|
164
|
+
: null;
|
|
165
|
+
|
|
166
|
+
// useEffect(() => {
|
|
167
|
+
// if (!categoryLoading && categoryData.categories.items.length > 0) {
|
|
168
|
+
// dispatch({
|
|
169
|
+
// type: 'CATEGORY_PAGE_VIEW',
|
|
170
|
+
// payload: {
|
|
171
|
+
// id: categoryData.categories.items[0].uid,
|
|
172
|
+
// name: categoryData.categories.items[0].name,
|
|
173
|
+
// url_key: categoryData.categories.items[0].url_key,
|
|
174
|
+
// url_path: categoryData.categories.items[0].url_path
|
|
175
|
+
// }
|
|
176
|
+
// });
|
|
177
|
+
// }
|
|
178
|
+
// }, [categoryData, dispatch, categoryLoading]);
|
|
179
|
+
|
|
180
|
+
return {
|
|
181
|
+
availableSortMethods,
|
|
182
|
+
categoryName,
|
|
183
|
+
categoryDescription,
|
|
184
|
+
filters,
|
|
185
|
+
items,
|
|
186
|
+
totalCount,
|
|
187
|
+
totalPagesFromData,
|
|
188
|
+
children,
|
|
189
|
+
parent,
|
|
190
|
+
attributesBlock,
|
|
191
|
+
category,
|
|
192
|
+
virtualCategoryFilters
|
|
193
|
+
};
|
|
194
|
+
};
|
|
@@ -0,0 +1,264 @@
|
|
|
1
|
+
import React, { useEffect, useMemo, useRef } from 'react';
|
|
2
|
+
import { useLocation } from 'react-router-dom';
|
|
3
|
+
import { useLazyQuery, useQuery } from '@apollo/client';
|
|
4
|
+
|
|
5
|
+
import mergeOperations from '@magento/peregrine/lib/util/shallowMerge';
|
|
6
|
+
import { useAppContext } from '@magento/peregrine/lib/context/app';
|
|
7
|
+
import { usePagination } from '@magento/peregrine/lib/hooks/usePagination';
|
|
8
|
+
import { useScrollTopOnChange } from '@magento/peregrine/lib/hooks/useScrollTopOnChange';
|
|
9
|
+
import { useSort } from '@magento/peregrine/lib/hooks/useSort';
|
|
10
|
+
import {
|
|
11
|
+
getFiltersFromSearch,
|
|
12
|
+
getFilterInput
|
|
13
|
+
} from '@magento/peregrine/lib/talons/FilterModal/helpers';
|
|
14
|
+
|
|
15
|
+
import DEFAULT_OPERATIONS from './sellerProducts.gql';
|
|
16
|
+
|
|
17
|
+
export const useSellerProducts = props => {
|
|
18
|
+
const {
|
|
19
|
+
sellerId,
|
|
20
|
+
queries: { getPageSize }
|
|
21
|
+
} = props;
|
|
22
|
+
|
|
23
|
+
const operations = mergeOperations(DEFAULT_OPERATIONS, props.operations);
|
|
24
|
+
const { getProductsQuery, getFilterInputsQuery, getCategoryDataQuery } = operations;
|
|
25
|
+
|
|
26
|
+
const { data: pageSizeData } = useQuery(getPageSize, {
|
|
27
|
+
fetchPolicy: 'cache-and-network',
|
|
28
|
+
nextFetchPolicy: 'cache-first'
|
|
29
|
+
});
|
|
30
|
+
const pageSize = pageSizeData && pageSizeData.storeConfig.grid_per_page;
|
|
31
|
+
|
|
32
|
+
const [paginationValues, paginationApi] = usePagination();
|
|
33
|
+
const { currentPage, totalPages } = paginationValues;
|
|
34
|
+
const { setCurrentPage, setTotalPages } = paginationApi;
|
|
35
|
+
|
|
36
|
+
const sortProps = useSort({ sortFromSearch: false });
|
|
37
|
+
const [currentSort] = sortProps;
|
|
38
|
+
|
|
39
|
+
// const { pathname } = useLocation();
|
|
40
|
+
|
|
41
|
+
// const pathnameArr = pathname.split('/');
|
|
42
|
+
// const categoryUrlKey = pathnameArr[pathnameArr.length - 1].replace('.html','');
|
|
43
|
+
|
|
44
|
+
// return <><span>useSellerProducts</span></>;
|
|
45
|
+
|
|
46
|
+
// Keep track of the sort criteria so we can tell when they change.
|
|
47
|
+
const previousSort = useRef(currentSort);
|
|
48
|
+
|
|
49
|
+
const pageControl = {
|
|
50
|
+
currentPage,
|
|
51
|
+
setPage: setCurrentPage,
|
|
52
|
+
totalPages
|
|
53
|
+
};
|
|
54
|
+
|
|
55
|
+
const [
|
|
56
|
+
,
|
|
57
|
+
{
|
|
58
|
+
actions: { setPageLoading }
|
|
59
|
+
}
|
|
60
|
+
] = useAppContext();
|
|
61
|
+
|
|
62
|
+
const [runQuery, queryResponse] = useLazyQuery(getProductsQuery, {
|
|
63
|
+
fetchPolicy: 'cache-and-network',
|
|
64
|
+
nextFetchPolicy: 'cache-first'
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
const [runGetCategoriesQuery, queryGetCategoriesResponse] = useLazyQuery(getCategoryDataQuery, {
|
|
68
|
+
fetchPolicy: 'cache-and-network',
|
|
69
|
+
nextFetchPolicy: 'cache-first'
|
|
70
|
+
});
|
|
71
|
+
|
|
72
|
+
const {
|
|
73
|
+
called: productCalled,
|
|
74
|
+
loading: productLoading,
|
|
75
|
+
error,
|
|
76
|
+
data
|
|
77
|
+
} = queryResponse;
|
|
78
|
+
|
|
79
|
+
console.log('===data===')
|
|
80
|
+
console.log(data)
|
|
81
|
+
console.log('======')
|
|
82
|
+
|
|
83
|
+
const {
|
|
84
|
+
called: categoryCalled,
|
|
85
|
+
loading: categoryLoading,
|
|
86
|
+
error: categoryError,
|
|
87
|
+
data: categoryData
|
|
88
|
+
} = queryGetCategoriesResponse;
|
|
89
|
+
|
|
90
|
+
const { search } = useLocation();
|
|
91
|
+
|
|
92
|
+
const isBackgroundLoading = !!data && productLoading;
|
|
93
|
+
|
|
94
|
+
// Update the page indicator if the GraphQL query is in flight.
|
|
95
|
+
useEffect(() => {
|
|
96
|
+
setPageLoading(isBackgroundLoading);
|
|
97
|
+
}, [isBackgroundLoading, setPageLoading]);
|
|
98
|
+
|
|
99
|
+
// Keep track of the search terms so we can tell when they change.
|
|
100
|
+
const previousSearch = useRef(search);
|
|
101
|
+
|
|
102
|
+
// Get "allowed" filters by intersection of schema and aggregations
|
|
103
|
+
const {
|
|
104
|
+
called: introspectionCalled,
|
|
105
|
+
data: introspectionData,
|
|
106
|
+
loading: introspectionLoading
|
|
107
|
+
} = useQuery(getFilterInputsQuery);
|
|
108
|
+
|
|
109
|
+
// const {
|
|
110
|
+
// data: categoryData
|
|
111
|
+
// } = useQuery(getCategoryDataQuery);
|
|
112
|
+
|
|
113
|
+
useEffect(() => {
|
|
114
|
+
// const filters = getFiltersFromSearch(search);
|
|
115
|
+
|
|
116
|
+
// Construct the filter arg object.
|
|
117
|
+
const newFilters = {};
|
|
118
|
+
newFilters['url_key'] = { eq: "lego" };
|
|
119
|
+
|
|
120
|
+
runGetCategoriesQuery({
|
|
121
|
+
variables: {
|
|
122
|
+
currentPage: Number(1),
|
|
123
|
+
filters: newFilters,
|
|
124
|
+
pageSize: Number(1)
|
|
125
|
+
}
|
|
126
|
+
});
|
|
127
|
+
}, [
|
|
128
|
+
runGetCategoriesQuery,
|
|
129
|
+
search
|
|
130
|
+
]);
|
|
131
|
+
|
|
132
|
+
const categoryId = useMemo(() => {
|
|
133
|
+
let uid = null;
|
|
134
|
+
if (categoryData) {
|
|
135
|
+
uid = categoryData.categories.items[0].id;
|
|
136
|
+
}
|
|
137
|
+
return uid;
|
|
138
|
+
}, [categoryData]);
|
|
139
|
+
|
|
140
|
+
|
|
141
|
+
|
|
142
|
+
// Create a type map we can reference later to ensure we pass valid args
|
|
143
|
+
// to the graphql query.
|
|
144
|
+
// For example: { category_id: 'FilterEqualTypeInput', price: 'FilterRangeTypeInput' }
|
|
145
|
+
const filterTypeMap = useMemo(() => {
|
|
146
|
+
const typeMap = new Map();
|
|
147
|
+
if (introspectionData) {
|
|
148
|
+
introspectionData.__type.inputFields.forEach(({ name, type }) => {
|
|
149
|
+
typeMap.set(name, type.name);
|
|
150
|
+
});
|
|
151
|
+
}
|
|
152
|
+
return typeMap;
|
|
153
|
+
}, [introspectionData]);
|
|
154
|
+
|
|
155
|
+
// Run the category query immediately and whenever its variable values change.
|
|
156
|
+
useEffect(() => {
|
|
157
|
+
console.log('=categoryData=')
|
|
158
|
+
console.log(categoryData)
|
|
159
|
+
if (!categoryData) {
|
|
160
|
+
return;
|
|
161
|
+
}
|
|
162
|
+
// Wait until we have the type map to fetch product data.
|
|
163
|
+
if (!filterTypeMap.size || !pageSize) {
|
|
164
|
+
return;
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
const filters = getFiltersFromSearch(search);
|
|
168
|
+
|
|
169
|
+
// Construct the filter arg object.
|
|
170
|
+
const newFilters = {};
|
|
171
|
+
filters.forEach((values, key) => {
|
|
172
|
+
newFilters[key] = getFilterInput(values, filterTypeMap.get(key));
|
|
173
|
+
});
|
|
174
|
+
|
|
175
|
+
// Use the category uid for the current category page regardless of the
|
|
176
|
+
// applied filters. Follow-up in PWA-404.
|
|
177
|
+
if (categoryId) {
|
|
178
|
+
newFilters['category_id'] = { eq: categoryId };
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
runQuery({
|
|
182
|
+
variables: {
|
|
183
|
+
currentPage: Number(currentPage),
|
|
184
|
+
sellerId: sellerId,
|
|
185
|
+
filter: newFilters,
|
|
186
|
+
pageSize: Number(pageSize),
|
|
187
|
+
sort: { [currentSort.sortAttribute]: currentSort.sortDirection }
|
|
188
|
+
}
|
|
189
|
+
});
|
|
190
|
+
}, [
|
|
191
|
+
currentPage,
|
|
192
|
+
currentSort,
|
|
193
|
+
filterTypeMap,
|
|
194
|
+
categoryId,
|
|
195
|
+
pageSize,
|
|
196
|
+
runQuery,
|
|
197
|
+
search,
|
|
198
|
+
categoryData
|
|
199
|
+
]);
|
|
200
|
+
|
|
201
|
+
const totalPagesFromData = data
|
|
202
|
+
? data.productsBySellerId.page_info.total_pages
|
|
203
|
+
: null;
|
|
204
|
+
|
|
205
|
+
useEffect(() => {
|
|
206
|
+
setTotalPages(totalPagesFromData);
|
|
207
|
+
return () => {
|
|
208
|
+
setTotalPages(null);
|
|
209
|
+
};
|
|
210
|
+
}, [setTotalPages, totalPagesFromData]);
|
|
211
|
+
|
|
212
|
+
// If we get an error after loading we should try to reset to page 1.
|
|
213
|
+
// If we continue to have errors after that, render an error message.
|
|
214
|
+
useEffect(() => {
|
|
215
|
+
if (error && !productLoading && !data && currentPage !== 1) {
|
|
216
|
+
setCurrentPage(1);
|
|
217
|
+
}
|
|
218
|
+
}, [currentPage, error, productLoading, setCurrentPage, data]);
|
|
219
|
+
|
|
220
|
+
// Reset the current page back to one (1) when the search string, filters
|
|
221
|
+
// or sort criteria change.
|
|
222
|
+
useEffect(() => {
|
|
223
|
+
// We don't want to compare page value.
|
|
224
|
+
const prevSearch = new URLSearchParams(previousSearch.current);
|
|
225
|
+
const nextSearch = new URLSearchParams(search);
|
|
226
|
+
prevSearch.delete('page');
|
|
227
|
+
nextSearch.delete('page');
|
|
228
|
+
|
|
229
|
+
if (
|
|
230
|
+
prevSearch.toString() !== nextSearch.toString() ||
|
|
231
|
+
previousSort.current.sortAttribute.toString() !==
|
|
232
|
+
currentSort.sortAttribute.toString() ||
|
|
233
|
+
previousSort.current.sortDirection.toString() !==
|
|
234
|
+
currentSort.sortDirection.toString()
|
|
235
|
+
) {
|
|
236
|
+
// The search term changed.
|
|
237
|
+
setCurrentPage(1, true);
|
|
238
|
+
// And update the ref.
|
|
239
|
+
previousSearch.current = search;
|
|
240
|
+
previousSort.current = currentSort;
|
|
241
|
+
}
|
|
242
|
+
}, [currentSort, previousSearch, search, setCurrentPage]);
|
|
243
|
+
|
|
244
|
+
const productData = productLoading && !data ? null : data;
|
|
245
|
+
const categoryNotFound = false;
|
|
246
|
+
|
|
247
|
+
// When only productLoading is involved, noProductsFound component flashes for a moment
|
|
248
|
+
const loading =
|
|
249
|
+
(introspectionCalled && !categoryCalled) ||
|
|
250
|
+
(productLoading && !data) ||
|
|
251
|
+
introspectionLoading;
|
|
252
|
+
|
|
253
|
+
useScrollTopOnChange(currentPage);
|
|
254
|
+
|
|
255
|
+
return {
|
|
256
|
+
error,
|
|
257
|
+
productData,
|
|
258
|
+
loading,
|
|
259
|
+
pageControl,
|
|
260
|
+
sortProps,
|
|
261
|
+
pageSize,
|
|
262
|
+
categoryNotFound
|
|
263
|
+
};
|
|
264
|
+
};
|