@magento/venia-ui 11.5.0 → 11.6.0-alpha.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/lib/RootComponents/Category/__tests__/__snapshots__/categoryContent.shimmer.spec.js.snap +12 -12
- package/lib/RootComponents/Category/categoryContent.js +2 -1
- package/lib/components/AuthBar/authBar.js +6 -4
- package/lib/components/CartPage/ProductListing/EditModal/__tests__/__snapshots__/productForm.spec.js.snap +2 -2
- package/lib/components/CartPage/__tests__/__snapshots__/cartPage.spec.js.snap +12 -6
- package/lib/components/CartPage/cartPage.js +12 -6
- package/lib/components/CheckoutPage/ItemsReview/__tests__/__snapshots__/itemsReview.spec.js.snap +3 -3
- package/lib/components/CheckoutPage/ItemsReview/itemsReview.js +1 -16
- package/lib/components/CheckoutPage/OrderConfirmationPage/__fixtures__/cartItems.js +33 -0
- package/lib/components/CheckoutPage/OrderConfirmationPage/__tests__/__snapshots__/orderConfirmationPage.spec.js.snap +135 -1
- package/lib/components/CheckoutPage/OrderConfirmationPage/__tests__/orderConfirmationPage.spec.js +40 -3
- package/lib/components/CheckoutPage/OrderConfirmationPage/orderConfirmationPage.js +118 -103
- package/lib/components/CheckoutPage/checkoutPage.js +15 -7
- package/lib/components/CreateAccount/__tests__/createAccount.spec.js +30 -0
- package/lib/components/FilterModal/CurrentFilters/__tests__/currentFilter.spec.js +6 -1
- package/lib/components/FilterModal/CurrentFilters/currentFilter.js +11 -1
- package/lib/components/FilterModal/FilterList/__tests__/filterList.spec.js +16 -3
- package/lib/components/FilterModal/FilterList/filterList.js +81 -31
- package/lib/components/FilterModal/filterBlock.js +2 -1
- package/lib/components/FilterSidebar/__tests__/filterSidebar.spec.js +51 -19
- package/lib/components/FilterSidebar/filterSidebar.js +36 -2
- package/lib/components/Gallery/__tests__/__snapshots__/gallery.spec.js.snap +2 -2
- package/lib/components/Gallery/__tests__/__snapshots__/item.spec.js.snap +3 -3
- package/lib/components/MiniCart/ProductList/__tests__/__snapshots__/item.spec.js.snap +4 -4
- package/lib/components/MiniCart/miniCart.js +16 -12
- package/lib/components/OrderHistoryPage/OrderDetails/__tests__/__snapshots__/item.spec.js.snap +1 -1
- package/lib/components/OrderHistoryPage/collapsedImageGallery.js +3 -0
- package/lib/components/ProductImageCarousel/__tests__/__snapshots__/carousel.spec.js.snap +7 -7
- package/lib/components/ProductImageCarousel/__tests__/__snapshots__/thumbnail.spec.js.snap +4 -4
- package/lib/components/RangeSlider/rangeSlider.js +127 -0
- package/lib/components/RangeSlider/rangeSlider.module.css +76 -0
- package/lib/components/SearchBar/__tests__/__snapshots__/suggestedProduct.spec.js.snap +1 -1
- package/lib/components/SignIn/__tests__/signIn.spec.js +31 -0
- package/lib/components/SignIn/signIn.js +0 -2
- package/lib/components/WishlistPage/__tests__/__snapshots__/wishlistItem.spec.js.snap +2 -2
- package/lib/defaultRoutes.json +6 -0
- package/package.json +4 -4
- package/upward.yml +31 -1
|
@@ -3,6 +3,8 @@ import { FormattedMessage, useIntl } from 'react-intl';
|
|
|
3
3
|
import { object, shape, string } from 'prop-types';
|
|
4
4
|
import { useOrderConfirmationPage } from '@magento/peregrine/lib/talons/CheckoutPage/OrderConfirmationPage/useOrderConfirmationPage';
|
|
5
5
|
|
|
6
|
+
import { useLocation } from 'react-router-dom';
|
|
7
|
+
import { fullPageLoadingIndicator } from '../../LoadingIndicator';
|
|
6
8
|
import { useStyle } from '../../../classify';
|
|
7
9
|
import { StoreTitle } from '../../../components/Head';
|
|
8
10
|
import CreateAccount from './createAccount';
|
|
@@ -11,34 +13,19 @@ import defaultClasses from './orderConfirmationPage.module.css';
|
|
|
11
13
|
|
|
12
14
|
const OrderConfirmationPage = props => {
|
|
13
15
|
const classes = useStyle(defaultClasses, props.classes);
|
|
14
|
-
const
|
|
16
|
+
const location = useLocation();
|
|
17
|
+
const data = props.data;
|
|
18
|
+
const orderNumber = props.orderNumber || location.state.orderNumber;
|
|
19
|
+
const cartItems = data ? data.cart.items : location.state.items;
|
|
20
|
+
|
|
15
21
|
const { formatMessage } = useIntl();
|
|
16
22
|
|
|
17
23
|
const talonProps = useOrderConfirmationPage({
|
|
18
|
-
data
|
|
24
|
+
data,
|
|
25
|
+
orderNumber
|
|
19
26
|
});
|
|
20
27
|
|
|
21
|
-
const { flatData, isSignedIn } = talonProps;
|
|
22
|
-
|
|
23
|
-
const {
|
|
24
|
-
city,
|
|
25
|
-
country,
|
|
26
|
-
email,
|
|
27
|
-
firstname,
|
|
28
|
-
lastname,
|
|
29
|
-
postcode,
|
|
30
|
-
region,
|
|
31
|
-
shippingMethod,
|
|
32
|
-
street
|
|
33
|
-
} = flatData;
|
|
34
|
-
|
|
35
|
-
const streetRows = street.map((row, index) => {
|
|
36
|
-
return (
|
|
37
|
-
<span key={index} className={classes.addressStreet}>
|
|
38
|
-
{row}
|
|
39
|
-
</span>
|
|
40
|
-
);
|
|
41
|
-
});
|
|
28
|
+
const { flatData, isSignedIn, loading } = talonProps;
|
|
42
29
|
|
|
43
30
|
useEffect(() => {
|
|
44
31
|
const { scrollTo } = globalThis;
|
|
@@ -52,90 +39,118 @@ const OrderConfirmationPage = props => {
|
|
|
52
39
|
}
|
|
53
40
|
}, []);
|
|
54
41
|
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
42
|
+
if (!flatData || loading) {
|
|
43
|
+
return fullPageLoadingIndicator;
|
|
44
|
+
} else {
|
|
45
|
+
const {
|
|
46
|
+
city,
|
|
47
|
+
country,
|
|
48
|
+
email,
|
|
49
|
+
firstname,
|
|
50
|
+
lastname,
|
|
51
|
+
postcode,
|
|
52
|
+
region,
|
|
53
|
+
shippingMethod,
|
|
54
|
+
street
|
|
55
|
+
} = flatData;
|
|
62
56
|
|
|
63
|
-
|
|
64
|
-
|
|
57
|
+
const streetRows = street.map((row, index) => {
|
|
58
|
+
return (
|
|
59
|
+
<span key={index} className={classes.addressStreet}>
|
|
60
|
+
{row}
|
|
61
|
+
</span>
|
|
62
|
+
);
|
|
63
|
+
});
|
|
65
64
|
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
{
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
<
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
<
|
|
65
|
+
const createAccountForm = !isSignedIn ? (
|
|
66
|
+
<CreateAccount
|
|
67
|
+
firstname={firstname}
|
|
68
|
+
lastname={lastname}
|
|
69
|
+
email={email}
|
|
70
|
+
/>
|
|
71
|
+
) : null;
|
|
72
|
+
|
|
73
|
+
const nameString = `${firstname} ${lastname}`;
|
|
74
|
+
const additionalAddressString = `${city}, ${region} ${postcode} ${country}`;
|
|
75
|
+
|
|
76
|
+
return (
|
|
77
|
+
<div className={classes.root} data-cy="OrderConfirmationPage-root">
|
|
78
|
+
<StoreTitle>
|
|
79
|
+
{formatMessage({
|
|
80
|
+
id: 'checkoutPage.titleReceipt',
|
|
81
|
+
defaultMessage: 'Receipt'
|
|
82
|
+
})}
|
|
83
|
+
</StoreTitle>
|
|
84
|
+
<div className={classes.mainContainer}>
|
|
85
|
+
<h2
|
|
86
|
+
data-cy="OrderConfirmationPage-header"
|
|
87
|
+
className={classes.heading}
|
|
88
|
+
>
|
|
89
|
+
<FormattedMessage
|
|
90
|
+
id={'checkoutPage.thankYou'}
|
|
91
|
+
defaultMessage={'Thank you for your order!'}
|
|
92
|
+
/>
|
|
93
|
+
</h2>
|
|
94
|
+
<div
|
|
95
|
+
data-cy="OrderConfirmationPage-orderNumber"
|
|
96
|
+
className={classes.orderNumber}
|
|
97
|
+
>
|
|
98
|
+
<FormattedMessage
|
|
99
|
+
id={'checkoutPage.orderNumber'}
|
|
100
|
+
defaultMessage={'Order Number: {orderNumber}'}
|
|
101
|
+
values={{ orderNumber }}
|
|
102
|
+
/>
|
|
103
|
+
</div>
|
|
104
|
+
<div
|
|
105
|
+
data-cy="OrderConfirmationPage-shippingInfoHeading"
|
|
106
|
+
className={classes.shippingInfoHeading}
|
|
107
|
+
>
|
|
108
|
+
<FormattedMessage
|
|
109
|
+
id={'global.shippingInformation'}
|
|
110
|
+
defaultMessage={'Shipping Information'}
|
|
111
|
+
/>
|
|
112
|
+
</div>
|
|
113
|
+
<div className={classes.shippingInfo}>
|
|
114
|
+
<span className={classes.email}>{email}</span>
|
|
115
|
+
<span className={classes.name}>{nameString}</span>
|
|
116
|
+
{streetRows}
|
|
117
|
+
<span className={classes.addressAdditional}>
|
|
118
|
+
{additionalAddressString}
|
|
119
|
+
</span>
|
|
120
|
+
</div>
|
|
121
|
+
<div
|
|
122
|
+
data-cy="OrderConfirmationPage-shippingMethodHeading"
|
|
123
|
+
className={classes.shippingMethodHeading}
|
|
124
|
+
>
|
|
125
|
+
<FormattedMessage
|
|
126
|
+
id={'global.shippingMethod'}
|
|
127
|
+
defaultMessage={'Shipping Method'}
|
|
128
|
+
/>
|
|
129
|
+
</div>
|
|
130
|
+
<div className={classes.shippingMethod}>
|
|
131
|
+
{shippingMethod}
|
|
132
|
+
</div>
|
|
133
|
+
<div className={classes.itemsReview}>
|
|
134
|
+
<ItemsReview items={cartItems} />
|
|
135
|
+
</div>
|
|
136
|
+
<div
|
|
137
|
+
data-cy="OrderConfirmationPage-additionalText"
|
|
138
|
+
className={classes.additionalText}
|
|
139
|
+
>
|
|
140
|
+
<FormattedMessage
|
|
141
|
+
id={'checkoutPage.additionalText'}
|
|
142
|
+
defaultMessage={
|
|
143
|
+
'You will also receive an email with the details and we will let you know when your order has shipped.'
|
|
144
|
+
}
|
|
145
|
+
/>
|
|
146
|
+
</div>
|
|
123
147
|
</div>
|
|
124
|
-
<div
|
|
125
|
-
|
|
126
|
-
className={classes.additionalText}
|
|
127
|
-
>
|
|
128
|
-
<FormattedMessage
|
|
129
|
-
id={'checkoutPage.additionalText'}
|
|
130
|
-
defaultMessage={
|
|
131
|
-
'You will also receive an email with the details and we will let you know when your order has shipped.'
|
|
132
|
-
}
|
|
133
|
-
/>
|
|
148
|
+
<div className={classes.sidebarContainer}>
|
|
149
|
+
{createAccountForm}
|
|
134
150
|
</div>
|
|
135
151
|
</div>
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
);
|
|
152
|
+
);
|
|
153
|
+
}
|
|
139
154
|
};
|
|
140
155
|
|
|
141
156
|
export default OrderConfirmationPage;
|
|
@@ -157,6 +172,6 @@ OrderConfirmationPage.propTypes = {
|
|
|
157
172
|
additionalText: string,
|
|
158
173
|
sidebarContainer: string
|
|
159
174
|
}),
|
|
160
|
-
data: object
|
|
175
|
+
data: object,
|
|
161
176
|
orderNumber: string
|
|
162
177
|
};
|
|
@@ -2,14 +2,13 @@ import React, { Fragment, useEffect } from 'react';
|
|
|
2
2
|
import { shape, string } from 'prop-types';
|
|
3
3
|
import { FormattedMessage, useIntl } from 'react-intl';
|
|
4
4
|
import { AlertCircle as AlertCircleIcon } from 'react-feather';
|
|
5
|
-
import { Link } from 'react-router-dom';
|
|
5
|
+
import { Link, useHistory } from 'react-router-dom';
|
|
6
6
|
|
|
7
7
|
import { useWindowSize, useToasts } from '@magento/peregrine';
|
|
8
8
|
import {
|
|
9
9
|
CHECKOUT_STEP,
|
|
10
10
|
useCheckoutPage
|
|
11
11
|
} from '@magento/peregrine/lib/talons/CheckoutPage/useCheckoutPage';
|
|
12
|
-
|
|
13
12
|
import { useStyle } from '../../classify';
|
|
14
13
|
import Button from '../Button';
|
|
15
14
|
import { StoreTitle } from '../Head';
|
|
@@ -25,8 +24,8 @@ import payments from './PaymentInformation/paymentMethodCollection';
|
|
|
25
24
|
import PriceAdjustments from './PriceAdjustments';
|
|
26
25
|
import ShippingMethod from './ShippingMethod';
|
|
27
26
|
import ShippingInformation from './ShippingInformation';
|
|
28
|
-
import OrderConfirmationPage from './OrderConfirmationPage';
|
|
29
27
|
import ItemsReview from './ItemsReview';
|
|
28
|
+
import OrderConfirmationPage from './OrderConfirmationPage';
|
|
30
29
|
import GoogleReCaptcha from '../GoogleReCaptcha';
|
|
31
30
|
|
|
32
31
|
import defaultClasses from './checkoutPage.module.css';
|
|
@@ -35,6 +34,7 @@ import ScrollAnchor from '../ScrollAnchor/scrollAnchor';
|
|
|
35
34
|
const errorIcon = <Icon src={AlertCircleIcon} size={20} />;
|
|
36
35
|
|
|
37
36
|
const CheckoutPage = props => {
|
|
37
|
+
const history = useHistory();
|
|
38
38
|
const { classes: propClasses } = props;
|
|
39
39
|
const { formatMessage } = useIntl();
|
|
40
40
|
const talonProps = useCheckoutPage();
|
|
@@ -58,8 +58,8 @@ const CheckoutPage = props => {
|
|
|
58
58
|
isGuestCheckout,
|
|
59
59
|
isLoading,
|
|
60
60
|
isUpdating,
|
|
61
|
-
orderDetailsData,
|
|
62
61
|
orderDetailsLoading,
|
|
62
|
+
orderDetailsData,
|
|
63
63
|
orderNumber,
|
|
64
64
|
placeOrderLoading,
|
|
65
65
|
placeOrderButtonClicked,
|
|
@@ -83,7 +83,15 @@ const CheckoutPage = props => {
|
|
|
83
83
|
} = talonProps;
|
|
84
84
|
|
|
85
85
|
const [, { addToast }] = useToasts();
|
|
86
|
-
|
|
86
|
+
const orderCount = localStorage.getItem('orderCount');
|
|
87
|
+
useEffect(() => {
|
|
88
|
+
if (isGuestCheckout && !orderDetailsData) {
|
|
89
|
+
if (orderCount === '1') {
|
|
90
|
+
history.push('/');
|
|
91
|
+
localStorage.setItem('orderCount', '0');
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
}, [isGuestCheckout, history, orderDetailsData, orderCount]);
|
|
87
95
|
useEffect(() => {
|
|
88
96
|
if (hasError) {
|
|
89
97
|
const message =
|
|
@@ -125,7 +133,7 @@ const CheckoutPage = props => {
|
|
|
125
133
|
defaultMessage: 'Checkout'
|
|
126
134
|
});
|
|
127
135
|
|
|
128
|
-
if (
|
|
136
|
+
if (isGuestCheckout && orderDetailsData && orderNumber) {
|
|
129
137
|
return (
|
|
130
138
|
<OrderConfirmationPage
|
|
131
139
|
data={orderDetailsData}
|
|
@@ -265,7 +273,7 @@ const CheckoutPage = props => {
|
|
|
265
273
|
const itemsReview =
|
|
266
274
|
checkoutStep === CHECKOUT_STEP.REVIEW ? (
|
|
267
275
|
<div className={classes.items_review_container}>
|
|
268
|
-
<ItemsReview />
|
|
276
|
+
<ItemsReview items={cartItems} />
|
|
269
277
|
</div>
|
|
270
278
|
) : null;
|
|
271
279
|
|
|
@@ -4,6 +4,8 @@ import { createTestInstance } from '@magento/peregrine';
|
|
|
4
4
|
|
|
5
5
|
import CreateAccount from '../createAccount';
|
|
6
6
|
|
|
7
|
+
import { useHistory, useLocation } from 'react-router-dom';
|
|
8
|
+
|
|
7
9
|
jest.mock('@apollo/client', () => ({
|
|
8
10
|
gql: jest.fn(),
|
|
9
11
|
useApolloClient: jest.fn().mockImplementation(() => {}),
|
|
@@ -24,6 +26,16 @@ jest.mock('@apollo/client', () => ({
|
|
|
24
26
|
}))
|
|
25
27
|
}));
|
|
26
28
|
|
|
29
|
+
// Mocking the react-router hooks
|
|
30
|
+
|
|
31
|
+
jest.mock('react-router-dom', () => ({
|
|
32
|
+
...jest.requireActual('react-router-dom'),
|
|
33
|
+
|
|
34
|
+
useHistory: jest.fn(),
|
|
35
|
+
|
|
36
|
+
useLocation: jest.fn()
|
|
37
|
+
}));
|
|
38
|
+
|
|
27
39
|
jest.mock('../../../util/formValidators');
|
|
28
40
|
jest.mock('@magento/peregrine/lib/context/user', () => {
|
|
29
41
|
const userState = {
|
|
@@ -58,6 +70,24 @@ jest.mock('@magento/peregrine/lib/hooks/useAwaitQuery', () => {
|
|
|
58
70
|
return { useAwaitQuery };
|
|
59
71
|
});
|
|
60
72
|
|
|
73
|
+
// Mocking useLocation and useHistory for the tests
|
|
74
|
+
|
|
75
|
+
beforeEach(() => {
|
|
76
|
+
useHistory.mockReturnValue({
|
|
77
|
+
push: jest.fn() // mock any methods you need from useHistory
|
|
78
|
+
});
|
|
79
|
+
|
|
80
|
+
useLocation.mockReturnValue({
|
|
81
|
+
pathname: '/mock-path', // mock the location properties
|
|
82
|
+
|
|
83
|
+
search: '',
|
|
84
|
+
|
|
85
|
+
hash: '',
|
|
86
|
+
|
|
87
|
+
state: null
|
|
88
|
+
});
|
|
89
|
+
});
|
|
90
|
+
|
|
61
91
|
jest.mock('@magento/peregrine/lib/context/eventing', () => ({
|
|
62
92
|
useEventingContext: jest.fn().mockReturnValue([{}, { dispatch: jest.fn() }])
|
|
63
93
|
}));
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import { act } from 'react-test-renderer';
|
|
3
|
+
import { MemoryRouter } from 'react-router-dom';
|
|
3
4
|
|
|
4
5
|
import { createTestInstance } from '@magento/peregrine';
|
|
5
6
|
|
|
@@ -19,7 +20,11 @@ jest.mock('../../../Trigger', () => props => <mock-Trigger {...props} />);
|
|
|
19
20
|
let inputProps = {};
|
|
20
21
|
|
|
21
22
|
const Component = () => {
|
|
22
|
-
return
|
|
23
|
+
return (
|
|
24
|
+
<MemoryRouter>
|
|
25
|
+
<CurrentFilter {...inputProps} />
|
|
26
|
+
</MemoryRouter>
|
|
27
|
+
);
|
|
23
28
|
};
|
|
24
29
|
|
|
25
30
|
const givenDefaultValues = () => {
|
|
@@ -2,6 +2,7 @@ import React, { useCallback } from 'react';
|
|
|
2
2
|
import { useIntl } from 'react-intl';
|
|
3
3
|
import { shape, string, func } from 'prop-types';
|
|
4
4
|
import { X as Remove } from 'react-feather';
|
|
5
|
+
import { useHistory, useLocation } from 'react-router-dom';
|
|
5
6
|
|
|
6
7
|
import { useStyle } from '../../../classify';
|
|
7
8
|
import Icon from '../../Icon';
|
|
@@ -12,13 +13,22 @@ const CurrentFilter = props => {
|
|
|
12
13
|
const { group, item, removeItem, onRemove } = props;
|
|
13
14
|
const classes = useStyle(defaultClasses, props.classes);
|
|
14
15
|
const { formatMessage } = useIntl();
|
|
16
|
+
const location = useLocation();
|
|
17
|
+
const history = useHistory();
|
|
15
18
|
|
|
16
19
|
const handleClick = useCallback(() => {
|
|
17
20
|
removeItem({ group, item });
|
|
18
21
|
if (typeof onRemove === 'function') {
|
|
19
22
|
onRemove(group, item);
|
|
20
23
|
}
|
|
21
|
-
|
|
24
|
+
|
|
25
|
+
if (group == 'price') {
|
|
26
|
+
// preserve all existing params
|
|
27
|
+
const params = new URLSearchParams(location.search);
|
|
28
|
+
params.delete('price[filter]');
|
|
29
|
+
history.replace({ search: params.toString() });
|
|
30
|
+
}
|
|
31
|
+
}, [group, item, removeItem, onRemove, history, location.search]);
|
|
22
32
|
|
|
23
33
|
const ariaLabel = formatMessage(
|
|
24
34
|
{
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
+
import { MemoryRouter } from 'react-router-dom';
|
|
2
3
|
|
|
3
4
|
import { createTestInstance } from '@magento/peregrine';
|
|
4
5
|
|
|
@@ -67,7 +68,11 @@ describe('#FilterList', () => {
|
|
|
67
68
|
});
|
|
68
69
|
|
|
69
70
|
it('renders without show more button', () => {
|
|
70
|
-
const { root } = createTestInstance(
|
|
71
|
+
const { root } = createTestInstance(
|
|
72
|
+
<MemoryRouter>
|
|
73
|
+
<Component />
|
|
74
|
+
</MemoryRouter>
|
|
75
|
+
);
|
|
71
76
|
|
|
72
77
|
expect(root.findAllByType(FilterItem)).toHaveLength(2);
|
|
73
78
|
expect(() => root.findByType('button')).toThrow();
|
|
@@ -76,7 +81,11 @@ describe('#FilterList', () => {
|
|
|
76
81
|
it('renders with show more button', () => {
|
|
77
82
|
givenShowMore();
|
|
78
83
|
|
|
79
|
-
const { root } = createTestInstance(
|
|
84
|
+
const { root } = createTestInstance(
|
|
85
|
+
<MemoryRouter>
|
|
86
|
+
<Component />
|
|
87
|
+
</MemoryRouter>
|
|
88
|
+
);
|
|
80
89
|
|
|
81
90
|
expect(() => root.findByType('button')).not.toThrow();
|
|
82
91
|
expect(root.findByType('button').children[0]).toBe(mockShowMore);
|
|
@@ -86,7 +95,11 @@ describe('#FilterList', () => {
|
|
|
86
95
|
givenShowMore();
|
|
87
96
|
givenExpanded();
|
|
88
97
|
|
|
89
|
-
const { root } = createTestInstance(
|
|
98
|
+
const { root } = createTestInstance(
|
|
99
|
+
<MemoryRouter>
|
|
100
|
+
<Component />
|
|
101
|
+
</MemoryRouter>
|
|
102
|
+
);
|
|
90
103
|
|
|
91
104
|
expect(() => root.findByType('button')).not.toThrow();
|
|
92
105
|
expect(root.findByType('button').children[0]).toBe(mockShowLess);
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import React, { Fragment, useMemo } from 'react';
|
|
1
|
+
import React, { Fragment, useMemo, useCallback } from 'react';
|
|
2
2
|
import { array, func, number, shape, string } from 'prop-types';
|
|
3
3
|
import { useIntl } from 'react-intl';
|
|
4
4
|
import setValidator from '@magento/peregrine/lib/validators/set';
|
|
@@ -8,6 +8,8 @@ import { useStyle } from '../../../classify';
|
|
|
8
8
|
import FilterItem from './filterItem';
|
|
9
9
|
import defaultClasses from './filterList.module.css';
|
|
10
10
|
import FilterItemRadioGroup from './filterItemRadioGroup';
|
|
11
|
+
import RangeSlider from '../../RangeSlider/rangeSlider';
|
|
12
|
+
import { useHistory, useLocation } from 'react-router-dom';
|
|
11
13
|
|
|
12
14
|
const labels = new WeakMap();
|
|
13
15
|
|
|
@@ -22,13 +24,46 @@ const FilterList = props => {
|
|
|
22
24
|
items,
|
|
23
25
|
onApply
|
|
24
26
|
} = props;
|
|
27
|
+
const { pathname, search } = useLocation();
|
|
28
|
+
const history = useHistory();
|
|
25
29
|
const classes = useStyle(defaultClasses, props.classes);
|
|
26
30
|
const talonProps = useFilterList({ filterState, items, itemCountToShow });
|
|
27
31
|
const { isListExpanded, handleListToggle } = talonProps;
|
|
28
32
|
const { formatMessage } = useIntl();
|
|
29
33
|
|
|
30
|
-
|
|
31
|
-
|
|
34
|
+
if (name === 'Price') {
|
|
35
|
+
var minRange = Number(items[0].value.split('_')[0]);
|
|
36
|
+
var maxRange = Number(items[items.length - 1].value.split('_')[1]);
|
|
37
|
+
if (filterState !== undefined) {
|
|
38
|
+
const filterArray = [...filterState];
|
|
39
|
+
var currentMinVal = Number(filterArray[0].value.split('_')[0]);
|
|
40
|
+
var currentMaxVal = Number(filterArray[0].value.split('_')[1]);
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
const handleChange = useCallback(
|
|
45
|
+
newValue => {
|
|
46
|
+
const test = String(search).split('&');
|
|
47
|
+
const filters = test.filter(element => {
|
|
48
|
+
return !element.includes('price');
|
|
49
|
+
});
|
|
50
|
+
const newSearch = filters.join('&');
|
|
51
|
+
const nextParams = new URLSearchParams(newSearch);
|
|
52
|
+
|
|
53
|
+
const DELIMITER = ',';
|
|
54
|
+
const title = String(newValue.min) + '-' + String(newValue.max);
|
|
55
|
+
const value = String(newValue.min) + '_' + String(newValue.max);
|
|
56
|
+
nextParams.append(
|
|
57
|
+
`${group}[filter]`,
|
|
58
|
+
`${title}${DELIMITER}${value}`
|
|
59
|
+
);
|
|
60
|
+
|
|
61
|
+
history.push({ pathname, search: String(nextParams) });
|
|
62
|
+
},
|
|
63
|
+
[group, history, pathname, search]
|
|
64
|
+
);
|
|
65
|
+
|
|
66
|
+
// Memoize item creation
|
|
32
67
|
const itemElements = useMemo(() => {
|
|
33
68
|
if (filterFrontendInput === 'boolean') {
|
|
34
69
|
const key = `item-${group}`;
|
|
@@ -51,36 +86,46 @@ const FilterList = props => {
|
|
|
51
86
|
);
|
|
52
87
|
}
|
|
53
88
|
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
const element = (
|
|
64
|
-
<li
|
|
65
|
-
key={key}
|
|
66
|
-
className={classes.item}
|
|
67
|
-
data-cy="FilterList-item"
|
|
68
|
-
>
|
|
69
|
-
<FilterItem
|
|
70
|
-
filterApi={filterApi}
|
|
71
|
-
filterState={filterState}
|
|
72
|
-
group={group}
|
|
73
|
-
item={item}
|
|
74
|
-
onApply={onApply}
|
|
89
|
+
if (name === 'Price') {
|
|
90
|
+
return (
|
|
91
|
+
<div className={classes.root}>
|
|
92
|
+
<RangeSlider
|
|
93
|
+
min={minRange}
|
|
94
|
+
max={maxRange}
|
|
95
|
+
initialMin={currentMinVal}
|
|
96
|
+
initialMax={currentMaxVal}
|
|
97
|
+
onChange={handleChange}
|
|
75
98
|
/>
|
|
76
|
-
</
|
|
99
|
+
</div>
|
|
77
100
|
);
|
|
101
|
+
} else {
|
|
102
|
+
return items.map((item, index) => {
|
|
103
|
+
const { title, value } = item;
|
|
104
|
+
const key = `item-${group}-${value}`;
|
|
105
|
+
|
|
106
|
+
if (!isListExpanded && index >= itemCountToShow) {
|
|
107
|
+
return null;
|
|
108
|
+
}
|
|
78
109
|
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
110
|
+
const element = (
|
|
111
|
+
<li
|
|
112
|
+
key={key}
|
|
113
|
+
className={classes.item}
|
|
114
|
+
data-cy="FilterList-item"
|
|
115
|
+
>
|
|
116
|
+
<FilterItem
|
|
117
|
+
filterApi={filterApi}
|
|
118
|
+
filterState={filterState}
|
|
119
|
+
group={group}
|
|
120
|
+
item={item}
|
|
121
|
+
onApply={onApply}
|
|
122
|
+
/>
|
|
123
|
+
</li>
|
|
124
|
+
);
|
|
125
|
+
labels.set(element, title.toUpperCase());
|
|
126
|
+
return element;
|
|
127
|
+
});
|
|
128
|
+
}
|
|
84
129
|
}, [
|
|
85
130
|
classes,
|
|
86
131
|
filterApi,
|
|
@@ -91,7 +136,12 @@ const FilterList = props => {
|
|
|
91
136
|
items,
|
|
92
137
|
isListExpanded,
|
|
93
138
|
itemCountToShow,
|
|
94
|
-
onApply
|
|
139
|
+
onApply,
|
|
140
|
+
minRange,
|
|
141
|
+
maxRange,
|
|
142
|
+
currentMinVal,
|
|
143
|
+
currentMaxVal,
|
|
144
|
+
handleChange
|
|
95
145
|
]);
|
|
96
146
|
|
|
97
147
|
const showMoreLessItem = useMemo(() => {
|