Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refresh page when ECE is dismissed #9888

Merged
merged 35 commits into from
Dec 17, 2024
Merged
Show file tree
Hide file tree
Changes from 27 commits
Commits
Show all changes
35 commits
Select commit Hold shift + click to select a range
4a45962
Add condition to identify button context when dismissed
rafaelzaleski Dec 5, 2024
e1be2e2
Add flag to control if a refresh is needed.
rafaelzaleski Dec 5, 2024
21e38d7
Simplify logic to refresh page.
rafaelzaleski Dec 5, 2024
c03c229
Add changelog
rafaelzaleski Dec 5, 2024
ffa1286
Add prototype for shortcode cart handling
rafaelzaleski Dec 11, 2024
41d527c
remove unused comment
rafaelzaleski Dec 12, 2024
46defc4
create helper to interact with shortcode fields
rafaelzaleski Dec 12, 2024
0db8da6
Only update UI in the cancel event
rafaelzaleski Dec 12, 2024
84ced5a
Add shortcodeCheckout to utils index
rafaelzaleski Dec 12, 2024
ee2b1d2
use select2 triggers for cart interactions
rafaelzaleski Dec 12, 2024
eaf650d
Update shipping addr on blocks cart and checkout
rafaelzaleski Dec 12, 2024
8cfe829
Merge branch 'develop' into fix/9794-refresh-page-when-ece-dismissed
rafaelzaleski Dec 12, 2024
c04f201
Remove console statements
rafaelzaleski Dec 16, 2024
752a88e
Remove todo comment and add check for cart data store
rafaelzaleski Dec 16, 2024
7d8c479
Remove code redundancy
rafaelzaleski Dec 16, 2024
b399fb6
Simplify assignment of last addr
rafaelzaleski Dec 16, 2024
e57f86a
Rename utils file
rafaelzaleski Dec 16, 2024
5ca6d08
Simplify null check in updateShortcodeField
rafaelzaleski Dec 16, 2024
959eb6e
Merge branch 'develop' into fix/9794-refresh-page-when-ece-dismissed
rafaelzaleski Dec 16, 2024
0e665d7
Add doc to new functions
rafaelzaleski Dec 16, 2024
f68ea83
Rename util
rafaelzaleski Dec 16, 2024
b5a0e47
Add reset to lastSelectedAddress in the onCancelHandler
rafaelzaleski Dec 16, 2024
1831e70
Add doc for updateShortcodeField
rafaelzaleski Dec 16, 2024
64f118e
Add implementation for tokenized express checkout
rafaelzaleski Dec 16, 2024
86f69cf
Remove update for CA and GB addresses
rafaelzaleski Dec 16, 2024
c0728be
Add comment to clarify why CA and UK addresses are not included
rafaelzaleski Dec 16, 2024
ce9aa79
Mirror code for tokenized ece
rafaelzaleski Dec 16, 2024
b47ab71
Refactor logic to determine countries with redacted addresses
rafaelzaleski Dec 17, 2024
08d18fc
Add logic to fallback to option text when value is not found
rafaelzaleski Dec 17, 2024
42dad17
Remove comment for external dependencies
rafaelzaleski Dec 17, 2024
240576d
Merge branch 'develop' into fix/9794-refresh-page-when-ece-dismissed
rafaelzaleski Dec 17, 2024
ec81858
Fix comparison to be case-insensitive.
rafaelzaleski Dec 17, 2024
80f40dc
Copy changes to tokenized carts.
rafaelzaleski Dec 17, 2024
20c4e42
Remove redundant check in isPostcodeRedactedForCountry
rafaelzaleski Dec 17, 2024
9dd5e1d
Merge branch 'develop' into fix/9794-refresh-page-when-ece-dismissed
rafaelzaleski Dec 17, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions changelog/fix-9794-refresh-page-when-ece-dismissed
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
Significance: patch
Type: add

Refresh the cart and checkout pages when ECE is dismissed and the shipping options were modified in the payment sheet.
28 changes: 28 additions & 0 deletions client/express-checkout/event-handlers.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,16 @@ import {
normalizeShippingAddress,
normalizeLineItems,
getExpressCheckoutData,
updateBlocksShippingUI,
updateShortcodeShippingUI,
} from './utils';
import {
trackExpressCheckoutButtonClick,
trackExpressCheckoutButtonLoad,
} from './tracking';

let lastSelectedAddress = null;

export const shippingAddressChangeHandler = async ( api, event, elements ) => {
try {
const response = await api.expressCheckoutECECalculateShippingOptions(
Expand All @@ -29,6 +33,9 @@ export const shippingAddressChangeHandler = async ( api, event, elements ) => {
elements.update( {
amount: response.total.amount,
} );

lastSelectedAddress = event.address;

event.resolve( {
shippingRates: response.shipping_options,
lineItems: normalizeLineItems( response.displayItems ),
Expand Down Expand Up @@ -171,5 +178,26 @@ export const onCompletePaymentHandler = () => {
};

export const onCancelHandler = () => {
const context = getExpressCheckoutData( 'button_context' );
const isBlocks = getExpressCheckoutData( 'has_block' );

/*
* CA and GB addresses are redacted and are causing errors until WooCommerce is able to
* handle redacted addresses.
* https://developers.google.com/pay/api/web/reference/response-objects#IntermediateAddress
*/
if (
[ 'cart', 'checkout' ].includes( context ) &&
lastSelectedAddress &&
! [ 'CA', 'GB' ].includes( lastSelectedAddress.country )
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we move this array, along with the accompanying comment, into a self-explanatory variable, either within this function or at a higher level? As this list will likely need to be updated with more countries in the future, using a variable name and relocating it would improve readability and maintainability.

) {
if ( isBlocks ) {
updateBlocksShippingUI( lastSelectedAddress );
} else {
updateShortcodeShippingUI( lastSelectedAddress );
}
}

lastSelectedAddress = null;
unblockUI();
};
1 change: 1 addition & 0 deletions client/express-checkout/utils/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
* Internal dependencies
*/
export * from './normalize';
export * from './shipping-fields';
import { getDefaultBorderRadius } from 'wcpay/utils/express-checkout';

interface MyWindow extends Window {
Expand Down
76 changes: 76 additions & 0 deletions client/express-checkout/utils/shipping-fields.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
/* global jQuery */
/**
* External dependencies
*/

/**
* Internal dependencies
*/
import { normalizeShippingAddress, getExpressCheckoutData } from '.';

/*
* Updates a field in a form with a new value.
*
* @param {String} formSelector - The selector for the form containing the field.
* @param {Object} fieldName - The name of the field to update.
* @param {Object} value - The new value for the field.
*/
const updateShortcodeField = ( formSelector, fieldName, value ) => {
const field = document.querySelector(
`${ formSelector } [name="${ fieldName }"]`
);
if ( field ) {
field.value = value;
jQuery( field ).trigger( 'change' ).trigger( 'close' );
}
};

/**
* Updates the WooCommerce Blocks shipping UI to reflect a new shipping address.
*
* @param {Object} eventAddress - The shipping address returned by the payment event.
*/
export const updateBlocksShippingUI = ( eventAddress ) => {
wp?.data
?.dispatch( 'wc/store/cart' )
?.setShippingAddress( normalizeShippingAddress( eventAddress ) );
};

/**
* Updates the WooCommerce shortcode cart/checkout shipping UI to reflect a new shipping address.
*
* @param {Object} eventAddress - The shipping address returned by the payment event.
*/
export const updateShortcodeShippingUI = ( eventAddress ) => {
const context = getExpressCheckoutData( 'button_context' );
const address = normalizeShippingAddress( eventAddress );

const keys = [ 'country', 'state', 'city', 'postcode' ];

if ( context === 'cart' ) {
keys.forEach( ( key ) => {
if ( address[ key ] ) {
updateShortcodeField(
'form.woocommerce-shipping-calculator',
`calc_shipping_${ key }`,
address[ key ]
);
}
} );
document
.querySelector(
'form.woocommerce-shipping-calculator [name="calc_shipping"]'
)
?.click();
} else if ( context === 'checkout' ) {
keys.forEach( ( key ) => {
if ( address[ key ] ) {
updateShortcodeField(
'form.woocommerce-checkout',
`billing_${ key }`,
address[ key ]
);
}
} );
}
};
32 changes: 31 additions & 1 deletion client/tokenized-express-checkout/event-handlers.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,12 @@ import { applyFilters } from '@wordpress/hooks';
/**
* Internal dependencies
*/
import { getErrorMessageFromNotice, getExpressCheckoutData } from './utils';
import {
getErrorMessageFromNotice,
getExpressCheckoutData,
updateBlocksShippingUI,
updateShortcodeShippingUI,
} from './utils';
import {
trackExpressCheckoutButtonClick,
trackExpressCheckoutButtonLoad,
Expand All @@ -24,6 +29,7 @@ import {
transformPrice,
} from './transformers/wc-to-stripe';

let lastSelectedAddress = null;
let cartApi = new ExpressCheckoutCartApi();
export const setCartApiHandler = ( handler ) => ( cartApi = handler );
export const getCartApiHandler = () => cartApi;
Expand Down Expand Up @@ -56,6 +62,9 @@ export const shippingAddressChangeHandler = async ( event, elements ) => {
cartData.totals
),
} );

lastSelectedAddress = event.address;

event.resolve( {
shippingRates: transformCartDataForShippingRates( cartData ),
lineItems: transformCartDataForDisplayItems( cartData ),
Expand Down Expand Up @@ -216,5 +225,26 @@ export const onCompletePaymentHandler = () => {
};

export const onCancelHandler = () => {
const context = getExpressCheckoutData( 'button_context' );
const isBlocks = getExpressCheckoutData( 'has_block' );

/*
* CA and GB addresses are redacted and are causing errors until WooCommerce is able to
* handle redacted addresses.
* https://developers.google.com/pay/api/web/reference/response-objects#IntermediateAddress
*/
if (
[ 'cart', 'checkout' ].includes( context ) &&
lastSelectedAddress &&
! [ 'CA', 'GB' ].includes( lastSelectedAddress.country )
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same here. Let's put this array in a variable.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since this mirrors the code in the other file, I’ll wait until we complete the review process before copying the changes over to tokenized carts. You can focus your review on the code outside tokenized carts for now.

) {
if ( isBlocks ) {
updateBlocksShippingUI( lastSelectedAddress );
} else {
updateShortcodeShippingUI( lastSelectedAddress );
}
}

lastSelectedAddress = null;
unblockUI();
};
1 change: 1 addition & 0 deletions client/tokenized-express-checkout/utils/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
*/
import { WCPayExpressCheckoutParams } from 'wcpay/express-checkout/utils';
export * from './normalize';
export * from './shipping-fields';
import { getDefaultBorderRadius } from 'wcpay/utils/express-checkout';

export const getExpressCheckoutData = <
Expand Down
76 changes: 76 additions & 0 deletions client/tokenized-express-checkout/utils/shipping-fields.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
/* global jQuery */
/**
* External dependencies
*/
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just curious: is it necessary to include this “external dependencies” comment even if we’re not importing a single module?


/**
* Internal dependencies
*/
import { normalizeShippingAddress, getExpressCheckoutData } from '.';

/*
* Updates a field in a form with a new value.
*
* @param {String} formSelector - The selector for the form containing the field.
* @param {Object} fieldName - The name of the field to update.
* @param {Object} value - The new value for the field.
*/
const updateShortcodeField = ( formSelector, fieldName, value ) => {
const field = document.querySelector(
`${ formSelector } [name="${ fieldName }"]`
);
if ( field ) {
field.value = value;
jQuery( field ).trigger( 'change' ).trigger( 'close' );
}
};

/**
* Updates the WooCommerce Blocks shipping UI to reflect a new shipping address.
*
* @param {Object} eventAddress - The shipping address returned by the payment event.
*/
export const updateBlocksShippingUI = ( eventAddress ) => {
wp?.data
?.dispatch( 'wc/store/cart' )
?.setShippingAddress( normalizeShippingAddress( eventAddress ) );
};

/**
* Updates the WooCommerce shortcode cart/checkout shipping UI to reflect a new shipping address.
*
* @param {Object} eventAddress - The shipping address returned by the payment event.
*/
export const updateShortcodeShippingUI = ( eventAddress ) => {
const context = getExpressCheckoutData( 'button_context' );
const address = normalizeShippingAddress( eventAddress );

const keys = [ 'country', 'state', 'city', 'postcode' ];

if ( context === 'cart' ) {
keys.forEach( ( key ) => {
if ( address[ key ] ) {
updateShortcodeField(
'form.woocommerce-shipping-calculator',
`calc_shipping_${ key }`,
address[ key ]
);
}
} );
document
.querySelector(
'form.woocommerce-shipping-calculator [name="calc_shipping"]'
)
?.click();
} else if ( context === 'checkout' ) {
keys.forEach( ( key ) => {
if ( address[ key ] ) {
updateShortcodeField(
'form.woocommerce-checkout',
`billing_${ key }`,
address[ key ]
);
}
} );
}
};
Loading