extends PartialFetcherContinu
protected abstract filter(params: SearchHistoricalParams): Observable;
protected fetch(params: FetchPaymentParams, continuationId?: string): Observable> {
- const { sortOrder, size, from, to, paymentId, cardToken, shopId, partyId, status, fingerprint, email } = params;
+ const {
+ sortOrder,
+ size,
+ from,
+ to,
+ paymentId,
+ cardToken,
+ shopId,
+ partyId,
+ status,
+ fingerprint,
+ email,
+ template,
+ rule,
+ } = params;
return this.filter({
from: this.datepipe.transform(from, DateFormat._yyyyMMDdHHMmSs),
to: this.datepipe.transform(to, DateFormat._yyyyMMDdHHMmSs),
@@ -48,6 +64,8 @@ export abstract class FetchHistoricalService extends PartialFetcherContinu
status: status || '',
fingerprint: fingerprint || '',
email: email || '',
+ template: template || '',
+ rule: rule || '',
size: size ? size : this.pageSize,
...(continuationId ? { continuationId } : {}),
});
diff --git a/src/app/shared/components/charts/bar-chart/bar-chart.component.spec.ts b/src/app/shared/components/charts/bar-chart/bar-chart.component.spec.ts
new file mode 100644
index 00000000..f8ee79a0
--- /dev/null
+++ b/src/app/shared/components/charts/bar-chart/bar-chart.component.spec.ts
@@ -0,0 +1,11 @@
+import { BarChartComponent } from './bar-chart.component';
+import { DEFAULT_CONFIG } from './default-config';
+
+describe('BarChartComponent', () => {
+ it('creates an independent config containing formatter functions', () => {
+ const component = new BarChartComponent();
+
+ expect(component.config).toEqual(DEFAULT_CONFIG);
+ expect(component.config).not.toBe(DEFAULT_CONFIG);
+ });
+});
diff --git a/src/app/shared/components/charts/bar-chart/bar-chart.component.ts b/src/app/shared/components/charts/bar-chart/bar-chart.component.ts
index b6abd690..aae8287c 100644
--- a/src/app/shared/components/charts/bar-chart/bar-chart.component.ts
+++ b/src/app/shared/components/charts/bar-chart/bar-chart.component.ts
@@ -1,4 +1,7 @@
import { Component, Input, OnChanges, SimpleChanges } from '@angular/core';
+// Apex options contain formatter callbacks, which structuredClone cannot clone.
+// eslint-disable-next-line you-dont-need-lodash-underscore/clone-deep
+import cloneDeep from 'lodash-es/cloneDeep';
import { ApexAxisChartSeries } from 'ng-apexcharts';
import { DEFAULT_CONFIG } from './default-config';
@@ -18,7 +21,7 @@ export class BarChartComponent implements OnChanges {
@Input()
height?: number;
- config = structuredClone(DEFAULT_CONFIG);
+ config = cloneDeep(DEFAULT_CONFIG);
ngOnChanges(changes: SimpleChanges) {
if (changes.height && changes.height.currentValue !== changes.height.previousValue) {
diff --git a/src/app/shared/components/infinite-scroll-trigger.ts b/src/app/shared/components/infinite-scroll-trigger.ts
new file mode 100644
index 00000000..8f6f6313
--- /dev/null
+++ b/src/app/shared/components/infinite-scroll-trigger.ts
@@ -0,0 +1,44 @@
+export class InfiniteScrollTrigger {
+ private observer?: IntersectionObserver;
+ private retryTimer?: number;
+ private isIntersecting = false;
+ private isLoading = false;
+ private requestPending = false;
+
+ constructor(private readonly loadMore: () => void) {}
+
+ observe(element: Element) {
+ this.observer = new IntersectionObserver(
+ ([entry]) => {
+ this.isIntersecting = entry.isIntersecting;
+ this.loadIfNeeded();
+ },
+ { rootMargin: '300px 0px' }
+ );
+ this.observer.observe(element);
+ }
+
+ setLoading(isLoading: boolean) {
+ const requestFinished = this.isLoading && !isLoading;
+ this.isLoading = isLoading;
+ if (requestFinished) {
+ this.requestPending = false;
+ this.retryTimer = window.setTimeout(() => this.loadIfNeeded());
+ }
+ }
+
+ disconnect() {
+ this.observer?.disconnect();
+ if (this.retryTimer) {
+ window.clearTimeout(this.retryTimer);
+ }
+ }
+
+ private loadIfNeeded() {
+ if (!this.isIntersecting || this.isLoading || this.requestPending) {
+ return;
+ }
+ this.requestPending = true;
+ this.loadMore();
+ }
+}
diff --git a/src/app/shared/components/show-more-panel-continuation/show-more-continuation-panel.component.html b/src/app/shared/components/show-more-panel-continuation/show-more-continuation-panel.component.html
index 195d712a..0647117c 100644
--- a/src/app/shared/components/show-more-panel-continuation/show-more-continuation-panel.component.html
+++ b/src/app/shared/components/show-more-panel-continuation/show-more-continuation-panel.component.html
@@ -1,3 +1,3 @@
-
-
-
+
+
+
diff --git a/src/app/shared/components/show-more-panel-continuation/show-more-continuation-panel.component.scss b/src/app/shared/components/show-more-panel-continuation/show-more-continuation-panel.component.scss
index caf74cf4..6458a0b8 100644
--- a/src/app/shared/components/show-more-panel-continuation/show-more-continuation-panel.component.scss
+++ b/src/app/shared/components/show-more-panel-continuation/show-more-continuation-panel.component.scss
@@ -1,4 +1,7 @@
-.show-more-panel {
- margin: 0;
- padding: 0 !important;
+.infinite-scroll-sentinel {
+ display: flex;
+ min-height: 48px;
+ align-items: center;
+ justify-content: center;
+ width: 100%;
}
diff --git a/src/app/shared/components/show-more-panel-continuation/show-more-continuation-panel.component.ts b/src/app/shared/components/show-more-panel-continuation/show-more-continuation-panel.component.ts
index 5abe8f78..8a66eb6b 100644
--- a/src/app/shared/components/show-more-panel-continuation/show-more-continuation-panel.component.ts
+++ b/src/app/shared/components/show-more-panel-continuation/show-more-continuation-panel.component.ts
@@ -1,26 +1,52 @@
-import { Component, EventEmitter, Input, Output } from '@angular/core';
+import {
+ AfterViewInit,
+ Component,
+ ElementRef,
+ EventEmitter,
+ Input,
+ NgZone,
+ OnDestroy,
+ Output,
+ ViewChild,
+} from '@angular/core';
import { ActivatedRoute, Params } from '@angular/router';
-import { take } from 'rxjs/operators';
+
+import { InfiniteScrollTrigger } from '../infinite-scroll-trigger';
@Component({
selector: 'fb-show-more-continuation-panel',
templateUrl: 'show-more-continuation-panel.component.html',
styleUrls: ['show-more-continuation-panel.component.scss'],
})
-export class ShowMoreContinuationPanelComponent {
- @Input()
- isLoading = false;
+export class ShowMoreContinuationPanelComponent implements AfterViewInit, OnDestroy {
+ @ViewChild('sentinel', { static: true }) sentinel: ElementRef;
+
+ @Input() set isLoading(value: boolean | null) {
+ this.loading = Boolean(value);
+ this.infiniteScrollTrigger.setLoading(this.loading);
+ }
+
+ get isLoading(): boolean {
+ return this.loading;
+ }
@Output()
showMore: EventEmitter = new EventEmitter();
- queryParams = {};
+ private loading = false;
+ private readonly infiniteScrollTrigger: InfiniteScrollTrigger;
+
+ constructor(private route: ActivatedRoute, private ngZone: NgZone) {
+ this.infiniteScrollTrigger = new InfiniteScrollTrigger(() =>
+ this.ngZone.run(() => this.showMore.emit(this.route.snapshot.queryParams))
+ );
+ }
- constructor(private route: ActivatedRoute) {
- this.route.queryParams.pipe(take(1)).subscribe((v) => (this.queryParams = v));
+ ngAfterViewInit() {
+ this.infiniteScrollTrigger.observe(this.sentinel.nativeElement);
}
- getMore() {
- this.showMore.emit(this.queryParams);
+ ngOnDestroy() {
+ this.infiniteScrollTrigger.disconnect();
}
}
diff --git a/src/app/shared/components/show-more-panel-continuation/show-more-continuation-panel.module.ts b/src/app/shared/components/show-more-panel-continuation/show-more-continuation-panel.module.ts
index 0d779254..3c175273 100644
--- a/src/app/shared/components/show-more-panel-continuation/show-more-continuation-panel.module.ts
+++ b/src/app/shared/components/show-more-panel-continuation/show-more-continuation-panel.module.ts
@@ -1,13 +1,12 @@
+import { CommonModule } from '@angular/common';
import { NgModule } from '@angular/core';
-import { FlexModule } from '@angular/flex-layout';
-import { MatButtonModule } from '@angular/material/button';
-import { MatCardModule } from '@angular/material/card';
+import { MatProgressSpinnerModule } from '@angular/material/progress-spinner';
import { ShowMoreContinuationPanelComponent } from './show-more-continuation-panel.component';
@NgModule({
declarations: [ShowMoreContinuationPanelComponent],
- imports: [FlexModule, MatCardModule, MatButtonModule],
+ imports: [CommonModule, MatProgressSpinnerModule],
exports: [ShowMoreContinuationPanelComponent],
})
export class ShowMoreContinuationPanelModule {}
diff --git a/src/app/shared/components/show-more-panel/show-more-panel.component.html b/src/app/shared/components/show-more-panel/show-more-panel.component.html
index 195d712a..0647117c 100644
--- a/src/app/shared/components/show-more-panel/show-more-panel.component.html
+++ b/src/app/shared/components/show-more-panel/show-more-panel.component.html
@@ -1,3 +1,3 @@
-
-
-
+
+
+
diff --git a/src/app/shared/components/show-more-panel/show-more-panel.component.scss b/src/app/shared/components/show-more-panel/show-more-panel.component.scss
index caf74cf4..6458a0b8 100644
--- a/src/app/shared/components/show-more-panel/show-more-panel.component.scss
+++ b/src/app/shared/components/show-more-panel/show-more-panel.component.scss
@@ -1,4 +1,7 @@
-.show-more-panel {
- margin: 0;
- padding: 0 !important;
+.infinite-scroll-sentinel {
+ display: flex;
+ min-height: 48px;
+ align-items: center;
+ justify-content: center;
+ width: 100%;
}
diff --git a/src/app/shared/components/show-more-panel/show-more-panel.component.ts b/src/app/shared/components/show-more-panel/show-more-panel.component.ts
index 047cbbaf..708641aa 100644
--- a/src/app/shared/components/show-more-panel/show-more-panel.component.ts
+++ b/src/app/shared/components/show-more-panel/show-more-panel.component.ts
@@ -1,24 +1,52 @@
-import { Component, EventEmitter, Input, Output } from '@angular/core';
+import {
+ AfterViewInit,
+ Component,
+ ElementRef,
+ EventEmitter,
+ Input,
+ NgZone,
+ OnDestroy,
+ Output,
+ ViewChild,
+} from '@angular/core';
import { ActivatedRoute, Params } from '@angular/router';
-import { take } from 'rxjs/operators';
+
+import { InfiniteScrollTrigger } from '../infinite-scroll-trigger';
@Component({
selector: 'fb-show-more-panel',
templateUrl: 'show-more-panel.component.html',
styleUrls: ['show-more-panel.component.scss'],
})
-export class ShowMorePanelComponent {
- @Input()
- isLoading = false;
+export class ShowMorePanelComponent implements AfterViewInit, OnDestroy {
+ @ViewChild('sentinel', { static: true }) sentinel: ElementRef;
+
+ @Input() set isLoading(value: boolean | null) {
+ this.loading = Boolean(value);
+ this.infiniteScrollTrigger.setLoading(this.loading);
+ }
+
+ get isLoading(): boolean {
+ return this.loading;
+ }
@Output()
showMore: EventEmitter = new EventEmitter();
- constructor(private route: ActivatedRoute) {
- this.route.queryParams.pipe(take(1)).subscribe((v) => this.showMore.emit(v));
+ private loading = false;
+ private readonly infiniteScrollTrigger: InfiniteScrollTrigger;
+
+ constructor(private route: ActivatedRoute, private ngZone: NgZone) {
+ this.infiniteScrollTrigger = new InfiniteScrollTrigger(() =>
+ this.ngZone.run(() => this.showMore.emit(this.route.snapshot.queryParams))
+ );
+ }
+
+ ngAfterViewInit() {
+ this.infiniteScrollTrigger.observe(this.sentinel.nativeElement);
}
- getMore() {
- this.showMore.emit();
+ ngOnDestroy() {
+ this.infiniteScrollTrigger.disconnect();
}
}
diff --git a/src/app/shared/components/show-more-panel/show-more-panel.module.ts b/src/app/shared/components/show-more-panel/show-more-panel.module.ts
index 06c2647a..3cee64ab 100644
--- a/src/app/shared/components/show-more-panel/show-more-panel.module.ts
+++ b/src/app/shared/components/show-more-panel/show-more-panel.module.ts
@@ -1,13 +1,12 @@
+import { CommonModule } from '@angular/common';
import { NgModule } from '@angular/core';
-import { FlexModule } from '@angular/flex-layout';
-import { MatButtonModule } from '@angular/material/button';
-import { MatCardModule } from '@angular/material/card';
+import { MatProgressSpinnerModule } from '@angular/material/progress-spinner';
import { ShowMorePanelComponent } from './show-more-panel.component';
@NgModule({
declarations: [ShowMorePanelComponent],
- imports: [FlexModule, MatCardModule, MatButtonModule],
+ imports: [CommonModule, MatProgressSpinnerModule],
exports: [ShowMorePanelComponent],
})
export class ShowMorePanelModule {}
diff --git a/src/assets/appConfig.json b/src/assets/appConfig.json
index 8297e61c..9f457379 100644
--- a/src/assets/appConfig.json
+++ b/src/assets/appConfig.json
@@ -1,4 +1,4 @@
{
"fbManagementEndpoint": "https://api.empayre.com/fb-management/v1",
- "pageSize": 10
+ "pageSize": 100
}