mirror of
https://dev.azure.com/hugendubel/ISA/_git/ISA-Frontend
synced 2025-12-28 22:42:11 +01:00
Breadcrumb fue abholfach
This commit is contained in:
@@ -1,8 +1,7 @@
|
||||
import { Injectable, inject } from '@angular/core';
|
||||
import { AbholfachService, ListResponseArgsOfDBHOrderItemListItemDTO, OrderItemProcessingStatusValue, QueryTokenDTO } from '@swagger/oms';
|
||||
import { AbholfachService, ListResponseArgsOfDBHOrderItemListItemDTO, QueryTokenDTO } from '@swagger/oms';
|
||||
import { PickupShelfIOService } from './pickup-shelf-io.service';
|
||||
import { Observable, throwError } from 'rxjs';
|
||||
import { map } from 'rxjs/operators';
|
||||
|
||||
@Injectable({ providedIn: 'root' })
|
||||
export class PickupShelfOutService extends PickupShelfIOService {
|
||||
@@ -20,15 +19,12 @@ export class PickupShelfOutService extends PickupShelfIOService {
|
||||
orderNumber?: string;
|
||||
compartmentCode?: string;
|
||||
}): Observable<ListResponseArgsOfDBHOrderItemListItemDTO> {
|
||||
console.log('args', args);
|
||||
if (!args.orderNumber && !args.compartmentCode) {
|
||||
return throwError(
|
||||
'PickupShelfOutService.getOrderItemsByOrderNumberOrCompartmentCode(): Either orderNumber or compartmentCode must be provided.'
|
||||
);
|
||||
}
|
||||
|
||||
console.log('args', args);
|
||||
|
||||
return this._abholfachService.AbholfachWarenausgabe({
|
||||
input: {
|
||||
qs: args.compartmentCode ?? args.orderNumber,
|
||||
|
||||
@@ -1,21 +1,24 @@
|
||||
import { DestroyRef, inject } from '@angular/core';
|
||||
import { PickupShelfStore } from './store';
|
||||
import { ActivatedRoute, ActivatedRouteSnapshot, NavigationEnd, Router } from '@angular/router';
|
||||
import { DestroyRef, Directive, OnInit, inject } from '@angular/core';
|
||||
import { PickupShelfDetailsStore, PickupShelfStore } from './store';
|
||||
import { ActivatedRoute, Router } from '@angular/router';
|
||||
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
|
||||
import { log, logAsync } from '@utils/common';
|
||||
import { Breadcrumb, BreadcrumbService } from '@core/breadcrumb';
|
||||
import { take } from 'rxjs/operators';
|
||||
import { switchMap, take, tap, withLatestFrom } from 'rxjs/operators';
|
||||
import { NavigationRoute } from '@shared/services';
|
||||
import { DBHOrderItemListItemDTO } from '@swagger/oms';
|
||||
import { DBHOrderItemListItemDTO, OrderItemProcessingStatusValue } from '@swagger/oms';
|
||||
import { isEmpty } from 'lodash';
|
||||
import { Observable, combineLatest, concat } from 'rxjs';
|
||||
|
||||
/**
|
||||
* Enthält die gemeinsame Logik für die Suche und verbindet die Komponenten mit dem Store.
|
||||
*/
|
||||
export abstract class PickupShelfBaseComponent {
|
||||
@Directive()
|
||||
export abstract class PickupShelfBaseComponent implements OnInit {
|
||||
protected destroyRef = inject(DestroyRef);
|
||||
|
||||
protected store = inject(PickupShelfStore);
|
||||
protected listStore = inject(PickupShelfStore);
|
||||
|
||||
protected detailsStore = inject(PickupShelfDetailsStore);
|
||||
|
||||
protected router = inject(Router);
|
||||
|
||||
@@ -23,92 +26,70 @@ export abstract class PickupShelfBaseComponent {
|
||||
|
||||
protected breadcrumbService = inject(BreadcrumbService);
|
||||
|
||||
constructor() {
|
||||
/**
|
||||
* Wenn die Suche erfolgreich war, wird der Benutzer auf die Liste oder Detailseite des gefundenen Artikels weitergeleitet.
|
||||
*/
|
||||
this.store.fetchListResponse$.pipe(takeUntilDestroyed(this.destroyRef)).subscribe(async (response) => {
|
||||
ngOnInit() {
|
||||
this.regsiterFetchListResponseHandler();
|
||||
this.regsiterProcessIdHandler();
|
||||
this.registerQueryParamsHandler();
|
||||
this.registerViewHandler();
|
||||
}
|
||||
|
||||
regsiterFetchListResponseHandler() {
|
||||
this.listStore.fetchListResponse$.pipe(takeUntilDestroyed(this.destroyRef)).subscribe(async (response) => {
|
||||
/**
|
||||
* Wenn die Suche erfolgreich war, wird der Benutzer auf die Liste oder Detailseite des gefundenen Artikels weitergeleitet.
|
||||
*/
|
||||
const queryParams = this.activatedRoute.snapshot.queryParams;
|
||||
const filterQueryParams = this.store.filter.getQueryParams();
|
||||
const filterQueryParams = this.listStore.filter.getQueryParams();
|
||||
if (response.hits === 1) {
|
||||
const detailsPath = await this.getPathForDetail(response.result[0]);
|
||||
const detailsPath = await this.getPathForDetail(response.result[0]).pipe(take(1)).toPromise();
|
||||
await this.router.navigate(detailsPath.path, { queryParams: { ...queryParams, ...filterQueryParams, ...detailsPath.queryParams } });
|
||||
} else if (response.hits > 1) {
|
||||
const listPath = await this.getPathFoList();
|
||||
const listPath = await this.getPathFoListBreadcrumb().pipe(take(1)).toPromise();
|
||||
await this.router.navigate(listPath.path, { queryParams: { ...queryParams, ...filterQueryParams, ...listPath.queryParams } });
|
||||
} else {
|
||||
// TODO: Fehlermeldung in Suchbox
|
||||
await this.router.navigate([], { queryParams: { ...queryParams, ...filterQueryParams } });
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Checkt ob sich die ProzessId in der URL geändert hat und aktualisiert den Store.
|
||||
* Zusätzlich wird die Breadcrumb aktualisiert.
|
||||
*/
|
||||
this.router.events.pipe(takeUntilDestroyed(this.destroyRef)).subscribe((event) => {
|
||||
if (event instanceof NavigationEnd) {
|
||||
this.runCheck();
|
||||
regsiterProcessIdHandler() {
|
||||
this.activatedRoute.params.pipe(takeUntilDestroyed(this.destroyRef)).subscribe((params) => {
|
||||
const processIdStr = params.processId;
|
||||
|
||||
if (!processIdStr) {
|
||||
return;
|
||||
}
|
||||
|
||||
const processId = Number(processIdStr);
|
||||
|
||||
this.listStore.setProcessId(processId);
|
||||
});
|
||||
}
|
||||
|
||||
registerQueryParamsHandler() {
|
||||
this.activatedRoute.queryParams.pipe(takeUntilDestroyed(this.destroyRef)).subscribe((queryParams) => {
|
||||
if (isEmpty(queryParams)) {
|
||||
this.listStore.setQueryParams(undefined);
|
||||
} else {
|
||||
this.listStore.setQueryParams(queryParams);
|
||||
}
|
||||
});
|
||||
|
||||
this.runCheck(true);
|
||||
}
|
||||
|
||||
protected async runCheck(firstCheck: boolean = false) {
|
||||
this._checkAndUpdateProcessIdInStore();
|
||||
this._checkAndUpdateQueryParamsInStore();
|
||||
const crumb = await this._checkAndUpdateBreadcrumb();
|
||||
|
||||
if (firstCheck && ['list', 'filter'].includes(crumb)) {
|
||||
this.store.fetchList();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Aktualiisiert die ProzessId im Store.
|
||||
* @returns void
|
||||
*/
|
||||
@log
|
||||
private _checkAndUpdateProcessIdInStore() {
|
||||
const processIdStr = this.activatedRoute.snapshot.params.processId;
|
||||
|
||||
if (!processIdStr) {
|
||||
return;
|
||||
}
|
||||
|
||||
const processId = Number(processIdStr);
|
||||
|
||||
this.store.setProcessId(processId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Update die QueryParams im Store.
|
||||
* @returns void
|
||||
*/
|
||||
@log
|
||||
private _checkAndUpdateQueryParamsInStore() {
|
||||
const queryParams = this.activatedRoute.snapshot.queryParams;
|
||||
|
||||
if (isEmpty(queryParams)) {
|
||||
this.store.setQueryParams(undefined);
|
||||
} else {
|
||||
this.store.setQueryParams(queryParams);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Aktualisiert die Breadcrumb.
|
||||
*/
|
||||
@logAsync
|
||||
private async _checkAndUpdateBreadcrumb() {
|
||||
const breadcrumb = this.findDataInActivatedRouteSnapshot(this.activatedRoute.snapshot, 'breadcrumb', 2);
|
||||
|
||||
await this._checkAndUpdateMainBreadcrumb(breadcrumb);
|
||||
await this._checkAndUpdateListBreadcrumb(breadcrumb);
|
||||
await this._checkAndUpdateFilterBreadcrumb(breadcrumb);
|
||||
|
||||
return breadcrumb;
|
||||
registerViewHandler() {
|
||||
this.activatedRoute.data
|
||||
.pipe(
|
||||
takeUntilDestroyed(this.destroyRef),
|
||||
switchMap(({ view }) =>
|
||||
this._checkAndUpdateMainBreadcrumb(view).pipe(
|
||||
switchMap(() => this._checkAndUpdateListBreadcrumb(view)),
|
||||
switchMap(() => this._checkAndUpdateFilterBreadcrumb(view)),
|
||||
switchMap(() => this._checkAndUpdateDetailBreadcrumb(view))
|
||||
)
|
||||
)
|
||||
)
|
||||
.subscribe();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -116,152 +97,171 @@ export abstract class PickupShelfBaseComponent {
|
||||
* @param tag Der gesuchte Tag
|
||||
* @returns Breadcumb
|
||||
*/
|
||||
@logAsync
|
||||
private async _getBreadcrumbByTag(tag: string) {
|
||||
const breadcrumbs = await this.breadcrumbService
|
||||
.getBreadcrumbsByKeyAndTags$(this.store.processId, ['pickup-shelf', tag])
|
||||
.pipe(takeUntilDestroyed(this.destroyRef), take(1))
|
||||
.toPromise();
|
||||
return breadcrumbs[0];
|
||||
private _getBreadcrumbByTag(tag: string) {
|
||||
return this.breadcrumbService
|
||||
.getBreadcrumbsByKeyAndTags$(this.listStore.processId, ['pickup-shelf', tag])
|
||||
.pipe(takeUntilDestroyed(this.destroyRef), take(1));
|
||||
}
|
||||
|
||||
/**
|
||||
* Update die Main Breadcrumb.
|
||||
* @param breadcrumb Der Aktuelle Breadcrumb Tag
|
||||
*/
|
||||
@logAsync
|
||||
private async _checkAndUpdateMainBreadcrumb(breadcrumb: string) {
|
||||
let mainBreadcrumb: Breadcrumb = await this._getBreadcrumbByTag('main');
|
||||
abstract getNameForMainBreadcrumb(): Observable<string>;
|
||||
|
||||
if (!mainBreadcrumb) {
|
||||
const name = await this.getNameForMainBreadcrumb();
|
||||
const path = await this.getPathForMain();
|
||||
mainBreadcrumb = {
|
||||
key: this.store.processId,
|
||||
name,
|
||||
tags: ['pickup-shelf', 'main'],
|
||||
path: path?.path,
|
||||
section: 'customer',
|
||||
params: { ...path?.queryParams, ...this.activatedRoute.snapshot.queryParams },
|
||||
};
|
||||
this.breadcrumbService.addBreadcrumb(mainBreadcrumb);
|
||||
} else {
|
||||
const name = await this.getNameForMainBreadcrumb();
|
||||
const path = await this.getPathForMain();
|
||||
const changes: Partial<Breadcrumb> = {
|
||||
name,
|
||||
path: path?.path,
|
||||
params: { ...path?.queryParams, ...this.activatedRoute.snapshot.queryParams },
|
||||
};
|
||||
this.breadcrumbService.patchBreadcrumb(mainBreadcrumb.id, changes);
|
||||
}
|
||||
}
|
||||
abstract getPathForMainBreadcrumb(): Observable<NavigationRoute>;
|
||||
|
||||
abstract getNameForMainBreadcrumb(): Promise<string>;
|
||||
private _checkAndUpdateMainBreadcrumb(view: string) {
|
||||
return combineLatest([this.getNameForMainBreadcrumb(), this.getPathForMainBreadcrumb()]).pipe(
|
||||
withLatestFrom(this._getBreadcrumbByTag('main')),
|
||||
tap(([[name, path], breadcrumbs]) => {
|
||||
let mainBreadcrumb: Breadcrumb = breadcrumbs.pop();
|
||||
|
||||
abstract getPathForMain(): Promise<NavigationRoute>;
|
||||
|
||||
/**
|
||||
* Update die List Breadcrumb.
|
||||
* @param breadcrumb Der Aktuelle Breadcrumb Tag
|
||||
*/
|
||||
@logAsync
|
||||
private async _checkAndUpdateListBreadcrumb(breadcrumb: string) {
|
||||
let listBreadcrumb: Breadcrumb = await this._getBreadcrumbByTag('list');
|
||||
|
||||
const shouldHaveBreadcrumb = ['list', 'filter'].includes(breadcrumb);
|
||||
|
||||
if (shouldHaveBreadcrumb && !listBreadcrumb) {
|
||||
const name = await this.getNameForListBreadcrumb();
|
||||
const path = await this.getPathFoList();
|
||||
listBreadcrumb = {
|
||||
key: this.store.processId,
|
||||
name,
|
||||
tags: ['pickup-shelf', 'list'],
|
||||
path: path?.path,
|
||||
section: 'customer',
|
||||
params: { ...path?.queryParams, ...this.activatedRoute.snapshot.queryParams },
|
||||
};
|
||||
this.breadcrumbService.addBreadcrumb(listBreadcrumb);
|
||||
} else if (shouldHaveBreadcrumb && listBreadcrumb) {
|
||||
const name = await this.getNameForListBreadcrumb();
|
||||
const path = await this.getPathFoList();
|
||||
const changes: Partial<Breadcrumb> = {
|
||||
name,
|
||||
path: path?.path,
|
||||
params: { ...path?.queryParams, ...this.activatedRoute.snapshot.queryParams },
|
||||
};
|
||||
this.breadcrumbService.patchBreadcrumb(listBreadcrumb.id, changes);
|
||||
} else if (!shouldHaveBreadcrumb && listBreadcrumb) {
|
||||
this.breadcrumbService.removeBreadcrumb(listBreadcrumb.id);
|
||||
}
|
||||
}
|
||||
|
||||
abstract getNameForListBreadcrumb(): Promise<string>;
|
||||
|
||||
abstract getPathFoList(): Promise<NavigationRoute>;
|
||||
|
||||
/**
|
||||
* Update die Filter Breadcrumb.
|
||||
* @param breadcrumb Der Aktuelle Breadcrumb Tag
|
||||
*/
|
||||
@logAsync
|
||||
private async _checkAndUpdateFilterBreadcrumb(breadcrumb: string) {
|
||||
let filterBreadcrumb: Breadcrumb = await this._getBreadcrumbByTag('filter');
|
||||
|
||||
const shouldHaveBreadcrumb = ['filter'].includes(breadcrumb);
|
||||
|
||||
if (shouldHaveBreadcrumb && !filterBreadcrumb) {
|
||||
const name = await this.getNameForFilterBreadcrumb();
|
||||
const path = await this.getPathForFilter();
|
||||
filterBreadcrumb = {
|
||||
key: this.store.processId,
|
||||
name,
|
||||
tags: ['pickup-shelf', 'filter'],
|
||||
path: path?.path,
|
||||
section: 'customer',
|
||||
params: { ...path?.queryParams, ...this.activatedRoute.snapshot.queryParams },
|
||||
};
|
||||
this.breadcrumbService.addBreadcrumb(filterBreadcrumb);
|
||||
} else if (shouldHaveBreadcrumb && filterBreadcrumb) {
|
||||
const name = await this.getNameForFilterBreadcrumb();
|
||||
const path = await this.getPathForFilter();
|
||||
const changes: Partial<Breadcrumb> = {
|
||||
name,
|
||||
path: path?.path,
|
||||
params: { ...path?.queryParams, ...this.activatedRoute.snapshot.queryParams },
|
||||
};
|
||||
this.breadcrumbService.patchBreadcrumb(filterBreadcrumb.id, changes);
|
||||
} else if (!shouldHaveBreadcrumb && filterBreadcrumb) {
|
||||
this.breadcrumbService.removeBreadcrumb(filterBreadcrumb.id);
|
||||
}
|
||||
}
|
||||
|
||||
abstract getNameForFilterBreadcrumb(): Promise<string>;
|
||||
|
||||
abstract getPathForFilter(): Promise<NavigationRoute>;
|
||||
|
||||
@log
|
||||
// TODO: Ort für auslagerung finden
|
||||
findDataInActivatedRouteSnapshot(snapshot: ActivatedRouteSnapshot, data: string, depth: number) {
|
||||
if (!snapshot) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (snapshot.data[data]) {
|
||||
return snapshot.data[data];
|
||||
}
|
||||
|
||||
if (depth > 0) {
|
||||
const children = snapshot.children;
|
||||
for (const child of children) {
|
||||
const result = this.findDataInActivatedRouteSnapshot(child, data, depth - 1);
|
||||
if (result) {
|
||||
return result;
|
||||
if (!mainBreadcrumb) {
|
||||
mainBreadcrumb = {
|
||||
key: this.listStore.processId,
|
||||
name,
|
||||
tags: ['pickup-shelf', 'main'],
|
||||
path: path?.path,
|
||||
section: 'customer',
|
||||
params: { ...path?.queryParams, ...this.activatedRoute.snapshot.queryParams },
|
||||
};
|
||||
this.breadcrumbService.addBreadcrumb(mainBreadcrumb);
|
||||
} else {
|
||||
const changes: Partial<Breadcrumb> = {
|
||||
name,
|
||||
path: path?.path,
|
||||
params: { ...path?.queryParams, ...this.activatedRoute.snapshot.queryParams },
|
||||
};
|
||||
this.breadcrumbService.patchBreadcrumb(mainBreadcrumb.id, changes);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// remove excess breadcrumbs
|
||||
breadcrumbs.forEach((breadcrumb) => {
|
||||
this.breadcrumbService.removeBreadcrumb(breadcrumb.id);
|
||||
});
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
abstract getPathForDetail(item: DBHOrderItemListItemDTO): Promise<NavigationRoute>;
|
||||
abstract getNameForListBreadcrumb(): Observable<string>;
|
||||
|
||||
abstract getPathFoListBreadcrumb(): Observable<NavigationRoute>;
|
||||
|
||||
private _checkAndUpdateListBreadcrumb(view: string) {
|
||||
return combineLatest([this.getNameForListBreadcrumb(), this.getPathFoListBreadcrumb()]).pipe(
|
||||
withLatestFrom(this._getBreadcrumbByTag('list')),
|
||||
tap(([[name, path], breadcrumbs]) => {
|
||||
let listBreadcrumb: Breadcrumb = breadcrumbs.pop();
|
||||
|
||||
const shouldHaveBreadcrumb = ['list', 'filter', 'details'].includes(view);
|
||||
|
||||
if (shouldHaveBreadcrumb && !listBreadcrumb) {
|
||||
listBreadcrumb = {
|
||||
key: this.listStore.processId,
|
||||
name,
|
||||
tags: ['pickup-shelf', 'list'],
|
||||
path: path?.path,
|
||||
section: 'customer',
|
||||
params: { ...path?.queryParams, ...this.activatedRoute.snapshot.queryParams },
|
||||
};
|
||||
this.breadcrumbService.addBreadcrumb(listBreadcrumb);
|
||||
} else if (shouldHaveBreadcrumb && listBreadcrumb) {
|
||||
const changes: Partial<Breadcrumb> = {
|
||||
name,
|
||||
path: path?.path,
|
||||
params: { ...path?.queryParams, ...this.activatedRoute.snapshot.queryParams },
|
||||
};
|
||||
this.breadcrumbService.patchBreadcrumb(listBreadcrumb.id, changes);
|
||||
} else if (!shouldHaveBreadcrumb && listBreadcrumb) {
|
||||
this.breadcrumbService.removeBreadcrumb(listBreadcrumb.id);
|
||||
}
|
||||
|
||||
// remove excess breadcrumbs
|
||||
breadcrumbs.forEach((breadcrumb) => {
|
||||
this.breadcrumbService.removeBreadcrumb(breadcrumb.id);
|
||||
});
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
abstract getNameForFilterBreadcrumb(): Observable<string>;
|
||||
|
||||
abstract getPathForFilter(): Observable<NavigationRoute>;
|
||||
|
||||
private _checkAndUpdateFilterBreadcrumb(view: string) {
|
||||
return combineLatest([this.getNameForFilterBreadcrumb(), this.getPathForFilter()]).pipe(
|
||||
withLatestFrom(this._getBreadcrumbByTag('filter')),
|
||||
tap(([[name, path], breadcrumbs]) => {
|
||||
let filterBreadcrumb: Breadcrumb = breadcrumbs.pop();
|
||||
|
||||
const shouldHaveBreadcrumb = ['filter'].includes(view);
|
||||
|
||||
if (shouldHaveBreadcrumb && !filterBreadcrumb) {
|
||||
filterBreadcrumb = {
|
||||
key: this.listStore.processId,
|
||||
name,
|
||||
tags: ['pickup-shelf', 'filter'],
|
||||
path: path?.path,
|
||||
section: 'customer',
|
||||
params: { ...path?.queryParams, ...this.activatedRoute.snapshot.queryParams },
|
||||
};
|
||||
this.breadcrumbService.addBreadcrumb(filterBreadcrumb);
|
||||
} else if (shouldHaveBreadcrumb && filterBreadcrumb) {
|
||||
const changes: Partial<Breadcrumb> = {
|
||||
name,
|
||||
path: path?.path,
|
||||
params: { ...path?.queryParams, ...this.activatedRoute.snapshot.queryParams },
|
||||
};
|
||||
this.breadcrumbService.patchBreadcrumb(filterBreadcrumb.id, changes);
|
||||
} else if (!shouldHaveBreadcrumb && filterBreadcrumb) {
|
||||
this.breadcrumbService.removeBreadcrumb(filterBreadcrumb.id);
|
||||
}
|
||||
|
||||
// remove excess breadcrumbs
|
||||
breadcrumbs.forEach((breadcrumb) => {
|
||||
this.breadcrumbService.removeBreadcrumb(breadcrumb.id);
|
||||
});
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
abstract getNameForDetailBreadcrumb(): Observable<string>;
|
||||
|
||||
abstract getPathForDetail(item: DBHOrderItemListItemDTO): Observable<NavigationRoute>;
|
||||
|
||||
abstract getPathForDetailForDetailBreadcrumb(): Observable<NavigationRoute>;
|
||||
|
||||
private _checkAndUpdateDetailBreadcrumb(view: string) {
|
||||
return combineLatest([this.getNameForDetailBreadcrumb(), this.getPathForDetailForDetailBreadcrumb()]).pipe(
|
||||
withLatestFrom(this._getBreadcrumbByTag('details')),
|
||||
tap(([[name, path], breadcrumbs]) => {
|
||||
let filterBreadcrumb: Breadcrumb = breadcrumbs.pop();
|
||||
|
||||
const shouldHaveBreadcrumb = ['details'].includes(view);
|
||||
|
||||
if (shouldHaveBreadcrumb && !filterBreadcrumb) {
|
||||
filterBreadcrumb = {
|
||||
key: this.listStore.processId,
|
||||
name,
|
||||
tags: ['pickup-shelf', 'details'],
|
||||
path: path?.path,
|
||||
section: 'customer',
|
||||
params: { ...path?.queryParams, ...this.activatedRoute.snapshot.queryParams },
|
||||
};
|
||||
this.breadcrumbService.addBreadcrumb(filterBreadcrumb);
|
||||
} else if (shouldHaveBreadcrumb && filterBreadcrumb) {
|
||||
const changes: Partial<Breadcrumb> = {
|
||||
name,
|
||||
path: path?.path,
|
||||
params: { ...path?.queryParams, ...this.activatedRoute.snapshot.queryParams },
|
||||
};
|
||||
this.breadcrumbService.patchBreadcrumb(filterBreadcrumb.id, changes);
|
||||
} else if (!shouldHaveBreadcrumb && filterBreadcrumb) {
|
||||
this.breadcrumbService.removeBreadcrumb(filterBreadcrumb.id);
|
||||
}
|
||||
|
||||
// remove excess breadcrumbs
|
||||
breadcrumbs.forEach((breadcrumb) => {
|
||||
this.breadcrumbService.removeBreadcrumb(breadcrumb.id);
|
||||
});
|
||||
})
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,6 +7,7 @@ import { PickupShelfIOService, PickupShelfService } from '@domain/pickup-shelf';
|
||||
import { PickupShelfBaseComponent } from '../pickup-shelf-base.component';
|
||||
import { NavigationRoute, PickupShelfInNavigationService } from '@shared/services';
|
||||
import { DBHOrderItemListItemDTO } from '@swagger/oms';
|
||||
import { Observable, of } from 'rxjs';
|
||||
|
||||
@Component({
|
||||
selector: 'page-pickup-shelf-in',
|
||||
@@ -21,29 +22,37 @@ import { DBHOrderItemListItemDTO } from '@swagger/oms';
|
||||
export class PickupShelfInComponent extends PickupShelfBaseComponent {
|
||||
private _pickupShelfInNavigationService = inject(PickupShelfInNavigationService);
|
||||
|
||||
async getPathForMain(): Promise<NavigationRoute> {
|
||||
return this._pickupShelfInNavigationService.defaultRoute();
|
||||
getPathForMainBreadcrumb(): Observable<NavigationRoute> {
|
||||
return of(this._pickupShelfInNavigationService.defaultRoute());
|
||||
}
|
||||
async getNameForMainBreadcrumb(): Promise<string> {
|
||||
return 'Wareneingang';
|
||||
getNameForMainBreadcrumb(): Observable<string> {
|
||||
return of('Wareneingang');
|
||||
}
|
||||
|
||||
async getNameForListBreadcrumb(): Promise<string> {
|
||||
return 'Liste';
|
||||
getNameForListBreadcrumb(): Observable<string> {
|
||||
return of('Liste');
|
||||
}
|
||||
|
||||
async getPathFoList(): Promise<NavigationRoute> {
|
||||
return this._pickupShelfInNavigationService.listRoute();
|
||||
getPathFoListBreadcrumb(): Observable<NavigationRoute> {
|
||||
return of(this._pickupShelfInNavigationService.listRoute());
|
||||
}
|
||||
|
||||
async getNameForFilterBreadcrumb(): Promise<string> {
|
||||
return 'Filter';
|
||||
getNameForFilterBreadcrumb(): Observable<string> {
|
||||
return of('Filter');
|
||||
}
|
||||
async getPathForFilter(): Promise<NavigationRoute> {
|
||||
return this._pickupShelfInNavigationService.filterRoute();
|
||||
getPathForFilter(): Observable<NavigationRoute> {
|
||||
return of(this._pickupShelfInNavigationService.filterRoute());
|
||||
}
|
||||
|
||||
async getPathForDetail(item: DBHOrderItemListItemDTO): Promise<NavigationRoute> {
|
||||
return this._pickupShelfInNavigationService.detailRoute({ item });
|
||||
getPathForDetail(item: DBHOrderItemListItemDTO): Observable<NavigationRoute> {
|
||||
return of(this._pickupShelfInNavigationService.detailRoute({ item }));
|
||||
}
|
||||
|
||||
getNameForDetailBreadcrumb(): Observable<string> {
|
||||
throw new Error('Method not implemented.');
|
||||
}
|
||||
|
||||
getPathForDetailForDetailBreadcrumb(): Observable<NavigationRoute> {
|
||||
throw new Error('Method not implemented.');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,2 +1,2 @@
|
||||
<shared-breadcrumb [key]="store.processId$ | async" [tags]="['pickup-shelf']"></shared-breadcrumb>
|
||||
<shared-breadcrumb [key]="listStore.processId$ | async" [tags]="['pickup-shelf']"></shared-breadcrumb>
|
||||
<shared-splitscreen></shared-splitscreen>
|
||||
|
||||
@@ -7,8 +7,9 @@ import { PickupShelfIOService, PickupShelfOutService } from '@domain/pickup-shel
|
||||
import { PickupShelfBaseComponent } from '../pickup-shelf-base.component';
|
||||
import { NavigationRoute, PickupShelfOutNavigationService } from '@shared/services';
|
||||
import { AsyncPipe } from '@angular/common';
|
||||
import { DBHOrderItemListItemDTO } from '@swagger/oms';
|
||||
import { logAsync } from '@utils/common';
|
||||
import { DBHOrderItemListItemDTO, OrderItemProcessingStatusValue } from '@swagger/oms';
|
||||
import { Observable, combineLatest, of } from 'rxjs';
|
||||
import { filter, map } from 'rxjs/operators';
|
||||
|
||||
@Component({
|
||||
selector: 'page-pickup-shelf-out',
|
||||
@@ -27,38 +28,83 @@ import { logAsync } from '@utils/common';
|
||||
export class PickupShelfOutComponent extends PickupShelfBaseComponent {
|
||||
private _pickupShelfOutNavigationService = inject(PickupShelfOutNavigationService);
|
||||
|
||||
@logAsync
|
||||
async getPathForMain(): Promise<NavigationRoute> {
|
||||
return this._pickupShelfOutNavigationService.defaultRoute({ processId: this.store.processId });
|
||||
constructor() {
|
||||
super();
|
||||
}
|
||||
|
||||
@logAsync
|
||||
async getNameForMainBreadcrumb(): Promise<string> {
|
||||
return 'Warenausgabe';
|
||||
getPathForMainBreadcrumb(): Observable<NavigationRoute> {
|
||||
return of(this._pickupShelfOutNavigationService.defaultRoute({ processId: this.listStore.processId }));
|
||||
}
|
||||
|
||||
@logAsync
|
||||
async getNameForListBreadcrumb(): Promise<string> {
|
||||
return 'Liste';
|
||||
getNameForMainBreadcrumb(): Observable<string> {
|
||||
return of('Warenausgabe');
|
||||
}
|
||||
|
||||
@logAsync
|
||||
async getPathFoList(): Promise<NavigationRoute> {
|
||||
return this._pickupShelfOutNavigationService.listRoute({ processId: this.store.processId });
|
||||
getNameForListBreadcrumb(): Observable<string> {
|
||||
return this.listStore.queryParams$.pipe(
|
||||
map((queryParams) => {
|
||||
if (queryParams?.main_qs) {
|
||||
return queryParams.main_qs;
|
||||
}
|
||||
|
||||
return 'Suche';
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
@logAsync
|
||||
async getNameForFilterBreadcrumb(): Promise<string> {
|
||||
return 'Filter';
|
||||
getPathFoListBreadcrumb(): Observable<NavigationRoute> {
|
||||
return of(this._pickupShelfOutNavigationService.listRoute({ processId: this.listStore.processId }));
|
||||
}
|
||||
|
||||
@logAsync
|
||||
async getPathForFilter(): Promise<NavigationRoute> {
|
||||
return this._pickupShelfOutNavigationService.filterRoute({ processId: this.store.processId });
|
||||
getNameForFilterBreadcrumb(): Observable<string> {
|
||||
return of('Filter');
|
||||
}
|
||||
|
||||
@logAsync
|
||||
async getPathForDetail(item: DBHOrderItemListItemDTO): Promise<NavigationRoute> {
|
||||
return this._pickupShelfOutNavigationService.detailRoute({ processId: this.store.processId, item });
|
||||
getPathForFilter(): Observable<NavigationRoute> {
|
||||
return of(this._pickupShelfOutNavigationService.filterRoute({ processId: this.listStore.processId }));
|
||||
}
|
||||
|
||||
getNameForDetailBreadcrumb(): Observable<string> {
|
||||
return combineLatest([this.detailsStore.order$, this.detailsStore.compartmentCode$]).pipe(
|
||||
filter(([order, compartmentCode]) => !!order || !!compartmentCode),
|
||||
map(([order, compartmentCode]) => {
|
||||
if (compartmentCode) {
|
||||
return compartmentCode;
|
||||
}
|
||||
|
||||
return order.orderNumber;
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
getPathForDetail(item: DBHOrderItemListItemDTO): Observable<NavigationRoute> {
|
||||
return of(
|
||||
this._pickupShelfOutNavigationService.detailRoute({
|
||||
processId: this.listStore.processId,
|
||||
item: {
|
||||
compartmentCode: item.compartmentCode,
|
||||
orderId: item.orderId,
|
||||
orderNumber: item.orderNumber,
|
||||
processingStatus: item.processingStatus,
|
||||
},
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
getPathForDetailForDetailBreadcrumb(): Observable<NavigationRoute> {
|
||||
return combineLatest([this.detailsStore.order$, this.detailsStore.compartmentCode$, this.detailsStore.processingStatus$]).pipe(
|
||||
filter(([order, compartmentCode, processingStatus]) => !!order && (!!compartmentCode || !!processingStatus)),
|
||||
map(([order, compartmentCode, processingStatus]) => {
|
||||
return this._pickupShelfOutNavigationService.detailRoute({
|
||||
processId: this.listStore.processId,
|
||||
item: {
|
||||
orderId: order.id,
|
||||
compartmentCode,
|
||||
orderNumber: order.orderNumber,
|
||||
processingStatus: processingStatus,
|
||||
},
|
||||
});
|
||||
})
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,21 +5,26 @@ import { PickupShelfOutMainComponent } from './pickup-shelf-out-main/pickup-shel
|
||||
import { PickupShelfOutListComponent } from './pickup-shelf-out-list/pickup-shelf-out-list.component';
|
||||
import { PickupShelfFilterComponent } from '../shared/pickup-shelf-filter/pickup-shelf-filter.component';
|
||||
import { PickupShelfOutDetailsComponent } from './pickup-shelf-out-details/pickup-shelf-out-details.component';
|
||||
import { viewResolver } from '../resolvers/view.resolver';
|
||||
|
||||
export const routes: Routes = [
|
||||
{
|
||||
path: '',
|
||||
component: PickupShelfOutComponent,
|
||||
resolve: {
|
||||
view: viewResolver,
|
||||
},
|
||||
runGuardsAndResolvers: 'always',
|
||||
children: [
|
||||
{ path: '', component: PickupShelfOutMainComponent, data: { breadcrumb: 'main' } },
|
||||
{ path: 'list', component: PickupShelfOutListComponent, data: { breadcrumb: 'list' } },
|
||||
{ path: 'list/filter', component: PickupShelfFilterComponent, data: { breadcrumb: 'filter' } },
|
||||
{ path: '', component: PickupShelfOutMainComponent, data: { view: 'main' } },
|
||||
{ path: 'list', component: PickupShelfOutListComponent, data: { view: 'list' } },
|
||||
{ path: 'list/filter', component: PickupShelfFilterComponent, data: { view: 'filter' } },
|
||||
{
|
||||
path: 'order/:orderId/:orderNumber/item/status/:orderItemProcessingStatus',
|
||||
component: PickupShelfOutDetailsComponent,
|
||||
data: { breadcrumb: 'details' },
|
||||
data: { view: 'details' },
|
||||
},
|
||||
{ path: 'order/:orderId/compartment/:compartmentCode', component: PickupShelfOutDetailsComponent, data: { breadcrumb: 'details' } },
|
||||
{ path: 'order/:orderId/compartment/:compartmentCode', component: PickupShelfOutDetailsComponent, data: { view: 'details' } },
|
||||
// { path: 'main', outlet: 'side' },
|
||||
// { path: 'list', outlet: 'side' },
|
||||
],
|
||||
|
||||
27
apps/page/pickup-shelf/src/lib/resolvers/view.resolver.ts
Normal file
27
apps/page/pickup-shelf/src/lib/resolvers/view.resolver.ts
Normal file
@@ -0,0 +1,27 @@
|
||||
import { ActivatedRouteSnapshot, ResolveFn } from '@angular/router';
|
||||
|
||||
function findDataInActivatedRouteSnapshot(snapshot: ActivatedRouteSnapshot, data: string, depth: number) {
|
||||
if (!snapshot) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (snapshot.data[data]) {
|
||||
return snapshot.data[data];
|
||||
}
|
||||
|
||||
if (depth > 0) {
|
||||
const children = snapshot.children;
|
||||
for (const child of children) {
|
||||
const result = findDataInActivatedRouteSnapshot(child, data, depth - 1);
|
||||
if (result) {
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export const viewResolver: ResolveFn<string> = (route: ActivatedRouteSnapshot) => {
|
||||
const result = findDataInActivatedRouteSnapshot(route, 'view', 2);
|
||||
console.log('viewResolver', result);
|
||||
return result;
|
||||
};
|
||||
@@ -1,4 +1,6 @@
|
||||
import { uniq } from 'lodash';
|
||||
import { PickupShelfDetailsState } from './pickup-shelf-details.state';
|
||||
import { DBHOrderItemListItemDTO } from '@swagger/oms';
|
||||
|
||||
export const selectOrder = (s: PickupShelfDetailsState) => s.order;
|
||||
|
||||
@@ -10,8 +12,25 @@ export const selectFetchingOrderItems = (s: PickupShelfDetailsState) => s.fetchi
|
||||
|
||||
export const selectSelectedOrderItemProcessingStatus = (s: PickupShelfDetailsState) => s.selectedOrderItemProcessingStatus;
|
||||
|
||||
export const selectOrderItemsWithSelectedOrderItemProcessingStatus = (s: PickupShelfDetailsState) =>
|
||||
s.orderItems?.filter((oi) => oi.processingStatus === s.selectedOrderItemProcessingStatus);
|
||||
export const selectSelectedCompartmentCode = (s: PickupShelfDetailsState) => s.selectedCompartmentCode;
|
||||
|
||||
export const selectOrderItems = (s: PickupShelfDetailsState): DBHOrderItemListItemDTO[] => {
|
||||
const compartmentCode = selectSelectedCompartmentCode(s);
|
||||
const items = selectOrderItemsRaw(s);
|
||||
|
||||
if (compartmentCode) {
|
||||
const compartmentInfo = selectCompartmentInfo(s);
|
||||
return items?.filter((oi) => oi.compartmentCode === compartmentCode && oi.compartmentInfo === compartmentInfo);
|
||||
}
|
||||
|
||||
const processingStatus = selectSelectedOrderItemProcessingStatus(s);
|
||||
|
||||
if (processingStatus) {
|
||||
return items?.filter((oi) => oi.processingStatus === processingStatus);
|
||||
}
|
||||
|
||||
return items;
|
||||
};
|
||||
|
||||
export const selectCustomer = (s: PickupShelfDetailsState) => s.customer;
|
||||
|
||||
@@ -30,5 +49,35 @@ export const selectEstimatedDeliveryDate = (s: PickupShelfDetailsState) => {
|
||||
};
|
||||
|
||||
export const selectCompartmentCode = (s: PickupShelfDetailsState) => {
|
||||
throw new Error('not implemented');
|
||||
const items = selectOrderItems(s);
|
||||
const compartmentCodes = uniq(items?.filter((oi) => oi.compartmentCode)?.map((oi) => oi.compartmentCode));
|
||||
|
||||
if (compartmentCodes.length > 1) {
|
||||
throw new Error('multiple compartments');
|
||||
}
|
||||
|
||||
return compartmentCodes[0];
|
||||
};
|
||||
|
||||
export const selectCompartmentInfo = (s: PickupShelfDetailsState) => {
|
||||
const items = selectOrderItems(s);
|
||||
const compartmentInfos = uniq(items?.filter((oi) => oi.compartmentInfo)?.map((oi) => oi.compartmentInfo));
|
||||
|
||||
if (compartmentInfos.length > 1) {
|
||||
throw new Error('multiple compartments');
|
||||
}
|
||||
|
||||
return compartmentInfos[0];
|
||||
};
|
||||
|
||||
export const selectCompartment = (s: PickupShelfDetailsState) => {
|
||||
const compartmentCode = selectCompartmentCode(s);
|
||||
|
||||
if (!compartmentCode) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
const compartmentInfo = selectCompartmentInfo(s);
|
||||
|
||||
return `${compartmentCode}_${compartmentInfo}`;
|
||||
};
|
||||
|
||||
@@ -9,6 +9,7 @@ export interface PickupShelfDetailsState {
|
||||
orderItems?: DBHOrderItemListItemDTO[];
|
||||
|
||||
selectedOrderItemProcessingStatus?: OrderItemProcessingStatusValue;
|
||||
selectedCompartmentCode?: string;
|
||||
|
||||
fetchingCustomer?: boolean;
|
||||
customer?: CustomerInfoDTO;
|
||||
|
||||
@@ -33,10 +33,10 @@ export class PickupShelfDetailsStore extends ComponentStore<PickupShelfDetailsSt
|
||||
return this.get(Selectors.selectFetchingOrder);
|
||||
}
|
||||
|
||||
orderItems$ = this.select(Selectors.selectOrderItemsWithSelectedOrderItemProcessingStatus);
|
||||
orderItems$ = this.select(Selectors.selectOrderItems);
|
||||
|
||||
get orderItems() {
|
||||
return this.get(Selectors.selectOrderItemsWithSelectedOrderItemProcessingStatus);
|
||||
return this.get(Selectors.selectOrderItems);
|
||||
}
|
||||
|
||||
fetchingOrderItems$ = this.select(Selectors.selectFetchingOrderItems);
|
||||
@@ -45,9 +45,9 @@ export class PickupShelfDetailsStore extends ComponentStore<PickupShelfDetailsSt
|
||||
return this.get(Selectors.selectFetchingOrderItems);
|
||||
}
|
||||
|
||||
selectedOrderItemProcessingStatus$ = this.select(Selectors.selectSelectedOrderItemProcessingStatus);
|
||||
processingStatus$ = this.select(Selectors.selectSelectedOrderItemProcessingStatus);
|
||||
|
||||
get selectedOrderItemProcessingStatus() {
|
||||
get processingStatus() {
|
||||
return this.get(Selectors.selectSelectedOrderItemProcessingStatus);
|
||||
}
|
||||
|
||||
@@ -63,6 +63,24 @@ export class PickupShelfDetailsStore extends ComponentStore<PickupShelfDetailsSt
|
||||
return this.get(Selectors.selectFetchingCustomer);
|
||||
}
|
||||
|
||||
compartmentCode$ = this.select(Selectors.selectCompartmentCode);
|
||||
|
||||
get compartmentCode() {
|
||||
return this.get(Selectors.selectCompartmentCode);
|
||||
}
|
||||
|
||||
compartmentInfo$ = this.select(Selectors.selectCompartmentInfo);
|
||||
|
||||
get compartmentInfo() {
|
||||
return this.get(Selectors.selectCompartmentInfo);
|
||||
}
|
||||
|
||||
compartment$ = this.select(Selectors.selectCompartment);
|
||||
|
||||
get compartment() {
|
||||
return this.get(Selectors.selectCompartment);
|
||||
}
|
||||
|
||||
constructor() {
|
||||
super({});
|
||||
|
||||
@@ -108,8 +126,8 @@ export class PickupShelfDetailsStore extends ComponentStore<PickupShelfDetailsSt
|
||||
)
|
||||
);
|
||||
|
||||
private beforeFetchOrderItems = () => {
|
||||
this.patchState({ fetchingOrderItems: true, orderItems: [] });
|
||||
private beforeFetchOrderItems = ({ compartmentCode }: { orderNumber?: string; compartmentCode?: string }) => {
|
||||
this.patchState({ fetchingOrderItems: true, orderItems: [], selectedCompartmentCode: compartmentCode });
|
||||
};
|
||||
|
||||
private fetchOrderItemsSuccess = (res: ListResponseArgsOfDBHOrderItemListItemDTO) => {
|
||||
|
||||
@@ -40,6 +40,12 @@ export class PickupShelfStore extends ComponentStore<PickupShelfState> implement
|
||||
|
||||
readonly list$ = this.select(Selectors.selectList);
|
||||
|
||||
readonly queryParams$ = this.select(Selectors.selectQueryParams);
|
||||
|
||||
get queryParams() {
|
||||
return this.get(Selectors.selectQueryParams);
|
||||
}
|
||||
|
||||
get list() {
|
||||
return this.get(Selectors.selectList);
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { Injectable, inject } from '@angular/core';
|
||||
import { NavigationRoute } from './navigation-route';
|
||||
import { Router } from '@angular/router';
|
||||
import { DBHOrderItemListItemDTO } from '@swagger/oms';
|
||||
import { DBHOrderItemListItemDTO, OrderItemProcessingStatusValue } from '@swagger/oms';
|
||||
|
||||
@Injectable({ providedIn: 'root' })
|
||||
export class PickupShelfOutNavigationService {
|
||||
@@ -49,7 +49,13 @@ export class PickupShelfOutNavigationService {
|
||||
};
|
||||
}
|
||||
|
||||
detailRoute({ processId, item }: { processId?: number; item: DBHOrderItemListItemDTO }): NavigationRoute {
|
||||
detailRoute({
|
||||
processId,
|
||||
item,
|
||||
}: {
|
||||
processId?: number;
|
||||
item: { orderId: number; orderNumber: string; compartmentCode: string; processingStatus: OrderItemProcessingStatusValue };
|
||||
}): NavigationRoute {
|
||||
let path: any[];
|
||||
|
||||
if (item.compartmentCode) {
|
||||
|
||||
Reference in New Issue
Block a user