Press n or j to go to the next uncovered block, b, p or k for the previous block.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 | 7x 7x 7x 7x 7x 7x 9x 9x 9x 9x 9x 8x 8x 8x 8x 8x 8x 8x 3x 2x 2x 8x 8x 3x 1x 8x 8x 3x 3x 8x 8x 8x 8x 6x 1x 1x | import { ChangeDetectionStrategy, Component, DestroyRef, EventEmitter, OnInit, Output, inject } from '@angular/core'; import { takeUntilDestroyed } from '@angular/core/rxjs-interop'; import { uniq } from 'lodash-es'; import { Observable } from 'rxjs'; import { map, shareReplay } from 'rxjs/operators'; import { CheckoutFacade } from 'ish-core/facades/checkout.facade'; import { BasketFeedback } from 'ish-core/models/basket-feedback/basket-feedback.model'; import { BasketValidationResultType } from 'ish-core/models/basket-validation/basket-validation.model'; import { LineItemView } from 'ish-core/models/line-item/line-item.model'; import { PriceItem } from 'ish-core/models/price-item/price-item.model'; /** * Displays the basket validation result messages. In case of basket adjustments removed or undeliverable items are * * @example * <ish-basket-validation-results></ish-basket-validation-results> */ @Component({ selector: 'ish-basket-validation-results', templateUrl: './basket-validation-results.component.html', changeDetection: ChangeDetectionStrategy.Default, }) export class BasketValidationResultsComponent implements OnInit { private validationResults$: Observable<BasketValidationResultType>; hasGeneralBasketError$: Observable<boolean>; errorMessages$: Observable<string[]>; infoMessages$: Observable<string[]>; undeliverableItems$: Observable<LineItemView[]>; removedItems$: Observable<{ message: string; productSKU: string; price: PriceItem }[]>; scrollToMessage$: Observable<boolean>; private itemHasBeenRemoved = false; // default values to control scrolling behavior scrollSpacing = 64; private destroyRef = inject(DestroyRef); constructor(private checkoutFacade: CheckoutFacade) {} @Output() continueCheckout = new EventEmitter<void>(); ngOnInit() { // update emitted to display spinning animation this.validationResults$ = this.checkoutFacade.basketValidationResults$.pipe(shareReplay(1)); this.validationResults$.pipe(takeUntilDestroyed(this.destroyRef)).subscribe(() => { Iif (this.itemHasBeenRemoved) { this.continueCheckout.emit(); this.itemHasBeenRemoved = false; } }); this.hasGeneralBasketError$ = this.validationResults$.pipe( map(results => results?.errors?.some(error => this.isLineItemMessage(error))) ); this.errorMessages$ = this.validationResults$.pipe( map(results => uniq( results?.errors ?.filter( error => !this.isLineItemMessage(error) && ![ 'basket.validation.line_item_shipping_restrictions.error', 'basket.validation.basket_not_covered.error', ].includes(error.code) ) .map(error => error.parameters?.shippingRestriction ? error.parameters.shippingRestriction : error.message ) ).filter(message => !!message) ) ); this.undeliverableItems$ = this.validationResults$.pipe( map(results => results?.errors ?.filter(error => error.code === 'basket.validation.line_item_shipping_restrictions.error' && error.lineItem) .map(error => ({ ...error.lineItem })) ) ); this.removedItems$ = this.validationResults$.pipe( map(results => results?.infos ?.map(info => ({ message: info.message, productSKU: info.parameters?.productSku, price: info.lineItem?.price, })) .filter(info => !!info.productSKU) ) ); this.infoMessages$ = this.validationResults$.pipe( map(results => uniq(results?.infos?.map(info => info.message)).filter(message => !!message)) ); this.scrollToMessage$ = this.validationResults$.pipe( map(results => !!(results?.errors?.length || results?.infos?.length)) ); } private isLineItemMessage(error: BasketFeedback): boolean { return !!( error.parameters && error.code !== 'basket.validation.line_item_shipping_restrictions.error' && error.parameters.scopes && (error.parameters.scopes.includes('Addresses') || error.parameters.scopes.includes('Products')) && error.parameters.lineItemId ); } deleteItem(itemId: string) { this.checkoutFacade.deleteBasketItem(itemId); this.itemHasBeenRemoved = true; } } |