@salesforce/retail-react-app 2.3.1 → 2.4.0-dev
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/CHANGELOG.md +11 -0
- package/app/components/product-item/index.test.js +1 -1
- package/app/components/promo-code/index.jsx +25 -28
- package/app/pages/account/index.jsx +1 -1
- package/app/pages/account/profile.jsx +21 -30
- package/app/pages/account/wishlist/index.jsx +1 -1
- package/app/pages/cart/index.jsx +1 -1
- package/app/pages/checkout/partials/payment.jsx +2 -2
- package/app/pages/checkout/partials/shipping-options.jsx +1 -1
- package/app/pages/product-detail/index.jsx +1 -1
- package/app/pages/product-list/index.jsx +4 -1
- package/app/utils/url.js +1 -4
- package/package.json +7 -7
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,14 @@
|
|
|
1
|
+
## v2.4.0-dev (Jan 22, 2024)
|
|
2
|
+
|
|
3
|
+
### Bug Fixes
|
|
4
|
+
|
|
5
|
+
- Fix promo codes not being properly applied in cart [#1692](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/1692)
|
|
6
|
+
- Fix checkout shipping method fetching [#1693](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/1693)
|
|
7
|
+
- Fix invalid query params warnings [#1655](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/1655)
|
|
8
|
+
- Fix internal server error on account pages [#1675](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/1675)
|
|
9
|
+
- Fix `product-item` component imports to ensure that it is overridable. [#1672](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/1672)
|
|
10
|
+
- Fix locale selector navigating back to default locale [#1670](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/1670)
|
|
11
|
+
|
|
1
12
|
## v2.3.1 (Jan 23, 2024)
|
|
2
13
|
|
|
3
14
|
### Bug Fixes
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
* For full license text, see the LICENSE file in the repo root or https://opensource.org/licenses/BSD-3-Clause
|
|
6
6
|
*/
|
|
7
7
|
import React from 'react'
|
|
8
|
-
import ProductItem from '@salesforce/retail-react-app/app/components/product-item
|
|
8
|
+
import ProductItem from '@salesforce/retail-react-app/app/components/product-item'
|
|
9
9
|
import {mockedCustomerProductListsDetails} from '@salesforce/retail-react-app/app/mocks/mock-data'
|
|
10
10
|
import {renderWithProviders} from '@salesforce/retail-react-app/app/utils/test-utils'
|
|
11
11
|
import {screen} from '@testing-library/react'
|
|
@@ -33,38 +33,35 @@ export const usePromoCode = () => {
|
|
|
33
33
|
const removePromoCodeMutation = useShopperBasketsMutation('removeCouponFromBasket')
|
|
34
34
|
|
|
35
35
|
const submitPromoCode = async ({code}) => {
|
|
36
|
-
|
|
37
|
-
{
|
|
36
|
+
try {
|
|
37
|
+
await applyPromoCodeMutation.mutateAsync({
|
|
38
38
|
parameters: {basketId: basket?.basketId},
|
|
39
39
|
body: {
|
|
40
40
|
code
|
|
41
41
|
}
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
}
|
|
66
|
-
}
|
|
67
|
-
)
|
|
42
|
+
})
|
|
43
|
+
|
|
44
|
+
form.reset({code: ''})
|
|
45
|
+
|
|
46
|
+
toast({
|
|
47
|
+
title: formatMessage({
|
|
48
|
+
defaultMessage: 'Promotion applied',
|
|
49
|
+
id: 'use_promocode.info.promo_applied'
|
|
50
|
+
}),
|
|
51
|
+
status: 'success',
|
|
52
|
+
position: 'top-right',
|
|
53
|
+
isClosable: true
|
|
54
|
+
})
|
|
55
|
+
} catch (e) {
|
|
56
|
+
form.setError('code', {
|
|
57
|
+
type: 'manual',
|
|
58
|
+
message: formatMessage({
|
|
59
|
+
defaultMessage:
|
|
60
|
+
'Check the code and try again, it may already be applied or the promo has expired.',
|
|
61
|
+
id: 'use_promocode.error.check_the_code'
|
|
62
|
+
})
|
|
63
|
+
})
|
|
64
|
+
}
|
|
68
65
|
}
|
|
69
66
|
|
|
70
67
|
const removePromoCode = async (couponItemId) => {
|
|
@@ -110,11 +110,11 @@ const Account = () => {
|
|
|
110
110
|
// If we have customer data and they are not registered, push to login page
|
|
111
111
|
// Using Redirect allows us to store the directed page to location
|
|
112
112
|
// so we can direct users back after they are successfully log in
|
|
113
|
-
// we don't want redirect on server side
|
|
114
113
|
if (customerType !== null && !isRegistered && onClient) {
|
|
115
114
|
const path = buildUrl('/login')
|
|
116
115
|
return <Redirect to={{pathname: path, state: {directedFrom: '/account'}}} />
|
|
117
116
|
}
|
|
117
|
+
|
|
118
118
|
return (
|
|
119
119
|
<Box
|
|
120
120
|
data-testid={isRegistered && isHydrated() ? 'account-page' : 'account-page-skeleton'}
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
* For full license text, see the LICENSE file in the repo root or https://opensource.org/licenses/BSD-3-Clause
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
|
-
import React, {useEffect, useRef, useState} from 'react'
|
|
8
|
+
import React, {forwardRef, useEffect, useRef, useState} from 'react'
|
|
9
9
|
import {FormattedMessage, useIntl} from 'react-intl'
|
|
10
10
|
import {
|
|
11
11
|
Alert,
|
|
@@ -42,7 +42,7 @@ import {useCurrentCustomer} from '@salesforce/retail-react-app/app/hooks/use-cur
|
|
|
42
42
|
* the bounding element will affect the contents size.
|
|
43
43
|
*/
|
|
44
44
|
// eslint-disable-next-line react/prop-types
|
|
45
|
-
const Skeleton = ({children, height, width, ...rest}) => {
|
|
45
|
+
const Skeleton = forwardRef(({children, height, width, ...rest}, ref) => {
|
|
46
46
|
const {data: customer} = useCurrentCustomer()
|
|
47
47
|
const {isRegistered} = customer
|
|
48
48
|
const size = !isRegistered
|
|
@@ -52,15 +52,17 @@ const Skeleton = ({children, height, width, ...rest}) => {
|
|
|
52
52
|
}
|
|
53
53
|
: {}
|
|
54
54
|
return (
|
|
55
|
-
<ChakraSkeleton isLoaded={!customer.isLoading} {...rest} {...size}>
|
|
55
|
+
<ChakraSkeleton ref={ref} isLoaded={!customer.isLoading} {...rest} {...size}>
|
|
56
56
|
{children}
|
|
57
57
|
</ChakraSkeleton>
|
|
58
58
|
)
|
|
59
|
-
}
|
|
59
|
+
})
|
|
60
|
+
|
|
61
|
+
Skeleton.displayName = 'Skeleton'
|
|
60
62
|
|
|
61
63
|
const ProfileCard = () => {
|
|
62
64
|
const {formatMessage} = useIntl()
|
|
63
|
-
|
|
65
|
+
const headingRef = useRef(null)
|
|
64
66
|
const {data: customer} = useCurrentCustomer()
|
|
65
67
|
const {isRegistered, customerId} = customer
|
|
66
68
|
|
|
@@ -87,14 +89,6 @@ const ProfileCard = () => {
|
|
|
87
89
|
})
|
|
88
90
|
}, [customer?.firstName, customer?.lastName, customer?.email, customer?.phoneHome])
|
|
89
91
|
|
|
90
|
-
const profileHeadingText = formatMessage({
|
|
91
|
-
defaultMessage: 'My Profile',
|
|
92
|
-
id: 'profile_card.title.my_profile'
|
|
93
|
-
})
|
|
94
|
-
const profileHeading = Array.from(document.querySelectorAll('h2')).find(
|
|
95
|
-
(element) => element.textContent === profileHeadingText
|
|
96
|
-
)
|
|
97
|
-
|
|
98
92
|
const submit = async (values) => {
|
|
99
93
|
try {
|
|
100
94
|
form.clearErrors()
|
|
@@ -126,7 +120,7 @@ const ProfileCard = () => {
|
|
|
126
120
|
status: 'success',
|
|
127
121
|
isClosable: true
|
|
128
122
|
})
|
|
129
|
-
|
|
123
|
+
headingRef?.current?.focus()
|
|
130
124
|
}
|
|
131
125
|
}
|
|
132
126
|
)
|
|
@@ -139,8 +133,11 @@ const ProfileCard = () => {
|
|
|
139
133
|
<ToggleCard
|
|
140
134
|
id="my-profile"
|
|
141
135
|
title={
|
|
142
|
-
<Skeleton height="30px" width="120px">
|
|
143
|
-
|
|
136
|
+
<Skeleton ref={headingRef} tabIndex="-1" height="30px" width="120px">
|
|
137
|
+
<FormattedMessage
|
|
138
|
+
defaultMessage="My Profile"
|
|
139
|
+
id="profile_card.title.my_profile"
|
|
140
|
+
/>
|
|
144
141
|
</Skeleton>
|
|
145
142
|
}
|
|
146
143
|
editing={isEditing}
|
|
@@ -164,7 +161,8 @@ const ProfileCard = () => {
|
|
|
164
161
|
<FormActionButtons
|
|
165
162
|
onCancel={() => {
|
|
166
163
|
setIsEditing(false)
|
|
167
|
-
|
|
164
|
+
headingRef?.current?.focus()
|
|
165
|
+
form.reset()
|
|
168
166
|
}}
|
|
169
167
|
/>
|
|
170
168
|
</Stack>
|
|
@@ -232,7 +230,7 @@ const ProfileCard = () => {
|
|
|
232
230
|
|
|
233
231
|
const PasswordCard = () => {
|
|
234
232
|
const {formatMessage} = useIntl()
|
|
235
|
-
|
|
233
|
+
const headingRef = useRef(null)
|
|
236
234
|
const {data: customer} = useCurrentCustomer()
|
|
237
235
|
const {isRegistered, customerId, email} = customer
|
|
238
236
|
|
|
@@ -244,14 +242,6 @@ const PasswordCard = () => {
|
|
|
244
242
|
|
|
245
243
|
const form = useForm()
|
|
246
244
|
|
|
247
|
-
const passwordHeadingText = formatMessage({
|
|
248
|
-
defaultMessage: 'Password',
|
|
249
|
-
id: 'password_card.title.password'
|
|
250
|
-
})
|
|
251
|
-
const passwordHeading = Array.from(document.querySelectorAll('h2')).find(
|
|
252
|
-
(element) => element.textContent === passwordHeadingText
|
|
253
|
-
)
|
|
254
|
-
|
|
255
245
|
const submit = async (values) => {
|
|
256
246
|
try {
|
|
257
247
|
form.clearErrors()
|
|
@@ -278,7 +268,7 @@ const PasswordCard = () => {
|
|
|
278
268
|
username: email,
|
|
279
269
|
password: values.password
|
|
280
270
|
})
|
|
281
|
-
|
|
271
|
+
headingRef?.current?.focus()
|
|
282
272
|
form.reset()
|
|
283
273
|
},
|
|
284
274
|
onError: async (err) => {
|
|
@@ -296,8 +286,8 @@ const PasswordCard = () => {
|
|
|
296
286
|
<ToggleCard
|
|
297
287
|
id="password"
|
|
298
288
|
title={
|
|
299
|
-
<Skeleton height="30px" width="120px">
|
|
300
|
-
|
|
289
|
+
<Skeleton ref={headingRef} tabIndex="-1" height="30px" width="120px">
|
|
290
|
+
<FormattedMessage defaultMessage="Password" id="password_card.title.password" />
|
|
301
291
|
</Skeleton>
|
|
302
292
|
}
|
|
303
293
|
editing={isEditing}
|
|
@@ -321,7 +311,8 @@ const PasswordCard = () => {
|
|
|
321
311
|
<FormActionButtons
|
|
322
312
|
onCancel={() => {
|
|
323
313
|
setIsEditing(false)
|
|
324
|
-
|
|
314
|
+
headingRef?.current?.focus()
|
|
315
|
+
form.reset()
|
|
325
316
|
}}
|
|
326
317
|
/>
|
|
327
318
|
</Stack>
|
|
@@ -16,7 +16,7 @@ import {useWishList} from '@salesforce/retail-react-app/app/hooks/use-wish-list'
|
|
|
16
16
|
|
|
17
17
|
import PageActionPlaceHolder from '@salesforce/retail-react-app/app/components/page-action-placeholder'
|
|
18
18
|
import {HeartIcon} from '@salesforce/retail-react-app/app/components/icons'
|
|
19
|
-
import ProductItem from '@salesforce/retail-react-app/app/components/product-item
|
|
19
|
+
import ProductItem from '@salesforce/retail-react-app/app/components/product-item'
|
|
20
20
|
import WishlistPrimaryAction from '@salesforce/retail-react-app/app/pages/account/wishlist/partials/wishlist-primary-action'
|
|
21
21
|
import WishlistSecondaryButtonGroup from '@salesforce/retail-react-app/app/pages/account/wishlist/partials/wishlist-secondary-button-group'
|
|
22
22
|
|
package/app/pages/cart/index.jsx
CHANGED
|
@@ -26,7 +26,7 @@ import CartTitle from '@salesforce/retail-react-app/app/pages/cart/partials/cart
|
|
|
26
26
|
import ConfirmationModal from '@salesforce/retail-react-app/app/components/confirmation-modal'
|
|
27
27
|
import EmptyCart from '@salesforce/retail-react-app/app/pages/cart/partials/empty-cart'
|
|
28
28
|
import OrderSummary from '@salesforce/retail-react-app/app/components/order-summary'
|
|
29
|
-
import ProductItem from '@salesforce/retail-react-app/app/components/product-item
|
|
29
|
+
import ProductItem from '@salesforce/retail-react-app/app/components/product-item'
|
|
30
30
|
import ProductViewModal from '@salesforce/retail-react-app/app/components/product-view-modal'
|
|
31
31
|
import RecommendedProducts from '@salesforce/retail-react-app/app/components/recommended-products'
|
|
32
32
|
|
|
@@ -109,9 +109,9 @@ const Payment = () => {
|
|
|
109
109
|
// Using destructuring to remove properties from the object...
|
|
110
110
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
111
111
|
const {addressId, creationDate, lastModified, preferred, ...address} = billingAddress
|
|
112
|
-
return updateBillingAddressForBasket({
|
|
112
|
+
return await updateBillingAddressForBasket({
|
|
113
113
|
body: address,
|
|
114
|
-
parameters: {basketId: basket.basketId
|
|
114
|
+
parameters: {basketId: basket.basketId}
|
|
115
115
|
})
|
|
116
116
|
}
|
|
117
117
|
const onPaymentRemoval = async () => {
|
|
@@ -137,6 +137,9 @@ const ProductList = (props) => {
|
|
|
137
137
|
)
|
|
138
138
|
|
|
139
139
|
/**************** Query Actions ****************/
|
|
140
|
+
// _refine is an invalid param for useProductSearch, we don't want to pass it to API call
|
|
141
|
+
const {_refine, ...restOfParams} = searchParams
|
|
142
|
+
|
|
140
143
|
const {
|
|
141
144
|
isLoading,
|
|
142
145
|
isRefetching,
|
|
@@ -144,7 +147,7 @@ const ProductList = (props) => {
|
|
|
144
147
|
} = useProductSearch(
|
|
145
148
|
{
|
|
146
149
|
parameters: {
|
|
147
|
-
...
|
|
150
|
+
...restOfParams,
|
|
148
151
|
refine: searchParams._refine
|
|
149
152
|
}
|
|
150
153
|
},
|
package/app/utils/url.js
CHANGED
|
@@ -147,8 +147,6 @@ export const getPathWithLocale = (shortCode, buildUrl, opts = {}) => {
|
|
|
147
147
|
// remove ending any &
|
|
148
148
|
search = search.replace(/&$/, '')
|
|
149
149
|
|
|
150
|
-
const defaultSite = getDefaultSite()
|
|
151
|
-
|
|
152
150
|
// Remove query parameters
|
|
153
151
|
const {disallowParams = []} = opts
|
|
154
152
|
|
|
@@ -161,7 +159,6 @@ export const getPathWithLocale = (shortCode, buildUrl, opts = {}) => {
|
|
|
161
159
|
}
|
|
162
160
|
|
|
163
161
|
const site = getSiteByReference(siteRef)
|
|
164
|
-
|
|
165
162
|
const locale = getLocaleByReference(site, shortCode)
|
|
166
163
|
|
|
167
164
|
// rebuild the url with new locale,
|
|
@@ -169,7 +166,7 @@ export const getPathWithLocale = (shortCode, buildUrl, opts = {}) => {
|
|
|
169
166
|
`${pathname}${Array.from(queryString).length !== 0 ? `?${queryString}` : ''}`,
|
|
170
167
|
// By default, as for home page, when the values of site and locale belongs to the default site,
|
|
171
168
|
// they will be not shown in the url just
|
|
172
|
-
|
|
169
|
+
site.alias || site.id,
|
|
173
170
|
locale?.alias || locale?.id
|
|
174
171
|
)
|
|
175
172
|
return newUrl
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@salesforce/retail-react-app",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.4.0-dev",
|
|
4
4
|
"license": "See license in LICENSE",
|
|
5
5
|
"author": "cc-pwa-kit@salesforce.com",
|
|
6
6
|
"ccExtensibility": {
|
|
@@ -45,10 +45,10 @@
|
|
|
45
45
|
"@lhci/cli": "^0.11.0",
|
|
46
46
|
"@loadable/component": "^5.15.3",
|
|
47
47
|
"@peculiar/webcrypto": "^1.4.2",
|
|
48
|
-
"@salesforce/commerce-sdk-react": "1.
|
|
49
|
-
"@salesforce/pwa-kit-dev": "3.
|
|
50
|
-
"@salesforce/pwa-kit-react-sdk": "3.
|
|
51
|
-
"@salesforce/pwa-kit-runtime": "3.
|
|
48
|
+
"@salesforce/commerce-sdk-react": "1.4.0-gpt-nightly-20240315030539",
|
|
49
|
+
"@salesforce/pwa-kit-dev": "3.5.0-dev",
|
|
50
|
+
"@salesforce/pwa-kit-react-sdk": "3.5.0-dev",
|
|
51
|
+
"@salesforce/pwa-kit-runtime": "3.5.0-dev",
|
|
52
52
|
"@tanstack/react-query": "^4.28.0",
|
|
53
53
|
"@tanstack/react-query-devtools": "^4.29.1",
|
|
54
54
|
"@testing-library/dom": "^9.0.1",
|
|
@@ -97,8 +97,8 @@
|
|
|
97
97
|
},
|
|
98
98
|
{
|
|
99
99
|
"path": "build/vendor.js",
|
|
100
|
-
"maxSize": "
|
|
100
|
+
"maxSize": "370 kB"
|
|
101
101
|
}
|
|
102
102
|
],
|
|
103
|
-
"gitHead": "
|
|
103
|
+
"gitHead": "61dd7239a60def4e983fbab25194ffb1e25279fe"
|
|
104
104
|
}
|