Add optimizations around checkout filter calls (https://github.com/woocommerce/woocommerce-blocks/pull/4570)

* Extract productPriceValidation out of the component

* Extract checkout filter args outside of component

* Remove unnecessary default fallback

* Mark ProductName optional props as not required

* Use an empty array constant for the filteredNotices default value when there are no notices

* Refactor Panel component so hidden contents are not rendered

* Prevent extensions changing on each call of __experimentalApplyCheckoutFilter if it was an empty object

* Add missing line break

* Update tests
This commit is contained in:
Albert Juhé Lluveras 2021-08-13 15:42:09 +02:00 committed by GitHub
parent ff9c73bec5
commit 70ec1f8b31
10 changed files with 38 additions and 241 deletions

View File

@ -13,7 +13,7 @@ import {
import PropTypes from 'prop-types';
import Dinero from 'dinero.js';
import { getSetting } from '@woocommerce/settings';
import { useCallback, useMemo } from '@wordpress/element';
import { useMemo } from '@wordpress/element';
import { useStoreCart } from '@woocommerce/base-context/hooks';
/**
@ -24,21 +24,23 @@ import ProductImage from '../product-image';
import ProductLowStockBadge from '../product-low-stock-badge';
import ProductMetadata from '../product-metadata';
const productPriceValidation = ( value ) => mustContain( value, '<price/>' );
const OrderSummaryItem = ( { cartItem } ) => {
const {
images,
low_stock_remaining: lowStockRemaining = null,
show_backorder_badge: showBackorderBadge = false,
low_stock_remaining: lowStockRemaining,
show_backorder_badge: showBackorderBadge,
name: initialName,
permalink,
prices,
quantity,
short_description: shortDescription,
description: fullDescription,
item_data: itemData = [],
item_data: itemData,
variation,
totals,
extensions = {},
extensions,
} = cartItem;
// Prepare props to pass to the __experimentalApplyCheckoutFilter filter.
@ -46,11 +48,6 @@ const OrderSummaryItem = ( { cartItem } ) => {
// eslint-disable-next-line no-unused-vars
const { receiveCart, ...cart } = useStoreCart();
const productPriceValidation = useCallback(
( value ) => mustContain( value, '<price/>' ),
[]
);
const arg = useMemo(
() => ( {
context: 'summary',

View File

@ -12,7 +12,7 @@ import OrderSummary from '../index';
jest.mock( '@woocommerce/base-context', () => ( {
...jest.requireActual( '@woocommerce/base-context' ),
useContainerWidthContext: () => ( {
isLarge: false,
isLarge: true,
hasContainerWidth: true,
} ),
} ) );

View File

@ -16,6 +16,10 @@ import { getSetting } from '@woocommerce/settings';
*/
import './style.scss';
const filteredCartCouponsFilterArg = {
context: 'summary',
};
const TotalsDiscount = ( {
cartCoupons = [],
currency,
@ -42,9 +46,7 @@ const TotalsDiscount = ( {
: discountValue;
const filteredCartCoupons = __experimentalApplyCheckoutFilter( {
arg: {
context: 'summary',
},
arg: filteredCartCouponsFilterArg,
filterName: 'coupons',
defaultValue: cartCoupons,
} );

View File

@ -21,10 +21,10 @@ export default ( {
permalink = '',
...props
}: {
className: string;
disabled: boolean;
className?: string;
disabled?: boolean;
name: string;
permalink: string;
permalink?: string;
} ): JSX.Element => {
const classes = classnames( 'wc-block-components-product-name', className );
return disabled ? (

View File

@ -5,6 +5,8 @@ import { SnackbarList } from 'wordpress-components';
import classnames from 'classnames';
import { __experimentalApplyCheckoutFilter } from '@woocommerce/blocks-checkout';
const EMPTY_SNACKBAR_NOTICES = {};
const SnackbarNoticesContainer = ( {
className,
notices,
@ -19,10 +21,13 @@ const SnackbarNoticesContainer = ( {
( notice ) => notice.type === 'snackbar'
);
const noticeVisibility = snackbarNotices.reduce( ( acc, { content } ) => {
const noticeVisibility =
snackbarNotices.length > 0
? snackbarNotices.reduce( ( acc, { content } ) => {
acc[ content ] = true;
return acc;
}, {} );
}, {} )
: EMPTY_SNACKBAR_NOTICES;
const filteredNotices = __experimentalApplyCheckoutFilter( {
filterName: 'snackbarNoticeVisibility',

View File

@ -27,7 +27,7 @@ import {
mustContain,
} from '@woocommerce/blocks-checkout';
import Dinero from 'dinero.js';
import { useCallback, useMemo } from '@wordpress/element';
import { useMemo } from '@wordpress/element';
import type { CartItem } from '@woocommerce/type-defs/cart';
import { objectHasProp } from '@woocommerce/types';
import { getSetting } from '@woocommerce/settings';
@ -46,6 +46,8 @@ const getAmountFromRawPrice = (
return priceObject.convertPrecision( currency.minorUnit ).getAmount();
};
const productPriceValidation = ( value ) => mustContain( value, '<price/>' );
/**
* Cart line item table row component.
*
@ -99,7 +101,7 @@ const CartLineItemRow = ( {
line_subtotal: '0',
line_subtotal_tax: '0',
},
extensions = {},
extensions,
} = lineItem;
const {
@ -110,11 +112,6 @@ const CartLineItemRow = ( {
} = useStoreCartItemQuantity( lineItem );
const { dispatchStoreEvent } = useStoreEvents();
const productPriceValidation = useCallback(
( value ) => mustContain( value, '<price/>' ),
[]
);
// Prepare props to pass to the __experimentalApplyCheckoutFilter filter.
// We need to pluck out receiveCart.
// eslint-disable-next-line no-unused-vars
@ -308,4 +305,5 @@ const CartLineItemRow = ( {
</tr>
);
};
export default CartLineItemRow;

View File

@ -427,57 +427,6 @@ exports[`Testing cart Contains a Taxes section if Core options are set to show i
</span>
</button>
</div>
<div
class="wc-block-components-panel__content"
hidden=""
>
<div
class=""
>
<div
aria-hidden="false"
class=""
>
<div
class="wc-block-components-totals-coupon__content"
>
<form
class="wc-block-components-totals-coupon__form"
>
<div
class="wc-block-components-text-input wc-block-components-totals-coupon__input is-active"
>
<input
aria-describedby=""
aria-label="Enter code"
autocapitalize="off"
autocomplete="off"
id="wc-block-components-totals-coupon__input-1"
type="text"
value=""
/>
<label
for="wc-block-components-totals-coupon__input-1"
>
Enter code
</label>
</div>
<button
class="components-button wc-block-components-button wc-block-components-totals-coupon__button"
disabled=""
type="submit"
>
<span
class="wc-block-components-button__text"
>
Apply
</span>
</button>
</form>
</div>
</div>
</div>
</div>
</div>
</div>
<div
@ -1160,57 +1109,6 @@ exports[`Testing cart Shows individual tax lines if the store is set to do so 1`
</span>
</button>
</div>
<div
class="wc-block-components-panel__content"
hidden=""
>
<div
class=""
>
<div
aria-hidden="false"
class=""
>
<div
class="wc-block-components-totals-coupon__content"
>
<form
class="wc-block-components-totals-coupon__form"
>
<div
class="wc-block-components-text-input wc-block-components-totals-coupon__input is-active"
>
<input
aria-describedby=""
aria-label="Enter code"
autocapitalize="off"
autocomplete="off"
id="wc-block-components-totals-coupon__input-2"
type="text"
value=""
/>
<label
for="wc-block-components-totals-coupon__input-2"
>
Enter code
</label>
</div>
<button
class="components-button wc-block-components-button wc-block-components-totals-coupon__button"
disabled=""
type="submit"
>
<span
class="wc-block-components-button__text"
>
Apply
</span>
</button>
</form>
</div>
</div>
</div>
</div>
</div>
</div>
<div
@ -1898,57 +1796,6 @@ exports[`Testing cart Shows rate percentages after tax lines if the block is set
</span>
</button>
</div>
<div
class="wc-block-components-panel__content"
hidden=""
>
<div
class=""
>
<div
aria-hidden="false"
class=""
>
<div
class="wc-block-components-totals-coupon__content"
>
<form
class="wc-block-components-totals-coupon__form"
>
<div
class="wc-block-components-text-input wc-block-components-totals-coupon__input is-active"
>
<input
aria-describedby=""
aria-label="Enter code"
autocapitalize="off"
autocomplete="off"
id="wc-block-components-totals-coupon__input-3"
type="text"
value=""
/>
<label
for="wc-block-components-totals-coupon__input-3"
>
Enter code
</label>
</div>
<button
class="components-button wc-block-components-button wc-block-components-totals-coupon__button"
disabled=""
type="submit"
>
<span
class="wc-block-components-button__text"
>
Apply
</span>
</button>
</form>
</div>
</div>
</div>
</div>
</div>
</div>
<div

View File

@ -63,57 +63,6 @@ exports[`Testing checkout sidebar Shows rate percentages after tax lines if the
</span>
</button>
</div>
<div
class="wc-block-components-panel__content"
hidden=""
>
<div
class=""
>
<div
aria-hidden="false"
class=""
>
<div
class="wc-block-components-totals-coupon__content"
>
<form
class="wc-block-components-totals-coupon__form"
>
<div
class="wc-block-components-text-input wc-block-components-totals-coupon__input is-active"
>
<input
aria-describedby="wc-block-components-totals-coupon__input-0"
aria-label="Enter code"
autocapitalize="off"
autocomplete="off"
id="wc-block-components-totals-coupon__input-0"
type="text"
value=""
/>
<label
for="wc-block-components-totals-coupon__input-0"
>
Enter code
</label>
</div>
<button
class="components-button wc-block-components-button wc-block-components-totals-coupon__button"
disabled=""
type="submit"
>
<span
class="wc-block-components-button__text"
>
Apply
</span>
</button>
</form>
</div>
</div>
</div>
</div>
</div>
</div>
<div

View File

@ -50,12 +50,11 @@ const Panel = ( {
{ title }
</button>
</TitleTag>
<div
className="wc-block-components-panel__content"
hidden={ ! isOpen }
>
{ isOpen && (
<div className="wc-block-components-panel__content">
{ children }
</div>
) }
</div>
);
};

View File

@ -90,7 +90,7 @@ const getCheckoutFilters = ( filterName: string ): CheckoutFilterFunction[] => {
export const __experimentalApplyCheckoutFilter = < T >( {
filterName,
defaultValue,
extensions = {},
extensions = null,
arg = null,
validation = returnTrue,
}: {
@ -99,7 +99,7 @@ export const __experimentalApplyCheckoutFilter = < T >( {
/** Default value to filter. */
defaultValue: T;
/** Values extend to REST API response. */
extensions?: Record< string, unknown >;
extensions?: Record< string, unknown > | null;
/** Object containing arguments for the filter function. */
arg?: CheckoutFilterArguments;
/** Function that needs to return true when the filtered value is passed in order for the filter to be applied. */
@ -111,7 +111,7 @@ export const __experimentalApplyCheckoutFilter = < T >( {
let value = defaultValue;
filters.forEach( ( filter ) => {
try {
const newValue = filter( value, extensions, arg );
const newValue = filter( value, extensions || {}, arg );
if ( typeof newValue !== typeof value ) {
throw new Error(
sprintf(