@graphcommerce/magento-wishlist 1.0.3 → 1.1.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 CHANGED
@@ -1,5 +1,48 @@
1
1
  # @graphcommerce/magento-wishlist
2
2
 
3
+ ## 1.1.0
4
+
5
+ ### Minor Changes
6
+
7
+ - [#1467](https://github.com/graphcommerce-org/graphcommerce/pull/1467) [`0363b9671`](https://github.com/graphcommerce-org/graphcommerce/commit/0363b9671db7c2932321d97faf6f1eb385238397) Thanks [@timhofman](https://github.com/timhofman)! - optional feedback message upon adding products to wishlist
8
+
9
+ * [#1464](https://github.com/graphcommerce-org/graphcommerce/pull/1464) [`c74089bd7`](https://github.com/graphcommerce-org/graphcommerce/commit/c74089bd7475bd8dd6090d3cdb5f2cff2570a4fc) Thanks [@mikekeehnen](https://github.com/mikekeehnen)! - Moved early return to end of file and added next-env.d.ts to solve some type issues
10
+
11
+ ### Patch Changes
12
+
13
+ - [#1458](https://github.com/graphcommerce-org/graphcommerce/pull/1458) [`31ce79a89`](https://github.com/graphcommerce-org/graphcommerce/commit/31ce79a89624205ce12d7192375b864d9a87e31a) Thanks [@timhofman](https://github.com/timhofman)! - remove mandatory \_\_typename from chip base props
14
+
15
+ * [#1463](https://github.com/graphcommerce-org/graphcommerce/pull/1463) [`a71a7e4bc`](https://github.com/graphcommerce-org/graphcommerce/commit/a71a7e4bced2c2719839eecdd995e5b3a0faadb8) Thanks [@paales](https://github.com/paales)! - make sure the default color of the heart is black
16
+
17
+ - [#1466](https://github.com/graphcommerce-org/graphcommerce/pull/1466) [`ed2b67a06`](https://github.com/graphcommerce-org/graphcommerce/commit/ed2b67a0618d9db97e79ed2a8226e0ae12403943) Thanks [@FrankHarland](https://github.com/FrankHarland)! - Added a new useCustomerSession hook to allow for more fine grained control over loading data for customers.
18
+
19
+ - Updated dependencies [[`0363b9671`](https://github.com/graphcommerce-org/graphcommerce/commit/0363b9671db7c2932321d97faf6f1eb385238397), [`c6a62a338`](https://github.com/graphcommerce-org/graphcommerce/commit/c6a62a338abf8af83d3a6eb7ed796586009910ca), [`3ac90b57c`](https://github.com/graphcommerce-org/graphcommerce/commit/3ac90b57c68b96f9d81771d6664ed9435a28fc1d), [`00f6167ff`](https://github.com/graphcommerce-org/graphcommerce/commit/00f6167ff4096bf7432f3d8e8e739ecbf6ab0dd2), [`7159d3ab3`](https://github.com/graphcommerce-org/graphcommerce/commit/7159d3ab31e937c9c921023c46e80db5813e789c), [`32370574b`](https://github.com/graphcommerce-org/graphcommerce/commit/32370574bef6345b857ae911049ca27a64bc7e08), [`ed2b67a06`](https://github.com/graphcommerce-org/graphcommerce/commit/ed2b67a0618d9db97e79ed2a8226e0ae12403943), [`4c146c682`](https://github.com/graphcommerce-org/graphcommerce/commit/4c146c68242e6edc616807fb73173cc959c26034)]:
20
+ - @graphcommerce/next-ui@4.8.0
21
+ - @graphcommerce/magento-product@4.3.5
22
+ - @graphcommerce/magento-customer@4.3.0
23
+ - @graphcommerce/magento-cart@4.2.15
24
+ - @graphcommerce/magento-product-configurable@4.1.5
25
+ - @graphcommerce/magento-store@4.2.4
26
+
27
+ ## 1.0.5
28
+
29
+ ### Patch Changes
30
+
31
+ - [#1454](https://github.com/graphcommerce-org/graphcommerce/pull/1454) [`d38b58bb3`](https://github.com/graphcommerce-org/graphcommerce/commit/d38b58bb3499a8055e1a60ec416064811e7412ed) Thanks [@paales](https://github.com/paales)! - Make sure to keep casing when generating graphql documents to match graphql-mesh's casing.
32
+
33
+ ## 1.0.4
34
+
35
+ ### Patch Changes
36
+
37
+ - [#1452](https://github.com/graphcommerce-org/graphcommerce/pull/1452) [`062c19664`](https://github.com/graphcommerce-org/graphcommerce/commit/062c19664689a0b8675e986806dbb243cfb6c063) Thanks [@paales](https://github.com/paales)! - Fix issue where the local graphql vscode plugin encountered a duplicate type
38
+
39
+ - Updated dependencies [[`c30893857`](https://github.com/graphcommerce-org/graphcommerce/commit/c3089385791291e812a48c2691a39a2325ee0439)]:
40
+ - @graphcommerce/magento-store@4.2.3
41
+ - @graphcommerce/magento-cart@4.2.14
42
+ - @graphcommerce/magento-customer@4.2.12
43
+ - @graphcommerce/magento-product@4.3.4
44
+ - @graphcommerce/magento-product-configurable@4.1.4
45
+
3
46
  ## 1.0.3
4
47
 
5
48
  ### Patch Changes
package/README.md CHANGED
@@ -10,7 +10,7 @@ account.
10
10
  - Add products to wishlist based on SKU (all producttypes)
11
11
  - Add products with selected variants, like size and color, to wishlist
12
12
  (configurable product)
13
- - Add products from wishlist to cart (simple, downloadable, virtual)
13
+ - Add products from wishlist to cart (simple, virtual)
14
14
  - Enable/disable through Magento configuration item
15
15
  'magento_wishlist_general_is_enabled'
16
16
 
@@ -36,6 +36,13 @@ already is a product with the same SKU in the wishlist.
36
36
  NEXT_PUBLIC_WISHLIST_IGNORE_PRODUCT_WISHLIST_STATUS="1"
37
37
  ```
38
38
 
39
+ - Display a MessageSnackbar message as feedback upon adding a product to the
40
+ wishlist
41
+
42
+ ```
43
+ <ProductWishlistChip showFeedbackMessage {...props} />
44
+ ```
45
+
39
46
  ## Customizing wishlist styling
40
47
 
41
48
  - The ProductWishlistChip accepts SX props (see ProductWishlistChip and
@@ -1,4 +1,4 @@
1
1
  fragment ProductWishlistChip on ProductInterface {
2
- __typename
2
+ name
3
3
  sku
4
4
  }
@@ -1,10 +1,17 @@
1
- /* eslint-disable @typescript-eslint/no-floating-promises */
2
- /* eslint-disable react-hooks/rules-of-hooks */
3
1
  import { useQuery, useMutation, useApolloClient } from '@graphcommerce/graphql'
4
2
  import { CustomerTokenDocument } from '@graphcommerce/magento-customer'
5
- import { IconSvg, iconHeart, extendableComponent } from '@graphcommerce/next-ui'
3
+ import {
4
+ IconSvg,
5
+ iconHeart,
6
+ extendableComponent,
7
+ MessageSnackbar,
8
+ Button,
9
+ iconChevronRight,
10
+ } from '@graphcommerce/next-ui'
6
11
  import { i18n } from '@lingui/core'
7
- import { SxProps, Theme, IconButton } from '@mui/material'
12
+ import { Trans } from '@lingui/react'
13
+ import { SxProps, Theme, IconButton, Box } from '@mui/material'
14
+ import PageLink from 'next/link'
8
15
  import { useState, useEffect } from 'react'
9
16
  import { useWishlistEnabled } from '../../hooks'
10
17
  import { AddProductToWishlistDocument } from '../../queries/AddProductToWishlist.gql'
@@ -19,34 +26,43 @@ const ignoreProductWishlistStatus =
19
26
 
20
27
  export type ProductWishlistChipProps = ProductWishlistChipFragment & { sx?: SxProps<Theme> } & {
21
28
  selectedOptions?: string[]
29
+ showFeedbackMessage?: boolean
22
30
  }
23
31
 
24
- const name = 'ProductWishlistChipBase' as const
32
+ const compName = 'ProductWishlistChipBase' as const
25
33
  const parts = ['root', 'wishlistIcon', 'wishlistIconActive', 'wishlistButton'] as const
26
- const { classes } = extendableComponent(name, parts)
34
+ const { classes } = extendableComponent(compName, parts)
27
35
 
28
36
  export function ProductWishlistChipBase(props: ProductWishlistChipProps) {
29
- const { sku, selectedOptions = [], sx = [] } = props
37
+ const { name, sku, showFeedbackMessage, selectedOptions = [], sx = [] } = props
30
38
 
31
39
  const [inWishlist, setInWishlist] = useState(false)
40
+ const [displayMessageBar, setDisplayMessageBar] = useState(false)
32
41
 
33
42
  const { data: token } = useQuery(CustomerTokenDocument)
43
+ const [addWishlistItem] = useMutation(AddProductToWishlistDocument)
44
+ const [removeWishlistItem] = useMutation(RemoveProductFromWishlistDocument)
34
45
  const isLoggedIn = token?.customerToken && token?.customerToken.valid
35
46
 
47
+ const { data: GetCustomerWishlistData, loading } = useQuery(GetIsInWishlistsDocument, {
48
+ skip: !isLoggedIn,
49
+ })
50
+
51
+ const { data: guestWishlistData } = useQuery(GuestWishlistDocument, {
52
+ ssr: false,
53
+ skip: isLoggedIn === true,
54
+ })
55
+
36
56
  const { cache } = useApolloClient()
37
57
 
38
58
  const isWishlistEnabled = useWishlistEnabled()
39
59
 
40
- if (!isWishlistEnabled) {
41
- return null
42
- }
43
-
44
60
  const heart = (
45
61
  <IconSvg
46
62
  src={iconHeart}
47
63
  size='medium'
48
64
  className={classes.wishlistIcon}
49
- sx={(theme) => ({ color: theme.palette.primary.main })}
65
+ // sx={(theme) => ({ color: theme.palette.primary.main })}
50
66
  />
51
67
  )
52
68
 
@@ -59,18 +75,6 @@ export function ProductWishlistChipBase(props: ProductWishlistChipProps) {
59
75
  />
60
76
  )
61
77
 
62
- const { data: GetCustomerWishlistData, loading } = useQuery(GetIsInWishlistsDocument, {
63
- skip: !isLoggedIn,
64
- })
65
-
66
- const { data: guestWishlistData, loading: loadingGuestWishlistData } = useQuery(
67
- GuestWishlistDocument,
68
- {
69
- ssr: false,
70
- skip: isLoggedIn === true,
71
- },
72
- )
73
-
74
78
  useEffect(() => {
75
79
  // Do not display wishlist UI to guests when configured as customer only
76
80
  if (hideForGuest && !isLoggedIn) {
@@ -94,9 +98,6 @@ export function ProductWishlistChipBase(props: ProductWishlistChipProps) {
94
98
  }
95
99
  }, [isLoggedIn, sku, loading, GetCustomerWishlistData, guestWishlistData])
96
100
 
97
- const [addWishlistItem] = useMutation(AddProductToWishlistDocument)
98
- const [removeWishlistItem] = useMutation(RemoveProductFromWishlistDocument)
99
-
100
101
  const preventAnimationBubble: React.MouseEventHandler<HTMLButtonElement> = (e) => {
101
102
  e.preventDefault()
102
103
  e.stopPropagation()
@@ -114,15 +115,18 @@ export function ProductWishlistChipBase(props: ProductWishlistChipProps) {
114
115
  const wishlistItemsInSession =
115
116
  GetCustomerWishlistData?.customer?.wishlists[0]?.items_v2?.items || []
116
117
 
117
- const item = wishlistItemsInSession.find((element) => element?.product?.sku == sku)
118
+ const item = wishlistItemsInSession.find((element) => element?.product?.sku === sku)
118
119
 
119
120
  if (item?.id) {
121
+ // eslint-disable-next-line @typescript-eslint/no-floating-promises
120
122
  removeWishlistItem({ variables: { wishlistItemId: item.id } })
121
123
  }
122
124
  } else {
125
+ // eslint-disable-next-line @typescript-eslint/no-floating-promises
123
126
  addWishlistItem({
124
127
  variables: { input: { sku, quantity: 1, selected_options: selectedOptions } },
125
128
  })
129
+ setDisplayMessageBar(true)
126
130
  }
127
131
  } else if (inWishlist) {
128
132
  cache.modify({
@@ -153,36 +157,67 @@ export function ProductWishlistChipBase(props: ProductWishlistChipProps) {
153
157
  },
154
158
  broadcast: true,
155
159
  })
160
+ setDisplayMessageBar(true)
156
161
  }
157
162
  }
158
163
 
159
- const button = (
160
- <IconButton
161
- key={sku}
162
- onClick={handleClick}
163
- onMouseDown={preventAnimationBubble}
164
- size='small'
165
- className={classes.wishlistButton}
166
- sx={[
167
- (theme) => ({
168
- padding: theme.spacings.xxs,
169
- }),
170
- ...(Array.isArray(sx) ? sx : [sx]),
171
- ]}
172
- title={
173
- inWishlist
174
- ? i18n._(/* i18n */ `Remove from wishlist`)
175
- : i18n._(/* i18n */ `Add to wishlist`)
176
- }
177
- aria-label={
178
- inWishlist
179
- ? i18n._(/* i18n */ `Remove from wishlist`)
180
- : i18n._(/* i18n */ `Add to wishlist`)
181
- }
182
- >
183
- {inWishlist ? activeHeart : heart}
184
- </IconButton>
164
+ const output = (
165
+ <Box>
166
+ <IconButton
167
+ key={sku}
168
+ onClick={handleClick}
169
+ onMouseDown={preventAnimationBubble}
170
+ size='small'
171
+ className={classes.wishlistButton}
172
+ sx={[
173
+ (theme) => ({
174
+ padding: theme.spacings.xxs,
175
+ }),
176
+ ...(Array.isArray(sx) ? sx : [sx]),
177
+ ]}
178
+ title={
179
+ inWishlist
180
+ ? i18n._(/* i18n */ `Remove from wishlist`)
181
+ : i18n._(/* i18n */ `Add to wishlist`)
182
+ }
183
+ aria-label={
184
+ inWishlist
185
+ ? i18n._(/* i18n */ `Remove from wishlist`)
186
+ : i18n._(/* i18n */ `Add to wishlist`)
187
+ }
188
+ >
189
+ {inWishlist ? activeHeart : heart}
190
+ </IconButton>
191
+
192
+ <MessageSnackbar
193
+ open={showFeedbackMessage && displayMessageBar}
194
+ variant='pill'
195
+ action={
196
+ <PageLink href='/wishlist' passHref>
197
+ <Button
198
+ id='view-wishlist-button'
199
+ size='medium'
200
+ variant='pill'
201
+ color='secondary'
202
+ endIcon={<IconSvg src={iconChevronRight} />}
203
+ >
204
+ <Trans id='View wishlist' />
205
+ </Button>
206
+ </PageLink>
207
+ }
208
+ >
209
+ <Trans
210
+ id='<0>{name}</0> has been added to your wishlist!'
211
+ components={{ 0: <strong /> }}
212
+ values={{ name }}
213
+ />
214
+ </MessageSnackbar>
215
+ </Box>
185
216
  )
186
217
 
187
- return !hideForGuest || isLoggedIn ? button : null
218
+ return !hideForGuest || isLoggedIn ? output : null
219
+ }
220
+
221
+ ProductWishlistChipBase.defaultProps = {
222
+ showFeedbackMessage: false,
188
223
  }
@@ -3,11 +3,11 @@ import { ProductWishlistChipBase, ProductWishlistChipProps } from './ProductWish
3
3
 
4
4
  export function ProductWishlistChipDetailConfigurable(props: ProductWishlistChipProps) {
5
5
  const { sku } = props
6
+ const context = useConfigurableContext(sku ?? '')
6
7
 
7
8
  let selectedOptions: string[] = []
9
+
8
10
  if (sku) {
9
- // eslint-disable-next-line react-hooks/rules-of-hooks
10
- const context = useConfigurableContext(sku)
11
11
  selectedOptions = (Object as any).values(context.selection)
12
12
  }
13
13
 
@@ -1,7 +1,4 @@
1
- /* eslint-disable @typescript-eslint/no-floating-promises */
2
- /* eslint-disable react-hooks/rules-of-hooks */
3
1
  import { SxProps, Theme } from '@mui/material'
4
-
5
2
  import { PropsWithChildren } from 'react'
6
3
  import { ProductAddToCart } from './ProductAddToCart'
7
4
  import { WishlistItemBase } from './WishlistItemBase'
@@ -1,14 +1,10 @@
1
- /* eslint-disable @typescript-eslint/no-floating-promises */
2
- /* eslint-disable react-hooks/rules-of-hooks */
3
1
  import { useQuery, useMutation, useApolloClient } from '@graphcommerce/graphql'
4
2
  import { Image } from '@graphcommerce/image'
5
- import { useDisplayInclTax } from '@graphcommerce/magento-cart'
6
3
  import { CustomerTokenDocument } from '@graphcommerce/magento-customer'
7
4
  import { useProductLink } from '@graphcommerce/magento-product'
8
5
  import { Money } from '@graphcommerce/magento-store'
9
6
  import { responsiveVal, extendableComponent, iconEllypsis, IconSvg } from '@graphcommerce/next-ui'
10
7
  import { Trans } from '@lingui/react'
11
- import { i18n } from '@lingui/core'
12
8
  import { Badge, Box, Link, SxProps, Theme, Typography } from '@mui/material'
13
9
  import IconButton from '@mui/material/IconButton'
14
10
  import Menu from '@mui/material/Menu'
@@ -59,13 +55,12 @@ export function WishlistItemBase(props: WishlistItemBaseProps) {
59
55
  } = props
60
56
 
61
57
  const productLink = useProductLink({ url_key, __typename: productType })
62
- const inclTaxes = useDisplayInclTax()
63
58
  const { cache } = useApolloClient()
64
59
 
65
60
  const { data: token } = useQuery(CustomerTokenDocument)
66
61
  const isLoggedIn = token?.customerToken && token?.customerToken.valid
67
62
 
68
- const { data: GetCustomerWishlistData, loading } = useQuery(GetIsInWishlistsDocument, {
63
+ const { data: GetCustomerWishlistData } = useQuery(GetIsInWishlistsDocument, {
69
64
  skip: !isLoggedIn,
70
65
  })
71
66
 
@@ -74,6 +69,7 @@ export function WishlistItemBase(props: WishlistItemBaseProps) {
74
69
  const [anchorEl, setAnchorEl] = useState(null)
75
70
  const open = Boolean(anchorEl)
76
71
  const handleClick = (event) => {
72
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-argument
77
73
  setAnchorEl(event.currentTarget)
78
74
  }
79
75
 
@@ -94,6 +90,7 @@ export function WishlistItemBase(props: WishlistItemBaseProps) {
94
90
  }
95
91
 
96
92
  if (itemIdToDelete) {
93
+ // eslint-disable-next-line @typescript-eslint/no-floating-promises
97
94
  removeWishlistItem({ variables: { wishlistItemId: itemIdToDelete } })
98
95
  }
99
96
  } else {
@@ -170,7 +167,7 @@ export function WishlistItemBase(props: WishlistItemBaseProps) {
170
167
  vertical: 'top',
171
168
  horizontal: 'left',
172
169
  }}
173
- sx={(theme) => ({
170
+ sx={() => ({
174
171
  gridArea: 'picture',
175
172
  width: rowImageSize,
176
173
  height: rowImageSize,
@@ -234,7 +231,7 @@ export function WishlistItemBase(props: WishlistItemBaseProps) {
234
231
  variant='body1'
235
232
  className={classes.root}
236
233
  sx={[
237
- (theme) => ({ gridArea: 'itemPrice', marginLeft: 'auto' }),
234
+ () => ({ gridArea: 'itemPrice', marginLeft: 'auto' }),
238
235
  ...(Array.isArray(sx) ? sx : [sx]),
239
236
  ]}
240
237
  >
@@ -262,7 +259,7 @@ export function WishlistItemBase(props: WishlistItemBaseProps) {
262
259
  aria-expanded={open ? 'true' : undefined}
263
260
  aria-haspopup='true'
264
261
  onClick={handleClick}
265
- sx={(theme) => ({
262
+ sx={() => ({
266
263
  gridArea: 'iconMenu',
267
264
  alignSelf: 'flex-start',
268
265
  padding: '0',
@@ -1,5 +1,4 @@
1
1
  import { WishlistItem, WishlistItemProps } from './WishlistItem'
2
- import { WishlistItemFragment } from './WishlistItem.gql'
3
2
  import { WishlistItemConfigurableFragment } from './WishlistItemConfigurable.gql'
4
3
 
5
4
  export function WishlistItemConfigurable(
@@ -21,18 +21,15 @@ function WishlistMenuFabItemContent(props: WishlistMenuFabItemProps) {
21
21
  const { data: token } = useQuery(CustomerTokenDocument)
22
22
  const isLoggedIn = token?.customerToken && token?.customerToken.valid
23
23
 
24
- const { data: GetCustomerWishlistData, loading } = useQuery(GetIsInWishlistsDocument, {
24
+ const { data: GetCustomerWishlistData } = useQuery(GetIsInWishlistsDocument, {
25
25
  ssr: false,
26
26
  skip: !isLoggedIn,
27
27
  })
28
28
 
29
- const { data: guestWishlistData, loading: loadingGuestWishlistData } = useQuery(
30
- GuestWishlistDocument,
31
- {
32
- ssr: false,
33
- skip: isLoggedIn === true,
34
- },
35
- )
29
+ const { data: guestWishlistData } = useQuery(GuestWishlistDocument, {
30
+ ssr: false,
31
+ skip: isLoggedIn === true,
32
+ })
36
33
 
37
34
  let activeWishlist
38
35
  if (isLoggedIn) {
@@ -1,8 +1,5 @@
1
- /* eslint-disable react-hooks/exhaustive-deps */
2
- /* eslint-disable @typescript-eslint/no-floating-promises */
3
- /* eslint-disable react-hooks/rules-of-hooks */
4
1
  import { useMutation, useQuery, useApolloClient } from '@graphcommerce/graphql'
5
- import { CustomerTokenDocument } from '@graphcommerce/magento-customer'
2
+ import { useCustomerSession } from '@graphcommerce/magento-customer'
6
3
  import { useEffect } from 'react'
7
4
  import { AddProductToWishlistDocument } from '../queries/AddProductToWishlist.gql'
8
5
  import { GetGuestWishlistProductsDocument } from '../queries/GetGuestWishlistProducts.gql'
@@ -10,55 +7,34 @@ import { GuestWishlistDocument } from '../queries/GuestWishlist.gql'
10
7
 
11
8
  /** Merge guest wishlist items to customer session upon login */
12
9
  export function useMergeGuestWishlistWithCustomer() {
13
- const customerToken = useQuery(CustomerTokenDocument)?.data?.customerToken
14
- const isLoggedIn = customerToken?.token && customerToken?.valid
10
+ const { loggedIn } = useCustomerSession()
15
11
  const { cache } = useApolloClient()
16
12
 
17
- const guestWishlistData = useQuery(GuestWishlistDocument, {
18
- ssr: false,
19
- }).data?.guestWishlist
13
+ const guestSkus = useQuery(GuestWishlistDocument, { ssr: false }).data?.guestWishlist?.items
20
14
 
21
- const guestDataSkus = guestWishlistData?.items.map((item) => item?.sku) || []
22
- // eslint-disable-next-line react-hooks/exhaustive-deps
23
- const validatedItems =
24
- useQuery(GetGuestWishlistProductsDocument, {
25
- ssr: false,
26
- variables: {
27
- filters: { sku: { in: guestDataSkus } },
28
- },
29
- skip: guestDataSkus.length === 0,
30
- }).data?.products?.items?.map((item) => item?.sku) || []
15
+ const guestProducts = useQuery(GetGuestWishlistProductsDocument, {
16
+ ssr: false,
17
+ variables: { filters: { sku: { in: guestSkus?.map((item) => item?.sku) } } },
18
+ skip: guestSkus && guestSkus?.length === 0,
19
+ }).data?.products?.items
31
20
 
32
21
  const [addWishlistItem] = useMutation(AddProductToWishlistDocument)
33
22
 
34
23
  useEffect(() => {
35
- if (!isLoggedIn) return
24
+ if (!loggedIn || !guestSkus || guestSkus.length === 0) return
36
25
 
37
- if (!guestDataSkus.length) return
38
-
39
- if (!validatedItems.length) {
40
- /** Only outdated items were found, purge them */
41
- cache.evict({
42
- id: cache.identify({ __typename: 'GuestWishlist' }),
43
- })
44
- return
45
- }
26
+ const clearGuestList = () =>
27
+ cache.evict({ id: cache.identify({ __typename: 'GuestWishlist' }) })
46
28
 
47
- const wishlist =
48
- guestWishlistData?.items.filter((item) => validatedItems.includes(item.sku)) || []
29
+ if (guestProducts?.length === 0) {
30
+ clearGuestList()
31
+ } else {
32
+ const input = guestSkus
33
+ .filter((item) => guestProducts?.find((i) => i?.sku === item.sku))
34
+ .map(({ sku, selected_options, quantity }) => ({ sku, selected_options, quantity }))
49
35
 
50
- if (!wishlist.length) return
51
-
52
- const payload = wishlist.map((item) => ({
53
- sku: item.sku,
54
- selected_options: item.selected_options,
55
- quantity: item.quantity,
56
- }))
57
-
58
- addWishlistItem({ variables: { input: payload } }).then(() =>
59
- cache.evict({
60
- id: cache.identify({ __typename: 'GuestWishlist' }),
61
- })
62
- )
63
- }, [isLoggedIn])
36
+ // eslint-disable-next-line @typescript-eslint/no-floating-promises
37
+ if (input.length) addWishlistItem({ variables: { input } }).then(clearGuestList)
38
+ }
39
+ }, [addWishlistItem, cache, guestProducts, guestSkus, loggedIn])
64
40
  }
@@ -1,53 +1,35 @@
1
1
  import { useQuery } from '@graphcommerce/graphql'
2
- import { CustomerTokenDocument } from '@graphcommerce/magento-customer'
2
+ import { useCustomerSession } from '@graphcommerce/magento-customer'
3
3
  import { GetGuestWishlistProductsDocument } from '../queries/GetGuestWishlistProducts.gql'
4
4
  import { GetWishlistProductsDocument } from '../queries/GetWishlistProducts.gql'
5
5
  import { GuestWishlistDocument } from '../queries/GuestWishlist.gql'
6
6
 
7
7
  export function useWishlistItems() {
8
- const { data: token } = useQuery(CustomerTokenDocument)
9
- const isLoggedIn = token?.customerToken && token?.customerToken.valid
8
+ const { loggedIn } = useCustomerSession()
10
9
 
11
10
  let wishlistItems
12
11
 
13
12
  /** Get customer wishlist from session */
14
- const { data: GetCustomerWishlistData, loading: loadingCustomerItems } = useQuery(
15
- GetWishlistProductsDocument,
16
- {
17
- skip: !isLoggedIn,
18
- ssr: false,
19
- },
20
- )
13
+ const customerWl = useQuery(GetWishlistProductsDocument, { ssr: false, skip: !loggedIn })
21
14
 
22
15
  /** Get guest wishlist items from cache and hydrate with catalog data */
23
- const { data: guestWishlistData, loading: loadingGuestWishlistData } = useQuery(
24
- GuestWishlistDocument,
25
- {
26
- ssr: false,
27
- skip: isLoggedIn === true,
28
- },
29
- )
30
- const guestData = guestWishlistData?.guestWishlist?.items.map((item) => item?.sku) || []
16
+ const guestWl = useQuery(GuestWishlistDocument, { ssr: false, skip: loggedIn })
17
+ const guestSkus = guestWl.data?.guestWishlist?.items.map((item) => item?.sku) || []
31
18
 
32
- const { data: productGuestItems, loading: loadingGuestItems } = useQuery(
33
- GetGuestWishlistProductsDocument,
34
- {
35
- ssr: false,
36
- variables: {
37
- filters: { sku: { in: guestData } },
38
- },
39
- skip: loadingGuestWishlistData || guestData.length === 0,
40
- },
41
- )
19
+ const guestProducts = useQuery(GetGuestWishlistProductsDocument, {
20
+ ssr: false,
21
+ variables: { filters: { sku: { in: guestSkus } } },
22
+ skip: guestSkus.length === 0,
23
+ })
42
24
 
43
- if (isLoggedIn) {
44
- wishlistItems = GetCustomerWishlistData?.customer?.wishlists[0]?.items_v2?.items
25
+ if (loggedIn) {
26
+ wishlistItems = customerWl.data?.customer?.wishlists[0]?.items_v2?.items
45
27
  } else {
46
- wishlistItems = productGuestItems?.products?.items || []
28
+ wishlistItems = guestProducts.data?.products?.items || []
47
29
  }
48
30
 
49
31
  return {
50
32
  items: wishlistItems,
51
- loading: loadingGuestWishlistData || loadingGuestItems || loadingCustomerItems,
33
+ loading: guestWl.loading || guestProducts.loading || customerWl.loading,
52
34
  }
53
35
  }
package/next-env.d.ts ADDED
@@ -0,0 +1,4 @@
1
+ /// <reference types="next" />
2
+ /// <reference types="next/types/global" />
3
+ /// <reference types="next/image-types/global" />
4
+ /// <reference types="@graphcommerce/next-ui/types" />
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@graphcommerce/magento-wishlist",
3
- "version": "1.0.3",
3
+ "version": "1.1.0",
4
4
  "sideEffects": false,
5
5
  "prettier": "@graphcommerce/prettier-config-pwa",
6
6
  "browserslist": [
@@ -20,13 +20,14 @@
20
20
  },
21
21
  "dependencies": {
22
22
  "@graphcommerce/graphql": "3.1.3",
23
+ "@graphcommerce/graphql-mesh": "4.1.3",
23
24
  "@graphcommerce/image": "3.1.5",
24
- "@graphcommerce/magento-cart": "4.2.13",
25
- "@graphcommerce/magento-customer": "4.2.11",
26
- "@graphcommerce/magento-product": "4.3.3",
27
- "@graphcommerce/magento-product-configurable": "4.1.3",
28
- "@graphcommerce/magento-store": "4.2.2",
29
- "@graphcommerce/next-ui": "4.7.2"
25
+ "@graphcommerce/magento-cart": "4.2.15",
26
+ "@graphcommerce/magento-customer": "4.3.0",
27
+ "@graphcommerce/magento-product": "4.3.5",
28
+ "@graphcommerce/magento-product-configurable": "4.1.5",
29
+ "@graphcommerce/magento-store": "4.2.4",
30
+ "@graphcommerce/next-ui": "4.8.0"
30
31
  },
31
32
  "peerDependencies": {
32
33
  "@lingui/react": "^3.13.2",
@@ -1,10 +1,4 @@
1
- type WishlistItemInput {
2
- sku: String
3
- quantity: Int!
4
- selected_options: [ID]
5
- }
6
-
7
- mutation addProductToWishlist($input: [WishlistItemInput!]!) {
1
+ mutation AddProductToWishlist($input: [WishlistItemInput!]!) {
8
2
  addProductsToWishlist(wishlistId: 0, wishlistItems: $input) {
9
3
  wishlist {
10
4
  ...WishlistSummaryFragment
@@ -8,6 +8,7 @@ query GetWishlistProducts {
8
8
  id
9
9
  ...WishlistItem
10
10
  product {
11
+ __typename
11
12
  uid
12
13
  sku
13
14
  ...ProductListItem
@@ -1,4 +1,4 @@
1
- mutation removeProductFromWishlist($wishlistItemId: ID!) {
1
+ mutation RemoveProductFromWishlist($wishlistItemId: ID!) {
2
2
  removeProductsFromWishlist(wishlistId: 0, wishlistItemsIds: [$wishlistItemId]) {
3
3
  wishlist {
4
4
  ...WishlistSummaryFragment