Browse Source

Task/improve type safety in portfolio summary component (#7293)

* fix(client): resolve type errors

* feat(client): enforce encapsulation

* feat(client): replace constructor based DI with inject functions

* feat(client): implement output signal
pull/7299/head
Kenrick Tandrian 4 days ago
committed by GitHub
parent
commit
d10e815a3d
No known key found for this signature in database GPG Key ID: B5690EEEBB952194
  1. 32
      apps/client/src/app/components/portfolio-summary/portfolio-summary.component.ts

32
apps/client/src/app/components/portfolio-summary/portfolio-summary.component.ts

@ -8,10 +8,10 @@ import { GfValueComponent } from '@ghostfolio/ui/value';
import { import {
ChangeDetectionStrategy, ChangeDetectionStrategy,
Component, Component,
EventEmitter, inject,
Input, Input,
OnChanges, OnChanges,
Output output
} from '@angular/core'; } from '@angular/core';
import { MatTooltipModule } from '@angular/material/tooltip'; import { MatTooltipModule } from '@angular/material/tooltip';
import { IonIcon } from '@ionic/angular/standalone'; import { IonIcon } from '@ionic/angular/standalone';
@ -40,44 +40,46 @@ export class GfPortfolioSummaryComponent implements OnChanges {
@Input() summary: PortfolioSummary; @Input() summary: PortfolioSummary;
@Input() user: User; @Input() user: User;
@Output() emergencyFundChanged = new EventEmitter<number>(); public emergencyFundChanged = output<number>();
public buyAndSellActivitiesTooltip = translate( protected readonly buyAndSellActivitiesTooltip = translate(
'BUY_AND_SELL_ACTIVITIES_TOOLTIP' 'BUY_AND_SELL_ACTIVITIES_TOOLTIP'
); );
public precision = 2; protected precision = 2;
public timeInMarket: string; protected timeInMarket: string | undefined;
public get buyingPowerPercentage() { private readonly notificationService = inject(NotificationService);
public constructor() {
addIcons({ ellipsisHorizontalCircleOutline, informationCircleOutline });
}
protected get buyingPowerPercentage() {
return this.summary?.totalValueInBaseCurrency return this.summary?.totalValueInBaseCurrency
? this.summary.cash / this.summary.totalValueInBaseCurrency ? this.summary.cash / this.summary.totalValueInBaseCurrency
: 0; : 0;
} }
public get emergencyFundPercentage() { protected get emergencyFundPercentage() {
return this.summary?.totalValueInBaseCurrency return this.summary?.totalValueInBaseCurrency
? (this.summary.emergencyFund?.total || 0) / ? (this.summary.emergencyFund?.total || 0) /
this.summary.totalValueInBaseCurrency this.summary.totalValueInBaseCurrency
: 0; : 0;
} }
public get excludedFromAnalysisPercentage() { protected get excludedFromAnalysisPercentage() {
return this.summary?.totalValueInBaseCurrency return this.summary?.totalValueInBaseCurrency
? this.summary.excludedAccountsAndActivities / ? this.summary.excludedAccountsAndActivities /
this.summary.totalValueInBaseCurrency this.summary.totalValueInBaseCurrency
: 0; : 0;
} }
public constructor(private notificationService: NotificationService) {
addIcons({ ellipsisHorizontalCircleOutline, informationCircleOutline });
}
public ngOnChanges() { public ngOnChanges() {
if (this.summary) { if (this.summary) {
if ( if (
this.deviceType === 'mobile' && this.deviceType === 'mobile' &&
this.summary.totalValueInBaseCurrency >= (this.summary.totalValueInBaseCurrency ?? 0) >=
NUMERICAL_PRECISION_THRESHOLD_6_FIGURES NUMERICAL_PRECISION_THRESHOLD_6_FIGURES
) { ) {
this.precision = 0; this.precision = 0;
@ -98,7 +100,7 @@ export class GfPortfolioSummaryComponent implements OnChanges {
} }
} }
public onEditEmergencyFund() { protected onEditEmergencyFund() {
this.notificationService.prompt({ this.notificationService.prompt({
confirmFn: (value) => { confirmFn: (value) => {
const emergencyFund = parseFloat(value.trim()) || 0; const emergencyFund = parseFloat(value.trim()) || 0;

Loading…
Cancel
Save