mirror of https://github.com/ghostfolio/ghostfolio
Thomas Kaul
2 years ago
committed by
GitHub
20 changed files with 224 additions and 352 deletions
@ -1,110 +1,15 @@ |
|||||
<div class="container"> |
<router-outlet></router-outlet> |
||||
<h3 class="d-flex justify-content-center mb-3" i18n>Portfolio</h3> |
|
||||
<div class="row"> |
<nav mat-align-tabs="center" mat-tab-nav-bar> |
||||
<div class="col-xs-12 col-md-6 mb-3"> |
<a |
||||
<mat-card class="d-flex flex-column h-100"> |
#rla="routerLinkActive" |
||||
<h4 i18n>Holdings</h4> |
*ngFor="let tab of tabs" |
||||
<div class="flex-grow-1" i18n> |
class="px-3" |
||||
Get an overview of your current holdings. |
mat-tab-link |
||||
</div> |
routerLinkActive |
||||
<div class="mt-2 text-right"> |
[active]="rla.isActive" |
||||
<a |
[routerLink]="tab.path" |
||||
color="primary" |
> |
||||
mat-button |
<ion-icon size="large" [name]="tab.iconName"></ion-icon> |
||||
[routerLink]="['/portfolio', 'holdings']" |
</a> |
||||
> |
</nav> |
||||
<span i18n>Open Holdings</span> |
|
||||
<ion-icon class="ml-1" name="arrow-forward-outline"></ion-icon> |
|
||||
</a> |
|
||||
</div> |
|
||||
</mat-card> |
|
||||
</div> |
|
||||
<div class="col-xs-12 col-md-6 mb-3"> |
|
||||
<mat-card class="d-flex flex-column h-100"> |
|
||||
<h4 i18n>Activities</h4> |
|
||||
<div class="flex-grow-1" i18n> |
|
||||
Manage your activities: stocks, ETFs, cryptocurrencies, dividend, and |
|
||||
valuables. |
|
||||
</div> |
|
||||
<div class="mt-2 text-right"> |
|
||||
<a |
|
||||
color="primary" |
|
||||
mat-button |
|
||||
[routerLink]="['/portfolio', 'activities']" |
|
||||
> |
|
||||
<span i18n>Open Activities</span> |
|
||||
<ion-icon class="ml-1" name="arrow-forward-outline"></ion-icon> |
|
||||
</a> |
|
||||
</div> |
|
||||
</mat-card> |
|
||||
</div> |
|
||||
<div class="col-xs-12 col-md-6 mb-3"> |
|
||||
<mat-card class="d-flex flex-column h-100"> |
|
||||
<h4 i18n>Allocations</h4> |
|
||||
<div class="flex-grow-1" i18n> |
|
||||
Check the allocations of your portfolio by account, asset class, |
|
||||
currency, sector and region. |
|
||||
</div> |
|
||||
<div class="mt-2 text-right"> |
|
||||
<a |
|
||||
color="primary" |
|
||||
mat-button |
|
||||
[routerLink]="['/portfolio', 'allocations']" |
|
||||
> |
|
||||
<span i18n>Open Allocations</span> |
|
||||
<ion-icon class="ml-1" name="arrow-forward-outline"></ion-icon> |
|
||||
</a> |
|
||||
</div> |
|
||||
</mat-card> |
|
||||
</div> |
|
||||
<div class="col-xs-12 col-md-6 mb-3"> |
|
||||
<mat-card class="d-flex flex-column h-100"> |
|
||||
<h4 i18n>Analysis</h4> |
|
||||
<div class="flex-grow-1" i18n> |
|
||||
Ghostfolio Analysis visualizes your portfolio and shows your top and |
|
||||
bottom performers. |
|
||||
</div> |
|
||||
<div class="mt-2 text-right"> |
|
||||
<a |
|
||||
color="primary" |
|
||||
mat-button |
|
||||
[routerLink]="['/portfolio', 'analysis']" |
|
||||
> |
|
||||
<span i18n>Open Analysis</span> |
|
||||
<ion-icon class="ml-1" name="arrow-forward-outline"></ion-icon> |
|
||||
</a> |
|
||||
</div> |
|
||||
</mat-card> |
|
||||
</div> |
|
||||
<div class="col-xs-12 col-md-6 mb-3"> |
|
||||
<mat-card class="d-flex flex-column h-100"> |
|
||||
<h4>X-ray</h4> |
|
||||
<div class="flex-grow-1" i18n> |
|
||||
Ghostfolio X-ray uses static analysis to identify potential issues and |
|
||||
risks in your portfolio. |
|
||||
</div> |
|
||||
<div class="mt-2 text-right"> |
|
||||
<a color="primary" mat-button [routerLink]="['/portfolio', 'report']"> |
|
||||
<span i18n>Open X-ray</span> |
|
||||
<ion-icon class="ml-1" name="arrow-forward-outline"></ion-icon> |
|
||||
</a> |
|
||||
</div> |
|
||||
</mat-card> |
|
||||
</div> |
|
||||
<div class="col-xs-12 col-md-6 mb-3"> |
|
||||
<mat-card class="d-flex flex-column h-100"> |
|
||||
<h4>FIRE</h4> |
|
||||
<div class="flex-grow-1" i18n> |
|
||||
Ghostfolio FIRE calculates metrics for the |
|
||||
<i>Financial Independence, Retire Early</i> lifestyle. |
|
||||
</div> |
|
||||
<div class="mt-2 text-right"> |
|
||||
<a color="primary" mat-button [routerLink]="['/portfolio', 'fire']"> |
|
||||
<span i18n>Open FIRE</span> |
|
||||
<ion-icon class="ml-1" name="arrow-forward-outline"></ion-icon> |
|
||||
</a> |
|
||||
</div> |
|
||||
</mat-card> |
|
||||
</div> |
|
||||
</div> |
|
||||
</div> |
|
||||
|
@ -1,20 +0,0 @@ |
|||||
import { NgModule } from '@angular/core'; |
|
||||
import { RouterModule, Routes } from '@angular/router'; |
|
||||
import { AuthGuard } from '@ghostfolio/client/core/auth.guard'; |
|
||||
|
|
||||
import { ReportPageComponent } from './report-page.component'; |
|
||||
|
|
||||
const routes: Routes = [ |
|
||||
{ |
|
||||
canActivate: [AuthGuard], |
|
||||
component: ReportPageComponent, |
|
||||
path: '', |
|
||||
title: 'X-ray' |
|
||||
} |
|
||||
]; |
|
||||
|
|
||||
@NgModule({ |
|
||||
imports: [RouterModule.forChild(routes)], |
|
||||
exports: [RouterModule] |
|
||||
}) |
|
||||
export class ReportPageRoutingModule {} |
|
@ -1,64 +0,0 @@ |
|||||
import { ChangeDetectorRef, Component, OnDestroy, OnInit } from '@angular/core'; |
|
||||
import { DataService } from '@ghostfolio/client/services/data.service'; |
|
||||
import { UserService } from '@ghostfolio/client/services/user/user.service'; |
|
||||
import { PortfolioReportRule, User } from '@ghostfolio/common/interfaces'; |
|
||||
import { hasPermission, permissions } from '@ghostfolio/common/permissions'; |
|
||||
import { Subject } from 'rxjs'; |
|
||||
import { takeUntil } from 'rxjs/operators'; |
|
||||
|
|
||||
@Component({ |
|
||||
host: { class: 'page' }, |
|
||||
selector: 'gf-report-page', |
|
||||
styleUrls: ['./report-page.scss'], |
|
||||
templateUrl: './report-page.html' |
|
||||
}) |
|
||||
export class ReportPageComponent implements OnDestroy, OnInit { |
|
||||
public accountClusterRiskRules: PortfolioReportRule[]; |
|
||||
public currencyClusterRiskRules: PortfolioReportRule[]; |
|
||||
public feeRules: PortfolioReportRule[]; |
|
||||
public hasPermissionToCreateOrder: boolean; |
|
||||
public user: User; |
|
||||
|
|
||||
private unsubscribeSubject = new Subject<void>(); |
|
||||
|
|
||||
public constructor( |
|
||||
private changeDetectorRef: ChangeDetectorRef, |
|
||||
private dataService: DataService, |
|
||||
private userService: UserService |
|
||||
) {} |
|
||||
|
|
||||
public ngOnInit() { |
|
||||
this.dataService |
|
||||
.fetchPortfolioReport() |
|
||||
.pipe(takeUntil(this.unsubscribeSubject)) |
|
||||
.subscribe((portfolioReport) => { |
|
||||
this.accountClusterRiskRules = |
|
||||
portfolioReport.rules['accountClusterRisk'] || null; |
|
||||
this.currencyClusterRiskRules = |
|
||||
portfolioReport.rules['currencyClusterRisk'] || null; |
|
||||
this.feeRules = portfolioReport.rules['fees'] || null; |
|
||||
|
|
||||
this.changeDetectorRef.markForCheck(); |
|
||||
}); |
|
||||
|
|
||||
this.userService.stateChanged |
|
||||
.pipe(takeUntil(this.unsubscribeSubject)) |
|
||||
.subscribe((state) => { |
|
||||
if (state?.user) { |
|
||||
this.user = state.user; |
|
||||
|
|
||||
this.hasPermissionToCreateOrder = hasPermission( |
|
||||
this.user.permissions, |
|
||||
permissions.createOrder |
|
||||
); |
|
||||
|
|
||||
this.changeDetectorRef.markForCheck(); |
|
||||
} |
|
||||
}); |
|
||||
} |
|
||||
|
|
||||
public ngOnDestroy() { |
|
||||
this.unsubscribeSubject.next(); |
|
||||
this.unsubscribeSubject.complete(); |
|
||||
} |
|
||||
} |
|
@ -1,57 +0,0 @@ |
|||||
<div class="container"> |
|
||||
<div class="row"> |
|
||||
<div class="col"> |
|
||||
<h3 class="align-items-center d-flex justify-content-center mb-3"> |
|
||||
X-ray |
|
||||
</h3> |
|
||||
<p class="mb-4"> |
|
||||
Ghostfolio X-ray uses static analysis to identify potential issues and |
|
||||
risks in your portfolio. |
|
||||
<span class="d-none" |
|
||||
>It will be highly configurable in the future: activate / deactivate |
|
||||
rules and customize the thresholds to match your personal investment |
|
||||
style.</span |
|
||||
> |
|
||||
</p> |
|
||||
<div class="mb-4"> |
|
||||
<h4 class="align-items-center d-flex m-0"> |
|
||||
<span>Currency Cluster Risks</span |
|
||||
><gf-premium-indicator |
|
||||
*ngIf="user?.subscription?.type === 'Basic'" |
|
||||
class="ml-1" |
|
||||
></gf-premium-indicator> |
|
||||
</h4> |
|
||||
<gf-rules |
|
||||
[hasPermissionToCreateOrder]="hasPermissionToCreateOrder" |
|
||||
[rules]="currencyClusterRiskRules" |
|
||||
></gf-rules> |
|
||||
</div> |
|
||||
<div class="mb-4"> |
|
||||
<h4 class="align-items-center d-flex m-0"> |
|
||||
<span>Account Cluster Risks</span |
|
||||
><gf-premium-indicator |
|
||||
*ngIf="user?.subscription?.type === 'Basic'" |
|
||||
class="ml-1" |
|
||||
></gf-premium-indicator> |
|
||||
</h4> |
|
||||
<gf-rules |
|
||||
[hasPermissionToCreateOrder]="hasPermissionToCreateOrder" |
|
||||
[rules]="accountClusterRiskRules" |
|
||||
></gf-rules> |
|
||||
</div> |
|
||||
<div> |
|
||||
<h4 class="align-items-center d-flex m-0"> |
|
||||
<span>Fees</span |
|
||||
><gf-premium-indicator |
|
||||
*ngIf="user?.subscription?.type === 'Basic'" |
|
||||
class="ml-1" |
|
||||
></gf-premium-indicator> |
|
||||
</h4> |
|
||||
<gf-rules |
|
||||
[hasPermissionToCreateOrder]="hasPermissionToCreateOrder" |
|
||||
[rules]="feeRules" |
|
||||
></gf-rules> |
|
||||
</div> |
|
||||
</div> |
|
||||
</div> |
|
||||
</div> |
|
@ -1,19 +0,0 @@ |
|||||
import { CommonModule } from '@angular/common'; |
|
||||
import { CUSTOM_ELEMENTS_SCHEMA, NgModule } from '@angular/core'; |
|
||||
import { RulesModule } from '@ghostfolio/client/components/rules/rules.module'; |
|
||||
import { GfPremiumIndicatorModule } from '@ghostfolio/ui/premium-indicator'; |
|
||||
|
|
||||
import { ReportPageRoutingModule } from './report-page-routing.module'; |
|
||||
import { ReportPageComponent } from './report-page.component'; |
|
||||
|
|
||||
@NgModule({ |
|
||||
declarations: [ReportPageComponent], |
|
||||
imports: [ |
|
||||
CommonModule, |
|
||||
GfPremiumIndicatorModule, |
|
||||
ReportPageRoutingModule, |
|
||||
RulesModule |
|
||||
], |
|
||||
schemas: [CUSTOM_ELEMENTS_SCHEMA] |
|
||||
}) |
|
||||
export class ReportPageModule {} |
|
@ -1,8 +0,0 @@ |
|||||
:host { |
|
||||
color: rgb(var(--dark-primary-text)); |
|
||||
display: block; |
|
||||
} |
|
||||
|
|
||||
:host-context(.is-dark-theme) { |
|
||||
color: rgb(var(--light-primary-text)); |
|
||||
} |
|
Loading…
Reference in new issue