File

projects/storefrontlib/cms-components/myaccount/my-interests/my-interests.component.ts

Implements

OnInit OnDestroy

Metadata

changeDetection ChangeDetectionStrategy.OnPush
selector cx-my-interests
templateUrl ./my-interests.component.html

Index

Properties
Methods

Constructor

constructor(productInterestService: UserInterestsService, translationService: TranslationService, productService: ProductService)
Parameters :
Name Type Optional
productInterestService UserInterestsService No
translationService TranslationService No
productService ProductService No

Methods

Private getProduct
getProduct(interest: ProductInterestEntryRelation)
Parameters :
Name Type Optional
interest ProductInterestEntryRelation No
Returns : Observable<Product>
Private getSortLabels
getSortLabels()
Returns : Observable<literal type>
ngOnDestroy
ngOnDestroy()
Returns : void
ngOnInit
ngOnInit()
Returns : void
pageChange
pageChange(page: number)
Parameters :
Name Type Optional
page number No
Returns : void
removeInterest
removeInterest(relation)
Parameters :
Name Optional
relation No
Returns : void
sortChange
sortChange(sort: string)
Parameters :
Name Type Optional
sort string No
Returns : void

Properties

Private DEFAULT_PAGE_SIZE
Type : number
Default value : 10
getInterestsloading$
Type : Observable<boolean>
interests$
Type : Observable<ProductInterestSearchResultUI>
isRemoveDisabled$
Type : Observable<boolean>
pagination
Type : PaginationModel
sort
Type : string
Default value : 'byNameAsc'
sortLabels
Type : Observable<literal type>
Private sortMapping
Type : object
Default value : { byNameAsc: 'name:asc', byNameDesc: 'name:desc', }
sortOptions
Type : []
Default value : [ { code: 'byNameAsc', selected: false, }, { code: 'byNameDesc', selected: false, }, ]
import {
  ChangeDetectionStrategy,
  Component,
  OnDestroy,
  OnInit,
} from '@angular/core';
import { combineLatest, Observable } from 'rxjs';
import {
  PaginationModel,
  Product,
  ProductInterestEntryRelation,
  ProductInterestSearchResult,
  ProductScope,
  ProductService,
  TranslationService,
  UserInterestsService,
} from '@spartacus/core';
import { map, tap } from 'rxjs/operators';

interface ProductInterestSearchResultUI extends ProductInterestSearchResult {
  results?: (ProductInterestEntryRelation & {
    product$?: Observable<Product>;
  })[];
}

@Component({
  selector: 'cx-my-interests',
  templateUrl: './my-interests.component.html',
  changeDetection: ChangeDetectionStrategy.OnPush,
})
export class MyInterestsComponent implements OnInit, OnDestroy {
  private DEFAULT_PAGE_SIZE = 10;
  private sortMapping = {
    byNameAsc: 'name:asc',
    byNameDesc: 'name:desc',
  };

  sort = 'byNameAsc';
  sortOptions = [
    {
      code: 'byNameAsc',
      selected: false,
    },
    {
      code: 'byNameDesc',
      selected: false,
    },
  ];
  pagination: PaginationModel;

  interests$: Observable<ProductInterestSearchResultUI>;
  isRemoveDisabled$: Observable<boolean>;
  getInterestsloading$: Observable<boolean>;
  sortLabels: Observable<{ byNameAsc: string; byNameDesc: string }>;

  constructor(
    private productInterestService: UserInterestsService,
    private translationService: TranslationService,
    private productService: ProductService
  ) {}

  ngOnInit() {
    this.interests$ = this.productInterestService
      .getAndLoadProductInterests(this.DEFAULT_PAGE_SIZE)
      .pipe(
        tap(
          (interests) =>
            (this.pagination = {
              currentPage: interests.pagination.page,
              pageSize: interests.pagination.count,
              totalPages: interests.pagination.totalPages,
              totalResults: interests.pagination.totalCount,
              sort: 'byNameAsc',
            })
        ),
        map((interest) => ({
          ...interest,
          results: interest.results
            ? interest.results.map((result) => ({
                ...result,
                product$: this.getProduct(result),
              }))
            : interest.results,
        }))
      );

    this.getInterestsloading$ =
      this.productInterestService.getProdutInterestsLoading();
    this.isRemoveDisabled$ = combineLatest([
      this.getInterestsloading$,
      this.productInterestService.getRemoveProdutInterestLoading(),
    ]).pipe(map(([getLoading, removeLoading]) => getLoading || removeLoading));

    this.sortLabels = this.getSortLabels();
  }

  private getSortLabels(): Observable<{
    byNameAsc: string;
    byNameDesc: string;
  }> {
    return combineLatest([
      this.translationService.translate('myInterests.sorting.byNameAsc'),
      this.translationService.translate('myInterests.sorting.byNameDesc'),
    ]).pipe(
      map(([asc, desc]) => {
        return {
          byNameAsc: asc,
          byNameDesc: desc,
        };
      })
    );
  }

  private getProduct(
    interest: ProductInterestEntryRelation
  ): Observable<Product> {
    return this.productService.get(interest.product.code, ProductScope.DETAILS);
  }

  removeInterest(
    relation: ProductInterestEntryRelation & {
      product$?: Observable<Product>;
    }
  ): void {
    this.productInterestService.removeProdutInterest({
      product: relation.product,
      productInterestEntry: relation.productInterestEntry,
    });
  }

  sortChange(sort: string): void {
    this.sort = sort;
    this.productInterestService.loadProductInterests(
      this.DEFAULT_PAGE_SIZE,
      0,
      this.sortMapping[sort]
    );
  }

  pageChange(page: number): void {
    this.productInterestService.loadProductInterests(
      this.DEFAULT_PAGE_SIZE,
      page,
      this.sortMapping[this.sort]
    );
  }

  ngOnDestroy(): void {
    this.productInterestService.clearProductInterests();
    this.productInterestService.resetRemoveInterestState();
  }
}
<div *ngIf="interests$ | async as interests" class="container">
  <div class="cx-product-interests-title h3">
    <h3>{{ 'myInterests.header' | cxTranslate }}</h3>
  </div>
  <div
    class="cx-product-interests-body"
    *ngIf="!(getInterestsloading$ | async); else loading"
  >
    <ng-container *ngIf="interests.pagination.totalCount > 0; else noInterest">
      <div class="cx-product-interests-sort top row">
        <label
          class="
            cx-product-interests-form-group
            form-group
            col-sm-12 col-md-4 col-lg-4
          "
          ><span>{{ 'myInterests.sortBy' | cxTranslate }}</span>
          <cx-sorting
            [sortOptions]="sortOptions"
            [sortLabels]="sortLabels | async"
            (sortListEvent)="sortChange($event)"
            [selectedOption]="sort"
            placeholder="{{ 'myInterests.sortBy' | cxTranslate }}"
          >
          </cx-sorting>
        </label>
        <div
          class="
            cx-product-interests-pagination cx-product-interests-thead-mobile
          "
        >
          <cx-pagination
            [pagination]="pagination"
            (viewPageEvent)="pageChange($event)"
          ></cx-pagination>
        </div>
      </div>
      <table class="table cx-product-interests-table">
        <thead class="cx-product-interests-thead-mobile">
          <th scope="col">
            {{ 'myInterests.item' | cxTranslate }}
          </th>
          <th scope="col"></th>
          <th scope="col">
            {{ 'myInterests.price' | cxTranslate }}
          </th>
          <th scope="col">
            {{ 'myInterests.notifications' | cxTranslate }}
          </th>
          <th scope="col"></th>
        </thead>
        <tbody>
          <tr
            *ngFor="let interest of interests.results"
            class="cx-product-interests-product-item"
          >
            <ng-container *ngIf="interest.product$ | async as product">
              <td>
                <div class="cx-product-interests-label">
                  <a
                    class="cx-product-interests-product-image-link"
                    tabindex="-1"
                    [routerLink]="
                      { cxRoute: 'product', params: product } | cxUrl
                    "
                  >
                    <cx-media
                      [container]="product.images?.PRIMARY"
                      format="thumbnail"
                    ></cx-media>
                  </a>
                </div>
              </td>
              <td>
                <div class="cx-info col-10">
                  <div class="cx-info-container row">
                    <div>
                      <div *ngIf="product.name" class="cx-name">
                        <a
                          class="cx-link cx-product-interests-product-code-link"
                          [routerLink]="
                            { cxRoute: 'product', params: product } | cxUrl
                          "
                        >
                          {{ product.name }}
                        </a>
                      </div>
                      <div *ngIf="product.code" class="cx-code">
                        <span>{{
                          'myInterests.productId'
                            | cxTranslate: { code: product.code }
                        }}</span>
                      </div>

                      <ng-container
                        *ngFor="let baseOptions of product.baseOptions"
                      >
                        <div
                          *ngFor="
                            let variant of baseOptions.selected
                              ?.variantOptionQualifiers
                          "
                          class="cx-property"
                        >
                          <div
                            class="cx-label cx-product-interests-variant-name"
                          >
                            {{ variant.name }}
                          </div>
                          <div
                            class="cx-value cx-product-interests-variant-value"
                          >
                            {{ variant.value }}
                          </div>
                        </div>
                      </ng-container>
                      <div
                        class="cx-property"
                        *ngIf="product.stock.stockLevelStatus === 'outOfStock'"
                      >
                        <div
                          class="cx-label cx-product-interests-product-stock"
                        >
                          {{ 'myInterests.outOfStock' | cxTranslate }}
                        </div>
                      </div>
                    </div>
                  </div>
                </div>
              </td>
              <td>
                <div class="cx-product-interests-product-price">
                  <div class="d-md-none cx-product-interests-label">
                    {{ 'myInterests.price' | cxTranslate }}
                  </div>
                  <span>{{ product.price.formattedValue }}</span>
                </div>
              </td>
              <td>
                <div class="cx-product-interests-subscriptions">
                  <div class="d-md-none cx-product-interests-label">
                    {{ 'myInterests.notifications' | cxTranslate }}
                  </div>
                  <div
                    class="cx-product-interests-notification"
                    *ngFor="let interestEntry of interest.productInterestEntry"
                  >
                    <span class="cx-product-interests-type">
                      {{
                        'myInterests.' + interestEntry.interestType
                          | cxTranslate
                      }}
                    </span>
                    <span class="cx-product-interests-expiration-date">
                      {{
                        'myInterests.expirationDate'
                          | cxTranslate
                            : {
                                expirationDate:
                                  interestEntry.expirationDate | date
                              }
                      }}
                    </span>
                  </div>
                </div>
              </td>
              <td>
                <div class="cx-actions cx-product-interests-remove-button">
                  <button
                    type="button"
                    class="link cx-product-interests-remove-btn"
                    [disabled]="isRemoveDisabled$ | async"
                    (click)="removeInterest(interest)"
                  >
                    {{ 'myInterests.remove' | cxTranslate }}
                  </button>
                </div>
              </td>
            </ng-container>
          </tr>
        </tbody>
      </table>
      <div class="cx-product-interests-sort bottom row">
        <label
          class="
            cx-product-interests-form-group cx-product-interests-thead-mobile
            form-group
            col-sm-12 col-md-4 col-lg-4
          "
          ><span>{{ 'myInterests.sortBy' | cxTranslate }}</span>
          <cx-sorting
            [sortOptions]="sortOptions"
            [sortLabels]="sortLabels | async"
            (sortListEvent)="sortChange($event)"
            [selectedOption]="sort"
            placeholder="{{ 'myInterests.sortBy' | cxTranslate }}"
          >
          </cx-sorting>
        </label>
        <div class="cx-product-interests-pagination">
          <cx-pagination
            [pagination]="pagination"
            (viewPageEvent)="pageChange($event)"
          ></cx-pagination>
        </div>
      </div>
    </ng-container>
  </div>
</div>
<ng-template #noInterest>
  <div class="cx-product-interests-message">
    {{ 'myInterests.noInterests' | cxTranslate }}
  </div>
</ng-template>
<ng-template #loading>
  <div class="cx-spinner">
    <cx-spinner></cx-spinner>
  </div>
</ng-template>
Legend
Html element
Component
Html element with directive

result-matching ""

    No results matching ""