Browse Source

Feature/persist savings rate (#849)

* Persist savings rate

* Update changelog
pull/850/head
Thomas Kaul 3 years ago
committed by GitHub
parent
commit
20358d9105
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 1
      CHANGELOG.md
  2. 4
      apps/api/src/app/user/update-user-setting.dto.ts
  3. 7
      apps/client/src/app/pages/portfolio/fire/fire-page.component.ts
  4. 4
      apps/client/src/app/pages/portfolio/fire/fire-page.html
  5. 40
      libs/ui/src/lib/fire-calculator/fire-calculator.component.ts

1
CHANGELOG.md

@ -14,6 +14,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Changed ### Changed
- Reused the value component in the _Ghostfolio in Numbers_ section of the about page - Reused the value component in the _Ghostfolio in Numbers_ section of the about page
- Persisted the savings rate in the _FIRE_ calculator
- Upgraded `yahoo-finance2` from version `2.3.0` to `2.3.1` - Upgraded `yahoo-finance2` from version `2.3.0` to `2.3.1`
## 1.139.0 - 18.04.2022 ## 1.139.0 - 18.04.2022

4
apps/api/src/app/user/update-user-setting.dto.ts

@ -12,4 +12,8 @@ export class UpdateUserSettingDto {
@IsString() @IsString()
@IsOptional() @IsOptional()
locale?: string; locale?: string;
@IsNumber()
@IsOptional()
savingsRate?: number;
} }

7
apps/client/src/app/pages/portfolio/fire/fire-page.component.ts

@ -68,6 +68,13 @@ export class FirePageComponent implements OnDestroy, OnInit {
}); });
} }
public onSavingsRateChange(savingsRate: number) {
this.dataService
.putUserSetting({ savingsRate })
.pipe(takeUntil(this.unsubscribeSubject))
.subscribe(() => {});
}
public ngOnDestroy() { public ngOnDestroy() {
this.unsubscribeSubject.next(); this.unsubscribeSubject.next();
this.unsubscribeSubject.complete(); this.unsubscribeSubject.complete();

4
apps/client/src/app/pages/portfolio/fire/fire-page.html

@ -41,7 +41,7 @@
[value]="withdrawalRatePerMonth?.toNumber()" [value]="withdrawalRatePerMonth?.toNumber()"
></gf-value> ></gf-value>
per month</span per month</span
>, based on your investment of >, based on your total assets of
<gf-value <gf-value
class="d-inline-block" class="d-inline-block"
[currency]="user?.settings?.baseCurrency" [currency]="user?.settings?.baseCurrency"
@ -60,6 +60,8 @@
[deviceType]="deviceType" [deviceType]="deviceType"
[fireWealth]="fireWealth?.toNumber()" [fireWealth]="fireWealth?.toNumber()"
[locale]="user?.settings?.locale" [locale]="user?.settings?.locale"
[savingsRate]="user?.settings?.savingsRate"
(savingsRateChanged)="onSavingsRateChange($event)"
></gf-fire-calculator> ></gf-fire-calculator>
</div> </div>
</div> </div>

40
libs/ui/src/lib/fire-calculator/fire-calculator.component.ts

@ -5,9 +5,11 @@ import {
ChangeDetectionStrategy, ChangeDetectionStrategy,
ChangeDetectorRef, ChangeDetectorRef,
Component, Component,
EventEmitter,
Input, Input,
OnChanges, OnChanges,
OnDestroy, OnDestroy,
Output,
ViewChild ViewChild
} from '@angular/core'; } from '@angular/core';
import { FormBuilder, FormControl } from '@angular/forms'; import { FormBuilder, FormControl } from '@angular/forms';
@ -40,6 +42,9 @@ export class FireCalculatorComponent
@Input() deviceType: string; @Input() deviceType: string;
@Input() fireWealth: number; @Input() fireWealth: number;
@Input() locale: string; @Input() locale: string;
@Input() savingsRate = 0;
@Output() savingsRateChanged = new EventEmitter<number>();
@ViewChild('chartCanvas') chartCanvas; @ViewChild('chartCanvas') chartCanvas;
@ -73,7 +78,7 @@ export class FireCalculatorComponent
this.calculatorForm.setValue({ this.calculatorForm.setValue({
annualInterestRate: 5, annualInterestRate: 5,
paymentPerPeriod: 500, paymentPerPeriod: this.savingsRate,
principalInvestmentAmount: 0, principalInvestmentAmount: 0,
time: 10 time: 10
}); });
@ -83,15 +88,28 @@ export class FireCalculatorComponent
.subscribe(() => { .subscribe(() => {
this.initialize(); this.initialize();
}); });
this.calculatorForm
.get('paymentPerPeriod')
.valueChanges.pipe(takeUntil(this.unsubscribeSubject))
.subscribe((savingsRate) => {
this.savingsRateChanged.emit(savingsRate);
});
} }
public ngAfterViewInit() { public ngAfterViewInit() {
if (isNumber(this.fireWealth) && this.fireWealth >= 0) { if (isNumber(this.fireWealth) && this.fireWealth >= 0) {
setTimeout(() => { setTimeout(() => {
// Wait for the chartCanvas // Wait for the chartCanvas
this.calculatorForm.patchValue({ this.calculatorForm.patchValue(
principalInvestmentAmount: this.fireWealth {
}); principalInvestmentAmount: this.fireWealth,
paymentPerPeriod: this.savingsRate ?? 0
},
{
emitEvent: false
}
);
this.calculatorForm.get('principalInvestmentAmount').disable(); this.calculatorForm.get('principalInvestmentAmount').disable();
this.changeDetectorRef.markForCheck(); this.changeDetectorRef.markForCheck();
@ -103,9 +121,15 @@ export class FireCalculatorComponent
if (isNumber(this.fireWealth) && this.fireWealth >= 0) { if (isNumber(this.fireWealth) && this.fireWealth >= 0) {
setTimeout(() => { setTimeout(() => {
// Wait for the chartCanvas // Wait for the chartCanvas
this.calculatorForm.patchValue({ this.calculatorForm.patchValue(
principalInvestmentAmount: this.fireWealth {
}); principalInvestmentAmount: this.fireWealth,
paymentPerPeriod: this.savingsRate ?? 0
},
{
emitEvent: false
}
);
this.calculatorForm.get('principalInvestmentAmount').disable(); this.calculatorForm.get('principalInvestmentAmount').disable();
this.changeDetectorRef.markForCheck(); this.changeDetectorRef.markForCheck();
@ -152,7 +176,7 @@ export class FireCalculatorComponent
0 0
); );
return `Total Amount: ${new Intl.NumberFormat(this.locale, { return `Total: ${new Intl.NumberFormat(this.locale, {
currency: this.currency, currency: this.currency,
currencyDisplay: 'code', currencyDisplay: 'code',
style: 'currency' style: 'currency'

Loading…
Cancel
Save