SAP / spartacus

Spartacus is a lean, Angular-based JavaScript storefront for SAP Commerce Cloud that communicates exclusively through the Commerce REST API.
Apache License 2.0
736 stars 381 forks source link

Make pageSize in ProductListComponentService configurable #11097

Open janwidmer opened 3 years ago

janwidmer commented 3 years ago

Is your feature request related to a problem? Please describe. A fairly common feature on the product list page is, that the customer is able to set the pageSize to define the number of products, he can see on one page. Currently, this value is hardcoded in the service ProductListComponentService:

image

Describe the solution you'd like The service ProductListComponentService get's enhanced by a setPageSize method. The default pageSize parameter is configurable to be able to set the default value, the customer wants (when having 3 grid items, 10 items per page always leaves a single item per row at the end of the list)

Describe alternatives you've considered As a workaround, we tried to extend the service ProductListComponentService, but that did not work that well (leaded to duplicated search requests where the first always got cancelled due to timing requests).

We now made it work by directly using the routing when setting the page size and overriding the facet service:

// product-list.component.ts
model$: Observable<ProductSearchPage> = this.productListComponentService.model$.pipe(
    // get pageSize from model and set in query parameters
    tap((model: ProductSearchPage) =>
        this.pageSize$
            .pipe(
                take(1),
                filter((pageSize) => !pageSize)
            )
            // workaround as the model pageSize is based on the default value of 10, which is hardcoded in spartacus
            .subscribe(() => this.setPageSize(model.pageSizes.sizes[0]))
            //.subscribe(() => this.setPageSize(model.pagination?.pageSize))
    )
);

setPageSize(pageSize: number | undefined): void {
    if (pageSize === undefined) return;

    // change pageSize in query parameters by triggering a route change
    this.router.navigate([], {
        queryParams: { pageSize, currentPage: '0' },
        queryParamsHandling: 'merge',
        relativeTo: this.activatedRoute,
    });
}

// custom-facet.service.ts
constructor(productFacetService: ProductFacetService, activatedRoute: ActivatedRoute) {
    super(productFacetService);
    this.subscription = activatedRoute.queryParamMap.pipe().subscribe((params) => {
        this.pageSize = params.get('pageSize') || undefined;
    });
}

getLinkParams(query: string): { [key: string]: string } {
    const queryParams = super.getLinkParams(query);
    if (!this.pageSize) return queryParams;
    return {
        ...queryParams,
        pageSize: this.pageSize,
    };
}

Additional context It would probably make sense to do the adjustment together with ticket #7191

Ross-Rawlins commented 2 years ago

Is there any new news on this?

dydome commented 2 years ago

@janwidmer @Ross-Rawlins There is the possibility to modify the page size for the product list. In the ProductListComponentService there is method getCriteriaFromRoute which takes pageSize from query params or from config. You can modify Config in your module. The default config for product list is here projects/storefrontlib/cms-components/product/config/default-view-config.ts

Xymmer commented 2 years ago

we can close this? or is there more to do?

janwidmer commented 2 years ago

@dydome @Xymmer as far as I understand, the config option mentioned is only to change the page size for all users? What the customers usually want (and what is pretty much standard in the ECommerce World) is, that they have a dropdown above the product list, where each user chan choose the page size he wants (same as changing the sort or the list view type)

So in my opinion, this ticket is still valid and the request would be to have a method in the ProductListComponentService to change the pageSize Value, according to the sort method:

sort(sortCode: string): void {
    this.route({ sortCode });
  }

When we last tried to extend the ProductListComponentService, it lead to duplicated Search Requests, as described above in the initial ticket descripton. @dydome can you confirm, that it should be possible to extend the ProductListComponentService without duplicated search requests?