Browse Source

Merge eb83ffcb56 into a8937fbf04

pull/4370/merge
dandevaud 3 months ago
committed by GitHub
parent
commit
814fe0fb31
No known key found for this signature in database GPG Key ID: B5690EEEBB952194
  1. 10
      apps/api/src/app/portfolio/portfolio.controller.ts
  2. 5
      apps/client/src/app/components/home-holdings/home-holdings.component.ts
  3. 1
      apps/client/src/app/components/home-holdings/home-holdings.html
  4. 6
      libs/common/src/lib/interfaces/responses/portfolio-holdings-response.interface.ts
  5. 37
      libs/ui/src/lib/holdings-table/holdings-table.component.html
  6. 12
      libs/ui/src/lib/holdings-table/holdings-table.component.ts

10
apps/api/src/app/portfolio/portfolio.controller.ts

@ -417,6 +417,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,
@ -424,7 +432,7 @@ export class PortfolioController {
userId: this.request.user.id
});
return { holdings: Object.values(holdings) };
return { holdings: Object.values(holdings), performance };
}
@Get('investments')

5
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<HoldingsViewMode>(
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();
});

1
apps/client/src/app/components/home-holdings/home-holdings.html

@ -50,6 +50,7 @@
[deviceType]="deviceType"
[holdings]="holdings"
[locale]="user?.settings?.locale"
[performance]="performance"
(holdingClicked)="onHoldingClicked($event)"
/>
@if (hasPermissionToCreateOrder && holdings?.length > 0) {

6
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;
}

37
libs/ui/src/lib/holdings-table/holdings-table.component.html

@ -16,6 +16,7 @@
[tooltip]="element.name"
/>
</td>
<td *matFooterCellDef class="px-1" mat-footer-cell></td>
</ng-container>
<ng-container matColumnDef="nameWithSymbol">
@ -38,6 +39,7 @@
<small class="text-muted">{{ element.symbol }}</small>
</div>
</td>
<td *matFooterCellDef class="px-1" i18n mat-footer-cell>Total</td>
</ng-container>
<ng-container matColumnDef="dateOfFirstActivity">
@ -62,6 +64,11 @@
/>
</div>
</td>
<td
*matFooterCellDef
class="d-none d-lg-table-cell justify-content-end px-1"
mat-footer-cell
></td>
</ng-container>
<ng-container matColumnDef="valueInBaseCurrency">
@ -86,6 +93,10 @@
/>
</div>
</td>
<td *matFooterCellDef class="d-none d-lg-table-cell px-1" mat-footer-cell>
<gf-value [isCurrency]="true" [locale]="locale" [value]="totalValue" />
</td>
</ng-container>
<ng-container matColumnDef="allocationInPercentage">
@ -107,6 +118,7 @@
/>
</div>
</td>
<td *matFooterCellDef class="px-1" mat-footer-cell></td>
</ng-container>
<ng-container matColumnDef="performance">
@ -130,6 +142,16 @@
/>
</div>
</td>
<td *matFooterCellDef class="px-1" mat-footer-cell>
<div class="d-flex justify-content-end">
<gf-value
[colorizeSign]="true"
[isCurrency]="true"
[locale]="locale"
[value]="totalChange"
/>
</div>
</td>
</ng-container>
<ng-container matColumnDef="performanceInPercentage" stickyEnd>
@ -156,6 +178,16 @@
/>
</div>
</td>
<td *matFooterCellDef class="px-1" mat-footer-cell>
<div class="d-flex justify-content-end">
<gf-value
[colorizeSign]="true"
[isPercent]="true"
[locale]="locale"
[value]="totalChangePercentage"
/>
</div>
</td>
</ng-container>
<tr *matHeaderRowDef="displayedColumns" mat-header-row></tr>
@ -175,6 +207,11 @@
})
"
></tr>
<tr
*matFooterRowDef="displayedColumns"
mat-footer-row
[ngClass]="{ 'd-none': isLoading }"
></tr>
</table>
</div>

12
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 { GfValueComponent } from '@ghostfolio/ui/value';
@ -55,6 +56,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<AssetProfileIdentifier>();
@ -67,6 +69,10 @@ export class GfHoldingsTableComponent implements OnChanges, OnDestroy {
public isLoading = true;
public routeQueryParams: Subscription;
protected totalChange = 0;
protected totalChangePercentage = 0;
protected totalValue = 0;
private unsubscribeSubject = new Subject<void>();
public ngOnChanges() {
@ -90,6 +96,12 @@ export class GfHoldingsTableComponent implements OnChanges, OnDestroy {
this.dataSource.paginator = this.paginator;
this.dataSource.sort = this.sort;
this.totalChange =
this.performance.netPerformancePercentageWithCurrencyEffect;
this.totalChangePercentage =
this.performance.netPerformancePercentageWithCurrencyEffect;
this.totalValue = this.performance.currentValueInBaseCurrency;
if (this.holdings) {
this.isLoading = false;
}

Loading…
Cancel
Save