File

projects/storefrontlib/cms-components/product/product-intro/product-intro.component.ts

Implements

AfterContentChecked

Metadata

changeDetection ChangeDetectionStrategy.OnPush
selector cx-product-intro
templateUrl ./product-intro.component.html

Index

Properties
Methods

Constructor

constructor(currentProductService: CurrentProductService, translationService: TranslationService, winRef: WindowRef)
Parameters :
Name Type Optional
currentProductService CurrentProductService No
translationService TranslationService No
winRef WindowRef No

Methods

Private clickTabIfInactive
clickTabIfInactive(tab: HTMLElement)
Parameters :
Name Type Optional
tab HTMLElement No
Returns : void
Private getReviewsComponent
getReviewsComponent()
Returns : Element
Private getTabByLabel
getTabByLabel(label: string, tabsComponent: Element)
Parameters :
Name Type Optional
label string No
tabsComponent Element No
Returns : HTMLElement
Private getTabsComponent
getTabsComponent()
Returns : Element
ngAfterContentChecked
ngAfterContentChecked()
Returns : void
showReviews
showReviews()
Returns : void

Properties

product$
Type : Observable<Product>
Default value : this.currentProductService.getProduct()
reviewsTabAvailable
Default value : new BehaviorSubject<boolean>(false)
import {
  AfterContentChecked,
  ChangeDetectionStrategy,
  Component,
} from '@angular/core';
import { Product, TranslationService, WindowRef } from '@spartacus/core';
import { BehaviorSubject, Observable } from 'rxjs';
import { CurrentProductService } from '../current-product.service';

@Component({
  selector: 'cx-product-intro',
  templateUrl: './product-intro.component.html',
  changeDetection: ChangeDetectionStrategy.OnPush,
})
export class ProductIntroComponent implements AfterContentChecked {
  reviewsTabAvailable = new BehaviorSubject<boolean>(false);

  product$: Observable<Product> = this.currentProductService.getProduct();

  constructor(
    protected currentProductService: CurrentProductService,
    private translationService: TranslationService,
    protected winRef: WindowRef
  ) {}

  ngAfterContentChecked() {
    this.reviewsTabAvailable.next(!!this.getReviewsComponent());
  }

  // Scroll to views component on page and click "Reviews" tab
  showReviews() {
    // Use translated label for Reviews tab reference
    this.translationService
      .translate('TabPanelContainer.tabs.ProductReviewsTabComponent')
      .subscribe((reviewsTabLabel) => {
        const tabsComponent = this.getTabsComponent();
        const reviewsTab = this.getTabByLabel(reviewsTabLabel, tabsComponent);
        const reviewsComponent = this.getReviewsComponent();
        if (reviewsTab && reviewsComponent) {
          this.clickTabIfInactive(reviewsTab);
          setTimeout(
            () => reviewsComponent.scrollIntoView({ behavior: 'smooth' }),
            0
          );
        }
      })
      .unsubscribe();
  }

  // NOTE: Does not currently exists as its own component
  // but part of tabs component. This is likely to change in refactor.
  private getReviewsComponent(): Element {
    return this.winRef.document.querySelector('cx-product-reviews');
  }

  // Get Tabs Component if exists on page
  private getTabsComponent(): Element {
    return this.winRef.document.querySelector('cx-tab-paragraph-container');
  }

  // Click to activate tab if not already active
  private clickTabIfInactive(tab: HTMLElement): void {
    if (
      !tab.classList.contains('active') ||
      tab.classList.contains('toggled')
    ) {
      tab.click();
    }
  }

  // Get Tab by label if exists on page
  private getTabByLabel(label: string, tabsComponent: Element): HTMLElement {
    if (tabsComponent) {
      // NOTE: Reads through button tags to click on correct tab
      // There may be a better way of doing this now/after refactor
      const tabElements: HTMLCollectionOf<HTMLElement> =
        tabsComponent.getElementsByTagName('button');

      // Look through button tab elements until finding tab with label
      for (const buttonElement of Array.from(tabElements)) {
        if (buttonElement.innerHTML.includes(label)) {
          return buttonElement;
        }
      }
    }
  }
}
<ng-container *ngIf="product$ | async as product">
  <div class="rating" *ngIf="product.averageRating">
    <cx-star-rating [rating]="product?.averageRating"></cx-star-rating>

    <div class="count">({{ product?.numberOfReviews }})</div>

    <button
      *ngIf="reviewsTabAvailable | async"
      class="btn btn-link cx-action-link"
      (click)="showReviews()"
      [attr.aria-label]="
        'productSummary.showReviewsDetailed'
          | cxTranslate
            : {
                rating: product.averageRating | number: '1.0-1',
                count: product?.numberOfReviews
              }
      "
    >
      {{ 'productSummary.showReviews' | cxTranslate }}
    </button>
  </div>
  <div class="rating" *ngIf="!product.averageRating">
    {{ 'productDetails.noReviews' | cxTranslate }}
  </div>
  <div class="code">
    {{ 'productSummary.id' | cxTranslate }} {{ product?.code }}
  </div>
</ng-container>
Legend
Html element
Component
Html element with directive

result-matching ""

    No results matching ""