@graphcommerce/magento-wishlist 1.6.11 → 1.7.0
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 +20 -0
- package/components/ProductWishlistChip/ProductWishlistChip.graphql +1 -0
- package/components/ProductWishlistChip/ProductWishlistChipBase.tsx +28 -17
- package/components/ProductWishlistChip/ProductWishlistChipDetailConfigurable.tsx +1 -19
- package/components/WishlistItem/WishlistItem.tsx +1 -1
- package/components/WishlistItem/WishlistItemBase.tsx +3 -1
- package/components/WishlistItems/WishlistItems.tsx +1 -1
- package/hooks/useMergeGuestWishlistWithCustomer.tsx +6 -6
- package/hooks/useWishlistItems.tsx +32 -14
- package/package.json +7 -7
- package/queries/GuestWishlist.graphql +1 -0
- package/queries/GuestWishlist.graphqls +1 -0
- package/queries/WishlistSummaryFragment.graphql +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,25 @@
|
|
|
1
1
|
# @graphcommerce/magento-wishlist
|
|
2
2
|
|
|
3
|
+
## 1.7.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- [#1642](https://github.com/graphcommerce-org/graphcommerce/pull/1642) [`ad63ebf4e`](https://github.com/graphcommerce-org/graphcommerce/commit/ad63ebf4e33bfb0e5c9e5e68ab69b14775f3f8a8) Thanks [@paales](https://github.com/paales)! - Introduced `<AddProductsToCartForm/>`, which is allows for adding all product types to the cart with a single react-hook-form form.
|
|
8
|
+
|
|
9
|
+
Which allows you to fully compose the form on the product page without having to modify the page.
|
|
10
|
+
|
|
11
|
+
* [#1652](https://github.com/graphcommerce-org/graphcommerce/pull/1652) [`961b06fbb`](https://github.com/graphcommerce-org/graphcommerce/commit/961b06fbbfef3dd9b7b41b3dcdefbe78ddbc58c3) Thanks [@mikekeehnen](https://github.com/mikekeehnen)! - Improved useWishlistItems hook, and merge guest wishlist based on url_key instead of sku
|
|
12
|
+
|
|
13
|
+
### Patch Changes
|
|
14
|
+
|
|
15
|
+
- Updated dependencies [[`ad63ebf4e`](https://github.com/graphcommerce-org/graphcommerce/commit/ad63ebf4e33bfb0e5c9e5e68ab69b14775f3f8a8), [`87c897cda`](https://github.com/graphcommerce-org/graphcommerce/commit/87c897cda1934f072887d5302b7b7ef5ecccd1c0), [`b6bf2c941`](https://github.com/graphcommerce-org/graphcommerce/commit/b6bf2c94197ddacbf8f1fc0d352cd0d46e096f30), [`b91b9eb1f`](https://github.com/graphcommerce-org/graphcommerce/commit/b91b9eb1f3f9c2740fcbe03d8047f23941b10dcc)]:
|
|
16
|
+
- @graphcommerce/magento-product@4.6.0
|
|
17
|
+
- @graphcommerce/magento-product-configurable@4.3.0
|
|
18
|
+
- @graphcommerce/magento-store@4.3.0
|
|
19
|
+
- @graphcommerce/next-ui@4.27.0
|
|
20
|
+
- @graphcommerce/magento-cart@4.8.4
|
|
21
|
+
- @graphcommerce/magento-customer@4.11.4
|
|
22
|
+
|
|
3
23
|
## 1.6.11
|
|
4
24
|
|
|
5
25
|
### Patch Changes
|
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
import { useMutation, useApolloClient } from '@graphcommerce/graphql'
|
|
2
|
+
import { WishlistItem } from '@graphcommerce/graphql-mesh'
|
|
2
3
|
import {
|
|
3
4
|
useCustomerQuery,
|
|
4
5
|
useCustomerSession,
|
|
5
6
|
useGuestQuery,
|
|
6
7
|
} from '@graphcommerce/magento-customer'
|
|
8
|
+
import { useFormAddProductsToCart } from '@graphcommerce/magento-product'
|
|
7
9
|
import {
|
|
8
10
|
IconSvg,
|
|
9
11
|
iconHeart,
|
|
@@ -22,6 +24,7 @@ import { AddProductToWishlistDocument } from '../../queries/AddProductToWishlist
|
|
|
22
24
|
import { GetIsInWishlistsDocument } from '../../queries/GetIsInWishlists.gql'
|
|
23
25
|
import { GuestWishlistDocument } from '../../queries/GuestWishlist.gql'
|
|
24
26
|
import { RemoveProductFromWishlistDocument } from '../../queries/RemoveProductFromWishlist.gql'
|
|
27
|
+
import { WishlistSummaryFragment } from '../../queries/WishlistSummaryFragment.gql'
|
|
25
28
|
import { ProductWishlistChipFragment } from './ProductWishlistChip.gql'
|
|
26
29
|
|
|
27
30
|
const hideForGuest = process.env.NEXT_PUBLIC_WISHLIST_HIDE_FOR_GUEST === '1'
|
|
@@ -29,17 +32,22 @@ const ignoreProductWishlistStatus =
|
|
|
29
32
|
process.env.NEXT_PUBLIC_WISHLIST_IGNORE_PRODUCT_WISHLIST_STATUS === '1'
|
|
30
33
|
|
|
31
34
|
export type ProductWishlistChipProps = ProductWishlistChipFragment & { sx?: SxProps<Theme> } & {
|
|
32
|
-
selectedOptions?: string[]
|
|
33
35
|
showFeedbackMessage?: boolean
|
|
34
36
|
buttonProps?: IconButtonProps
|
|
35
37
|
}
|
|
36
38
|
|
|
39
|
+
export type WishListItemType = NonNullable<
|
|
40
|
+
NonNullable<NonNullable<WishlistSummaryFragment['items_v2']>['items']>[0]
|
|
41
|
+
>['product']
|
|
42
|
+
|
|
37
43
|
const compName = 'ProductWishlistChipBase' as const
|
|
38
44
|
const parts = ['root', 'wishlistIcon', 'wishlistIconActive', 'wishlistButton'] as const
|
|
39
45
|
const { classes } = extendableComponent(compName, parts)
|
|
40
46
|
|
|
41
47
|
export function ProductWishlistChipBase(props: ProductWishlistChipProps) {
|
|
42
|
-
const { name, sku,
|
|
48
|
+
const { name, sku, url_key, showFeedbackMessage, buttonProps, sx = [] } = props
|
|
49
|
+
|
|
50
|
+
const addToCartForm = useFormAddProductsToCart(true)
|
|
43
51
|
|
|
44
52
|
const [inWishlist, setInWishlist] = useState(false)
|
|
45
53
|
const [displayMessageBar, setDisplayMessageBar] = useState(false)
|
|
@@ -85,7 +93,7 @@ export function ProductWishlistChipBase(props: ProductWishlistChipProps) {
|
|
|
85
93
|
return
|
|
86
94
|
}
|
|
87
95
|
|
|
88
|
-
if (!sku) {
|
|
96
|
+
if (!url_key || !sku) {
|
|
89
97
|
return
|
|
90
98
|
}
|
|
91
99
|
|
|
@@ -93,14 +101,15 @@ export function ProductWishlistChipBase(props: ProductWishlistChipProps) {
|
|
|
93
101
|
if (loggedIn && !loading) {
|
|
94
102
|
const inWishlistTest =
|
|
95
103
|
GetCustomerWishlistData?.customer?.wishlists[0]?.items_v2?.items.map(
|
|
96
|
-
(item) => item?.product?.
|
|
104
|
+
(item) => item?.product?.url_key,
|
|
97
105
|
) || []
|
|
98
|
-
setInWishlist(inWishlistTest.includes(
|
|
106
|
+
setInWishlist(inWishlistTest.includes(url_key))
|
|
99
107
|
} else if (!loggedIn) {
|
|
100
|
-
const inWishlistTest =
|
|
101
|
-
|
|
108
|
+
const inWishlistTest =
|
|
109
|
+
guestWishlistData?.guestWishlist?.items.map((item) => item?.url_key) || []
|
|
110
|
+
setInWishlist(inWishlistTest.includes(url_key))
|
|
102
111
|
}
|
|
103
|
-
}, [loggedIn,
|
|
112
|
+
}, [loggedIn, url_key, loading, GetCustomerWishlistData, guestWishlistData, sku])
|
|
104
113
|
|
|
105
114
|
const preventAnimationBubble: React.MouseEventHandler<HTMLButtonElement> = (e) => {
|
|
106
115
|
e.preventDefault()
|
|
@@ -110,7 +119,10 @@ export function ProductWishlistChipBase(props: ProductWishlistChipProps) {
|
|
|
110
119
|
const handleClick: React.MouseEventHandler<HTMLButtonElement> = (e) => {
|
|
111
120
|
e.preventDefault()
|
|
112
121
|
|
|
113
|
-
|
|
122
|
+
const selectedOptions = addToCartForm?.getValues().cartItems[0].selected_options ?? []
|
|
123
|
+
const selected_options = Array.isArray(selectedOptions) ? selectedOptions : [selectedOptions]
|
|
124
|
+
|
|
125
|
+
if (!url_key || !sku) {
|
|
114
126
|
return
|
|
115
127
|
}
|
|
116
128
|
|
|
@@ -119,7 +131,7 @@ export function ProductWishlistChipBase(props: ProductWishlistChipProps) {
|
|
|
119
131
|
const wishlistItemsInSession =
|
|
120
132
|
GetCustomerWishlistData?.customer?.wishlists[0]?.items_v2?.items || []
|
|
121
133
|
|
|
122
|
-
const item = wishlistItemsInSession.find((element) => element?.product?.
|
|
134
|
+
const item = wishlistItemsInSession.find((element) => element?.product?.url_key === url_key)
|
|
123
135
|
|
|
124
136
|
if (item?.id) {
|
|
125
137
|
// eslint-disable-next-line @typescript-eslint/no-floating-promises
|
|
@@ -127,17 +139,15 @@ export function ProductWishlistChipBase(props: ProductWishlistChipProps) {
|
|
|
127
139
|
}
|
|
128
140
|
} else {
|
|
129
141
|
// eslint-disable-next-line @typescript-eslint/no-floating-promises
|
|
130
|
-
addWishlistItem({
|
|
131
|
-
variables: { input: { sku, quantity: 1, selected_options: selectedOptions } },
|
|
132
|
-
})
|
|
142
|
+
addWishlistItem({ variables: { input: [{ sku, quantity: 1, selected_options }] } })
|
|
133
143
|
setDisplayMessageBar(true)
|
|
134
144
|
}
|
|
135
145
|
} else if (inWishlist) {
|
|
136
146
|
cache.modify({
|
|
137
147
|
id: cache.identify({ __typename: 'GuestWishlist' }),
|
|
138
148
|
fields: {
|
|
139
|
-
items(existingItems = []) {
|
|
140
|
-
const items = existingItems.filter((item) => item
|
|
149
|
+
items(existingItems: WishListItemType[] = []) {
|
|
150
|
+
const items = existingItems.filter((item) => item?.url_key !== url_key)
|
|
141
151
|
return items
|
|
142
152
|
},
|
|
143
153
|
},
|
|
@@ -153,8 +163,9 @@ export function ProductWishlistChipBase(props: ProductWishlistChipProps) {
|
|
|
153
163
|
{
|
|
154
164
|
__typename: 'GuestWishlistItem',
|
|
155
165
|
sku,
|
|
166
|
+
url_key,
|
|
156
167
|
quantity: 1,
|
|
157
|
-
selected_options
|
|
168
|
+
selected_options,
|
|
158
169
|
},
|
|
159
170
|
],
|
|
160
171
|
},
|
|
@@ -168,7 +179,7 @@ export function ProductWishlistChipBase(props: ProductWishlistChipProps) {
|
|
|
168
179
|
const output = (
|
|
169
180
|
<Box>
|
|
170
181
|
<IconButton
|
|
171
|
-
key={
|
|
182
|
+
key={url_key}
|
|
172
183
|
onClick={handleClick}
|
|
173
184
|
onMouseDown={preventAnimationBubble}
|
|
174
185
|
size='small'
|
|
@@ -1,23 +1,5 @@
|
|
|
1
|
-
import { useConfigurableContext } from '@graphcommerce/magento-product-configurable'
|
|
2
1
|
import { ProductWishlistChipBase, ProductWishlistChipProps } from './ProductWishlistChipBase'
|
|
3
2
|
|
|
4
3
|
export function ProductWishlistChipDetailConfigurable(props: ProductWishlistChipProps) {
|
|
5
|
-
|
|
6
|
-
const context = useConfigurableContext(sku ?? '')
|
|
7
|
-
|
|
8
|
-
let selectedOptions: string[] = []
|
|
9
|
-
|
|
10
|
-
if (sku) {
|
|
11
|
-
selectedOptions = (Object as any).values(context.selection)
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
return (
|
|
15
|
-
<ProductWishlistChipBase
|
|
16
|
-
sx={(theme) => ({
|
|
17
|
-
boxShadow: theme.shadows[6],
|
|
18
|
-
})}
|
|
19
|
-
selectedOptions={selectedOptions}
|
|
20
|
-
{...props}
|
|
21
|
-
/>
|
|
22
|
-
)
|
|
4
|
+
return <ProductWishlistChipBase sx={(theme) => ({ boxShadow: theme.shadows[6] })} {...props} />
|
|
23
5
|
}
|
|
@@ -11,7 +11,7 @@ type OptionalProductWishlistParent = {
|
|
|
11
11
|
|
|
12
12
|
export type WishlistItemProps = PropsWithChildren<WishlistItemProductFragment> & {
|
|
13
13
|
sx?: SxProps<Theme>
|
|
14
|
-
selectedOptions?: InputMaybe<
|
|
14
|
+
selectedOptions?: InputMaybe<string[]> | undefined
|
|
15
15
|
} & OptionalProductWishlistParent
|
|
16
16
|
|
|
17
17
|
export function WishlistItem(props: WishlistItemProps) {
|
|
@@ -80,7 +80,9 @@ export function WishlistItemBase(props: WishlistItemBaseProps) {
|
|
|
80
80
|
const wishlistItemsInSession =
|
|
81
81
|
GetCustomerWishlistData?.customer?.wishlists[0]?.items_v2?.items || []
|
|
82
82
|
|
|
83
|
-
const item = wishlistItemsInSession.find(
|
|
83
|
+
const item = wishlistItemsInSession.find(
|
|
84
|
+
(element) => element?.product?.url_key === url_key,
|
|
85
|
+
)
|
|
84
86
|
if (item?.id) {
|
|
85
87
|
itemIdToDelete = item.id
|
|
86
88
|
}
|
|
@@ -18,7 +18,7 @@ export function WishlistItems(props: WishlistProps) {
|
|
|
18
18
|
/** Structure between guest and customer wishlist differs */
|
|
19
19
|
return (
|
|
20
20
|
<>
|
|
21
|
-
{wishlistItemsData.
|
|
21
|
+
{wishlistItemsData.data?.map((item) => {
|
|
22
22
|
if (!item?.uid && !item?.id) return null
|
|
23
23
|
|
|
24
24
|
const productData = item?.product ? item?.product : item
|
|
@@ -10,18 +10,18 @@ export function useMergeGuestWishlistWithCustomer() {
|
|
|
10
10
|
const { loggedIn } = useCustomerSession()
|
|
11
11
|
const { cache } = useApolloClient()
|
|
12
12
|
|
|
13
|
-
const
|
|
13
|
+
const guestItems = useQuery(GuestWishlistDocument, { ssr: false }).data?.guestWishlist?.items
|
|
14
14
|
|
|
15
15
|
const guestProducts = useQuery(GetGuestWishlistProductsDocument, {
|
|
16
16
|
ssr: false,
|
|
17
|
-
variables: { filters: {
|
|
18
|
-
skip:
|
|
17
|
+
variables: { filters: { url_key: { in: guestItems?.map((item) => item?.url_key) } } },
|
|
18
|
+
skip: guestItems && guestItems?.length === 0,
|
|
19
19
|
}).data?.products?.items
|
|
20
20
|
|
|
21
21
|
const [addWishlistItem] = useMutation(AddProductToWishlistDocument)
|
|
22
22
|
|
|
23
23
|
useEffect(() => {
|
|
24
|
-
if (!loggedIn || !
|
|
24
|
+
if (!loggedIn || !guestItems || guestItems.length === 0) return
|
|
25
25
|
|
|
26
26
|
const clearGuestList = () =>
|
|
27
27
|
cache.evict({ id: cache.identify({ __typename: 'GuestWishlist' }) })
|
|
@@ -29,12 +29,12 @@ export function useMergeGuestWishlistWithCustomer() {
|
|
|
29
29
|
if (guestProducts?.length === 0) {
|
|
30
30
|
clearGuestList()
|
|
31
31
|
} else {
|
|
32
|
-
const input =
|
|
32
|
+
const input = guestItems
|
|
33
33
|
.filter((item) => guestProducts?.find((i) => i?.sku === item.sku))
|
|
34
34
|
.map(({ sku, selected_options, quantity }) => ({ sku, selected_options, quantity }))
|
|
35
35
|
|
|
36
36
|
// eslint-disable-next-line @typescript-eslint/no-floating-promises
|
|
37
37
|
if (input.length) addWishlistItem({ variables: { input } }).then(clearGuestList)
|
|
38
38
|
}
|
|
39
|
-
}, [addWishlistItem, cache, guestProducts,
|
|
39
|
+
}, [addWishlistItem, cache, guestProducts, guestItems, loggedIn])
|
|
40
40
|
}
|
|
@@ -1,14 +1,26 @@
|
|
|
1
|
-
import { useQuery } from '@graphcommerce/graphql'
|
|
1
|
+
import { QueryResult, useQuery } from '@graphcommerce/graphql'
|
|
2
2
|
import { useCustomerSession } from '@graphcommerce/magento-customer'
|
|
3
|
-
import {
|
|
4
|
-
|
|
3
|
+
import {
|
|
4
|
+
GetGuestWishlistProductsDocument,
|
|
5
|
+
GetGuestWishlistProductsQuery,
|
|
6
|
+
} from '../queries/GetGuestWishlistProducts.gql'
|
|
7
|
+
import {
|
|
8
|
+
GetWishlistProductsDocument,
|
|
9
|
+
GetWishlistProductsQuery,
|
|
10
|
+
} from '../queries/GetWishlistProducts.gql'
|
|
5
11
|
import { GuestWishlistDocument } from '../queries/GuestWishlist.gql'
|
|
6
12
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
13
|
+
type WishListData =
|
|
14
|
+
| NonNullable<GetGuestWishlistProductsQuery['products']>['items']
|
|
15
|
+
| NonNullable<
|
|
16
|
+
NonNullable<NonNullable<GetWishlistProductsQuery['customer']>['wishlists'][0]>['items_v2']
|
|
17
|
+
>['items']
|
|
11
18
|
|
|
19
|
+
export function useWishlistItems(): Omit<QueryResult<GetGuestWishlistProductsQuery>, 'data'> & {
|
|
20
|
+
data: WishListData
|
|
21
|
+
} {
|
|
22
|
+
const { loggedIn } = useCustomerSession()
|
|
23
|
+
let wishlistItems: WishListData = []
|
|
12
24
|
/** Get customer wishlist from session */
|
|
13
25
|
const customerWl = useQuery(GetWishlistProductsDocument, { ssr: false, skip: !loggedIn })
|
|
14
26
|
|
|
@@ -22,14 +34,20 @@ export function useWishlistItems() {
|
|
|
22
34
|
skip: guestSkus.length === 0,
|
|
23
35
|
})
|
|
24
36
|
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
37
|
+
const loading = guestWl.loading || guestProducts.loading || customerWl.loading
|
|
38
|
+
|
|
39
|
+
// When loading the queries, data will return undefined. While we load the new data, we want
|
|
40
|
+
// to return the previous data, to prevent the UI for going in a loading state
|
|
41
|
+
if (loading && !loggedIn) wishlistItems = guestProducts.previousData?.products?.items
|
|
42
|
+
if (loading && loggedIn)
|
|
43
|
+
wishlistItems = customerWl.previousData?.customer?.wishlists[0]?.items_v2?.items
|
|
44
|
+
|
|
45
|
+
if (!loading && loggedIn) wishlistItems = customerWl.data?.customer?.wishlists[0]?.items_v2?.items
|
|
46
|
+
if (!loading && !loggedIn) wishlistItems = guestProducts.data?.products?.items
|
|
30
47
|
|
|
31
48
|
return {
|
|
32
|
-
|
|
33
|
-
|
|
49
|
+
...guestProducts,
|
|
50
|
+
data: wishlistItems,
|
|
51
|
+
loading,
|
|
34
52
|
}
|
|
35
53
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@graphcommerce/magento-wishlist",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.7.0",
|
|
4
4
|
"sideEffects": false,
|
|
5
5
|
"prettier": "@graphcommerce/prettier-config-pwa",
|
|
6
6
|
"browserslist": [
|
|
@@ -22,12 +22,12 @@
|
|
|
22
22
|
"@graphcommerce/graphql": "3.4.8",
|
|
23
23
|
"@graphcommerce/graphql-mesh": "4.2.0",
|
|
24
24
|
"@graphcommerce/image": "3.1.9",
|
|
25
|
-
"@graphcommerce/magento-cart": "4.8.
|
|
26
|
-
"@graphcommerce/magento-customer": "4.11.
|
|
27
|
-
"@graphcommerce/magento-product": "4.
|
|
28
|
-
"@graphcommerce/magento-product-configurable": "4.
|
|
29
|
-
"@graphcommerce/magento-store": "4.
|
|
30
|
-
"@graphcommerce/next-ui": "4.
|
|
25
|
+
"@graphcommerce/magento-cart": "4.8.4",
|
|
26
|
+
"@graphcommerce/magento-customer": "4.11.4",
|
|
27
|
+
"@graphcommerce/magento-product": "4.6.0",
|
|
28
|
+
"@graphcommerce/magento-product-configurable": "4.3.0",
|
|
29
|
+
"@graphcommerce/magento-store": "4.3.0",
|
|
30
|
+
"@graphcommerce/next-ui": "4.27.0"
|
|
31
31
|
},
|
|
32
32
|
"peerDependencies": {
|
|
33
33
|
"@lingui/react": "^3.13.2",
|