diff --git a/assets/js/base/hooks/index.js b/assets/js/base/hooks/index.js index eb2820eabac..0467b599de3 100644 --- a/assets/js/base/hooks/index.js +++ b/assets/js/base/hooks/index.js @@ -9,6 +9,7 @@ export * from './use-collection'; export * from './use-collection-header'; export * from './use-collection-data'; export * from './use-previous'; -export * from './checkout'; export * from './payment-methods'; -export * from './use-shipping-rates'; +export * from './shipping'; +export * from './order'; +export * from './use-payment-method-interface'; diff --git a/assets/js/base/hooks/shipping/index.js b/assets/js/base/hooks/shipping/index.js new file mode 100644 index 00000000000..e5b3f650909 --- /dev/null +++ b/assets/js/base/hooks/shipping/index.js @@ -0,0 +1 @@ +export { useShippingRates } from './use-shipping-rates'; diff --git a/assets/js/base/hooks/use-shipping-rates.js b/assets/js/base/hooks/shipping/use-shipping-rates.js similarity index 96% rename from assets/js/base/hooks/use-shipping-rates.js rename to assets/js/base/hooks/shipping/use-shipping-rates.js index 4c8dee0289f..4011bd7eede 100644 --- a/assets/js/base/hooks/use-shipping-rates.js +++ b/assets/js/base/hooks/shipping/use-shipping-rates.js @@ -6,7 +6,7 @@ import { useDebounce } from 'use-debounce'; /** * Internal dependencies */ -import { useCollection } from './use-collection'; +import { useCollection } from '../use-collection'; /** * This is a custom hook that is wired up to the `wc/store/collections` data diff --git a/assets/js/base/hooks/test/use-shipping-rates.js b/assets/js/base/hooks/test/use-shipping-rates.js index 823a8b4a11a..6ba16d5c915 100644 --- a/assets/js/base/hooks/test/use-shipping-rates.js +++ b/assets/js/base/hooks/test/use-shipping-rates.js @@ -8,7 +8,7 @@ import { COLLECTIONS_STORE_KEY as storeKey } from '@woocommerce/block-data'; /** * Internal dependencies */ -import { useShippingRates } from '../use-shipping-rates'; +import { useShippingRates } from '../shipping/use-shipping-rates'; jest.mock( '@woocommerce/block-data', () => ( { __esModule: true, diff --git a/assets/js/base/hooks/use-store-cart-coupons.js b/assets/js/base/hooks/use-store-cart-coupons.js index e44fd499b3e..1574eaa15ca 100644 --- a/assets/js/base/hooks/use-store-cart-coupons.js +++ b/assets/js/base/hooks/use-store-cart-coupons.js @@ -7,6 +7,8 @@ import { __, sprintf } from '@wordpress/i18n'; import { useSelect } from '@wordpress/data'; import { CART_STORE_KEY as storeKey } from '@woocommerce/block-data'; import { useStoreNotices } from '@woocommerce/base-hooks'; +import { useCheckoutContext } from '@woocommerce/base-context'; +import { useEffect } from '@wordpress/element'; /** * Internal dependencies @@ -22,6 +24,7 @@ import { useStoreCart } from './use-store-cart'; * store api /cart/coupons endpoint. */ export const useStoreCartCoupons = () => { + const { dispatchActions } = useCheckoutContext(); const { cartCoupons, cartIsLoading } = useStoreCart(); const { addErrorNotice, @@ -97,7 +100,23 @@ export const useStoreCartCoupons = () => { }, [ addErrorNotice, addSuccessNotice, addInfoNotice ] ); - + // Dispatch calculating increments on loading changes for checkout state. + // Each of the below are done individually to avoid unnecessary dispatches. + useEffect( () => { + return void ( cartIsLoading + ? dispatchActions.incrementCalculating() + : dispatchActions.decrementCalculating() ); + }, [ cartIsLoading ] ); + useEffect( () => { + return void ( results.isApplyingCoupon + ? dispatchActions.incrementCalculating() + : dispatchActions.decrementCalculating() ); + }, [ results.isApplyingCoupon ] ); + useEffect( () => { + return void ( results.isRemovingCoupon + ? dispatchActions.incrementCalculating() + : dispatchActions.decrementCalculating() ); + }, [ results.isRemovingCoupon ] ); return { appliedCoupons: cartCoupons, isLoading: cartIsLoading, diff --git a/assets/js/base/hooks/use-store-cart.js b/assets/js/base/hooks/use-store-cart.js index 1f37c1dcd6d..624c8ceebb1 100644 --- a/assets/js/base/hooks/use-store-cart.js +++ b/assets/js/base/hooks/use-store-cart.js @@ -5,6 +5,8 @@ */ import { CART_STORE_KEY as storeKey } from '@woocommerce/block-data'; import { useSelect } from '@wordpress/data'; +import { useEffect } from '@wordpress/element'; +import { useCheckoutContext } from '@woocommerce/base-context'; /** * @constant @@ -35,11 +37,12 @@ const defaultCartData = { */ export const useStoreCart = ( options = { shouldSelect: true } ) => { const { shouldSelect } = options; - + // get dispatcher from checkout context to record errors. + const { dispatchActions } = useCheckoutContext(); const results = useSelect( ( select ) => { if ( ! shouldSelect ) { - return null; + return defaultCartData; } const store = select( storeKey ); const cartData = store.getCartData(); @@ -62,8 +65,20 @@ export const useStoreCart = ( options = { shouldSelect: true } ) => { }, [ shouldSelect ] ); - if ( results === null ) { - return defaultCartData; - } + + // React to loading and error status dispatch checkout status updates. + // Note these are done separately to avoid unnecessary dispatches. + useEffect( () => { + return void ( results.cartErrors + ? dispatchActions.setHasError() + : dispatchActions.clearError() ); + }, [ results.cartErrors ] ); + + useEffect( () => { + return void ( results.cartIsLoading + ? dispatchActions.incrementCalculating() + : dispatchActions.decrementCalculating() ); + }, [ results.cartIsLoading ] ); + return results; }; diff --git a/assets/js/blocks/cart-checkout/checkout/block.js b/assets/js/blocks/cart-checkout/checkout/block.js index d8a04b6a9f7..a37a59911eb 100644 --- a/assets/js/blocks/cart-checkout/checkout/block.js +++ b/assets/js/blocks/cart-checkout/checkout/block.js @@ -16,7 +16,7 @@ import ShippingRatesControl, { import { CheckboxControl } from '@wordpress/components'; import { getCurrencyFromPriceResponse } from '@woocommerce/base-utils'; import FormattedMonetaryAmount from '@woocommerce/base-components/formatted-monetary-amount'; -import CheckoutProvider from '@woocommerce/base-context/checkout-context'; +import { CheckoutProvider } from '@woocommerce/base-context'; import { ExpressCheckoutFormControl, PaymentMethods, @@ -74,7 +74,7 @@ const Block = ( { attributes, isEditor = false, shippingRates = [] } ) => { return ( - + { 'woo-gutenberg-products-block' ) } > - + { /*@todo this should be something the payment method controls*/ }