|
@ -1,21 +1,37 @@ |
|
|
import { ChangeDetectorRef, Component, OnDestroy, OnInit } from '@angular/core'; |
|
|
import { ViewportScroller } from '@angular/common'; |
|
|
|
|
|
import { |
|
|
|
|
|
AfterViewInit, |
|
|
|
|
|
ChangeDetectorRef, |
|
|
|
|
|
Component, |
|
|
|
|
|
ElementRef, |
|
|
|
|
|
OnDestroy, |
|
|
|
|
|
OnInit, |
|
|
|
|
|
ViewChild |
|
|
|
|
|
} from '@angular/core'; |
|
|
|
|
|
import { ActivatedRoute } from '@angular/router'; |
|
|
import { LineChartItem } from '@ghostfolio/client/components/line-chart/interfaces/line-chart.interface'; |
|
|
import { LineChartItem } from '@ghostfolio/client/components/line-chart/interfaces/line-chart.interface'; |
|
|
import { DataService } from '@ghostfolio/client/services/data.service'; |
|
|
import { DataService } from '@ghostfolio/client/services/data.service'; |
|
|
import { ImpersonationStorageService } from '@ghostfolio/client/services/impersonation-storage.service'; |
|
|
import { ImpersonationStorageService } from '@ghostfolio/client/services/impersonation-storage.service'; |
|
|
import { UserService } from '@ghostfolio/client/services/user/user.service'; |
|
|
import { UserService } from '@ghostfolio/client/services/user/user.service'; |
|
|
import { PortfolioPerformance, User } from '@ghostfolio/common/interfaces'; |
|
|
import { |
|
|
|
|
|
PortfolioPerformance, |
|
|
|
|
|
PortfolioPosition, |
|
|
|
|
|
User |
|
|
|
|
|
} from '@ghostfolio/common/interfaces'; |
|
|
import { hasPermission, permissions } from '@ghostfolio/common/permissions'; |
|
|
import { hasPermission, permissions } from '@ghostfolio/common/permissions'; |
|
|
import { DateRange } from '@ghostfolio/common/types'; |
|
|
import { DateRange } from '@ghostfolio/common/types'; |
|
|
import { DeviceDetectorService } from 'ngx-device-detector'; |
|
|
import { DeviceDetectorService } from 'ngx-device-detector'; |
|
|
import { Subject } from 'rxjs'; |
|
|
import { Subject } from 'rxjs'; |
|
|
import { takeUntil } from 'rxjs/operators'; |
|
|
import { first, takeUntil } from 'rxjs/operators'; |
|
|
|
|
|
|
|
|
@Component({ |
|
|
@Component({ |
|
|
selector: 'gf-zen-page', |
|
|
selector: 'gf-zen-page', |
|
|
templateUrl: './zen-page.html', |
|
|
templateUrl: './zen-page.html', |
|
|
styleUrls: ['./zen-page.scss'] |
|
|
styleUrls: ['./zen-page.scss'] |
|
|
}) |
|
|
}) |
|
|
export class ZenPageComponent implements OnDestroy, OnInit { |
|
|
export class ZenPageComponent implements AfterViewInit, OnDestroy, OnInit { |
|
|
|
|
|
@ViewChild('positionsContainer') positionsContainer: ElementRef; |
|
|
|
|
|
|
|
|
public dateRange: DateRange = 'max'; |
|
|
public dateRange: DateRange = 'max'; |
|
|
public deviceType: string; |
|
|
public deviceType: string; |
|
|
public hasImpersonationId: boolean; |
|
|
public hasImpersonationId: boolean; |
|
@ -24,6 +40,8 @@ export class ZenPageComponent implements OnDestroy, OnInit { |
|
|
public historicalDataItems: LineChartItem[]; |
|
|
public historicalDataItems: LineChartItem[]; |
|
|
public isLoadingPerformance = true; |
|
|
public isLoadingPerformance = true; |
|
|
public performance: PortfolioPerformance; |
|
|
public performance: PortfolioPerformance; |
|
|
|
|
|
public positions: { [symbol: string]: PortfolioPosition }; |
|
|
|
|
|
public showPositionsButton: boolean; |
|
|
public user: User; |
|
|
public user: User; |
|
|
|
|
|
|
|
|
private unsubscribeSubject = new Subject<void>(); |
|
|
private unsubscribeSubject = new Subject<void>(); |
|
@ -32,11 +50,13 @@ export class ZenPageComponent implements OnDestroy, OnInit { |
|
|
* @constructor |
|
|
* @constructor |
|
|
*/ |
|
|
*/ |
|
|
public constructor( |
|
|
public constructor( |
|
|
|
|
|
private route: ActivatedRoute, |
|
|
private changeDetectorRef: ChangeDetectorRef, |
|
|
private changeDetectorRef: ChangeDetectorRef, |
|
|
private dataService: DataService, |
|
|
private dataService: DataService, |
|
|
private deviceService: DeviceDetectorService, |
|
|
private deviceService: DeviceDetectorService, |
|
|
private impersonationStorageService: ImpersonationStorageService, |
|
|
private impersonationStorageService: ImpersonationStorageService, |
|
|
private userService: UserService |
|
|
private userService: UserService, |
|
|
|
|
|
private viewportScroller: ViewportScroller |
|
|
) { |
|
|
) { |
|
|
this.userService.stateChanged |
|
|
this.userService.stateChanged |
|
|
.pipe(takeUntil(this.unsubscribeSubject)) |
|
|
.pipe(takeUntil(this.unsubscribeSubject)) |
|
@ -54,9 +74,6 @@ export class ZenPageComponent implements OnDestroy, OnInit { |
|
|
}); |
|
|
}); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
/** |
|
|
|
|
|
* Initializes the controller |
|
|
|
|
|
*/ |
|
|
|
|
|
public ngOnInit() { |
|
|
public ngOnInit() { |
|
|
this.deviceType = this.deviceService.getDeviceInfo().deviceType; |
|
|
this.deviceType = this.deviceService.getDeviceInfo().deviceType; |
|
|
|
|
|
|
|
@ -70,6 +87,12 @@ export class ZenPageComponent implements OnDestroy, OnInit { |
|
|
this.update(); |
|
|
this.update(); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
public ngAfterViewInit(): void { |
|
|
|
|
|
this.route.fragment |
|
|
|
|
|
.pipe(first()) |
|
|
|
|
|
.subscribe((fragment) => this.viewportScroller.scrollToAnchor(fragment)); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
public ngOnDestroy() { |
|
|
public ngOnDestroy() { |
|
|
this.unsubscribeSubject.next(); |
|
|
this.unsubscribeSubject.next(); |
|
|
this.unsubscribeSubject.complete(); |
|
|
this.unsubscribeSubject.complete(); |
|
@ -89,8 +112,6 @@ export class ZenPageComponent implements OnDestroy, OnInit { |
|
|
}; |
|
|
}; |
|
|
}); |
|
|
}); |
|
|
|
|
|
|
|
|
this.hasPositions = this.historicalDataItems?.length > 0; |
|
|
|
|
|
|
|
|
|
|
|
this.changeDetectorRef.markForCheck(); |
|
|
this.changeDetectorRef.markForCheck(); |
|
|
}); |
|
|
}); |
|
|
|
|
|
|
|
@ -104,6 +125,18 @@ export class ZenPageComponent implements OnDestroy, OnInit { |
|
|
this.changeDetectorRef.markForCheck(); |
|
|
this.changeDetectorRef.markForCheck(); |
|
|
}); |
|
|
}); |
|
|
|
|
|
|
|
|
|
|
|
this.dataService |
|
|
|
|
|
.fetchPortfolioPositions({ range: this.dateRange }) |
|
|
|
|
|
.pipe(takeUntil(this.unsubscribeSubject)) |
|
|
|
|
|
.subscribe((response) => { |
|
|
|
|
|
this.positions = response; |
|
|
|
|
|
this.hasPositions = |
|
|
|
|
|
this.positions && Object.keys(this.positions).length > 1; |
|
|
|
|
|
this.showPositionsButton = this.hasPositions; |
|
|
|
|
|
|
|
|
|
|
|
this.changeDetectorRef.markForCheck(); |
|
|
|
|
|
}); |
|
|
|
|
|
|
|
|
this.changeDetectorRef.markForCheck(); |
|
|
this.changeDetectorRef.markForCheck(); |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|