Try move shipping related dat to a `@wordpress/data` store (https://github.com/woocommerce/woocommerce-blocks/pull/5896)
* Add address-related items to wc/store/cart data store * Add useUpdateCustomerData hook This allows us to have a single hook responsible for updating the customer information on the server. * Add useUpdateCustomerData hook in Checkout block * Remove shippingAsBilling from previousCustomerData ref type * Add useShippingAsBillingCheckbox hook * Remove checkbox handling from useCheckoutAddress * Merge with woocommerce/woocommerce-blocks#5810 changes * Move shipping as billing to checkout state context provider * Subscribe to changes * Cache customerDataToUpdate * Combine customerDataType and customerDataContextType * Fix notice context * Clean up inline docs for push changes * Add useShippingData hook * Add shipping related selectors to cart store * Update useShippingDataContext to useCustomerData hook * Update uses of useShippingDataContext to get data from hook instead * Remove rogue linebreak * Re-add linebreak * Re-add linebreak, remove shippingAsBilling * Re-add linebreak * Use useShippingData and useCustomerData instead of context * Fix fromEntriesPolyfill to use number or undefined as an index option * Convert derive-selected-shipping-rates to TS * Add SelectShippingRateType * Get needsShipping from new hook and not context * Get address data from useCustomerData instead of useShippingDataContext * Move selectedRates, selectShippingRate and isSelectingRate * Remove items from ShippingDatacontext that are available in data stores * Get shipping data from stores, not context in payment method interface * Consider shipping rates to be loading if customer data is updating * Get rates from useShippingData hook instead of context * Fix incorrect TypeScript types and incorrectly named destructure * Move useShippingData into shipping folder * Update tests to mock useShippingData instead of context * Remove empty string fallback from shipping phone * Get types from Cart declaration instead of Picking them Co-authored-by: Mike Jolley <mike.jolley@me.com>
This commit is contained in:
parent
719c7f7c23
commit
6b8ef2773a
|
@ -1,8 +1,8 @@
|
|||
/**
|
||||
* External dependencies
|
||||
*/
|
||||
import { useShippingDataContext } from '@woocommerce/base-context';
|
||||
import type { EnteredAddress } from '@woocommerce/settings';
|
||||
import { useCustomerData } from '@woocommerce/base-context/hooks';
|
||||
|
||||
/**
|
||||
* Internal dependencies
|
||||
|
@ -21,7 +21,7 @@ const ShippingCalculator = ( {
|
|||
},
|
||||
addressFields = [ 'country', 'state', 'city', 'postcode' ],
|
||||
}: ShippingCalculatorProps ): JSX.Element => {
|
||||
const { shippingAddress, setShippingAddress } = useShippingDataContext();
|
||||
const { shippingAddress, setShippingAddress } = useCustomerData();
|
||||
return (
|
||||
<div className="wc-block-components-shipping-calculator">
|
||||
<ShippingCalculatorAddress
|
||||
|
|
|
@ -23,6 +23,7 @@ import { usePaymentMethodDataContext } from '../../providers/cart-checkout/payme
|
|||
import { useShippingDataContext } from '../../providers/cart-checkout/shipping';
|
||||
import { useCustomerDataContext } from '../../providers/cart-checkout/customer';
|
||||
import { prepareTotalItems } from './utils';
|
||||
import { useShippingData } from '../shipping/use-shipping-data';
|
||||
|
||||
/**
|
||||
* Returns am interface to use as payment method props.
|
||||
|
@ -50,17 +51,19 @@ export const usePaymentMethodInterface = (): PaymentMethodInterface => {
|
|||
const {
|
||||
shippingErrorStatus,
|
||||
shippingErrorTypes,
|
||||
shippingRates,
|
||||
shippingRatesLoading,
|
||||
selectedRates,
|
||||
setSelectedRates,
|
||||
isSelectingRate,
|
||||
onShippingRateSuccess,
|
||||
onShippingRateFail,
|
||||
onShippingRateSelectSuccess,
|
||||
onShippingRateSelectFail,
|
||||
needsShipping,
|
||||
} = useShippingDataContext();
|
||||
const {
|
||||
shippingRates,
|
||||
shippingRatesLoading,
|
||||
selectedRates,
|
||||
isSelectingRate,
|
||||
selectShippingRate,
|
||||
needsShipping,
|
||||
} = useShippingData();
|
||||
const {
|
||||
billingData,
|
||||
shippingAddress,
|
||||
|
@ -157,7 +160,7 @@ export const usePaymentMethodInterface = (): PaymentMethodInterface => {
|
|||
isSelectingRate,
|
||||
needsShipping,
|
||||
selectedRates,
|
||||
setSelectedRates,
|
||||
selectShippingRate,
|
||||
setShippingAddress,
|
||||
shippingAddress,
|
||||
shippingRates,
|
||||
|
|
|
@ -1 +1,2 @@
|
|||
export * from './use-select-shipping-rate';
|
||||
export * from './use-shipping-data';
|
||||
|
|
|
@ -5,6 +5,7 @@ import { useDispatch, useSelect } from '@wordpress/data';
|
|||
import { useCallback } from '@wordpress/element';
|
||||
import { CART_STORE_KEY as storeKey } from '@woocommerce/block-data';
|
||||
import { useThrowError } from '@woocommerce/base-hooks';
|
||||
import { SelectShippingRateType } from '@woocommerce/type-defs/shipping';
|
||||
|
||||
/**
|
||||
* Internal dependencies
|
||||
|
@ -18,15 +19,7 @@ import { useStoreEvents } from '../use-store-events';
|
|||
* - selectShippingRate: A function that immediately returns the selected rate and dispatches an action generator.
|
||||
* - isSelectingRate: True when rates are being resolved to the API.
|
||||
*/
|
||||
export const useSelectShippingRate = (): {
|
||||
// Returns a function that accepts a shipping rate ID and a package ID.
|
||||
selectShippingRate: (
|
||||
newShippingRateId: string,
|
||||
packageId: string | number
|
||||
) => unknown;
|
||||
// True when a rate is currently being selected and persisted to the server.
|
||||
isSelectingRate: boolean;
|
||||
} => {
|
||||
export const useSelectShippingRate = (): SelectShippingRateType => {
|
||||
const throwError = useThrowError();
|
||||
const { dispatchCheckoutEvent } = useStoreEvents();
|
||||
|
||||
|
|
|
@ -0,0 +1,66 @@
|
|||
/**
|
||||
* External dependencies
|
||||
*/
|
||||
import { CART_STORE_KEY as storeKey } from '@woocommerce/block-data';
|
||||
import { useSelect } from '@wordpress/data';
|
||||
import { Cart } from '@woocommerce/type-defs/cart';
|
||||
import { SelectShippingRateType } from '@woocommerce/type-defs/shipping';
|
||||
import { useEffect, useRef } from '@wordpress/element';
|
||||
import { deriveSelectedShippingRates } from '@woocommerce/base-utils';
|
||||
import isShallowEqual from '@wordpress/is-shallow-equal';
|
||||
import { isObject } from '@woocommerce/types';
|
||||
|
||||
/**
|
||||
* Internal dependencies
|
||||
*/
|
||||
import { useSelectShippingRate } from './use-select-shipping-rate';
|
||||
|
||||
interface ShippingData extends SelectShippingRateType {
|
||||
needsShipping: Cart[ 'needsShipping' ];
|
||||
hasCalculatedShipping: Cart[ 'hasCalculatedShipping' ];
|
||||
shippingRates: Cart[ 'shippingRates' ];
|
||||
shippingRatesLoading: boolean;
|
||||
selectedRates: Record< string, string | unknown >;
|
||||
}
|
||||
|
||||
export const useShippingData = (): ShippingData => {
|
||||
const {
|
||||
shippingRates,
|
||||
needsShipping,
|
||||
hasCalculatedShipping,
|
||||
shippingRatesLoading,
|
||||
} = useSelect( ( select ) => {
|
||||
const store = select( storeKey );
|
||||
return {
|
||||
shippingRates: store.getShippingRates(),
|
||||
needsShipping: store.getNeedsShipping(),
|
||||
hasCalculatedShipping: store.getHasCalculatedShipping(),
|
||||
shippingRatesLoading: store.isCustomerDataUpdating(),
|
||||
};
|
||||
} );
|
||||
const { isSelectingRate, selectShippingRate } = useSelectShippingRate();
|
||||
|
||||
// set selected rates on ref so it's always current.
|
||||
const selectedRates = useRef< Record< string, unknown > >( {} );
|
||||
useEffect( () => {
|
||||
const derivedSelectedRates = deriveSelectedShippingRates(
|
||||
shippingRates
|
||||
);
|
||||
if (
|
||||
isObject( derivedSelectedRates ) &&
|
||||
! isShallowEqual( selectedRates.current, derivedSelectedRates )
|
||||
) {
|
||||
selectedRates.current = derivedSelectedRates;
|
||||
}
|
||||
}, [ shippingRates ] );
|
||||
|
||||
return {
|
||||
isSelectingRate,
|
||||
selectedRates: selectedRates.current,
|
||||
selectShippingRate,
|
||||
shippingRates,
|
||||
needsShipping,
|
||||
hasCalculatedShipping,
|
||||
shippingRatesLoading,
|
||||
};
|
||||
};
|
|
@ -13,11 +13,9 @@ import { useCallback } from '@wordpress/element';
|
|||
/**
|
||||
* Internal dependencies
|
||||
*/
|
||||
import {
|
||||
useShippingDataContext,
|
||||
useCheckoutContext,
|
||||
} from '../providers/cart-checkout';
|
||||
import { useCheckoutContext } from '../providers/cart-checkout';
|
||||
import { useCustomerData } from './use-customer-data';
|
||||
import { useShippingData } from './shipping/use-shipping-data';
|
||||
|
||||
interface CheckoutAddress {
|
||||
shippingAddress: ShippingAddress;
|
||||
|
@ -38,7 +36,7 @@ interface CheckoutAddress {
|
|||
* Custom hook for exposing address related functionality for the checkout address form.
|
||||
*/
|
||||
export const useCheckoutAddress = (): CheckoutAddress => {
|
||||
const { needsShipping } = useShippingDataContext();
|
||||
const { needsShipping } = useShippingData();
|
||||
const {
|
||||
useShippingAsBilling,
|
||||
setUseShippingAsBilling,
|
||||
|
|
|
@ -8,12 +8,11 @@ import { useCallback, useMemo } from '@wordpress/element';
|
|||
*/
|
||||
import { actions, ActionType } from './actions';
|
||||
import { STATUS } from './constants';
|
||||
import { useCustomerDataContext } from '../customer';
|
||||
import { useShippingDataContext } from '../shipping';
|
||||
import type {
|
||||
PaymentStatusDispatchers,
|
||||
PaymentMethodDispatchers,
|
||||
} from './types';
|
||||
import { useCustomerData } from '../../../hooks/use-customer-data';
|
||||
|
||||
export const usePaymentMethodDataDispatchers = (
|
||||
dispatch: React.Dispatch< ActionType >
|
||||
|
@ -21,8 +20,7 @@ export const usePaymentMethodDataDispatchers = (
|
|||
dispatchActions: PaymentMethodDispatchers;
|
||||
setPaymentStatus: () => PaymentStatusDispatchers;
|
||||
} => {
|
||||
const { setBillingData } = useCustomerDataContext();
|
||||
const { setShippingAddress } = useShippingDataContext();
|
||||
const { setBillingData, setShippingAddress } = useCustomerData();
|
||||
|
||||
const dispatchActions = useMemo(
|
||||
(): PaymentMethodDispatchers => ( {
|
||||
|
|
|
@ -21,12 +21,12 @@ import { useDebouncedCallback } from 'use-debounce';
|
|||
* Internal dependencies
|
||||
*/
|
||||
import { useEditorContext } from '../../editor-context';
|
||||
import { useShippingDataContext } from '../shipping';
|
||||
import { useCustomerDataContext } from '../customer';
|
||||
import { useStoreCart } from '../../../hooks/cart/use-store-cart';
|
||||
import { useStoreNotices } from '../../../hooks/use-store-notices';
|
||||
import { useEmitResponse } from '../../../hooks/use-emit-response';
|
||||
import type { PaymentMethodsDispatcherType } from './types';
|
||||
import { useShippingData } from '../../../hooks/shipping/use-shipping-data';
|
||||
|
||||
/**
|
||||
* This hook handles initializing registered payment methods and exposing all
|
||||
|
@ -48,7 +48,7 @@ const usePaymentMethodRegistration = (
|
|||
) => {
|
||||
const [ isInitialized, setIsInitialized ] = useState( false );
|
||||
const { isEditor } = useEditorContext();
|
||||
const { selectedRates } = useShippingDataContext();
|
||||
const { selectedRates } = useShippingData();
|
||||
const { billingData, shippingAddress } = useCustomerDataContext();
|
||||
const selectedShippingMethods = useShallowEqual( selectedRates );
|
||||
const paymentMethodsOrder = useShallowEqual( paymentMethodsSortOrder );
|
||||
|
|
|
@ -9,8 +9,6 @@ import {
|
|||
useMemo,
|
||||
useRef,
|
||||
} from '@wordpress/element';
|
||||
import isShallowEqual from '@wordpress/is-shallow-equal';
|
||||
import { deriveSelectedShippingRates } from '@woocommerce/base-utils';
|
||||
|
||||
/**
|
||||
* Internal dependencies
|
||||
|
@ -25,9 +23,9 @@ import {
|
|||
emitEvent,
|
||||
} from './event-emit';
|
||||
import { useCheckoutContext } from '../checkout-state';
|
||||
import { useCustomerDataContext } from '../customer';
|
||||
import { useStoreCart } from '../../../hooks/cart/use-store-cart';
|
||||
import { useSelectShippingRate } from '../../../hooks/shipping/use-select-shipping-rate';
|
||||
import { useShippingData } from '../../../hooks/shipping/use-shipping-data';
|
||||
|
||||
/**
|
||||
* @typedef {import('@woocommerce/type-defs/contexts').ShippingDataContext} ShippingDataContext
|
||||
|
@ -52,15 +50,9 @@ export const useShippingDataContext = () => {
|
|||
*/
|
||||
export const ShippingDataProvider = ( { children } ) => {
|
||||
const { dispatchActions } = useCheckoutContext();
|
||||
const { shippingAddress, setShippingAddress } = useCustomerDataContext();
|
||||
const {
|
||||
cartNeedsShipping: needsShipping,
|
||||
cartHasCalculatedShipping: hasCalculatedShipping,
|
||||
shippingRates,
|
||||
shippingRatesLoading,
|
||||
cartErrors,
|
||||
} = useStoreCart();
|
||||
const { selectShippingRate, isSelectingRate } = useSelectShippingRate();
|
||||
const { shippingRates, shippingRatesLoading, cartErrors } = useStoreCart();
|
||||
const { isSelectingRate } = useSelectShippingRate();
|
||||
const { selectedRates } = useShippingData();
|
||||
const [ shippingErrorStatus, dispatchErrorStatus ] = useReducer(
|
||||
errorStatusReducer,
|
||||
NONE
|
||||
|
@ -85,19 +77,6 @@ export const ShippingDataProvider = ( { children } ) => {
|
|||
currentObservers.current = observers;
|
||||
}, [ observers ] );
|
||||
|
||||
// set selected rates on ref so it's always current.
|
||||
const selectedRates = useRef( () =>
|
||||
deriveSelectedShippingRates( shippingRates )
|
||||
);
|
||||
useEffect( () => {
|
||||
const derivedSelectedRates = deriveSelectedShippingRates(
|
||||
shippingRates
|
||||
);
|
||||
if ( ! isShallowEqual( selectedRates.current, derivedSelectedRates ) ) {
|
||||
selectedRates.current = derivedSelectedRates;
|
||||
}
|
||||
}, [ shippingRates ] );
|
||||
|
||||
// increment/decrement checkout calculating counts when shipping is loading.
|
||||
useEffect( () => {
|
||||
if ( shippingRatesLoading ) {
|
||||
|
@ -198,6 +177,7 @@ export const ShippingDataProvider = ( { children } ) => {
|
|||
);
|
||||
}
|
||||
}, [
|
||||
selectedRates,
|
||||
isSelectingRate,
|
||||
currentErrorStatus.hasError,
|
||||
currentErrorStatus.hasInvalidAddress,
|
||||
|
@ -210,15 +190,6 @@ export const ShippingDataProvider = ( { children } ) => {
|
|||
shippingErrorStatus: currentErrorStatus,
|
||||
dispatchErrorStatus,
|
||||
shippingErrorTypes: ERROR_TYPES,
|
||||
shippingRates,
|
||||
shippingRatesLoading,
|
||||
selectedRates: selectedRates.current,
|
||||
setSelectedRates: selectShippingRate,
|
||||
isSelectingRate,
|
||||
shippingAddress,
|
||||
setShippingAddress,
|
||||
needsShipping,
|
||||
hasCalculatedShipping,
|
||||
...eventObservers,
|
||||
};
|
||||
|
||||
|
|
|
@ -1,10 +1,17 @@
|
|||
/**
|
||||
* External dependencies
|
||||
*/
|
||||
import { CartShippingRate } from '@woocommerce/type-defs/cart';
|
||||
|
||||
/**
|
||||
* Get an array of selected shipping rates keyed by Package ID.
|
||||
*
|
||||
* @param {Array} shippingRates Array of shipping rates.
|
||||
* @return {Object} Object containing the package IDs and selected rates in the format: { [packageId:string]: rateId:string }
|
||||
*/
|
||||
export const deriveSelectedShippingRates = ( shippingRates ) =>
|
||||
export const deriveSelectedShippingRates = (
|
||||
shippingRates: CartShippingRate[]
|
||||
): Record< string, string | unknown > =>
|
||||
Object.fromEntries(
|
||||
shippingRates.map(
|
||||
( { package_id: packageId, shipping_rates: packageRates } ) => [
|
|
@ -4,10 +4,8 @@
|
|||
import classnames from 'classnames';
|
||||
import { __ } from '@wordpress/i18n';
|
||||
import { FormStep } from '@woocommerce/base-components/cart-checkout';
|
||||
import {
|
||||
useCheckoutContext,
|
||||
useShippingDataContext,
|
||||
} from '@woocommerce/base-context';
|
||||
import { useCheckoutContext } from '@woocommerce/base-context';
|
||||
import { useShippingData } from '@woocommerce/base-context/hooks';
|
||||
|
||||
/**
|
||||
* Internal dependencies
|
||||
|
@ -15,7 +13,7 @@ import {
|
|||
import CheckoutOrderNotes from '../../order-notes';
|
||||
|
||||
const Block = ( { className }: { className?: string } ): JSX.Element => {
|
||||
const { needsShipping } = useShippingDataContext();
|
||||
const { needsShipping } = useShippingData();
|
||||
const {
|
||||
isProcessing: checkoutIsProcessing,
|
||||
orderNotes,
|
||||
|
|
|
@ -18,17 +18,13 @@ import {
|
|||
} from '@woocommerce/blocks-checkout';
|
||||
|
||||
import { getCurrencyFromPriceResponse } from '@woocommerce/price-format';
|
||||
import { useShippingDataContext } from '@woocommerce/base-context';
|
||||
import {
|
||||
useStoreCartCoupons,
|
||||
useStoreCart,
|
||||
useShippingData,
|
||||
} from '@woocommerce/base-context/hooks';
|
||||
import { getSetting } from '@woocommerce/settings';
|
||||
|
||||
/**
|
||||
* Internal dependencies
|
||||
*/
|
||||
|
||||
const Block = ( {
|
||||
showRateAfterTaxName = false,
|
||||
className,
|
||||
|
@ -44,7 +40,7 @@ const Block = ( {
|
|||
isRemovingCoupon,
|
||||
} = useStoreCartCoupons();
|
||||
|
||||
const { needsShipping } = useShippingDataContext();
|
||||
const { needsShipping } = useShippingData();
|
||||
const totalsCurrency = getCurrencyFromPriceResponse( cartTotals );
|
||||
|
||||
// Prepare props to pass to the ExperimentalOrderMeta slot fill.
|
||||
|
|
|
@ -18,7 +18,6 @@ import {
|
|||
textContentMatcherAcrossSiblings,
|
||||
} from '../../../../../../../tests/utils/find-by-text';
|
||||
const baseContextHooks = jest.requireMock( '@woocommerce/base-context/hooks' );
|
||||
const baseContext = jest.requireMock( '@woocommerce/base-context' );
|
||||
const woocommerceSettings = jest.requireMock( '@woocommerce/settings' );
|
||||
|
||||
const defaultUseStoreCartValue = {
|
||||
|
@ -51,15 +50,7 @@ jest.mock( '@woocommerce/base-context/hooks', () => ( {
|
|||
billingAddress: mockPreviewCart.billing_address,
|
||||
cartHasCalculatedShipping: mockPreviewCart.has_calculated_shipping,
|
||||
} ),
|
||||
} ) );
|
||||
|
||||
jest.mock( '@woocommerce/base-context', () => ( {
|
||||
...jest.requireActual( '@woocommerce/base-context' ),
|
||||
useContainerWidthContext: jest.fn().mockReturnValue( {
|
||||
hasContainerWidth: true,
|
||||
isLarge: true,
|
||||
} ),
|
||||
useShippingDataContext: jest.fn().mockReturnValue( {
|
||||
useShippingData: jest.fn().mockReturnValue( {
|
||||
needsShipping: true,
|
||||
shippingRates: [
|
||||
{
|
||||
|
@ -167,6 +158,14 @@ jest.mock( '@woocommerce/base-context', () => ( {
|
|||
} ),
|
||||
} ) );
|
||||
|
||||
jest.mock( '@woocommerce/base-context', () => ( {
|
||||
...jest.requireActual( '@woocommerce/base-context' ),
|
||||
useContainerWidthContext: jest.fn().mockReturnValue( {
|
||||
hasContainerWidth: true,
|
||||
isLarge: true,
|
||||
} ),
|
||||
} ) );
|
||||
|
||||
jest.mock( '@woocommerce/settings', () => {
|
||||
const originalModule = jest.requireActual( '@woocommerce/settings' );
|
||||
|
||||
|
@ -189,12 +188,14 @@ const setGetSettingImplementation = ( implementation ) => {
|
|||
woocommerceSettings.getSetting.mockImplementation( implementation );
|
||||
};
|
||||
|
||||
const setUseShippingDataContextReturnValue = ( value ) => {
|
||||
baseContext.useShippingDataContext.mockReturnValue( value );
|
||||
const setUseShippingDataReturnValue = ( value ) => {
|
||||
baseContextHooks.useShippingData.mockReturnValue( value );
|
||||
};
|
||||
|
||||
describe( 'Checkout Order Summary', () => {
|
||||
beforeEach( () => setUseStoreCartReturnValue() );
|
||||
beforeEach( () => {
|
||||
setUseStoreCartReturnValue();
|
||||
} );
|
||||
|
||||
it( 'Renders the standard preview items in the sidebar', async () => {
|
||||
const { container } = render( <Block showRateAfterTaxName={ true } /> );
|
||||
|
@ -335,7 +336,7 @@ describe( 'Checkout Order Summary', () => {
|
|||
...defaultUseStoreCartValue,
|
||||
needsShipping: false,
|
||||
} );
|
||||
setUseShippingDataContextReturnValue( { needsShipping: false } );
|
||||
setUseShippingDataReturnValue( { needsShipping: false } );
|
||||
const { container } = render( <Block showRateAfterTaxName={ true } /> );
|
||||
expect( queryByText( container, 'Shipping' ) ).not.toBeInTheDocument();
|
||||
} );
|
||||
|
@ -349,7 +350,6 @@ describe( 'Checkout Order Summary', () => {
|
|||
tax_lines: [ { name: 'Tax', price: '1000', rate: '5%' } ],
|
||||
},
|
||||
} );
|
||||
setUseShippingDataContextReturnValue( { needsShipping: false } );
|
||||
setGetSettingImplementation( ( setting, ...rest ) => {
|
||||
if ( setting === 'displayCartPricesIncludingTax' ) {
|
||||
return true;
|
||||
|
@ -378,7 +378,7 @@ describe( 'Checkout Order Summary', () => {
|
|||
tax_lines: [ { name: 'Tax', price: '1000', rate: '5%' } ],
|
||||
},
|
||||
} );
|
||||
setUseShippingDataContextReturnValue( { needsShipping: false } );
|
||||
setUseShippingDataReturnValue( { needsShipping: false } );
|
||||
setGetSettingImplementation( ( setting, ...rest ) => {
|
||||
if ( setting === 'displayCartPricesIncludingTax' ) {
|
||||
return false;
|
||||
|
@ -407,7 +407,7 @@ describe( 'Checkout Order Summary', () => {
|
|||
...mockPreviewCart.totals,
|
||||
},
|
||||
} );
|
||||
setUseShippingDataContextReturnValue( { needsShipping: false } );
|
||||
setUseShippingDataReturnValue( { needsShipping: false } );
|
||||
const { container } = render( <Block showRateAfterTaxName={ true } /> );
|
||||
expect(
|
||||
await findByText(
|
||||
|
@ -425,7 +425,7 @@ describe( 'Checkout Order Summary', () => {
|
|||
total_shipping: '4000',
|
||||
},
|
||||
} );
|
||||
setUseShippingDataContextReturnValue( {
|
||||
setUseShippingDataReturnValue( {
|
||||
needsShipping: true,
|
||||
shippingRates: [
|
||||
{
|
||||
|
|
|
@ -2,14 +2,12 @@
|
|||
* External dependencies
|
||||
*/
|
||||
import { __ } from '@wordpress/i18n';
|
||||
import { useShippingData } from '@woocommerce/base-context/hooks';
|
||||
import { ShippingRatesControl } from '@woocommerce/base-components/cart-checkout';
|
||||
import { getShippingRatesPackageCount } from '@woocommerce/base-utils';
|
||||
import { getCurrencyFromPriceResponse } from '@woocommerce/price-format';
|
||||
import FormattedMonetaryAmount from '@woocommerce/base-components/formatted-monetary-amount';
|
||||
import {
|
||||
useEditorContext,
|
||||
useShippingDataContext,
|
||||
} from '@woocommerce/base-context';
|
||||
import { useEditorContext } from '@woocommerce/base-context';
|
||||
import { decodeEntities } from '@wordpress/html-entities';
|
||||
import { Notice } from 'wordpress-components';
|
||||
import classnames from 'classnames';
|
||||
|
@ -50,12 +48,13 @@ const renderShippingRatesControlOption = (
|
|||
|
||||
const Block = (): JSX.Element | null => {
|
||||
const { isEditor } = useEditorContext();
|
||||
|
||||
const {
|
||||
shippingRates,
|
||||
shippingRatesLoading,
|
||||
needsShipping,
|
||||
shippingRatesLoading,
|
||||
hasCalculatedShipping,
|
||||
} = useShippingDataContext();
|
||||
} = useShippingData();
|
||||
|
||||
if ( ! needsShipping ) {
|
||||
return null;
|
||||
|
|
|
@ -1,7 +1,13 @@
|
|||
/**
|
||||
* External dependencies
|
||||
*/
|
||||
import type { Cart, CartTotals, CartMeta, CartItem } from '@woocommerce/types';
|
||||
import type {
|
||||
Cart,
|
||||
CartTotals,
|
||||
CartMeta,
|
||||
CartItem,
|
||||
CartShippingRate,
|
||||
} from '@woocommerce/types';
|
||||
import { BillingAddress, ShippingAddress } from '@woocommerce/settings';
|
||||
|
||||
/**
|
||||
|
@ -32,6 +38,36 @@ export const getCustomerData = (
|
|||
};
|
||||
};
|
||||
|
||||
/**
|
||||
* Retrieves shipping rates from state.
|
||||
*
|
||||
* @param { CartState } state The current state.
|
||||
* @return { CartShippingRate[] } The shipping rates on the cart.
|
||||
*/
|
||||
export const getShippingRates = ( state: CartState ): CartShippingRate[] => {
|
||||
return state.cartData.shippingRates;
|
||||
};
|
||||
|
||||
/**
|
||||
* Retrieves whether the cart needs shipping.
|
||||
*
|
||||
* @param { CartState } state The current state.
|
||||
* @return { boolean } True if the cart needs shipping.
|
||||
*/
|
||||
export const getNeedsShipping = ( state: CartState ): boolean => {
|
||||
return state.cartData.needsShipping;
|
||||
};
|
||||
|
||||
/**
|
||||
* Retrieves whether the cart shipping has been calculated.
|
||||
*
|
||||
* @param { CartState } state The current state.
|
||||
* @return { boolean } True if the shipping has been calculated.
|
||||
*/
|
||||
export const getHasCalculatedShipping = ( state: CartState ): boolean => {
|
||||
return state.cartData.hasCalculatedShipping;
|
||||
};
|
||||
|
||||
/**
|
||||
* Retrieves cart totals from state.
|
||||
*
|
||||
|
|
|
@ -10,10 +10,7 @@ import type LoadingMask from '@woocommerce/base-components/loading-mask';
|
|||
* Internal dependencies
|
||||
*/
|
||||
import type { Currency } from './currency';
|
||||
import type {
|
||||
CartBillingAddress,
|
||||
CartShippingPackageShippingRate,
|
||||
} from './cart';
|
||||
import type { CartBillingAddress, CartShippingRate } from './cart';
|
||||
import type {
|
||||
responseTypes,
|
||||
noticeContexts,
|
||||
|
@ -114,8 +111,8 @@ export interface ShippingDataProps {
|
|||
isSelectingRate: boolean;
|
||||
// True if cart requires shipping.
|
||||
needsShipping: boolean;
|
||||
// An array of selected rates (rate ids).
|
||||
selectedRates: string[];
|
||||
// An object containing package IDs as the key and selected rate as the value (rate ids).
|
||||
selectedRates: Record< string, unknown >;
|
||||
// A function for setting selected rates (receives id).
|
||||
setSelectedRates: (
|
||||
newShippingRateId: string,
|
||||
|
@ -126,7 +123,7 @@ export interface ShippingDataProps {
|
|||
// The current set shipping address.
|
||||
shippingAddress: CartResponseShippingAddress;
|
||||
// All the available shipping rates.
|
||||
shippingRates: CartShippingPackageShippingRate[];
|
||||
shippingRates: CartShippingRate[];
|
||||
// Whether the rates are loading or not.
|
||||
shippingRatesLoading: boolean;
|
||||
}
|
||||
|
|
|
@ -11,3 +11,13 @@ export interface PackageRateOption {
|
|||
secondaryDescription?: string;
|
||||
id?: string;
|
||||
}
|
||||
|
||||
export interface SelectShippingRateType {
|
||||
// Returns a function that accepts a shipping rate ID and a package ID.
|
||||
selectShippingRate: (
|
||||
newShippingRateId: string,
|
||||
packageId: string | number
|
||||
) => unknown;
|
||||
// True when a rate is currently being selected and persisted to the server.
|
||||
isSelectingRate: boolean;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue