mirror of
https://dev.azure.com/hugendubel/ISA/_git/ISA-Frontend
synced 2025-12-28 22:42:11 +01:00
Merge branch 'develop' of https://dev.azure.com/hugendubel/ISA/_git/ISA-Frontend into develop
This commit is contained in:
@@ -151,7 +151,13 @@
|
||||
<button *ngIf="!(store.isDownload$ | async)" class="cta-availabilities" (click)="showAvailabilities()">
|
||||
weitere Verfügbarkeiten
|
||||
</button>
|
||||
<button class="cta-continue" (click)="showPurchasingModal()" [disabled]="fetchingAvailabilities$ | async">In den Warenkorb</button>
|
||||
<button
|
||||
class="cta-continue"
|
||||
(click)="showPurchasingModal()"
|
||||
[disabled]="!(isAvailable$ | async) || (fetchingAvailabilities$ | async)"
|
||||
>
|
||||
In den Warenkorb
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div class="product-formats" *ngIf="item.family?.length > 0">
|
||||
|
||||
@@ -39,6 +39,14 @@ export class ArticleDetailsComponent implements OnInit, OnDestroy {
|
||||
this.store.fetchingTakeAwayAvailability$,
|
||||
]).pipe(map((values) => values.some((v) => v)));
|
||||
|
||||
isAvailable$ = combineLatest([
|
||||
this.store.isDeliveryAvailabilityAvailable$,
|
||||
this.store.isDeliveryDigAvailabilityAvailable$,
|
||||
this.store.isDeliveryB2BAvailabilityAvailable$,
|
||||
this.store.isPickUpAvailabilityAvailable$,
|
||||
this.store.isTakeAwayAvailabilityAvailable$,
|
||||
]).pipe(map((values) => values.some((v) => v)));
|
||||
|
||||
showDeliveryTruck$ = combineLatest([this.store.isDeliveryAvailabilityAvailable$, this.store.isDeliveryDigAvailabilityAvailable$]).pipe(
|
||||
map(([delivery, digDelivery]) => delivery || digDelivery)
|
||||
);
|
||||
|
||||
@@ -69,7 +69,7 @@ export class ArticleSearchResultsComponent implements OnInit, OnDestroy {
|
||||
this.scrollTop(Number(queryParams.scrollPos ?? 0));
|
||||
|
||||
// Fügt Breadcrumb hinzu falls dieser noch nicht vorhanden ist
|
||||
this.breadcrumb.addBreadcrumbIfNotExists({
|
||||
await this.breadcrumb.addBreadcrumbIfNotExists({
|
||||
key: processId,
|
||||
name: `${this.store.query} (Lade Ergebnisse)`,
|
||||
path: '/product/search/results',
|
||||
|
||||
@@ -233,6 +233,7 @@ export class CustomerCreateOnlineComponent extends CustomerCreateComponentBase i
|
||||
} catch (error) {
|
||||
if (error?.error?.invalidProperties?.Email) {
|
||||
this.addInvalidDomain(this.control.value.communicationDetails?.email);
|
||||
this.enableControl();
|
||||
} else {
|
||||
this.setValidationError(error.error?.invalidProperties, this.control);
|
||||
}
|
||||
|
||||
@@ -1,41 +0,0 @@
|
||||
import { ActivatedRoute } from '@angular/router';
|
||||
import { StringDictionary } from '@cmf/core';
|
||||
import { isEqual } from 'lodash';
|
||||
import { Subscription } from 'rxjs';
|
||||
import { finalize } from 'rxjs/operators';
|
||||
|
||||
export abstract class ActivatedRouteConnector {
|
||||
private connectedRouteSubscription: Subscription;
|
||||
|
||||
connect(route: ActivatedRoute, options?: { connected?: (params: StringDictionary<string>) => void; disconnected?: () => void }) {
|
||||
this.disconnect();
|
||||
let connected = false;
|
||||
|
||||
this.connectedRouteSubscription = route.queryParams.pipe(finalize(() => options?.disconnected?.call(undefined))).subscribe((params) => {
|
||||
const current = this.getQueryParams();
|
||||
|
||||
if (!isEqual(current, params)) {
|
||||
this.setQueryParams({ params });
|
||||
}
|
||||
|
||||
if (!connected) {
|
||||
connected = true;
|
||||
setTimeout(() => options?.connected?.call(undefined, params), 0);
|
||||
}
|
||||
});
|
||||
|
||||
return {
|
||||
disconnect: () => {
|
||||
this.disconnect();
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
disconnect() {
|
||||
this.connectedRouteSubscription?.unsubscribe();
|
||||
}
|
||||
|
||||
abstract setQueryParams({ params }: { params: StringDictionary<string> }): void;
|
||||
|
||||
abstract getQueryParams(): StringDictionary<string>;
|
||||
}
|
||||
@@ -1,18 +1,15 @@
|
||||
import { Component, ChangeDetectionStrategy, forwardRef, NgZone, OnInit } from '@angular/core';
|
||||
import { ActivatedRoute, Router } from '@angular/router';
|
||||
import { Location } from '@angular/common';
|
||||
import { ApplicationService } from '@core/application';
|
||||
import { BreadcrumbService } from '@core/breadcrumb';
|
||||
import { EnvironmentService } from '@core/environment';
|
||||
import { CrmCustomerService } from '@domain/crm';
|
||||
import { FilterOption, SelectFilterOption, UiFilterMappingService } from '@ui/filter';
|
||||
import { FilterOption, UiFilterMappingService } from '@ui/filter';
|
||||
import { NativeContainerService } from 'native-container';
|
||||
import { BehaviorSubject, Observable, of } from 'rxjs';
|
||||
import { delay, map, switchMap } from 'rxjs/operators';
|
||||
import { CustomerSearch } from './customer-search.service';
|
||||
import { isSelectFilterOption } from 'apps/ui/filter/src/lib/type-guards';
|
||||
import { CacheService } from 'apps/core/cache/src/public-api';
|
||||
import { StringDictionary } from '@cmf/core';
|
||||
|
||||
@Component({
|
||||
selector: 'page-customer-search',
|
||||
|
||||
@@ -13,16 +13,25 @@ import { NativeContainerService } from 'native-container';
|
||||
import { StringDictionary } from '@cmf/core';
|
||||
import { ApplicationService } from '@core/application';
|
||||
import { BreadcrumbService } from '@core/breadcrumb';
|
||||
import { ActivatedRouteConnector } from './activated-route-connector';
|
||||
|
||||
@Injectable()
|
||||
export abstract class CustomerSearch extends ActivatedRouteConnector implements OnInit, OnDestroy {
|
||||
export abstract class CustomerSearch implements OnInit, OnDestroy {
|
||||
protected abstract customerSearch: CrmCustomerService;
|
||||
|
||||
private queryParams: StringDictionary<string> = this.route.snapshot.queryParams;
|
||||
private queryParams: StringDictionary<string>;
|
||||
|
||||
private destroy$ = new Subject();
|
||||
|
||||
private _processId: number;
|
||||
|
||||
get processId(): number {
|
||||
return this._processId;
|
||||
}
|
||||
|
||||
set processId(processId: number) {
|
||||
this._processId = processId;
|
||||
}
|
||||
|
||||
filtersLoaded$ = new BehaviorSubject<boolean>(false);
|
||||
|
||||
initQueryFilter$ = new BehaviorSubject<{ initialFilter: Filter[] }>({
|
||||
@@ -64,6 +73,8 @@ export abstract class CustomerSearch extends ActivatedRouteConnector implements
|
||||
return this.searchState$.value;
|
||||
}
|
||||
|
||||
hits$ = new BehaviorSubject<number>(undefined);
|
||||
|
||||
get searchResult(): PagedResult<CustomerSearchType> {
|
||||
return this.searchResult$.value;
|
||||
}
|
||||
@@ -76,7 +87,7 @@ export abstract class CustomerSearch extends ActivatedRouteConnector implements
|
||||
return this.searchResult$.value.result.length;
|
||||
}
|
||||
|
||||
private get totalResults(): number {
|
||||
public get totalResults(): number {
|
||||
if (!this.searchResult$ || !this.searchResult$.value || !this.searchResult$.value.hits) {
|
||||
return 0;
|
||||
}
|
||||
@@ -93,9 +104,7 @@ export abstract class CustomerSearch extends ActivatedRouteConnector implements
|
||||
private environmentService: EnvironmentService,
|
||||
private filterMapping: UiFilterMappingService,
|
||||
private nativeContainer: NativeContainerService
|
||||
) {
|
||||
super();
|
||||
}
|
||||
) {}
|
||||
|
||||
ngOnInit() {
|
||||
this.initAvailableFilters();
|
||||
@@ -110,21 +119,21 @@ export abstract class CustomerSearch extends ActivatedRouteConnector implements
|
||||
|
||||
setQueryParams({ params }: { params: StringDictionary<string> }): void {
|
||||
this.queryParams = params;
|
||||
this.parseQueryParams();
|
||||
}
|
||||
|
||||
getQueryParams(): StringDictionary<string> {
|
||||
return this.queryParams;
|
||||
return this.queryParams || {};
|
||||
}
|
||||
|
||||
parseQueryParams() {
|
||||
const params = new URL(this.router.url, window.location.origin).searchParams;
|
||||
const params = this.getQueryParams();
|
||||
|
||||
this.setQuery(params.get('query'));
|
||||
this.setQuery(params.query);
|
||||
|
||||
const filters = this.queryFilter.filters.map(cloneFilter);
|
||||
|
||||
filters.forEach((f) => {
|
||||
const values = params.get(String(f.key))?.split(';');
|
||||
const values = params[f.key]?.split(';');
|
||||
|
||||
if (values?.length > 0) {
|
||||
f.options.forEach((o) => {
|
||||
@@ -136,7 +145,6 @@ export abstract class CustomerSearch extends ActivatedRouteConnector implements
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
this.setFilter(filters);
|
||||
}
|
||||
|
||||
@@ -240,7 +248,6 @@ export abstract class CustomerSearch extends ActivatedRouteConnector implements
|
||||
dict[filter.key] = selected.map((o) => o.id).join(';');
|
||||
}
|
||||
}
|
||||
|
||||
return dict;
|
||||
}
|
||||
|
||||
@@ -255,7 +262,6 @@ export abstract class CustomerSearch extends ActivatedRouteConnector implements
|
||||
}
|
||||
if (this.searchState !== 'fetching') {
|
||||
this.searchState$.next('fetching');
|
||||
|
||||
this.searchResult$
|
||||
.pipe(
|
||||
take(1),
|
||||
@@ -301,7 +307,7 @@ export abstract class CustomerSearch extends ActivatedRouteConnector implements
|
||||
)
|
||||
.subscribe((r) => {
|
||||
const hits = r.hits || r.result.length;
|
||||
|
||||
this.hits$.next(hits);
|
||||
this.searchResult$.next(this.removeLoadingProducts(this.searchResult));
|
||||
if (options.isNewSearch) {
|
||||
this.searchResult$.next({
|
||||
@@ -325,6 +331,7 @@ export abstract class CustomerSearch extends ActivatedRouteConnector implements
|
||||
}
|
||||
|
||||
if (hits > 0) {
|
||||
this.searchState$.next('result');
|
||||
this.filterActive$.next(false);
|
||||
}
|
||||
});
|
||||
@@ -384,7 +391,7 @@ export abstract class CustomerSearch extends ActivatedRouteConnector implements
|
||||
)
|
||||
.subscribe((r) => {
|
||||
const hits = r.hits || r.result.length;
|
||||
|
||||
this.hits$.next(hits);
|
||||
this.searchResult$.next(this.removeLoadingProducts(this.searchResult));
|
||||
if (options.isNewSearch) {
|
||||
this.searchResult$.next({
|
||||
@@ -408,6 +415,7 @@ export abstract class CustomerSearch extends ActivatedRouteConnector implements
|
||||
}
|
||||
|
||||
if (hits > 0) {
|
||||
this.searchState$.next('result');
|
||||
this.filterActive$.next(false);
|
||||
}
|
||||
});
|
||||
@@ -463,9 +471,10 @@ export abstract class CustomerSearch extends ActivatedRouteConnector implements
|
||||
currentResult: PagedResult<CustomerSearchType>,
|
||||
numberOfLoadingProducts: number = 10
|
||||
): PagedResult<CustomerSearchType> {
|
||||
const res = currentResult.result ? currentResult.result : [];
|
||||
return {
|
||||
...currentResult,
|
||||
result: [...currentResult.result, ...new Array(numberOfLoadingProducts).fill({ loaded: false })],
|
||||
result: [...res, ...new Array(numberOfLoadingProducts).fill({ loaded: false })],
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -3,9 +3,9 @@ import { ActivatedRoute } from '@angular/router';
|
||||
import { ApplicationService } from '@core/application';
|
||||
import { BreadcrumbService } from '@core/breadcrumb';
|
||||
import { EnvironmentService } from '@core/environment';
|
||||
import { CacheService } from 'apps/core/cache/src/public-api';
|
||||
import { Subject } from 'rxjs';
|
||||
import { takeUntil } from 'rxjs/operators';
|
||||
import { isEqual } from 'lodash';
|
||||
import { combineLatest, Subject, Subscription } from 'rxjs';
|
||||
import { debounceTime, first } from 'rxjs/operators';
|
||||
import { CustomerSearch } from '../customer-search.service';
|
||||
|
||||
@Component({
|
||||
@@ -19,38 +19,51 @@ export class CustomerSearchMainComponent implements OnInit, OnDestroy {
|
||||
|
||||
protected isMobile: boolean;
|
||||
|
||||
subscriptions = new Subscription();
|
||||
|
||||
constructor(
|
||||
public search: CustomerSearch,
|
||||
public cdr: ChangeDetectorRef,
|
||||
public environmentService: EnvironmentService,
|
||||
public application: ApplicationService,
|
||||
private breadcrumb: BreadcrumbService,
|
||||
private route: ActivatedRoute,
|
||||
private cache: CacheService
|
||||
private route: ActivatedRoute
|
||||
) {}
|
||||
|
||||
ngOnInit() {
|
||||
this.detectDevice();
|
||||
this.initBreadcrumb();
|
||||
this.search.connect(this.route);
|
||||
}
|
||||
this.subscriptions.add(
|
||||
combineLatest([this.application.activatedProcessId$, this.route.queryParams])
|
||||
.pipe(debounceTime(0))
|
||||
.subscribe(async ([processId, queryParams]) => {
|
||||
// Setzen des aktuellen Prozesses
|
||||
if (this.search?.processId !== processId) {
|
||||
this.search.processId = processId;
|
||||
}
|
||||
|
||||
initBreadcrumb() {
|
||||
this.application.activatedProcessId$.pipe(takeUntil(this.destroy$)).subscribe((key) => {
|
||||
this.breadcrumb.addBreadcrumbIfNotExists({
|
||||
key,
|
||||
name: 'Kundensuche',
|
||||
path: '/customer/search',
|
||||
tags: ['customer', 'search', 'main', 'filter'],
|
||||
params: this.search.createQueryParams(),
|
||||
});
|
||||
});
|
||||
// Updaten der QueryParams wenn diese sich ändern
|
||||
if (!isEqual(this.search.getQueryParams(), queryParams)) {
|
||||
const params = { ...queryParams };
|
||||
delete params.scrollPos;
|
||||
this.search.setQueryParams({ params });
|
||||
}
|
||||
|
||||
const crumbs = await this.breadcrumb
|
||||
.getBreadcrumbsByKeyAndTags$(processId, ['customer', 'search', 'main', 'filter'])
|
||||
.pipe(first())
|
||||
.toPromise();
|
||||
|
||||
for (const crumb of crumbs) {
|
||||
this.breadcrumb.removeBreadcrumbsAfter(crumb.id, ['customer']);
|
||||
}
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
ngOnDestroy() {
|
||||
this.destroy$.next();
|
||||
this.destroy$.complete();
|
||||
this.search.disconnect();
|
||||
this.subscriptions.unsubscribe();
|
||||
}
|
||||
|
||||
async detectDevice() {
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
import { AfterViewInit, ChangeDetectionStrategy, Component, ElementRef, OnDestroy, OnInit, ViewChild } from '@angular/core';
|
||||
import { ChangeDetectionStrategy, Component, ElementRef, OnDestroy, OnInit, ViewChild } from '@angular/core';
|
||||
import { ActivatedRoute } from '@angular/router';
|
||||
import { ApplicationService } from '@core/application';
|
||||
import { Breadcrumb, BreadcrumbService } from '@core/breadcrumb';
|
||||
import { BreadcrumbService } from '@core/breadcrumb';
|
||||
import { CacheService } from 'apps/core/cache/src/public-api';
|
||||
import { Observable, Subscription } from 'rxjs';
|
||||
import { filter, map, take, tap } from 'rxjs/operators';
|
||||
import { debounce, isEqual } from 'lodash';
|
||||
import { combineLatest, Observable, Subscription } from 'rxjs';
|
||||
import { debounceTime, first, map } from 'rxjs/operators';
|
||||
import { CustomerSearch } from '../customer-search.service';
|
||||
import { CustomerSearchType } from '../defs';
|
||||
|
||||
@@ -14,16 +15,18 @@ import { CustomerSearchType } from '../defs';
|
||||
styleUrls: ['./search-results.component.scss'],
|
||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||
})
|
||||
export class CustomerSearchResultComponent implements OnInit, OnDestroy, AfterViewInit {
|
||||
export class CustomerSearchResultComponent implements OnInit, OnDestroy {
|
||||
@ViewChild('scrollContainer', { static: false }) scrollContainer: ElementRef<HTMLDivElement>;
|
||||
private _breadcrumb: Breadcrumb;
|
||||
customers$: Observable<CustomerSearchType[]>;
|
||||
cacheSubscription: Subscription;
|
||||
|
||||
subscriptions = new Subscription();
|
||||
|
||||
protected readonly viewportEnterOptions: IntersectionObserverInit = {
|
||||
threshold: 0.75,
|
||||
};
|
||||
|
||||
triggerSearchDebounce = debounce(() => this.triggerSearch(), 1000);
|
||||
|
||||
constructor(
|
||||
private application: ApplicationService,
|
||||
private breadcrumb: BreadcrumbService,
|
||||
@@ -33,61 +36,93 @@ export class CustomerSearchResultComponent implements OnInit, OnDestroy, AfterVi
|
||||
) {}
|
||||
|
||||
ngOnInit() {
|
||||
this.search.connect(this.route, {
|
||||
connected: () => {
|
||||
this.route.queryParams.subscribe((params) => {
|
||||
const cachedItems = this.cache.get(params);
|
||||
if (cachedItems) {
|
||||
this.search.searchResult$.next(cachedItems);
|
||||
}
|
||||
});
|
||||
},
|
||||
disconnected: () => {
|
||||
this.cache.set(this.search.getQueryParams(), this.search.searchResult);
|
||||
},
|
||||
});
|
||||
|
||||
this.customers$ = this.search.searchResult$.pipe(map((response) => response.result));
|
||||
this.initBreadcrumb();
|
||||
this.subscriptions.add(
|
||||
combineLatest([this.application.activatedProcessId$, this.route.queryParams])
|
||||
.pipe(debounceTime(0))
|
||||
.subscribe(async ([processId, queryParams]) => {
|
||||
// Wenn ein Prozess bereits zugewiesen ist und der Prozess sich ändert
|
||||
// Speicher Ergebnisse in den Cache und Update Breadcrumb Params
|
||||
if (this.search.processId !== processId) {
|
||||
this.cacheCurrentItems();
|
||||
await this.updateBreadcrumbs();
|
||||
}
|
||||
|
||||
// Setzen des aktuellen Prozesses
|
||||
this.search.processId = processId;
|
||||
|
||||
// Updaten der QueryParams wenn diese sich ändern
|
||||
// scrollPos muss entfernt werden um die items anhand der QueryParams zu cachen
|
||||
if (!isEqual(this.search.getQueryParams(), queryParams)) {
|
||||
const params = { ...queryParams };
|
||||
delete params.scrollPos;
|
||||
const items = this.cache.get<CustomerSearchType[]>(params);
|
||||
this.search.setQueryParams({ params });
|
||||
this.setItems(items);
|
||||
this.triggerSearchDebounce();
|
||||
}
|
||||
|
||||
// Nach dem setzen der Items im store an die letzte Position scrollen
|
||||
setTimeout(() => this.scrollContainer.nativeElement.scrollTo(0, Number(queryParams.scrollPos ?? 0)), 0);
|
||||
|
||||
// Fügt Breadcrumb hinzu falls dieser noch nicht vorhanden ist
|
||||
await this.breadcrumb.addBreadcrumbIfNotExists({
|
||||
key: processId,
|
||||
name: `${this.search.queryFilter.query} (Lade Ergebnisse)`,
|
||||
path: '/customer/search/result',
|
||||
params: queryParams,
|
||||
tags: ['customer', 'search', 'results', 'filter'],
|
||||
});
|
||||
|
||||
await this.removeDetailBreadcrumb();
|
||||
// await this.updateBreadcrumbs();
|
||||
})
|
||||
);
|
||||
this.subscriptions.add(
|
||||
this.search.hits$.pipe(debounceTime(0)).subscribe(() => {
|
||||
this.updateBreadcrumbs();
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
ngAfterViewInit() {}
|
||||
async removeDetailBreadcrumb() {
|
||||
const processId = this.search.processId;
|
||||
const crumbs = await this.breadcrumb.getBreadcrumbsByKeyAndTags$(processId, ['customer', 'details']).pipe(first()).toPromise();
|
||||
|
||||
async initBreadcrumb() {
|
||||
await this.search.filtersLoaded$
|
||||
.pipe(
|
||||
filter((isLoaded) => !!isLoaded),
|
||||
take(1)
|
||||
)
|
||||
for (const crumb of crumbs) {
|
||||
this.breadcrumb.removeBreadcrumb(crumb.id);
|
||||
}
|
||||
}
|
||||
|
||||
async updateBreadcrumbs() {
|
||||
const scrollPos = this.scrollContainer.nativeElement.scrollTop;
|
||||
const processId = this.search.processId;
|
||||
const queryParams = { ...this.search.getQueryParams() };
|
||||
|
||||
const crumbs = await this.breadcrumb
|
||||
.getBreadcrumbsByKeyAndTags$(processId, ['customer', 'search', 'results', 'filter'])
|
||||
.pipe(first())
|
||||
.toPromise();
|
||||
|
||||
this._breadcrumb = await this.breadcrumb.addBreadcrumbIfNotExists({
|
||||
key: this.application.activatedProcessId,
|
||||
name: `${this.search?.queryFilter?.query}`,
|
||||
path: '/customer/search/result',
|
||||
tags: ['customer', 'search', 'results', 'filter'],
|
||||
params: this.search.createQueryParams(),
|
||||
});
|
||||
const params = { ...queryParams, scrollPos };
|
||||
|
||||
this.search.searchResult$.subscribe(() => {
|
||||
let name = this.search?.queryFilter?.query;
|
||||
if (this.search?.searchResult?.hits > 1) {
|
||||
name += ` (${this.search?.searchResult?.hits} Ergebnisse)`;
|
||||
}
|
||||
const hits = await this.search.hits$.pipe(first()).toPromise();
|
||||
|
||||
this.breadcrumb.patchBreadcrumb(this._breadcrumb.id, { name });
|
||||
});
|
||||
|
||||
if (!this.search?.searchResult?.result?.length) {
|
||||
this.triggerSearch();
|
||||
for (const crumb of crumbs) {
|
||||
this.breadcrumb.patchBreadcrumb(crumb.id, {
|
||||
params,
|
||||
name:
|
||||
hits !== undefined
|
||||
? `${this.search.queryFilter.query} (${hits} Ergebnisse)`
|
||||
: `${this.search.queryFilter.query} (Lade Ergebnisse)`,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
ngOnDestroy() {
|
||||
this.search.disconnect();
|
||||
if (!!this.cacheSubscription) {
|
||||
this.cacheSubscription.unsubscribe();
|
||||
}
|
||||
this.subscriptions.unsubscribe();
|
||||
this.cacheCurrentItems();
|
||||
this.updateBreadcrumbs();
|
||||
}
|
||||
|
||||
checkIfReload(target: HTMLElement): void {
|
||||
@@ -99,4 +134,14 @@ export class CustomerSearchResultComponent implements OnInit, OnDestroy, AfterVi
|
||||
triggerSearch() {
|
||||
this.search.search({ isNewSearch: false, take: 10 });
|
||||
}
|
||||
|
||||
setItems(items: CustomerSearchType[]) {
|
||||
this.search.searchResult$.next({
|
||||
result: items,
|
||||
});
|
||||
}
|
||||
|
||||
cacheCurrentItems() {
|
||||
this.cache.set(this.search.getQueryParams(), this.search.searchResult.result);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -110,6 +110,11 @@ export class TaskListComponent {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (statusB.includes('Completed')) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
} else if (aHasStatus && !bHasStatus) {
|
||||
return -1;
|
||||
|
||||
@@ -6,6 +6,9 @@
|
||||
>{{ group.items[0].firstName }} {{ group.items[0].lastName }}</span
|
||||
>
|
||||
</h3>
|
||||
<h4 class="sub-heading">
|
||||
{{ group.items[0].buyerNumber }}
|
||||
</h4>
|
||||
|
||||
<ng-container *ngFor="let byOrderNumber of group.items | groupBy: byOrderNumberFn; let lastOrder = last">
|
||||
<ng-container *ngFor="let byProcessingStatus of byOrderNumber.items | groupBy: byProcessingStatusFn; let lastStatus = last">
|
||||
|
||||
@@ -7,7 +7,11 @@
|
||||
|
||||
.heading {
|
||||
margin: 0;
|
||||
margin-bottom: 18px;
|
||||
margin-bottom: 9px;
|
||||
}
|
||||
|
||||
.sub-heading {
|
||||
@apply m-0 mb-1 text-regular font-bold;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -44,7 +44,7 @@ export class ShellBreadcrumbComponent implements OnInit {
|
||||
const activated = crumbs.find((crumb) => this.router.url.split('?')[0].endsWith(crumb.path));
|
||||
|
||||
if (activated) {
|
||||
this.breadcrumbService.removeBreadcrumbsAfter(activated.id);
|
||||
// this.breadcrumbService.removeBreadcrumbsAfter(activated.id);
|
||||
return activated;
|
||||
}
|
||||
}),
|
||||
|
||||
@@ -34,6 +34,8 @@ export class UiRangeFilterComponent implements OnInit, OnChanges {
|
||||
return `Der Wert darf nicht kleiner als ${errors[key].min} sein.`;
|
||||
case 'max':
|
||||
return `Der Wert darf nicht größer als ${errors[key].max} sein.`;
|
||||
case 'pattern':
|
||||
return `Es werden nur ganzzahlige Werte akzeptiert.`;
|
||||
default:
|
||||
return errors[key];
|
||||
}
|
||||
@@ -47,11 +49,13 @@ export class UiRangeFilterComponent implements OnInit, OnChanges {
|
||||
start: this.fb.control(this.filter.options[0].value, [
|
||||
Validators.min(0),
|
||||
Validators.max(99),
|
||||
Validators.pattern('^[0-9]+$'), // Only numbers
|
||||
maxValueRelativeTo((c) => c?.parent?.get('stop')),
|
||||
]),
|
||||
stop: this.fb.control(this.filter.options[1].value, [
|
||||
Validators.min(0),
|
||||
Validators.max(99),
|
||||
Validators.pattern('^[0-9]+$'), // Only numbers
|
||||
minValueRelativeTo((c) => c?.parent?.get('start')),
|
||||
]),
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user