import { coerceArray } from '@angular/cdk/coercion'; import { Component, ChangeDetectionStrategy, OnInit, ViewChild, ElementRef, } from '@angular/core'; import { Router } from '@angular/router'; import { ApplicationProcess, ApplicationService } from '@core/application'; import { BreadcrumbService } from '@core/breadcrumb'; import { DomainCheckoutService } from '@domain/checkout'; import { injectOpenMessageModal } from '@modal/message'; import { CustomerOrdersNavigationService, ProductCatalogNavigationService, } from '@shared/services/navigation'; import { NEVER, Observable, of } from 'rxjs'; import { delay, first, map, switchMap } from 'rxjs/operators'; @Component({ selector: 'shell-process-bar', templateUrl: 'process-bar.component.html', styleUrls: ['process-bar.component.css'], changeDetection: ChangeDetectionStrategy.OnPush, standalone: false, }) export class ShellProcessBarComponent implements OnInit { @ViewChild('processContainer') processContainer: ElementRef; section$: Observable<'customer' | 'branch'> = NEVER; processes$: Observable = NEVER; showStartProcessText$: Observable = NEVER; hovered: boolean; showScrollArrows: boolean; showArrowLeft: boolean; showArrowRight: boolean; trackByFn = (_: number, process: ApplicationProcess) => process.id; openMessageModal = injectOpenMessageModal(); constructor( private _app: ApplicationService, private _router: Router, private _catalogNavigationService: ProductCatalogNavigationService, private _customerOrderNavigationService: CustomerOrdersNavigationService, private _checkoutService: DomainCheckoutService, private _breadcrumb: BreadcrumbService, ) {} ngOnInit() { this.initSection$(); this.initProcesses$(); this.initShowStartProcessText$(); this.checkScrollArrowVisibility(); } initSection$() { this.section$ = of(undefined); } initProcesses$() { this.processes$ = this.section$.pipe( switchMap((section) => this._app.getProcesses$(section)), ); } initShowStartProcessText$() { this.showStartProcessText$ = this.processes$.pipe( map((processes) => processes.length === 0), ); } async createProcess(target = 'product') { // const process = await this.createCartProcess(); this.navigateTo(target, Date.now()); setTimeout(() => this.scrollToEnd(), 25); } static REGEX_PROCESS_NAME = /^Vorgang \d+$/; async createCartProcess() { return this._app.createCustomerProcess(); } async navigateTo(target: string, processId: number) { switch (target) { case 'product': await this._catalogNavigationService .getArticleSearchBasePath(processId) .navigate(); break; case 'customer': await this._router.navigate([ '/kunde', processId, 'customer', 'search', ]); break; case 'goods-out': await this._router.navigate(['/kunde', processId, 'goods', 'out']); break; case 'order': await this._customerOrderNavigationService .getCustomerOrdersBasePath(processId) .navigate(); break; default: await this._router.navigate(['/kunde', processId, target]); break; } } async closeAllProcesses() { const processes = await this.processes$.pipe(first()).toPromise(); this.openMessageModal({ title: 'Vorgänge schließen', message: `Sind Sie sich sicher, dass sie alle ${processes.length} Vorgänge schließen wollen?`, actions: [ { label: 'Abbrechen', value: false }, { label: 'leere Warenkörbe', value: true, action: () => this.handleCloseEmptyCartProcesses(), }, { label: 'Ja, alle', value: true, primary: true, action: () => this.handleCloseAllProcesses(), }, ], }); this.checkScrollArrowVisibility(); } async handleCloseEmptyCartProcesses() { let processes = await this.processes$.pipe(first()).toPromise(); for (const process of processes) { const cart = await this._checkoutService .getShoppingCart({ processId: process.id }) .pipe(first()) .toPromise(); if (cart?.items?.length === 0 || cart?.items === undefined) { this._app.removeProcess(process?.id); } processes = await this.processes$.pipe(delay(1), first()).toPromise(); if (processes.length === 0) { this._router.navigate(['/kunde', 'dashboard']); } else { const lastest = processes.reduce( (prev, current) => prev.activated > current.activated ? prev : current, processes[0], ); const crumb = await this._breadcrumb .getLastActivatedBreadcrumbByKey$(lastest.id) .pipe(first()) .toPromise(); if (crumb) { this._router.navigate(coerceArray(crumb.path), { queryParams: crumb.params, }); } else { this._router.navigate(['/kunde', lastest.id, 'product']); } } } } async handleCloseAllProcesses() { const processes = await this.processes$.pipe(first()).toPromise(); processes.forEach((process) => this._app.removeProcess(process?.id)); this._router.navigate(['/kunde', 'dashboard']); } onMouseWheel(event: any) { // Ermöglicht es, am Desktop die Prozessleiste mit dem Mausrad hoch/runter horizontal zu scrollen if (event.deltaY > 0) { this.processContainer.nativeElement.scrollLeft += 100; } else { this.processContainer.nativeElement.scrollLeft -= 100; } event.preventDefault(); } scrollLeft() { this.processContainer.nativeElement.scrollLeft -= 100; } scrollRight() { this.processContainer.nativeElement.scrollLeft += 100; } scrollToEnd() { this.processContainer.nativeElement.scrollLeft = this.processContainer?.nativeElement?.scrollWidth + this.processContainer?.nativeElement?.scrollLeft; } checkScrollArrowVisibility() { this.showScrollArrows = this.processContainer?.nativeElement?.scrollWidth > 0; this.showArrowRight = ((this.processContainer?.nativeElement?.scrollWidth - this.processContainer?.nativeElement?.scrollLeft) | 0) <= this.processContainer?.nativeElement?.offsetWidth; this.showArrowLeft = this.processContainer?.nativeElement?.scrollLeft <= 0; } }