From be6c74794bd6a37149d4acb7aaddf5fb0a9f5384 Mon Sep 17 00:00:00 2001 From: Thomas Roberts Date: Fri, 3 Mar 2023 14:27:40 -0800 Subject: [PATCH 1/7] Add LocalPickupSelect component This will be used to render the local pickup options and also display a title if there are more than one package (e.g. if WC subs adds them) --- .../local-pickup-select/index.tsx | 55 +++++++++++++++++++ 1 file changed, 55 insertions(+) create mode 100644 assets/js/base/components/cart-checkout/local-pickup-select/index.tsx diff --git a/assets/js/base/components/cart-checkout/local-pickup-select/index.tsx b/assets/js/base/components/cart-checkout/local-pickup-select/index.tsx new file mode 100644 index 00000000000..313e0022d34 --- /dev/null +++ b/assets/js/base/components/cart-checkout/local-pickup-select/index.tsx @@ -0,0 +1,55 @@ +/** + * External dependencies + */ +import { RadioControlOption } from '@woocommerce/base-components/radio-control/types'; +import { CartShippingPackageShippingRate } from '@woocommerce/types'; +/** + * Internal dependencies + */ +import RadioControl from '../../radio-control'; + +interface LocalPickupSelectProps { + title: string; + setSelectedOption: ( value: string ) => void; + selectedOption: string; + pickupLocations: CartShippingPackageShippingRate[]; + onSelectRate: ( value: string ) => void; + renderPickupLocation: ( + location: CartShippingPackageShippingRate, + pickupLocationsCount: number + ) => RadioControlOption; +} +/** + * Local pickup select component, used to render a package title and local pickup options. + */ +export const LocalPickupSelect = ( { + title, + setSelectedOption, + selectedOption, + pickupLocations, + onSelectRate, + renderPickupLocation, +}: LocalPickupSelectProps ) => { + // Hacky way to check if there are multiple packages, this way is borrowed from `assets/js/base/components/cart-checkout/shipping-rates-control-package/index.tsx` + // We have no built-in way of checking if other extensions have added packages. + const multiplePackages = + document.querySelectorAll( + '.wc-block-components-local-pickup-select .wc-block-components-radio-control' + ).length > 1; + return ( +
+ { multiplePackages &&
{ title }
} + { + setSelectedOption( value ); + onSelectRate( value ); + } } + selected={ selectedOption } + options={ pickupLocations.map( ( location ) => + renderPickupLocation( location, pickupLocations.length ) + ) } + /> +
+ ); +}; +export default LocalPickupSelect; From 0f4b7f8921f6188b4d0583cbac45be7dad50a2d5 Mon Sep 17 00:00:00 2001 From: Thomas Roberts Date: Fri, 3 Mar 2023 14:31:30 -0800 Subject: [PATCH 2/7] Add tests for LocalPickupSelect component --- .../local-pickup-select/test/index.tsx | 121 ++++++++++++++++++ 1 file changed, 121 insertions(+) create mode 100644 assets/js/base/components/cart-checkout/local-pickup-select/test/index.tsx diff --git a/assets/js/base/components/cart-checkout/local-pickup-select/test/index.tsx b/assets/js/base/components/cart-checkout/local-pickup-select/test/index.tsx new file mode 100644 index 00000000000..80c96e21ace --- /dev/null +++ b/assets/js/base/components/cart-checkout/local-pickup-select/test/index.tsx @@ -0,0 +1,121 @@ +/** + * External dependencies + */ +import { render, screen } from '@testing-library/react'; +import userEvent from '@testing-library/user-event'; +/** + * Internal dependencies + */ +import LocalPickupSelect from '..'; + +describe( 'LocalPickupSelect', () => { + const TestComponent = ( { + selectedOptionOverride = null, + onSelectRateOverride = null, + }: { + selectedOptionOverride?: null | ( ( value: string ) => void ); + onSelectRateOverride?: null | ( ( value: string ) => void ); + } ) => ( + { + return { + value: `${ location.rate_id }`, + onChange: jest.fn(), + label: `${ location.name }`, + description: `${ location.description }`, + }; + } } + /> + ); + it( 'Does not render the title if only one package is present on the page', () => { + render( ); + expect( screen.queryByText( 'Package 1' ) ).not.toBeInTheDocument(); + } ); + it( 'Does render the title if more than one package is present on the page', () => { + const { rerender } = render( +
+
+
+ ); + // Render twice so our component can check the DOM correctly. + rerender( + <> +
+
+
+ + + ); + rerender( + <> +
+
+
+ + + ); + + expect( screen.getByText( 'Package 1' ) ).toBeInTheDocument(); + } ); + it( 'Calls the correct functions when changing selected option', () => { + const setSelectedOption = jest.fn(); + const onSelectRate = jest.fn(); + render( + + ); + userEvent.click( screen.getByText( 'Store 2' ) ); + expect( setSelectedOption ).toHaveBeenLastCalledWith( '2' ); + expect( onSelectRate ).toHaveBeenLastCalledWith( '2' ); + userEvent.click( screen.getByText( 'Store 1' ) ); + expect( setSelectedOption ).toHaveBeenLastCalledWith( '1' ); + expect( onSelectRate ).toHaveBeenLastCalledWith( '1' ); + } ); +} ); From e123670291e352ea9a2f94655ddbcb1758e9077e Mon Sep 17 00:00:00 2001 From: Thomas Roberts Date: Fri, 3 Mar 2023 14:35:42 -0800 Subject: [PATCH 3/7] Make title optional --- .../components/cart-checkout/local-pickup-select/index.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/assets/js/base/components/cart-checkout/local-pickup-select/index.tsx b/assets/js/base/components/cart-checkout/local-pickup-select/index.tsx index 313e0022d34..b09b0dba43a 100644 --- a/assets/js/base/components/cart-checkout/local-pickup-select/index.tsx +++ b/assets/js/base/components/cart-checkout/local-pickup-select/index.tsx @@ -9,7 +9,7 @@ import { CartShippingPackageShippingRate } from '@woocommerce/types'; import RadioControl from '../../radio-control'; interface LocalPickupSelectProps { - title: string; + title?: string | undefined; setSelectedOption: ( value: string ) => void; selectedOption: string; pickupLocations: CartShippingPackageShippingRate[]; @@ -38,7 +38,7 @@ export const LocalPickupSelect = ( { ).length > 1; return (
- { multiplePackages &&
{ title }
} + { multiplePackages && title ?
{ title }
: false } { setSelectedOption( value ); From 10b1dc9497aa6c4329aee7e74e1404cb9645c3b9 Mon Sep 17 00:00:00 2001 From: Thomas Roberts Date: Thu, 9 Mar 2023 07:45:13 -0800 Subject: [PATCH 4/7] Add packageCount as an option to LocalPickupSelect --- .../cart-checkout/local-pickup-select/index.tsx | 4 +++- .../checkout-pickup-options-block/block.tsx | 15 ++++++++------- 2 files changed, 11 insertions(+), 8 deletions(-) diff --git a/assets/js/base/components/cart-checkout/local-pickup-select/index.tsx b/assets/js/base/components/cart-checkout/local-pickup-select/index.tsx index b09b0dba43a..3a4d42ba6cc 100644 --- a/assets/js/base/components/cart-checkout/local-pickup-select/index.tsx +++ b/assets/js/base/components/cart-checkout/local-pickup-select/index.tsx @@ -18,6 +18,7 @@ interface LocalPickupSelectProps { location: CartShippingPackageShippingRate, pickupLocationsCount: number ) => RadioControlOption; + packageCount: number; } /** * Local pickup select component, used to render a package title and local pickup options. @@ -29,6 +30,7 @@ export const LocalPickupSelect = ( { pickupLocations, onSelectRate, renderPickupLocation, + packageCount, }: LocalPickupSelectProps ) => { // Hacky way to check if there are multiple packages, this way is borrowed from `assets/js/base/components/cart-checkout/shipping-rates-control-package/index.tsx` // We have no built-in way of checking if other extensions have added packages. @@ -46,7 +48,7 @@ export const LocalPickupSelect = ( { } } selected={ selectedOption } options={ pickupLocations.map( ( location ) => - renderPickupLocation( location, pickupLocations.length ) + renderPickupLocation( location, packageCount ) ) } />
diff --git a/assets/js/blocks/checkout/inner-blocks/checkout-pickup-options-block/block.tsx b/assets/js/blocks/checkout/inner-blocks/checkout-pickup-options-block/block.tsx index 4dea0a89bdb..6fb764c6d4c 100644 --- a/assets/js/blocks/checkout/inner-blocks/checkout-pickup-options-block/block.tsx +++ b/assets/js/blocks/checkout/inner-blocks/checkout-pickup-options-block/block.tsx @@ -14,10 +14,10 @@ import FormattedMonetaryAmount from '@woocommerce/base-components/formatted-mone import { decodeEntities } from '@wordpress/html-entities'; import { getSetting } from '@woocommerce/settings'; import { Icon, mapMarker } from '@wordpress/icons'; -import RadioControl from '@woocommerce/base-components/radio-control'; import type { RadioControlOption } from '@woocommerce/base-components/radio-control/types'; import { CartShippingPackageShippingRate } from '@woocommerce/types'; import { isPackageRateCollectable } from '@woocommerce/base-utils'; +import LocalPickupSelect from '@woocommerce/base-components/cart-checkout/local-pickup-select'; /** * Internal dependencies @@ -142,15 +142,16 @@ const Block = (): JSX.Element | null => { }, [ onSelectRate, pickupLocations, selectedOption ] ); return ( - { + { setSelectedOption( value ); onSelectRate( value ); } } - selected={ selectedOption } - options={ pickupLocations.map( ( location ) => - renderPickupLocation( location, shippingRates.length ) - ) } + packageCount={ shippingRates.length } /> ); }; From f412ba8bc1a945e9711b23e6a5fac30f53b4507d Mon Sep 17 00:00:00 2001 From: Thomas Roberts Date: Fri, 10 Mar 2023 07:26:34 -0800 Subject: [PATCH 5/7] Revert "Add packageCount as an option to LocalPickupSelect" This reverts commit 10b1dc9497aa6c4329aee7e74e1404cb9645c3b9. --- .../cart-checkout/local-pickup-select/index.tsx | 4 +--- .../checkout-pickup-options-block/block.tsx | 15 +++++++-------- 2 files changed, 8 insertions(+), 11 deletions(-) diff --git a/assets/js/base/components/cart-checkout/local-pickup-select/index.tsx b/assets/js/base/components/cart-checkout/local-pickup-select/index.tsx index 3a4d42ba6cc..b09b0dba43a 100644 --- a/assets/js/base/components/cart-checkout/local-pickup-select/index.tsx +++ b/assets/js/base/components/cart-checkout/local-pickup-select/index.tsx @@ -18,7 +18,6 @@ interface LocalPickupSelectProps { location: CartShippingPackageShippingRate, pickupLocationsCount: number ) => RadioControlOption; - packageCount: number; } /** * Local pickup select component, used to render a package title and local pickup options. @@ -30,7 +29,6 @@ export const LocalPickupSelect = ( { pickupLocations, onSelectRate, renderPickupLocation, - packageCount, }: LocalPickupSelectProps ) => { // Hacky way to check if there are multiple packages, this way is borrowed from `assets/js/base/components/cart-checkout/shipping-rates-control-package/index.tsx` // We have no built-in way of checking if other extensions have added packages. @@ -48,7 +46,7 @@ export const LocalPickupSelect = ( { } } selected={ selectedOption } options={ pickupLocations.map( ( location ) => - renderPickupLocation( location, packageCount ) + renderPickupLocation( location, pickupLocations.length ) ) } /> diff --git a/assets/js/blocks/checkout/inner-blocks/checkout-pickup-options-block/block.tsx b/assets/js/blocks/checkout/inner-blocks/checkout-pickup-options-block/block.tsx index 6fb764c6d4c..4dea0a89bdb 100644 --- a/assets/js/blocks/checkout/inner-blocks/checkout-pickup-options-block/block.tsx +++ b/assets/js/blocks/checkout/inner-blocks/checkout-pickup-options-block/block.tsx @@ -14,10 +14,10 @@ import FormattedMonetaryAmount from '@woocommerce/base-components/formatted-mone import { decodeEntities } from '@wordpress/html-entities'; import { getSetting } from '@woocommerce/settings'; import { Icon, mapMarker } from '@wordpress/icons'; +import RadioControl from '@woocommerce/base-components/radio-control'; import type { RadioControlOption } from '@woocommerce/base-components/radio-control/types'; import { CartShippingPackageShippingRate } from '@woocommerce/types'; import { isPackageRateCollectable } from '@woocommerce/base-utils'; -import LocalPickupSelect from '@woocommerce/base-components/cart-checkout/local-pickup-select'; /** * Internal dependencies @@ -142,16 +142,15 @@ const Block = (): JSX.Element | null => { }, [ onSelectRate, pickupLocations, selectedOption ] ); return ( - { + { setSelectedOption( value ); onSelectRate( value ); } } - packageCount={ shippingRates.length } + selected={ selectedOption } + options={ pickupLocations.map( ( location ) => + renderPickupLocation( location, shippingRates.length ) + ) } /> ); }; From 7cf874bb31bbf4f3be05a9e4db460964d27c3191 Mon Sep 17 00:00:00 2001 From: Thomas Roberts Date: Fri, 10 Mar 2023 07:29:04 -0800 Subject: [PATCH 6/7] Add ackage count to LocalPickupSelect --- .../components/cart-checkout/local-pickup-select/index.tsx | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/assets/js/base/components/cart-checkout/local-pickup-select/index.tsx b/assets/js/base/components/cart-checkout/local-pickup-select/index.tsx index b09b0dba43a..3a4d42ba6cc 100644 --- a/assets/js/base/components/cart-checkout/local-pickup-select/index.tsx +++ b/assets/js/base/components/cart-checkout/local-pickup-select/index.tsx @@ -18,6 +18,7 @@ interface LocalPickupSelectProps { location: CartShippingPackageShippingRate, pickupLocationsCount: number ) => RadioControlOption; + packageCount: number; } /** * Local pickup select component, used to render a package title and local pickup options. @@ -29,6 +30,7 @@ export const LocalPickupSelect = ( { pickupLocations, onSelectRate, renderPickupLocation, + packageCount, }: LocalPickupSelectProps ) => { // Hacky way to check if there are multiple packages, this way is borrowed from `assets/js/base/components/cart-checkout/shipping-rates-control-package/index.tsx` // We have no built-in way of checking if other extensions have added packages. @@ -46,7 +48,7 @@ export const LocalPickupSelect = ( { } } selected={ selectedOption } options={ pickupLocations.map( ( location ) => - renderPickupLocation( location, pickupLocations.length ) + renderPickupLocation( location, packageCount ) ) } /> From deaa8c31bc65594ad2833a1b25b3e71d0ec996d8 Mon Sep 17 00:00:00 2001 From: Thomas Roberts Date: Fri, 10 Mar 2023 07:31:18 -0800 Subject: [PATCH 7/7] Add package count and remove unused variable from renderPickupLocation --- .../cart-checkout/local-pickup-select/test/index.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/assets/js/base/components/cart-checkout/local-pickup-select/test/index.tsx b/assets/js/base/components/cart-checkout/local-pickup-select/test/index.tsx index 80c96e21ace..6d3bd6da04a 100644 --- a/assets/js/base/components/cart-checkout/local-pickup-select/test/index.tsx +++ b/assets/js/base/components/cart-checkout/local-pickup-select/test/index.tsx @@ -61,8 +61,8 @@ describe( 'LocalPickupSelect', () => { }, ] } onSelectRate={ onSelectRateOverride || jest.fn() } - // eslint-disable-next-line @typescript-eslint/no-unused-vars - renderPickupLocation={ ( location, pickupLocationsCount ) => { + packageCount={ 1 } + renderPickupLocation={ ( location ) => { return { value: `${ location.rate_id }`, onChange: jest.fn(),