mirror of
https://dev.azure.com/hugendubel/ISA/_git/ISA-Frontend
synced 2025-12-28 22:42:11 +01:00
refactor(notifications): update remission path logic to use Date.now()
This commit is contained in:
@@ -1,55 +1,55 @@
|
||||
import {
|
||||
ChangeDetectionStrategy,
|
||||
Component,
|
||||
EventEmitter,
|
||||
Input,
|
||||
Output,
|
||||
inject,
|
||||
linkedSignal,
|
||||
} from '@angular/core';
|
||||
import { Router } from '@angular/router';
|
||||
import { PickupShelfInNavigationService } from '@shared/services/navigation';
|
||||
import { UiFilter } from '@ui/filter';
|
||||
import { MessageBoardItemDTO } from '@hub/notifications';
|
||||
import { TabService } from '@isa/core/tabs';
|
||||
|
||||
@Component({
|
||||
selector: 'modal-notifications-remission-group',
|
||||
templateUrl: 'notifications-remission-group.component.html',
|
||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||
standalone: false,
|
||||
})
|
||||
export class ModalNotificationsRemissionGroupComponent {
|
||||
tabService = inject(TabService);
|
||||
private _pickupShelfInNavigationService = inject(
|
||||
PickupShelfInNavigationService,
|
||||
);
|
||||
|
||||
@Input()
|
||||
notifications: MessageBoardItemDTO[];
|
||||
|
||||
@Output()
|
||||
navigated = new EventEmitter<void>();
|
||||
|
||||
remissionPath = linkedSignal(() => [
|
||||
'/',
|
||||
this.tabService.activatedTab()?.id || this.tabService.nextId(),
|
||||
'remission',
|
||||
]);
|
||||
|
||||
constructor(private _router: Router) {}
|
||||
|
||||
itemSelected(item: MessageBoardItemDTO) {
|
||||
const defaultNav = this._pickupShelfInNavigationService.listRoute();
|
||||
const queryParams = UiFilter.getQueryParamsFromQueryTokenDTO(
|
||||
item.queryToken,
|
||||
);
|
||||
this._router.navigate(defaultNav.path, {
|
||||
queryParams: {
|
||||
...defaultNav.queryParams,
|
||||
...queryParams,
|
||||
},
|
||||
});
|
||||
this.navigated.emit();
|
||||
}
|
||||
}
|
||||
import {
|
||||
ChangeDetectionStrategy,
|
||||
Component,
|
||||
EventEmitter,
|
||||
Input,
|
||||
Output,
|
||||
inject,
|
||||
linkedSignal,
|
||||
} from '@angular/core';
|
||||
import { Router } from '@angular/router';
|
||||
import { PickupShelfInNavigationService } from '@shared/services/navigation';
|
||||
import { UiFilter } from '@ui/filter';
|
||||
import { MessageBoardItemDTO } from '@hub/notifications';
|
||||
import { TabService } from '@isa/core/tabs';
|
||||
|
||||
@Component({
|
||||
selector: 'modal-notifications-remission-group',
|
||||
templateUrl: 'notifications-remission-group.component.html',
|
||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||
standalone: false,
|
||||
})
|
||||
export class ModalNotificationsRemissionGroupComponent {
|
||||
tabService = inject(TabService);
|
||||
private _pickupShelfInNavigationService = inject(
|
||||
PickupShelfInNavigationService,
|
||||
);
|
||||
|
||||
@Input()
|
||||
notifications: MessageBoardItemDTO[];
|
||||
|
||||
@Output()
|
||||
navigated = new EventEmitter<void>();
|
||||
|
||||
remissionPath = linkedSignal(() => [
|
||||
'/',
|
||||
this.tabService.activatedTab()?.id || Date.now(),
|
||||
'remission',
|
||||
]);
|
||||
|
||||
constructor(private _router: Router) {}
|
||||
|
||||
itemSelected(item: MessageBoardItemDTO) {
|
||||
const defaultNav = this._pickupShelfInNavigationService.listRoute();
|
||||
const queryParams = UiFilter.getQueryParamsFromQueryTokenDTO(
|
||||
item.queryToken,
|
||||
);
|
||||
this._router.navigate(defaultNav.path, {
|
||||
queryParams: {
|
||||
...defaultNav.queryParams,
|
||||
...queryParams,
|
||||
},
|
||||
});
|
||||
this.navigated.emit();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,254 +1,254 @@
|
||||
import {
|
||||
ChangeDetectionStrategy,
|
||||
Component,
|
||||
OnDestroy,
|
||||
OnInit,
|
||||
ViewChild,
|
||||
inject,
|
||||
linkedSignal,
|
||||
} from '@angular/core';
|
||||
import { Router } from '@angular/router';
|
||||
import { BreadcrumbService } from '@core/breadcrumb';
|
||||
import {
|
||||
KeyValueDTOOfStringAndString,
|
||||
OrderItemListItemDTO,
|
||||
} from '@generated/swagger/oms-api';
|
||||
import { UiErrorModalComponent, UiModalService } from '@ui/modal';
|
||||
import { UiScrollContainerComponent } from '@ui/scroll-container';
|
||||
import { BehaviorSubject, combineLatest, Subject } from 'rxjs';
|
||||
import { first, map, shareReplay, takeUntil } from 'rxjs/operators';
|
||||
import { GoodsInRemissionPreviewStore } from './goods-in-remission-preview.store';
|
||||
import { Config } from '@core/config';
|
||||
import { ToasterService } from '@shared/shell';
|
||||
import { PickupShelfInNavigationService } from '@shared/services/navigation';
|
||||
import { CacheService } from '@core/cache';
|
||||
import { TabService } from '@isa/core/tabs';
|
||||
|
||||
@Component({
|
||||
selector: 'page-goods-in-remission-preview',
|
||||
templateUrl: 'goods-in-remission-preview.component.html',
|
||||
styleUrls: ['goods-in-remission-preview.component.scss'],
|
||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||
providers: [GoodsInRemissionPreviewStore],
|
||||
standalone: false,
|
||||
})
|
||||
export class GoodsInRemissionPreviewComponent implements OnInit, OnDestroy {
|
||||
tabService = inject(TabService);
|
||||
private _pickupShelfInNavigationService = inject(
|
||||
PickupShelfInNavigationService,
|
||||
);
|
||||
@ViewChild(UiScrollContainerComponent)
|
||||
scrollContainer: UiScrollContainerComponent;
|
||||
|
||||
items$ = this._store.results$;
|
||||
|
||||
itemLength$ = this.items$.pipe(map((items) => items?.length));
|
||||
|
||||
hits$ = this._store.hits$;
|
||||
|
||||
loading$ = this._store.fetching$.pipe(shareReplay());
|
||||
|
||||
changeActionLoader$ = new BehaviorSubject<boolean>(false);
|
||||
|
||||
listEmpty$ = combineLatest([this.loading$, this.hits$]).pipe(
|
||||
map(([loading, hits]) => !loading && hits === 0),
|
||||
shareReplay(),
|
||||
);
|
||||
|
||||
actions$ = this.items$.pipe(map((items) => items[0]?.actions));
|
||||
|
||||
private _onDestroy$ = new Subject<void>();
|
||||
|
||||
byBuyerNumberFn = (item: OrderItemListItemDTO) => item.buyerNumber;
|
||||
|
||||
byOrderNumberFn = (item: OrderItemListItemDTO) => item.orderNumber;
|
||||
|
||||
byProcessingStatusFn = (item: OrderItemListItemDTO) => item.processingStatus;
|
||||
|
||||
byCompartmentCodeFn = (item: OrderItemListItemDTO) =>
|
||||
item.compartmentInfo
|
||||
? `${item.compartmentCode}_${item.compartmentInfo}`
|
||||
: item.compartmentCode;
|
||||
|
||||
private readonly SCROLL_POSITION_TOKEN = 'REMISSION_PREVIEW_SCROLL_POSITION';
|
||||
|
||||
remissionPath = linkedSignal(() => [
|
||||
'/',
|
||||
this.tabService.activatedTab()?.id || this.tabService.nextId(),
|
||||
'remission',
|
||||
]);
|
||||
|
||||
constructor(
|
||||
private _breadcrumb: BreadcrumbService,
|
||||
private _store: GoodsInRemissionPreviewStore,
|
||||
private _router: Router,
|
||||
private _modal: UiModalService,
|
||||
private _config: Config,
|
||||
private _toast: ToasterService,
|
||||
private _cache: CacheService,
|
||||
) {}
|
||||
|
||||
ngOnInit(): void {
|
||||
this.initInitialSearch();
|
||||
this.createBreadcrumb();
|
||||
this.removeBreadcrumbs();
|
||||
}
|
||||
|
||||
ngOnDestroy(): void {
|
||||
this._onDestroy$.next();
|
||||
this._onDestroy$.complete();
|
||||
this._addScrollPositionToCache();
|
||||
this.updateBreadcrumb();
|
||||
}
|
||||
|
||||
private _removeScrollPositionFromCache(): void {
|
||||
this._cache.delete({
|
||||
processId: this._config.get('process.ids.goodsIn'),
|
||||
token: this.SCROLL_POSITION_TOKEN,
|
||||
});
|
||||
}
|
||||
|
||||
private _addScrollPositionToCache(): void {
|
||||
this._cache.set<number>(
|
||||
{
|
||||
processId: this._config.get('process.ids.goodsIn'),
|
||||
token: this.SCROLL_POSITION_TOKEN,
|
||||
},
|
||||
this.scrollContainer?.scrollPos,
|
||||
);
|
||||
}
|
||||
|
||||
private async _getScrollPositionFromCache(): Promise<number> {
|
||||
return await this._cache.get<number>({
|
||||
processId: this._config.get('process.ids.goodsIn'),
|
||||
token: this.SCROLL_POSITION_TOKEN,
|
||||
});
|
||||
}
|
||||
|
||||
async createBreadcrumb() {
|
||||
await this._breadcrumb.addOrUpdateBreadcrumbIfNotExists({
|
||||
key: this._config.get('process.ids.goodsIn'),
|
||||
name: 'Abholfachremissionsvorschau',
|
||||
path: '/filiale/goods/in/preview',
|
||||
section: 'branch',
|
||||
params: { view: 'remission' },
|
||||
tags: ['goods-in', 'preview'],
|
||||
});
|
||||
}
|
||||
|
||||
async updateBreadcrumb() {
|
||||
const crumbs = await this._breadcrumb
|
||||
.getBreadcrumbsByKeyAndTags$(this._config.get('process.ids.goodsIn'), [
|
||||
'goods-in',
|
||||
'preview',
|
||||
])
|
||||
.pipe(first())
|
||||
.toPromise();
|
||||
for (const crumb of crumbs) {
|
||||
this._breadcrumb.patchBreadcrumb(crumb.id, {
|
||||
name: crumb.name,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
async removeBreadcrumbs() {
|
||||
let breadcrumbsToDelete = await this._breadcrumb
|
||||
.getBreadcrumbsByKeyAndTags$(this._config.get('process.ids.goodsIn'), [
|
||||
'goods-in',
|
||||
])
|
||||
.pipe(first())
|
||||
.toPromise();
|
||||
|
||||
breadcrumbsToDelete = breadcrumbsToDelete.filter(
|
||||
(crumb) =>
|
||||
!crumb.tags.includes('preview') && !crumb.tags.includes('main'),
|
||||
);
|
||||
|
||||
breadcrumbsToDelete.forEach((crumb) => {
|
||||
this._breadcrumb.removeBreadcrumb(crumb.id, true);
|
||||
});
|
||||
|
||||
const detailsCrumbs = await this._breadcrumb
|
||||
.getBreadcrumbsByKeyAndTags$(this._config.get('process.ids.goodsIn'), [
|
||||
'goods-in',
|
||||
'details',
|
||||
])
|
||||
.pipe(first())
|
||||
.toPromise();
|
||||
const editCrumbs = await this._breadcrumb
|
||||
.getBreadcrumbsByKeyAndTags$(this._config.get('process.ids.goodsIn'), [
|
||||
'goods-in',
|
||||
'edit',
|
||||
])
|
||||
.pipe(first())
|
||||
.toPromise();
|
||||
|
||||
detailsCrumbs.forEach((crumb) => {
|
||||
this._breadcrumb.removeBreadcrumb(crumb.id, true);
|
||||
});
|
||||
|
||||
editCrumbs.forEach((crumb) => {
|
||||
this._breadcrumb.removeBreadcrumb(crumb.id, true);
|
||||
});
|
||||
}
|
||||
|
||||
initInitialSearch() {
|
||||
if (this._store.hits === 0) {
|
||||
this._store.searchResult$
|
||||
.pipe(takeUntil(this._onDestroy$))
|
||||
.subscribe(async (result) => {
|
||||
await this.createBreadcrumb();
|
||||
|
||||
this.scrollContainer?.scrollTo(
|
||||
(await this._getScrollPositionFromCache()) ?? 0,
|
||||
);
|
||||
this._removeScrollPositionFromCache();
|
||||
});
|
||||
}
|
||||
|
||||
this._store.search();
|
||||
}
|
||||
|
||||
async navigateToRemission() {
|
||||
await this._router.navigate(this.remissionPath());
|
||||
}
|
||||
|
||||
navigateToDetails(orderItem: OrderItemListItemDTO) {
|
||||
const nav = this._pickupShelfInNavigationService.detailRoute({
|
||||
item: orderItem,
|
||||
side: false,
|
||||
});
|
||||
|
||||
this._router.navigate(nav.path, {
|
||||
queryParams: { ...nav.queryParams, view: 'remission' },
|
||||
});
|
||||
}
|
||||
|
||||
async handleAction(action: KeyValueDTOOfStringAndString) {
|
||||
this.changeActionLoader$.next(true);
|
||||
|
||||
try {
|
||||
const response = await this._store
|
||||
.createRemissionFromPreview()
|
||||
.pipe(first())
|
||||
.toPromise();
|
||||
|
||||
if (!response?.dialog) {
|
||||
this._toast.open({
|
||||
title: 'Abholfachremission',
|
||||
message: response?.message,
|
||||
});
|
||||
}
|
||||
|
||||
await this.navigateToRemission();
|
||||
} catch (error) {
|
||||
this._modal.open({
|
||||
content: UiErrorModalComponent,
|
||||
data: error,
|
||||
});
|
||||
console.error(error);
|
||||
}
|
||||
|
||||
this.changeActionLoader$.next(false);
|
||||
}
|
||||
}
|
||||
import {
|
||||
ChangeDetectionStrategy,
|
||||
Component,
|
||||
OnDestroy,
|
||||
OnInit,
|
||||
ViewChild,
|
||||
inject,
|
||||
linkedSignal,
|
||||
} from '@angular/core';
|
||||
import { Router } from '@angular/router';
|
||||
import { BreadcrumbService } from '@core/breadcrumb';
|
||||
import {
|
||||
KeyValueDTOOfStringAndString,
|
||||
OrderItemListItemDTO,
|
||||
} from '@generated/swagger/oms-api';
|
||||
import { UiErrorModalComponent, UiModalService } from '@ui/modal';
|
||||
import { UiScrollContainerComponent } from '@ui/scroll-container';
|
||||
import { BehaviorSubject, combineLatest, Subject } from 'rxjs';
|
||||
import { first, map, shareReplay, takeUntil } from 'rxjs/operators';
|
||||
import { GoodsInRemissionPreviewStore } from './goods-in-remission-preview.store';
|
||||
import { Config } from '@core/config';
|
||||
import { ToasterService } from '@shared/shell';
|
||||
import { PickupShelfInNavigationService } from '@shared/services/navigation';
|
||||
import { CacheService } from '@core/cache';
|
||||
import { TabService } from '@isa/core/tabs';
|
||||
|
||||
@Component({
|
||||
selector: 'page-goods-in-remission-preview',
|
||||
templateUrl: 'goods-in-remission-preview.component.html',
|
||||
styleUrls: ['goods-in-remission-preview.component.scss'],
|
||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||
providers: [GoodsInRemissionPreviewStore],
|
||||
standalone: false,
|
||||
})
|
||||
export class GoodsInRemissionPreviewComponent implements OnInit, OnDestroy {
|
||||
tabService = inject(TabService);
|
||||
private _pickupShelfInNavigationService = inject(
|
||||
PickupShelfInNavigationService,
|
||||
);
|
||||
@ViewChild(UiScrollContainerComponent)
|
||||
scrollContainer: UiScrollContainerComponent;
|
||||
|
||||
items$ = this._store.results$;
|
||||
|
||||
itemLength$ = this.items$.pipe(map((items) => items?.length));
|
||||
|
||||
hits$ = this._store.hits$;
|
||||
|
||||
loading$ = this._store.fetching$.pipe(shareReplay());
|
||||
|
||||
changeActionLoader$ = new BehaviorSubject<boolean>(false);
|
||||
|
||||
listEmpty$ = combineLatest([this.loading$, this.hits$]).pipe(
|
||||
map(([loading, hits]) => !loading && hits === 0),
|
||||
shareReplay(),
|
||||
);
|
||||
|
||||
actions$ = this.items$.pipe(map((items) => items[0]?.actions));
|
||||
|
||||
private _onDestroy$ = new Subject<void>();
|
||||
|
||||
byBuyerNumberFn = (item: OrderItemListItemDTO) => item.buyerNumber;
|
||||
|
||||
byOrderNumberFn = (item: OrderItemListItemDTO) => item.orderNumber;
|
||||
|
||||
byProcessingStatusFn = (item: OrderItemListItemDTO) => item.processingStatus;
|
||||
|
||||
byCompartmentCodeFn = (item: OrderItemListItemDTO) =>
|
||||
item.compartmentInfo
|
||||
? `${item.compartmentCode}_${item.compartmentInfo}`
|
||||
: item.compartmentCode;
|
||||
|
||||
private readonly SCROLL_POSITION_TOKEN = 'REMISSION_PREVIEW_SCROLL_POSITION';
|
||||
|
||||
remissionPath = linkedSignal(() => [
|
||||
'/',
|
||||
this.tabService.activatedTab()?.id || Date.now(),
|
||||
'remission',
|
||||
]);
|
||||
|
||||
constructor(
|
||||
private _breadcrumb: BreadcrumbService,
|
||||
private _store: GoodsInRemissionPreviewStore,
|
||||
private _router: Router,
|
||||
private _modal: UiModalService,
|
||||
private _config: Config,
|
||||
private _toast: ToasterService,
|
||||
private _cache: CacheService,
|
||||
) {}
|
||||
|
||||
ngOnInit(): void {
|
||||
this.initInitialSearch();
|
||||
this.createBreadcrumb();
|
||||
this.removeBreadcrumbs();
|
||||
}
|
||||
|
||||
ngOnDestroy(): void {
|
||||
this._onDestroy$.next();
|
||||
this._onDestroy$.complete();
|
||||
this._addScrollPositionToCache();
|
||||
this.updateBreadcrumb();
|
||||
}
|
||||
|
||||
private _removeScrollPositionFromCache(): void {
|
||||
this._cache.delete({
|
||||
processId: this._config.get('process.ids.goodsIn'),
|
||||
token: this.SCROLL_POSITION_TOKEN,
|
||||
});
|
||||
}
|
||||
|
||||
private _addScrollPositionToCache(): void {
|
||||
this._cache.set<number>(
|
||||
{
|
||||
processId: this._config.get('process.ids.goodsIn'),
|
||||
token: this.SCROLL_POSITION_TOKEN,
|
||||
},
|
||||
this.scrollContainer?.scrollPos,
|
||||
);
|
||||
}
|
||||
|
||||
private async _getScrollPositionFromCache(): Promise<number> {
|
||||
return await this._cache.get<number>({
|
||||
processId: this._config.get('process.ids.goodsIn'),
|
||||
token: this.SCROLL_POSITION_TOKEN,
|
||||
});
|
||||
}
|
||||
|
||||
async createBreadcrumb() {
|
||||
await this._breadcrumb.addOrUpdateBreadcrumbIfNotExists({
|
||||
key: this._config.get('process.ids.goodsIn'),
|
||||
name: 'Abholfachremissionsvorschau',
|
||||
path: '/filiale/goods/in/preview',
|
||||
section: 'branch',
|
||||
params: { view: 'remission' },
|
||||
tags: ['goods-in', 'preview'],
|
||||
});
|
||||
}
|
||||
|
||||
async updateBreadcrumb() {
|
||||
const crumbs = await this._breadcrumb
|
||||
.getBreadcrumbsByKeyAndTags$(this._config.get('process.ids.goodsIn'), [
|
||||
'goods-in',
|
||||
'preview',
|
||||
])
|
||||
.pipe(first())
|
||||
.toPromise();
|
||||
for (const crumb of crumbs) {
|
||||
this._breadcrumb.patchBreadcrumb(crumb.id, {
|
||||
name: crumb.name,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
async removeBreadcrumbs() {
|
||||
let breadcrumbsToDelete = await this._breadcrumb
|
||||
.getBreadcrumbsByKeyAndTags$(this._config.get('process.ids.goodsIn'), [
|
||||
'goods-in',
|
||||
])
|
||||
.pipe(first())
|
||||
.toPromise();
|
||||
|
||||
breadcrumbsToDelete = breadcrumbsToDelete.filter(
|
||||
(crumb) =>
|
||||
!crumb.tags.includes('preview') && !crumb.tags.includes('main'),
|
||||
);
|
||||
|
||||
breadcrumbsToDelete.forEach((crumb) => {
|
||||
this._breadcrumb.removeBreadcrumb(crumb.id, true);
|
||||
});
|
||||
|
||||
const detailsCrumbs = await this._breadcrumb
|
||||
.getBreadcrumbsByKeyAndTags$(this._config.get('process.ids.goodsIn'), [
|
||||
'goods-in',
|
||||
'details',
|
||||
])
|
||||
.pipe(first())
|
||||
.toPromise();
|
||||
const editCrumbs = await this._breadcrumb
|
||||
.getBreadcrumbsByKeyAndTags$(this._config.get('process.ids.goodsIn'), [
|
||||
'goods-in',
|
||||
'edit',
|
||||
])
|
||||
.pipe(first())
|
||||
.toPromise();
|
||||
|
||||
detailsCrumbs.forEach((crumb) => {
|
||||
this._breadcrumb.removeBreadcrumb(crumb.id, true);
|
||||
});
|
||||
|
||||
editCrumbs.forEach((crumb) => {
|
||||
this._breadcrumb.removeBreadcrumb(crumb.id, true);
|
||||
});
|
||||
}
|
||||
|
||||
initInitialSearch() {
|
||||
if (this._store.hits === 0) {
|
||||
this._store.searchResult$
|
||||
.pipe(takeUntil(this._onDestroy$))
|
||||
.subscribe(async (result) => {
|
||||
await this.createBreadcrumb();
|
||||
|
||||
this.scrollContainer?.scrollTo(
|
||||
(await this._getScrollPositionFromCache()) ?? 0,
|
||||
);
|
||||
this._removeScrollPositionFromCache();
|
||||
});
|
||||
}
|
||||
|
||||
this._store.search();
|
||||
}
|
||||
|
||||
async navigateToRemission() {
|
||||
await this._router.navigate(this.remissionPath());
|
||||
}
|
||||
|
||||
navigateToDetails(orderItem: OrderItemListItemDTO) {
|
||||
const nav = this._pickupShelfInNavigationService.detailRoute({
|
||||
item: orderItem,
|
||||
side: false,
|
||||
});
|
||||
|
||||
this._router.navigate(nav.path, {
|
||||
queryParams: { ...nav.queryParams, view: 'remission' },
|
||||
});
|
||||
}
|
||||
|
||||
async handleAction(action: KeyValueDTOOfStringAndString) {
|
||||
this.changeActionLoader$.next(true);
|
||||
|
||||
try {
|
||||
const response = await this._store
|
||||
.createRemissionFromPreview()
|
||||
.pipe(first())
|
||||
.toPromise();
|
||||
|
||||
if (!response?.dialog) {
|
||||
this._toast.open({
|
||||
title: 'Abholfachremission',
|
||||
message: response?.message,
|
||||
});
|
||||
}
|
||||
|
||||
await this.navigateToRemission();
|
||||
} catch (error) {
|
||||
this._modal.open({
|
||||
content: UiErrorModalComponent,
|
||||
data: error,
|
||||
});
|
||||
console.error(error);
|
||||
}
|
||||
|
||||
this.changeActionLoader$.next(false);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user