@graphcommerce/magento-cart 4.13.3 → 4.14.0-canary.10
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 +26 -2
- package/components/CartStartCheckout/CartStartCheckout.tsx +17 -7
- package/components/CartStartCheckout/CartStartCheckoutLinkOrButton.tsx +45 -0
- package/components/CartStartCheckout/index.ts +2 -0
- package/components/index.ts +1 -1
- package/link/createCartErrorLink.ts +41 -39
- package/package.json +12 -12
- package/plugins/MagentoCartGraphqlProvider.tsx +21 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,8 +1,32 @@
|
|
|
1
1
|
# Change Log
|
|
2
2
|
|
|
3
|
-
## 4.
|
|
3
|
+
## 4.14.0-canary.10
|
|
4
4
|
|
|
5
|
-
## 4.
|
|
5
|
+
## 4.14.0-canary.9
|
|
6
|
+
|
|
7
|
+
## 4.14.0-canary.8
|
|
8
|
+
|
|
9
|
+
## 4.14.0-canary.7
|
|
10
|
+
|
|
11
|
+
## 4.14.0-canary.6
|
|
12
|
+
|
|
13
|
+
## 4.14.0-canary.5
|
|
14
|
+
|
|
15
|
+
## 4.14.0-canary.4
|
|
16
|
+
|
|
17
|
+
### Minor Changes
|
|
18
|
+
|
|
19
|
+
- [#1733](https://github.com/graphcommerce-org/graphcommerce/pull/1733) [`761bd2832`](https://github.com/graphcommerce-org/graphcommerce/commit/761bd2832f115afc8b95bedbf479266309dd5acc) - ApolloLinks, typePolicies and migration scripts are now handled with plugins on the new library component `<GraphQLProvider/>`. Hygraph's, Magento Cart, Customer, Store, Wishlist and Magento GraphQL are all migrated to be using plugins.
|
|
20
|
+
|
|
21
|
+
If you are using custom `links` / `policies` / `migrations` you can pass them as props to the `<GraphQLProvider/>` or create your own local plugin. ([@paales](https://github.com/paales))
|
|
22
|
+
|
|
23
|
+
## 4.14.0-canary.3
|
|
24
|
+
|
|
25
|
+
## 4.14.0-canary.2
|
|
26
|
+
|
|
27
|
+
## 4.13.2-canary.1
|
|
28
|
+
|
|
29
|
+
## 4.13.2-canary.0
|
|
6
30
|
|
|
7
31
|
## 4.13.1
|
|
8
32
|
|
|
@@ -3,12 +3,14 @@ import { iconChevronRight, IconSvg, extendableComponent } from '@graphcommerce/n
|
|
|
3
3
|
import { Trans } from '@lingui/react'
|
|
4
4
|
import { Box, Button, ButtonProps, SxProps, Theme } from '@mui/material'
|
|
5
5
|
import PageLink from 'next/link'
|
|
6
|
+
import React from 'react'
|
|
6
7
|
import { CartStartCheckoutFragment } from './CartStartCheckout.gql'
|
|
7
8
|
|
|
8
9
|
export type CartStartCheckoutProps = CartStartCheckoutFragment & {
|
|
9
10
|
children?: React.ReactNode
|
|
10
11
|
sx?: SxProps<Theme>
|
|
11
12
|
buttonProps?: ButtonProps<'button'>
|
|
13
|
+
onStart?: (e: React.MouseEvent<HTMLButtonElement>, cart: CartStartCheckoutFragment) => void
|
|
12
14
|
}
|
|
13
15
|
|
|
14
16
|
const name = 'CartStartCheckout' as const
|
|
@@ -21,17 +23,20 @@ const parts = [
|
|
|
21
23
|
const { classes } = extendableComponent(name, parts)
|
|
22
24
|
|
|
23
25
|
export function CartStartCheckout(props: CartStartCheckoutProps) {
|
|
24
|
-
const {
|
|
26
|
+
const {
|
|
27
|
+
children,
|
|
28
|
+
onStart,
|
|
29
|
+
buttonProps: { onClick, ...buttonProps } = {},
|
|
30
|
+
sx = [],
|
|
31
|
+
...cart
|
|
32
|
+
} = props
|
|
25
33
|
|
|
26
|
-
const hasTotals = (prices?.grand_total?.value ?? 0) > 0
|
|
34
|
+
const hasTotals = (cart.prices?.grand_total?.value ?? 0) > 0
|
|
27
35
|
return (
|
|
28
36
|
<Box
|
|
29
37
|
className={classes.checkoutButtonContainer}
|
|
30
38
|
sx={[
|
|
31
|
-
(theme) => ({
|
|
32
|
-
textAlign: 'center',
|
|
33
|
-
my: theme.spacings.md,
|
|
34
|
-
}),
|
|
39
|
+
(theme) => ({ textAlign: 'center', my: theme.spacings.md }),
|
|
35
40
|
...(Array.isArray(sx) ? sx : [sx]),
|
|
36
41
|
]}
|
|
37
42
|
>
|
|
@@ -45,6 +50,11 @@ export function CartStartCheckout(props: CartStartCheckoutProps) {
|
|
|
45
50
|
className={classes.checkoutButton}
|
|
46
51
|
endIcon={<IconSvg src={iconChevronRight} />}
|
|
47
52
|
{...buttonProps}
|
|
53
|
+
onClick={(e) => {
|
|
54
|
+
onClick?.(e)
|
|
55
|
+
onStart?.(e, cart)
|
|
56
|
+
return onClick?.(e)
|
|
57
|
+
}}
|
|
48
58
|
disabled={!hasTotals || buttonProps?.disabled}
|
|
49
59
|
>
|
|
50
60
|
<Box
|
|
@@ -59,7 +69,7 @@ export function CartStartCheckout(props: CartStartCheckoutProps) {
|
|
|
59
69
|
</Box>{' '}
|
|
60
70
|
{hasTotals && (
|
|
61
71
|
<span className={classes.checkoutMoney}>
|
|
62
|
-
<Money {...prices?.grand_total} />
|
|
72
|
+
<Money {...cart.prices?.grand_total} />
|
|
63
73
|
</span>
|
|
64
74
|
)}
|
|
65
75
|
</Button>
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { iconChevronRight, IconSvg, LinkOrButton, LinkOrButtonProps } from '@graphcommerce/next-ui'
|
|
2
|
+
import { Trans } from '@lingui/react'
|
|
3
|
+
import { SxProps, Theme } from '@mui/material'
|
|
4
|
+
import PageLink from 'next/link'
|
|
5
|
+
import React from 'react'
|
|
6
|
+
import { CartStartCheckoutFragment } from './CartStartCheckout.gql'
|
|
7
|
+
|
|
8
|
+
export type CartStartCheckoutLinkOrButtonProps = CartStartCheckoutFragment & {
|
|
9
|
+
children?: React.ReactNode
|
|
10
|
+
sx?: SxProps<Theme>
|
|
11
|
+
onStart?: (
|
|
12
|
+
e: React.MouseEvent<HTMLButtonElement | HTMLAnchorElement>,
|
|
13
|
+
cart: CartStartCheckoutFragment,
|
|
14
|
+
) => void
|
|
15
|
+
linkOrButtonProps?: LinkOrButtonProps
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export function CartStartCheckoutLinkOrButton(props: CartStartCheckoutLinkOrButtonProps) {
|
|
19
|
+
const {
|
|
20
|
+
children,
|
|
21
|
+
onStart,
|
|
22
|
+
linkOrButtonProps: { onClick, button, ...linkOrButtonProps } = {},
|
|
23
|
+
...cart
|
|
24
|
+
} = props
|
|
25
|
+
|
|
26
|
+
const hasTotals = (cart.prices?.grand_total?.value ?? 0) > 0
|
|
27
|
+
|
|
28
|
+
return (
|
|
29
|
+
<PageLink href='/checkout' passHref>
|
|
30
|
+
<LinkOrButton
|
|
31
|
+
onClick={(e: React.MouseEvent<HTMLButtonElement | HTMLAnchorElement>) => {
|
|
32
|
+
onClick?.(e)
|
|
33
|
+
onStart?.(e, cart)
|
|
34
|
+
}}
|
|
35
|
+
button={{ variant: 'pill', ...button }}
|
|
36
|
+
disabled={!hasTotals}
|
|
37
|
+
color='secondary'
|
|
38
|
+
endIcon={<IconSvg src={iconChevronRight} />}
|
|
39
|
+
{...linkOrButtonProps}
|
|
40
|
+
>
|
|
41
|
+
<Trans id='Next' />
|
|
42
|
+
</LinkOrButton>
|
|
43
|
+
</PageLink>
|
|
44
|
+
)
|
|
45
|
+
}
|
package/components/index.ts
CHANGED
|
@@ -6,7 +6,7 @@ export * from './CartAgreementsForm/CartAgreements.gql'
|
|
|
6
6
|
export * from './CartAgreementsForm/CartAgreementsForm'
|
|
7
7
|
export * from './CartFab/CartFab'
|
|
8
8
|
export * from './CartItemSummary/CartItemSummary'
|
|
9
|
-
export * from './CartStartCheckout
|
|
9
|
+
export * from './CartStartCheckout'
|
|
10
10
|
export * from './CartSummary/CartSummary'
|
|
11
11
|
export * from './CartSummary/CartSummary.gql'
|
|
12
12
|
export * from './CartTotals/CartTotals'
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import {
|
|
2
2
|
ApolloClient,
|
|
3
3
|
fromPromise,
|
|
4
|
+
globalApolloClient,
|
|
4
5
|
NormalizedCacheObject,
|
|
5
6
|
onError,
|
|
6
7
|
Operation,
|
|
@@ -19,50 +20,51 @@ function errorIsIncluded(errorPath: readonly (string | number)[] | undefined, ke
|
|
|
19
20
|
return keys.some((value) => value === error)
|
|
20
21
|
}
|
|
21
22
|
|
|
22
|
-
export const
|
|
23
|
-
|
|
24
|
-
if (!clientRef.current) return undefined
|
|
23
|
+
export const cartErrorLink = onError(({ graphQLErrors, operation, forward }) => {
|
|
24
|
+
if (!globalApolloClient.current) return undefined
|
|
25
25
|
|
|
26
|
-
|
|
27
|
-
|
|
26
|
+
const client = globalApolloClient.current
|
|
27
|
+
const { cache } = client
|
|
28
28
|
|
|
29
|
-
|
|
29
|
+
if (!isCartOperation(operation) || !graphQLErrors) return undefined
|
|
30
30
|
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
31
|
+
const cartErr = graphQLErrors.find(
|
|
32
|
+
(err) =>
|
|
33
|
+
err.extensions?.category === 'graphql-no-such-entity' &&
|
|
34
|
+
errorIsIncluded(err.path, [
|
|
35
|
+
'cart',
|
|
36
|
+
'addProductsToCart',
|
|
37
37
|
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
38
|
+
/**
|
|
39
|
+
* These mutations can also throw the graphql-no-such-entity exception, however, we're not
|
|
40
|
+
* sure if it also throws for other types of entities.
|
|
41
|
+
*/
|
|
42
|
+
// 'removeItemFromCart',
|
|
43
|
+
// 'setBillingAddressOnCart',
|
|
44
|
+
// 'setGuestEmailOnCart',
|
|
45
|
+
// 'setPaymentMethodOnCart',
|
|
46
|
+
// 'setShippingAddressesOnCart',
|
|
47
|
+
// 'setShippingMethodsOnCart',
|
|
48
|
+
// 'updateCartItems',
|
|
49
|
+
// 'applyCouponToCart',
|
|
50
|
+
// 'removeCouponFromCart'
|
|
51
|
+
]),
|
|
52
|
+
)
|
|
53
53
|
|
|
54
|
-
|
|
54
|
+
if (!cartErr) return undefined
|
|
55
55
|
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
56
|
+
return fromPromise(client?.mutate({ mutation: CreateEmptyCartDocument }))
|
|
57
|
+
.filter((value) => Boolean(value))
|
|
58
|
+
.flatMap((cartData) => {
|
|
59
|
+
const cartId = cartData.data?.createEmptyCart
|
|
60
|
+
if (!cartId) return forward(operation)
|
|
61
61
|
|
|
62
|
-
|
|
63
|
-
|
|
62
|
+
writeCartId(cache, cartId)
|
|
63
|
+
operation.variables = { ...operation.variables, cartId }
|
|
64
64
|
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
65
|
+
// retry the request, returning the new observable
|
|
66
|
+
return forward(operation)
|
|
67
|
+
})
|
|
68
|
+
})
|
|
69
|
+
|
|
70
|
+
export const createCartErrorLink = () => cartErrorLink
|
package/package.json
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"name": "@graphcommerce/magento-cart",
|
|
3
3
|
"homepage": "https://www.graphcommerce.org/",
|
|
4
4
|
"repository": "github:graphcommerce-org/graphcommerce",
|
|
5
|
-
"version": "4.
|
|
5
|
+
"version": "4.14.0-canary.10",
|
|
6
6
|
"sideEffects": false,
|
|
7
7
|
"prettier": "@graphcommerce/prettier-config-pwa",
|
|
8
8
|
"eslintConfig": {
|
|
@@ -18,17 +18,17 @@
|
|
|
18
18
|
"@playwright/test": "^1.21.1"
|
|
19
19
|
},
|
|
20
20
|
"dependencies": {
|
|
21
|
-
"@graphcommerce/ecommerce-ui": "4.
|
|
22
|
-
"@graphcommerce/framer-utils": "4.
|
|
23
|
-
"@graphcommerce/framer-next-pages": "4.
|
|
24
|
-
"@graphcommerce/framer-scroller": "4.
|
|
25
|
-
"@graphcommerce/graphql": "4.
|
|
26
|
-
"@graphcommerce/image": "4.
|
|
27
|
-
"@graphcommerce/magento-customer": "4.
|
|
28
|
-
"@graphcommerce/magento-graphql": "4.
|
|
29
|
-
"@graphcommerce/magento-store": "4.
|
|
30
|
-
"@graphcommerce/next-ui": "4.
|
|
31
|
-
"@graphcommerce/react-hook-form": "4.
|
|
21
|
+
"@graphcommerce/ecommerce-ui": "4.31.0-canary.6",
|
|
22
|
+
"@graphcommerce/framer-utils": "4.31.0-canary.6",
|
|
23
|
+
"@graphcommerce/framer-next-pages": "4.31.0-canary.6",
|
|
24
|
+
"@graphcommerce/framer-scroller": "4.31.0-canary.6",
|
|
25
|
+
"@graphcommerce/graphql": "4.31.0-canary.6",
|
|
26
|
+
"@graphcommerce/image": "4.31.0-canary.6",
|
|
27
|
+
"@graphcommerce/magento-customer": "4.14.0-canary.10",
|
|
28
|
+
"@graphcommerce/magento-graphql": "4.14.0-canary.10",
|
|
29
|
+
"@graphcommerce/magento-store": "4.14.0-canary.10",
|
|
30
|
+
"@graphcommerce/next-ui": "4.31.0-canary.6",
|
|
31
|
+
"@graphcommerce/react-hook-form": "4.31.0-canary.6"
|
|
32
32
|
},
|
|
33
33
|
"peerDependencies": {
|
|
34
34
|
"@lingui/react": "^3.13.2",
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { GraphQLProviderProps } from '@graphcommerce/graphql'
|
|
2
|
+
import type { PluginProps } from '@graphcommerce/next-config'
|
|
3
|
+
import { cartErrorLink } from '../link/createCartErrorLink'
|
|
4
|
+
import { cartTypePolicies, migrateCart } from '../typePolicies'
|
|
5
|
+
|
|
6
|
+
export const component = 'GraphQLProvider'
|
|
7
|
+
export const exported = '@graphcommerce/graphql'
|
|
8
|
+
|
|
9
|
+
function MagentoCartGraphqlProvider(props: PluginProps<GraphQLProviderProps>) {
|
|
10
|
+
const { Prev, links = [], policies = [], migrations = [], ...rest } = props
|
|
11
|
+
return (
|
|
12
|
+
<Prev
|
|
13
|
+
{...rest}
|
|
14
|
+
links={[...links, cartErrorLink]}
|
|
15
|
+
policies={[...policies, cartTypePolicies]}
|
|
16
|
+
migrations={[...migrations, migrateCart]}
|
|
17
|
+
/>
|
|
18
|
+
)
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export const Plugin = MagentoCartGraphqlProvider
|