Browse Source

Start with implementation

pull/110/head
Thomas 4 years ago
parent
commit
7c1312477d
  1. 5
      apps/client/src/app/app-routing.module.ts
  2. 15
      apps/client/src/app/pages/account/account-page.component.ts
  3. 16
      apps/client/src/app/pages/account/account-page.html
  4. 10
      apps/client/src/app/pages/home/home-page.component.ts
  5. 2
      apps/client/src/app/pages/home/home-page.module.ts
  6. 15
      apps/client/src/app/pages/zen/zen-page-routing.module.ts
  7. 104
      apps/client/src/app/pages/zen/zen-page.component.ts
  8. 25
      apps/client/src/app/pages/zen/zen-page.html
  9. 23
      apps/client/src/app/pages/zen/zen-page.module.ts
  10. 39
      apps/client/src/app/pages/zen/zen-page.scss
  11. 1
      libs/common/src/lib/interfaces/user-settings.interface.ts

5
apps/client/src/app/app-routing.module.ts

@ -78,6 +78,11 @@ const routes: Routes = [
(m) => m.TransactionsPageModule
)
},
{
path: 'zen',
loadChildren: () =>
import('./pages/zen/zen-page.module').then((m) => m.ZenPageModule)
},
{
// wildcard, if requested url doesn't match any paths for routes defined
// earlier

15
apps/client/src/app/pages/account/account-page.component.ts

@ -51,6 +51,8 @@ export class AccountPageComponent implements OnDestroy, OnInit {
this.dataService.fetchUser().subscribe((user) => {
this.user = user;
this.user.settings.mode = 'ZEN';
this.hasPermissionToUpdateUserSettings = hasPermission(
this.user.permissions,
permissions.updateUserSettings
@ -81,6 +83,19 @@ export class AccountPageComponent implements OnDestroy, OnInit {
});
}
public onChangeMode({ value: mode }: { value: Currency }) {
/*this.dataService
.putUserSettings({ currency })
.pipe(takeUntil(this.unsubscribeSubject))
.subscribe(() => {
this.dataService.fetchUser().subscribe((user) => {
this.user = user;
this.cd.markForCheck();
});
});*/
}
public ngOnDestroy() {
this.unsubscribeSubject.next();
this.unsubscribeSubject.complete();

16
apps/client/src/app/pages/account/account-page.html

@ -30,7 +30,7 @@
<div class="d-flex mt-4 py-1">
<div class="pt-4 w-50" i18n>Settings</div>
<div class="w-50">
<form #addTransactionForm="ngForm">
<form #changeBaseCurrencyForm="ngForm">
<mat-form-field appearance="outline" class="w-100">
<mat-label i18n>Base Currency</mat-label>
<mat-select
@ -47,6 +47,20 @@
</mat-select>
</mat-form-field>
</form>
<form #changeModeForm="ngForm">
<mat-form-field appearance="outline" class="w-100">
<mat-label i18n>Mode</mat-label>
<mat-select
name="baseCurrency"
[disabled]="!hasPermissionToUpdateUserSettings"
[value]="user.settings.mode"
(selectionChange)="onChangeMode($event)"
>
<mat-option value="DEFAULT">Default</mat-option>
<mat-option value="ZEN">Zen</mat-option>
</mat-select>
</mat-form-field>
</form>
</div>
</div>
</mat-card-content>

10
apps/client/src/app/pages/home/home-page.component.ts

@ -132,6 +132,11 @@ export class HomePageComponent implements OnDestroy, OnInit {
this.update();
}
public ngOnDestroy() {
this.unsubscribeSubject.next();
this.unsubscribeSubject.complete();
}
private openDialog(): void {
const dialogRef = this.dialog.open(PerformanceChartDialog, {
autoFocus: false,
@ -195,9 +200,4 @@ export class HomePageComponent implements OnDestroy, OnInit {
this.cd.markForCheck();
}
public ngOnDestroy() {
this.unsubscribeSubject.next();
this.unsubscribeSubject.complete();
}
}

2
apps/client/src/app/pages/home/home-page.module.ts

@ -1,6 +1,5 @@
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 { RouterModule } from '@angular/router';
import { GfLineChartModule } from '@ghostfolio/client/components/line-chart/line-chart.module';
@ -27,7 +26,6 @@ import { HomePageComponent } from './home-page.component';
GfPositionsModule,
GfToggleModule,
HomePageRoutingModule,
MatButtonModule,
MatCardModule,
RouterModule
],

15
apps/client/src/app/pages/zen/zen-page-routing.module.ts

@ -0,0 +1,15 @@
import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';
import { AuthGuard } from '@ghostfolio/client/core/auth.guard';
import { ZenPageComponent } from './zen-page.component';
const routes: Routes = [
{ path: '', component: ZenPageComponent, canActivate: [AuthGuard] }
];
@NgModule({
imports: [RouterModule.forChild(routes)],
exports: [RouterModule]
})
export class ZenPageRoutingModule {}

104
apps/client/src/app/pages/zen/zen-page.component.ts

@ -0,0 +1,104 @@
import { ChangeDetectorRef, Component, OnDestroy, OnInit } from '@angular/core';
import { LineChartItem } from '@ghostfolio/client/components/line-chart/interfaces/line-chart.interface';
import { DataService } from '@ghostfolio/client/services/data.service';
import { ImpersonationStorageService } from '@ghostfolio/client/services/impersonation-storage.service';
import { TokenStorageService } from '@ghostfolio/client/services/token-storage.service';
import { PortfolioPerformance, User } from '@ghostfolio/common/interfaces';
import { hasPermission, permissions } from '@ghostfolio/common/permissions';
import { DateRange } from '@ghostfolio/common/types';
import { DeviceDetectorService } from 'ngx-device-detector';
import { Subject } from 'rxjs';
import { takeUntil } from 'rxjs/operators';
@Component({
selector: 'gf-zen-page',
templateUrl: './zen-page.html',
styleUrls: ['./zen-page.scss']
})
export class ZenPageComponent implements OnDestroy, OnInit {
public dateRange: DateRange = 'max';
public deviceType: string;
public hasImpersonationId: boolean;
public hasPermissionToReadForeignPortfolio: boolean;
public historicalDataItems: LineChartItem[];
public isLoadingPerformance = true;
public performance: PortfolioPerformance;
public user: User;
private unsubscribeSubject = new Subject<void>();
/**
* @constructor
*/
public constructor(
private cd: ChangeDetectorRef,
private dataService: DataService,
private deviceService: DeviceDetectorService,
private impersonationStorageService: ImpersonationStorageService,
private tokenStorageService: TokenStorageService
) {
this.tokenStorageService
.onChangeHasToken()
.pipe(takeUntil(this.unsubscribeSubject))
.subscribe(() => {
this.dataService.fetchUser().subscribe((user) => {
this.user = user;
this.hasPermissionToReadForeignPortfolio = hasPermission(
user.permissions,
permissions.readForeignPortfolio
);
this.cd.markForCheck();
});
});
}
/**
* Initializes the controller
*/
public ngOnInit() {
this.deviceType = this.deviceService.getDeviceInfo().deviceType;
this.impersonationStorageService
.onChangeHasImpersonation()
.subscribe((aId) => {
this.hasImpersonationId = !!aId;
});
this.update();
}
public ngOnDestroy() {
this.unsubscribeSubject.next();
this.unsubscribeSubject.complete();
}
private update() {
this.isLoadingPerformance = true;
this.dataService
.fetchChart({ range: this.dateRange })
.subscribe((chartData) => {
this.historicalDataItems = chartData.map((chartDataItem) => {
return {
date: chartDataItem.date,
value: chartDataItem.value
};
});
this.cd.markForCheck();
});
this.dataService
.fetchPortfolioPerformance({ range: this.dateRange })
.subscribe((response) => {
this.performance = response;
this.isLoadingPerformance = false;
this.cd.markForCheck();
});
this.cd.markForCheck();
}
}

25
apps/client/src/app/pages/zen/zen-page.html

@ -0,0 +1,25 @@
<div class="container">
<div class="row">
<div class="chart-container col mr-3">
<gf-line-chart
symbol="Performance"
[historicalDataItems]="historicalDataItems"
[showLoader]="false"
[showXAxis]="false"
[showYAxis]="false"
></gf-line-chart>
</div>
</div>
<div class="overview-container row mb-5 mt-1">
<div class="col">
<gf-portfolio-performance-summary
class="pb-4"
[baseCurrency]="user?.settings?.baseCurrency"
[isLoading]="isLoadingPerformance"
[locale]="user?.settings?.locale"
[performance]="performance"
[showDetails]="!hasImpersonationId || hasPermissionToReadForeignPortfolio"
></gf-portfolio-performance-summary>
</div>
</div>
</div>

23
apps/client/src/app/pages/zen/zen-page.module.ts

@ -0,0 +1,23 @@
import { CommonModule } from '@angular/common';
import { CUSTOM_ELEMENTS_SCHEMA, NgModule } from '@angular/core';
import { MatCardModule } from '@angular/material/card';
import { GfLineChartModule } from '@ghostfolio/client/components/line-chart/line-chart.module';
import { GfPortfolioPerformanceSummaryModule } from '@ghostfolio/client/components/portfolio-performance-summary/portfolio-performance-summary.module';
import { ZenPageRoutingModule } from './zen-page-routing.module';
import { ZenPageComponent } from './zen-page.component';
@NgModule({
declarations: [ZenPageComponent],
exports: [],
imports: [
CommonModule,
GfLineChartModule,
GfPortfolioPerformanceSummaryModule,
MatCardModule,
ZenPageRoutingModule
],
providers: [],
schemas: [CUSTOM_ELEMENTS_SCHEMA]
})
export class ZenPageModule {}

39
apps/client/src/app/pages/zen/zen-page.scss

@ -0,0 +1,39 @@
:host {
color: rgb(var(--dark-primary-text));
display: block;
.chart-container {
aspect-ratio: 16 / 9;
cursor: pointer;
margin-top: -1rem;
max-height: 50vh;
// Fallback for aspect-ratio (using padding hack)
@supports not (aspect-ratio: 16 / 9) {
&::before {
float: left;
padding-top: 56.25%;
content: '';
}
&::after {
display: block;
content: '';
clear: both;
}
}
gf-line-chart {
bottom: 0;
left: 0;
position: absolute;
right: 0;
top: 0;
z-index: -1;
}
}
}
:host-context(.is-dark-theme) {
color: rgb(var(--light-primary-text));
}

1
libs/common/src/lib/interfaces/user-settings.interface.ts

@ -3,4 +3,5 @@ import { Currency } from '@prisma/client';
export interface UserSettings {
baseCurrency: Currency;
locale: string;
mode: 'DEFAULT' | 'ZEN';
}

Loading…
Cancel
Save