@riosst100/pwa-marketplace 1.6.0 → 1.6.2
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 +3 -2
- package/src/components/AlphaFilter/alphaFilter.js +86 -0
- package/src/components/AlphaFilter/alphaFilter.module.css +38 -0
- package/src/components/AlphaFilter/alphaFilter.shimmer.js +50 -0
- package/src/components/AlphaFilter/index.js +2 -0
- package/src/components/CollectibleGameSets/collectibleGameSets.js +1 -1
- package/src/components/CrossSeller/crossSellerBuy.js +19 -0
- package/src/components/CrossSeller/index.js +15 -0
- package/src/components/CrossSeller/item.js +79 -0
- package/src/components/CrossSeller/logo_seller.png +0 -0
- package/src/components/CrossSeller/starIcon.js +14 -0
- package/src/components/CrossSeller/verifyIcon.js +12 -0
- package/src/components/CustomSortBy/productSort.module.css +65 -0
- package/src/components/CustomSortBy/productSort.shimmer.js +28 -0
- package/src/components/CustomSortBy/productSort.shimmer.module.css +10 -0
- package/src/components/CustomSubCategory/subCategory.js +48 -0
- package/src/components/CustomSubCategory/subCategory.module.css +22 -0
- package/src/components/FilterTop/CurrentTopFilters/currentTopFilter.js +47 -0
- package/src/components/FilterTop/CurrentTopFilters/currentTopFilter.module.css +22 -0
- package/src/components/FilterTop/CurrentTopFilters/currentTopFilters.js +50 -0
- package/src/components/FilterTop/CurrentTopFilters/currentTopFilters.module.css +21 -0
- package/src/components/FilterTop/CurrentTopFilters/index.js +1 -0
- package/src/components/FilterTop/CustomFilters/customFilters.js +68 -30
- package/src/components/FilterTop/FilterBlockList/filterBlockList.js +50 -0
- package/src/components/FilterTop/FilterBlockList/filterBlockList.module.css +8 -0
- package/src/components/FilterTop/FilterBlockList/filterTopItem.js +40 -0
- package/src/components/FilterTop/FilterBlockList/filterTopItem.module.css +14 -0
- package/src/components/FilterTop/FilterBlockList/filterTopItemGroup.js +91 -0
- package/src/components/FilterTop/FilterBlockList/filterTopItemGroup.module.css +23 -0
- package/src/components/FilterTop/FilterBlockList/index.js +1 -0
- package/src/components/FilterTop/filterTop.js +131 -13
- package/src/components/FilterTop/filterTop.module.css +23 -58
- package/src/components/FilterTop/filterTop.shimmer.js +24 -24
- package/src/components/FilterTop/filterTopBlock.js +54 -0
- package/src/components/FilterTop/index.js +2 -2
- package/src/components/FilterTopBackup/CustomFilters/customFilter.js +83 -0
- package/src/components/FilterTopBackup/CustomFilters/customFilter.module.css +22 -0
- package/src/components/FilterTopBackup/CustomFilters/customFilters.js +132 -0
- package/src/components/FilterTopBackup/CustomFilters/customFilters.module.css +23 -0
- package/src/components/FilterTopBackup/CustomFilters/index.js +1 -0
- package/src/components/FilterTopBackup/filterTop.js +14 -0
- package/src/components/FilterTopBackup/filterTop.module.css +23 -0
- package/src/components/FilterTopBackup/filterTop.shimmer.js +24 -0
- package/src/components/FilterTopBackup/index.js +2 -0
- package/src/components/RelatedProduct/index.js +16 -0
- package/src/components/RelatedProduct/relatedProduct.js +112 -0
- package/src/components/RelatedProduct/sample.json +154 -0
- package/src/components/SubCategory/subCategory.js +2 -2
- package/src/overwrites/venia-ui/lib/RootComponents/Category/NoProductsFound/noProductsFound.js +0 -13
- package/src/overwrites/venia-ui/lib/RootComponents/Category/categoryContent.js +30 -7
- package/src/overwrites/venia-ui/lib/components/Breadcrumbs/breadcrumbs.js +3 -2
- package/src/overwrites/venia-ui/lib/components/Gallery/gallery.js +7 -2
- package/src/overwrites/venia-ui/lib/components/Gallery/item.js +3 -1
- package/src/overwrites/venia-ui/lib/components/Newsletter/newsletter.js +2 -2
- package/src/overwrites/venia-ui/lib/components/ProductFullDetail/CustomAttributes/customAttributes.js +1 -1
- package/src/overwrites/venia-ui/lib/components/ProductFullDetail/productFullDetail.js +13 -1
- package/src/overwrites/venia-ui/lib/components/QuantityStepper/quantityStepper.js +2 -2
- package/src/overwrites/venia-ui/lib/components/SearchBar/searchBar.js +1 -1
- package/src/talons/CustomFilters/useCustomFilters.js +163 -5
- package/src/talons/FilterTop/customFilters.gql.js +45 -0
- package/src/talons/FilterTop/filterTop.gql.js +45 -0
- package/src/talons/FilterTop/index.js +1 -0
- package/src/talons/FilterTop/useFilterTop.js +330 -0
|
@@ -16,7 +16,7 @@ const SubCategory = props => {
|
|
|
16
16
|
normalizedData
|
|
17
17
|
} = talonProps;
|
|
18
18
|
|
|
19
|
-
const maxSubCategory =
|
|
19
|
+
const maxSubCategory = 7;
|
|
20
20
|
|
|
21
21
|
const subCategory = [];
|
|
22
22
|
|
|
@@ -38,7 +38,7 @@ const SubCategory = props => {
|
|
|
38
38
|
<Link
|
|
39
39
|
to={resourceUrl('/')}
|
|
40
40
|
>
|
|
41
|
-
<li className={classes.item}>{"
|
|
41
|
+
<li className={classes.item}>{"More " + parent[0].name}</li>
|
|
42
42
|
</Link>
|
|
43
43
|
)
|
|
44
44
|
}
|
package/src/overwrites/venia-ui/lib/RootComponents/Category/NoProductsFound/noProductsFound.js
CHANGED
|
@@ -62,16 +62,3 @@ const NoProductsFound = props => {
|
|
|
62
62
|
};
|
|
63
63
|
|
|
64
64
|
export default NoProductsFound;
|
|
65
|
-
|
|
66
|
-
NoProductsFound.propTypes = {
|
|
67
|
-
categoryId: number,
|
|
68
|
-
classes: shape({
|
|
69
|
-
root: string,
|
|
70
|
-
title: string,
|
|
71
|
-
list: string,
|
|
72
|
-
categories: string,
|
|
73
|
-
listItem: string,
|
|
74
|
-
image: string,
|
|
75
|
-
imageContainer: string
|
|
76
|
-
})
|
|
77
|
-
};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import React, { Fragment, Suspense, useMemo, useRef } from 'react';
|
|
1
|
+
import React, { Fragment, Suspense, useMemo, useRef, useState } from 'react';
|
|
2
2
|
import { FormattedMessage } from 'react-intl';
|
|
3
3
|
import { array, number, shape, string } from 'prop-types';
|
|
4
4
|
|
|
@@ -32,6 +32,7 @@ import CollectibleGameSets from '@riosst100/pwa-marketplace/src/components/Colle
|
|
|
32
32
|
import { useLocation } from 'react-router-dom';
|
|
33
33
|
import { getFiltersFromSearch } from '@magento/peregrine/lib/talons/FilterModal/helpers';
|
|
34
34
|
import CustomSubCategory from '@riosst100/pwa-marketplace/src/components/SubCategory/customSubCategory';
|
|
35
|
+
import AlphaFilter from '@riosst100/pwa-marketplace/src/components/AlphaFilter';
|
|
35
36
|
|
|
36
37
|
const FilterModal = React.lazy(() => import('@magento/venia-ui/lib/components/FilterModal'));
|
|
37
38
|
const FilterSidebar = React.lazy(() =>
|
|
@@ -73,6 +74,26 @@ const CategoryContent = props => {
|
|
|
73
74
|
virtualCategoryFilters
|
|
74
75
|
} = talonProps;
|
|
75
76
|
|
|
77
|
+
const [activeLetter, setActiveLetter] = useState('all')
|
|
78
|
+
|
|
79
|
+
const handleActiveLetter = (val) => {
|
|
80
|
+
setActiveLetter(val);
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
const galleryItems = [];
|
|
84
|
+
|
|
85
|
+
useMemo(() => {
|
|
86
|
+
items && items.map((item, index) => {
|
|
87
|
+
if (item) {
|
|
88
|
+
const firstLetter = item.name.charAt(0).toUpperCase();
|
|
89
|
+
if (activeLetter == "all" || activeLetter != "all" && firstLetter == activeLetter) {
|
|
90
|
+
return galleryItems.push(item);
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
}),
|
|
94
|
+
[items, activeLetter]
|
|
95
|
+
});
|
|
96
|
+
|
|
76
97
|
const sidebarRef = useRef(null);
|
|
77
98
|
const classes = useStyle(defaultClasses, props.classes);
|
|
78
99
|
const shouldRenderSidebarContent = useIsInViewport({
|
|
@@ -127,11 +148,11 @@ const CategoryContent = props => {
|
|
|
127
148
|
) : null;
|
|
128
149
|
|
|
129
150
|
const categoryResultsHeading =
|
|
130
|
-
|
|
151
|
+
galleryItems.length > 0 ? (
|
|
131
152
|
<FormattedMessage
|
|
132
153
|
id={'categoryContent.resultCount'}
|
|
133
154
|
values={{
|
|
134
|
-
count:
|
|
155
|
+
count: galleryItems.length
|
|
135
156
|
}}
|
|
136
157
|
defaultMessage={'{count} Results'}
|
|
137
158
|
/>
|
|
@@ -149,9 +170,9 @@ const CategoryContent = props => {
|
|
|
149
170
|
}
|
|
150
171
|
|
|
151
172
|
const gallery = totalPagesFromData ? (
|
|
152
|
-
<Gallery items={
|
|
173
|
+
<Gallery items={galleryItems} activeLetter={activeLetter} />
|
|
153
174
|
) : (
|
|
154
|
-
<GalleryShimmer items={
|
|
175
|
+
<GalleryShimmer items={galleryItems} />
|
|
155
176
|
);
|
|
156
177
|
|
|
157
178
|
const pagination = totalPagesFromData ? (
|
|
@@ -171,7 +192,8 @@ const CategoryContent = props => {
|
|
|
171
192
|
isLoading,
|
|
172
193
|
items,
|
|
173
194
|
pageControl,
|
|
174
|
-
totalPagesFromData
|
|
195
|
+
totalPagesFromData,
|
|
196
|
+
activeLetter
|
|
175
197
|
]);
|
|
176
198
|
|
|
177
199
|
const categoryTitle = categoryName ? categoryName : <Shimmer width={5} />;
|
|
@@ -219,13 +241,14 @@ const CategoryContent = props => {
|
|
|
219
241
|
</div>
|
|
220
242
|
{/* {activeFilters.size <= 0 && category && category.custom_landing_page ? ( */}
|
|
221
243
|
<>
|
|
244
|
+
{currentFilter && <AlphaFilter items={items} handleActiveLetter={handleActiveLetter} activeLetter={activeLetter} />}
|
|
222
245
|
<SubCategory parent={parent} children={children} />
|
|
223
246
|
{!currentFilter && <CustomSubCategory customSubCategory={category ? category.custom_subcategory : null} />}
|
|
224
247
|
</>
|
|
225
248
|
{/* ) : ( */}
|
|
226
249
|
<>
|
|
227
250
|
{/* <SubCategory filters={filters} children={children} /> */}
|
|
228
|
-
<FilterTop filters={filters} category={category} />
|
|
251
|
+
<FilterTop filters={filters} category={category} children={children} allowedFilters={category ? category.allowed_filters : []} />
|
|
229
252
|
{/* <AttributesBlock category={category} attributesBlock={attributesBlock} /> */}
|
|
230
253
|
{/* <section className='category_brand-slider my-5'>
|
|
231
254
|
<BrandSlider />
|
|
@@ -76,6 +76,7 @@ const Breadcrumbs = props => {
|
|
|
76
76
|
currentProduct ? (
|
|
77
77
|
filterBreadcrumbsElement.push(
|
|
78
78
|
<Link
|
|
79
|
+
key={index}
|
|
79
80
|
className={classes.link}
|
|
80
81
|
to={resourceUrl(currentCategoryPath)}
|
|
81
82
|
onClick={handleClick}
|
|
@@ -85,10 +86,10 @@ const Breadcrumbs = props => {
|
|
|
85
86
|
)
|
|
86
87
|
) : (
|
|
87
88
|
filterBreadcrumbsElement.push(
|
|
88
|
-
|
|
89
|
+
<span key={index}>
|
|
89
90
|
<span className={classes.divider}>{DELIMITER}</span>
|
|
90
91
|
<span className={cn(classes.currentCategory, 'text-blue-700 font-medium')}>{filter.label}</span>
|
|
91
|
-
|
|
92
|
+
</span>
|
|
92
93
|
)
|
|
93
94
|
);
|
|
94
95
|
});
|
|
@@ -14,7 +14,7 @@ import { useGallery } from '@magento/peregrine/lib/talons/Gallery/useGallery';
|
|
|
14
14
|
* @params {Array} props.items an array of items to render
|
|
15
15
|
*/
|
|
16
16
|
const Gallery = props => {
|
|
17
|
-
const { items } = props;
|
|
17
|
+
const { items, activeLetter } = props;
|
|
18
18
|
const classes = useStyle(defaultClasses, props.classes);
|
|
19
19
|
const talonProps = useGallery();
|
|
20
20
|
const { storeConfig } = talonProps;
|
|
@@ -25,6 +25,10 @@ const Gallery = props => {
|
|
|
25
25
|
if (item === null) {
|
|
26
26
|
return <GalleryItemShimmer key={index} />;
|
|
27
27
|
}
|
|
28
|
+
|
|
29
|
+
const firstLetter = item.name.charAt(0).toUpperCase();
|
|
30
|
+
|
|
31
|
+
if (activeLetter == "all" || activeLetter != "all" && firstLetter == activeLetter) {
|
|
28
32
|
return (
|
|
29
33
|
<GalleryItem
|
|
30
34
|
key={item.id}
|
|
@@ -32,8 +36,9 @@ const Gallery = props => {
|
|
|
32
36
|
storeConfig={storeConfig}
|
|
33
37
|
/>
|
|
34
38
|
);
|
|
39
|
+
}
|
|
35
40
|
}),
|
|
36
|
-
[items, storeConfig]
|
|
41
|
+
[items, storeConfig, activeLetter]
|
|
37
42
|
);
|
|
38
43
|
|
|
39
44
|
return (
|
|
@@ -37,7 +37,8 @@ const GalleryItem = props => {
|
|
|
37
37
|
item,
|
|
38
38
|
itemRef,
|
|
39
39
|
wishlistButtonProps,
|
|
40
|
-
isSupportedProductType
|
|
40
|
+
isSupportedProductType,
|
|
41
|
+
rootClassName
|
|
41
42
|
} = useGalleryItem(props);
|
|
42
43
|
|
|
43
44
|
const seller = item.seller ? item.seller.name : '';
|
|
@@ -92,6 +93,7 @@ const GalleryItem = props => {
|
|
|
92
93
|
aria-label={name}
|
|
93
94
|
onClick={handleLinkClick}
|
|
94
95
|
to={productLink}
|
|
96
|
+
className={rootClassName}
|
|
95
97
|
>
|
|
96
98
|
<div data-cy="GalleryItem-root" className={cn(classes.root, 'border border-gray-100 rounded-lg hover_shadow-type-1 ')} ref={itemRef}>
|
|
97
99
|
<div className={cn('item-product')}>
|
|
@@ -121,8 +121,8 @@ const Newsletter = props => {
|
|
|
121
121
|
onClick={clearErrors}
|
|
122
122
|
>
|
|
123
123
|
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
124
|
-
<path d="M20.5 13.01L15.49 7.98999" stroke="#292D32"
|
|
125
|
-
<path d="M3.5 13.01H20.5" stroke="#292D32"
|
|
124
|
+
<path d="M20.5 13.01L15.49 7.98999" stroke="#292D32" strokeWidth="1.5" strokeMiterlimit="10" strokeLinecap="round" strokeLinejoin="round" />
|
|
125
|
+
<path d="M3.5 13.01H20.5" stroke="#292D32" strokeWidth="1.5" strokeMiterlimit="10" strokeLinecap="round" strokeLinejoin="round" />
|
|
126
126
|
</svg>
|
|
127
127
|
</LinkButton>
|
|
128
128
|
<div className={classes.buttonsContainer}>
|
|
@@ -24,7 +24,7 @@ const CustomAttributes = props => {
|
|
|
24
24
|
const attributeContent = (
|
|
25
25
|
<li
|
|
26
26
|
key={currentAttribute.attribute_metadata.uid}
|
|
27
|
-
className={cn(classes.listItem, '!text-[14px]')}
|
|
27
|
+
className={cn(classes.listItem, '!text-[14px] py-1')}
|
|
28
28
|
>
|
|
29
29
|
<AttributeType
|
|
30
30
|
showLabels={showLabels}
|
|
@@ -32,6 +32,8 @@ const Options = React.lazy(() => import('@magento/venia-ui/lib/components/Produc
|
|
|
32
32
|
import Share from '@riosst100/pwa-marketplace/src/components/SocialMediaShare';
|
|
33
33
|
import PreorderDetail from './components/preOrderDetail';
|
|
34
34
|
import AuctionDetail from './components/auctionDetail';
|
|
35
|
+
import CrossSeller from '@riosst100/pwa-marketplace/src/components/CrossSeller';
|
|
36
|
+
import RelatedProduct from '@riosst100/pwa-marketplace/src/components/RelatedProduct';
|
|
35
37
|
|
|
36
38
|
// Correlate a GQL error message to a field. GQL could return a longer error
|
|
37
39
|
// string but it may contain contextual info such as product id. We can use
|
|
@@ -658,7 +660,7 @@ const ProductFullDetail = props => {
|
|
|
658
660
|
<Divider />
|
|
659
661
|
</section>
|
|
660
662
|
</Form>
|
|
661
|
-
<section className='section_product-details-container
|
|
663
|
+
<section className='section_product-details-container mt-8 mb-10'>
|
|
662
664
|
<Tabs
|
|
663
665
|
data={dataTabs}
|
|
664
666
|
tabContentWrapperClassName='!p-0'
|
|
@@ -666,6 +668,16 @@ const ProductFullDetail = props => {
|
|
|
666
668
|
tabWrapperClassName='xl_gap-x-[60px] justify-center'
|
|
667
669
|
/>
|
|
668
670
|
</section>
|
|
671
|
+
|
|
672
|
+
<section className='pt-8 lg_pt-10'>
|
|
673
|
+
<RelatedProduct />
|
|
674
|
+
</section>
|
|
675
|
+
|
|
676
|
+
<section className='w-[calc(100vw-9px)] relative left-1/2 right-1/2 ml-[-50vw] mr-[-50vw] bg-gray-50 py-[30px] px-0 mb-10'>
|
|
677
|
+
<div className='max-w-[1200px] px-2.5 mx-auto relative'>
|
|
678
|
+
<CrossSeller />
|
|
679
|
+
</div>
|
|
680
|
+
</section>
|
|
669
681
|
</Fragment>
|
|
670
682
|
);
|
|
671
683
|
};
|
|
@@ -52,7 +52,7 @@ const QuantityStepper = props => {
|
|
|
52
52
|
})}
|
|
53
53
|
className={cn(
|
|
54
54
|
classes.button_decrement,
|
|
55
|
-
'!h-full min-w-[40px] min-h-[40px]'
|
|
55
|
+
'!h-full min-w-[40px] min-h-[40px] !rounded-l-md !rounded-r-none'
|
|
56
56
|
)}
|
|
57
57
|
disabled={isDecrementDisabled}
|
|
58
58
|
onClick={handleDecrement}
|
|
@@ -89,7 +89,7 @@ const QuantityStepper = props => {
|
|
|
89
89
|
})}
|
|
90
90
|
className={cn(
|
|
91
91
|
classes.button_increment,
|
|
92
|
-
'!h-full min-w-[40px] min-h-[40px]'
|
|
92
|
+
'!h-full min-w-[40px] min-h-[40px] !rounded-r-md !rounded-l-none'
|
|
93
93
|
)}
|
|
94
94
|
disabled={isIncrementDisabled}
|
|
95
95
|
onClick={handleIncrement}
|
|
@@ -4,15 +4,32 @@ import mergeOperations from '@magento/peregrine/lib/util/shallowMerge';
|
|
|
4
4
|
|
|
5
5
|
import DEFAULT_OPERATIONS from './customFilters.gql';
|
|
6
6
|
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
7
|
+
import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
|
|
8
|
+
import { useHistory, useLocation } from 'react-router-dom';
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
import { useFilterState } from '@magento/peregrine/lib/talons/FilterModal';
|
|
9
12
|
import {
|
|
10
13
|
getFiltersFromSearch,
|
|
11
|
-
getFilterInput
|
|
14
|
+
getFilterInput,
|
|
15
|
+
getSearchFromState,
|
|
16
|
+
getStateFromSearch,
|
|
17
|
+
sortFiltersArray,
|
|
18
|
+
stripHtml
|
|
12
19
|
} from '@magento/peregrine/lib/talons/FilterModal/helpers';
|
|
13
20
|
|
|
14
21
|
export const useCustomFilters = props => {
|
|
15
|
-
|
|
22
|
+
const { filters } = props;
|
|
23
|
+
|
|
24
|
+
const [isApplying, setIsApplying] = useState(false);
|
|
25
|
+
const [filterState, filterApi] = useFilterState();
|
|
26
|
+
|
|
27
|
+
const attributeCodes = useMemo(
|
|
28
|
+
() => filters.map(({ attribute_code }) => attribute_code),
|
|
29
|
+
[filters]
|
|
30
|
+
);
|
|
31
|
+
|
|
32
|
+
const history = useHistory();
|
|
16
33
|
|
|
17
34
|
const operations = mergeOperations(DEFAULT_OPERATIONS);
|
|
18
35
|
const { getCustomFilters, getFilterInputsQuery, getStoreConfigQuery } = operations;
|
|
@@ -88,10 +105,151 @@ export const useCustomFilters = props => {
|
|
|
88
105
|
}
|
|
89
106
|
}, [storeConfigData]);
|
|
90
107
|
|
|
108
|
+
// Create a set of disabled filters.
|
|
109
|
+
const DISABLED_FILTERS = useMemo(() => {
|
|
110
|
+
const disabled = new Set();
|
|
111
|
+
// Disable category filtering when not on a search page.
|
|
112
|
+
if (pathname !== '/search.html') {
|
|
113
|
+
// disabled.add('category_id');
|
|
114
|
+
// disabled.add('category_uid');
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
return disabled;
|
|
118
|
+
}, [pathname]);
|
|
119
|
+
|
|
120
|
+
const possibleFilters = useMemo(() => {
|
|
121
|
+
const nextFilters = new Set();
|
|
122
|
+
const inputFields = introspectionData
|
|
123
|
+
? introspectionData.__type.inputFields
|
|
124
|
+
: [];
|
|
125
|
+
|
|
126
|
+
// perform mapping and filtering in the same cycle
|
|
127
|
+
for (const { name } of inputFields) {
|
|
128
|
+
const isValid = attributeCodes.includes(name);
|
|
129
|
+
const isEnabled = !DISABLED_FILTERS.has(name);
|
|
130
|
+
|
|
131
|
+
if (isValid && isEnabled) {
|
|
132
|
+
nextFilters.add(name);
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
return nextFilters;
|
|
137
|
+
}, [DISABLED_FILTERS, attributeCodes, introspectionData]);
|
|
138
|
+
|
|
139
|
+
const isBooleanFilter = options => {
|
|
140
|
+
const optionsString = JSON.stringify(options);
|
|
141
|
+
return (
|
|
142
|
+
options.length <= 2 &&
|
|
143
|
+
(optionsString.includes(
|
|
144
|
+
JSON.stringify({
|
|
145
|
+
__typename: 'AggregationOption',
|
|
146
|
+
label: '0',
|
|
147
|
+
value: '0'
|
|
148
|
+
})
|
|
149
|
+
) ||
|
|
150
|
+
optionsString.includes(
|
|
151
|
+
JSON.stringify({
|
|
152
|
+
__typename: 'AggregationOption',
|
|
153
|
+
label: '1',
|
|
154
|
+
value: '1'
|
|
155
|
+
})
|
|
156
|
+
))
|
|
157
|
+
);
|
|
158
|
+
};
|
|
159
|
+
|
|
160
|
+
const [
|
|
161
|
+
filterNames,
|
|
162
|
+
filterKeys,
|
|
163
|
+
filterItems,
|
|
164
|
+
filterFrontendInput
|
|
165
|
+
] = useMemo(() => {
|
|
166
|
+
const names = new Map();
|
|
167
|
+
const keys = new Set();
|
|
168
|
+
const frontendInput = new Map();
|
|
169
|
+
const itemsByGroup = new Map();
|
|
170
|
+
|
|
171
|
+
const sortedFilters = sortFiltersArray([...filters]);
|
|
172
|
+
|
|
173
|
+
for (const filter of sortedFilters) {
|
|
174
|
+
const { options, label: name, attribute_code: group } = filter;
|
|
175
|
+
|
|
176
|
+
// If this aggregation is not a possible filter, just back out.
|
|
177
|
+
if (possibleFilters.has(group)) {
|
|
178
|
+
const items = [];
|
|
179
|
+
|
|
180
|
+
// add filter name
|
|
181
|
+
names.set(group, name);
|
|
182
|
+
|
|
183
|
+
// add filter key permutations
|
|
184
|
+
keys.add(`${group}[filter]`);
|
|
185
|
+
|
|
186
|
+
// TODO: Get all frontend input type from gql if other filter input types are needed
|
|
187
|
+
// See https://github.com/magento-commerce/magento2-pwa/pull/26
|
|
188
|
+
if (isBooleanFilter(options)) {
|
|
189
|
+
frontendInput.set(group, 'boolean');
|
|
190
|
+
// add items
|
|
191
|
+
items.push({
|
|
192
|
+
title: 'No',
|
|
193
|
+
value: '0',
|
|
194
|
+
label: name + ':' + 'No'
|
|
195
|
+
});
|
|
196
|
+
items.push({
|
|
197
|
+
title: 'Yes',
|
|
198
|
+
value: '1',
|
|
199
|
+
label: name + ':' + 'Yes'
|
|
200
|
+
});
|
|
201
|
+
} else {
|
|
202
|
+
// Add frontend input type
|
|
203
|
+
frontendInput.set(group, null);
|
|
204
|
+
// add items
|
|
205
|
+
for (const { label, value, path } of options) {
|
|
206
|
+
items.push({ title: stripHtml(label), value, path });
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
itemsByGroup.set(group, items);
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
return [names, keys, itemsByGroup, frontendInput];
|
|
214
|
+
}, [filters, possibleFilters]);
|
|
215
|
+
|
|
216
|
+
useEffect(() => {
|
|
217
|
+
if (isApplying) {
|
|
218
|
+
const nextSearch = getSearchFromState(
|
|
219
|
+
search,
|
|
220
|
+
filterKeys,
|
|
221
|
+
filterState
|
|
222
|
+
);
|
|
223
|
+
|
|
224
|
+
// write filter state to history
|
|
225
|
+
history.push({ pathname, search: nextSearch });
|
|
226
|
+
|
|
227
|
+
// mark the operation as complete
|
|
228
|
+
setIsApplying(false);
|
|
229
|
+
}
|
|
230
|
+
}, [filterKeys, filterState, history, isApplying, pathname, search]);
|
|
231
|
+
|
|
232
|
+
const handleApply = useCallback(() => {
|
|
233
|
+
setIsApplying(true);
|
|
234
|
+
}, []);
|
|
235
|
+
|
|
236
|
+
const handleReset = useCallback(() => {
|
|
237
|
+
filterApi.clear();
|
|
238
|
+
setIsApplying(true);
|
|
239
|
+
}, [filterApi, setIsApplying]);
|
|
240
|
+
|
|
91
241
|
return {
|
|
92
242
|
customFiltersData: customFiltersData || [],
|
|
93
243
|
categoryUrlSuffix,
|
|
94
244
|
search,
|
|
95
|
-
pathname
|
|
245
|
+
pathname,
|
|
246
|
+
filterApi,
|
|
247
|
+
// filterItems,
|
|
248
|
+
// filterKeys,
|
|
249
|
+
// filterNames,
|
|
250
|
+
// filterFrontendInput,
|
|
251
|
+
filterState,
|
|
252
|
+
handleApply,
|
|
253
|
+
handleReset
|
|
96
254
|
};
|
|
97
255
|
};
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { gql } from '@apollo/client';
|
|
2
|
+
|
|
3
|
+
export const GET_CUSTOM_FILTERS = gql`
|
|
4
|
+
query GetCustomFilters($filters: ProductAttributeFilterInput!) {
|
|
5
|
+
customSubFilters(filters: $filters) {
|
|
6
|
+
label
|
|
7
|
+
count
|
|
8
|
+
attribute_code
|
|
9
|
+
options {
|
|
10
|
+
label
|
|
11
|
+
value
|
|
12
|
+
}
|
|
13
|
+
position
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
`;
|
|
17
|
+
|
|
18
|
+
export const GET_FILTER_INPUTS = gql`
|
|
19
|
+
query GetFilterInputsForCategory {
|
|
20
|
+
__type(name: "ProductAttributeFilterInput") {
|
|
21
|
+
inputFields {
|
|
22
|
+
name
|
|
23
|
+
type {
|
|
24
|
+
name
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
`;
|
|
30
|
+
|
|
31
|
+
export const GET_STORE_CONFIG_DATA = gql`
|
|
32
|
+
query GetStoreConfigForBreadcrumbs {
|
|
33
|
+
# eslint-disable-next-line @graphql-eslint/require-id-when-available
|
|
34
|
+
storeConfig {
|
|
35
|
+
store_code
|
|
36
|
+
category_url_suffix
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
`;
|
|
40
|
+
|
|
41
|
+
export default {
|
|
42
|
+
getFilterInputsQuery: GET_FILTER_INPUTS,
|
|
43
|
+
getCustomFilters: GET_CUSTOM_FILTERS,
|
|
44
|
+
getStoreConfigQuery: GET_STORE_CONFIG_DATA
|
|
45
|
+
};
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { gql } from '@apollo/client';
|
|
2
|
+
|
|
3
|
+
export const GET_CUSTOM_FILTERS = gql`
|
|
4
|
+
query GetCustomFilters($filters: ProductAttributeFilterInput!) {
|
|
5
|
+
customSubFilters(filters: $filters) {
|
|
6
|
+
label
|
|
7
|
+
count
|
|
8
|
+
attribute_code
|
|
9
|
+
options {
|
|
10
|
+
label
|
|
11
|
+
value
|
|
12
|
+
}
|
|
13
|
+
position
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
`;
|
|
17
|
+
|
|
18
|
+
export const GET_FILTER_INPUTS = gql`
|
|
19
|
+
query GetFilterInputsForCategory {
|
|
20
|
+
__type(name: "ProductAttributeFilterInput") {
|
|
21
|
+
inputFields {
|
|
22
|
+
name
|
|
23
|
+
type {
|
|
24
|
+
name
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
`;
|
|
30
|
+
|
|
31
|
+
export const GET_STORE_CONFIG_DATA = gql`
|
|
32
|
+
query GetStoreConfigForBreadcrumbs {
|
|
33
|
+
# eslint-disable-next-line @graphql-eslint/require-id-when-available
|
|
34
|
+
storeConfig {
|
|
35
|
+
store_code
|
|
36
|
+
category_url_suffix
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
`;
|
|
40
|
+
|
|
41
|
+
export default {
|
|
42
|
+
getFilterInputsQuery: GET_FILTER_INPUTS,
|
|
43
|
+
getCustomFilters: GET_CUSTOM_FILTERS,
|
|
44
|
+
getStoreConfigQuery: GET_STORE_CONFIG_DATA
|
|
45
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { useFilterTop } from './useFilterTop';
|