Skip to content

Commit 6f65b9a

Browse files
sf-emmyzhangshethjkevinxhbendvcszirpesf
authored andcommitted
Merge standard products feature into develop @W-18912410 (#2697)
* Support standard product on PDP @W-12360908 (#2518) * update handleAddToCart and validate orderability * remove bundle changes, template test, and project config * add fallback if no image * linting * add validateOrderability tests * reorganize tests * fix lint errors * update validateOrderability logic * add product-detail tests * fix modal image link * add modal tests * changelog * pr suggestions * Handle SDK Client not initialized * Added tests for useResolvedClient * Handle missing SDK Client ShopperContext * ShopperCustomers - Handle SDK Client no init * ShopperExperience - Handle missing SDK Client * ShopperGiftCertificates - Handle missing SDK Client * ShopperLogin: Handle missing SDK client * ShopperOrders - Handle Missing SDK Client * ShopperProducts: Handle missing SDK Client * ShopperPromotions: Handle missing SDK client * ShopperSearch - Handle missing SDK Client * ShopperSEO: Handle missing SDK Client * ShopperStores: Handle missing SDK Client * Fix linting errors * Update useResolvedClient tests * Update changelog * Update changelog * Extract CLIENT_KEY literal to constnt * Remove additional hook for client validation * Fix linting * Add comments * rename apiClients variable to add clarity Co-authored-by: Kevin He <[email protected]> Signed-off-by: Jainam Sheth <[email protected]> * update variable name for apiClients * Update sample query implementation in query.ts * Initial Commit Follow `plugin_einstein_api` implementation for event data creation. * Update CHANGELOG.md * Add some additional tests * PR Feedback * Fix bar reference to master.variantId * feat: cursor rules for unit tests * Update change log * Support standard product on PDP @W-12360908 (#2518) * update handleAddToCart and validate orderability * remove bundle changes, template test, and project config * add fallback if no image * linting * add validateOrderability tests * reorganize tests * fix lint errors * update validateOrderability logic * add product-detail tests * fix modal image link * add modal tests * changelog * pr suggestions * Resolve merge conflict * Update files with conflicts * omg so we're not adding these * merge develop into standard product feature branch (#2626) * Handle SDK Client not initialized * Added tests for useResolvedClient * Handle missing SDK Client ShopperContext * ShopperCustomers - Handle SDK Client no init * ShopperExperience - Handle missing SDK Client * ShopperGiftCertificates - Handle missing SDK Client * ShopperLogin: Handle missing SDK client * ShopperOrders - Handle Missing SDK Client * ShopperProducts: Handle missing SDK Client * ShopperPromotions: Handle missing SDK client * ShopperSearch - Handle missing SDK Client * ShopperSEO: Handle missing SDK Client * ShopperStores: Handle missing SDK Client * Fix linting errors * Update useResolvedClient tests * Update changelog * implemented the voiceover feature for the email confirmation modal on PWA kit. * Update changelog * Extract CLIENT_KEY literal to constnt * updated the chanege log file to point to current changes and saved changes to email confirmation modal code * linted the files and built translations * changed role and aria label tags to solve unsuccessful check issues * Implemented changes to create more successful checks after facing a testing Library ElementError: Found multiple elements with the text: /check your email/i * Linted my files * Remove additional hook for client validation * Fix linting * Add comments * rename apiClients variable to add clarity Co-authored-by: Kevin He <[email protected]> Signed-off-by: Jainam Sheth <[email protected]> * update variable name for apiClients * linted more files to fix unsuccessful check error * linted more files to fix unsuccessful check error * Update packages/template-retail-react-app/CHANGELOG.md Co-authored-by: Yuna Kim <[email protected]> Signed-off-by: Larnelle Ankunda <[email protected]> * taking off the visible focus outline around the modal border * Initial Commit Follow `plugin_einstein_api` implementation for event data creation. * Update CHANGELOG.md * Update CHANGELOG.md * Add some additional tests * PR Feedback * adding an a11y tag to changes made docuemented in the change log reading document * Fix bar reference to master.variantId * removed redundant aria label that repeating email confirmation title * mitigating the need for additional translations * feat: cursor rules for unit tests * Update packages/template-retail-react-app/CHANGELOG.md Co-authored-by: Yuna Kim <[email protected]> Signed-off-by: Larnelle Ankunda <[email protected]> * Update packages/template-retail-react-app/CHANGELOG.md Co-authored-by: Yuna Kim <[email protected]> Signed-off-by: Larnelle Ankunda <[email protected]> * Update change log * Fixing bad merge * Update sample query implementation in query.ts * [Fix E2E Tests] Improve E2E Test and Tracking Consent Banner Handling (@W-18764173@) (#2575) * Improve e2e tests and Tracking Consent banner handling * Clean up * More clean up * Remove spacing changes * PR Feedback * Remove comments * rules only * Update translations (#2616) * update translations * @W-18541294@ Private client proxy updates (#2608) * Ensure only requests to /shopper/auth/ are allowed by the SLAS private client proxy * Remove console.logs * Stop swallowing errors from SLAS * Update CHANGELOG.md * Fix login and logout * Remove console logs * Lint * Add and fix tests * Cleanup regex --------- Signed-off-by: Jainam Sheth <[email protected]> Signed-off-by: Larnelle Ankunda <[email protected]> Signed-off-by: Ben Chypak <[email protected]> Co-authored-by: Jainam Sheth <[email protected]> Co-authored-by: Jainam Sheth <[email protected]> Co-authored-by: Larnelle Ankunda <[email protected]> Co-authored-by: Kevin He <[email protected]> Co-authored-by: Yuna Kim <[email protected]> Co-authored-by: Ben Chypak <[email protected]> Co-authored-by: Ben Chypak <[email protected]> Co-authored-by: Shailesh Zirpe <[email protected]> Co-authored-by: Shailesh Zirpe <[email protected]> Co-authored-by: Adam Raya <[email protected]> Co-authored-by: Alex Vuong <[email protected]> Co-authored-by: vcua-mobify <[email protected]> * @W-12360935 Modify the Product Card to support standard products (#2581) * remove 'edit'for std prd | Add unit tests * update changelog * lint fixes * show Edit button on bundleProducts * handle empty product bundles * better determination of if-standardProduct --------- Signed-off-by: sf-shikhar-prasoon <[email protected]> * udpate changelog to resolve conflict * udpate changelog to resolve conflict 2 * udpate changelog to resolve conflict 3 * oops * Merge develop into standard-product-support (#2633) * Handle SDK Client not initialized * Added tests for useResolvedClient * Handle missing SDK Client ShopperContext * ShopperCustomers - Handle SDK Client no init * ShopperExperience - Handle missing SDK Client * ShopperGiftCertificates - Handle missing SDK Client * ShopperLogin: Handle missing SDK client * ShopperOrders - Handle Missing SDK Client * ShopperProducts: Handle missing SDK Client * ShopperPromotions: Handle missing SDK client * ShopperSearch - Handle missing SDK Client * ShopperSEO: Handle missing SDK Client * ShopperStores: Handle missing SDK Client * Fix linting errors * Update useResolvedClient tests * Update changelog * implemented the voiceover feature for the email confirmation modal on PWA kit. * Update changelog * Extract CLIENT_KEY literal to constnt * updated the chanege log file to point to current changes and saved changes to email confirmation modal code * linted the files and built translations * changed role and aria label tags to solve unsuccessful check issues * Implemented changes to create more successful checks after facing a testing Library ElementError: Found multiple elements with the text: /check your email/i * Linted my files * Remove additional hook for client validation * Fix linting * Add comments * rename apiClients variable to add clarity Co-authored-by: Kevin He <[email protected]> Signed-off-by: Jainam Sheth <[email protected]> * update variable name for apiClients * linted more files to fix unsuccessful check error * linted more files to fix unsuccessful check error * Update packages/template-retail-react-app/CHANGELOG.md Co-authored-by: Yuna Kim <[email protected]> Signed-off-by: Larnelle Ankunda <[email protected]> * taking off the visible focus outline around the modal border * Initial Commit Follow `plugin_einstein_api` implementation for event data creation. * Update CHANGELOG.md * Update CHANGELOG.md * Add some additional tests * PR Feedback * adding an a11y tag to changes made docuemented in the change log reading document * Fix bar reference to master.variantId * removed redundant aria label that repeating email confirmation title * mitigating the need for additional translations * feat: cursor rules for unit tests * Update packages/template-retail-react-app/CHANGELOG.md Co-authored-by: Yuna Kim <[email protected]> Signed-off-by: Larnelle Ankunda <[email protected]> * Update packages/template-retail-react-app/CHANGELOG.md Co-authored-by: Yuna Kim <[email protected]> Signed-off-by: Larnelle Ankunda <[email protected]> * Update change log * Fixing bad merge * Update sample query implementation in query.ts * [Fix E2E Tests] Improve E2E Test and Tracking Consent Banner Handling (@W-18764173@) (#2575) * Improve e2e tests and Tracking Consent banner handling * Clean up * More clean up * Remove spacing changes * PR Feedback * Remove comments * rules only * Update translations (#2616) * update translations * @W-18541294@ Private client proxy updates (#2608) * Ensure only requests to /shopper/auth/ are allowed by the SLAS private client proxy * Remove console.logs * Stop swallowing errors from SLAS * Update CHANGELOG.md * Fix login and logout * Remove console logs * Lint * Add and fix tests * Cleanup regex * skip changelog --------- Signed-off-by: Jainam Sheth <[email protected]> Signed-off-by: Larnelle Ankunda <[email protected]> Signed-off-by: Ben Chypak <[email protected]> Co-authored-by: Jainam Sheth <[email protected]> Co-authored-by: Jainam Sheth <[email protected]> Co-authored-by: Larnelle Ankunda <[email protected]> Co-authored-by: Kevin He <[email protected]> Co-authored-by: Yuna Kim <[email protected]> Co-authored-by: Ben Chypak <[email protected]> Co-authored-by: Ben Chypak <[email protected]> Co-authored-by: Shailesh Zirpe <[email protected]> Co-authored-by: Shailesh Zirpe <[email protected]> Co-authored-by: Adam Raya <[email protected]> Co-authored-by: Alex Vuong <[email protected]> Co-authored-by: vcua-mobify <[email protected]> * Support standard product as a child item in bundles @W-18790730 (#2574) * init commit * skip variation check for standard product * update modal logic * add product view test * add to cart modal test * add product detail test * update add to cart modal test * add product util test * update changelog * fix edit bundle * lint * Handle standard product shape in sendAddToCart * Update CHANGELOG.md * Support standard product as a child item in sets @W-18790730 (#2636) * fix adding set to cart * updae changelog * udpate util test * Add test * Lint tests * @W-18767088 refactor add to cart * @W-18767088 refactor add to cart * @W-18767088 fix lint errors * @W-18767088 do not move handleChildProductValidation * @W-12360935 2nd PR- fixing Edit button appearing briefly for standard products (#2649) * fix Edit button appearing briefly * fix tests * @W-18767088 utils rename * Revert CHANGELOG.md Signed-off-by: sf-emmyzhang <[email protected]> * increase bundle size for ci error * update use add to cart modal unit test * revert auto merge change * add image placeholder todo * rename bundleChildVariant * revert refactor work * add bundle test * lint * update test * lint * Handle out of stock for standard product * tests and linting * handle lack of type --------- Signed-off-by: Jainam Sheth <[email protected]> Signed-off-by: Larnelle Ankunda <[email protected]> Signed-off-by: Ben Chypak <[email protected]> Signed-off-by: sf-shikhar-prasoon <[email protected]> Signed-off-by: Kyle Wright <[email protected]> Signed-off-by: sf-emmyzhang <[email protected]> Co-authored-by: Jainam Sheth <[email protected]> Co-authored-by: Jainam Sheth <[email protected]> Co-authored-by: Kevin He <[email protected]> Co-authored-by: Ben Chypak <[email protected]> Co-authored-by: Shailesh Zirpe <[email protected]> Co-authored-by: Larnelle Ankunda <[email protected]> Co-authored-by: Yuna Kim <[email protected]> Co-authored-by: Ben Chypak <[email protected]> Co-authored-by: Shailesh Zirpe <[email protected]> Co-authored-by: Adam Raya <[email protected]> Co-authored-by: Alex Vuong <[email protected]> Co-authored-by: vcua-mobify <[email protected]> Co-authored-by: sf-shikhar-prasoon <[email protected]> Co-authored-by: Jang ho Jung <[email protected]> Co-authored-by: Kyle Wright <[email protected]> Co-authored-by: jeremy-jung1 <[email protected]> Co-authored-by: Kyle Wright <[email protected]>
1 parent 1def99b commit 6f65b9a

File tree

18 files changed

+1967
-369
lines changed

18 files changed

+1967
-369
lines changed

packages/template-retail-react-app/CHANGELOG.md

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,13 @@
66
- Fix Einstein event tracking for `addToCart` event [#2558](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/2558)
77
- Update latest translations for all languages [#2616](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/2616)
88
- Added support for Buy Online Pick up In Store (BOPIS) [#2646](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/2646)
9+
- Support standard product on PDP [#2518](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/2518)
10+
- Removed the "Edit" button from product cards of Standard Products [#2581](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/2581)
11+
- Support standard product as a child item in bundles [#2574](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/2574)
12+
- Verify einstein activity with standard product [#2650](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/2650)
13+
- Support standard product as a child item in sets [#2636](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/2636)
914
- Load active data scripts on demand only [#2623](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/2623)
15+
- Refactor Add to Cart in PDP [#2664](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/2664)
1016
- Provide base image for convenient perf optimizations [#2642](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/2642)
1117
- Support saving billing phone number on user registration from order confirmation [#2653](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/2653)
1218
- Support saving default shipping address on user registration from order confirmation [#2706](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/2706)
@@ -451,4 +457,4 @@ The versions published below were not published on npm, and the versioning match
451457

452458
### v1.0.0 (Sep 08, 2021)
453459

454-
- PWA Kit General Availability and open source. 🎉
460+
- PWA Kit General Availability and open source. 🎉

packages/template-retail-react-app/app/components/product-view-modal/bundle.jsx

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,9 @@ const BundleProductViewModal = ({product: bundle, isOpen, onClose, updateCart, .
4444
let childProductIds = productViewModalData.product?.bundledProductItems
4545
?.map(({productId}) => productId)
4646
.join(',')
47-
const productIds = selectedChildProducts.map(({variant}) => variant.productId).join(',')
47+
const productIds = selectedChildProducts
48+
.map(({variant, product}) => variant?.productId || product?.id)
49+
.join(',')
4850
if (productIds?.length > 0 && productIds !== childProductIds) {
4951
childProductIds = productIds
5052
}

packages/template-retail-react-app/app/components/product-view-modal/bundle.test.js

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ import {
1717
mockProductBundle
1818
} from '@salesforce/retail-react-app/app/mocks/product-bundle'
1919
import {rest} from 'msw'
20+
import {mockStandardProductOrderable} from '@salesforce/retail-react-app/app/mocks/standard-product'
2021

2122
const MockComponent = ({updateCart}) => {
2223
const {isOpen, onOpen, onClose} = useDisclosure()
@@ -166,6 +167,20 @@ test('bundle product view modal disables update button when quantity exceeds chi
166167
expect(swingTankProductView).toBeInTheDocument()
167168
expect(sizeSelectBtn).toBeInTheDocument()
168169
expect(quantityInput).toBeInTheDocument()
170+
})
171+
172+
// Wait for all child products to be rendered
173+
await waitFor(() => {
174+
expect(screen.getAllByText('Sleeveless Pleated Floral Front Blouse')).toHaveLength(2)
175+
expect(screen.getAllByText('Swing Tank')).toHaveLength(2)
176+
expect(screen.getAllByText('Pull On Neutral Pant')).toHaveLength(2)
177+
})
178+
179+
// Select a valid variant
180+
fireEvent.click(sizeSelectBtn)
181+
182+
// Wait for the initial state to be fully loaded and the button to be enabled
183+
await waitFor(() => {
169184
expect(updateBtn).toBeInTheDocument()
170185
})
171186

@@ -187,3 +202,58 @@ test('bundle product view modal disables update button when quantity exceeds chi
187202
expect(screen.getByText('Only 1 left!')).toBeInTheDocument()
188203
})
189204
})
205+
206+
test('modal displays standard product child name when bundle contains a standard product', async () => {
207+
// Create a bundle with a standard product as the first child
208+
const bundleWithStandardChild = {
209+
...mockBundledProductItemsVariant,
210+
bundledProductItems: [
211+
{
212+
...mockBundledProductItemsVariant.bundledProductItems[0],
213+
productId: mockStandardProductOrderable.id,
214+
productName: mockStandardProductOrderable.name,
215+
itemText: mockStandardProductOrderable.name
216+
},
217+
...mockBundledProductItemsVariant.bundledProductItems.slice(1)
218+
]
219+
}
220+
221+
// Custom MSW handler for this test
222+
global.server.use(
223+
rest.get('*/products', (req, res, ctx) => {
224+
const ids = req.url.searchParams.get('ids')
225+
if (ids && ids.includes(mockStandardProductOrderable.id)) {
226+
return res(ctx.json({data: [mockStandardProductOrderable], total: 1}))
227+
}
228+
return res(ctx.json(mockProductBundleWithVariants))
229+
})
230+
)
231+
232+
const MockComponent = ({updateCart}) => {
233+
const {isOpen, onOpen, onClose} = useDisclosure()
234+
return (
235+
<div>
236+
<button onClick={onOpen}>Open Modal</button>
237+
<BundleProductViewModal
238+
updateCart={updateCart}
239+
onOpen={onOpen}
240+
onClose={onClose}
241+
isOpen={isOpen}
242+
product={bundleWithStandardChild}
243+
/>
244+
</div>
245+
)
246+
}
247+
MockComponent.propTypes = {updateCart: PropTypes.func}
248+
249+
renderWithProviders(<MockComponent />)
250+
await waitFor(() => {
251+
const trigger = screen.getByText(/open modal/i)
252+
fireEvent.click(trigger)
253+
})
254+
255+
// Assert the standard product child name is rendered
256+
await waitFor(() => {
257+
expect(screen.getAllByText(mockStandardProductOrderable.name)[0]).toBeInTheDocument()
258+
})
259+
})

packages/template-retail-react-app/app/components/product-view/index.jsx

Lines changed: 26 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -125,8 +125,21 @@ const ProductView = forwardRef(
125125
setChildProductOrderability,
126126
isBasketLoading = false,
127127
onVariantSelected = () => {},
128-
validateOrderability = (variant, quantity, stockLevel) =>
129-
!isProductLoading && variant?.orderable && quantity > 0 && quantity <= stockLevel,
128+
validateOrderability = (variant, product, quantity, stockLevel) => {
129+
if (isProductLoading) return false
130+
131+
// If product has variations, a variant must be selected
132+
if (product?.variationAttributes?.length > 0 && !variant) {
133+
return false
134+
}
135+
136+
// Check if product (either variant or standard) is orderable and if quantity is valid
137+
return (
138+
(variant?.orderable || product?.inventory?.orderable) &&
139+
quantity > 0 &&
140+
quantity <= stockLevel
141+
)
142+
},
130143
showImageGallery = true,
131144
setSelectedBundleQuantity = () => {},
132145
selectedBundleParentQuantity = 1,
@@ -169,8 +182,8 @@ const ProductView = forwardRef(
169182
return getPriceData(product, {quantity})
170183
}, [product, quantity])
171184
const canAddToWishlist = !isProductLoading
172-
const isProductASet = product?.type.set
173-
const isProductABundle = product?.type.bundle
185+
const isProductASet = product?.type?.set
186+
const isProductABundle = product?.type?.bundle
174187
const errorContainerRef = useRef(null)
175188
const [pickupEnabled, setPickupEnabled] = useState(false)
176189
const storeName = selectedStore?.name
@@ -223,7 +236,7 @@ const ProductView = forwardRef(
223236
const validateAndShowError = (opts = {}) => {
224237
const {scrollErrorIntoView = true} = opts
225238
// Validate that all attributes are selected before proceeding.
226-
const hasValidSelection = validateOrderability(variant, quantity, stockLevel)
239+
const hasValidSelection = validateOrderability(variant, product, quantity, stockLevel)
227240
const showError = !isProductASet && !isProductABundle && !hasValidSelection
228241
const scrollToError = showError && scrollErrorIntoView
229242

@@ -292,7 +305,7 @@ const ProductView = forwardRef(
292305
return
293306
}
294307
try {
295-
const itemsAdded = await addToCart(variant, quantity)
308+
const itemsAdded = await addToCart([{product, variant, quantity}])
296309
// Open modal only when `addToCart` returns some data
297310
// It's possible that the item has been added to cart, but we don't want to open the modal.
298311
// See wishlist_primary_action for example.
@@ -390,7 +403,7 @@ const ProductView = forwardRef(
390403
if (
391404
!isProductASet &&
392405
!isProductABundle &&
393-
validateOrderability(variant, quantity, stockLevel)
406+
validateOrderability(variant, product, quantity, stockLevel)
394407
) {
395408
toggleShowOptionsMessage(false)
396409
}
@@ -402,6 +415,12 @@ const ProductView = forwardRef(
402415
}
403416
}, [variant?.productId, quantity])
404417

418+
useEffect(() => {
419+
if ((isProductPartOfBundle || isProductPartOfSet) && product && product.type?.item) {
420+
onVariantSelected(product, null, childOfBundleQuantity || quantity)
421+
}
422+
}, [product, childOfBundleQuantity, quantity, isProductPartOfBundle, isProductPartOfSet])
423+
405424
useEffect(() => {
406425
if (isProductPartOfBundle || isProductPartOfSet) {
407426
const key = product.itemId ?? product.id

0 commit comments

Comments
 (0)