Merge branch 'release/3.0' into develop

This commit is contained in:
Nino
2024-01-03 11:52:25 +01:00
11 changed files with 78 additions and 95 deletions

View File

@@ -6,12 +6,10 @@ import { ArticleSearchComponent } from './article-search.component';
import { SearchResultsModule } from './search-results/search-results.module';
import { SearchMainModule } from './search-main/search-main.module';
import { SearchFilterModule } from './search-filter/search-filter.module';
import { ArticleSearchService } from './article-search.store';
@NgModule({
imports: [CommonModule, RouterModule, UiIconModule, SearchResultsModule, SearchMainModule, SearchFilterModule],
exports: [ArticleSearchComponent],
declarations: [ArticleSearchComponent],
providers: [ArticleSearchService],
})
export class ArticleSearchModule {}

View File

@@ -48,7 +48,7 @@
</div>
<ng-container *ngIf="primaryOutletActive$ | async; else sideOutlet">
<cdk-virtual-scroll-viewport class="product-list" [itemSize]="106 * (scale$ | async)" (scrolledIndexChange)="scrolledIndexChange($event)">
<cdk-virtual-scroll-viewport class="product-list" [itemSize]="103 * (scale$ | async)" (scrolledIndexChange)="scrolledIndexChange($event)">
<a
*cdkVirtualFor="let item of results$ | async; let i = index; trackBy: trackByItemId"
[routerLink]="getDetailsPath(item.id)"
@@ -82,7 +82,7 @@
</ng-container>
<ng-template #sideOutlet>
<cdk-virtual-scroll-viewport class="product-list" [itemSize]="222 * (scale$ | async)" (scrolledIndexChange)="scrolledIndexChange($event)">
<cdk-virtual-scroll-viewport class="product-list" [itemSize]="191 * (scale$ | async)" (scrolledIndexChange)="scrolledIndexChange($event)">
<a
*cdkVirtualFor="let item of results$ | async; let i = index; trackBy: trackByItemId"
[routerLink]="getDetailsPath(item.id)"

View File

@@ -11,12 +11,14 @@ import { combineLatest, fromEvent, Observable, Subject } from 'rxjs';
import { first, map, switchMap, takeUntil, withLatestFrom } from 'rxjs/operators';
import { ActionsSubject } from '@ngrx/store';
import { DomainAvailabilityService } from '@domain/availability';
import { provideComponentStore } from '@ngrx/component-store';
import { ArticleSearchService } from './article-search/article-search.store';
@Component({
selector: 'page-catalog',
templateUrl: 'page-catalog.component.html',
styleUrls: ['page-catalog.component.scss'],
providers: [],
providers: [provideComponentStore(ArticleSearchService)],
changeDetection: ChangeDetectionStrategy.OnPush,
})
export class PageCatalogComponent implements OnInit, AfterViewInit, OnDestroy {

View File

@@ -1,58 +0,0 @@
import { Directive, HostListener, Input, Output, EventEmitter, OnInit } from '@angular/core';
import { BranchDTO } from '@swagger/checkout';
import { PurchasingOptionsModalStore } from '../../modals/purchasing-options-modal/purchasing-options-modal.store';
/* tslint:disable: directive-selector */
@Directive({ selector: '[keyNavigation]' })
export class KeyNavigationDirective implements OnInit {
@Input() element: any;
@Input('keyNavigation') data: BranchDTO[];
@Output() closeDropdown = new EventEmitter<void>();
@Output() preselectBranch = new EventEmitter<BranchDTO>();
selectedData: BranchDTO;
position = 0;
posMarker = 0;
@HostListener('window:keyup', ['$event'])
keyEvent(event: KeyboardEvent) {
if (event.key === 'ArrowUp') {
if (this.position > 0) {
this.position--;
}
if (this.position <= this.posMarker - 4) {
this.element.scrollTop -= 44;
}
this.selectedData = this.data[this.position];
this.preselectBranch.emit(this.selectedData);
}
if (event.key === 'ArrowDown') {
if (this.position < this.data.length - 1) {
this.position++;
}
if (this.position >= 4) {
this.posMarker = this.position;
this.element.scrollTop += 44;
}
this.selectedData = this.data[this.position];
this.preselectBranch.emit(this.selectedData);
}
if (event.key === 'Enter') {
this.purchasingOptionsModalStore.setBranch(this.selectedData);
this.position = 0;
this.closeDropdown.emit();
}
}
constructor(private purchasingOptionsModalStore: PurchasingOptionsModalStore) {}
ngOnInit() {
this.selectedData = this.data[this.position];
this.preselectBranch.emit(this.selectedData);
}
}

View File

@@ -1,12 +0,0 @@
import { CommonModule } from '@angular/common';
import { NgModule } from '@angular/core';
import { KeyNavigationDirective } from './key-navigation.directive';
@NgModule({
imports: [CommonModule],
exports: [KeyNavigationDirective],
declarations: [KeyNavigationDirective],
providers: [],
})
export class KeyNavigationModule {}

View File

@@ -3,6 +3,7 @@ import { ActivatedRoute } from '@angular/router';
import { ApplicationService } from '@core/application';
import { AuthService } from '@core/auth';
import { EnvironmentService } from '@core/environment';
import { provideComponentStore } from '@ngrx/component-store';
import { BranchSelectorComponent } from '@shared/components/branch-selector';
import { BreadcrumbComponent } from '@shared/components/breadcrumb';
import { BranchDTO } from '@swagger/checkout';
@@ -16,7 +17,7 @@ import { CustomerOrderSearchStore } from './customer-order-search';
templateUrl: 'customer-order.component.html',
styleUrls: ['customer-order.component.scss'],
changeDetection: ChangeDetectionStrategy.OnPush,
providers: [CustomerOrderSearchStore],
providers: [provideComponentStore(CustomerOrderSearchStore)],
})
export class CustomerOrderComponent implements OnInit {
@ViewChild(BreadcrumbComponent, { read: ElementRef }) breadcrumbRef: ElementRef<HTMLElement>;

View File

@@ -126,7 +126,7 @@ export abstract class PickupShelfBaseComponent implements OnInit {
// Only Update QueryParams if the user is already on the details, edit or history page
const view: string = this.activatedRoute.snapshot.data.view;
if (['details', 'edit', 'history'].includes(view)) {
if (['filter', 'details', 'edit', 'history'].includes(view)) {
await this.router.navigate([], { queryParams: { ...queryParams, ...filterQueryParams }, skipLocationChange: true });
return;
}

View File

@@ -18,7 +18,7 @@ import { PickUpShelfListItemComponent } from '../../shared/pickup-shelf-list-ite
import { Group, GroupByPipe } from '@ui/common';
import { UiSpinnerModule } from '@ui/spinner';
import { PickupShelfInNavigationService } from '@shared/services';
import { debounceTime, map } from 'rxjs/operators';
import { map } from 'rxjs/operators';
import { DBHOrderItemListItemDTO } from '@swagger/oms';
import { Observable, combineLatest, of } from 'rxjs';
import { PickupShelfDetailsStore, PickupShelfStore } from '../../store';
@@ -124,7 +124,8 @@ export class PickUpShelfInListComponent implements OnInit, AfterViewInit {
combineLatest([this.store.processId$, this._activatedRoute.queryParams])
.pipe(takeUntilDestroyed(this.destroyRef))
.subscribe(([_, queryParams]) => {
if (!this.store.list.length || !isEqual(queryParams, this.store.filter.getQueryParams())) {
if (!this.store.list.length || !isEqual(queryParams, this.cleanupQueryParams(this.store.filter.getQueryParams()))) {
this.store.setQueryParams(queryParams);
this.store.fetchList();
}
@@ -148,6 +149,20 @@ export class PickUpShelfInListComponent implements OnInit, AfterViewInit {
this.scrollItemIntoView();
}
cleanupQueryParams(params: Record<string, string> = {}) {
const clean = { ...params };
for (const key in clean) {
if (Object.prototype.hasOwnProperty.call(clean, key)) {
if (clean[key] == undefined) {
delete clean[key];
}
}
}
return clean;
}
private _removeScrollPositionFromCache(): void {
this._cache.delete({ processId: this.store.processId, token: this.SCROLL_POSITION_TOKEN });
}

View File

@@ -100,11 +100,11 @@ export class SharedNotificationChannelControlComponent extends ComponentStore<Sh
}
showChannelActionNameForEmailControl() {
return !!this.channelActionName && this.emailControl?.dirty;
return (!!this.channelActionName && this.emailControl?.dirty) || this.showSendAgainActionForEmail();
}
showChannelActionNameForMobileControl() {
return !!this.channelActionName && this.mobileControl?.dirty;
return (!!this.channelActionName && this.mobileControl?.dirty) || this.showSendAgainActionForMobile();
}
clear(control: FormControl) {
@@ -142,7 +142,7 @@ export class SharedNotificationChannelControlComponent extends ComponentStore<Sh
}
setNotificationChannels(notificationChannels: NotificationChannel[]) {
const notificationChannel = notificationChannels.reduce((val, current) => val | current, 0) as NotificationChannel;
const notificationChannel = this.getNotificationChannel(notificationChannels);
this.notificationChannelControl.setValue(notificationChannel);
this.notificationChannelControl.markAsDirty();
if (this.communicationDetails) {
@@ -150,6 +150,24 @@ export class SharedNotificationChannelControlComponent extends ComponentStore<Sh
}
}
getNotificationChannel(notificationChannels?: NotificationChannel[]) {
let nfc = notificationChannels ?? this.notificationChannels;
return nfc.reduce((val, current) => val | current, 0) as NotificationChannel;
}
// Ticket #4526 RD // Bearbeiten - erneut senden Button fehlt
// Auf den Pickup Shelf Edit Seiten soll der Erneut senden button immer ersichtlich sein
showSendAgainActionForEmail() {
return this.channelActionName === 'Erneut senden' && (this.getNotificationChannel() as Number) !== 3;
}
// Ticket #4526 RD // Bearbeiten - erneut senden Button fehlt
// Auf den Pickup Shelf Edit Seiten soll der Erneut senden button immer ersichtlich sein
// Wenn die Felder Email und SMS angehakt wurden, soll der Button nur einmal angezeigt werden
showSendAgainActionForMobile() {
return this.channelActionName === 'Erneut senden' && (this.getNotificationChannel() === 2 || this.getNotificationChannel() !== 1);
}
toggle(value?: boolean) {
this.patchState({ open: value ?? !this.get((s) => s.open) });
}

View File

@@ -107,10 +107,14 @@ export class ShellSideMenuComponent {
})
);
taskCalenderNavigation$ = this.getLastNavigationByProcessId(this._config.get('process.ids.taskCalendar'), {
path: ['/filiale', 'task-calendar'],
queryParams: {},
});
taskCalenderNavigation$ = this.getLastNavigationByProcessId(
this._config.get('process.ids.taskCalendar'),
{
path: ['/filiale', 'task-calendar'],
queryParams: {},
},
'/filiale/task-calendar'
);
assortmentNavigation$ = this.getLastNavigationByProcessId(this._config.get('process.ids.assortment'), {
path: ['/filiale', 'assortment'],
@@ -119,7 +123,8 @@ export class ShellSideMenuComponent {
pickUpShelfInRoutePath$ = this.getLastNavigationByProcessId(
this._config.get('process.ids.pickupShelf'),
this._pickUpShelfInNavigation.defaultRoute()
this._pickUpShelfInNavigation.defaultRoute(),
'/filiale/pickup-shelf'
);
// #4478 - RD // Abholfach - Routing löst Suche aus
@@ -188,10 +193,24 @@ export class ShellSideMenuComponent {
this._cdr.markForCheck();
}
getLastNavigationByProcessId(id: number, fallback?: { path: string[]; queryParams: any }) {
getLastNavigationByProcessId(id: number, fallback?: { path: string[]; queryParams: any }, pathContainsString?: string) {
return this._breadcrumbService.getBreadcrumbByKey$(id)?.pipe(
map((breadcrumbs) => {
const lastCrumb = breadcrumbs
.filter((breadcrumb) => {
/**
* #4532 - Der optionale Filter wurde hinzugefügt Breadcrumbs mit fehlerhaften Pfad auszuschließen.
* Dieser Filter kann entfernt werden, sobald die Breadcrumbs korrekt gesetzt werden. Jedoch konnte man bisher nicht feststellen,
* woher die fehlerhaften Breadcrumbs kommen.
*/
if (!pathContainsString) {
// Wenn kein Filter gesetzt ist, dann wird der letzte Breadcrumb zurückgegeben
return true;
}
const pathStr = Array.isArray(breadcrumb.path) ? breadcrumb.path.join('/') : breadcrumb.path;
return pathStr.includes(pathContainsString);
})
.filter((breadcrumb) => !breadcrumb?.params?.hasOwnProperty('view'))
.filter((breadcrumb) => !breadcrumb?.tags?.includes('reservation'))
.filter((breadcrumb) => !breadcrumb?.tags?.includes('cleanup'))

View File

@@ -5,10 +5,10 @@
"ng": "ng",
"start": "ng serve isa-app --ssl",
"test": "npm-run-all --serial \"test:* -- --watch=false --browsers=ChromeHeadlessNoSandbox --code-coverage\" --continue-on-error --print-label",
"test:isa-app": "ng test isa-app",
"*test:isa-app": "ng test isa-app",
"test:adapter-scan": "ng test @adapter/scan",
"test:cdn-product-image": "ng test @cdn/product-image",
"test:core": "ng test core",
"*test:core": "ng test core",
"*test:domain-availability": "ng test @domain/availability",
"*test:domain-cart": "ng test @domain/cart",
"*test:domain-catalog": "ng test @domain/catalog",
@@ -19,22 +19,22 @@
"*test:domain-oms": "ng test @domain/oms",
"*test:domain-package-inspection": "ng test @domain/package-inspection",
"*test:domain-printer": "ng test @domain/printer",
"test:domain-remission": "ng test @domain/remission",
"*test:domain-remission": "ng test @domain/remission",
"*test:domain-task-calendar": "ng test @domain/task-calendar",
"test:external": "ng test external",
"*test:hub-notifications": "ng test @hub/notifications",
"*test:isa-remission": "ng test @isa/remission",
"*test:modal-availabilities": "ng test @modal/availabilities",
"test:modal-history": "ng test @modal/history",
"*test:modal-history": "ng test @modal/history",
"*test:modal-images": "ng test @modal/images",
"test:modal-notifications": "ng test @modal/notifications",
"*test:modal-printer": "ng test @modal/printer",
"*test:modal-reorder": "ng test @modal/reorder",
"*test:modal-reviews": "ng test @modal/reviews",
"test:page": "ng test page",
"test:shared": "ng test shared",
"*test:page": "ng test page",
"*test:shared": "ng test shared",
"*test:shell-breadcrumb": "ng test @shell/breadcrumb",
"test:store-search-component-store": "ng test @store/search-component-store",
"*test:store-search-component-store": "ng test @store/search-component-store",
"*test:ui": "ng test ui",
"*test:utils": "ng test utils",
"*test:native-container": "ng test native-container",