From 6bc6c21eaa6e6ab567640d74605c5c507ebc8870 Mon Sep 17 00:00:00 2001 From: Sonlis Date: Sun, 7 Jul 2024 19:20:51 +0300 Subject: [PATCH] Cleanups, move x rules updated to fire component --- apps/api/src/app/portfolio/rules.service.ts | 7 ++- .../src/app/user/update-user-setting.dto.ts | 4 +- apps/api/src/app/user/user.controller.ts | 1 + .../app/components/rule/rule.component.html | 49 ++++++++----------- .../src/app/components/rule/rule.component.ts | 39 +++------------ .../app/components/rules/rules.component.html | 4 +- .../app/components/rules/rules.component.ts | 14 +++++- .../portfolio/fire/fire-page.component.ts | 24 +++++++++ .../app/pages/portfolio/fire/fire-page.html | 4 ++ .../portfolio-report-rule.interface.ts | 1 + .../lib/interfaces/user-settings.interface.ts | 4 +- .../lib/interfaces/x-ray-rule.interface.ts | 2 +- 12 files changed, 84 insertions(+), 69 deletions(-) diff --git a/apps/api/src/app/portfolio/rules.service.ts b/apps/api/src/app/portfolio/rules.service.ts index 7c0e83919..c74d54f4f 100644 --- a/apps/api/src/app/portfolio/rules.service.ts +++ b/apps/api/src/app/portfolio/rules.service.ts @@ -17,14 +17,17 @@ export class RulesService { const { evaluation, value } = rule.evaluate( rule.getSettings(aUserSettings) ); + return { evaluation, - value, + isActive: true, key: rule.getKey(), - name: rule.getName() + name: rule.getName(), + value }; } else { return { + isActive: false, key: rule.getKey(), name: rule.getName() }; diff --git a/apps/api/src/app/user/update-user-setting.dto.ts b/apps/api/src/app/user/update-user-setting.dto.ts index 2473ab583..ff4adb476 100644 --- a/apps/api/src/app/user/update-user-setting.dto.ts +++ b/apps/api/src/app/user/update-user-setting.dto.ts @@ -1,5 +1,5 @@ import { IsCurrencyCode } from '@ghostfolio/api/validators/is-currency-code'; -import { xRayRules } from '@ghostfolio/common/interfaces/x-ray-rule.interface'; +import { XRayRules } from '@ghostfolio/common/interfaces/x-ray-rule.interface'; import type { ColorScheme, DateRange, @@ -105,5 +105,5 @@ export class UpdateUserSettingDto { viewMode?: ViewMode; @IsOptional() - xRayRules?: xRayRules; + xRayRules?: XRayRules; } diff --git a/apps/api/src/app/user/user.controller.ts b/apps/api/src/app/user/user.controller.ts index 1258341c4..1aec17596 100644 --- a/apps/api/src/app/user/user.controller.ts +++ b/apps/api/src/app/user/user.controller.ts @@ -155,6 +155,7 @@ export class UserController { delete userSettings[key]; } } + return this.userService.updateUserSetting({ userSettings, userId: this.request.user.id diff --git a/apps/client/src/app/components/rule/rule.component.html b/apps/client/src/app/components/rule/rule.component.html index 6493c2c0b..556b65a68 100644 --- a/apps/client/src/app/components/rule/rule.component.html +++ b/apps/client/src/app/components/rule/rule.component.html @@ -16,16 +16,13 @@ class="align-items-center d-flex icon-container mr-2 px-2" [ngClass]="{ okay: rule?.value === true, - warn: rule?.value === false, - disabled: rule?.value === undefined + warn: rule?.value === false }" > @if (rule?.value === true) { - } @else if (rule?.value === false) { - } @else { - + } } @@ -53,32 +50,28 @@
@if (rule?.evaluation) { {{ rule?.evaluation }} - } @else { - Rule is disabled } -
- - - - -
+
+ + + + +
} diff --git a/apps/client/src/app/components/rule/rule.component.ts b/apps/client/src/app/components/rule/rule.component.ts index 09a56bb46..9318514f2 100644 --- a/apps/client/src/app/components/rule/rule.component.ts +++ b/apps/client/src/app/components/rule/rule.component.ts @@ -1,16 +1,14 @@ import { UpdateUserSettingDto } from '@ghostfolio/api/app/user/update-user-setting.dto'; -import { DataService } from '@ghostfolio/client/services/data.service'; import { PortfolioReportRule } from '@ghostfolio/common/interfaces'; import { - ChangeDetectorRef, ChangeDetectionStrategy, Component, + EventEmitter, Input, - OnInit + OnInit, + Output } from '@angular/core'; -import { Subject } from 'rxjs'; -import { takeUntil } from 'rxjs/operators'; @Component({ selector: 'gf-rule', @@ -21,39 +19,18 @@ import { takeUntil } from 'rxjs/operators'; export class RuleComponent implements OnInit { @Input() isLoading: boolean; @Input() rule: PortfolioReportRule; - private unsubscribeSubject = new Subject(); + @Output() ruleUpdated = new EventEmitter(); - public constructor( - private changeDetectorRef: ChangeDetectorRef, - private dataService: DataService - ) {} + public constructor() {} public ngOnInit() {} - public onUpdateAccount(rule: PortfolioReportRule) { + public onUpdateRule(rule: PortfolioReportRule) { let settings: UpdateUserSettingDto = { xRayRules: { - [rule.key]: { isActive: !('evaluation' in rule) } + [rule.key]: { isActive: !rule.isActive } } }; - this.dataService - .putUserSetting(settings) - .pipe(takeUntil(this.unsubscribeSubject)) - .subscribe(() => { - this.dataService - .fetchPortfolioReport() - .pipe(takeUntil(this.unsubscribeSubject)) - .subscribe((report) => { - for (const ruleGroup in report.rules) { - for (const singleRule in report.rules[ruleGroup]) { - if (report.rules[ruleGroup][singleRule]['key'] === rule.key) { - this.rule = report.rules[ruleGroup][singleRule]; - break; - } - } - } - this.changeDetectorRef.markForCheck(); - }); - }); + this.ruleUpdated.emit(settings); } } diff --git a/apps/client/src/app/components/rules/rules.component.html b/apps/client/src/app/components/rules/rules.component.html index 5ef182329..3e78d7cf4 100644 --- a/apps/client/src/app/components/rules/rules.component.html +++ b/apps/client/src/app/components/rules/rules.component.html @@ -13,8 +13,8 @@ } @if (rules !== null && rules !== undefined) { - @for (rule of rules; track rule) { - + @for (rule of rules; track rule.key) { + } } diff --git a/apps/client/src/app/components/rules/rules.component.ts b/apps/client/src/app/components/rules/rules.component.ts index 9017700c2..04a6ae1f3 100644 --- a/apps/client/src/app/components/rules/rules.component.ts +++ b/apps/client/src/app/components/rules/rules.component.ts @@ -1,6 +1,13 @@ +import { UpdateUserSettingDto } from '@ghostfolio/api/app/user/update-user-setting.dto'; import { PortfolioReportRule } from '@ghostfolio/common/interfaces'; -import { ChangeDetectionStrategy, Component, Input } from '@angular/core'; +import { + ChangeDetectionStrategy, + Component, + EventEmitter, + Input, + Output +} from '@angular/core'; @Component({ selector: 'gf-rules', @@ -11,6 +18,11 @@ import { ChangeDetectionStrategy, Component, Input } from '@angular/core'; export class RulesComponent { @Input() hasPermissionToCreateOrder: boolean; @Input() rules: PortfolioReportRule[]; + @Output() rulesUpdated = new EventEmitter(); public constructor() {} + + public onRulesUpdated(event: UpdateUserSettingDto) { + this.rulesUpdated.emit(event); + } } diff --git a/apps/client/src/app/pages/portfolio/fire/fire-page.component.ts b/apps/client/src/app/pages/portfolio/fire/fire-page.component.ts index c33b2c3f5..34394d608 100644 --- a/apps/client/src/app/pages/portfolio/fire/fire-page.component.ts +++ b/apps/client/src/app/pages/portfolio/fire/fire-page.component.ts @@ -1,3 +1,4 @@ +import { UpdateUserSettingDto } from '@ghostfolio/api/app/user/update-user-setting.dto'; import { DataService } from '@ghostfolio/client/services/data.service'; import { ImpersonationStorageService } from '@ghostfolio/client/services/impersonation-storage.service'; import { UserService } from '@ghostfolio/client/services/user/user.service'; @@ -149,6 +150,29 @@ export class FirePageComponent implements OnDestroy, OnInit { }); } + public onRulesUpdated(event: UpdateUserSettingDto) { + this.isLoading = true; + this.dataService + .putUserSetting(event) + .pipe(takeUntil(this.unsubscribeSubject)) + .subscribe(() => { + this.dataService + .fetchPortfolioReport() + .pipe(takeUntil(this.unsubscribeSubject)) + .subscribe((portfolioReport) => { + this.accountClusterRiskRules = + portfolioReport.rules['accountClusterRisk'] || null; + this.currencyClusterRiskRules = + portfolioReport.rules['currencyClusterRisk'] || null; + this.emergencyFundRules = + portfolioReport.rules['emergencyFund'] || null; + this.feeRules = portfolioReport.rules['fees'] || null; + this.isLoading = false; + this.changeDetectorRef.markForCheck(); + }); + }); + } + public onSavingsRateChange(savingsRate: number) { this.dataService .putUserSetting({ savingsRate }) diff --git a/apps/client/src/app/pages/portfolio/fire/fire-page.html b/apps/client/src/app/pages/portfolio/fire/fire-page.html index 7c8e09ee7..f7295e662 100644 --- a/apps/client/src/app/pages/portfolio/fire/fire-page.html +++ b/apps/client/src/app/pages/portfolio/fire/fire-page.html @@ -127,6 +127,7 @@
@@ -139,6 +140,7 @@
@@ -151,6 +153,7 @@
@@ -163,6 +166,7 @@
diff --git a/libs/common/src/lib/interfaces/portfolio-report-rule.interface.ts b/libs/common/src/lib/interfaces/portfolio-report-rule.interface.ts index 7e0be4fb1..61fe389af 100644 --- a/libs/common/src/lib/interfaces/portfolio-report-rule.interface.ts +++ b/libs/common/src/lib/interfaces/portfolio-report-rule.interface.ts @@ -1,5 +1,6 @@ export interface PortfolioReportRule { evaluation?: string; + isActive: boolean; key: string; name: string; value?: boolean; diff --git a/libs/common/src/lib/interfaces/user-settings.interface.ts b/libs/common/src/lib/interfaces/user-settings.interface.ts index eaeae5206..8e4911ae2 100644 --- a/libs/common/src/lib/interfaces/user-settings.interface.ts +++ b/libs/common/src/lib/interfaces/user-settings.interface.ts @@ -5,7 +5,7 @@ import { ViewMode } from '@ghostfolio/common/types'; -import { xRayRules } from './x-ray-rule.interface'; +import { XRayRules } from './x-ray-rule.interface'; export interface UserSettings { annualInterestRate?: number; @@ -25,5 +25,5 @@ export interface UserSettings { retirementDate?: string; savingsRate?: number; viewMode?: ViewMode; - xRayRules?: xRayRules; + xRayRules?: XRayRules; } diff --git a/libs/common/src/lib/interfaces/x-ray-rule.interface.ts b/libs/common/src/lib/interfaces/x-ray-rule.interface.ts index d0881f2c8..aecb78a5f 100644 --- a/libs/common/src/lib/interfaces/x-ray-rule.interface.ts +++ b/libs/common/src/lib/interfaces/x-ray-rule.interface.ts @@ -1,4 +1,4 @@ -export interface xRayRules { +export interface XRayRules { AccountClusterRiskCurrentInvestment?: Rule; AccountClusterRiskSingleAccount?: Rule; CurrencyClusterRiskBaseCurrencyCurrentInvestment?: Rule;