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

#198 Feature/add graphql dynamic filters introspection #223

Conversation

kevin-mitchell
Copy link
Contributor

New feature added allowing for dynamic filtering (or "faceting") of attributes on search and product list pages.

Description

This PR represents the work required to provide filtering functionality on the search and product list pages, powered by Magento 2.3.4's new GraphQL filtering functionality.

There are quite a few changes here a number of key items to call out.

SearchResultsService

The SearchResultsService is intended to be useful way of querying for Magento products that acts as the translation layer between "frontend" code / Sling Models / etc and the GraphQL query layer. The hopeful goal of this class is to make it usable in a number of potential different cases - it's original use was in the SearchResults component, however it was easily incorporated into ProductList as well.

DRY-ness

These changes were originally made specifically for search results, NOT for the category pages (aka ProductList and related). Later, we needed to support the filtering on the category page as well. As mentioned above, the flexibility of the SearchResultsService and the fact that the category page is VERY similar to the search results made this fairly simple, HOWEVER the result is that there is quite a bit of code that is nearly identical between the two components SearchResults and ProductList.

There are enough differences between the two designs that I didn't want to totally steamroll over the ProductList component but it would likely be possible to refactor to reduce some of the code duplication at some point.

Certain aspects of the category page vs search are unique, e.g. category specific images and other marketing related features made possible by the differences in ProductList.

Dependency on GraphQL Introspection additions

The PR "#91 add css rules for search results component relating to filter bar" has changes that are REQUIRED for this PR to land. Most likely we'll need to bump version numbers somewhere in here to make sure that this change lands in such a way that the updated GraphQL introspection changes are available.

Related Issue

#198

Motivation and Context

Motivated by Magento 2.3.4 and it's ability to dynamically filter search results.

How Has This Been Tested?

There are a large number of unit tests that have been added as part of this change. Where possible I've used the converter pattern when changing GraphQL layer data to Sling Model friendly POJOs and the like. This makes testing quite a bit easier.

Screenshots (if appropriate):

Screen Shot 2020-03-11 at 8 37 49 PM

Types of changes

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to change)

Checklist:

  • I have signed the Adobe Open Source CLA.
  • My change requires a change to the documentation.
  • I have updated the documentation accordingly.
  • I have read the CONTRIBUTING document.
  • I have added tests to cover my changes and the overall coverage did not decrease.
  • All unit tests pass on CircleCi.
  • I ran all tests locally and they pass.

@kevin-mitchell kevin-mitchell changed the title Feature/add graphql dynamic filters introspection #198 Feature/add graphql dynamic filters introspection Mar 11, 2020
@@ -15,10 +15,10 @@
package com.adobe.cq.commerce.core.components.internal.models.v1.productlist;
Copy link
Contributor Author

Choose a reason for hiding this comment

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

The changes made to this class are almost entirely in an effort to port the functionality from the SearchResults component here, so that essentially the same functionality available in search is available on the product listing pages (basically the category pages)

@@ -29,7 +29,9 @@
import com.adobe.cq.commerce.graphql.client.RequestOptions;
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Changes to this file are made so that introspection queries can be made. If memory serves originally I had created a separate MagentoIntrospectionGraphqlClient or something similar but the team thought it would be better to just have the existing class handle both queries types (with the default behavior remaining in tact)

@@ -11,14 +11,12 @@
* governing permissions and limitations under the License.
Copy link
Contributor Author

Choose a reason for hiding this comment

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

This was refactored to use the SearchResultsService, which hopefully hides most of the details about how to actually query for search results.

@@ -71,21 +71,15 @@
@Nullable
String getTitle();

int getTotalCount();
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Here again an attempt was made to DRY things out a bit by moving all pagination / search result information and pagination functionality into the search result class(es).

/**
* Name of the String resource property indicating number of products to render on front-end.
*/
String PN_PAGE_SIZE = "pageSize";
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Some of this functionality was borrowed from the ProductList component to allow the same authoring options (at least those that are relevant for search result pages)

@codecov
Copy link

codecov bot commented Mar 12, 2020

Codecov Report

Merging #223 into master will not change coverage.
The diff coverage is n/a.

Impacted file tree graph

@@            Coverage Diff            @@
##             master     #223   +/-   ##
=========================================
  Coverage     62.28%   62.28%           
  Complexity      724      724           
=========================================
  Files           171      171           
  Lines          5236     5236           
  Branches        817      817           
=========================================
  Hits           3261     3261           
  Misses         1864     1864           
  Partials        111      111           
Flag Coverage Δ Complexity Δ
#jest 40.21% <0.00%> (ø) 0.00% <0.00%> (ø%)
#karma 94.88% <0.00%> (ø) 0.00% <0.00%> (ø%)
#unittests 84.74% <0.00%> (ø) 724.00% <0.00%> (ø%)

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update a4a5e7c...a4a5e7c. Read the comment docs.

@mhaack mhaack added the feature New feature or request label Mar 23, 2020
@kevin-mitchell kevin-mitchell force-pushed the feature/add-graphql-dynamic-filters-introspection branch from 82294c5 to 5f2ee2c Compare April 3, 2020 11:55
Most of the changes here are cosmetic, but I did add a few new classes to support pagination / removing pagination logic from the search results set itself. This greatly simplifies each class and makes it a lot easier to test the pagination logic itself.

class CategoryRetriever extends AbstractCategoryRetriever {

CategoryRetriever(MagentoGraphqlClient client) {
super(client);
}

private ProductPriceQueryDefinition generatePriceQuery() {
Copy link
Contributor Author

Choose a reason for hiding this comment

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

This class no longer is responsible for generating product searches, this is all being handled in the search service

*
* @param productQueryHook Lambda that extends the product query
*/
public void extendProductQueryWith(Consumer<ProductInterfaceQuery> productQueryHook) {
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 moved this same functionality into the SearchService, and the extended product query hook is supplied as a parameter in the search method.

}
}

@Test
Copy link
Contributor Author

Choose a reason for hiding this comment

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

These tests (or similar tests) have been moved to the Pager class which is responsible for computing pagination.

id-mitchell and others added 7 commits April 14, 2020 14:18
* I've reverted the parseCategoryId call to use the current (`master`) version of this method without the Optional or value checking.
* I also remove the call that sanitized the search term query string per PR feedback (it's likely better to allow this sort of heavy handed decision to be decided by the implementer or allow Magento's API to respond appropriately if strange search terms are used)
- removed usage of "selectors" to build urls
- remove duplicate html templates
- fixed issue when product cannot be converted
- modified code and added tests to support missing introspection results
…pection

# Conflicts:
#	bundles/core/src/main/java/com/adobe/cq/commerce/core/components/internal/models/v1/productlist/ProductListImpl.java
#	bundles/core/src/main/java/com/adobe/cq/commerce/core/components/internal/models/v1/searchresults/SearchResultsImpl.java
#	bundles/core/src/test/java/com/adobe/cq/commerce/core/components/internal/models/v1/productlist/ProductListImplTest.java
#	bundles/core/src/test/java/com/adobe/cq/commerce/core/components/internal/models/v1/searchresults/SearchResultsImplTest.java
#	ui.apps/src/main/content/jcr_root/apps/core/cif/components/commerce/productlist/v1/productlist/paginationbar.html
@cjelger cjelger requested review from herzog31 and mhaack April 16, 2020 11:06
- enforce non empty search term in search component
- only display pagination when there are products
Map<String, String> getPreviousPageParameters();

/**
* Get the mext page parameters for supporting linking to the mext page.
Copy link
Member

Choose a reason for hiding this comment

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

Typo mext.

@Override
public SearchResultsSet getSearchResultsSet() {
if (searchResultsSet == null) {
searchResultsSet = searchResultsService.performSearch(searchOptions, resource, productPage, request);
Copy link
Member

Choose a reason for hiding this comment

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

Setting a query hook for the product query is supported via the 5th argument of the performSearch search method. However, currently a customer has no way of using it in any way using the Sling model delegation pattern. Replacing the whole query is also not possible.

The same applies for the SearchResults component.

Copy link
Contributor

Choose a reason for hiding this comment

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

Right I missed that, I had this in my radar and then forgot to check it ... We definitely have to support this.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
feature New feature or request verified
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants