Skip to content
This repository has been archived by the owner on Feb 23, 2024. It is now read-only.

Commit

Permalink
Checkout/Store API - Allow partial pushes without country (#8425)
Browse files Browse the repository at this point in the history
* Support partial push without country field

* Increase timeout to prevent excessive pushes

* Push on focusout

* Only flush inputs

* change debounce timer to 1s

---------

Co-authored-by: Nadir Seghir <[email protected]>
  • Loading branch information
2 people authored and tarhi-saad committed Feb 15, 2023
1 parent ae4f1c5 commit d2d065b
Show file tree
Hide file tree
Showing 3 changed files with 40 additions and 31 deletions.
13 changes: 12 additions & 1 deletion assets/js/data/cart/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import * as actions from './actions';
import * as resolvers from './resolvers';
import reducer, { State } from './reducers';
import type { SelectFromMap, DispatchFromMap } from '../mapped-types';
import { pushChanges } from './push-changes';
import { pushChanges, flushChanges } from './push-changes';
import {
updatePaymentMethods,
debouncedUpdatePaymentMethods,
Expand All @@ -34,6 +34,17 @@ const registeredStore = registerStore< State >( STORE_KEY, {

registeredStore.subscribe( pushChanges );

// This will skip the debounce and immediately push changes to the server when a field is blurred.
document.body.addEventListener( 'focusout', ( event: FocusEvent ) => {
if (
event.target &&
event.target instanceof Element &&
event.target.tagName.toLowerCase() === 'input'
) {
flushChanges();
}
} );

// First we will run the updatePaymentMethods function without any debounce to ensure payment methods are ready as soon
// as the cart is loaded. After that, we will unsubscribe this function and instead run the
// debouncedUpdatePaymentMethods function on subsequent cart updates.
Expand Down
48 changes: 27 additions & 21 deletions assets/js/data/cart/push-changes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,25 +34,28 @@ const isBillingAddress = (
return 'email' in address;
};

export const trimAddress = ( address: BillingOrShippingAddress ) => {
const trimmedAddress = {
...address,
};
Object.keys( address ).forEach( ( key ) => {
trimmedAddress[ key as keyof BillingOrShippingAddress ] =
address[ key as keyof BillingOrShippingAddress ].trim();
} );

trimmedAddress.postcode = trimmedAddress.postcode
? trimmedAddress.postcode.replace( ' ', '' ).toUpperCase()
: '';

/**
* Trims and normalizes address data for comparison.
*/
export const normalizeAddress = ( address: BillingOrShippingAddress ) => {
const trimmedAddress = Object.entries( address ).reduce(
( acc, [ key, value ] ) => {
if ( key === 'postcode' ) {
acc[ key as keyof BillingOrShippingAddress ] = value
.replace( ' ', '' )
.toUpperCase();
} else {
acc[ key as keyof BillingOrShippingAddress ] = value.trim();
}
return acc;
},
{} as BillingOrShippingAddress
);
return trimmedAddress;
};

/**
* Does a shallow compare of important address data to determine if the cart needs updating on the server. This takes
* the current and previous address into account, as well as the billing email field.
* Does a shallow compare of all address data to determine if the cart needs updating on the server.
*/
const isAddressDirty = < T extends CartBillingAddress | CartShippingAddress >(
// An object containing all previous address information
Expand All @@ -68,13 +71,12 @@ const isAddressDirty = < T extends CartBillingAddress | CartShippingAddress >(
return true;
}

return (
!! address.country &&
! isShallowEqual(
trimAddress( previousAddress ),
trimAddress( address )
)
const addressMatches = isShallowEqual(
normalizeAddress( previousAddress ),
normalizeAddress( address )
);

return ! addressMatches;
};

type BaseAddressKey = keyof CartBillingAddress | keyof CartShippingAddress;
Expand Down Expand Up @@ -239,3 +241,7 @@ export const pushChanges = (): void => {
updateCustomerData();
}
};

export const flushChanges = (): void => {
updateCustomerData.flush();
};
10 changes: 1 addition & 9 deletions src/StoreApi/Schemas/V1/AbstractAddressSchema.php
Original file line number Diff line number Diff line change
Expand Up @@ -167,15 +167,7 @@ public function validate_callback( $address, $request, $param ) {
$errors = new \WP_Error();
$address = $this->sanitize_callback( $address, $request, $param );

if ( empty( $address['country'] ) ) {
$errors->add(
'missing_country',
__( 'Country is required', 'woo-gutenberg-products-block' )
);
return $errors;
}

if ( ! in_array( $address['country'], array_keys( wc()->countries->get_countries() ), true ) ) {
if ( ! empty( $address['country'] ) && ! in_array( $address['country'], array_keys( wc()->countries->get_countries() ), true ) ) {
$errors->add(
'invalid_country',
sprintf(
Expand Down

0 comments on commit d2d065b

Please sign in to comment.