From ffb7cbff50f6f3d07d99fab81f2eb2421a4fc681 Mon Sep 17 00:00:00 2001 From: Thomas Kaul <4159106+dtslvr@users.noreply.github.com> Date: Mon, 11 Dec 2023 19:45:30 +0100 Subject: [PATCH 1/4] Feature/highlight all time high in benchmarks of the markets overview (#2740) * Highlight all time high * Update changelog --- CHANGELOG.md | 4 ++++ apps/api/src/app/benchmark/benchmark.service.ts | 13 +++++++++++-- libs/common/src/lib/helper.ts | 6 +++--- .../src/lib/interfaces/benchmark.interface.ts | 2 +- libs/ui/src/lib/benchmark/benchmark.component.html | 2 +- 5 files changed, 20 insertions(+), 7 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index dcecac253..7cdca7fc4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## Unreleased +### Added + +- Extended the benchmarks of the markets overview by the current market condition (all time high) + ### Changed - Upgraded `prisma` from version `5.6.0` to `5.7.0` diff --git a/apps/api/src/app/benchmark/benchmark.service.ts b/apps/api/src/app/benchmark/benchmark.service.ts index 93f4ecc9b..cbd5e7e1f 100644 --- a/apps/api/src/app/benchmark/benchmark.service.ts +++ b/apps/api/src/app/benchmark/benchmark.service.ts @@ -14,6 +14,7 @@ import { calculateBenchmarkTrend } from '@ghostfolio/common/helper'; import { + Benchmark, BenchmarkMarketDataDetails, BenchmarkProperty, BenchmarkResponse, @@ -339,7 +340,15 @@ export class BenchmarkService { }; } - private getMarketCondition(aPerformanceInPercent: number) { - return aPerformanceInPercent <= -0.2 ? 'BEAR_MARKET' : 'NEUTRAL_MARKET'; + private getMarketCondition( + aPerformanceInPercent: number + ): Benchmark['marketCondition'] { + if (aPerformanceInPercent === 0) { + return 'ALL_TIME_HIGH'; + } else if (aPerformanceInPercent <= -0.2) { + return 'BEAR_MARKET'; + } else { + return 'NEUTRAL_MARKET'; + } } } diff --git a/libs/common/src/lib/helper.ts b/libs/common/src/lib/helper.ts index 0ca83e3ba..16d5d041b 100644 --- a/libs/common/src/lib/helper.ts +++ b/libs/common/src/lib/helper.ts @@ -381,10 +381,10 @@ export function resolveFearAndGreedIndex(aValue: number) { export function resolveMarketCondition( aMarketCondition: Benchmark['marketCondition'] ) { - if (aMarketCondition === 'BEAR_MARKET') { + if (aMarketCondition === 'ALL_TIME_HIGH') { + return { emoji: '🎉' }; + } else if (aMarketCondition === 'BEAR_MARKET') { return { emoji: '🐻' }; - } else if (aMarketCondition === 'BULL_MARKET') { - return { emoji: '🐮' }; } else { return { emoji: '⚪' }; } diff --git a/libs/common/src/lib/interfaces/benchmark.interface.ts b/libs/common/src/lib/interfaces/benchmark.interface.ts index 2124173fd..2d63b677c 100644 --- a/libs/common/src/lib/interfaces/benchmark.interface.ts +++ b/libs/common/src/lib/interfaces/benchmark.interface.ts @@ -3,7 +3,7 @@ import { BenchmarkTrend } from '@ghostfolio/common/types/'; import { EnhancedSymbolProfile } from './enhanced-symbol-profile.interface'; export interface Benchmark { - marketCondition: 'BEAR_MARKET' | 'BULL_MARKET' | 'NEUTRAL_MARKET'; + marketCondition: 'ALL_TIME_HIGH' | 'BEAR_MARKET' | 'NEUTRAL_MARKET'; name: EnhancedSymbolProfile['name']; performances: { allTimeHigh: { diff --git a/libs/ui/src/lib/benchmark/benchmark.component.html b/libs/ui/src/lib/benchmark/benchmark.component.html index 39e1db7c1..c0fdbf956 100644 --- a/libs/ui/src/lib/benchmark/benchmark.component.html +++ b/libs/ui/src/lib/benchmark/benchmark.component.html @@ -89,7 +89,7 @@ 'text-danger': element?.performances?.allTimeHigh?.performancePercent < 0, 'text-success': - element?.performances?.allTimeHigh?.performancePercent > 0 + element?.performances?.allTimeHigh?.performancePercent === 0 }" [value]="element?.performances?.allTimeHigh?.performancePercent" /> From b22edff16bb261fbb7a9c4624fc321f38c025354 Mon Sep 17 00:00:00 2001 From: Thomas Kaul <4159106+dtslvr@users.noreply.github.com> Date: Tue, 12 Dec 2023 19:54:40 +0100 Subject: [PATCH 2/4] Feature/add support for column sorting to lazy loaded activities table (#2738) * Add support for column sorting * Update changelog --- CHANGELOG.md | 1 + .../admin-market-data.component.ts | 10 +++--- .../activities/activities-page.component.ts | 13 +++++-- .../portfolio/activities/activities-page.html | 3 ++ apps/client/src/app/services/admin.service.ts | 5 +-- apps/client/src/app/services/data.service.ts | 5 +-- .../activities-table-lazy.component.html | 34 +++++++------------ .../activities-table-lazy.component.ts | 14 +++++++- .../activities-table-lazy.module.ts | 1 + 9 files changed, 53 insertions(+), 33 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7cdca7fc4..4451972b1 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 25076ca0a..6728843ad 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 a1f596e37..f72f83e97 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 bab5eb066..5ab9999d3 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 116883b18..7e5ce9d0f 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 4300dd421..caab993e0 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 3d7e79a4b..22c9f6354 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, From 0e94112dc77dd9de6e10f0f51265fe2b6f62aebe Mon Sep 17 00:00:00 2001 From: Thomas Kaul <4159106+dtslvr@users.noreply.github.com> Date: Tue, 12 Dec 2023 19:54:58 +0100 Subject: [PATCH 3/4] Feature/adjust holdings weight threshold in trackinsight data enhancer (#2742) * Adjust holdings weight threshold * Update changelog --- CHANGELOG.md | 1 + .../data-enhancer/trackinsight/trackinsight.service.ts | 5 ++++- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4451972b1..ea9a42479 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,6 +14,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Changed +- Adjusted the threshold to skip the data enhancement (_Trackinsight_) if data is inaccurate - Upgraded `prisma` from version `5.6.0` to `5.7.0` ## 2.29.0 - 2023-12-09 diff --git a/apps/api/src/services/data-provider/data-enhancer/trackinsight/trackinsight.service.ts b/apps/api/src/services/data-provider/data-enhancer/trackinsight/trackinsight.service.ts index 4de08fcef..c949a1f22 100644 --- a/apps/api/src/services/data-provider/data-enhancer/trackinsight/trackinsight.service.ts +++ b/apps/api/src/services/data-provider/data-enhancer/trackinsight/trackinsight.service.ts @@ -13,6 +13,7 @@ export class TrackinsightDataEnhancerService implements DataEnhancerInterface { private static countriesMapping = { 'Russian Federation': 'Russia' }; + private static holdingsWeightTreshold = 0.85; private static sectorsMapping = { 'Consumer Discretionary': 'Consumer Cyclical', 'Consumer Defensive': 'Consumer Staples', @@ -113,7 +114,9 @@ export class TrackinsightDataEnhancerService implements DataEnhancerInterface { }); }); - if (holdings?.weight < 0.95) { + if ( + holdings?.weight < TrackinsightDataEnhancerService.holdingsWeightTreshold + ) { // Skip if data is inaccurate return response; } From 67dbef3b7a3674a280cb0ac8a55cdfe9c710bfbb Mon Sep 17 00:00:00 2001 From: Thomas Kaul <4159106+dtslvr@users.noreply.github.com> Date: Tue, 12 Dec 2023 19:56:46 +0100 Subject: [PATCH 4/4] Release 2.30.0 (#2743) --- CHANGELOG.md | 2 +- package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ea9a42479..31cea9617 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,7 +5,7 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). -## Unreleased +## 2.30.0 - 2023-12-12 ### Added diff --git a/package.json b/package.json index 1770499a4..7d043112a 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "ghostfolio", - "version": "2.29.0", + "version": "2.30.0", "homepage": "https://ghostfol.io", "license": "AGPL-3.0", "repository": "https://github.com/ghostfolio/ghostfolio",