File
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 |
Methods
|
isBundleBasedConfigurator
|
isBundleBasedConfigurator(entry: OrderEntry)
|
|
|
Verifies whether the configurator type is a bundle based one.
Parameters :
| Name |
Type |
Optional |
Description |
| entry |
OrderEntry
|
No
|
|
- '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 than
BREAKPOINT.md returns true, otherwise false.
|
|
toggleItems
|
toggleItems()
|
|
|
Toggles the state of the items list.
|
|
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 with directive