diff --git a/apps/api/src/app/portfolio/portfolio.controller.ts b/apps/api/src/app/portfolio/portfolio.controller.ts index 797d0449a..f95499f0b 100644 --- a/apps/api/src/app/portfolio/portfolio.controller.ts +++ b/apps/api/src/app/portfolio/portfolio.controller.ts @@ -389,6 +389,14 @@ export class PortfolioController { filterByTags }); + const { performance } = await this.portfolioService.getPerformance({ + dateRange, + filters, + impersonationId, + userId: this.request.user.id, + withExcludedAccounts: false + }); + const { holdings } = await this.portfolioService.getDetails({ dateRange, filters, @@ -396,7 +404,7 @@ export class PortfolioController { userId: this.request.user.id }); - return { holdings: Object.values(holdings) }; + return { holdings: Object.values(holdings), performance }; } @Get('investments') diff --git a/apps/client/src/app/components/home-holdings/home-holdings.component.ts b/apps/client/src/app/components/home-holdings/home-holdings.component.ts index dd411f6cc..652e2831e 100644 --- a/apps/client/src/app/components/home-holdings/home-holdings.component.ts +++ b/apps/client/src/app/components/home-holdings/home-holdings.component.ts @@ -3,6 +3,7 @@ import { ImpersonationStorageService } from '@ghostfolio/client/services/imperso import { UserService } from '@ghostfolio/client/services/user/user.service'; import { AssetProfileIdentifier, + PortfolioPerformance, PortfolioPosition, ToggleOption, User @@ -36,6 +37,7 @@ export class HomeHoldingsComponent implements OnDestroy, OnInit { { label: $localize`Active`, value: 'ACTIVE' }, { label: $localize`Closed`, value: 'CLOSED' } ]; + public performance: PortfolioPerformance; public user: User; public viewModeFormControl = new FormControl( HomeHoldingsComponent.DEFAULT_HOLDINGS_VIEW_MODE @@ -162,8 +164,9 @@ export class HomeHoldingsComponent implements OnDestroy, OnInit { this.fetchHoldings() .pipe(takeUntil(this.unsubscribeSubject)) - .subscribe(({ holdings }) => { + .subscribe(({ holdings, performance }) => { this.holdings = holdings; + this.performance = performance; this.changeDetectorRef.markForCheck(); }); diff --git a/apps/client/src/app/components/home-holdings/home-holdings.html b/apps/client/src/app/components/home-holdings/home-holdings.html index abbc93b3d..5c55845fc 100644 --- a/apps/client/src/app/components/home-holdings/home-holdings.html +++ b/apps/client/src/app/components/home-holdings/home-holdings.html @@ -51,6 +51,7 @@ [hasPermissionToCreateActivity]="hasPermissionToCreateOrder" [holdings]="holdings" [locale]="user?.settings?.locale" + [performance]="performance" (holdingClicked)="onHoldingClicked($event)" /> @if (hasPermissionToCreateOrder && holdings?.length > 0) { diff --git a/libs/common/src/lib/interfaces/responses/portfolio-holdings-response.interface.ts b/libs/common/src/lib/interfaces/responses/portfolio-holdings-response.interface.ts index d2cf38f55..7702bac6c 100644 --- a/libs/common/src/lib/interfaces/responses/portfolio-holdings-response.interface.ts +++ b/libs/common/src/lib/interfaces/responses/portfolio-holdings-response.interface.ts @@ -1,5 +1,9 @@ -import { PortfolioPosition } from '@ghostfolio/common/interfaces'; +import { + PortfolioPerformance, + PortfolioPosition +} from '@ghostfolio/common/interfaces'; export interface PortfolioHoldingsResponse { holdings: PortfolioPosition[]; + performance: PortfolioPerformance; } diff --git a/libs/ui/src/lib/holdings-table/holdings-table.component.html b/libs/ui/src/lib/holdings-table/holdings-table.component.html index f27a23f11..042468429 100644 --- a/libs/ui/src/lib/holdings-table/holdings-table.component.html +++ b/libs/ui/src/lib/holdings-table/holdings-table.component.html @@ -39,7 +39,7 @@ {{ element.symbol }} - Total + Total @@ -95,11 +95,7 @@ - + @@ -153,7 +149,7 @@ [isCurrency]="true" [locale]="locale" [value]="totalChange" - > + /> @@ -189,7 +185,7 @@ [isPercent]="true" [locale]="locale" [value]="totalChangePercentage" - > + /> @@ -214,7 +210,7 @@ diff --git a/libs/ui/src/lib/holdings-table/holdings-table.component.ts b/libs/ui/src/lib/holdings-table/holdings-table.component.ts index b02261377..259567d0c 100644 --- a/libs/ui/src/lib/holdings-table/holdings-table.component.ts +++ b/libs/ui/src/lib/holdings-table/holdings-table.component.ts @@ -3,6 +3,7 @@ import { GfSymbolModule } from '@ghostfolio/client/pipes/symbol/symbol.module'; import { getLocale } from '@ghostfolio/common/helper'; import { AssetProfileIdentifier, + PortfolioPerformance, PortfolioPosition } from '@ghostfolio/common/interfaces'; import { GfNoTransactionsInfoComponent } from '@ghostfolio/ui/no-transactions-info'; @@ -58,6 +59,7 @@ export class GfHoldingsTableComponent implements OnChanges, OnDestroy { @Input() holdings: PortfolioPosition[]; @Input() locale = getLocale(); @Input() pageSize = Number.MAX_SAFE_INTEGER; + @Input() performance: PortfolioPerformance; @Output() holdingClicked = new EventEmitter(); @@ -70,9 +72,9 @@ export class GfHoldingsTableComponent implements OnChanges, OnDestroy { public isLoading = true; public routeQueryParams: Subscription; - protected totalValue = 0; protected totalChange = 0; protected totalChangePercentage = 0; + protected totalValue = 0; private unsubscribeSubject = new Subject(); @@ -96,16 +98,12 @@ export class GfHoldingsTableComponent implements OnChanges, OnDestroy { this.dataSource = new MatTableDataSource(this.holdings); this.dataSource.paginator = this.paginator; this.dataSource.sort = this.sort; - this.totalValue = this.dataSource.data.reduce( - (sum, current) => (sum += current.valueInBaseCurrency), - 0 - ); - this.totalChange = this.dataSource.data.reduce( - (sum, current) => (sum += current.netPerformanceWithCurrencyEffect), - 0 - ); + + this.totalChange = + this.performance.netPerformancePercentageWithCurrencyEffect; this.totalChangePercentage = - this.totalChange / (this.totalValue - this.totalChange); + this.performance.netPerformancePercentageWithCurrencyEffect; + this.totalValue = this.performance.currentValueInBaseCurrency; if (this.holdings) { this.isLoading = false;