File

feature-libs/product-configurator/common/components/configurator-cart-entry-bundle-info/configurator-cart-entry-bundle-info.component.ts

Description

Requires default change detection strategy, as the disabled state of the quantity from control may change, which would not be proper detected with onPush strategy.

Metadata

selector cx-configurator-cart-entry-bundle-info
templateUrl ./configurator-cart-entry-bundle-info.component.html

Index

Properties
Methods

Constructor

constructor(commonConfigUtilsService: CommonConfiguratorUtilsService, configCartEntryBundleInfoService: ConfiguratorCartEntryBundleInfoService, breakpointService: BreakpointService, cartItemContext?: CartItemContext)
Parameters :
Name Type Optional
commonConfigUtilsService CommonConfiguratorUtilsService No
configCartEntryBundleInfoService ConfiguratorCartEntryBundleInfoService No
breakpointService BreakpointService No
cartItemContext CartItemContext Yes

Methods

isBundleBasedConfigurator
isBundleBasedConfigurator(entry: OrderEntry)

Verifies whether the configurator type is a bundle based one.

Parameters :
Name Type Optional Description
entry OrderEntry No
  • Order entry
Returns : boolean
  • 'true' if the expected configurator type, otherwise 'false'
isDesktop
isDesktop()

Verifies whether the current screen size equals or is larger than breakpoint BREAKPOINT.md.

Returns : Observable<boolean>
  • If the given breakpoint equals or is larger thanBREAKPOINT.md returns true, otherwise false.
toggleItems
toggleItems()

Toggles the state of the items list.

Returns : void

Properties

hideItems
Default value : true
lineItems$
Type : Observable<LineItem[]>
Default value : this.orderEntry$.pipe( map((entry) => this.configCartEntryBundleInfoService.retrieveLineItems(entry) ) )
numberOfLineItems$
Type : Observable<number>
Default value : this.lineItems$.pipe( map((items) => items.length) )
Readonly orderEntry$
Type : Observable<OrderEntry>
Default value : this.cartItemContext?.item$ ?? EMPTY
Readonly quantityControl$
Type : Observable<FormControl>
Default value : this.cartItemContext?.quantityControl$ ?? EMPTY
Readonly readonly$
Type : Observable<boolean>
Default value : this.cartItemContext?.readonly$ ?? EMPTY
Readonly shouldShowButton$
Type : Observable<boolean>
Default value : this.commonConfigUtilsService.isActiveCartContext(this.cartItemContext)
import { Component, Optional } from '@angular/core';
import { FormControl } from '@angular/forms';
import { OrderEntry } from '@spartacus/core';
import {
  BREAKPOINT,
  BreakpointService,
  CartItemContext,
} from '@spartacus/storefront';
import { EMPTY, Observable } from 'rxjs';
import { map } from 'rxjs/operators';
import { CommonConfiguratorUtilsService } from '../../shared/utils/common-configurator-utils.service';
import { LineItem } from './configurator-cart-entry-bundle-info.model';
import { ConfiguratorCartEntryBundleInfoService } from './configurator-cart-entry-bundle-info.service';

/**
 * Requires default change detection strategy, as the disabled state of the quantity from control may change,
 * which would not be proper detected with onPush strategy.
 */
@Component({
  selector: 'cx-configurator-cart-entry-bundle-info',
  templateUrl: './configurator-cart-entry-bundle-info.component.html',
})
export class ConfiguratorCartEntryBundleInfoComponent {
  constructor(
    protected commonConfigUtilsService: CommonConfiguratorUtilsService,
    protected configCartEntryBundleInfoService: ConfiguratorCartEntryBundleInfoService,
    protected breakpointService: BreakpointService,
    @Optional() protected cartItemContext?: CartItemContext
  ) {}

  readonly orderEntry$: Observable<OrderEntry> =
    this.cartItemContext?.item$ ?? EMPTY;

  readonly quantityControl$: Observable<FormControl> =
    this.cartItemContext?.quantityControl$ ?? EMPTY;

  readonly readonly$: Observable<boolean> =
    this.cartItemContext?.readonly$ ?? EMPTY;

  hideItems = true;

  lineItems$: Observable<LineItem[]> = this.orderEntry$.pipe(
    map((entry) =>
      this.configCartEntryBundleInfoService.retrieveLineItems(entry)
    )
  );

  numberOfLineItems$: Observable<number> = this.lineItems$.pipe(
    map((items) => items.length)
  );

  /**
   * Toggles the state of the items list.
   */
  toggleItems(): void {
    this.hideItems = !this.hideItems;
  }

  /**
   * Verifies whether the configurator type is a bundle based one.
   *
   * @param {OrderEntry} entry - Order entry
   * @returns {boolean} - 'true' if the expected configurator type, otherwise 'false'
   */
  isBundleBasedConfigurator(entry: OrderEntry): boolean {
    const configInfos = entry.configurationInfos;
    return configInfos
      ? this.commonConfigUtilsService.isBundleBasedConfigurator(
          configInfos[0]?.configuratorType
        )
      : false;
  }

  /**
   * Verifies whether the current screen size equals or is larger than breakpoint `BREAKPOINT.md`.
   *
   * @returns {Observable<boolean>} - If the given breakpoint equals or is larger than`BREAKPOINT.md` returns `true`, otherwise `false`.
   */
  isDesktop(): Observable<boolean> {
    return this.breakpointService?.isUp(BREAKPOINT.md);
  }

  // TODO: remove the logic below when configurable products support "Saved Cart" and "Save For Later"
  readonly shouldShowButton$: Observable<boolean> =
    this.commonConfigUtilsService.isActiveCartContext(this.cartItemContext);
}
<ng-container *ngIf="orderEntry$ | async as orderEntry">
  <ng-container *ngIf="isBundleBasedConfigurator(orderEntry)">
    <ng-container *ngIf="numberOfLineItems$ | async as numberOfItems">
      <div class="cx-number-items">
        {{
          'configurator.header.items' | cxTranslate: { count: numberOfItems }
        }}
      </div>
      <button (click)="toggleItems()">
        <div class="cx-toggle-hide-items">
          <ng-container *ngIf="hideItems">
            {{ 'configurator.header.show' | cxTranslate }}
          </ng-container>
          <ng-container *ngIf="!hideItems">
            {{ 'configurator.header.hide' | cxTranslate }}
          </ng-container>
        </div>
      </button>

      <div class="cx-item-infos" [class.open]="!hideItems">
        <div class="cx-item-info" *ngFor="let lineItem of lineItems$ | async">
          <div class="cx-item-name">
            {{ lineItem?.name }}
          </div>
          <ng-container *ngIf="isDesktop() | async; else mobile">
            <div class="cx-item-price">
              <span class="cx-item" *ngIf="lineItem?.formattedPrice">{{
                lineItem?.formattedPrice
              }}</span>
            </div>
            <div class="cx-item-quantity">
              <span class="cx-item" *ngIf="lineItem?.formattedQuantity">{{
                lineItem?.formattedQuantity | cxNumeric
              }}</span>
            </div>
          </ng-container>
          <ng-template #mobile>
            <div class="cx-item-quantity">
              <ng-container *ngIf="lineItem?.formattedQuantity">
                <span class="cx-identifier">{{
                  'configurator.attribute.quantity' | cxTranslate
                }}</span>
                <span class="cx-item">{{
                  lineItem?.formattedQuantity | cxNumeric
                }}</span>
              </ng-container>
            </div>
            <div class="cx-item-price">
              <ng-container *ngIf="lineItem?.formattedPrice">
                <span class="cx-identifier">{{
                  'configurator.overviewForm.itemPrice' | cxTranslate
                }}</span>
                <span class="cx-item">{{ lineItem?.formattedPrice }}</span>
              </ng-container>
            </div>
          </ng-template>
        </div>
      </div>
    </ng-container>
    <cx-configure-cart-entry
      *ngIf="
        (shouldShowButton$ | async) &&
          orderEntry?.product?.configurable &&
          quantityControl$ | async as quantityControl
      "
      [cartEntry]="orderEntry"
      [readOnly]="readonly$ | async"
      [msgBanner]="false"
      [disabled]="quantityControl.disabled"
    ></cx-configure-cart-entry>
  </ng-container>
</ng-container>
Legend
Html element
Component
Html element with directive

result-matching ""

    No results matching ""