From 859aa8b39b6d0393d5878e702c65bbe81605dfbb Mon Sep 17 00:00:00 2001 From: lil-goat <167018448+lil-goat@users.noreply.github.com> Date: Sun, 17 May 2026 02:07:53 +0800 Subject: [PATCH] Task/improve pagination for activities in holding detail dialog (#6874) * Improve pagination * Update changelog --- CHANGELOG.md | 1 + .../holding-detail-dialog.component.ts | 52 +++++++++++++------ .../holding-detail-dialog.html | 3 ++ 3 files changed, 40 insertions(+), 16 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 228e9c377..d46d92da9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Changed +- Improved the pagination in the activities table of the holding detail dialog - Enabled the _Bull Dashboard_ in the admin control panel without requiring an environment variable (experimental) - Extracted the page tabs to a reusable component - Upgraded `bull-board` from version `7.0.0` to `7.1.5` diff --git a/apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.component.ts b/apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.component.ts index bf4955e45..8c42e37ea 100644 --- a/apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.component.ts +++ b/apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.component.ts @@ -1,5 +1,6 @@ import { UserService } from '@ghostfolio/client/services/user/user.service'; import { + DEFAULT_PAGE_SIZE, NUMERICAL_PRECISION_THRESHOLD_3_FIGURES, NUMERICAL_PRECISION_THRESHOLD_5_FIGURES, NUMERICAL_PRECISION_THRESHOLD_6_FIGURES @@ -48,6 +49,7 @@ import { MatDialogRef } from '@angular/material/dialog'; import { MatFormFieldModule } from '@angular/material/form-field'; +import { PageEvent } from '@angular/material/paginator'; import { SortDirection } from '@angular/material/sort'; import { MatTableDataSource } from '@angular/material/table'; import { MatTabsModule } from '@angular/material/tabs'; @@ -140,6 +142,8 @@ export class GfHoldingDetailDialogComponent implements OnInit { public netPerformancePercentWithCurrencyEffectPrecision = 2; public netPerformanceWithCurrencyEffect: number; public netPerformanceWithCurrencyEffectPrecision = 2; + public pageIndex = 0; + public pageSize = DEFAULT_PAGE_SIZE; public quantity: number; public quantityPrecision = 2; public reportDataGlitchMail: string; @@ -178,10 +182,7 @@ export class GfHoldingDetailDialogComponent implements OnInit { } public ngOnInit() { - const filters: Filter[] = [ - { id: this.data.dataSource, type: 'DATA_SOURCE' }, - { id: this.data.symbol, type: 'SYMBOL' } - ]; + const filters = this.getActivityFilters(); this.holdingForm = this.formBuilder.group({ tags: [] as string[] @@ -240,18 +241,7 @@ export class GfHoldingDetailDialogComponent implements OnInit { this.changeDetectorRef.markForCheck(); }); - this.dataService - .fetchActivities({ - filters, - sortColumn: this.sortColumn, - sortDirection: this.sortDirection - }) - .pipe(takeUntilDestroyed(this.destroyRef)) - .subscribe(({ activities }) => { - this.dataSource = new MatTableDataSource(activities); - - this.changeDetectorRef.markForCheck(); - }); + this.fetchActivities(filters); this.dataService .fetchHoldingDetail({ @@ -543,6 +533,12 @@ export class GfHoldingDetailDialogComponent implements OnInit { }); } + public onChangePage(page: PageEvent) { + this.pageIndex = page.pageIndex; + + this.fetchActivities(); + } + public onCloneActivity(aActivity: Activity) { this.router.navigate( internalRoutes.portfolio.subRoutes.activities.routerLink, @@ -626,6 +622,23 @@ export class GfHoldingDetailDialogComponent implements OnInit { this.dialogRef.close(); } + private fetchActivities(filters: Filter[] = this.getActivityFilters()) { + this.dataService + .fetchActivities({ + filters, + skip: this.pageIndex * this.pageSize, + sortColumn: this.sortColumn, + sortDirection: this.sortDirection, + take: this.pageSize + }) + .pipe(takeUntilDestroyed(this.destroyRef)) + .subscribe(({ activities }) => { + this.dataSource = new MatTableDataSource(activities); + + this.changeDetectorRef.markForCheck(); + }); + } + private fetchMarketData() { this.dataService .fetchMarketDataBySymbol({ @@ -648,4 +661,11 @@ export class GfHoldingDetailDialogComponent implements OnInit { this.changeDetectorRef.markForCheck(); }); } + + private getActivityFilters(): Filter[] { + return [ + { id: this.data.dataSource, type: 'DATA_SOURCE' }, + { id: this.data.symbol, type: 'SYMBOL' } + ]; + } } diff --git a/apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html b/apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html index 7c1906ee5..4b04a0986 100644 --- a/apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html +++ b/apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html @@ -353,6 +353,8 @@ [hasPermissionToFilter]="false" [hasPermissionToOpenDetails]="false" [locale]="data.locale" + [pageIndex]="pageIndex" + [pageSize]="pageSize" [showActions]=" !data.hasImpersonationId && data.hasPermissionToCreateActivity && @@ -367,6 +369,7 @@ (activityToClone)="onCloneActivity($event)" (activityToUpdate)="onUpdateActivity($event)" (export)="onExport()" + (pageChanged)="onChangePage($event)" />