feature-libs/cart/quick-order/components/quick-order/quick-order.component.ts
| changeDetection | ChangeDetectionStrategy.OnPush |
| selector | cx-quick-order |
| templateUrl | ./quick-order.component.html |
Properties |
|
Methods |
|
Accessors |
constructor(activeCartService: ActiveCartService, component: CmsComponentData<CmsQuickOrderComponent>, globalMessageService: GlobalMessageService, quickOrderService: QuickOrderFacade, quickOrderStatePersistenceService: QuickOrderStatePersistenceService)
|
||||||||||||||||||
|
Parameters :
|
| addToCart | ||||||
addToCart(orderEntries: OrderEntry[])
|
||||||
|
Parameters :
Returns :
void
|
| canAddProduct |
canAddProduct()
|
|
Returns :
Observable<boolean>
|
| clear |
clear()
|
|
Returns :
void
|
| clearAddToCartInformation |
clearAddToCartInformation()
|
|
Returns :
void
|
| clearDeletion | ||||||
clearDeletion(entry: OrderEntry)
|
||||||
|
Parameters :
Returns :
void
|
| clearErrors |
clearErrors()
|
|
Returns :
void
|
| clearNonPurchasableError |
clearNonPurchasableError()
|
|
Returns :
void
|
| Protected clearStatuses |
clearStatuses()
|
|
Returns :
void
|
| clearSuccesses |
clearSuccesses()
|
|
Returns :
void
|
| clearWarnings |
clearWarnings()
|
|
Returns :
void
|
| Protected extractErrors | ||||||
extractErrors(errors: QuickOrderAddEntryEvent[])
|
||||||
|
Parameters :
Returns :
void
|
| Protected extractSuccesses | |||||||||
extractSuccesses(errors: QuickOrderAddEntryEvent[], entries: OrderEntry[])
|
|||||||||
|
Parameters :
Returns :
void
|
| Protected extractWarnings | ||||||
extractWarnings(errors: QuickOrderAddEntryEvent[])
|
||||||
|
Parameters :
Returns :
void
|
| ngOnDestroy |
ngOnDestroy()
|
|
Returns :
void
|
| ngOnInit |
ngOnInit()
|
|
Returns :
void
|
| Protected setErrors | ||||||
setErrors(errors: QuickOrderAddEntryEvent[])
|
||||||
|
Parameters :
Returns :
void
|
| Protected setSuccesses | ||||||
setSuccesses(entries: OrderEntry[])
|
||||||
|
Parameters :
Returns :
void
|
| Protected setWarnings | ||||||
setWarnings(warnings: QuickOrderAddEntryEvent[])
|
||||||
|
Parameters :
Returns :
void
|
| Protected showAddedToCartSuccessMessage |
showAddedToCartSuccessMessage()
|
|
Returns :
void
|
| undoDeletion | ||||||
undoDeletion(entry: OrderEntry)
|
||||||
|
Parameters :
Returns :
void
|
| Protected cartErrors$ |
Default value : new BehaviorSubject<QuickOrderAddEntryEvent[]>([])
|
| cartId$ |
Type : Observable<string>
|
| Protected cartSuccesses$ |
Default value : new BehaviorSubject<OrderEntry[]>([])
|
| Protected cartWarnings$ |
Default value : new BehaviorSubject<QuickOrderAddEntryEvent[]>([])
|
| entries$ |
Type : Observable<OrderEntry[]>
|
| globalMessageType |
Default value : GlobalMessageType
|
| listLimitReached$ |
Type : Observable<boolean>
|
| Protected nonPurchasableProductError$ |
Default value : new BehaviorSubject<Product | null>(
null
)
|
| quickOrderForm |
Type : QuickOrderFormComponent
|
Decorators :
@ViewChild('quickOrderForm')
|
| quickOrderListLimit$ |
Type : Observable<number | undefined>
|
Default value : this.component.data$.pipe(
map((data) => data.quickOrderListLimit),
tap((limit) => {
if (!!limit) {
this.quickOrderService.setListLimit(limit);
}
})
)
|
| Protected showAddToCartInformation$ |
Default value : new BehaviorSubject<boolean>(false)
|
| errors$ |
geterrors$()
|
| warnings$ |
getwarnings$()
|
| successes$ |
getsuccesses$()
|
| nonPurchasableError$ |
getnonPurchasableError$()
|
| addToCartInformation$ |
getaddToCartInformation$()
|
| softDeletedEntries$ |
getsoftDeletedEntries$()
|
import {
ChangeDetectionStrategy,
Component,
OnDestroy,
OnInit,
ViewChild,
} from '@angular/core';
import {
CmsQuickOrderComponent,
QuickOrderStatePersistenceService,
} from '@spartacus/cart/quick-order/core';
import {
QuickOrderAddEntryEvent,
QuickOrderFacade,
} from '@spartacus/cart/quick-order/root';
import {
ActiveCartService,
GlobalMessageService,
GlobalMessageType,
OrderEntry,
Product,
} from '@spartacus/core';
import { CmsComponentData } from '@spartacus/storefront';
import { BehaviorSubject, combineLatest, Observable } from 'rxjs';
import { first, map, tap } from 'rxjs/operators';
import { QuickOrderFormComponent } from './form/quick-order-form.component';
@Component({
selector: 'cx-quick-order',
templateUrl: './quick-order.component.html',
changeDetection: ChangeDetectionStrategy.OnPush,
})
export class QuickOrderComponent implements OnInit, OnDestroy {
cartId$: Observable<string>;
entries$: Observable<OrderEntry[]>;
quickOrderListLimit$: Observable<number | undefined> =
this.component.data$.pipe(
map((data) => data.quickOrderListLimit),
tap((limit) => {
if (!!limit) {
this.quickOrderService.setListLimit(limit);
}
})
);
isCartStable$: Observable<boolean> = combineLatest([
this.activeCartService.getActiveCartId(),
this.activeCartService.isStable(),
]).pipe(map(([activeCartId, isStable]) => (!activeCartId ? true : isStable)));
globalMessageType = GlobalMessageType;
listLimitReached$: Observable<boolean>;
@ViewChild('quickOrderForm')
quickOrderForm: QuickOrderFormComponent;
protected cartErrors$ = new BehaviorSubject<QuickOrderAddEntryEvent[]>([]);
protected cartWarnings$ = new BehaviorSubject<QuickOrderAddEntryEvent[]>([]);
protected cartSuccesses$ = new BehaviorSubject<OrderEntry[]>([]);
protected showAddToCartInformation$ = new BehaviorSubject<boolean>(false);
protected nonPurchasableProductError$ = new BehaviorSubject<Product | null>(
null
);
constructor(
protected activeCartService: ActiveCartService,
protected component: CmsComponentData<CmsQuickOrderComponent>,
protected globalMessageService: GlobalMessageService,
protected quickOrderService: QuickOrderFacade,
protected quickOrderStatePersistenceService: QuickOrderStatePersistenceService
) {}
ngOnInit(): void {
this.cartId$ = this.activeCartService.getActiveCartId();
this.entries$ = this.quickOrderService.getEntries();
this.quickOrderStatePersistenceService.initSync();
}
ngOnDestroy(): void {
this.quickOrderService.clearDeletedEntries();
}
get errors$(): Observable<QuickOrderAddEntryEvent[]> {
return this.cartErrors$.asObservable();
}
get warnings$(): Observable<QuickOrderAddEntryEvent[]> {
return this.cartWarnings$.asObservable();
}
get successes$(): Observable<OrderEntry[]> {
return this.cartSuccesses$.asObservable();
}
get nonPurchasableError$(): Observable<Product | null> {
return this.quickOrderService.getNonPurchasableProductError();
}
get addToCartInformation$(): Observable<boolean> {
return this.showAddToCartInformation$.asObservable();
}
get softDeletedEntries$(): Observable<Record<string, OrderEntry>> {
return this.quickOrderService.getSoftDeletedEntries();
}
clear(): void {
this.quickOrderService.clearList();
this.globalMessageService.add(
{
key: 'quickOrderTable.listCleared',
},
GlobalMessageType.MSG_TYPE_INFO
);
}
addToCart(orderEntries: OrderEntry[]): void {
if (!orderEntries.length) {
this.showAddToCartInformation$.next(true);
return;
}
this.clearStatuses();
this.quickOrderService
.addToCart()
.pipe(first())
.subscribe(([entries, errors]) => {
errors.forEach((err) => {
if (!err.entry) {
err.entry = orderEntries.find(
(e) => e.product?.code === err.productCode
);
}
});
this.extractErrors(errors);
this.extractWarnings(errors);
if (!errors.length) {
this.showAddedToCartSuccessMessage();
} else {
this.extractSuccesses(errors, entries);
}
});
}
clearErrors(): void {
this.cartErrors$.next([]);
}
clearWarnings(): void {
this.cartWarnings$.next([]);
}
clearSuccesses(): void {
this.cartSuccesses$.next([]);
}
clearAddToCartInformation(): void {
this.showAddToCartInformation$.next(false);
}
undoDeletion(entry: OrderEntry): void {
if (entry.product?.code) {
this.quickOrderService.restoreSoftDeletedEntry(entry.product.code);
}
}
clearDeletion(entry: OrderEntry): void {
if (entry.product?.code) {
this.quickOrderService.hardDeleteEntry(entry.product.code);
}
}
clearNonPurchasableError(): void {
this.quickOrderService.clearNonPurchasableProductError();
}
canAddProduct(): Observable<boolean> {
return this.quickOrderService.canAdd();
}
protected extractErrors(errors: QuickOrderAddEntryEvent[]): void {
const noAddedEntries = errors.filter((error) => error.quantityAdded === 0);
this.setErrors(noAddedEntries);
}
protected extractWarnings(errors: QuickOrderAddEntryEvent[]): void {
const warnings = errors.filter((error) => error.quantityAdded !== 0);
this.setWarnings(warnings);
}
protected extractSuccesses(
errors: QuickOrderAddEntryEvent[],
entries: OrderEntry[]
): void {
const successAddedEntries: OrderEntry[] = [];
entries.forEach((entry) => {
const element = errors.find(
(error) => error.productCode === entry.product?.code
);
if (!element) {
successAddedEntries.push(entry);
}
});
this.setSuccesses(successAddedEntries);
}
protected clearStatuses(): void {
this.clearErrors();
this.clearWarnings();
this.clearSuccesses();
}
protected showAddedToCartSuccessMessage(): void {
this.globalMessageService.add(
{
key: 'quickOrderTable.addedtoCart',
},
GlobalMessageType.MSG_TYPE_CONFIRMATION
);
}
protected setErrors(errors: QuickOrderAddEntryEvent[]): void {
this.cartErrors$.next(errors);
}
protected setWarnings(warnings: QuickOrderAddEntryEvent[]): void {
this.cartWarnings$.next(warnings);
}
protected setSuccesses(entries: OrderEntry[]): void {
this.cartSuccesses$.next(entries);
}
}
<ng-container *ngIf="entries$ | async as entries">
<ng-container *ngIf="!(canAddProduct() | async)">
<ng-container *ngIf="quickOrderForm?.form?.get('product')?.dirty">
<cx-message
[text]="
'quickOrderList.errors.listIsFull'
| cxTranslate: { count: entries.length }
"
[isVisibleCloseButton]="false"
[type]="globalMessageType.MSG_TYPE_ERROR"
class="quick-order-list-limit-message"
>
</cx-message>
</ng-container>
</ng-container>
</ng-container>
<ng-container *ngIf="addToCartInformation$ | async">
<cx-message
(closeMessage)="clearAddToCartInformation()"
[text]="
'quickOrderList.informations.addProductBeforeAddingToCart' | cxTranslate
"
[type]="globalMessageType.MSG_TYPE_ERROR"
class="quick-order-add-to-cart-information-message"
>
</cx-message>
</ng-container>
<ng-container *ngIf="nonPurchasableError$ | async as nonPurchasableError">
<cx-message
(closeMessage)="clearNonPurchasableError()"
[text]="
'quickOrderList.errors.nonPurchasableError'
| cxTranslate: { name: nonPurchasableError.name }
"
[type]="globalMessageType.MSG_TYPE_ERROR"
class="quick-order-non-purchasable-product-error-message"
>
</cx-message>
</ng-container>
<ng-container *ngIf="softDeletedEntries$ | async as deletedEntries">
<cx-message
*ngFor="let deletedEntry of deletedEntries | keyvalue"
(buttonAction)="undoDeletion(deletedEntry.value)"
(closeMessage)="clearDeletion(deletedEntry.value)"
[actionButtonText]="'quickOrderList.undo' | cxTranslate"
[text]="
'quickOrderList.productWasDeleted'
| cxTranslate: { name: deletedEntry.value.product?.name }
"
[type]="globalMessageType.MSG_TYPE_CONFIRMATION"
class="quick-order-deletions-message"
>
</cx-message>
</ng-container>
<ng-container *ngIf="errors$ | async as errors">
<cx-message
*ngIf="errors.length"
(closeMessage)="clearErrors()"
[accordionText]="'quickOrderList.errors.reviewErrors' | cxTranslate"
[text]="'quickOrderList.errorProceedingToCart' | cxTranslate"
[type]="globalMessageType.MSG_TYPE_ERROR"
class="quick-order-errors-message"
>
<ul class="quick-order-errors">
<li *ngFor="let error of errors" class="quick-order-error-item">
<span>
{{
'quickOrderList.errors.productIsOutOfStock'
| cxTranslate
: {
name: error.entry.product.name,
code: error.entry.product.code
}
}}
</span>
</li>
</ul>
</cx-message>
</ng-container>
<ng-container *ngIf="warnings$ | async as warnings">
<cx-message
*ngIf="warnings.length"
(closeMessage)="clearWarnings()"
[accordionText]="'quickOrderList.warnings.reviewWarnings' | cxTranslate"
[text]="'quickOrderList.warningProceedingToCart' | cxTranslate"
[type]="globalMessageType.MSG_TYPE_WARNING"
class="quick-order-warnings-message"
>
<ul class="quick-order-warnings">
<li *ngFor="let warning of warnings" class="quick-order-warning-item">
<span>
{{
'quickOrderList.warnings.productWasReduced'
| cxTranslate
: {
name: warning.entry.product.name,
code: warning.entry.product.code,
quantityAdded: warning.quantityAdded
}
}}
</span>
</li>
</ul>
</cx-message>
</ng-container>
<ng-container *ngIf="successes$ | async as successes">
<cx-message
*ngIf="successes.length"
(closeMessage)="clearSuccesses()"
[text]="'quickOrderList.successfullyAddedToCart' | cxTranslate"
[type]="globalMessageType.MSG_TYPE_CONFIRMATION"
class="quick-order-successes-message"
>
<ul class="quick-order-successes">
<li *ngFor="let entry of successes" class="quick-order-success-item">
<span>{{
'quickOrderList.successes.productAddedToCart'
| cxTranslate
: {
name: entry.product.name,
code: entry.product.code
}
}}</span>
</li>
</ul>
</cx-message>
</ng-container>
<ng-container *ngIf="quickOrderListLimit$ | async as quickOrderListLimit">
<ng-container *ngIf="entries$ | async as entries">
<div class="quick-order-header">
<h3>{{ 'quickOrderList.header' | cxTranslate }}</h3>
<p>
{{
'quickOrderList.subHeader'
| cxTranslate: { limit: quickOrderListLimit }
}}
</p>
</div>
<div class="quick-order-form-body">
<cx-quick-order-form #quickOrderForm> </cx-quick-order-form>
</div>
<div class="quick-order-table-body">
<cx-quick-order-table
[entries]="entries"
[loading]="!(isCartStable$ | async)"
></cx-quick-order-table>
</div>
<div class="quick-order-footer row">
<div class="col-xs-12 col-md-5 col-lg-4">
<button
*ngIf="entries.length"
(click)="clear()"
[attr.aria-label]="'quickOrderList.emptyList' | cxTranslate"
[disabled]="!(isCartStable$ | async)"
class="btn btn-block btn-action clear-button"
type="button"
>
{{ 'quickOrderList.emptyList' | cxTranslate }}
</button>
</div>
<div class="col-xs-12 col-md-5 col-lg-4">
<cx-progress-button
(clikEvent)="addToCart(entries)"
[ariaLabel]="'quickOrderList.addToCart' | cxTranslate"
[class]="'btn-block add-button'"
[loading]="!(isCartStable$ | async)"
>
{{ 'quickOrderList.addToCart' | cxTranslate }}
</cx-progress-button>
</div>
</div>
</ng-container>
</ng-container>