Browse Source
Feature/add positions table to public page (#1037)
* Add positions table
* Update changelog
pull/1038/head
Thomas Kaul
3 years ago
committed by
GitHub
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with
49 additions and
12 deletions
-
CHANGELOG.md
-
apps/api/src/app/portfolio/portfolio.controller.ts
-
apps/client/src/app/components/positions-table/positions-table.component.html
-
apps/client/src/app/components/positions-table/positions-table.component.ts
-
apps/client/src/app/pages/public/public-page.component.ts
-
apps/client/src/app/pages/public/public-page.html
-
apps/client/src/app/pages/public/public-page.module.ts
-
libs/common/src/lib/interfaces/portfolio-public-details.interface.ts
|
|
@ -5,6 +5,12 @@ 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 |
|
|
|
|
|
|
|
### Added |
|
|
|
|
|
|
|
- Added the positions table including performance to the public page |
|
|
|
|
|
|
|
## 1.163.0 - 22.06.2022 |
|
|
|
|
|
|
|
### Changed |
|
|
|
|
|
@ -317,7 +317,7 @@ export class PortfolioController { |
|
|
|
const { holdings } = await this.portfolioService.getDetails( |
|
|
|
access.userId, |
|
|
|
access.userId, |
|
|
|
'1d', |
|
|
|
'max', |
|
|
|
[{ id: 'EQUITY', type: 'ASSET_CLASS' }] |
|
|
|
); |
|
|
|
|
|
|
@ -338,12 +338,14 @@ export class PortfolioController { |
|
|
|
|
|
|
|
for (const [symbol, portfolioPosition] of Object.entries(holdings)) { |
|
|
|
portfolioPublicDetails.holdings[symbol] = { |
|
|
|
allocationCurrent: portfolioPosition.allocationCurrent, |
|
|
|
allocationCurrent: portfolioPosition.value / totalValue, |
|
|
|
countries: hasDetails ? portfolioPosition.countries : [], |
|
|
|
currency: portfolioPosition.currency, |
|
|
|
markets: portfolioPosition.markets, |
|
|
|
name: portfolioPosition.name, |
|
|
|
netPerformancePercent: portfolioPosition.netPerformancePercent, |
|
|
|
sectors: hasDetails ? portfolioPosition.sectors : [], |
|
|
|
symbol: portfolioPosition.symbol, |
|
|
|
value: portfolioPosition.value / totalValue |
|
|
|
}; |
|
|
|
} |
|
|
|
|
|
@ -11,7 +11,7 @@ |
|
|
|
Symbol |
|
|
|
</th> |
|
|
|
<td *matCellDef="let element" class="px-1" mat-cell> |
|
|
|
{{ element.symbol | gfSymbol }} |
|
|
|
<span [title]="element.name">{{ element.symbol | gfSymbol }}</span> |
|
|
|
</td> |
|
|
|
</ng-container> |
|
|
|
|
|
|
@ -104,10 +104,13 @@ |
|
|
|
*matRowDef="let row; columns: displayedColumns" |
|
|
|
mat-row |
|
|
|
[ngClass]="{ |
|
|
|
'cursor-pointer': !ignoreAssetSubClasses.includes(row.assetSubClass) |
|
|
|
'cursor-pointer': |
|
|
|
hasPermissionToShowValues && |
|
|
|
!ignoreAssetSubClasses.includes(row.assetSubClass) |
|
|
|
}" |
|
|
|
(click)=" |
|
|
|
!ignoreAssetSubClasses.includes(row.assetSubClass) && |
|
|
|
hasPermissionToShowValues && |
|
|
|
!ignoreAssetSubClasses.includes(row.assetSubClass) && |
|
|
|
onOpenPositionDialog({ dataSource: row.dataSource, symbol: row.symbol }) |
|
|
|
" |
|
|
|
></tr> |
|
|
|
|
|
@ -27,6 +27,7 @@ import { Subject, Subscription } from 'rxjs'; |
|
|
|
export class PositionsTableComponent implements OnChanges, OnDestroy, OnInit { |
|
|
|
@Input() baseCurrency: string; |
|
|
|
@Input() deviceType: string; |
|
|
|
@Input() hasPermissionToShowValues = true; |
|
|
|
@Input() locale: string; |
|
|
|
@Input() positions: PortfolioPosition[]; |
|
|
|
|
|
|
@ -54,13 +55,19 @@ export class PositionsTableComponent implements OnChanges, OnDestroy, OnInit { |
|
|
|
public ngOnInit() {} |
|
|
|
|
|
|
|
public ngOnChanges() { |
|
|
|
this.displayedColumns = [ |
|
|
|
'symbol', |
|
|
|
'value', |
|
|
|
'performance', |
|
|
|
'allocationInvestment', |
|
|
|
'allocationCurrent' |
|
|
|
]; |
|
|
|
this.displayedColumns = ['symbol']; |
|
|
|
|
|
|
|
if (this.hasPermissionToShowValues) { |
|
|
|
this.displayedColumns.push('value'); |
|
|
|
} |
|
|
|
|
|
|
|
this.displayedColumns.push('performance'); |
|
|
|
|
|
|
|
if (this.hasPermissionToShowValues) { |
|
|
|
this.displayedColumns.push('allocationInvestment'); |
|
|
|
} |
|
|
|
|
|
|
|
this.displayedColumns.push('allocationCurrent'); |
|
|
|
|
|
|
|
this.isLoading = true; |
|
|
|
|
|
|
|
|
|
@ -34,6 +34,10 @@ export class PublicPageComponent implements OnInit { |
|
|
|
public positions: { |
|
|
|
[symbol: string]: Pick<PortfolioPosition, 'currency' | 'name' | 'value'>; |
|
|
|
}; |
|
|
|
public positionsArray: Pick< |
|
|
|
PortfolioPosition, |
|
|
|
'currency' | 'name' | 'netPerformancePercent' | 'symbol' | 'value' |
|
|
|
>[]; |
|
|
|
public sectors: { |
|
|
|
[name: string]: { name: string; value: number }; |
|
|
|
}; |
|
|
@ -115,6 +119,7 @@ export class PublicPageComponent implements OnInit { |
|
|
|
} |
|
|
|
}; |
|
|
|
this.positions = {}; |
|
|
|
this.positionsArray = []; |
|
|
|
this.sectors = { |
|
|
|
[UNKNOWN_KEY]: { |
|
|
|
name: UNKNOWN_KEY, |
|
|
@ -139,6 +144,7 @@ export class PublicPageComponent implements OnInit { |
|
|
|
currency: position.currency, |
|
|
|
name: position.name |
|
|
|
}; |
|
|
|
this.positionsArray.push(position); |
|
|
|
|
|
|
|
if (position.countries.length > 0) { |
|
|
|
this.markets.developedMarkets.value += |
|
|
|
|
|
@ -109,6 +109,15 @@ |
|
|
|
</mat-card> |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
<div class="row"> |
|
|
|
<div class="col-lg"> |
|
|
|
<gf-positions-table |
|
|
|
[deviceType]="deviceType" |
|
|
|
[hasPermissionToShowValues]="false" |
|
|
|
[positions]="positionsArray" |
|
|
|
></gf-positions-table> |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
<div class="row my-5"> |
|
|
|
<div class="col-md-10 offset-md-1"> |
|
|
|
<h2 class="h4 mb-1 text-center"> |
|
|
|
|
|
@ -2,6 +2,7 @@ import { CommonModule } from '@angular/common'; |
|
|
|
import { CUSTOM_ELEMENTS_SCHEMA, NgModule } from '@angular/core'; |
|
|
|
import { MatButtonModule } from '@angular/material/button'; |
|
|
|
import { MatCardModule } from '@angular/material/card'; |
|
|
|
import { GfPositionsTableModule } from '@ghostfolio/client/components/positions-table/positions-table.module'; |
|
|
|
import { GfWorldMapChartModule } from '@ghostfolio/client/components/world-map-chart/world-map-chart.module'; |
|
|
|
import { GfPortfolioProportionChartModule } from '@ghostfolio/ui/portfolio-proportion-chart/portfolio-proportion-chart.module'; |
|
|
|
import { GfValueModule } from '@ghostfolio/ui/value'; |
|
|
@ -15,6 +16,7 @@ import { PublicPageComponent } from './public-page.component'; |
|
|
|
imports: [ |
|
|
|
CommonModule, |
|
|
|
GfPortfolioProportionChartModule, |
|
|
|
GfPositionsTableModule, |
|
|
|
GfValueModule, |
|
|
|
GfWorldMapChartModule, |
|
|
|
MatButtonModule, |
|
|
|
|
|
@ -10,7 +10,9 @@ export interface PortfolioPublicDetails { |
|
|
|
| 'currency' |
|
|
|
| 'markets' |
|
|
|
| 'name' |
|
|
|
| 'netPerformancePercent' |
|
|
|
| 'sectors' |
|
|
|
| 'symbol' |
|
|
|
| 'value' |
|
|
|
>; |
|
|
|
}; |
|
|
|