@graphcommerce/magento-wishlist 1.6.11 → 1.7.1

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,35 @@
1
1
  # @graphcommerce/magento-wishlist
2
2
 
3
+ ## 1.7.1
4
+
5
+ ### Patch Changes
6
+
7
+ - Updated dependencies [[`48e6522bb`](https://github.com/graphcommerce-org/graphcommerce/commit/48e6522bb9424d4bd77fd77c68065f5625f3ec8d), [`37b1980a0`](https://github.com/graphcommerce-org/graphcommerce/commit/37b1980a04a4a3d77663b404ae83539620cf65b9)]:
8
+ - @graphcommerce/magento-product@4.6.1
9
+ - @graphcommerce/magento-product-configurable@4.3.1
10
+ - @graphcommerce/magento-cart@4.8.5
11
+ - @graphcommerce/magento-customer@4.11.5
12
+
13
+ ## 1.7.0
14
+
15
+ ### Minor Changes
16
+
17
+ - [#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.
18
+
19
+ Which allows you to fully compose the form on the product page without having to modify the page.
20
+
21
+ * [#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
22
+
23
+ ### Patch Changes
24
+
25
+ - 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)]:
26
+ - @graphcommerce/magento-product@4.6.0
27
+ - @graphcommerce/magento-product-configurable@4.3.0
28
+ - @graphcommerce/magento-store@4.3.0
29
+ - @graphcommerce/next-ui@4.27.0
30
+ - @graphcommerce/magento-cart@4.8.4
31
+ - @graphcommerce/magento-customer@4.11.4
32
+
3
33
  ## 1.6.11
4
34
 
5
35
  ### Patch Changes
@@ -1,4 +1,5 @@
1
1
  fragment ProductWishlistChip on ProductInterface {
2
2
  name
3
3
  sku
4
+ url_key
4
5
  }
@@ -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, showFeedbackMessage, selectedOptions = [], buttonProps, sx = [] } = props
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?.sku,
104
+ (item) => item?.product?.url_key,
97
105
  ) || []
98
- setInWishlist(inWishlistTest.includes(sku))
106
+ setInWishlist(inWishlistTest.includes(url_key))
99
107
  } else if (!loggedIn) {
100
- const inWishlistTest = guestWishlistData?.guestWishlist?.items.map((item) => item?.sku) || []
101
- setInWishlist(inWishlistTest.includes(sku))
108
+ const inWishlistTest =
109
+ guestWishlistData?.guestWishlist?.items.map((item) => item?.url_key) || []
110
+ setInWishlist(inWishlistTest.includes(url_key))
102
111
  }
103
- }, [loggedIn, sku, loading, GetCustomerWishlistData, guestWishlistData])
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
- if (!sku) {
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?.sku === sku)
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.sku !== sku)
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: selectedOptions,
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={sku}
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
- const { sku } = props
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<InputMaybe<string> | InputMaybe<string>[]> | undefined
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((element) => element?.product?.sku === sku)
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.items?.map((item) => {
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 guestSkus = useQuery(GuestWishlistDocument, { ssr: false }).data?.guestWishlist?.items
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: { sku: { in: guestSkus?.map((item) => item?.sku) } } },
18
- skip: guestSkus && guestSkus?.length === 0,
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 || !guestSkus || guestSkus.length === 0) return
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 = guestSkus
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, guestSkus, loggedIn])
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 { GetGuestWishlistProductsDocument } from '../queries/GetGuestWishlistProducts.gql'
4
- import { GetWishlistProductsDocument } from '../queries/GetWishlistProducts.gql'
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
- export function useWishlistItems() {
8
- const { loggedIn } = useCustomerSession()
9
-
10
- let wishlistItems
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
- if (loggedIn) {
26
- wishlistItems = customerWl.data?.customer?.wishlists[0]?.items_v2?.items
27
- } else {
28
- wishlistItems = guestProducts.data?.products?.items || []
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
- items: wishlistItems,
33
- loading: guestWl.loading || guestProducts.loading || customerWl.loading,
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.6.11",
3
+ "version": "1.7.1",
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.3",
26
- "@graphcommerce/magento-customer": "4.11.3",
27
- "@graphcommerce/magento-product": "4.5.10",
28
- "@graphcommerce/magento-product-configurable": "4.2.11",
29
- "@graphcommerce/magento-store": "4.2.35",
30
- "@graphcommerce/next-ui": "4.26.0"
25
+ "@graphcommerce/magento-cart": "4.8.5",
26
+ "@graphcommerce/magento-customer": "4.11.5",
27
+ "@graphcommerce/magento-product": "4.6.1",
28
+ "@graphcommerce/magento-product-configurable": "4.3.1",
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",
@@ -4,6 +4,7 @@ query GuestWishlist {
4
4
  items {
5
5
  __typename
6
6
  sku
7
+ url_key
7
8
  selected_options
8
9
  quantity
9
10
  }
@@ -8,6 +8,7 @@ type GuestWishlist {
8
8
 
9
9
  type GuestWishlistItem {
10
10
  sku: String!
11
+ url_key: String!
11
12
  selected_options: [ID]
12
13
  quantity: Float!
13
14
  }
@@ -6,7 +6,7 @@ fragment WishlistSummaryFragment on Wishlist {
6
6
  id
7
7
  product {
8
8
  uid
9
- sku
9
+ url_key
10
10
  }
11
11
  }
12
12
  }