@riosst100/pwa-marketplace 1.4.4 → 1.4.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/package.json +1 -1
- package/src/components/AttributesBlock/attributesBlock.js +2 -2
- package/src/components/CollectibleGameSets/collectibleGameSets.js +0 -3
- package/src/components/FilterTop/CustomFilters/customFilter.js +84 -0
- package/src/components/FilterTop/CustomFilters/customFilter.module.css +22 -0
- package/src/components/FilterTop/CustomFilters/customFilters.js +104 -0
- package/src/components/FilterTop/CustomFilters/customFilters.module.css +24 -0
- package/src/components/FilterTop/CustomFilters/index.js +1 -0
- package/src/components/FilterTop/filterTop.js +139 -0
- package/src/components/FilterTop/filterTop.module.css +58 -0
- package/src/components/FilterTop/filterTop.shimmer.js +24 -0
- package/src/components/FilterTop/index.js +2 -0
- package/src/components/SubCategory/subCategory.js +1 -0
- package/src/overwrites/peregrine/lib/talons/MegaMenu/useMegaMenuItem.js +2 -2
- package/src/overwrites/venia-ui/lib/RootComponents/Category/categoryContent.js +6 -2
- package/src/overwrites/venia-ui/lib/components/FilterModal/CurrentFilters/currentFilter.js +2 -2
- package/src/overwrites/venia-ui/lib/components/FilterModal/CurrentFilters/currentFilter.module.css +2 -2
- package/src/overwrites/venia-ui/lib/components/FilterModal/CurrentFilters/currentFilters.module.css +2 -0
- package/src/overwrites/venia-ui/lib/components/MegaMenu/megaMenuItem.js +2 -2
- package/src/talons/CustomFilters/customFilters.gql.js +45 -0
- package/src/talons/CustomFilters/useCustomFilters.js +97 -0
package/package.json
CHANGED
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
import React, { useCallback } from 'react';
|
|
2
|
+
import { useIntl } from 'react-intl';
|
|
3
|
+
import { shape, string, func } from 'prop-types';
|
|
4
|
+
import { X as Remove } from 'react-feather';
|
|
5
|
+
|
|
6
|
+
import { useStyle } from '@magento/venia-ui/lib/classify';
|
|
7
|
+
import Icon from '@magento/venia-ui/lib/components/Icon';
|
|
8
|
+
import Trigger from '@magento/venia-ui/lib/components/Trigger';
|
|
9
|
+
import defaultClasses from './customFilter.module.css';
|
|
10
|
+
import resourceUrl from '@magento/peregrine/lib/util/makeUrl';
|
|
11
|
+
|
|
12
|
+
import { Link } from 'react-router-dom';
|
|
13
|
+
|
|
14
|
+
const CustomFilter = props => {
|
|
15
|
+
const { group, item, onRemove } = props;
|
|
16
|
+
const classes = useStyle(defaultClasses, props.classes);
|
|
17
|
+
const { formatMessage } = useIntl();
|
|
18
|
+
|
|
19
|
+
const ariaLabel = formatMessage(
|
|
20
|
+
{
|
|
21
|
+
id: 'filterModal.action.clearFilterItem.ariaLabel',
|
|
22
|
+
defaultMessage: 'Clear filter "{name}"'
|
|
23
|
+
},
|
|
24
|
+
{
|
|
25
|
+
name: item.label ? item.label : item.title
|
|
26
|
+
}
|
|
27
|
+
);
|
|
28
|
+
|
|
29
|
+
console.log(group)
|
|
30
|
+
console.log(item)
|
|
31
|
+
|
|
32
|
+
const normalizedData = [
|
|
33
|
+
{
|
|
34
|
+
'label': 'Sealed Products',
|
|
35
|
+
'path': '/'
|
|
36
|
+
},
|
|
37
|
+
{
|
|
38
|
+
'label': 'Singles',
|
|
39
|
+
'path': '/'
|
|
40
|
+
},
|
|
41
|
+
{
|
|
42
|
+
'label': 'Supplies',
|
|
43
|
+
'path': '/'
|
|
44
|
+
}
|
|
45
|
+
];
|
|
46
|
+
|
|
47
|
+
const subCategory = [];
|
|
48
|
+
|
|
49
|
+
if (group == "card_set") {
|
|
50
|
+
normalizedData && normalizedData.map(({ label, path }, index) => {
|
|
51
|
+
subCategory.push(
|
|
52
|
+
<Link
|
|
53
|
+
key={index}
|
|
54
|
+
to={resourceUrl(path)}
|
|
55
|
+
>
|
|
56
|
+
<li className={classes.item}>{label}</li>
|
|
57
|
+
</Link>
|
|
58
|
+
)
|
|
59
|
+
});
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
return (
|
|
64
|
+
<ul className={classes.root}>{subCategory}</ul>
|
|
65
|
+
// <span className={classes.root} data-cy="CustomFilter-root">
|
|
66
|
+
// <span className={classes.text}>
|
|
67
|
+
// {item.label ? item.label : item.title}
|
|
68
|
+
// </span>
|
|
69
|
+
// </span>
|
|
70
|
+
);
|
|
71
|
+
};
|
|
72
|
+
|
|
73
|
+
export default CustomFilter;
|
|
74
|
+
|
|
75
|
+
CustomFilter.defaultProps = {
|
|
76
|
+
onRemove: null
|
|
77
|
+
};
|
|
78
|
+
|
|
79
|
+
CustomFilter.propTypes = {
|
|
80
|
+
classes: shape({
|
|
81
|
+
root: string
|
|
82
|
+
}),
|
|
83
|
+
onRemove: func
|
|
84
|
+
};
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
.root {
|
|
2
|
+
composes: flex from global;
|
|
3
|
+
composes: flex-wrap from global;
|
|
4
|
+
composes: mt-3 from global;
|
|
5
|
+
composes: gap-[15px] from global;
|
|
6
|
+
margin-bottom: 10px;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
.item {
|
|
10
|
+
composes: px-4 from global;
|
|
11
|
+
composes: py-2 from global;
|
|
12
|
+
composes: transition-colors from global;
|
|
13
|
+
composes: duration-150 from global;
|
|
14
|
+
composes: border from global;
|
|
15
|
+
composes: border-solid from global;
|
|
16
|
+
composes: leading-normal from global;
|
|
17
|
+
composes: text-base from global;
|
|
18
|
+
composes: text-colorDefault from global;
|
|
19
|
+
composes: bg-white from global;
|
|
20
|
+
composes: border-gray-100 from global;
|
|
21
|
+
border-radius: 5px;
|
|
22
|
+
}
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
import React, { useMemo } from 'react';
|
|
2
|
+
import { func, shape, string } from 'prop-types';
|
|
3
|
+
import { useIntl } from 'react-intl';
|
|
4
|
+
|
|
5
|
+
import { useStyle } from '@magento/venia-ui/lib/classify';
|
|
6
|
+
import CustomFilter from './customFilter';
|
|
7
|
+
import defaultClasses from './customFilters.module.css';
|
|
8
|
+
import resourceUrl from '@magento/peregrine/lib/util/makeUrl';
|
|
9
|
+
import { Link } from 'react-router-dom';
|
|
10
|
+
import { useCustomFilters } from '@riosst100/pwa-marketplace/src/talons/CustomFilters/useCustomFilters';
|
|
11
|
+
|
|
12
|
+
const CustomFilters = props => {
|
|
13
|
+
const { filterState, onRemove, clearAll, category } = props;
|
|
14
|
+
const classes = useStyle(defaultClasses, props.classes);
|
|
15
|
+
const { formatMessage } = useIntl();
|
|
16
|
+
|
|
17
|
+
const talonProps = useCustomFilters();
|
|
18
|
+
|
|
19
|
+
const { customFiltersData, categoryUrlSuffix, search, pathname } = talonProps;
|
|
20
|
+
|
|
21
|
+
// console.log(category.url_path)
|
|
22
|
+
// console.log(categoryUrlSuffix)
|
|
23
|
+
|
|
24
|
+
const params = search ? JSON.parse('{"' + decodeURI(search).replace(/"/g, '\\"').replace(/&/g, '","').replace(/=/g,'":"') + '"}') : {};
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
// console.log(params)
|
|
29
|
+
|
|
30
|
+
// create elements and params at the same time for efficiency
|
|
31
|
+
const filterElements = useMemo(() => {
|
|
32
|
+
const elements = [];
|
|
33
|
+
customFiltersData.map((filter, index) => {
|
|
34
|
+
const { label, attribute_code, options } = filter || {};
|
|
35
|
+
|
|
36
|
+
if (options.length) {
|
|
37
|
+
const items = [];
|
|
38
|
+
options.map(({ label, value }, index) => {
|
|
39
|
+
// const path = '/';
|
|
40
|
+
|
|
41
|
+
// const path = resourceUrl(
|
|
42
|
+
// `/${category.url_path}${categoryUrlSuffix || ''}?${attribute_code}[filter]=${label},${value}`
|
|
43
|
+
// );
|
|
44
|
+
// const keyAttr = `${attribute_code}[filter]`;
|
|
45
|
+
|
|
46
|
+
Object.keys(params).forEach(function(key, index) {
|
|
47
|
+
if (index > 1) {
|
|
48
|
+
delete params[key];
|
|
49
|
+
}
|
|
50
|
+
});
|
|
51
|
+
|
|
52
|
+
if (value != "all") {
|
|
53
|
+
params[`${attribute_code}[filter]`] = `${label},${value}`;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
const finalParams = Object.keys(params).map(key => `${key}=${params[key]}`).join('&');
|
|
57
|
+
|
|
58
|
+
// console.log(params)
|
|
59
|
+
|
|
60
|
+
// console.log(finalParams);
|
|
61
|
+
|
|
62
|
+
const path = pathname + finalParams;
|
|
63
|
+
|
|
64
|
+
items.push(
|
|
65
|
+
<li>
|
|
66
|
+
<Link
|
|
67
|
+
key={index}
|
|
68
|
+
to={path}
|
|
69
|
+
>
|
|
70
|
+
<li className={classes.item}>{label}</li>
|
|
71
|
+
</Link>
|
|
72
|
+
</li>
|
|
73
|
+
)
|
|
74
|
+
});
|
|
75
|
+
|
|
76
|
+
elements.push(
|
|
77
|
+
<ul className={classes.root}>{items}</ul>
|
|
78
|
+
);
|
|
79
|
+
}
|
|
80
|
+
})
|
|
81
|
+
|
|
82
|
+
return elements;
|
|
83
|
+
}, [customFiltersData]);
|
|
84
|
+
|
|
85
|
+
return (
|
|
86
|
+
<>{filterElements}</>
|
|
87
|
+
);
|
|
88
|
+
};
|
|
89
|
+
|
|
90
|
+
CustomFilters.defaultProps = {
|
|
91
|
+
onRemove: null
|
|
92
|
+
};
|
|
93
|
+
|
|
94
|
+
CustomFilters.propTypes = {
|
|
95
|
+
classes: shape({
|
|
96
|
+
root: string,
|
|
97
|
+
item: string,
|
|
98
|
+
button: string,
|
|
99
|
+
icon: string
|
|
100
|
+
}),
|
|
101
|
+
onRemove: func
|
|
102
|
+
};
|
|
103
|
+
|
|
104
|
+
export default CustomFilters;
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
.root {
|
|
2
|
+
composes: flex from global;
|
|
3
|
+
composes: flex-wrap from global;
|
|
4
|
+
composes: mt-3 from global;
|
|
5
|
+
composes: gap-[15px] from global;
|
|
6
|
+
margin-bottom: 10px;
|
|
7
|
+
justify-content: center;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
.item {
|
|
11
|
+
composes: px-4 from global;
|
|
12
|
+
composes: py-2 from global;
|
|
13
|
+
composes: transition-colors from global;
|
|
14
|
+
composes: duration-150 from global;
|
|
15
|
+
composes: border from global;
|
|
16
|
+
composes: border-solid from global;
|
|
17
|
+
composes: leading-normal from global;
|
|
18
|
+
composes: text-base from global;
|
|
19
|
+
composes: text-colorDefault from global;
|
|
20
|
+
composes: bg-white from global;
|
|
21
|
+
composes: border-gray-100 from global;
|
|
22
|
+
border-radius: 5px;
|
|
23
|
+
composes: shadow-type-1 from global;
|
|
24
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default } from './customFilters';
|
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
import React, { useMemo, useCallback, useRef } from 'react';
|
|
2
|
+
import { FormattedMessage } from 'react-intl';
|
|
3
|
+
import { array, arrayOf, shape, string, number } from 'prop-types';
|
|
4
|
+
import { useFilterSidebar } from '@magento/peregrine/lib/talons/FilterSidebar';
|
|
5
|
+
|
|
6
|
+
import { useStyle } from '@magento/venia-ui/lib/classify';
|
|
7
|
+
import LinkButton from '@magento/venia-ui/lib/components/LinkButton';
|
|
8
|
+
import CustomFilters from './CustomFilters';
|
|
9
|
+
import FilterBlock from '@magento/venia-ui/lib/components/FilterModal/filterBlock';
|
|
10
|
+
import defaultClasses from './filterTop.module.css';
|
|
11
|
+
|
|
12
|
+
import resourceUrl from '@magento/peregrine/lib/util/makeUrl';
|
|
13
|
+
|
|
14
|
+
import { Link } from 'react-router-dom';
|
|
15
|
+
import CurrentFilters from '@riosst100/pwa-marketplace/src/overwrites/venia-ui/lib/components/FilterModal/CurrentFilters';
|
|
16
|
+
|
|
17
|
+
const SCROLL_OFFSET = 150;
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* A view that displays applicable and applied filters.
|
|
21
|
+
*
|
|
22
|
+
* @param {Object} props.filters - filters to display
|
|
23
|
+
*/
|
|
24
|
+
const FilterTop = props => {
|
|
25
|
+
const { filters, filterCountToOpen, category } = props;
|
|
26
|
+
const talonProps = useFilterSidebar({ filters });
|
|
27
|
+
const {
|
|
28
|
+
filterApi,
|
|
29
|
+
filterItems,
|
|
30
|
+
filterNames,
|
|
31
|
+
filterFrontendInput,
|
|
32
|
+
filterState,
|
|
33
|
+
handleApply,
|
|
34
|
+
handleReset
|
|
35
|
+
} = talonProps;
|
|
36
|
+
|
|
37
|
+
const filterRef = useRef();
|
|
38
|
+
const classes = useStyle(defaultClasses, props.classes);
|
|
39
|
+
|
|
40
|
+
const handleApplyFilter = useCallback(
|
|
41
|
+
(...args) => {
|
|
42
|
+
const filterElement = filterRef.current;
|
|
43
|
+
if (
|
|
44
|
+
filterElement &&
|
|
45
|
+
typeof filterElement.getBoundingClientRect === 'function'
|
|
46
|
+
) {
|
|
47
|
+
const filterTop = filterElement.getBoundingClientRect().top;
|
|
48
|
+
const windowScrollY =
|
|
49
|
+
window.scrollY + filterTop - SCROLL_OFFSET;
|
|
50
|
+
window.scrollTo(0, windowScrollY);
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
handleApply(...args);
|
|
54
|
+
},
|
|
55
|
+
[handleApply, filterRef]
|
|
56
|
+
);
|
|
57
|
+
|
|
58
|
+
const filtersList = useMemo(
|
|
59
|
+
() =>
|
|
60
|
+
Array.from(filterItems, ([group, items], iteration) => {
|
|
61
|
+
const blockState = filterState.get(group);
|
|
62
|
+
const groupName = filterNames.get(group);
|
|
63
|
+
const frontendInput = filterFrontendInput.get(group);
|
|
64
|
+
return (
|
|
65
|
+
<FilterBlock
|
|
66
|
+
key={group}
|
|
67
|
+
filterApi={filterApi}
|
|
68
|
+
filterState={blockState}
|
|
69
|
+
filterFrontendInput={frontendInput}
|
|
70
|
+
group={group}
|
|
71
|
+
items={items}
|
|
72
|
+
name={groupName}
|
|
73
|
+
onApply={handleApplyFilter}
|
|
74
|
+
initialOpen={iteration < filterCountToOpen}
|
|
75
|
+
/>
|
|
76
|
+
);
|
|
77
|
+
}),
|
|
78
|
+
[
|
|
79
|
+
filterApi,
|
|
80
|
+
filterItems,
|
|
81
|
+
filterNames,
|
|
82
|
+
filterFrontendInput,
|
|
83
|
+
filterState,
|
|
84
|
+
filterCountToOpen,
|
|
85
|
+
handleApplyFilter
|
|
86
|
+
]
|
|
87
|
+
);
|
|
88
|
+
|
|
89
|
+
const clearAll = filterState.size ? (
|
|
90
|
+
<div className={classes.action}>
|
|
91
|
+
<LinkButton
|
|
92
|
+
type="button"
|
|
93
|
+
onClick={handleReset}
|
|
94
|
+
data-cy="FilterSidebar-clearButton"
|
|
95
|
+
>
|
|
96
|
+
<FormattedMessage
|
|
97
|
+
id={'filterModal.all'}
|
|
98
|
+
defaultMessage={'All'}
|
|
99
|
+
/>
|
|
100
|
+
</LinkButton>
|
|
101
|
+
</div>
|
|
102
|
+
) : null;
|
|
103
|
+
|
|
104
|
+
return (
|
|
105
|
+
<CustomFilters
|
|
106
|
+
filterApi={filterApi}
|
|
107
|
+
filterNames={filterNames}
|
|
108
|
+
filterState={filterState}
|
|
109
|
+
clearAll={clearAll}
|
|
110
|
+
category={category}
|
|
111
|
+
onRemove={handleApplyFilter}
|
|
112
|
+
/>
|
|
113
|
+
);
|
|
114
|
+
};
|
|
115
|
+
|
|
116
|
+
FilterTop.defaultProps = {
|
|
117
|
+
filterCountToOpen: 3
|
|
118
|
+
};
|
|
119
|
+
|
|
120
|
+
FilterTop.propTypes = {
|
|
121
|
+
classes: shape({
|
|
122
|
+
action: string,
|
|
123
|
+
blocks: string,
|
|
124
|
+
body: string,
|
|
125
|
+
header: string,
|
|
126
|
+
headerTitle: string,
|
|
127
|
+
root: string,
|
|
128
|
+
root_open: string
|
|
129
|
+
}),
|
|
130
|
+
filters: arrayOf(
|
|
131
|
+
shape({
|
|
132
|
+
attribute_code: string,
|
|
133
|
+
items: array
|
|
134
|
+
})
|
|
135
|
+
),
|
|
136
|
+
filterCountToOpen: number
|
|
137
|
+
};
|
|
138
|
+
|
|
139
|
+
export default FilterTop;
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
.root {
|
|
2
|
+
composes: bg-white from global;
|
|
3
|
+
composes: bottom-0 from global;
|
|
4
|
+
composes: hidden from global;
|
|
5
|
+
composes: max-w-modal from global;
|
|
6
|
+
composes: w-full from global;
|
|
7
|
+
composes: z-foreground from global;
|
|
8
|
+
grid-template-rows: 1fr 7rem;
|
|
9
|
+
|
|
10
|
+
composes: lg_grid from global;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
.body {
|
|
14
|
+
composes: overflow-auto from global;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
.header {
|
|
18
|
+
composes: flex from global;
|
|
19
|
+
composes: justify-between from global;
|
|
20
|
+
composes: pb-0 from global;
|
|
21
|
+
composes: pt-5 from global;
|
|
22
|
+
composes: px-5 from global;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
.headerTitle {
|
|
26
|
+
composes: flex from global;
|
|
27
|
+
composes: items-center from global;
|
|
28
|
+
composes: leading-none from global;
|
|
29
|
+
composes: text-lg from global;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
.action {
|
|
33
|
+
composes: pb-0 from global;
|
|
34
|
+
composes: pt-xs from global;
|
|
35
|
+
composes: px-xs from global;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
/* TODO @TW: cannot compose */
|
|
39
|
+
.action button {
|
|
40
|
+
/* composes: text-sm from global; */
|
|
41
|
+
font-size: 0.875rem;
|
|
42
|
+
/* composes: no-underline from global; */
|
|
43
|
+
text-decoration: none;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
.blocks {
|
|
47
|
+
composes: pb-0 from global;
|
|
48
|
+
composes: pt-xs from global;
|
|
49
|
+
composes: px-xs from global;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/* TODO @TW: cannot compose */
|
|
53
|
+
.blocks > li:last-child {
|
|
54
|
+
/* composes: border-b-2 from global; */
|
|
55
|
+
/* composes: border-solid from global; */
|
|
56
|
+
/* composes: border-subtle from global; */
|
|
57
|
+
border-bottom: 2px solid rgb(var(--venia-global-color-border));
|
|
58
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { shape, string } from 'prop-types';
|
|
3
|
+
import { useStyle } from '@magento/venia-ui/lib/classify';
|
|
4
|
+
|
|
5
|
+
import Shimmer from '@magento/venia-ui/lib/components/Shimmer';
|
|
6
|
+
import defaultClasses from './filterTop.module.css';
|
|
7
|
+
|
|
8
|
+
const FilterTop = props => {
|
|
9
|
+
const classes = useStyle(defaultClasses, props.classes);
|
|
10
|
+
|
|
11
|
+
return (
|
|
12
|
+
<aside className={classes.root} aria-live="polite" aria-busy="true">
|
|
13
|
+
<Shimmer width="95%" height="70vh" style={{ marginBottom: 25 }} />
|
|
14
|
+
</aside>
|
|
15
|
+
);
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
FilterTop.propTypes = {
|
|
19
|
+
classes: shape({
|
|
20
|
+
root: string
|
|
21
|
+
})
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
export default FilterTop;
|
|
@@ -4,6 +4,7 @@ import { Link } from 'react-router-dom';
|
|
|
4
4
|
import resourceUrl from '@magento/peregrine/lib/util/makeUrl';
|
|
5
5
|
import defaultClasses from './subCategory.module.css';
|
|
6
6
|
import { useStyle } from '@magento/venia-ui/lib/classify';
|
|
7
|
+
import { useFilterSidebar } from '@magento/peregrine/lib/talons/FilterSidebar';
|
|
7
8
|
|
|
8
9
|
const SubCategory = props => {
|
|
9
10
|
const { children } = props;
|
|
@@ -33,7 +33,7 @@ export const useMegaMenuItem = props => {
|
|
|
33
33
|
// checking down arrow and spacebar
|
|
34
34
|
if (pressedKey === 'ArrowDown' || pressedKey === ' ') {
|
|
35
35
|
event.preventDefault();
|
|
36
|
-
if (category.children.length) {
|
|
36
|
+
if (category.children.length || category.name == "Lego") {
|
|
37
37
|
setIsFocused(true);
|
|
38
38
|
} else {
|
|
39
39
|
setIsFocused(false);
|
|
@@ -52,7 +52,7 @@ export const useMegaMenuItem = props => {
|
|
|
52
52
|
setIsFocused(false);
|
|
53
53
|
}
|
|
54
54
|
},
|
|
55
|
-
[category.children.length]
|
|
55
|
+
[category.children.length, category.name]
|
|
56
56
|
);
|
|
57
57
|
|
|
58
58
|
return {
|
|
@@ -33,6 +33,9 @@ const FilterModal = React.lazy(() => import('@magento/venia-ui/lib/components/Fi
|
|
|
33
33
|
const FilterSidebar = React.lazy(() =>
|
|
34
34
|
import('@magento/venia-ui/lib/components/FilterSidebar')
|
|
35
35
|
);
|
|
36
|
+
const FilterTop = React.lazy(() =>
|
|
37
|
+
import('@riosst100/pwa-marketplace/src/components/FilterTop')
|
|
38
|
+
);
|
|
36
39
|
|
|
37
40
|
const CategoryContent = props => {
|
|
38
41
|
const {
|
|
@@ -183,8 +186,9 @@ const CategoryContent = props => {
|
|
|
183
186
|
</h1>
|
|
184
187
|
{categoryDescriptionElement}
|
|
185
188
|
</div>
|
|
186
|
-
<SubCategory children={children} />
|
|
187
|
-
<
|
|
189
|
+
<SubCategory filters={filters} children={children} />
|
|
190
|
+
<FilterTop filters={filters} category={category} />
|
|
191
|
+
{/* <AttributesBlock category={category} attributesBlock={attributesBlock} /> */}
|
|
188
192
|
{/* <section className='category_brand-slider my-5'>
|
|
189
193
|
<BrandSlider />
|
|
190
194
|
</section> */}
|
|
@@ -34,10 +34,10 @@ const CurrentFilter = props => {
|
|
|
34
34
|
<span className={classes.root} data-cy="CurrentFilter-root">
|
|
35
35
|
<Trigger
|
|
36
36
|
action={handleClick}
|
|
37
|
-
|
|
37
|
+
aria-label={ariaLabel}
|
|
38
38
|
data-cy="CurrentFilter-trigger"
|
|
39
39
|
>
|
|
40
|
-
<Icon size={
|
|
40
|
+
<Icon size={15} src={Remove} />
|
|
41
41
|
</Trigger>
|
|
42
42
|
<span className={classes.text}>
|
|
43
43
|
{item.label ? item.label : item.title}
|
package/src/overwrites/venia-ui/lib/components/FilterModal/CurrentFilters/currentFilter.module.css
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
.root {
|
|
2
2
|
min-height: 24px;
|
|
3
3
|
composes: bg-blue-700 from global;
|
|
4
|
-
composes: font-semibold from global;
|
|
4
|
+
/* composes: font-semibold from global; */
|
|
5
5
|
composes: gap-2xs from global;
|
|
6
6
|
composes: grid-flow-col from global;
|
|
7
7
|
composes: inline-grid from global;
|
|
@@ -17,5 +17,5 @@
|
|
|
17
17
|
/* TODO @TW: cannot compose */
|
|
18
18
|
.root svg {
|
|
19
19
|
/* composes: stroke-white from global; */
|
|
20
|
-
stroke:
|
|
20
|
+
stroke: white;
|
|
21
21
|
}
|
package/src/overwrites/venia-ui/lib/components/FilterModal/CurrentFilters/currentFilters.module.css
CHANGED
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
composes: px-[10px] from global;
|
|
3
3
|
composes: py-2 from global;
|
|
4
4
|
composes: overflow-auto from global;
|
|
5
|
+
composes: text-white from global;
|
|
5
6
|
}
|
|
6
7
|
|
|
7
8
|
/* TODO @TW: cannot compose */
|
|
@@ -14,4 +15,5 @@
|
|
|
14
15
|
composes: pb-0 from global;
|
|
15
16
|
composes: pl-0 from global;
|
|
16
17
|
composes: pr-2 from global;
|
|
18
|
+
composes: pt-2 from global;
|
|
17
19
|
}
|
|
@@ -64,7 +64,7 @@ const MegaMenuItem = props => {
|
|
|
64
64
|
const arrow = <ArrowDown2 className='ml-2 stroke-current' size="14" color={textPrimary} variant="Outline" />;
|
|
65
65
|
|
|
66
66
|
const children = useMemo(() => {
|
|
67
|
-
return category.children.length ? (
|
|
67
|
+
return category.children.length || category.name == "Lego" ? (
|
|
68
68
|
<Submenu
|
|
69
69
|
isFocused={isFocused}
|
|
70
70
|
subMenuState={subMenuState}
|
|
@@ -88,7 +88,7 @@ const MegaMenuItem = props => {
|
|
|
88
88
|
onNavigate
|
|
89
89
|
]);
|
|
90
90
|
|
|
91
|
-
const maybeDownArrowIcon = category.children.length ? (
|
|
91
|
+
const maybeDownArrowIcon = category.children.length || category.name == "Lego" ? (
|
|
92
92
|
<ArrowDown2 className='ml-2 stroke-current' size="14" color={textPrimary} variant="Outline" />
|
|
93
93
|
) : null;
|
|
94
94
|
|
|
@@ -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,97 @@
|
|
|
1
|
+
import { useLazyQuery, useQuery } from '@apollo/client';
|
|
2
|
+
|
|
3
|
+
import mergeOperations from '@magento/peregrine/lib/util/shallowMerge';
|
|
4
|
+
|
|
5
|
+
import DEFAULT_OPERATIONS from './customFilters.gql';
|
|
6
|
+
|
|
7
|
+
import { useLocation } from 'react-router-dom';
|
|
8
|
+
import { useEffect, useMemo } from 'react';
|
|
9
|
+
import {
|
|
10
|
+
getFiltersFromSearch,
|
|
11
|
+
getFilterInput
|
|
12
|
+
} from '@magento/peregrine/lib/talons/FilterModal/helpers';
|
|
13
|
+
|
|
14
|
+
export const useCustomFilters = props => {
|
|
15
|
+
// const { filters } = props;
|
|
16
|
+
|
|
17
|
+
const operations = mergeOperations(DEFAULT_OPERATIONS);
|
|
18
|
+
const { getCustomFilters, getFilterInputsQuery, getStoreConfigQuery } = operations;
|
|
19
|
+
|
|
20
|
+
const { data: storeConfigData } = useQuery(getStoreConfigQuery, {
|
|
21
|
+
fetchPolicy: 'cache-and-network'
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
const [runQuery, queryResponse] = useLazyQuery(getCustomFilters, {
|
|
25
|
+
fetchPolicy: 'cache-and-network',
|
|
26
|
+
nextFetchPolicy: 'cache-first'
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
const {
|
|
30
|
+
called: called,
|
|
31
|
+
loading: customFiltersLoading,
|
|
32
|
+
error,
|
|
33
|
+
data
|
|
34
|
+
} = queryResponse;
|
|
35
|
+
|
|
36
|
+
const { pathname, search } = useLocation();
|
|
37
|
+
|
|
38
|
+
const {
|
|
39
|
+
called: introspectionCalled,
|
|
40
|
+
data: introspectionData,
|
|
41
|
+
loading: introspectionLoading
|
|
42
|
+
} = useQuery(getFilterInputsQuery);
|
|
43
|
+
|
|
44
|
+
const filterTypeMap = useMemo(() => {
|
|
45
|
+
const typeMap = new Map();
|
|
46
|
+
if (introspectionData) {
|
|
47
|
+
introspectionData.__type.inputFields.forEach(({ name, type }) => {
|
|
48
|
+
typeMap.set(name, type.name);
|
|
49
|
+
});
|
|
50
|
+
}
|
|
51
|
+
return typeMap;
|
|
52
|
+
}, [introspectionData]);
|
|
53
|
+
|
|
54
|
+
useEffect(() => {
|
|
55
|
+
|
|
56
|
+
if (!filterTypeMap.size) {
|
|
57
|
+
return;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
const filters = getFiltersFromSearch(search);
|
|
61
|
+
|
|
62
|
+
// Construct the filter arg object.
|
|
63
|
+
const newFilters = {};
|
|
64
|
+
filters.forEach((values, key) => {
|
|
65
|
+
newFilters[key] = getFilterInput(values, filterTypeMap.get(key));
|
|
66
|
+
});
|
|
67
|
+
|
|
68
|
+
// Use the category uid for the current category page regardless of the
|
|
69
|
+
// applied filters. Follow-up in PWA-404.
|
|
70
|
+
// newFilters['category_uid'] = { eq: id };
|
|
71
|
+
|
|
72
|
+
runQuery({
|
|
73
|
+
variables: {
|
|
74
|
+
filters: newFilters
|
|
75
|
+
}
|
|
76
|
+
});
|
|
77
|
+
}, [
|
|
78
|
+
runQuery,
|
|
79
|
+
filterTypeMap,
|
|
80
|
+
search
|
|
81
|
+
]);
|
|
82
|
+
|
|
83
|
+
const customFiltersData = customFiltersLoading && !data ? null : (data ? data.customSubFilters : null);
|
|
84
|
+
|
|
85
|
+
const categoryUrlSuffix = useMemo(() => {
|
|
86
|
+
if (storeConfigData) {
|
|
87
|
+
return storeConfigData.storeConfig.category_url_suffix;
|
|
88
|
+
}
|
|
89
|
+
}, [storeConfigData]);
|
|
90
|
+
|
|
91
|
+
return {
|
|
92
|
+
customFiltersData: customFiltersData || [],
|
|
93
|
+
categoryUrlSuffix,
|
|
94
|
+
search,
|
|
95
|
+
pathname
|
|
96
|
+
};
|
|
97
|
+
};
|