File

integration-libs/cds/src/merchandising/cms-components/merchandising-carousel/merchandising-carousel.component.ts

Metadata

changeDetection ChangeDetectionStrategy.OnPush
selector cx-merchandising-carousel
templateUrl ./merchandising-carousel.component.html

Index

Properties
Methods

Constructor

constructor(componentData: CmsComponentData<CmsMerchandisingCarouselComponent>, merchandisingCarouselComponentService: MerchandisingCarouselComponentService, routingService: RoutingService, intersectionService: IntersectionService, el: ElementRef)
Parameters :
Name Type Optional
componentData CmsComponentData<CmsMerchandisingCarouselComponent> No
merchandisingCarouselComponentService MerchandisingCarouselComponentService No
routingService RoutingService No
intersectionService IntersectionService No
el ElementRef No

Methods

onMerchandisingCarouselItemClick
onMerchandisingCarouselItemClick(merchandisingCarouselModel: MerchandisingCarouselModel, clickedProduct: MerchandisingProduct)
Parameters :
Name Type Optional
merchandisingCarouselModel MerchandisingCarouselModel No
clickedProduct MerchandisingProduct No
Returns : void

Properties

Private fetchProducts$
Type : Observable<MerchandisingCarouselModel>
Default value : this.componentData.data$.pipe( filter((data) => Boolean(data)), distinctUntilKeyChanged('strategy'), switchMap((data) => this.merchandisingCarouselComponentService.getMerchandisingCarouselModel( data ) ), tap((data) => { if (typeof data.backgroundColor === 'string') { this.el.nativeElement.style.setProperty( '--cx-color-background', data.backgroundColor ); } if (typeof data.textColor === 'string') { this.el.nativeElement.style.setProperty( '--cx-color-text', data.textColor ); } }), shareReplay({ bufferSize: 1, refCount: true }) )
Private intersection$
Type : Observable<void>
Default value : this.fetchProducts$.pipe( take(1), switchMapTo( this.routingService.getPageContext().pipe( switchMapTo(this.componentData.data$), map((data) => this.merchandisingCarouselComponentService.getMerchandisingCaourselViewportThreshold( data ) ), switchMap((threshold) => this.intersectionService .isIntersected(this.el.nativeElement, { threshold, }) .pipe( filter((carouselIsVisible) => carouselIsVisible), switchMap((_) => { return this.merchandisingCarouselComponentService .sendCarouselViewEvent( this.lastEventModelId, this.fetchProducts$ ) .pipe( tap((model) => { this.lastEventModelId = model.id; }), switchMapTo(of()) ); }) ) ) ) ) )
Protected lastEventModelId
Type : string
merchandisingCarouselModel$
Default value : using( () => this.intersection$.subscribe(), () => this.fetchProducts$ )
import { ChangeDetectionStrategy, Component, ElementRef } from '@angular/core';
import { RoutingService } from '@spartacus/core';
import { CmsComponentData, IntersectionService } from '@spartacus/storefront';
import { Observable, of, using } from 'rxjs';
import {
  distinctUntilKeyChanged,
  filter,
  map,
  shareReplay,
  switchMap,
  switchMapTo,
  take,
  tap,
} from 'rxjs/operators';
import { CmsMerchandisingCarouselComponent } from '../../../cds-models/cms.model';
import { MerchandisingProduct } from '../../model/index';
import { MerchandisingCarouselComponentService } from './merchandising-carousel.component.service';
import { MerchandisingCarouselModel } from './model/index';

@Component({
  selector: 'cx-merchandising-carousel',
  templateUrl: './merchandising-carousel.component.html',
  changeDetection: ChangeDetectionStrategy.OnPush,
})
export class MerchandisingCarouselComponent {
  protected lastEventModelId: string;

  constructor(
    protected componentData: CmsComponentData<CmsMerchandisingCarouselComponent>,
    protected merchandisingCarouselComponentService: MerchandisingCarouselComponentService,
    protected routingService: RoutingService,
    protected intersectionService: IntersectionService,
    protected el: ElementRef
  ) {
    this.lastEventModelId = '';
  }

  private fetchProducts$: Observable<MerchandisingCarouselModel> =
    this.componentData.data$.pipe(
      filter((data) => Boolean(data)),
      distinctUntilKeyChanged('strategy'),
      switchMap((data) =>
        this.merchandisingCarouselComponentService.getMerchandisingCarouselModel(
          data
        )
      ),
      tap((data) => {
        if (typeof data.backgroundColor === 'string') {
          this.el.nativeElement.style.setProperty(
            '--cx-color-background',
            data.backgroundColor
          );
        }
        if (typeof data.textColor === 'string') {
          this.el.nativeElement.style.setProperty(
            '--cx-color-text',
            data.textColor
          );
        }
      }),
      shareReplay({ bufferSize: 1, refCount: true })
    );

  private intersection$: Observable<void> = this.fetchProducts$.pipe(
    take(1),
    switchMapTo(
      this.routingService.getPageContext().pipe(
        switchMapTo(this.componentData.data$),
        map((data) =>
          this.merchandisingCarouselComponentService.getMerchandisingCaourselViewportThreshold(
            data
          )
        ),
        switchMap((threshold) =>
          this.intersectionService
            .isIntersected(this.el.nativeElement, {
              threshold,
            })
            .pipe(
              filter((carouselIsVisible) => carouselIsVisible),
              switchMap((_) => {
                return this.merchandisingCarouselComponentService
                  .sendCarouselViewEvent(
                    this.lastEventModelId,
                    this.fetchProducts$
                  )
                  .pipe(
                    tap((model) => {
                      this.lastEventModelId = model.id;
                    }),
                    switchMapTo(of())
                  );
              })
            )
        )
      )
    )
  );

  merchandisingCarouselModel$ = using(
    () => this.intersection$.subscribe(),
    () => this.fetchProducts$
  );

  onMerchandisingCarouselItemClick(
    merchandisingCarouselModel: MerchandisingCarouselModel,
    clickedProduct: MerchandisingProduct
  ): void {
    this.merchandisingCarouselComponentService.sendCarouselItemClickedEvent(
      merchandisingCarouselModel,
      clickedProduct
    );
  }
}
<ng-container
  *ngIf="merchandisingCarouselModel$ | async as merchandisingCarouselModel"
>
  <div
    class="data-cx-merchandising-carousel"
    [cxAttributes]="merchandisingCarouselModel.metadata"
    [cxAttributesNamePrefix]="'data-cx-merchandising-carousel'"
  ></div>
  <cx-carousel
    [items]="merchandisingCarouselModel.items$"
    [title]="merchandisingCarouselModel.title"
    [template]="carouselItem"
    itemWidth="285px"
  >
  </cx-carousel>

  <ng-template #carouselItem let-item="item">
    <div
      class="data-cx-merchandising-product"
      [cxAttributes]="item.metadata"
      [cxAttributesNamePrefix]="'data-cx-merchandising-product'"
    ></div>
    <a
      tabindex="0"
      [routerLink]="{ cxRoute: 'product', params: item } | cxUrl"
      (click)="
        onMerchandisingCarouselItemClick(merchandisingCarouselModel, item)
      "
    >
      <cx-media
        *ngIf="item.images?.PRIMARY"
        [container]="item.images.PRIMARY"
        format="product"
      >
      </cx-media>
      <h4>{{ item.name }}</h4>
      <div class="price">
        {{ item.price?.formattedValue }}
      </div>
      <div class="price" *ngIf="item.stock?.stockLevel > 0; else outOfStock">
        {{ item.stock?.stockLevelStatus }} : {{ item.stock?.stockLevel }}
      </div>
      <ng-template #outOfStock>
        <div class="price">
          {{ item.stock?.stockLevelStatus }}
        </div>
      </ng-template>
    </a>
  </ng-template>
</ng-container>
Legend
Html element
Component
Html element with directive

result-matching ""

    No results matching ""