Init PickUpShelfIn page, Navigation and SubPages

This commit is contained in:
Nino
2023-10-04 18:06:28 +02:00
parent e6afd6887a
commit d13cf0ef8d
20 changed files with 967 additions and 35 deletions

View File

@@ -125,10 +125,16 @@ const routes: Routes = [
canActivate: [CanActivateTaskCalendarGuard],
},
{
path: 'goods/in',
loadChildren: () => import('@page/goods-in').then((m) => m.GoodsInModule),
canActivate: [CanActivateGoodsInGuard],
path: 'pickup-shelf',
canActivate: [ProcessIdGuard],
// NOTE: This is a workaround for the canActivate guard not being called
loadChildren: () => import('@page/pickup-shelf').then((m) => m.PickupShelfInModule),
},
// {
// path: 'goods/in',
// loadChildren: () => import('@page/goods-in').then((m) => m.GoodsInModule),
// canActivate: [CanActivateGoodsInGuard],
// },
{
path: 'remission',
loadChildren: () => import('@page/remission').then((m) => m.PageRemissionModule),

View File

@@ -1,3 +1,26 @@
:host {
@apply block;
@apply box-border grid overflow-y-scroll h-split-screen-tablet desktop-small:h-split-screen-desktop;
grid-template-rows: auto 1fr;
}
.page-pickup-shelf-in-details__action-wrapper {
@apply sticky bottom-4 mt-4 text-center;
}
.cta-action {
@apply border-2 border-solid border-brand rounded-full py-3 px-6 font-bold text-lg outline-none self-end whitespace-nowrap m-2;
}
.fetching {
@apply bg-inactive-branch;
}
.cta-action-primary {
@apply bg-brand text-white;
}
.cta-action-secondary {
@apply bg-white text-brand;
}
button:disabled {
@apply bg-inactive-customer border-inactive-customer text-white cursor-not-allowed;
}

View File

@@ -1 +1,44 @@
<h1>Details</h1>
<!-- <div class="mb-4">
<page-pickup-shelf-details-header
[processId]="processId"
[order]="order$ | async"
(handleAction)="handleAction($event)"
(updateDate)="updateDate($event)"
(editClick)="navigateToEditPage($event)"
></page-pickup-shelf-details-header>
TODO: ITEM NUR EINZELN ANZEIGEN
<page-pickup-shelf-details-item
class="mb-px-2"
*ngFor="let item of orderItems$ | async; trackBy: trackByFnDBHOrderItemListItemDTO"
[orderItem]="item"
[selected]="true"
(historyClick)="navigateToHistoryPage($event)"
[order]="order$ | async"
[notifications]="getNotifications$(item) | async"
(specialCommentChanged)="updateSpecialComment(item, $event)"
(sharedOnInit)="fetchNotifications(item)"
></page-pickup-shelf-details-item>
<page-pickup-shelf-details-tags *ngIf="showTagsComponent$ | async"></page-pickup-shelf-details-tags>
TODO: ITEM COVER ANZEIGE
</div>
<div class="page-pickup-shelf-in-details__action-wrapper">
TODO: ZUBUCHEN ACTION
<button
[disabled]="actionsDisabled$ | async"
class="cta-action shadow-action"
[class.cta-action-primary]="action.selected"
[class.cta-action-secondary]="!action.selected"
*ngFor="let action of mainActions$ | async"
(click)="handleAction(action)"
>
<ui-spinner [show]="(changeActionLoader$ | async) === action.command">{{ action.label }}</ui-spinner>
</button>
</div>
-->

View File

@@ -0,0 +1,47 @@
:host {
@apply box-border grid h-split-screen-tablet desktop-small:h-split-screen-desktop;
grid-template-rows: auto 1fr;
}
.page-pickup-shelf-in-list__filter:active {
@apply bg-[#596470] text-white;
}
.empty-message {
@apply bg-white text-center font-semibold text-inactive-customer py-10 rounded;
}
page-pickup-shelf-list-item {
@apply cursor-pointer;
}
.actions {
@apply flex sticky bottom-12 items-center justify-center;
}
.cta-action {
@apply border-2 border-solid border-brand rounded-full py-4 px-6 font-bold text-lg outline-none self-end whitespace-nowrap;
}
.cta-action:disabled {
@apply bg-inactive-branch border-inactive-branch text-white;
}
.cta-action-primary {
@apply bg-brand text-white;
}
.cta-action-secondary {
@apply bg-white text-brand;
}
::ng-deep page-pickup-shelf-in-list ui-scroll-container {
height: 100% !important;
overflow: hidden !important;
}
::ng-deep page-pickup-shelf-in-list ui-scroll-container .scroll-container {
height: 100% !important;
max-height: 100% !important;
gap: 0.625rem !important;
}

View File

@@ -0,0 +1,101 @@
<div
class="page-pickup-shelf-in-list__header bg-background-liste flex items-end justify-between"
[class.pb-4]="!(primaryOutletActive$ | async)"
[class.flex-col]="!(primaryOutletActive$ | async)"
>
<div class="flex flex-row w-full desktop-small:w-min" [class.desktop-large:w-full]="!(primaryOutletActive$ | async)">
<shared-filter-input-group-main
*ngIf="filter$ | async; let filter"
class="block mr-3 w-full desktop-small:w-[23.5rem]"
[class.desktop-large:w-full]="!(primaryOutletActive$ | async)"
[hint]="searchboxHint$ | async"
[loading]="fetching$ | async"
[inputGroup]="filter?.input | group: 'main'"
(search)="search(filter)"
[showDescription]="false"
[scanner]="true"
></shared-filter-input-group-main>
<a
*ngIf="filterNavigation"
class="page-pickup-shelf-in-list__filter w-[6.75rem] h-14 rounded font-bold px-5 mb-4 text-lg bg-[#AEB7C1] flex flex-row flex-nowrap items-center justify-center"
[class.active]="hasFilter$ | async"
[routerLink]="filterNavigation.path"
[queryParams]="filterNavigation.queryParams"
queryParamsHandling="preserve"
>
<shared-icon class="mr-2" icon="filter-variant"></shared-icon>
Filter
</a>
</div>
<div
*ngIf="hits$ | async; let hits"
class="page-pickup-shelf-in-list__items-count inline-flex flex-row items-center pr-5 text-p3"
[class.mb-4]="primaryOutletActive$ | async"
>
{{ hits ??
0 }}
Titel
</div>
</div>
<div class="h-full relative overflow-hidden overflow-y-scroll">
<ui-scroll-container
*ngIf="!(listEmpty$ | async); else emptyMessage"
class="page-pickup-shelf-in-list__scroll-container m-0 p-0"
(reachEnd)="loadMore()"
[deltaEnd]="150"
[showScrollbar]="false"
[containerHeight]="25"
[showScrollArrow]="false"
[showSpacer]="(primaryOutletActive$ | async) || (isTablet$ | async)"
>
<div class="page-pickup-shelf-in-list__items-list w-full" *ngFor="let bueryNumberGroup of list$ | async | groupBy: byBuyerNumberFn">
<ng-container *ngIf="bueryNumberGroup.items[0]; let firstItem">
<div
class="page-pickup-shelf-in-list__item-header-group w-full grid grid-flow-col gap-x-4 items-center justify-between bg-white text-xl rounded-t p-4 font-bold mb-px-2"
>
<h3>
{{ firstItem?.organisation }}
<ng-container *ngIf="!!firstItem?.organisation && (!!firstItem?.firstName || !!firstItem?.lastName)"> - </ng-container>
{{ firstItem?.lastName }}
{{ firstItem?.firstName }}
</h3>
</div>
</ng-container>
<ng-container *ngFor="let orderNumberGroup of bueryNumberGroup.items | groupBy: byOrderNumberFn">
<ng-container *ngFor="let processingStatusGroup of orderNumberGroup.items | groupBy: byProcessingStatusFn">
<ng-container *ngFor="let compartmentCodeGroup of processingStatusGroup.items | groupBy: byCompartmentCodeFn">
<page-pickup-shelf-list-item
*ngFor="let item of compartmentCodeGroup.items; let firstItem = first; trackBy: trackByFn"
class="page-pickup-shelf-in-list__result-item mb-[0.125rem]"
[item]="item"
[primaryOutletActive]="primaryOutletActive$ | async"
></page-pickup-shelf-list-item>
</ng-container>
</ng-container>
</ng-container>
</div>
</ui-scroll-container>
<div class="actions z-sticky h-0 gap-4" *ngIf="actions$ | async; let actions">
<button
[disabled]="(loadingFetchedActionButton$ | async) || (fetching$ | async)"
class="cta-action"
*ngFor="let action of actions"
[class.cta-action-primary]="action.selected"
[class.cta-action-secondary]="!action.selected"
(click)="handleAction(action)"
>
<ui-spinner [show]="(loadingFetchedActionButton$ | async) || (fetching$ | async)">{{ action.label }}</ui-spinner>
</button>
</div>
</div>
<ng-template #emptyMessage>
<div class="empty-message">
Es sind im Moment keine Bestellposten vorhanden,<br />
die bearbeitet werden können.
</div>
</ng-template>

View File

@@ -0,0 +1,269 @@
import { AsyncPipe, NgFor, NgIf } from '@angular/common';
import { ChangeDetectionStrategy, Component, OnInit, TrackByFunction, inject } from '@angular/core';
import { ActivatedRoute, RouterLink } from '@angular/router';
import { Filter, FilterModule } from '@shared/components/filter';
import { IconModule } from '@shared/components/icon';
import { PickUpShelfListItemComponent } from '../../shared/pickup-shelf-list-item/pickup-shelf-list-item.component';
import { UiScrollContainerModule } from '@ui/scroll-container';
import { GroupByPipe } from '@ui/common';
import { UiSpinnerModule } from '@ui/spinner';
import { GetNameForBreadcrumbData, GetPathForBreadcrumbData, PickupShelfBaseComponent } from '../../pickup-shelf-base.component';
import { NavigationRoute, PickupShelfInNavigationService } from '@shared/services';
import { map, take } from 'rxjs/operators';
import { DBHOrderItemListItemDTO, KeyValueDTOOfStringAndString } from '@swagger/oms';
import { BehaviorSubject, Observable, combineLatest, of } from 'rxjs';
import { PickupShelfDetailsStore, PickupShelfStore } from '../../store';
import { isEqual } from 'lodash';
import { EnvironmentService } from '@core/environment';
import { UiErrorModalComponent, UiModalService } from '@ui/modal';
@Component({
selector: 'page-pickup-shelf-in-list',
templateUrl: 'pickup-shelf-in-list.component.html',
styleUrls: ['pickup-shelf-in-list.component.css'],
changeDetection: ChangeDetectionStrategy.OnPush,
host: { class: 'page-pickup-shelf-in-list' },
standalone: true,
imports: [
AsyncPipe,
NgFor,
RouterLink,
NgIf,
IconModule,
FilterModule,
PickUpShelfListItemComponent,
UiScrollContainerModule,
GroupByPipe,
UiSpinnerModule,
],
})
export class PickUpShelfInListComponent extends PickupShelfBaseComponent implements OnInit {
private _pickupShelfInNavigationService = inject(PickupShelfInNavigationService);
store = inject(PickupShelfStore);
detailsStore = inject(PickupShelfDetailsStore);
list$ = this.store.list$;
hits$ = this.store.listHits$;
filterNavigation = this._pickupShelfInNavigationService.filterRoute();
get primaryOutletActive$() {
return this.isTablet$.pipe(map((matches) => !matches && this._activatedRoute.outlet === 'primary'));
}
filter$ = this.store.filter$;
hasFilter$ = combineLatest([this.filter$, this.store.defaultFilter$]).pipe(
map(([filter, defaultFilter]) => {
const filterQueryParams = filter?.getQueryParams();
return !isEqual(filterQueryParams, Filter.create(defaultFilter).getQueryParams());
})
);
fetching$: Observable<boolean> = this.store.fetching$;
searchboxHint$ = this.store.searchboxHint$;
get isTablet$() {
return this._environment.matchTablet$;
}
get selectedIds$() {
return this.store.selectedListItems$.pipe(map((items) => items?.map((item) => item.orderItemSubsetId)));
}
listEmpty$ = combineLatest([this.fetching$, this.hits$]).pipe(map(([fetching, hits]) => !fetching && hits === 0));
byBuyerNumberFn = (item: DBHOrderItemListItemDTO) => item.buyerNumber;
byOrderNumberFn = (item: DBHOrderItemListItemDTO) => item.orderNumber;
byProcessingStatusFn = (item: DBHOrderItemListItemDTO) => item.processingStatus;
byCompartmentCodeFn = (item: DBHOrderItemListItemDTO) =>
!!item.compartmentInfo ? `${item.compartmentCode}_${item.compartmentInfo}` : item.compartmentCode;
trackByFn: TrackByFunction<DBHOrderItemListItemDTO> = (index, item) => `${item.orderId}${item.orderItemId}${item.orderItemSubsetId}`;
actions$ = combineLatest([this.list$, this.selectedIds$]).pipe(
map(([items, selectedIds]) =>
items?.find((item) => selectedIds.find((orderItemSubsetId) => item.orderItemSubsetId === orderItemSubsetId))
),
map((item) => item?.actions?.filter((action) => this.selectionRules(action)))
);
loadingFetchedActionButton$ = new BehaviorSubject<boolean>(false);
constructor(private _environment: EnvironmentService, private _activatedRoute: ActivatedRoute, private _uiModal: UiModalService) {
super();
}
ngOnInit() {
if (!this.store.list.length) {
this.store.fetchList();
}
}
selectionRules(action: KeyValueDTOOfStringAndString) {
return (
(action.command.includes('FETCHED') && action.key === '256' && action.enabled !== false) ||
action.command.includes('COLLECT_ON_DELIVERYNOTE')
);
}
search(filter: Filter) {
this.store.setQueryParams(filter.getQueryParams());
this.store.fetchList();
}
loadMore() {
this.store.fetchMoreList();
}
async handleAction(action: KeyValueDTOOfStringAndString) {
this.loadingFetchedActionButton$.next(true);
try {
await this.execAction(action);
this.store.fetchList();
this.store.resetSelectedListItems();
this.loadingFetchedActionButton$.next(false);
} catch (error) {
console.error(error);
this._uiModal.open({
content: UiErrorModalComponent,
data: error,
});
this.loadingFetchedActionButton$.next(false);
}
}
getNameForMainBreadcrumb(data: { queryParams: Record<string, string> }): string | Promise<string> {
return 'Einbuchen';
}
getPathForMainBreadcrumb(data: { queryParams: Record<string, string> }): NavigationRoute | Promise<NavigationRoute> {
return this._pickupShelfInNavigationService.defaultRoute();
}
getNameForListBreadcrumb(data: GetNameForBreadcrumbData): string | Promise<string> {
if (data.queryParams?.main_qs) {
return data.queryParams.main_qs;
}
return 'Alle';
}
getPathFoListBreadcrumb(data: GetPathForBreadcrumbData): NavigationRoute | Promise<NavigationRoute> {
return this._pickupShelfInNavigationService.listRoute();
}
getNameForFilterBreadcrumb(data: GetNameForBreadcrumbData): string | Promise<string> {
return 'Filter';
}
getPathForFilter(data: GetPathForBreadcrumbData): NavigationRoute | Promise<NavigationRoute> {
return this._pickupShelfInNavigationService.filterRoute();
}
async getNameForDetailBreadcrumb(data: GetNameForBreadcrumbData): Promise<string> {
const compartmentCode = await this.detailsStore.compartmentCode$.pipe(take(1)).toPromise();
if (compartmentCode) {
return compartmentCode;
}
const order = await this.detailsStore.order$.pipe(take(1)).toPromise();
if (order?.orderNumber) {
return order?.orderNumber;
}
return 'Details';
}
async getPathForDetailForDetailBreadcrumb(data: GetPathForBreadcrumbData): Promise<NavigationRoute> {
const compartmentCode = await this.detailsStore.compartmentCode$.pipe(take(1)).toPromise();
const order = await this.detailsStore.order$.pipe(take(1)).toPromise();
const processingStatus = await this.detailsStore.processingStatus$.pipe(take(1)).toPromise();
return this._pickupShelfInNavigationService.detailRoute({
item: {
orderId: order?.id,
compartmentCode,
orderNumber: order?.orderNumber,
processingStatus: processingStatus,
},
});
}
getPathForDetail(item: DBHOrderItemListItemDTO): Observable<NavigationRoute> {
return of(
this._pickupShelfInNavigationService.detailRoute({
item: {
compartmentCode: item.compartmentCode,
orderId: item.orderId,
orderNumber: item.orderNumber,
processingStatus: item.processingStatus,
},
})
);
}
getPathForEdit(item: DBHOrderItemListItemDTO): Observable<NavigationRoute> {
return of(
this._pickupShelfInNavigationService.editRoute({
compartmentCode: item.compartmentCode,
orderId: item.orderId,
orderNumber: item.orderNumber,
processingStatus: item.processingStatus,
})
);
}
async getPathForEditBreadcrumb(data: GetPathForBreadcrumbData): Promise<NavigationRoute> {
const compartmentCode = await this.detailsStore.compartmentCode$.pipe(take(1)).toPromise();
const order = await this.detailsStore.order$.pipe(take(1)).toPromise();
const processingStatus = await this.detailsStore.processingStatus$.pipe(take(1)).toPromise();
return this._pickupShelfInNavigationService.editRoute({
orderId: order?.id,
compartmentCode,
orderNumber: order?.orderNumber,
processingStatus: processingStatus,
});
}
async getNameForEditBreadcrumb(data: GetNameForBreadcrumbData): Promise<string> {
return 'Bearbeiten';
}
getPathForHistory(item: DBHOrderItemListItemDTO): Observable<NavigationRoute> {
return of(
this._pickupShelfInNavigationService.historyRoute({
compartmentCode: item.compartmentCode,
orderId: item.orderId,
orderNumber: item.orderNumber,
processingStatus: item.processingStatus,
})
);
}
async getPathForHistoryBreadcrumb(data: GetPathForBreadcrumbData): Promise<NavigationRoute> {
const compartmentCode = await this.detailsStore.compartmentCode$.pipe(take(1)).toPromise();
const order = await this.detailsStore.order$.pipe(take(1)).toPromise();
const processingStatus = await this.detailsStore.processingStatus$.pipe(take(1)).toPromise();
return this._pickupShelfInNavigationService.historyRoute({
orderId: order?.id,
compartmentCode,
orderNumber: order?.orderNumber,
processingStatus: processingStatus,
});
}
async getNameForHistoryBreadcrumb(data: GetNameForBreadcrumbData): Promise<string> {
return 'Historie';
}
}

View File

@@ -0,0 +1,11 @@
:host {
@apply block bg-white h-split-screen-tablet desktop-small:h-split-screen-desktop;
}
.page-pickup-shelf-in-main__filter:active {
@apply bg-[#596470] text-white;
}
::ng-deep page-pickup-shelf-in-main-side-view ui-filter-filter-group-main .ui-filter-chip:not(.selected) {
@apply bg-glitter;
}

View File

@@ -0,0 +1,36 @@
<div class="rounded py-10 px-4 text-center shadow-[0_-2px_24px_0_#dce2e9] h-full">
<h1 class="text-[1.625rem] font-bold">Einbuchen</h1>
<p class="text-lg mt-2 mb-10">
Scannen Sie den Artikel, um diesen einzubuchen <br />
oder suchen Sie nach Kundennamen.
</p>
<ng-container *ngIf="filter$ | async; let filter">
<shared-filter-filter-group-main
class="mb-8 w-full"
*ngIf="!(isDesktop$ | async)"
[inputGroup]="filter?.filter | group: 'main'"
></shared-filter-filter-group-main>
<div class="flex flex-row px-12 justify-center desktop-large:px-0">
<shared-filter-input-group-main
class="block w-full mr-3 desktop-large:mx-auto"
*ngIf="filter$ | async; let filter"
[inputGroup]="filter?.input | group: 'main'"
[hint]="searchboxHint$ | async"
[loading]="fetching$ | async"
(search)="search(filter)"
[showDescription]="false"
[scanner]="true"
></shared-filter-input-group-main>
<button
type="button"
*ngIf="!(isDesktop$ | async)"
(click)="showFilter.emit()"
class="page-pickup-shelf-in-main__filter w-[6.75rem] h-14 rounded font-bold px-5 mb-4 text-lg bg-[#AEB7C1] flex flex-row flex-nowrap items-center justify-center"
[class.active]="hasFilter$ | async"
>
<shared-icon class="mr-2" icon="filter-variant"></shared-icon>
Filter
</button>
</div>
</ng-container>
</div>

View File

@@ -0,0 +1,53 @@
import { AsyncPipe, NgIf } from '@angular/common';
import { ChangeDetectionStrategy, Component, EventEmitter, OnInit, Output, ViewChild, inject } from '@angular/core';
import { EnvironmentService } from '@core/environment';
import { Filter, FilterInputGroupMainComponent, FilterModule } from '@shared/components/filter';
import { IconModule } from '@shared/components/icon';
import { isEqual } from 'lodash';
import { Observable, combineLatest } from 'rxjs';
import { map } from 'rxjs/operators';
import { PickupShelfStore } from '../../store';
@Component({
selector: 'page-pickup-shelf-in-main-side-view',
templateUrl: 'pickup-shelf-in-main-side-view.component.html',
styleUrls: ['pickup-shelf-in-main-side-view.component.css'],
standalone: true,
changeDetection: ChangeDetectionStrategy.OnPush,
host: { class: 'page-pickup-shelf-in-main-side-view' },
imports: [FilterModule, AsyncPipe, NgIf, IconModule],
})
export class PickUpShelfInMainSideViewComponent implements OnInit {
@Output() showFilter = new EventEmitter<void>();
@ViewChild(FilterInputGroupMainComponent, { static: false })
sharedFilterInputGroupMain: FilterInputGroupMainComponent;
store = inject(PickupShelfStore);
filter$ = this.store.filter$;
get isDesktop$() {
return this._environment.matchDesktopLarge$;
}
hasFilter$ = combineLatest([this.filter$, this.store.defaultFilter$]).pipe(
map(([filter, defaultFilter]) => {
const filterQueryParams = filter?.getQueryParams();
return !isEqual(filterQueryParams, Filter.create(defaultFilter).getQueryParams());
})
);
fetching$: Observable<boolean> = this.store.fetching$;
searchboxHint$ = this.store.searchboxHint$;
constructor(private _environment: EnvironmentService) {}
ngOnInit() {}
search(filter: Filter) {
this.store.setQueryParams(filter.getQueryParams());
this.store.fetchList();
}
}

View File

@@ -0,0 +1,7 @@
:host {
@apply block h-split-screen-tablet desktop-small:h-split-screen-desktop;
}
.show-filter {
@apply block;
}

View File

@@ -0,0 +1,6 @@
<div class="hidden desktop-large:block" [class.show-filter]="showFilter">
<page-pickup-shelf-filter (showFilter)="showFilter = false"></page-pickup-shelf-filter>
</div>
<div class="desktop-large:hidden" [class.hidden]="showFilter">
<page-pickup-shelf-in-main-side-view (showFilter)="showFilter = true"></page-pickup-shelf-in-main-side-view>
</div>

View File

@@ -0,0 +1,27 @@
import { ChangeDetectionStrategy, Component, OnInit } from '@angular/core';
import { PickupShelfFilterComponent } from '../../shared/pickup-shelf-filter/pickup-shelf-filter.component';
import { ActivatedRoute } from '@angular/router';
import { PickUpShelfInMainSideViewComponent } from '../pickup-shelf-in-main-side-view/pickup-shelf-in-main-side-view.component';
@Component({
selector: 'page-pickup-shelf-in-main',
templateUrl: 'pickup-shelf-in-main.component.html',
styleUrls: ['pickup-shelf-in-main.component.css'],
changeDetection: ChangeDetectionStrategy.OnPush,
host: { class: 'page-pickup-shelf-in-main' },
standalone: true,
imports: [PickupShelfFilterComponent, PickUpShelfInMainSideViewComponent],
})
export class PickUpShelfInMainComponent implements OnInit {
showFilter: boolean = false;
get sideOutlet() {
return this._activatedRoute?.parent?.children?.find((childRoute) => childRoute?.outlet === 'side')?.snapshot?.routeConfig?.path;
}
constructor(private _activatedRoute: ActivatedRoute) {}
ngOnInit(): void {
this.showFilter = this.sideOutlet !== 'search';
}
}

View File

@@ -1,2 +1,2 @@
<shared-breadcrumb></shared-breadcrumb>
<shared-breadcrumb [key]="pickUpShelfInKey" [tags]="['pickup-shelf']"></shared-breadcrumb>
<shared-splitscreen></shared-splitscreen>

View File

@@ -1,12 +1,18 @@
import { Component, ChangeDetectionStrategy, inject } from '@angular/core';
import { BreadcrumbModule } from '@shared/components/breadcrumb';
import { SharedSplitscreenComponent } from '@shared/components/splitscreen';
import { PickupShelfStore } from '../store';
import { PickupShelfDetailsStore, PickupShelfStore } from '../store';
import { provideComponentStore } from '@ngrx/component-store';
import { PickupShelfIOService, PickupShelfService } from '@domain/pickup-shelf';
import { PickupShelfInNavigationService } from '@shared/services';
import { CoreCommandModule } from '@core/command';
import { PickupShelfIOService, PickupShelfInService } from '@domain/pickup-shelf';
import { NavigationRoute, PickupShelfInNavigationService } from '@shared/services';
import { provideActionHandlers } from '@core/command';
import { ActionHandlerServices } from '@domain/oms';
import { Config } from '@core/config';
import { ActionHandlerService } from '../services/action-handler.service';
import { GetNameForBreadcrumbData, GetPathForBreadcrumbData, PickupShelfBaseComponent } from '../pickup-shelf-base.component';
import { DBHOrderItemListItemDTO } from '@swagger/oms';
import { Observable, of } from 'rxjs';
import { take } from 'rxjs/operators';
@Component({
selector: 'page-pickup-shelf-in',
@@ -18,10 +24,148 @@ import { ActionHandlerServices } from '@domain/oms';
imports: [BreadcrumbModule, SharedSplitscreenComponent],
providers: [
provideComponentStore(PickupShelfStore),
{ provide: PickupShelfIOService, useClass: PickupShelfService },
CoreCommandModule.forChild(ActionHandlerServices).providers,
provideComponentStore(PickupShelfDetailsStore),
{ provide: PickupShelfIOService, useClass: PickupShelfInService },
ActionHandlerService,
provideActionHandlers(ActionHandlerServices),
],
})
export class PickupShelfInComponent /*extends PickupShelfBaseComponent*/ {
export class PickupShelfInComponent extends PickupShelfBaseComponent {
private _pickupShelfInNavigationService = inject(PickupShelfInNavigationService);
get pickUpShelfInKey() {
return this._config.get('process.ids.goodsIn');
}
constructor(private _config: Config) {
super();
}
getNameForMainBreadcrumb(data: { queryParams: Record<string, string> }): string | Promise<string> {
return 'Einbuchen';
}
getPathForMainBreadcrumb(data: { queryParams: Record<string, string> }): NavigationRoute | Promise<NavigationRoute> {
return this._pickupShelfInNavigationService.defaultRoute();
}
getNameForListBreadcrumb(data: GetNameForBreadcrumbData): string | Promise<string> {
if (data.queryParams?.main_qs) {
return data.queryParams.main_qs;
}
return 'Alle';
}
getPathFoListBreadcrumb(data: GetPathForBreadcrumbData): NavigationRoute | Promise<NavigationRoute> {
return this._pickupShelfInNavigationService.listRoute();
}
getNameForFilterBreadcrumb(data: GetNameForBreadcrumbData): string | Promise<string> {
return 'Filter';
}
getPathForFilter(data: GetPathForBreadcrumbData): NavigationRoute | Promise<NavigationRoute> {
return this._pickupShelfInNavigationService.filterRoute();
}
async getNameForDetailBreadcrumb(data: GetNameForBreadcrumbData): Promise<string> {
const compartmentCode = await this.detailsStore.compartmentCode$.pipe(take(1)).toPromise();
if (compartmentCode) {
return compartmentCode;
}
const order = await this.detailsStore.order$.pipe(take(1)).toPromise();
if (order?.orderNumber) {
return order?.orderNumber;
}
return 'Details';
}
async getPathForDetailForDetailBreadcrumb(data: GetPathForBreadcrumbData): Promise<NavigationRoute> {
const compartmentCode = await this.detailsStore.compartmentCode$.pipe(take(1)).toPromise();
const order = await this.detailsStore.order$.pipe(take(1)).toPromise();
const processingStatus = await this.detailsStore.processingStatus$.pipe(take(1)).toPromise();
return this._pickupShelfInNavigationService.detailRoute({
item: {
orderId: order?.id,
compartmentCode,
orderNumber: order?.orderNumber,
processingStatus: processingStatus,
},
});
}
getPathForDetail(item: DBHOrderItemListItemDTO): Observable<NavigationRoute> {
return of(
this._pickupShelfInNavigationService.detailRoute({
item: {
compartmentCode: item.compartmentCode,
orderId: item.orderId,
orderNumber: item.orderNumber,
processingStatus: item.processingStatus,
},
})
);
}
getPathForEdit(item: DBHOrderItemListItemDTO): Observable<NavigationRoute> {
return of(
this._pickupShelfInNavigationService.editRoute({
compartmentCode: item.compartmentCode,
orderId: item.orderId,
orderNumber: item.orderNumber,
processingStatus: item.processingStatus,
})
);
}
async getPathForEditBreadcrumb(data: GetPathForBreadcrumbData): Promise<NavigationRoute> {
const compartmentCode = await this.detailsStore.compartmentCode$.pipe(take(1)).toPromise();
const order = await this.detailsStore.order$.pipe(take(1)).toPromise();
const processingStatus = await this.detailsStore.processingStatus$.pipe(take(1)).toPromise();
return this._pickupShelfInNavigationService.editRoute({
orderId: order?.id,
compartmentCode,
orderNumber: order?.orderNumber,
processingStatus: processingStatus,
});
}
async getNameForEditBreadcrumb(data: GetNameForBreadcrumbData): Promise<string> {
return 'Bearbeiten';
}
getPathForHistory(item: DBHOrderItemListItemDTO): Observable<NavigationRoute> {
return of(
this._pickupShelfInNavigationService.historyRoute({
compartmentCode: item.compartmentCode,
orderId: item.orderId,
orderNumber: item.orderNumber,
processingStatus: item.processingStatus,
})
);
}
async getPathForHistoryBreadcrumb(data: GetPathForBreadcrumbData): Promise<NavigationRoute> {
const compartmentCode = await this.detailsStore.compartmentCode$.pipe(take(1)).toPromise();
const order = await this.detailsStore.order$.pipe(take(1)).toPromise();
const processingStatus = await this.detailsStore.processingStatus$.pipe(take(1)).toPromise();
return this._pickupShelfInNavigationService.historyRoute({
orderId: order?.id,
compartmentCode,
orderNumber: order?.orderNumber,
processingStatus: processingStatus,
});
}
async getNameForHistoryBreadcrumb(data: GetNameForBreadcrumbData): Promise<string> {
return 'Historie';
}
}

View File

@@ -1,9 +1,6 @@
import { NgModule } from '@angular/core';
import { RouterModule } from '@angular/router';
import { routes } from './routes';
import { provideComponentStore } from '@ngrx/component-store';
import { PickupShelfStore } from '../store/pickup-shelf.store';
import { PickupShelfIOService, PickupShelfService } from '@domain/pickup-shelf';
@NgModule({
imports: [RouterModule.forChild(routes)],

View File

@@ -2,18 +2,45 @@ import { Routes } from '@angular/router';
import { PickupShelfInComponent } from './pickup-shelf-in.component';
import { PickupShelfFilterComponent } from '../shared/pickup-shelf-filter/pickup-shelf-filter.component';
import { PickupShelfInDetailsComponent } from './pickup-shelf-in-details/pickup-shelf-in-details.component';
import { viewResolver } from '../resolvers/view.resolver';
import { PickUpShelfHistoryComponent } from '../shared/pickup-shelf-history/pickup-shelf-history.component';
import { PickUpShelfEditComponent } from '../shared/pickup-shelf-edit/pickup-shelf-edit.component';
import { PickUpShelfInMainSideViewComponent } from './pickup-shelf-in-main-side-view/pickup-shelf-in-main-side-view.component';
import { PickUpShelfInMainComponent } from './pickup-shelf-in-main/pickup-shelf-in-main.component';
import { PickUpShelfInListComponent } from './pickup-shelf-in-list/pickup-shelf-in-list.component';
export const routes: Routes = [
{
path: '',
component: PickupShelfInComponent,
resolve: {
view: viewResolver,
},
runGuardsAndResolvers: 'always',
children: [
{ path: '', data: { breadcrumb: 'main' } },
{ path: 'list', data: { breadcrumb: 'list' } },
{ path: 'list/filter', component: PickupShelfFilterComponent, data: { breadcrumb: 'filter' } },
{ path: 'order/:orderId/:orderItemId', component: PickupShelfInDetailsComponent, data: { breadcrumb: 'details' } },
// { path: 'main', outlet: 'side' },
// { path: 'list', outlet: 'side' },
{ path: 'main', component: PickUpShelfInMainComponent, data: { view: 'main' } },
{ path: 'list', component: PickUpShelfInListComponent, data: { view: 'list' } },
{ path: 'list/filter', component: PickupShelfFilterComponent, data: { view: 'filter' } },
{
path: 'order/:orderId/:orderNumber/item/status/:orderItemProcessingStatus',
component: PickupShelfInDetailsComponent,
data: { view: 'details' },
},
{ path: 'order/:orderId/compartment/:compartmentCode', component: PickupShelfInDetailsComponent, data: { view: 'details' } },
{
path: 'order/:orderId/:orderNumber/item/status/:orderItemProcessingStatus/edit',
component: PickUpShelfEditComponent,
data: { view: 'edit' },
},
{ path: 'order/:orderId/compartment/:compartmentCode/edit', component: PickUpShelfEditComponent, data: { view: 'edit' } },
{
path: 'order/:orderId/:orderNumber/item/status/:orderItemProcessingStatus/history',
component: PickUpShelfHistoryComponent,
data: { view: 'history' },
},
{ path: 'order/:orderId/compartment/:compartmentCode/history', component: PickUpShelfHistoryComponent, data: { view: 'history' } },
{ path: 'search', component: PickUpShelfInMainSideViewComponent, outlet: 'side' },
{ path: 'list', component: PickUpShelfInListComponent, data: { view: 'list' }, outlet: 'side' },
],
},
];

View File

@@ -2,7 +2,7 @@
@apply block bg-white h-split-screen-tablet desktop-small:h-split-screen-desktop;
}
.page-search-main__filter:active {
.page-pickup-shelf-out-main__filter:active {
@apply bg-[#596470] text-white;
}

View File

@@ -2,16 +2,20 @@ import { Injectable, inject } from '@angular/core';
import { NavigationRoute } from './navigation-route';
import { Router } from '@angular/router';
import { Config } from '@core/config';
import { DBHOrderItemListItemDTO } from '@swagger/oms';
import { DBHOrderItemListItemDTO, OrderItemProcessingStatusValue } from '@swagger/oms';
@Injectable({ providedIn: 'root' })
export class PickupShelfInNavigationService {
private readonly _router = inject(Router);
private readonly _config = inject(Config);
// private readonly _config = inject(Config);
// private get _processId() {
// return this._config.get('process.ids.goodsIn');
// }
defaultRoute(): NavigationRoute {
const path = ['/filiale', 'pickup-shelf'].filter((v) => !!v);
const path = ['/filiale', 'pickup-shelf', { outlets: { primary: ['main'], side: ['search'] } }].filter((v) => !!v);
const queryParams = {};
@@ -25,7 +29,7 @@ export class PickupShelfInNavigationService {
}
listRoute(): NavigationRoute {
const path = ['/filiale', 'pickup-shelf', 'list'].filter((v) => !!v);
const path = ['/filiale', 'pickup-shelf', { outlets: { primary: ['list'], side: null } }].filter((v) => !!v);
const queryParams = {};
@@ -39,7 +43,7 @@ export class PickupShelfInNavigationService {
}
filterRoute(): NavigationRoute {
const path = ['/filiale', 'pickup-shelf', 'list', 'filter'].filter((v) => !!v);
const path = ['/filiale', 'pickup-shelf', { outlets: { primary: ['list', 'filter'], side: ['list'] } }].filter((v) => !!v);
const queryParams = {};
@@ -53,7 +57,129 @@ export class PickupShelfInNavigationService {
}
detailRoute({ item }: { item: DBHOrderItemListItemDTO }): NavigationRoute {
const path = ['/filiale', 'pickup-shelf', 'order', item.orderId, item.orderItemId].filter((v) => !!v);
let path: any[];
if (item.compartmentCode) {
path = [
'/filiale',
'pickup-shelf',
{
outlets: {
primary: ['order', item.orderId, 'compartment', encodeURIComponent(item.compartmentCode)].filter((v) => !!v),
side: ['list'],
},
},
].filter((v) => !!v);
} else {
path = [
'/filiale',
'pickup-shelf',
{
outlets: {
primary: ['order', item.orderId, encodeURIComponent(item.orderNumber), 'item', 'status', item.processingStatus].filter(
(v) => !!v
),
side: ['list'],
},
},
].filter((v) => !!v);
}
const queryParams = {};
const urlTree = this._router.createUrlTree(path, { queryParams });
return {
path,
queryParams,
urlTree,
};
}
editRoute(item: {
orderId: number;
orderNumber: string;
compartmentCode: string;
processingStatus: OrderItemProcessingStatusValue;
}): NavigationRoute {
let path: any[];
if (item.compartmentCode) {
path = [
'/filiale',
'pickup-shelf',
{
outlets: {
primary: ['order', item.orderId, 'compartment', encodeURIComponent(item.compartmentCode), 'edit'].filter((v) => !!v),
side: ['list'],
},
},
].filter((v) => !!v);
} else {
path = [
'/filiale',
'pickup-shelf',
{
outlets: {
primary: ['order', item.orderId, encodeURIComponent(item.orderNumber), 'item', 'status', item.processingStatus, 'edit'].filter(
(v) => !!v
),
side: ['list'],
},
},
].filter((v) => !!v);
}
const queryParams = {};
const urlTree = this._router.createUrlTree(path, { queryParams });
return {
path,
queryParams,
urlTree,
};
}
historyRoute(item: {
orderId: number;
orderNumber: string;
compartmentCode: string;
processingStatus: OrderItemProcessingStatusValue;
}): NavigationRoute {
let path: any[];
if (item.compartmentCode) {
path = [
'/filiale',
'pickup-shelf',
{
outlets: {
primary: ['order', item.orderId, 'compartment', encodeURIComponent(item.compartmentCode), 'history'].filter((v) => !!v),
side: ['list'],
},
},
].filter((v) => !!v);
} else {
path = [
'/filiale',
'pickup-shelf',
{
outlets: {
primary: [
'order',
item.orderId,
encodeURIComponent(item.orderNumber),
'item',
'status',
item.processingStatus,
'history',
].filter((v) => !!v),
side: ['list'],
},
},
].filter((v) => !!v);
}
const queryParams = {};

View File

@@ -141,9 +141,9 @@
<a
class="side-menu-group-item"
(click)="closeSideMenu(); focusSearchBox()"
*ngIf="goodsInNavigation$ | async; let goodsInNavigation"
[routerLink]="goodsInNavigation.path"
[queryParams]="goodsInNavigation.queryParams"
*ngIf="pickUpShelfInRoutePath$ | async; let pickUpShelfInNavigation"
[routerLink]="pickUpShelfInNavigation.path"
[queryParams]="pickUpShelfInNavigation.queryParams"
routerLinkActive="active"
>
<span class="side-menu-group-item-icon">
@@ -164,8 +164,10 @@
<div class="side-menu-group-sub-items" [class.hidden]="!goodsInExpanded">
<a
class="side-menu-group-item"
*ngIf="pickUpShelfInListRoutePath$ | async; let pickUpShelfInListNavigation"
(click)="closeSideMenu(); focusSearchBox()"
[routerLink]="['/filiale', 'goods', 'in', 'results']"
[routerLink]="pickUpShelfInListNavigation.path"
[queryParams]="pickUpShelfInListNavigation.queryParams"
routerLinkActive="active"
>
<span class="side-menu-group-item-icon"></span>

View File

@@ -13,6 +13,7 @@ import {
ProductCatalogNavigationService,
CustomerCreateNavigation,
PickUpShelfOutNavigationService,
PickupShelfInNavigationService,
} from '@shared/services';
import { CommonModule, DOCUMENT } from '@angular/common';
import { Config } from '@core/config';
@@ -115,8 +116,13 @@ export class ShellSideMenuComponent {
queryParams: {},
});
goodsInNavigation$ = this.getLastNavigationByProcessId(this._config.get('process.ids.goodsIn'), {
path: ['/filiale', 'goods', 'in'],
pickUpShelfInRoutePath$ = this.getLastNavigationByProcessId(this._config.get('process.ids.goodsIn'), {
path: this._pickUpShelfInNavigation.defaultRoute().path,
queryParams: {},
});
pickUpShelfInListRoutePath$ = this.getLastNavigationByProcessId(this._config.get('process.ids.goodsIn'), {
path: this._pickUpShelfInNavigation.listRoute().path,
queryParams: {},
});
@@ -148,6 +154,7 @@ export class ShellSideMenuComponent {
private _customerSearchNavigation: CustomerSearchNavigation,
private _customerCreateNavigation: CustomerCreateNavigation,
private _pickUpShelfOutNavigation: PickUpShelfOutNavigationService,
private _pickUpShelfInNavigation: PickupShelfInNavigationService,
@Inject(DOCUMENT) private readonly _document: Document
) {}