-
Notifications
You must be signed in to change notification settings - Fork 202
Enable wishlist functionalities for Einstein recommended products #131
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from 107 commits
Commits
Show all changes
123 commits
Select commit
Hold shift + click to select a range
818c63d
add isInitialized getter
kevinxh 9ffb476
remove problematic wishlist init code
kevinxh f7618bb
rename getOrCreateProductLists
kevinxh ce2879f
extract contexts into its own file
kevinxh 387a9f2
add empty reducer in wishlist context
kevinxh 2d6e732
add init and reset methods
kevinxh 6ea795f
fetch product details in wishlist
kevinxh 14272bf
update loading and empty state
kevinxh 14059c3
add list item methods
kevinxh 5640563
add createListItem method
kevinxh e797be9
create useWishlist hook
kevinxh be0e6e3
rename file to useWishlist.js
kevinxh 2dd157a
add createWishlistItem and updateWishlistItem
kevinxh 33f0960
add createWishlistItem and updateWishlistItem 2
kevinxh 202a746
remove unnecessary code
kevinxh 560ef4b
rename useWishlist to useCustomerProductList
kevinxh 64d289f
refactor useCustomerProductList
kevinxh 6e157cc
fix PLP
kevinxh 35ca633
clean up PLP
kevinxh 2571722
clean up PDP
kevinxh 47c9f5d
clean up Cart
kevinxh 4acd16b
fix wishlist page
kevinxh eea0c42
make reducers pure
kevinxh d86836c
add isInitialized state
kevinxh 7bd6d90
set isInitialized initial value
kevinxh eee8dbe
remove queue
kevinxh 161cbb9
remove testing code
kevinxh 4ff3562
remove unused constants
kevinxh 4cc5310
move useWishlist from commerce api
kevinxh 98e8bbd
move toast back to PLP due to i18n limitation
kevinxh 35c65c2
merge develop
kevinxh 9a89251
fallback to onClick navigation
kevinxh 6dc5024
update plp remove wishlist
kevinxh 9a45610
move toasts out from useWishlist hook
kevinxh 2eea8c2
remove old code
kevinxh 0e03015
catch update quantity error
kevinxh 9be7858
fix product type
kevinxh 9b5d118
fix add to cart
kevinxh ad6dfdf
merge conflict
kevinxh 8019604
fix lint
kevinxh a455f2a
rewrite wishlist unit test
kevinxh f82e2f0
fix tests
kevinxh 8654496
fix isCustomerProductListLoading
kevinxh a8b1d51
Merge branch 'develop' into wishlist_rework
kevinxh be9195b
add changelog
kevinxh c7d4a10
fix add item reducer
kevinxh 54591bc
move comment
kevinxh 1440d10
add missing toast
kevinxh 15331d0
remove unnecessary optional chaining
kevinxh 900b764
rename context
kevinxh e98dba2
remove console log
kevinxh f79f5d1
add comment
kevinxh 5811f4d
rename _super to customerProductLists
kevinxh 8cd8012
move methods to useCustomerProductLists
kevinxh b0d03bf
rename detail to product
kevinxh f211a10
add jsdoc
kevinxh e995a74
change isInitialized to a derived state
kevinxh 09555e3
fix additem bug
kevinxh c99a2f4
fix remove item issue
kevinxh 985b367
fix isInitialized
kevinxh ac926dd
Merge branch 'develop' into wishlist_rework
kevinxh b006de0
cleanup ProductTile api
kevinxh 120aeb3
cleanup ProductTile api 2
kevinxh 8e34fa2
clean up ProductTile styles
kevinxh bd47d50
rename wishlist icon to heart icon
kevinxh d39bf42
refactor PLP product tiles
kevinxh 36f0408
decouple productscroller and producttile
kevinxh b51c3a8
remove testing code
kevinxh 823dbf4
replace prev with acc
kevinxh ec28c0f
fix isInitialized
kevinxh 4a2b544
Merge branch 'wishlist_rework' of https://github.com/SalesforceCommer…
kevinxh 0945482
remove unnecessary toast id
kevinxh 5415abb
merge develop
kevinxh 08e0635
desctruct payload in reducer
kevinxh da61d82
fix test
kevinxh a4e4c79
rename file name to useCustomerProductLists
kevinxh ba0c503
add handleAsyncError util function
kevinxh 506676c
move methods into useCustomerProductLists
kevinxh ead837b
finish init method in useWishlist
kevinxh 8bbf0bc
simplify getOrCreateList
kevinxh 1b36418
add getters to useWishlist
kevinxh 7b7cb5f
add findItem method
kevinxh 55dd6b7
add list item crud actions
kevinxh 298b294
fix createListItem
kevinxh 635f766
fix removeListItemByProductId
kevinxh 4806ab5
fix pdp
kevinxh 7b73696
fix wishlist item update
kevinxh 6680c32
fix remove button and cart wishlist
kevinxh ec8fa21
add comments
kevinxh f3e9b5f
fix wishlist init
kevinxh f880203
return responses
kevinxh 2fdaaea
bump bundle size limit
kevinxh cbab3d8
lint
kevinxh 9b11aca
fix tests
kevinxh 5361200
add tests
kevinxh 313443a
remove actions from return
kevinxh 6799779
Merge branch 'wishlist_rework' into W-9807216__wishlist-einstein
kevinxh 3ef5a51
fix merge conflicts
kevinxh cf5c9a3
add more tests
kevinxh f1e2572
fix handleAsyncError comment
kevinxh 5e1b0b0
add handleAsyncError tests
kevinxh 11d4677
fix test case name
kevinxh 55b5593
Merge branch 'wishlist_rework' into W-9807216__wishlist-einstein
kevinxh 9f8fb4d
merge develop
kevinxh f8b011d
Merge branch 'develop' into W-9807216__wishlist-einstein
kevinxh 88ec4a3
fix merge conflicts
kevinxh 0189199
merge develop
kevinxh c2c6013
Merge branch 'develop' into W-9807216__wishlist-einstein
kevinxh c9e100e
update changelog
kevinxh 151bab3
introduce productTilePropsFactory
kevinxh 3d077dd
add loading state
kevinxh 57cf2e6
remove testing code
kevinxh 26941e2
rename productTileProps
kevinxh 720719f
Chakra IconButton already supports disabled state
kevinxh 3ee155d
avoid click event bubbling
kevinxh 4322e35
fix tests
kevinxh 88c2f62
fix import
kevinxh e379ca1
allow func or object
kevinxh 9a531f2
add more tests
kevinxh da27b61
minor updates
kevinxh 4ece56c
compile messages
kevinxh 30b8f0d
Merge branch 'develop' into W-9807216__wishlist-einstein
kevinxh b124855
Merge branch 'develop' into W-9807216__wishlist-einstein
kevinxh File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
File renamed without changes
File renamed without changes
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -7,7 +7,7 @@ | |
|
|
||
| import React from 'react' | ||
| import PropTypes from 'prop-types' | ||
| import {WishlistIcon, WishlistSolidIcon} from '../icons' | ||
| import {HeartIcon, HeartSolidIcon} from '../icons' | ||
|
|
||
| // Components | ||
| import { | ||
|
|
@@ -50,80 +50,47 @@ export const Skeleton = () => { | |
| } | ||
|
|
||
| /** | ||
| * The ProductTile is a simple visual representation of a product search hit | ||
| * object. It will show it's default image, name and price. | ||
| * The ProductTile is a simple visual representation of a | ||
| * product object. It will show it's default image, name and price. | ||
| * It also supports favourite products, controlled by a heart icon. | ||
| */ | ||
| const ProductTile = (props) => { | ||
| const intl = useIntl() | ||
|
|
||
| // eslint-disable-next-line react/prop-types | ||
| const { | ||
| productSearchItem, | ||
| // eslint-disable-next-line react/prop-types | ||
| staticContext, | ||
| onAddToWishlistClick, | ||
| onRemoveWishlistClick, | ||
| isInWishlist, | ||
| isWishlistLoading, | ||
| ...rest | ||
| } = props | ||
| const {currency, image, price, productName} = productSearchItem | ||
| const styles = useMultiStyleConfig('ProductTile', {isLoading: isWishlistLoading}) | ||
| const {product, enableFavourite = false, isFavourite, onFavouriteToggle, ...rest} = props | ||
|
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. i'd like to de-couple the concept of wishlist from the components like i intentionally renamed wishlist related props to "favourite", which i think is more generic. feedback is welcomed |
||
| const {currency, image, price, productName, productId} = product | ||
| const styles = useMultiStyleConfig('ProductTile') | ||
|
|
||
| return ( | ||
| <Link | ||
| data-testid="product-tile" | ||
| {...styles.container} | ||
| to={productUrlBuilder({id: productSearchItem?.productId}, intl.local)} | ||
| to={productUrlBuilder({id: productId}, intl.local)} | ||
| {...rest} | ||
| > | ||
| <Box {...styles.imageWrapper}> | ||
| <AspectRatio {...styles.image} ratio={1}> | ||
| <AspectRatio {...styles.image}> | ||
| <Img alt={image.alt} src={image.disBaseLink} /> | ||
| </AspectRatio> | ||
| {onAddToWishlistClick && onRemoveWishlistClick && ( | ||
| <> | ||
| {isInWishlist ? ( | ||
| <IconButton | ||
| aria-label={intl.formatMessage({ | ||
| defaultMessage: 'wishlist-solid' | ||
| })} | ||
| icon={<WishlistSolidIcon />} | ||
| variant="unstyled" | ||
| {...styles.iconButton} | ||
| onClick={(e) => { | ||
| e.preventDefault() | ||
| if (isWishlistLoading) return | ||
| onRemoveWishlistClick() | ||
| }} | ||
| /> | ||
| ) : ( | ||
| <IconButtonWithRegistration | ||
| aria-label={intl.formatMessage({ | ||
| defaultMessage: 'wishlist' | ||
| })} | ||
| icon={<WishlistIcon />} | ||
| variant="unstyled" | ||
| {...styles.iconButton} | ||
| onClick={() => { | ||
| if (isWishlistLoading) return | ||
| onAddToWishlistClick() | ||
| }} | ||
| /> | ||
| )} | ||
| </> | ||
|
|
||
| {enableFavourite && ( | ||
| <IconButtonWithRegistration | ||
| aria-label={intl.formatMessage({ | ||
| defaultMessage: 'wishlist' | ||
| })} | ||
| icon={isFavourite ? <HeartSolidIcon /> : <HeartIcon />} | ||
| {...styles.favIcon} | ||
| onClick={() => { | ||
| onFavouriteToggle(!isFavourite) | ||
| }} | ||
| /> | ||
| )} | ||
| </Box> | ||
|
|
||
| {/* Title */} | ||
| <Text {...styles.title} aria-label="product name"> | ||
| {productName} | ||
| </Text> | ||
| <Text {...styles.title}>{productName}</Text> | ||
|
|
||
| {/* Price */} | ||
| <Text {...styles.price} aria-label="price"> | ||
| {intl.formatNumber(price, {style: 'currency', currency})} | ||
| </Text> | ||
| <Text {...styles.price}>{intl.formatNumber(price, {style: 'currency', currency})}</Text> | ||
| </Link> | ||
| ) | ||
| } | ||
|
|
@@ -135,20 +102,30 @@ ProductTile.propTypes = { | |
| * The product search hit that will be represented in this | ||
| * component. | ||
| */ | ||
| productSearchItem: PropTypes.object.isRequired, | ||
| product: PropTypes.shape({ | ||
| currency: PropTypes.string, | ||
| image: PropTypes.shape({ | ||
| alt: PropTypes.string, | ||
| disBaseLink: PropTypes.string | ||
| }), | ||
| price: PropTypes.number, | ||
| productName: PropTypes.string, | ||
| productId: PropTypes.string | ||
| }), | ||
| /** | ||
| * Types of lists the product/variant is added to. (eg: wishlist) | ||
| * Enable adding/removing product as a favourite. | ||
| * Use case: wishlist. | ||
| */ | ||
| isInWishlist: PropTypes.bool, | ||
| enableFavourite: PropTypes.bool, | ||
| /** | ||
| * Callback function to be invoked when the user add item to wishlist | ||
| * Display the product as a faviourite. | ||
| */ | ||
| onAddToWishlistClick: PropTypes.func, | ||
| isFavourite: PropTypes.bool, | ||
| /** | ||
| * Callback function to be invoked when the user removes item to wishlist | ||
| * Callback function to be invoked when the user | ||
| * interacts with favourite icon/button. | ||
| */ | ||
| onRemoveWishlistClick: PropTypes.func, | ||
| isWishlistLoading: PropTypes.bool | ||
| onFavouriteToggle: PropTypes.func | ||
| } | ||
|
|
||
| export default ProductTile | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
it's hard to customize the product tiles in the scroller so this is my attempt to decouple the two components...
feedback is welcomed