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

Enhance: Bring back user to 1st page when filters are changed #9952

Conversation

imanish003
Copy link
Contributor

URL page number removal on filter change: When filters are changed, the page number in the URL is removed. This is to ensure that when a filter is applied, the user is taken back to the first page of results. The code accommodates three different formats of page numbers in the URL and removes them accordingly.

Part of #9876

Testing

  1. Create a new post.
  2. Add all filter blocks and a 'Products Beta' block to it.
  3. Save the post and navigate to the frontend.
  4. Navigate to the 2nd page using pagination.
  5. Modify any filter and confirm that the page number resets to the 1st page upon filter alteration.
  6. Repeat the above steps and validate that this also holds true for:
    • 'Product Collection' block (The product collection block is currently in the experimental phase and is not shipped with the plugin/core)
    • 'Classic WooCommerce Product Grid Block'
    • Note: This behavior doesn't affect the 'All Products' block.
  • Do not include in the Testing Notes

WooCommerce Visibility

  • WooCommerce Core
  • Feature plugin
  • Experimental

Changelog

Enhancement: Bring back user to 1st page when filters are changed

This commit updates the `ProductCollection` block implementation to add support for filter blocks, including the Price filter, Attributes filter, Rating filter, and In stock filter.

The changes include:

1. Adding a new property `$attributes_filter_query_args` to store the query arguments related to the filter by attributes block.

2. Adding a new method `add_support_for_filter_blocks()` to enable support for filter blocks. This method sets the necessary asset data to enable filtering and refreshes the page when a filter is applied.

3. Adding new methods to handle specific filter queries, including `get_filter_by_price_query()`, `get_filter_by_attributes_query()`, `get_filter_by_stock_status_query()`, and `get_filter_by_rating_query()`. These methods generate the respective queries based on the applied filters.

4. Refactoring the `get_final_query_args()` method to include the newly added filter queries using the `get_queries_by_applied_filters()` method.

These changes enhance the functionality of the `ProductCollection` block by allowing users to filter products based on price, attributes, rating, and stock status.
This commit enhances the ProductCollection block to support various filter blocks such as Price filter block, Attributes filter block, Rating filter block, and In stock filter block.

The `build_query` method has been refactored into two separate methods: `build_frontend_query` and `get_final_frontend_query` to make the code more modular and readable. The `add_support_for_filter_blocks` method has been modified to support the generation of product IDs for filter blocks.

The method `update_rest_query` has been renamed to `update_rest_query_in_editor` for better clarity and understanding of its function. Similarly, `get_final_query_args` has been refactored to include the `$is_exclude_applied_filters` parameter which helps in generating product IDs for the filter blocks.

Moreover, the filter hook `pre_render_block` has been added to support the filtering of blocks before they are rendered.

This update will enhance the user experience by providing more filtering options in the ProductCollection block.
This commit refactors the changeUrl function in the `filters.ts` file. The purpose of this refactor is to remove the page number from the URL whenever filters are changed. This ensures that the user is always taken to the first page of results.

The commit includes the following changes:
- Added comments explaining the different page number formats in the URL.
- Updated the `newUrl` parameter by removing the page number using regular expressions.
- The page is then reloaded with the updated URL using `window.location.href`.

These changes improve the URL handling in the `changeUrl` function and enhance the user experience when interacting with filters.
@github-actions
Copy link
Contributor

github-actions bot commented Jun 22, 2023

The release ZIP for this PR is accessible via:

https://wcblocks.wpcomstaging.com/wp-content/uploads/woocommerce-gutenberg-products-block-9952.zip

Script Dependencies Report

There is no changed script dependency between this branch and trunk.

This comment was automatically generated by the ./github/compare-assets action.

TypeScript Errors Report

  • Files with errors: 464
  • Total errors: 2213

🎉 🎉 This PR does not introduce new TS errors.

comments-aggregator

@imanish003 imanish003 changed the base branch from trunk to fix/9876-product-collection-should-work-well-with-filter-blocks June 22, 2023 09:42
@imanish003 imanish003 added type: enhancement The issue is a request for an enhancement. block-type: product-query Issues related to/affecting all product-query variations. block: product collection Issues related to the Product Collection block labels Jun 22, 2023
@imanish003 imanish003 marked this pull request as ready for review June 22, 2023 09:44
@woocommercebot woocommercebot requested review from a team and nefeline and removed request for a team June 22, 2023 09:44
@imanish003 imanish003 requested a review from kmanijak June 22, 2023 09:44
@github-actions
Copy link
Contributor

github-actions bot commented Jun 22, 2023

Size Change: +877 B (0%)

Total Size: 1.17 MB

Filename Size Change
build/active-filters-frontend.js 8.69 kB +61 B (+1%)
build/active-filters-wrapper-frontend.js 7.64 kB +58 B (+1%)
build/active-filters.js 7.54 kB +63 B (+1%)
build/attribute-filter-frontend.js 23.1 kB +59 B (0%)
build/attribute-filter-wrapper-frontend.js 7.78 kB +58 B (+1%)
build/attribute-filter.js 13.3 kB +51 B (0%)
build/price-filter-frontend.js 14.7 kB +59 B (0%)
build/price-filter-wrapper-frontend.js 6.83 kB +61 B (+1%)
build/price-filter.js 8.62 kB +64 B (+1%)
build/rating-filter-frontend.js 21.5 kB +56 B (0%)
build/rating-filter-wrapper-frontend.js 6.29 kB +58 B (+1%)
build/rating-filter.js 6.99 kB +61 B (+1%)
build/stock-filter-frontend.js 21.7 kB +57 B (0%)
build/stock-filter-wrapper-frontend.js 6.54 kB +54 B (+1%)
build/stock-filter.js 7.72 kB +57 B (+1%)
ℹ️ View Unchanged
Filename Size
build/all-products-frontend.js 12.2 kB
build/all-products.js 40.3 kB
build/all-reviews.js 7.86 kB
build/blocks-checkout.js 35.1 kB
build/breadcrumbs.js 2.13 kB
build/cart-blocks/cart-accepted-payment-methods-frontend.js 1.38 kB
build/cart-blocks/cart-cross-sells-frontend.js 253 B
build/cart-blocks/cart-cross-sells-products--product-price-frontend.js 2.92 kB
build/cart-blocks/cart-cross-sells-products-frontend.js 3.77 kB
build/cart-blocks/cart-express-payment--checkout-blocks/express-payment-frontend.js 5.17 kB
build/cart-blocks/cart-express-payment-frontend.js 719 B
build/cart-blocks/cart-items-frontend.js 302 B
build/cart-blocks/cart-line-items--mini-cart-contents-block/products-table-frontend.js 5.57 kB
build/cart-blocks/cart-line-items-frontend.js 1.06 kB
build/cart-blocks/cart-order-summary-frontend.js 1.27 kB
build/cart-blocks/cart-totals-frontend.js 308 B
build/cart-blocks/empty-cart-frontend.js 345 B
build/cart-blocks/filled-cart-frontend.js 655 B
build/cart-blocks/order-summary-coupon-form-frontend.js 1.63 kB
build/cart-blocks/order-summary-discount-frontend.js 2.12 kB
build/cart-blocks/order-summary-fee-frontend.js 274 B
build/cart-blocks/order-summary-heading-frontend.js 333 B
build/cart-blocks/order-summary-shipping-frontend.js 17.1 kB
build/cart-blocks/order-summary-subtotal-frontend.js 274 B
build/cart-blocks/order-summary-taxes-frontend.js 436 B
build/cart-blocks/proceed-to-checkout-frontend.js 1.44 kB
build/cart-frontend.js 30 kB
build/cart.js 45.2 kB
build/catalog-sorting.js 1.7 kB
build/checkout-blocks/actions-frontend.js 1.88 kB
build/checkout-blocks/billing-address--checkout-blocks/shipping-address-frontend.js 4.69 kB
build/checkout-blocks/billing-address-frontend.js 1.18 kB
build/checkout-blocks/contact-information-frontend.js 2.04 kB
build/checkout-blocks/express-payment-frontend.js 1.14 kB
build/checkout-blocks/fields-frontend.js 331 B
build/checkout-blocks/order-note-frontend.js 1.14 kB
build/checkout-blocks/order-summary-cart-items-frontend.js 3.76 kB
build/checkout-blocks/order-summary-coupon-form-frontend.js 1.79 kB
build/checkout-blocks/order-summary-discount-frontend.js 2.29 kB
build/checkout-blocks/order-summary-fee-frontend.js 276 B
build/checkout-blocks/order-summary-frontend.js 1.28 kB
build/checkout-blocks/order-summary-shipping-frontend.js 17 kB
build/checkout-blocks/order-summary-subtotal-frontend.js 274 B
build/checkout-blocks/order-summary-taxes-frontend.js 436 B
build/checkout-blocks/payment-frontend.js 8.29 kB
build/checkout-blocks/pickup-options-frontend.js 4.84 kB
build/checkout-blocks/shipping-address-frontend.js 1.18 kB
build/checkout-blocks/shipping-method-frontend.js 2.64 kB
build/checkout-blocks/shipping-methods-frontend.js 6.41 kB
build/checkout-blocks/terms-frontend.js 1.56 kB
build/checkout-blocks/totals-frontend.js 360 B
build/checkout-frontend.js 31.9 kB
build/checkout.js 46.6 kB
build/customer-account.js 3.18 kB
build/featured-category.js 15.1 kB
build/featured-product.js 15.3 kB
build/filter-wrapper-frontend.js 14.3 kB
build/filter-wrapper.js 2.4 kB
build/general-style-rtl.css 1.31 kB
build/general-style.css 1.31 kB
build/handpicked-products.js 8.05 kB
build/legacy-template.js 6.8 kB
build/mini-cart-component-frontend.js 30.7 kB
build/mini-cart-contents-block/cart-button-frontend.js 1.73 kB
build/mini-cart-contents-block/checkout-button-frontend.js 1.81 kB
build/mini-cart-contents-block/empty-cart-frontend.js 360 B
build/mini-cart-contents-block/filled-cart-frontend.js 267 B
build/mini-cart-contents-block/footer-frontend.js 3.83 kB
build/mini-cart-contents-block/items-frontend.js 237 B
build/mini-cart-contents-block/products-table-frontend.js 588 B
build/mini-cart-contents-block/shopping-button-frontend.js 530 B
build/mini-cart-contents-block/title-frontend.js 1.9 kB
build/mini-cart-contents-block/title-items-counter-frontend.js 1.59 kB
build/mini-cart-contents-block/title-label-frontend.js 1.53 kB
build/mini-cart-contents.js 18.1 kB
build/mini-cart-frontend.js 2.85 kB
build/mini-cart.js 5.92 kB
build/price-format.js 1.19 kB
build/product-add-to-cart--product-button--product-image--product-price--product-rating--product-sale-bad--49d3ecb2.js 250 B
build/product-add-to-cart--product-button--product-image--product-rating--product-title.js 151 B
build/product-add-to-cart-frontend.js 6.52 kB
build/product-add-to-cart.js 8.84 kB
build/product-best-sellers.js 8.36 kB
build/product-button--product-image--product-price--product-rating--product-sale-badge--product-sku--prod--5bce0384.js 955 B
build/product-button-frontend.js 2.65 kB
build/product-button.js 3.97 kB
build/product-categories.js 2.7 kB
build/product-category.js 9.37 kB
build/product-collection.js 12.3 kB
build/product-image-frontend.js 2.61 kB
build/product-image.js 4.14 kB
build/product-new.js 8.65 kB
build/product-on-sale.js 8.65 kB
build/product-price-frontend.js 204 B
build/product-price.js 1.68 kB
build/product-query.js 11.9 kB
build/product-rating-frontend.js 2.33 kB
build/product-rating.js 1.03 kB
build/product-results-count.js 1.66 kB
build/product-sale-badge-frontend.js 1.79 kB
build/product-sale-badge.js 666 B
build/product-search.js 2.63 kB
build/product-sku-frontend.js 1.83 kB
build/product-sku.js 535 B
build/product-stock-indicator-frontend.js 2.03 kB
build/product-stock-indicator.js 731 B
build/product-summary-frontend.js 2.25 kB
build/product-summary.js 1 kB
build/product-tag.js 9.01 kB
build/product-template.js 3.34 kB
build/product-title-frontend.js 2.21 kB
build/product-title.js 3.66 kB
build/product-top-rated.js 8.91 kB
build/products-by-attribute.js 9.75 kB
build/reviews-by-category.js 12.1 kB
build/reviews-by-product.js 13.3 kB
build/reviews-frontend.js 7.17 kB
build/single-product.js 11.1 kB
build/store-notices.js 1.68 kB
build/vendors--attribute-filter-wrapper--cart-blocks/order-summary-coupon-form--cart-blocks/order-summary--48e1e4bb-frontend.js 6.84 kB
build/vendors--attribute-filter-wrapper--cart-blocks/order-summary-shipping--checkout-blocks/billing-addr--d9f38f9d-frontend.js 4.19 kB
build/vendors--attribute-filter-wrapper-frontend.js 5.11 kB
build/vendors--cart-blocks/cart-cross-sells-products--cart-blocks/cart-line-items--cart-blocks/cart-order--3c5fe802-frontend.js 5.26 kB
build/vendors--cart-blocks/cart-line-items--checkout-blocks/order-summary-cart-items--mini-cart-contents---233ab542-frontend.js 3.57 kB
build/vendors--cart-blocks/order-summary-shipping--checkout-blocks/billing-address--checkout-blocks/order--decc3dc6-frontend.js 19.4 kB
build/vendors--checkout-blocks/pickup-options--checkout-blocks/shipping-methods-frontend.js 8.25 kB
build/vendors--checkout-blocks/shipping-method-frontend.js 12.4 kB
build/vendors--price-filter-wrapper-frontend.js 2.2 kB
build/vendors--product-add-to-cart-frontend.js 7.25 kB
build/vendors--rating-filter-wrapper-frontend.js 5.11 kB
build/vendors--stock-filter-wrapper-frontend.js 5.11 kB
build/wc-blocks-data.js 22.3 kB
build/wc-blocks-editor-style-rtl.css 6.21 kB
build/wc-blocks-editor-style.css 6.21 kB
build/wc-blocks-google-analytics.js 1.56 kB
build/wc-blocks-middleware.js 934 B
build/wc-blocks-registry.js 3.15 kB
build/wc-blocks-shared-context.js 1.1 kB
build/wc-blocks-shared-hocs.js 1.75 kB
build/wc-blocks-style-rtl.css 28 kB
build/wc-blocks-style.css 28 kB
build/wc-blocks-vendors-style-rtl.css 1.96 kB
build/wc-blocks-vendors-style.css 1.96 kB
build/wc-blocks-vendors.js 65.1 kB
build/wc-blocks.js 3.7 kB
build/wc-payment-method-bacs.js 816 B
build/wc-payment-method-cheque.js 811 B
build/wc-payment-method-cod.js 909 B
build/wc-payment-method-paypal.js 837 B
build/wc-settings.js 2.6 kB
build/wc-shipping-method-pickup-location.js 30.4 kB
build/woo-directives-runtime.js 2.73 kB
build/woo-directives-vendors.js 7.91 kB

compressed-size-action

@imanish003 imanish003 requested review from Aljullu and removed request for nefeline June 22, 2023 09:50
Base automatically changed from fix/9876-product-collection-should-work-well-with-filter-blocks to trunk June 22, 2023 09:57
Copy link
Contributor

@kmanijak kmanijak left a comment

Choose a reason for hiding this comment

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

LGTM!

@github-actions github-actions bot added this to the 10.6.0 milestone Jun 22, 2023
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 noticed that when removing all filters, the URL becomes /? first and then /, causing an unnecessary reload:

Enregistrament.de.pantalla.des.de.2023-06-22.14-56-46.webm

Can you reproduce as well?

@imanish003
Copy link
Contributor Author

imanish003 commented Jun 23, 2023

@Aljullu, I can reproduce the issue. Thank you for identifying this edge case. I will work on fixing it and push the necessary changes 🤝

This commit optimizes the `changeUrl` utility function to prevent unnecessary page reloads.

Changes:
1. It checks if there are no query parameters in the URL and the URL ends with a '?'.
2. If these conditions are met, it removes the trailing '?' from the URL.

The reason for this change is that a '?' in the URL typically indicates that query parameters will follow. If there are no query parameters, the '?' is unnecessary and can cause the page to reload, which can negatively affect performance. Therefore, by removing the '?', we prevent this unnecessary page reload.
@imanish003 imanish003 requested a review from Aljullu June 23, 2023 09:20
@imanish003
Copy link
Contributor Author

Hi @Aljullu, I have pushed a fix in 872c583. Can you please take a look again? 🙂

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.

This is working great, @imanish003! I just left one small comment about a possible small optimization, but besides that, LGTM.

Comment on lines 61 to 62
const numberOfQueryParams = [ ...urlObject.searchParams.keys() ].length;
if ( numberOfQueryParams === 0 && newUrl.endsWith( '?' ) ) {
Copy link
Contributor

Choose a reason for hiding this comment

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

I think it's safe to skip the query params check (numberOfQueryParams === 0), no? I mean, if the URL ends with ?, it's always safe to remove the last question mark, no matter if there are query params or not, no? 🤔

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I think so. I was just trying to be extra careful to ensure I do not break any existing functionality.

But good point, the trailing "?" can indeed be removed safely without checking for query parameters. I will simplify the code accordingly. Thanks for the suggestion! 🙌🏻

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@Aljullu I have made the changes in 9a82cd9. Can you please take a look again just to be sure that everything still works as expected? 🙂

This commit simplifies the removal of trailing '?' characters from URLs.
The previous implementation checked if there were any query parameters
before removing a trailing '?'.

However, upon review, it was determined that this check was unnecessary,
as a trailing '?' could be removed safely even if query parameters were
present, without any negative impact.

This change simplifies the code and prevents unnecessary computation
checking for the existence of query parameters.
@opr opr modified the milestones: 10.6.0, 10.7.0 Jul 4, 2023
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.

Thanks for the update, @imanish003. I just found one last minor issue: in some occassions I end up with two && in the URL.

Steps to reproduce:

  1. Add the Filter by Price and Filter by Attribute blocks alongside the Product Collection block.
  2. In the frontend, add a price filter so pagination is still available. The URL will look something like /?min_price=15.
  3. Using pagination, switch to page two. The URL will look something like /?query-0-page=2&min_price=15.
  4. Now, add an attribute filter. The URL will look something like /?min_price=15&&filter_color=blue&query_type_color=or. Notice the double && before filter_color.

Can you reproduce as well?

@imanish003
Copy link
Contributor Author

Hi @Aljullu, This issue isn't reproducing for me 🤔 Here is a quick demo of what I tried:

Screen.Recording.2023-07-05.at.12.18.37.PM.mov

If you are still able to reproduce the issue then maybe I can add a logic like this to clean up query params:

let url = new URL(newUrl);
let params = new URLSearchParams(url.search);

// Assign the cleaned up search parameters back to the URL
url.search = params.toString();

// Now update newUrl with the cleaned up URL
newUrl = url.toString();

What do you think? 🙂

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.

Ups, I don't seem to be able to reproduce anymore, sorry for the confusion. 😕 Not sure what was wrong with my setup, I will open an issue if I can reproduce again, but for now, let's merge this PR. 🚀

@imanish003 imanish003 merged commit 34fb8c0 into trunk Jul 10, 2023
10 checks passed
@imanish003 imanish003 deleted the fix/9876-product-collection-should-work-well-with-filter-blocks-2 branch July 10, 2023 06:04
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
block: product collection Issues related to the Product Collection block block-type: product-query Issues related to/affecting all product-query variations. type: enhancement The issue is a request for an enhancement.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants