diff --git a/CHANGELOG.md b/CHANGELOG.md index 7cdca7fc..4451972b 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 ### Added +- Added support for column sorting to the lazy-loaded activities table on the portfolio activities page (experimental) - Extended the benchmarks of the markets overview by the current market condition (all time high) ### Changed diff --git a/apps/client/src/app/components/admin-market-data/admin-market-data.component.ts b/apps/client/src/app/components/admin-market-data/admin-market-data.component.ts index 25076ca0..6728843a 100644 --- a/apps/client/src/app/components/admin-market-data/admin-market-data.component.ts +++ b/apps/client/src/app/components/admin-market-data/admin-market-data.component.ts @@ -9,7 +9,7 @@ import { } from '@angular/core'; import { MatDialog } from '@angular/material/dialog'; import { MatPaginator, PageEvent } from '@angular/material/paginator'; -import { MatSort, Sort } from '@angular/material/sort'; +import { MatSort, Sort, SortDirection } from '@angular/material/sort'; import { MatTableDataSource } from '@angular/material/table'; import { ActivatedRoute, Router } from '@angular/router'; import { AdminService } from '@ghostfolio/client/services/admin.service'; @@ -19,7 +19,7 @@ import { getDateFormatString } from '@ghostfolio/common/helper'; import { Filter, UniqueAsset, User } from '@ghostfolio/common/interfaces'; import { AdminMarketDataItem } from '@ghostfolio/common/interfaces/admin-market-data.interface'; import { translate } from '@ghostfolio/ui/i18n'; -import { AssetSubClass, DataSource, Prisma } from '@prisma/client'; +import { AssetSubClass, DataSource } from '@prisma/client'; import { isUUID } from 'class-validator'; import { DeviceDetectorService } from 'ngx-device-detector'; import { Subject } from 'rxjs'; @@ -160,7 +160,7 @@ export class AdminMarketDataComponent this.loadData({ sortColumn, - sortDirection: direction, + sortDirection: direction, pageIndex: this.paginator.pageIndex }); } @@ -175,7 +175,7 @@ export class AdminMarketDataComponent this.loadData({ pageIndex: page.pageIndex, sortColumn: this.sort.active, - sortDirection: this.sort.direction + sortDirection: this.sort.direction }); } @@ -262,7 +262,7 @@ export class AdminMarketDataComponent }: { pageIndex: number; sortColumn?: string; - sortDirection?: Prisma.SortOrder; + sortDirection?: SortDirection; } = { pageIndex: 0 } ) { this.isLoading = true; diff --git a/apps/client/src/app/pages/portfolio/activities/activities-page.component.ts b/apps/client/src/app/pages/portfolio/activities/activities-page.component.ts index a1f596e3..f72f83e9 100644 --- a/apps/client/src/app/pages/portfolio/activities/activities-page.component.ts +++ b/apps/client/src/app/pages/portfolio/activities/activities-page.component.ts @@ -1,6 +1,7 @@ import { ChangeDetectorRef, Component, OnDestroy, OnInit } from '@angular/core'; import { MatDialog } from '@angular/material/dialog'; import { PageEvent } from '@angular/material/paginator'; +import { Sort, SortDirection } from '@angular/material/sort'; import { MatTableDataSource } from '@angular/material/table'; import { ActivatedRoute, Router } from '@angular/router'; import { CreateOrderDto } from '@ghostfolio/api/app/order/create-order.dto'; @@ -16,7 +17,7 @@ import { DEFAULT_PAGE_SIZE } from '@ghostfolio/common/config'; import { downloadAsFile } from '@ghostfolio/common/helper'; import { User } from '@ghostfolio/common/interfaces'; import { hasPermission, permissions } from '@ghostfolio/common/permissions'; -import { DataSource, Order as OrderModel, Prisma } from '@prisma/client'; +import { DataSource, Order as OrderModel } from '@prisma/client'; import { format, parseISO } from 'date-fns'; import { DeviceDetectorService } from 'ngx-device-detector'; import { Subject, Subscription } from 'rxjs'; @@ -43,7 +44,7 @@ export class ActivitiesPageComponent implements OnDestroy, OnInit { public pageSize = DEFAULT_PAGE_SIZE; public routeQueryParams: Subscription; public sortColumn = 'date'; - public sortDirection: Prisma.SortOrder = 'desc'; + public sortDirection: SortDirection = 'desc'; public totalItems: number; public user: User; @@ -261,6 +262,14 @@ export class ActivitiesPageComponent implements OnDestroy, OnInit { }); } + public onSortChanged({ active, direction }: Sort) { + this.pageIndex = 0; + this.sortColumn = active; + this.sortDirection = direction; + + this.fetchActivities(); + } + public onUpdateActivity(aActivity: OrderModel) { this.router.navigate([], { queryParams: { activityId: aActivity.id, editDialog: true } diff --git a/apps/client/src/app/pages/portfolio/activities/activities-page.html b/apps/client/src/app/pages/portfolio/activities/activities-page.html index bab5eb06..5ab9999d 100644 --- a/apps/client/src/app/pages/portfolio/activities/activities-page.html +++ b/apps/client/src/app/pages/portfolio/activities/activities-page.html @@ -13,6 +13,8 @@ [pageIndex]="pageIndex" [pageSize]="pageSize" [showActions]="!hasImpersonationId && hasPermissionToDeleteActivity && !user.settings.isRestrictedView" + [sortColumn]="sortColumn" + [sortDirection]="sortDirection" [totalItems]="totalItems" (activityDeleted)="onDeleteActivity($event)" (activityToClone)="onCloneActivity($event)" @@ -23,6 +25,7 @@ (import)="onImport()" (importDividends)="onImportDividends()" (pageChanged)="onChangePage($event)" + (sortChanged)="onSortChanged($event)" > { let params = this.buildFiltersAsQueryParams({ filters }); diff --git a/libs/ui/src/lib/activities-table-lazy/activities-table-lazy.component.html b/libs/ui/src/lib/activities-table-lazy/activities-table-lazy.component.html index 116883b1..7e5ce9d0 100644 --- a/libs/ui/src/lib/activities-table-lazy/activities-table-lazy.component.html +++ b/libs/ui/src/lib/activities-table-lazy/activities-table-lazy.component.html @@ -65,7 +65,14 @@
- +
- + Name @@ -243,7 +245,6 @@ *matHeaderCellDef class="d-none d-lg-table-cell justify-content-end px-1" mat-header-cell - mat-sort-header > Value @@ -263,12 +264,7 @@ - + Currency Value @@ -301,12 +296,7 @@ - + Account @@ -473,7 +463,9 @@ [ngClass]="{ 'd-none': (isLoading && totalItems === 0) || totalItems <= pageSize }" + [pageIndex]="pageIndex" [pageSize]="pageSize" + [showFirstLastButtons]="true" (page)="onChangePage($event)" > diff --git a/libs/ui/src/lib/activities-table-lazy/activities-table-lazy.component.ts b/libs/ui/src/lib/activities-table-lazy/activities-table-lazy.component.ts index 4300dd42..caab993e 100644 --- a/libs/ui/src/lib/activities-table-lazy/activities-table-lazy.component.ts +++ b/libs/ui/src/lib/activities-table-lazy/activities-table-lazy.component.ts @@ -1,5 +1,6 @@ import { SelectionModel } from '@angular/cdk/collections'; import { + AfterViewInit, ChangeDetectionStrategy, Component, EventEmitter, @@ -11,6 +12,7 @@ import { ViewChild } from '@angular/core'; import { MatPaginator, PageEvent } from '@angular/material/paginator'; +import { MatSort, Sort, SortDirection } from '@angular/material/sort'; import { MatTableDataSource } from '@angular/material/table'; import { Router } from '@angular/router'; import { Activity } from '@ghostfolio/api/app/order/interfaces/activities.interface'; @@ -29,7 +31,7 @@ import { Subject, Subscription, takeUntil } from 'rxjs'; templateUrl: './activities-table-lazy.component.html' }) export class ActivitiesTableLazyComponent - implements OnChanges, OnDestroy, OnInit + implements AfterViewInit, OnChanges, OnDestroy, OnInit { @Input() baseCurrency: string; @Input() dataSource: MatTableDataSource; @@ -44,6 +46,8 @@ export class ActivitiesTableLazyComponent @Input() showCheckbox = false; @Input() showFooter = true; @Input() showNameColumn = true; + @Input() sortColumn: string; + @Input() sortDirection: SortDirection; @Input() totalItems = Number.MAX_SAFE_INTEGER; @Output() activityDeleted = new EventEmitter(); @@ -56,8 +60,10 @@ export class ActivitiesTableLazyComponent @Output() importDividends = new EventEmitter(); @Output() pageChanged = new EventEmitter(); @Output() selectedActivities = new EventEmitter(); + @Output() sortChanged = new EventEmitter(); @ViewChild(MatPaginator) paginator: MatPaginator; + @ViewChild(MatSort) sort: MatSort; public defaultDateFormat: string; public displayedColumns = []; @@ -86,6 +92,12 @@ export class ActivitiesTableLazyComponent } } + public ngAfterViewInit() { + this.sort.sortChange.subscribe((value: Sort) => { + this.sortChanged.emit(value); + }); + } + public areAllRowsSelected() { const numSelectedRows = this.selectedRows.selected.length; const numTotalRows = this.dataSource.data.length; diff --git a/libs/ui/src/lib/activities-table-lazy/activities-table-lazy.module.ts b/libs/ui/src/lib/activities-table-lazy/activities-table-lazy.module.ts index 3d7e79a4..22c9f635 100644 --- a/libs/ui/src/lib/activities-table-lazy/activities-table-lazy.module.ts +++ b/libs/ui/src/lib/activities-table-lazy/activities-table-lazy.module.ts @@ -31,6 +31,7 @@ import { ActivitiesTableLazyComponent } from './activities-table-lazy.component' MatCheckboxModule, MatMenuModule, MatPaginatorModule, + MatSortModule, MatTableModule, MatTooltipModule, NgxSkeletonLoaderModule,