Files
ISA-Frontend/apps/isa-app/src/shared/shell/process-bar/process-bar.component.ts
2025-09-17 13:56:35 +00:00

223 lines
6.6 KiB
TypeScript

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<ApplicationProcess[]> = NEVER;
showStartProcessText$: Observable<boolean> = 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;
}
}