File

projects/storefrontlib/cms-components/cart/add-to-cart/added-to-cart-dialog/added-to-cart-dialog.component.ts

Implements

OnInit

Metadata

selector cx-added-to-cart-dialog
templateUrl ./added-to-cart-dialog.component.html

Index

Properties
Methods

Constructor

constructor(modalService: ModalService, cartService: ActiveCartService)
Parameters :
Name Type Optional
modalService ModalService No
cartService ActiveCartService No

Methods

dismissModal
dismissModal(reason?: any)
Parameters :
Name Type Optional
reason any Yes
Returns : void
getQuantityControl
getQuantityControl()

Returns an observable formControl with the quantity of the cartEntry, but also updates the entry in case of a changed value. The quantity can be set to zero in order to remove the entry.

Returns : Observable<FormControl>
Protected getQuantityFormControl
getQuantityFormControl(entry: OrderEntry)

Adds quantity and entryNumber form controls to the FormGroup. Returns quantity form control.

Parameters :
Name Type Optional
entry OrderEntry No
Returns : FormControl
ngOnInit
ngOnInit()
Returns : void

Properties

addedEntryWasMerged$
Type : Observable<boolean>
cart$
Type : Observable<Cart>
dialog
Type : ElementRef
Decorators :
@ViewChild('dialog', {read: ElementRef})
entry$
Type : Observable<OrderEntry>
form
Type : FormGroup
Default value : new FormGroup({})
iconTypes
Default value : ICON_TYPE
loaded$
Type : Observable<boolean>
modalIsOpen
Default value : false
numberOfEntriesBeforeAdd
Type : number
promotionLocation
Type : PromotionLocation
Default value : PromotionLocation.ActiveCart
quantity
Type : number
Default value : 0
Protected quantityControl$
Type : Observable<FormControl>
import { Component, ElementRef, OnInit, ViewChild } from '@angular/core';
import { FormControl, FormGroup } from '@angular/forms';
import {
  ActiveCartService,
  Cart,
  OrderEntry,
  PromotionLocation,
} from '@spartacus/core';
import { Observable } from 'rxjs';
import {
  filter,
  map,
  shareReplay,
  startWith,
  switchMap,
  switchMapTo,
  tap,
} from 'rxjs/operators';
import { ICON_TYPE } from '../../../../cms-components/misc/icon/icon.model';
import { ModalService } from '../../../../shared/components/modal/modal.service';

@Component({
  selector: 'cx-added-to-cart-dialog',
  templateUrl: './added-to-cart-dialog.component.html',
})
export class AddedToCartDialogComponent implements OnInit {
  iconTypes = ICON_TYPE;

  entry$: Observable<OrderEntry>;
  cart$: Observable<Cart>;
  loaded$: Observable<boolean>;
  addedEntryWasMerged$: Observable<boolean>;
  numberOfEntriesBeforeAdd: number;
  promotionLocation: PromotionLocation = PromotionLocation.ActiveCart;

  quantity = 0;
  modalIsOpen = false;

  @ViewChild('dialog', { read: ElementRef })
  dialog: ElementRef;

  form: FormGroup = new FormGroup({});

  protected quantityControl$: Observable<FormControl>;

  constructor(
    protected modalService: ModalService,
    protected cartService: ActiveCartService
  ) {}
  /**
   * Returns an observable formControl with the quantity of the cartEntry,
   * but also updates the entry in case of a changed value.
   * The quantity can be set to zero in order to remove the entry.
   */
  getQuantityControl(): Observable<FormControl> {
    if (!this.quantityControl$) {
      this.quantityControl$ = this.entry$.pipe(
        filter((e) => !!e),
        map((entry) => this.getQuantityFormControl(entry)),
        switchMap(() =>
          this.form.valueChanges.pipe(
            // eslint-disable-next-line import/no-deprecated
            startWith(null),
            tap((valueChange) => {
              if (valueChange) {
                this.cartService.updateEntry(
                  valueChange.entryNumber,
                  valueChange.quantity
                );
                if (valueChange.quantity === 0) {
                  this.dismissModal('Removed');
                }
              } else {
                this.form.markAsPristine();
              }
            })
          )
        ),
        map(() => <FormControl>this.form.get('quantity')),
        shareReplay({ bufferSize: 1, refCount: true })
      );
    }
    return this.quantityControl$;
  }

  ngOnInit() {
    this.addedEntryWasMerged$ = this.loaded$.pipe(
      filter((loaded) => loaded),
      switchMapTo(this.cartService.getEntries()),
      map((entries) => entries.length === this.numberOfEntriesBeforeAdd)
    );
  }

  /**
   * Adds quantity and entryNumber form controls to the FormGroup.
   * Returns quantity form control.
   */
  protected getQuantityFormControl(entry: OrderEntry): FormControl {
    if (!this.form.get('quantity')) {
      const quantity = new FormControl(entry.quantity, { updateOn: 'blur' });
      this.form.addControl('quantity', quantity);

      const entryNumber = new FormControl(entry.entryNumber);
      this.form.addControl('entryNumber', entryNumber);
    }
    return <FormControl>this.form.get('quantity');
  }

  dismissModal(reason?: any): void {
    this.modalService.dismissActiveModal(reason);
  }
}
<div #dialog>
  <!-- Modal Header -->
  <ng-container *ngIf="(loaded$ | async) || modalIsOpen; else loading">
    <div class="cx-dialog-header modal-header">
      <div
        class="cx-dialog-title modal-title"
        aria-live="polite"
        aria-atomic="true"
      >
        {{
          (addedEntryWasMerged$ | async)
            ? ('addToCart.itemsIncrementedInYourCart' | cxTranslate)
            : ('addToCart.itemsAddedToYourCart' | cxTranslate)
        }}
      </div>
      <button
        type="button"
        class="close"
        attr.aria-label="{{ 'addToCart.closeModal' | cxTranslate }}"
        cxModal="dismiss"
        cxModalReason="Cross click"
      >
        <span aria-hidden="true">
          <cx-icon [type]="iconTypes.CLOSE"></cx-icon>
        </span>
      </button>
    </div>
    <!-- Modal Body -->
    <div class="cx-dialog-body modal-body" *ngIf="entry$ | async as entry">
      <div class="cx-dialog-row">
        <div class="cx-dialog-item col-sm-12 col-md-6">
          <cx-cart-item
            [item]="entry"
            [compact]="true"
            [quantityControl]="getQuantityControl() | async"
            [promotionLocation]="promotionLocation"
          ></cx-cart-item>
        </div>
        <!-- Separator -->
        <div
          class="cx-dialog-separator col-sm-12 d-xs-block d-sm-block d-md-none"
        ></div>
        <!-- Total container -->
        <div
          class="cx-dialog-actions col-sm-12 col-md-6"
          *ngIf="cart$ | async as cart"
        >
          <div class="cx-dialog-total">
            <div>
              {{
                'cartItems.cartTotal'
                  | cxTranslate: { count: cart.deliveryItemsQuantity }
              }}
            </div>

            <div>{{ cart.subTotal?.formattedValue }}</div>
          </div>

          <!-- Promotions -->
          <div class="cx-dialog-promotions">
            <cx-promotions
              [promotions]="
                (cart.appliedOrderPromotions || []).concat(
                  cart.potentialOrderPromotions || []
                )
              "
            ></cx-promotions>
          </div>

          <!-- Actions -->
          <div class="cx-dialog-buttons">
            <a
              [class.disabled]="form.dirty"
              [routerLink]="{ cxRoute: 'cart' } | cxUrl"
              cxModal="dismiss"
              cxModalReason="View Cart click"
              class="btn btn-primary"
              autofocus
              >{{ 'addToCart.viewCart' | cxTranslate }}</a
            >
            <a
              [class.disabled]="form.dirty"
              [routerLink]="{ cxRoute: 'checkout' } | cxUrl"
              cxModal="dismiss"
              cxModalReason="Proceed To Checkout click"
              class="btn btn-secondary"
              >{{ 'addToCart.proceedToCheckout' | cxTranslate }}</a
            >
          </div>
        </div>
      </div>
    </div>
  </ng-container>

  <ng-template #loading>
    <div class="cx-dialog-header modal-header">
      <div class="cx-dialog-title modal-title">
        {{ 'addToCart.updatingCart' | cxTranslate }}
      </div>
      <button
        type="button"
        class="close"
        [attr.aria-label]="'common.close' | cxTranslate"
        cxModal="dismiss"
        cxModalReason="Cross click"
      >
        <span aria-hidden="true">
          <cx-icon [type]="iconTypes.CLOSE"></cx-icon>
        </span>
      </button>
    </div>
    <!-- Modal Body -->
    <div class="cx-dialog-body modal-body">
      <div class="cx-dialog-row">
        <div class="col-sm-12"><cx-spinner></cx-spinner></div>
      </div>
    </div>
  </ng-template>
</div>
Legend
Html element
Component
Html element with directive

result-matching ""

    No results matching ""