mirror of
https://dev.azure.com/hugendubel/ISA/_git/ISA-Frontend
synced 2025-12-28 22:42:11 +01:00
Paging Kundensuche
This commit is contained in:
@@ -1,4 +1,9 @@
|
||||
<cdk-virtual-scroll-viewport itemSize="98" class="h-[calc(100vh-18.875rem)]" *ngIf="!compact">
|
||||
<cdk-virtual-scroll-viewport
|
||||
itemSize="98"
|
||||
class="h-[calc(100vh-18.875rem)]"
|
||||
*ngIf="!compact"
|
||||
(scrolledIndexChange)="scrolledIndexChange($event)"
|
||||
>
|
||||
<a
|
||||
*cdkVirtualFor="let customer of customers; trackBy: trackByFn"
|
||||
[routerLink]="customerSearchNavigation.detailsRoute({ processId: processId, customerId: customer.id })?.path"
|
||||
@@ -11,7 +16,12 @@
|
||||
</a>
|
||||
</cdk-virtual-scroll-viewport>
|
||||
|
||||
<cdk-virtual-scroll-viewport itemSize="98" class="h-[calc(100vh-20.75rem)]" *ngIf="compact">
|
||||
<cdk-virtual-scroll-viewport
|
||||
itemSize="98"
|
||||
class="h-[calc(100vh-20.75rem)]"
|
||||
*ngIf="compact"
|
||||
(scrolledIndexChange)="scrolledIndexChange($event)"
|
||||
>
|
||||
<a
|
||||
*cdkVirtualFor="let customer of customers; trackBy: trackByFn"
|
||||
[routerLink]="customerSearchNavigation.detailsRoute({ processId: processId, customerId: customer.id })?.path"
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
import { Component, ChangeDetectionStrategy, Input, EventEmitter, Output } from '@angular/core';
|
||||
import { Component, ChangeDetectionStrategy, Input, EventEmitter, Output, ViewChild } from '@angular/core';
|
||||
import { CustomerInfoDTO } from '@swagger/crm';
|
||||
import { BooleanInput, NumberInput, coerceBooleanProperty, coerceNumberProperty } from '@angular/cdk/coercion';
|
||||
import { CustomerSearchNavigation } from '../../navigations';
|
||||
import { CdkVirtualScrollViewport } from '@angular/cdk/scrolling';
|
||||
|
||||
@Component({
|
||||
selector: 'page-customer-result-list',
|
||||
@@ -28,6 +29,9 @@ export class CustomerResultListComponent {
|
||||
@Output()
|
||||
selectedChange = new EventEmitter<CustomerInfoDTO>();
|
||||
|
||||
@Output()
|
||||
endReached = new EventEmitter<void>();
|
||||
|
||||
private _processId: NumberInput;
|
||||
@Input()
|
||||
get processId() {
|
||||
@@ -39,5 +43,19 @@ export class CustomerResultListComponent {
|
||||
|
||||
trackByFn = (_: number, item: CustomerInfoDTO) => item?.id;
|
||||
|
||||
@ViewChild(CdkVirtualScrollViewport, { static: false })
|
||||
viewport: CdkVirtualScrollViewport;
|
||||
|
||||
@Input()
|
||||
set scrollIndex(index: number) {
|
||||
this.viewport?.scrollToIndex(index);
|
||||
}
|
||||
|
||||
constructor(public customerSearchNavigation: CustomerSearchNavigation) {}
|
||||
|
||||
scrolledIndexChange(index: number) {
|
||||
if (index && this.customers.length <= this.viewport?.getRenderedRange()?.end) {
|
||||
this.endReached.emit();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,4 +19,5 @@
|
||||
|
||||
<span class="mr-5 self-end text-sm"> {{ hits$ | async }} Treffer </span>
|
||||
</div>
|
||||
<page-customer-result-list [processId]="processId$ | async" [customers]="customers$ | async"> </page-customer-result-list>
|
||||
<page-customer-result-list [processId]="processId$ | async" [customers]="customers$ | async" (endReached)="paginate()">
|
||||
</page-customer-result-list>
|
||||
|
||||
@@ -67,4 +67,9 @@ export class CustomerResultsMainViewComponent implements OnInit, OnDestroy {
|
||||
this._store.setFilter(filter);
|
||||
this._store.search();
|
||||
}
|
||||
|
||||
paginate() {
|
||||
console.log('paginate');
|
||||
this._store.paginate();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,4 +19,5 @@
|
||||
|
||||
<span class="mr-5 self-end text-sm mt-4"> {{ hits$ | async }} Treffer </span>
|
||||
</div>
|
||||
<page-customer-result-list [processId]="processId$ | async" compact="true" [customers]="customers$ | async"> </page-customer-result-list>
|
||||
<page-customer-result-list [processId]="processId$ | async" compact="true" [customers]="customers$ | async" (endReached)="paginate()">
|
||||
</page-customer-result-list>
|
||||
|
||||
@@ -67,4 +67,8 @@ export class CustomerResultsSideViewComponent implements OnInit, OnDestroy {
|
||||
this._store.setFilter(filter);
|
||||
this._store.search();
|
||||
}
|
||||
|
||||
paginate() {
|
||||
this._store.paginate();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@ import { CustomerSearchState } from './customer-search.state';
|
||||
import * as S from './selectors';
|
||||
import { Injectable, OnDestroy } from '@angular/core';
|
||||
import { Observable, Subject } from 'rxjs';
|
||||
import { distinctUntilChanged, filter, switchMap, takeUntil, tap, withLatestFrom, delayWhen } from 'rxjs/operators';
|
||||
import { distinctUntilChanged, filter, switchMap, takeUntil, tap, withLatestFrom, delayWhen, delay } from 'rxjs/operators';
|
||||
import { CrmCustomerService } from '@domain/crm';
|
||||
import { Result } from '@domain/defs';
|
||||
import { CustomerDTO, ListResponseArgsOfCustomerInfoDTO, QuerySettingsDTO } from '@swagger/crm';
|
||||
@@ -197,9 +197,13 @@ export class CustomerSearchStore extends ComponentStore<CustomerSearchState> imp
|
||||
this.patchState({ fetchingCustomerList: true, customerList: [], customerListCount: 0 });
|
||||
this.restoreSearchResult();
|
||||
}),
|
||||
delay(1),
|
||||
switchMap(([_, filter, processId]) =>
|
||||
this._customerService
|
||||
.getCustomersWithQueryToken(filter.getQueryToken())
|
||||
.getCustomersWithQueryToken({
|
||||
...filter.getQueryToken(),
|
||||
take: this.customerList?.length || 20,
|
||||
})
|
||||
.pipe(
|
||||
takeUntil(this._cancelSearch),
|
||||
tapResponse(this.handleSearchResponse(filter, processId), this.handleSearchError, this.handleSearchComplete)
|
||||
@@ -226,6 +230,45 @@ export class CustomerSearchStore extends ComponentStore<CustomerSearchState> imp
|
||||
this._cancelSearch.next();
|
||||
}
|
||||
|
||||
paginate = this.effect(($: Observable<void>) =>
|
||||
$.pipe(
|
||||
withLatestFrom(this.filter$, this.processId$, this.customerList$, this.fetchingCustomerList$),
|
||||
filter(
|
||||
([_, __, ___, customerList, fetchingCustomerList]) =>
|
||||
!fetchingCustomerList && customerList.length && customerList.length < this.customerListCount
|
||||
),
|
||||
delayWhen(() => this.fetchingCustomerList$.pipe(filter((fetching) => !fetching))),
|
||||
tap(() => {
|
||||
this.patchState({ fetchingCustomerList: true });
|
||||
}),
|
||||
switchMap(([_, filter, processId, customerList]) =>
|
||||
this._customerService
|
||||
.getCustomersWithQueryToken({
|
||||
...filter.getQueryToken(),
|
||||
skip: customerList.length,
|
||||
})
|
||||
.pipe(
|
||||
takeUntil(this._cancelSearch),
|
||||
tapResponse(this.handlePaginateResponse(filter, processId), this.handlePaginateError, this.handlePaginateComplete)
|
||||
)
|
||||
)
|
||||
)
|
||||
);
|
||||
|
||||
handlePaginateResponse = (filter: Filter, processId: number) => (result: ListResponseArgsOfCustomerInfoDTO) => {
|
||||
this.patchState({ customerList: [...this.customerList, ...result.result], customerListCount: result.hits });
|
||||
this._customerListResponse.next([result, filter, processId]);
|
||||
this.cacheSearchResult();
|
||||
};
|
||||
|
||||
handlePaginateError = (err: any) => {
|
||||
console.error(err);
|
||||
};
|
||||
|
||||
handlePaginateComplete = () => {
|
||||
this.patchState({ fetchingCustomerList: false });
|
||||
};
|
||||
|
||||
reset(queryParams: Record<string, string> = {}) {
|
||||
this.patchState({ customerList: [], customerListCount: 0, queryParams });
|
||||
|
||||
|
||||
Reference in New Issue
Block a user