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

Migrate Cart i1 to Cart i2 #4973

Merged
merged 31 commits into from
Oct 25, 2021
Merged

Migrate Cart i1 to Cart i2 #4973

merged 31 commits into from
Oct 25, 2021

Conversation

senadir
Copy link
Member

@senadir senadir commented Oct 20, 2021

This PR migrates Cart i1 to Cart i2.

Closes #4798

Testing steps

Migration process:

  1. Before using this PR, create a page containing a cart block, change alignment.
  2. Use this PR. Load the page in the editor.
  3. Confirm it shows the correct content in both filled/empty states. Do not save.
  4. View frontend - confirm cart is functional.
  5. Save page in editor.
  6. View frontend - confirm cart is functional.

Cart in general:

  1. Insert cart into page and smoke test functionality.

Mini Cart:

  1. Insert mini cart and smoke test functionality.

Dev note

Some Cart block options might not work in the frontend unless you resave the cart block again in the editor.

Changelog

Cart v2: The cart block, like checkout block, now supports inner blocks that allow for greater customizability.

@senadir senadir force-pushed the add/migrate-cart-i1-to-i2 branch from 9baed2f to ea42468 Compare October 20, 2021 16:14
@github-actions
Copy link
Contributor

github-actions bot commented Oct 20, 2021

Size Change: -139 kB (-11%) 👏

Total Size: 1.1 MB

Filename Size Change
build/active-filters-frontend.js 8.33 kB -22 B (0%)
build/active-filters.js 8 kB -15 B (0%)
build/all-products-frontend.js 22.8 kB -245 B (-1%)
build/all-products.js 37.4 kB +64 B (0%)
build/all-reviews.js 9.57 kB +6 B (0%)
build/atomic-block-components/add-to-cart--atomic-block-components/button--atomic-block-components/image---a7e2bb9b.js 2.69 kB -3 B (0%)
build/atomic-block-components/add-to-cart--atomic-block-components/image--atomic-block-components/title.js 332 B -1 B (0%)
build/atomic-block-components/add-to-cart-frontend.js 8.51 kB -5 B (0%)
build/atomic-block-components/add-to-cart.js 7.84 kB -10 B (0%)
build/atomic-block-components/button-frontend.js 1.74 kB +1 B (0%)
build/atomic-block-components/button.js 874 B -1 B (0%)
build/atomic-block-components/category-list-frontend.js 464 B -4 B (-1%)
build/atomic-block-components/category-list.js 471 B +1 B (0%)
build/atomic-block-components/image-frontend.js 1.88 kB +1 B (0%)
build/atomic-block-components/image.js 1.35 kB +2 B (0%)
build/atomic-block-components/price-frontend.js 2.14 kB +8 B (0%)
build/atomic-block-components/price.js 2.11 kB -1 B (0%)
build/atomic-block-components/rating-frontend.js 561 B -1 B (0%)
build/atomic-block-components/sale-badge.js 868 B -1 B (0%)
build/atomic-block-components/sku.js 391 B -2 B (-1%)
build/atomic-block-components/stock-indicator.js 610 B -2 B (0%)
build/atomic-block-components/summary.js 911 B -2 B (0%)
build/atomic-block-components/tag-list-frontend.js 466 B -1 B (0%)
build/atomic-block-components/title-frontend.js 1.55 kB -3 B (0%)
build/atomic-block-components/title.js 1.38 kB +1 B (0%)
build/attribute-filter-frontend.js 18.3 kB -432 B (-2%)
build/attribute-filter.js 12.1 kB -199 B (-2%)
build/blocks-checkout.js 21.1 kB -2 B (0%)
build/cart-blocks/checkout-button-frontend.js 1.21 kB -2 B (0%)
build/cart-blocks/empty-cart-frontend.js 341 B +14 B (+4%)
build/cart-blocks/express-payment--checkout-blocks/express-payment--checkout-blocks/payment-frontend.js 4.71 kB -18 B (0%)
build/cart-blocks/express-payment-frontend.js 1.57 kB -14 B (-1%)
build/cart-blocks/line-items-frontend.js 5.79 kB +230 B (+4%)
build/cart-blocks/order-summary--checkout-blocks/billing-address--checkout-blocks/shipping-address-frontend.js 3.69 kB +6 B (0%)
build/cart-blocks/order-summary-frontend.js 7.4 kB +94 B (+1%)
build/cart-blocks/totals-frontend.js 312 B -1 B (0%)
build/cart-frontend.js 52.7 kB -39 kB (-43%) 🎉
build/cart-i2-frontend.js 0 B -52.4 kB (removed) 🏆
build/cart-i2.js 0 B -49.7 kB (removed) 🏆
build/cart.js 50.1 kB +3.25 kB (+7%) 🔍
build/checkout-blocks/actions-frontend.js 1.51 kB +5 B (0%)
build/checkout-blocks/billing-address-frontend.js 2.66 kB +4 B (0%)
build/checkout-blocks/contact-information-frontend.js 3.9 kB +2 B (0%)
build/checkout-blocks/express-payment-frontend.js 1.93 kB +2 B (0%)
build/checkout-blocks/fields-frontend.js 347 B +2 B (+1%)
build/checkout-blocks/order-summary-frontend.js 12.8 kB +14 B (0%)
build/checkout-blocks/payment-frontend.js 4.58 kB +6 B (0%)
build/checkout-blocks/shipping-address-frontend.js 3.06 kB -1 B (0%)
build/checkout-blocks/shipping-methods-frontend.js 5.56 kB -6 B (0%)
build/checkout-blocks/terms-frontend.js 1.65 kB +4 B (0%)
build/checkout-blocks/totals-frontend.js 330 B +2 B (+1%)
build/checkout-frontend.js 54.6 kB +233 B (0%)
build/checkout.js 53.4 kB +152 B (0%)
build/featured-category.js 7.74 kB +5 B (0%)
build/featured-product.js 9.43 kB +19 B (0%)
build/handpicked-products.js 6.27 kB +4 B (0%)
build/mini-cart-component-frontend.js 36.8 kB -101 B (0%)
build/mini-cart-frontend.js 2.28 kB -5 B (0%)
build/mini-cart.js 5.29 kB -11 B (0%)
build/price-filter-frontend.js 14.4 kB +30 B (0%)
build/price-filter.js 9.65 kB -18 B (0%)
build/product-best-sellers.js 6.63 kB +17 B (0%)
build/product-categories.js 3.37 kB -5 B (0%)
build/product-category.js 7.5 kB +10 B (0%)
build/product-new.js 6.79 kB +18 B (0%)
build/product-on-sale.js 7.13 kB +7 B (0%)
build/product-search.js 2.68 kB -6 B (0%)
build/product-tag.js 6.59 kB +12 B (0%)
build/product-top-rated.js 6.75 kB +14 B (0%)
build/products-by-attribute.js 7.71 kB +10 B (0%)
build/reviews-by-category.js 11.5 kB -4 B (0%)
build/reviews-by-product.js 13 kB +11 B (0%)
build/reviews-frontend.js 8.96 kB -5 B (0%)
build/single-product-frontend.js 26.1 kB -154 B (-1%)
build/single-product.js 9.77 kB +10 B (0%)
build/stock-filter-frontend.js 8.76 kB -5 B (0%)
build/stock-filter.js 7.81 kB -2 B (0%)
build/vendors--atomic-block-components/add-to-cart--cart-blocks/order-summary--checkout-blocks/billing-ad--c5eb4dcd-frontend.js 16.1 kB -45 B (0%)
build/vendors--atomic-block-components/add-to-cart-frontend.js 4.78 kB +7 B (0%)
build/wc-blocks-editor-style.css 15.6 kB -1 B (0%)
build/wc-blocks-style-rtl.css 20.4 kB -201 B (-1%)
build/wc-blocks-style.css 20.4 kB -208 B (-1%)
build/wc-blocks-vendors.js 254 kB +62 B (0%)
build/wc-blocks.js 3.49 kB -1 B (0%)
ℹ️ View Unchanged
Filename Size
build/atomic-block-components/add-to-cart--atomic-block-components/button.js 1.81 kB
build/atomic-block-components/rating.js 567 B
build/atomic-block-components/sale-badge-frontend.js 859 B
build/atomic-block-components/sku-frontend.js 392 B
build/atomic-block-components/stock-indicator-frontend.js 611 B
build/atomic-block-components/summary-frontend.js 908 B
build/atomic-block-components/tag-list.js 471 B
build/cart-blocks/accepted-payment-methods-frontend.js 1.38 kB
build/cart-blocks/filled-cart-frontend.js 802 B
build/cart-blocks/items-frontend.js 300 B
build/checkout-blocks/order-note-frontend.js 1.56 kB
build/price-format.js 1.37 kB
build/vendors--atomic-block-components/price--cart-blocks/line-items--cart-blocks/order-summary--checkout--8a3571de-frontend.js 5.71 kB
build/vendors--cart-blocks/line-items--checkout-blocks/order-summary-frontend.js 3.1 kB
build/vendors--cart-blocks/order-summary--checkout-blocks/billing-address--checkout-blocks/order-summary---eb4d2cec-frontend.js 5.02 kB
build/wc-blocks-data.js 11.3 kB
build/wc-blocks-editor-style-rtl.css 15.6 kB
build/wc-blocks-google-analytics.js 1.98 kB
build/wc-blocks-middleware.js 1.47 kB
build/wc-blocks-registry.js 3.71 kB
build/wc-blocks-shared-context.js 1.54 kB
build/wc-blocks-shared-hocs.js 1.75 kB
build/wc-blocks-vendors-style-rtl.css 1.37 kB
build/wc-blocks-vendors-style.css 1.37 kB
build/wc-payment-method-bacs.js 806 B
build/wc-payment-method-cheque.js 806 B
build/wc-payment-method-cod.js 898 B
build/wc-payment-method-paypal.js 839 B
build/wc-payment-method-stripe.js 12.2 kB
build/wc-settings.js 2.91 kB

compressed-size-action

Comment on lines -21 to -30
const EmptyCart = ( { content } ) => {
useEffect( () => {
dispatchEvent( 'wc-blocks_render_blocks_frontend', {
element: document.body.querySelector(
'.wp-block-woocommerce-cart'
),
} );
}, [] );
return <RawHTML>{ content }</RawHTML>;
};
Copy link
Member Author

Choose a reason for hiding this comment

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

This was moved to Empty cart block, no RawHTML needed

@@ -75,19 +86,32 @@ const Block = ( { emptyCart, attributes, scrollToTop } ) => {
};
}, [ scrollToTop ] );

Copy link
Member Author

Choose a reason for hiding this comment

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

I used the updated ScrollonError from Checkout.

@@ -1,47 +1,54 @@
/* tslint:disable */
Copy link
Member Author

Choose a reason for hiding this comment

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

We will handle TS in a follow up, this is useful to keep a good blame history.

Comment on lines -32 to -44
const CartFrontend = ( props ) => {
return (
<StoreSnackbarNoticesProvider context="wc/cart">
<StoreNoticesProvider context="wc/cart">
<SlotFillProvider>
<CartProvider>
<Block { ...props } />
</CartProvider>
</SlotFillProvider>
</StoreNoticesProvider>
</StoreSnackbarNoticesProvider>
);
};
Copy link
Member Author

Choose a reason for hiding this comment

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

This moves to Block.

Comment on lines 59 to 98
migrate: ( attributes, innerBlocks ) => {
return [
attributes,
[
createBlock( 'woocommerce/filled-cart-block' ),
createBlock(
'woocommerce/empty-cart-block',
{},
innerBlocks
),
],
];
},
Copy link
Member Author

Choose a reason for hiding this comment

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

This function takes the previous inner Blocks from Cart i1 and place it in the correct place.

@@ -80,7 +80,32 @@ protected function render( $attributes, $content ) {
wp_dequeue_script( 'selectWoo' );
wp_dequeue_style( 'select2' );

return $content . $this->get_skeleton();
// If the content contains new inner blocks, it means we're in the newer version of Cart.
$regex_for_new_block = '/<div[\n\r\s\ta-zA-Z0-9_\-=\'"]*data-block-name="woocommerce\/filled-cart-block"[\n\r\s\ta-zA-Z0-9_\-=\'"]*>/mi';
Copy link
Member Author

Choose a reason for hiding this comment

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

We check if we're running Cart i2.


$is_new = preg_match( $regex_for_new_block, $content );

if ( ! $is_new ) {
Copy link
Member Author

Choose a reason for hiding this comment

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

If we're not, then we're going to insert the default template


if ( ! $is_new ) {
// This fallback needs to match the default templates defined in our Blocks.
$inner_blocks_html = '$0
Copy link
Member Author

Choose a reason for hiding this comment

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

$0 is used here to replace the old block opening, it supports custom calsses.

<div data-block-name="woocommerce/empty-cart-block" class="wp-block-woocommerce-empty-cart-block">
';

$content = preg_replace( '/<div class="[a-zA-Z0-9_\- ]*wp-block-woocommerce-cart[a-zA-Z0-9_\- ]*">/mi', $inner_blocks_html, $content );
Copy link
Member Author

Choose a reason for hiding this comment

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

Insert template at start.

';

$content = preg_replace( '/<div class="[a-zA-Z0-9_\- ]*wp-block-woocommerce-cart[a-zA-Z0-9_\- ]*">/mi', $inner_blocks_html, $content );
$content = substr_replace( $content, '</div></div>', -6 );
Copy link
Member Author

Choose a reason for hiding this comment

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

insert a closing div at the end.

Copy link
Contributor

Choose a reason for hiding this comment

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

What exactly is the function of this line? I understand it replaces the last 6 chars with </div></div> am I correct?

Why not just add </div></div> to the end of the $inner_blocks_html string?

Copy link
Member Author

Choose a reason for hiding this comment

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

Yeah that would work.

@senadir senadir changed the title WIP: Migrate Cart i1 to Cart i2 Migrate Cart i1 to Cart i2 Oct 20, 2021
@senadir senadir marked this pull request as ready for review October 20, 2021 16:23
Copy link
Contributor

@Aljullu Aljullu left a comment

Choose a reason for hiding this comment

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

I didn't do a full review, but wanted to raise a couple of changes that were implemented recently and that it looks like they are not included in Cart i2. I didn't do a close examination, so there might be more, but these are two that stood out to me. 👇

assets/js/blocks/cart-checkout/cart/block.js Outdated Show resolved Hide resolved
@mikejolley mikejolley self-assigned this Oct 21, 2021
@mikejolley mikejolley added status: needs review block: cart Issues related to the cart block. labels Oct 21, 2021
@ralucaStan
Copy link
Contributor

Is there a reason we see Accepted Payment Methods grayed out when trying to add a new block on the right column of the cart?
Screenshot 2021-10-21 at 12 59 25

Comment on lines -43 to -46
emptyCart={ null }
attributes={ {
isShippingCalculatorEnabled: false,
} }
Copy link
Member Author

Choose a reason for hiding this comment

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

We no longer need to define emptyCart or attributes here.

Comment on lines 55 to 56
// ["`select` control in `@wordpress/data-controls` is deprecated. Please use built-in `resolveSelect` control in `@wordpress/data` instead."]
expect( console ).toHaveWarned();
Copy link
Member Author

Choose a reason for hiding this comment

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

This is now fixed.

await waitFor( () => expect( fetchMock ).toHaveBeenCalled() );
expect( container ).toMatchSnapshot();
expect( screen.getByText( /Tax/i ) ).toBeInTheDocument();
Copy link
Member Author

Choose a reason for hiding this comment

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

Removed snapshots in favor of RTL selectors.

Comment on lines 24 to 44
<Cart attributes={ attributes }>
<FilledCart>
<ItemsBlock>
<LineItemsBlock />
</ItemsBlock>
<TotalsBlock>
<OrderSummaryBlock
showRateAfterTaxName={ showRateAfterTaxName }
isShippingCalculatorEnabled={
isShippingCalculatorEnabled
}
/>
<ExpressPaymentBlock />
<ProceedToCheckoutBlock />
<AcceptedPaymentMethodsIcons />
</TotalsBlock>
</FilledCart>
<EmptyCart>
<p>Empty Cart</p>
</EmptyCart>
</Cart>
Copy link
Member Author

Choose a reason for hiding this comment

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

Since we're running an innerBlocks structure now, we need to construct the block ourselves.

@senadir
Copy link
Member Author

senadir commented Oct 21, 2021

@ralucaStan

Is there a reason we see Accepted Payment Methods grayed out when trying to add a new block on the right column of the cart?

Yes, that block is optional and so can be inserted and removed, it's also restricted to a single use, so it's grayed out because it's already inserted.

@ralucaStan
Copy link
Contributor

Some small Carti2 leftovers:

  • 3 in this file,
  • 1 mention of BlockTypes/CartI2.php here

@senadir
Copy link
Member Author

senadir commented Oct 21, 2021

I think those can be updated automatically the next time we run the automation script?

Copy link
Contributor

@ralucaStan ralucaStan left a comment

Choose a reason for hiding this comment

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

@senadir I'm gonna post this review so that you can look into my comments and I'll post individual comments for the rest of the review

Copy link
Contributor

@ralucaStan ralucaStan left a comment

Choose a reason for hiding this comment

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

I've finished my review, things I have tested:

  • Coupon code
  • Transfer of cart attributes from i1 to i2
  • Filters in cart
  • Interaction with the editor
  • Interaction with the cart on the frontend
  • Express payment
  • 0 total
  • Shipping calculator
  • Inserting custom blocks

Things I've found no to work:

@ralucaStan
Copy link
Contributor

I think those can be updated automatically the next time we run the automation script?

yes, running npm run build:docs fixed this. I've pushed a commit with the changes

@senadir
Copy link
Member Author

senadir commented Oct 22, 2021

disabling the Shipping calculator/ passing this setting from Cart i1 to Cart i2

I managed to get this to work on the editor, no luck on the frontend. It would make the block too complicated for little gain, we're going to issue a dev note with the block stating that people need to resave if they changed attributes. The attributes are mostly cosmetic and provide good defaults already, so it's not a big issue.

@ralucaStan ralucaStan self-requested a review October 22, 2021 16:08
@senadir
Copy link
Member Author

senadir commented Oct 25, 2021

The attributes are mostly cosmetic and provide good defaults already, so it's not a big issue.

as per request from @ralucaStan, I'm expanding on this section.

To get old attributes support in the new layout, we need to pass them via CartBlockContext and access them in the inner blocks templates and blocks. At that point we need to decide if we should apply the attribute saved with the inner block or coming from above. We need to do this both on frontend and editor.

This essentially introduces extra code for a simple migration code that we later need to delete. I didn't find value in doing this, especially as what we're trying to do is carry over the value of two cosmetic attributes. Having the wrong value in the frontend has little impact (e.g: showing the taxes % or not, showing shipping calculator or not). The attributes value isn't lost, it's saved in the editor block migration code (which is built in for that) and would reapply if the merchants saves the editor page again.
So it's a factor of how much effort/fragility we're creating for the inconvenience of possibly losing the value you applied.

Copy link
Contributor

@opr opr left a comment

Choose a reason for hiding this comment

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

Apart from the issues already pointed out by @ralucaStan already about attribute migration and custom classes, there is also the issue of the width of the block, the content doesn't stretch like it did in the old cart. I don't think this is too much of a big deal but just flagging it anyway.

edit: the width setting works fine on the front-end

Old cart New cart (after migration, before saving)
image image

Happy to approve on the basis that:

  • the migration from old cart to new cart works well and doesn't break the site, and the planned dev note will address what we've pointed out.
  • The comment I left about translation is addressed/defended.
  • The comment I left about the template is explained.

[
{
view: 'woocommerce/filled-cart-block',
label: __( 'Filled Cart', 'woo-gutenberg-products-block' ),
Copy link
Contributor

Choose a reason for hiding this comment

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

Noting that this previously read Full Cart

Copy link
Member Author

Choose a reason for hiding this comment

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

Yes, we changed from Full to Filled because Full didn't make sense, while filled assumes there's at least one item.

';

$content = preg_replace( '/<div class="[a-zA-Z0-9_\- ]*wp-block-woocommerce-cart[a-zA-Z0-9_\- ]*">/mi', $inner_blocks_html, $content );
$content = substr_replace( $content, '</div></div>', -6 );
Copy link
Contributor

Choose a reason for hiding this comment

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

What exactly is the function of this line? I understand it replaces the last 6 chars with </div></div> am I correct?

Why not just add </div></div> to the end of the $inner_blocks_html string?

Copy link
Contributor

@ralucaStan ralucaStan left a comment

Choose a reason for hiding this comment

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

👏

@senadir senadir merged commit fcca216 into trunk Oct 25, 2021
@senadir senadir deleted the add/migrate-cart-i1-to-i2 branch October 25, 2021 14:46
@frontdevde frontdevde added the type: enhancement The issue is a request for an enhancement. label Oct 26, 2021
jonny-bull pushed a commit to jonny-bull/woocommerce-gutenberg-products-block that referenced this pull request Dec 14, 2021
* move empty cart

* remove Cart and rename Cart i2 to Cart

* graduate blocks

* setup template migration from Cart i1 to Cart i2

* back to js so we have a good diff

* add migration

* fix bug in empty cart template

* add useForceLayout hook to edit

* migrate from old block to new block

* migrate styles

* respect align

* add tests

* Include latest cart line item improvements from cart-i1

* Missing changes from cart-i1

* Line items table should be disabled

* Fix e2e tests for cart i2

* update tests to adapt for inner blocks

* update select to resolveSelect to remove warning checker

* rename test/block to test/index

* move blocks to their own file

* undo rename to keep diff clean

* remove .tsx and update jest config

* Revert "update select to resolveSelect to remove warning checker"

This reverts commit 79d55de.

* revert resolveControl

* Fix empty cart editor E2E test by scrolling to the view switch

* parse attributes for order summary block

* migrate attributes when resaving

* Update documentation

Automatic update after running npm run build:docs

* add align options to filled cart and empty cart

* append instead of replcae

* import style.scss in frontend

Co-authored-by: Mike Jolley <[email protected]>
Co-authored-by: Raluca Stan <[email protected]>
jonny-bull pushed a commit to jonny-bull/woocommerce-gutenberg-products-block that referenced this pull request Dec 16, 2021
* move empty cart

* remove Cart and rename Cart i2 to Cart

* graduate blocks

* setup template migration from Cart i1 to Cart i2

* back to js so we have a good diff

* add migration

* fix bug in empty cart template

* add useForceLayout hook to edit

* migrate from old block to new block

* migrate styles

* respect align

* add tests

* Include latest cart line item improvements from cart-i1

* Missing changes from cart-i1

* Line items table should be disabled

* Fix e2e tests for cart i2

* update tests to adapt for inner blocks

* update select to resolveSelect to remove warning checker

* rename test/block to test/index

* move blocks to their own file

* undo rename to keep diff clean

* remove .tsx and update jest config

* Revert "update select to resolveSelect to remove warning checker"

This reverts commit 79d55de.

* revert resolveControl

* Fix empty cart editor E2E test by scrolling to the view switch

* parse attributes for order summary block

* migrate attributes when resaving

* Update documentation

Automatic update after running npm run build:docs

* add align options to filled cart and empty cart

* append instead of replcae

* import style.scss in frontend

Co-authored-by: Mike Jolley <[email protected]>
Co-authored-by: Raluca Stan <[email protected]>
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
block: cart Issues related to the cart block. type: enhancement The issue is a request for an enhancement.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Cart i2: setup automatic Depreciation from Cart i1 to Cart i2.
6 participants