@graphcommerce/magento-cart 9.1.0-canary.54 → 9.1.0-canary.55
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 +16 -0
- package/components/CartIdContext.tsx +20 -0
- package/components/CartStartCheckout/CartStartCheckout.tsx +11 -9
- package/components/CartStartCheckout/CartStartCheckoutLinkOrButton.tsx +6 -6
- package/components/EmptyCart/EmptyCart.tsx +9 -5
- package/components/index.ts +2 -1
- package/hooks/useFormGqlMutationCart.ts +18 -11
- package/package.json +15 -15
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,21 @@
|
|
|
1
1
|
# Change Log
|
|
2
2
|
|
|
3
|
+
## 9.1.0-canary.55
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- [#2539](https://github.com/graphcommerce-org/graphcommerce/pull/2539) [`cf44b1f`](https://github.com/graphcommerce-org/graphcommerce/commit/cf44b1f723b7f2073a21abd6821768427cb95315) - Added hideTotals to MultiCartStartCheckout ([@paales](https://github.com/paales))
|
|
8
|
+
|
|
9
|
+
- [#2539](https://github.com/graphcommerce-org/graphcommerce/pull/2539) [`af4463d`](https://github.com/graphcommerce-org/graphcommerce/commit/af4463dcbc6903241c8804ffba2f43b2b8e1a00b) - When running a cart mutation and the cartId is already passed to the form we use that value instead of retrieving the current cart again. ([@paales](https://github.com/paales))
|
|
10
|
+
|
|
11
|
+
- [#2539](https://github.com/graphcommerce-org/graphcommerce/pull/2539) [`415f9fb`](https://github.com/graphcommerce-org/graphcommerce/commit/415f9fb50454fb20cb533235969dd9ab4ffc134b) - Allow setting the cartId in the form for useFormGqlMutationCart by setting the cartId in the form AND allow setting the cartId for a whole context by wrapping with CartIdProvider ([@paales](https://github.com/paales))
|
|
12
|
+
|
|
13
|
+
- [#2539](https://github.com/graphcommerce-org/graphcommerce/pull/2539) [`4e3f3f2`](https://github.com/graphcommerce-org/graphcommerce/commit/4e3f3f2df58638ba8ffc68ee9f274cdd6c45d6d4) - Allow setting the redirect value in the AddProductsToCartForm as a form value. ([@paales](https://github.com/paales))
|
|
14
|
+
|
|
15
|
+
- [#2539](https://github.com/graphcommerce-org/graphcommerce/pull/2539) [`af4463d`](https://github.com/graphcommerce-org/graphcommerce/commit/af4463dcbc6903241c8804ffba2f43b2b8e1a00b) - Solve issue where if the onBeforeSubmit would return false, it would still error if submitted while the cart is locked. ([@paales](https://github.com/paales))
|
|
16
|
+
|
|
17
|
+
- [#2539](https://github.com/graphcommerce-org/graphcommerce/pull/2539) [`1a06135`](https://github.com/graphcommerce-org/graphcommerce/commit/1a061357f4ccb430dd13194f755815474e140520) - Allow awaitable async requests for onStart on checkout button ([@paales](https://github.com/paales))
|
|
18
|
+
|
|
3
19
|
## 9.1.0-canary.54
|
|
4
20
|
|
|
5
21
|
## 9.1.0-canary.53
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { createContext, useContext } from 'react'
|
|
2
|
+
|
|
3
|
+
export const CartIdContext = createContext<string | null>(null)
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* By default we use the currently selected cartId.
|
|
7
|
+
*
|
|
8
|
+
* However in a MultiCart scenario we need to be able to switch the cartId in certain contexts.
|
|
9
|
+
*/
|
|
10
|
+
export function CartIdProvider(props: {
|
|
11
|
+
children: React.ReactNode
|
|
12
|
+
cartId: string | null | undefined
|
|
13
|
+
}) {
|
|
14
|
+
const { children, cartId } = props
|
|
15
|
+
return <CartIdContext.Provider value={cartId ?? null}>{children}</CartIdContext.Provider>
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export function useCartIdContext() {
|
|
19
|
+
return useContext(CartIdContext)
|
|
20
|
+
}
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import { Money } from '@graphcommerce/magento-store'
|
|
2
|
-
import {
|
|
2
|
+
import type { ButtonProps } from '@graphcommerce/next-ui'
|
|
3
|
+
import { Button, extendableComponent, iconChevronRight, IconSvg } from '@graphcommerce/next-ui'
|
|
3
4
|
import { Trans } from '@lingui/macro'
|
|
4
|
-
import type {
|
|
5
|
-
import { Box,
|
|
5
|
+
import type { SxProps, Theme } from '@mui/material'
|
|
6
|
+
import { Box, Link } from '@mui/material'
|
|
6
7
|
import React from 'react'
|
|
7
8
|
import { useCheckoutShouldLoginToContinue } from '../../hooks'
|
|
8
9
|
import type { CartStartCheckoutFragment } from './CartStartCheckout.gql'
|
|
@@ -12,11 +13,12 @@ export type CartStartCheckoutProps = {
|
|
|
12
13
|
sx?: SxProps<Theme>
|
|
13
14
|
buttonProps?: ButtonProps<'button'>
|
|
14
15
|
disabled?: boolean
|
|
16
|
+
hideTotal?: boolean
|
|
15
17
|
cart?: CartStartCheckoutFragment | null | undefined
|
|
16
18
|
onStart?: (
|
|
17
|
-
e: React.MouseEvent<HTMLButtonElement>,
|
|
19
|
+
e: React.MouseEvent<HTMLButtonElement, MouseEvent>,
|
|
18
20
|
cart: CartStartCheckoutFragment | null | undefined,
|
|
19
|
-
) => void
|
|
21
|
+
) => Promise<void>
|
|
20
22
|
}
|
|
21
23
|
|
|
22
24
|
const name = 'CartStartCheckout'
|
|
@@ -35,6 +37,7 @@ export function CartStartCheckout(props: CartStartCheckoutProps) {
|
|
|
35
37
|
onStart,
|
|
36
38
|
buttonProps: { onClick, ...buttonProps } = {},
|
|
37
39
|
disabled,
|
|
40
|
+
hideTotal = false,
|
|
38
41
|
sx = [],
|
|
39
42
|
cart,
|
|
40
43
|
} = props
|
|
@@ -70,10 +73,9 @@ export function CartStartCheckout(props: CartStartCheckoutProps) {
|
|
|
70
73
|
size='large'
|
|
71
74
|
className={classes.checkoutButton}
|
|
72
75
|
endIcon={<IconSvg src={iconChevronRight} />}
|
|
73
|
-
onClick={(e) => {
|
|
76
|
+
onClick={async (e) => {
|
|
74
77
|
onClick?.(e)
|
|
75
|
-
onStart?.(e, cart)
|
|
76
|
-
return onClick?.(e)
|
|
78
|
+
await onStart?.(e, cart)
|
|
77
79
|
}}
|
|
78
80
|
disabled={disabled || !hasTotals || hasErrors || shouldLoginToContinue}
|
|
79
81
|
{...buttonProps}
|
|
@@ -88,7 +90,7 @@ export function CartStartCheckout(props: CartStartCheckoutProps) {
|
|
|
88
90
|
>
|
|
89
91
|
<Trans>Start Checkout</Trans>
|
|
90
92
|
</Box>{' '}
|
|
91
|
-
{hasTotals && (
|
|
93
|
+
{hasTotals && !hideTotal && (
|
|
92
94
|
<span className={classes.checkoutMoney}>
|
|
93
95
|
<Money {...cart?.prices?.grand_total} />
|
|
94
96
|
</span>
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { LinkOrButtonProps } from '@graphcommerce/next-ui'
|
|
2
|
-
import { iconChevronRight, IconSvg, LinkOrButton } from '@graphcommerce/next-ui'
|
|
2
|
+
import { iconChevronRight, IconSvg, LinkOrButton, sxx } from '@graphcommerce/next-ui'
|
|
3
3
|
import { Trans } from '@lingui/react'
|
|
4
4
|
import type { SxProps, Theme } from '@mui/material'
|
|
5
5
|
import React from 'react'
|
|
@@ -8,13 +8,12 @@ import type { CartStartCheckoutFragment } from './CartStartCheckout.gql'
|
|
|
8
8
|
|
|
9
9
|
export type CartStartCheckoutLinkOrButtonProps = {
|
|
10
10
|
children?: React.ReactNode
|
|
11
|
-
sx?: SxProps<Theme>
|
|
12
11
|
disabled?: boolean
|
|
13
12
|
cart?: CartStartCheckoutFragment | null | undefined
|
|
14
13
|
onStart?: (
|
|
15
14
|
e: React.MouseEvent<HTMLButtonElement & HTMLAnchorElement & HTMLSpanElement>,
|
|
16
15
|
cart: CartStartCheckoutFragment | null | undefined,
|
|
17
|
-
) => void
|
|
16
|
+
) => Promise<void>
|
|
18
17
|
linkOrButtonProps?: LinkOrButtonProps
|
|
19
18
|
}
|
|
20
19
|
|
|
@@ -24,6 +23,7 @@ export function CartStartCheckoutLinkOrButton(props: CartStartCheckoutLinkOrButt
|
|
|
24
23
|
disabled,
|
|
25
24
|
linkOrButtonProps: { onClick, button, ...linkOrButtonProps } = {},
|
|
26
25
|
cart,
|
|
26
|
+
children,
|
|
27
27
|
} = props
|
|
28
28
|
|
|
29
29
|
const shouldLoginToContinue = useCheckoutShouldLoginToContinue()
|
|
@@ -34,11 +34,11 @@ export function CartStartCheckoutLinkOrButton(props: CartStartCheckoutLinkOrButt
|
|
|
34
34
|
return (
|
|
35
35
|
<LinkOrButton
|
|
36
36
|
href='/checkout'
|
|
37
|
-
onClick={(
|
|
37
|
+
onClick={async (
|
|
38
38
|
e: React.MouseEvent<HTMLButtonElement & HTMLAnchorElement & HTMLSpanElement, MouseEvent>,
|
|
39
39
|
) => {
|
|
40
40
|
onClick?.(e)
|
|
41
|
-
onStart?.(e, cart)
|
|
41
|
+
await onStart?.(e, cart)
|
|
42
42
|
}}
|
|
43
43
|
button={{ variant: 'pill', ...button }}
|
|
44
44
|
disabled={disabled || !hasTotals || hasErrors || shouldLoginToContinue}
|
|
@@ -46,7 +46,7 @@ export function CartStartCheckoutLinkOrButton(props: CartStartCheckoutLinkOrButt
|
|
|
46
46
|
endIcon={<IconSvg src={iconChevronRight} />}
|
|
47
47
|
{...linkOrButtonProps}
|
|
48
48
|
>
|
|
49
|
-
<Trans id='Next' />
|
|
49
|
+
{children ?? <Trans id='Next' />}
|
|
50
50
|
</LinkOrButton>
|
|
51
51
|
)
|
|
52
52
|
}
|
|
@@ -1,8 +1,12 @@
|
|
|
1
1
|
import type { FullPageMessageProps } from '@graphcommerce/next-ui'
|
|
2
|
-
import {
|
|
2
|
+
import {
|
|
3
|
+
FullPageMessage,
|
|
4
|
+
iconShoppingBag,
|
|
5
|
+
IconSvg,
|
|
6
|
+
OverlayCloseButton,
|
|
7
|
+
} from '@graphcommerce/next-ui'
|
|
3
8
|
import { Trans } from '@lingui/react'
|
|
4
9
|
import type { SxProps, Theme } from '@mui/material'
|
|
5
|
-
import { Button } from '@mui/material'
|
|
6
10
|
import React from 'react'
|
|
7
11
|
|
|
8
12
|
export type EmptyCartProps = {
|
|
@@ -19,9 +23,9 @@ export function EmptyCart(props: EmptyCartProps) {
|
|
|
19
23
|
icon={<IconSvg src={iconShoppingBag} size='xxl' />}
|
|
20
24
|
button={
|
|
21
25
|
button || (
|
|
22
|
-
<
|
|
23
|
-
<Trans id='Continue shopping'
|
|
24
|
-
</
|
|
26
|
+
<OverlayCloseButton variant='pill' color='secondary' size='large'>
|
|
27
|
+
<Trans id='Continue shopping'>Continue shopping</Trans>
|
|
28
|
+
</OverlayCloseButton>
|
|
25
29
|
)
|
|
26
30
|
}
|
|
27
31
|
{...rest}
|
package/components/index.ts
CHANGED
|
@@ -5,11 +5,12 @@ export * from './CartAddressSingleLine/CartAddressSingleLine'
|
|
|
5
5
|
export * from './CartAgreementsForm/CartAgreements.gql'
|
|
6
6
|
export * from './CartAgreementsForm/CartAgreementsForm'
|
|
7
7
|
export * from './CartFab/CartFab'
|
|
8
|
+
export * from './CartIdContext'
|
|
8
9
|
export * from './CartItemSummary/CartItemSummary'
|
|
9
10
|
export * from './CartStartCheckout'
|
|
10
11
|
export * from './CartSummary/CartSummary'
|
|
11
12
|
export * from './CartSummary/CartSummary.gql'
|
|
12
13
|
export * from './CartTotals/CartTotals'
|
|
14
|
+
export * from './EditBillingAddressForm/EditBillingAddressForm'
|
|
13
15
|
export * from './EmptyCart/EmptyCart'
|
|
14
16
|
export * from './InlineAccount/InlineAccount'
|
|
15
|
-
export * from './EditBillingAddressForm/EditBillingAddressForm'
|
|
@@ -6,6 +6,7 @@ import type {
|
|
|
6
6
|
} from '@graphcommerce/react-hook-form'
|
|
7
7
|
import { useFormGqlMutation } from '@graphcommerce/react-hook-form'
|
|
8
8
|
import { GraphQLError, Kind } from 'graphql'
|
|
9
|
+
import { useCartIdContext } from '../components/CartIdContext'
|
|
9
10
|
import { isProtectedCartOperation } from '../link/isProtectedCartOperation'
|
|
10
11
|
import { CurrentCartIdDocument } from './CurrentCartId.gql'
|
|
11
12
|
import { useCartIdCreate } from './useCartIdCreate'
|
|
@@ -19,7 +20,8 @@ export function useFormGqlMutationCart<
|
|
|
19
20
|
options: UseFormGraphQlOptions<Q, V> & { submitWhileLocked?: boolean } = {},
|
|
20
21
|
operationOptions?: MutationHookOptions<Q, V>,
|
|
21
22
|
): UseFormGqlMutationReturn<Q, V> {
|
|
22
|
-
const
|
|
23
|
+
const cartIdCreate = useCartIdCreate()
|
|
24
|
+
const cartIdFromContext = useCartIdContext()
|
|
23
25
|
const client = useApolloClient()
|
|
24
26
|
const shouldLoginToContinue = useCartShouldLoginToContinue()
|
|
25
27
|
|
|
@@ -34,20 +36,25 @@ export function useFormGqlMutationCart<
|
|
|
34
36
|
document,
|
|
35
37
|
{
|
|
36
38
|
...options,
|
|
37
|
-
onBeforeSubmit: async (
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
const vars = { ...variables, cartId: await cartId() }
|
|
39
|
+
onBeforeSubmit: async (incoming) => {
|
|
40
|
+
const variables = options.onBeforeSubmit ? await options.onBeforeSubmit(incoming) : incoming
|
|
41
|
+
if (variables === false) return false
|
|
42
|
+
if (shouldLoginToContinue && shouldBlockOperation) return false
|
|
42
43
|
|
|
43
44
|
const res = client.cache.readQuery({ query: CurrentCartIdDocument })
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
45
|
+
const cartId = cartIdFromContext ?? incoming.cartId ?? (await cartIdCreate())
|
|
46
|
+
|
|
47
|
+
if (
|
|
48
|
+
cartId === res?.currentCartId?.id &&
|
|
49
|
+
res?.currentCartId?.locked &&
|
|
50
|
+
!options.submitWhileLocked
|
|
51
|
+
) {
|
|
52
|
+
throw Error(
|
|
53
|
+
'Could not submit form, cart is locked. This is a bug. You may never submit a form while the cart is locked.',
|
|
54
|
+
)
|
|
48
55
|
}
|
|
49
56
|
|
|
50
|
-
return
|
|
57
|
+
return { ...variables, cartId }
|
|
51
58
|
},
|
|
52
59
|
},
|
|
53
60
|
{ errorPolicy: 'all', ...operationOptions },
|
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": "9.1.0-canary.
|
|
5
|
+
"version": "9.1.0-canary.55",
|
|
6
6
|
"sideEffects": false,
|
|
7
7
|
"prettier": "@graphcommerce/prettier-config-pwa",
|
|
8
8
|
"eslintConfig": {
|
|
@@ -12,20 +12,20 @@
|
|
|
12
12
|
}
|
|
13
13
|
},
|
|
14
14
|
"peerDependencies": {
|
|
15
|
-
"@graphcommerce/ecommerce-ui": "^9.1.0-canary.
|
|
16
|
-
"@graphcommerce/eslint-config-pwa": "^9.1.0-canary.
|
|
17
|
-
"@graphcommerce/framer-next-pages": "^9.1.0-canary.
|
|
18
|
-
"@graphcommerce/framer-scroller": "^9.1.0-canary.
|
|
19
|
-
"@graphcommerce/framer-utils": "^9.1.0-canary.
|
|
20
|
-
"@graphcommerce/graphql": "^9.1.0-canary.
|
|
21
|
-
"@graphcommerce/image": "^9.1.0-canary.
|
|
22
|
-
"@graphcommerce/magento-customer": "^9.1.0-canary.
|
|
23
|
-
"@graphcommerce/magento-graphql": "^9.1.0-canary.
|
|
24
|
-
"@graphcommerce/magento-store": "^9.1.0-canary.
|
|
25
|
-
"@graphcommerce/next-ui": "^9.1.0-canary.
|
|
26
|
-
"@graphcommerce/prettier-config-pwa": "^9.1.0-canary.
|
|
27
|
-
"@graphcommerce/react-hook-form": "^9.1.0-canary.
|
|
28
|
-
"@graphcommerce/typescript-config-pwa": "^9.1.0-canary.
|
|
15
|
+
"@graphcommerce/ecommerce-ui": "^9.1.0-canary.55",
|
|
16
|
+
"@graphcommerce/eslint-config-pwa": "^9.1.0-canary.55",
|
|
17
|
+
"@graphcommerce/framer-next-pages": "^9.1.0-canary.55",
|
|
18
|
+
"@graphcommerce/framer-scroller": "^9.1.0-canary.55",
|
|
19
|
+
"@graphcommerce/framer-utils": "^9.1.0-canary.55",
|
|
20
|
+
"@graphcommerce/graphql": "^9.1.0-canary.55",
|
|
21
|
+
"@graphcommerce/image": "^9.1.0-canary.55",
|
|
22
|
+
"@graphcommerce/magento-customer": "^9.1.0-canary.55",
|
|
23
|
+
"@graphcommerce/magento-graphql": "^9.1.0-canary.55",
|
|
24
|
+
"@graphcommerce/magento-store": "^9.1.0-canary.55",
|
|
25
|
+
"@graphcommerce/next-ui": "^9.1.0-canary.55",
|
|
26
|
+
"@graphcommerce/prettier-config-pwa": "^9.1.0-canary.55",
|
|
27
|
+
"@graphcommerce/react-hook-form": "^9.1.0-canary.55",
|
|
28
|
+
"@graphcommerce/typescript-config-pwa": "^9.1.0-canary.55",
|
|
29
29
|
"@lingui/core": "^4.2.1",
|
|
30
30
|
"@lingui/macro": "^4.2.1",
|
|
31
31
|
"@lingui/react": "^4.2.1",
|