mirror of
https://dev.azure.com/hugendubel/ISA/_git/ISA-Frontend
synced 2025-12-28 22:42:11 +01:00
261 lines
8.2 KiB
TypeScript
261 lines
8.2 KiB
TypeScript
import { Component, ChangeDetectionStrategy, OnInit, ViewChild, OnDestroy, AfterViewInit } from '@angular/core';
|
|
import { ActivatedRoute, Params, Router } from '@angular/router';
|
|
import { Breadcrumb, BreadcrumbService } from '@core/breadcrumb';
|
|
import { CacheService } from '@core/cache';
|
|
import { Config } from '@core/config';
|
|
import { provideComponentStore } from '@ngrx/component-store';
|
|
import { ArrivalStatus, ListResponseArgsOfPackageDTO2 } from '@swagger/wws';
|
|
import { UiFilter } from '@ui/filter';
|
|
import moment from 'moment';
|
|
import { combineLatest, Subject, Subscription } from 'rxjs';
|
|
import { filter, first, map } from 'rxjs/operators';
|
|
import { PackageResultCacheData } from './package-result-cache-data';
|
|
import { PackageResultComponentStore } from './package-result.component.store';
|
|
import { SharedFilterOverlayComponent } from '@shared/components/filter-overlay';
|
|
import { PackageListComponent } from '@shared/components/package-inspection/package-list';
|
|
|
|
@Component({
|
|
selector: 'page-package-result',
|
|
templateUrl: 'package-result.component.html',
|
|
styleUrls: ['package-result.component.css'],
|
|
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
providers: [provideComponentStore(PackageResultComponentStore)],
|
|
})
|
|
export class PackageResultComponent implements OnInit, AfterViewInit, OnDestroy {
|
|
private _subscription = new Subscription();
|
|
|
|
get breadcrumbKey(): string {
|
|
return this._config.get('process.ids.packageInspection');
|
|
}
|
|
|
|
hint$ = new Subject<string>();
|
|
|
|
@ViewChild(SharedFilterOverlayComponent)
|
|
filterOverlay: SharedFilterOverlayComponent;
|
|
|
|
/**
|
|
* Zeigt die liste an, wenn entweder keine packages geladen werden oder wenn packages geladen wurden
|
|
* und mindestens ein package vorhanden ist.
|
|
*/
|
|
showList$ = combineLatest([this.store.fetching$, this.store.packages$]).pipe(
|
|
map(([fetching, packages]) => fetching || packages.length > 0)
|
|
);
|
|
|
|
@ViewChild(PackageListComponent, { static: true, read: PackageListComponent })
|
|
packageList: PackageListComponent;
|
|
|
|
initialScrollIndex = 0;
|
|
|
|
constructor(
|
|
public store: PackageResultComponentStore,
|
|
private _activatedRoute: ActivatedRoute,
|
|
private _config: Config,
|
|
private _breadcrumb: BreadcrumbService,
|
|
private _router: Router,
|
|
private _cache: CacheService
|
|
) {}
|
|
|
|
ngOnInit(): void {
|
|
this.removeBreadcrumbs();
|
|
}
|
|
|
|
ngAfterViewInit(): void {
|
|
this.initFilterSubscription();
|
|
|
|
this.initFetchResponseSubscription();
|
|
}
|
|
|
|
hasUpdate(): { arrivalStatus: ArrivalStatus; packageId: string } | undefined {
|
|
const packageId = this._activatedRoute.snapshot.queryParams['updated_packageId'];
|
|
const arrivalStatus = this._activatedRoute.snapshot.queryParams['updated_arrivalStatus'];
|
|
if (!!packageId && !!arrivalStatus) {
|
|
return { arrivalStatus: Number(arrivalStatus) as ArrivalStatus, packageId: String(packageId) };
|
|
}
|
|
}
|
|
|
|
initFilterSubscription() {
|
|
const initialFilter$ = this.store.filter$.pipe(
|
|
filter((f) => f instanceof UiFilter),
|
|
first()
|
|
);
|
|
const queryParams$ = this._activatedRoute.queryParams;
|
|
|
|
const filterSub = combineLatest([initialFilter$, queryParams$]).subscribe(([filter, queryParams]) => {
|
|
const restoredFilter = this.restoreFilterFromQueryParams(filter, queryParams);
|
|
const restoredData = this.restoreResultsFromCache(restoredFilter);
|
|
this.createBreadcrumbIfNotExists(this.store.filter);
|
|
this.fetchPackages(restoredFilter, { keep: true, take: restoredData?.packages?.length });
|
|
});
|
|
|
|
this._subscription.add(filterSub);
|
|
}
|
|
|
|
initFetchResponseSubscription() {
|
|
const onFetchPackageResponseSub = this.store.onFetchPackagesResponse$.subscribe(this.onFetchPackagesResponse);
|
|
|
|
this._subscription.add(onFetchPackageResponseSub);
|
|
}
|
|
|
|
ngOnDestroy(): void {
|
|
this._subscription.unsubscribe();
|
|
}
|
|
|
|
restoreFilterFromQueryParams(filter: UiFilter, queryParams: Params): UiFilter {
|
|
const nextFilter = UiFilter.create(filter);
|
|
nextFilter.fromQueryParams(queryParams);
|
|
this.store.setFilter(nextFilter);
|
|
this.store.setPendingFilter(nextFilter);
|
|
return nextFilter;
|
|
}
|
|
|
|
restoreResultsFromCache(filter: UiFilter): PackageResultCacheData | undefined {
|
|
const data = this._cache.get<PackageResultCacheData>(filter.getQueryParams());
|
|
if (data) {
|
|
const update = this.hasUpdate();
|
|
|
|
if (update) {
|
|
const packageIndex = data.packages.findIndex((p) => p.id === update.packageId);
|
|
if (packageIndex > -1) {
|
|
data.packages[packageIndex].arrivalStatus = update.arrivalStatus;
|
|
}
|
|
}
|
|
|
|
this.store.setPackages(data.packages);
|
|
this.store.setTotal(data.total);
|
|
this.store.setFetching(false);
|
|
|
|
if (data.scrollIndex) {
|
|
this.initialScrollIndex = data.scrollIndex;
|
|
}
|
|
}
|
|
|
|
return data;
|
|
}
|
|
|
|
applyFilter() {
|
|
this.store.applyPendingFilterToFilter();
|
|
this.fetchPackages(this.store.filter);
|
|
}
|
|
|
|
fetchPackages(filter: UiFilter, options: { keep?: boolean; take?: number } = {}) {
|
|
this.hint$.next('');
|
|
this.store.fetchPackages(options);
|
|
}
|
|
|
|
onFetchPackagesResponse = (response: ListResponseArgsOfPackageDTO2) => {
|
|
this.patchLocation(this.store.filter);
|
|
|
|
this.createBreadcrumbIfNotExists(this.store.filter);
|
|
if (response.error) {
|
|
console.error(response);
|
|
return;
|
|
}
|
|
|
|
if (response.result.length === 0) {
|
|
this.hint$.next('Keine Pakete gefunden');
|
|
return;
|
|
}
|
|
|
|
this.cacheData({});
|
|
this.closeFilterOverlay();
|
|
};
|
|
|
|
openFilter() {
|
|
this.store.cancelFetchPackages();
|
|
this.filterOverlay.open();
|
|
}
|
|
|
|
resetFilter() {
|
|
this.store.resetPendingFilter();
|
|
this.store.cancelFetchPackages();
|
|
}
|
|
|
|
async patchLocation(filter: UiFilter): Promise<void> {
|
|
this._router.navigate([], {
|
|
queryParams: filter.getQueryParams(),
|
|
});
|
|
}
|
|
|
|
getBreadcrumbName(filter: UiFilter): string {
|
|
const params = filter.getQueryParams();
|
|
const mainQs = params['main_qs'];
|
|
|
|
let name: string[] = [];
|
|
|
|
if (mainQs) {
|
|
name.push(mainQs);
|
|
}
|
|
|
|
const filterLieferant = params['filter_lieferant'];
|
|
if (filterLieferant) {
|
|
name.push(filterLieferant.split(';').join(' & '));
|
|
}
|
|
|
|
if (name.length > 0) {
|
|
return name.join(' - ');
|
|
}
|
|
|
|
const filterZeitraum = params['filter_zeitraum'];
|
|
|
|
if (filterZeitraum) {
|
|
const range = filterZeitraum.split('"-"').map((s) => s.replace('"', ''));
|
|
if (range[0] && range[1]) {
|
|
const start = moment(range[0]).format('DD.MM.YYYY');
|
|
const end = moment(range[1]).format('DD.MM.YYYY');
|
|
return `${start} - ${end}`;
|
|
} else if (filterZeitraum.endsWith('"-')) {
|
|
const dateString = filterZeitraum.replace('"-', '').replace('"', '');
|
|
return `Ab ${moment(dateString).format('DD.MM.YYYY')}`;
|
|
} else if (filterZeitraum.startsWith('-"')) {
|
|
const dateString = filterZeitraum.replace('-"', '').replace('"', '');
|
|
return `Bis ${moment(dateString).format('DD.MM.YYYY')}`;
|
|
}
|
|
}
|
|
|
|
return 'Paket-Übersicht';
|
|
}
|
|
|
|
async createBreadcrumbIfNotExists(filter: UiFilter): Promise<void> {
|
|
const crumb: Breadcrumb = {
|
|
key: this.breadcrumbKey,
|
|
name: this.getBreadcrumbName(filter),
|
|
path: '/filiale/package-inspection',
|
|
section: 'branch',
|
|
params: filter.getQueryParams(),
|
|
tags: ['filter'],
|
|
};
|
|
|
|
await this._breadcrumb.addOrUpdateBreadcrumbIfNotExists(crumb);
|
|
}
|
|
|
|
async removeBreadcrumbs(): Promise<void> {
|
|
const detailsCrumbs = await this._breadcrumb.getBreadcrumbsByKeyAndTag$(this.breadcrumbKey, 'details').pipe(first()).toPromise();
|
|
const filterCrumbs = await this._breadcrumb.getBreadcrumbsByKeyAndTag$(this.breadcrumbKey, 'filter').pipe(first()).toPromise();
|
|
const crumbs = [...detailsCrumbs, ...filterCrumbs];
|
|
for (let crumb of crumbs) {
|
|
await this._breadcrumb.removeBreadcrumb(crumb.id);
|
|
}
|
|
}
|
|
|
|
closeFilterOverlay() {
|
|
this.store.restorePendingFilter();
|
|
this.filterOverlay.close();
|
|
}
|
|
|
|
allItemsRendered() {
|
|
this.store.paginatePackages();
|
|
}
|
|
|
|
scrollIndexChange($event: number) {
|
|
this.cacheData({ scrollIndex: $event });
|
|
}
|
|
|
|
cacheData(partial: Partial<PackageResultCacheData>) {
|
|
this._cache.set(this.store.filter.getQueryParams(), {
|
|
packages: this.store.packages,
|
|
total: this.store.total,
|
|
...partial,
|
|
} as PackageResultCacheData);
|
|
}
|
|
}
|