From 24a3d92da00e6e5a4ed90000c101891ae0b27348 Mon Sep 17 00:00:00 2001 From: Shaunak Das <51281688+shaun-ak@users.noreply.github.com> Date: Tue, 1 Oct 2024 22:43:45 +0530 Subject: [PATCH] Feature/add business logic of rule settings (#3826) * Add business logic of rule settings * Update changelog --------- Co-authored-by: Thomas Kaul <4159106+dtslvr@users.noreply.github.com> --- CHANGELOG.md | 4 +++ .../src/app/user/update-user-setting.dto.ts | 1 + .../current-investment.ts | 8 ++--- .../account-cluster-risk/single-account.ts | 4 +-- .../base-currency-current-investment.ts | 6 ++-- .../current-investment.ts | 8 ++--- .../emergency-fund/emergency-fund-setup.ts | 10 +++--- .../fees/fee-ratio-initial-investment.ts | 8 ++--- .../rule-settings-dialog.component.ts | 2 ++ .../rule-settings-dialog.html | 32 +++++++++++++------ .../app/components/rule/rule.component.html | 2 +- .../src/app/components/rule/rule.component.ts | 17 +++++----- .../portfolio/fire/fire-page.component.ts | 2 -- .../lib/types/x-ray-rules-settings.type.ts | 4 ++- 14 files changed, 63 insertions(+), 45 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9d746a06..78862da6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## Unreleased +### Added + +- Added support to customize the rule thresholds in the _X-ray_ section (experimental) + ### Changed - Improved the language localization for German (`de`) 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 6ea6d742..b4d3edb7 100644 --- a/apps/api/src/app/user/update-user-setting.dto.ts +++ b/apps/api/src/app/user/update-user-setting.dto.ts @@ -1,4 +1,5 @@ import { IsCurrencyCode } from '@ghostfolio/api/validators/is-currency-code'; +import { PortfolioReportRule } from '@ghostfolio/common/interfaces'; import type { ColorScheme, DateRange, diff --git a/apps/api/src/models/rules/account-cluster-risk/current-investment.ts b/apps/api/src/models/rules/account-cluster-risk/current-investment.ts index e25bb2f0..13680270 100644 --- a/apps/api/src/models/rules/account-cluster-risk/current-investment.ts +++ b/apps/api/src/models/rules/account-cluster-risk/current-investment.ts @@ -76,11 +76,11 @@ export class AccountClusterRiskCurrentInvestment extends Rule { }; } - public getSettings(aUserSettings: UserSettings): Settings { + public getSettings({ baseCurrency, xRayRules }: UserSettings): Settings { return { - baseCurrency: aUserSettings.baseCurrency, - isActive: aUserSettings.xRayRules[this.getKey()].isActive, - thresholdMax: 0.5 + baseCurrency, + isActive: xRayRules[this.getKey()].isActive, + thresholdMax: xRayRules[this.getKey()]?.thresholdMax ?? 0.5 }; } } diff --git a/apps/api/src/models/rules/account-cluster-risk/single-account.ts b/apps/api/src/models/rules/account-cluster-risk/single-account.ts index 1f61b965..feaaf4e3 100644 --- a/apps/api/src/models/rules/account-cluster-risk/single-account.ts +++ b/apps/api/src/models/rules/account-cluster-risk/single-account.ts @@ -34,9 +34,9 @@ export class AccountClusterRiskSingleAccount extends Rule { }; } - public getSettings(aUserSettings: UserSettings): RuleSettings { + public getSettings({ xRayRules }: UserSettings): RuleSettings { return { - isActive: aUserSettings.xRayRules[this.getKey()].isActive + isActive: xRayRules[this.getKey()].isActive }; } } diff --git a/apps/api/src/models/rules/currency-cluster-risk/base-currency-current-investment.ts b/apps/api/src/models/rules/currency-cluster-risk/base-currency-current-investment.ts index 1258eb88..e3050efc 100644 --- a/apps/api/src/models/rules/currency-cluster-risk/base-currency-current-investment.ts +++ b/apps/api/src/models/rules/currency-cluster-risk/base-currency-current-investment.ts @@ -62,10 +62,10 @@ export class CurrencyClusterRiskBaseCurrencyCurrentInvestment extends Rule { }; } - public getSettings(aUserSettings: UserSettings): Settings { + public getSettings({ baseCurrency, xRayRules }: UserSettings): Settings { return { - baseCurrency: aUserSettings.baseCurrency, - isActive: aUserSettings.xRayRules[this.getKey()].isActive, - thresholdMax: 0.5 + baseCurrency, + isActive: xRayRules[this.getKey()].isActive, + thresholdMax: xRayRules[this.getKey()]?.thresholdMax ?? 0.5 }; } } diff --git a/apps/api/src/models/rules/emergency-fund/emergency-fund-setup.ts b/apps/api/src/models/rules/emergency-fund/emergency-fund-setup.ts index 0ba7a109..c5970143 100644 --- a/apps/api/src/models/rules/emergency-fund/emergency-fund-setup.ts +++ b/apps/api/src/models/rules/emergency-fund/emergency-fund-setup.ts @@ -19,7 +19,7 @@ export class EmergencyFundSetup extends Rule { } public evaluate(ruleSettings: Settings) { - if (this.emergencyFund < ruleSettings.thresholdMin) { + if (!this.emergencyFund) { return { evaluation: 'No emergency fund has been set up', value: false @@ -32,16 +32,14 @@ export class EmergencyFundSetup extends Rule { }; } - public getSettings(aUserSettings: UserSettings): Settings { + public getSettings({ baseCurrency, xRayRules }: UserSettings): Settings { return { - baseCurrency: aUserSettings.baseCurrency, - isActive: aUserSettings.xRayRules[this.getKey()].isActive, - thresholdMin: 0 + baseCurrency, + isActive: xRayRules[this.getKey()].isActive }; } } interface Settings extends RuleSettings { baseCurrency: string; - thresholdMin: number; } diff --git a/apps/api/src/models/rules/fees/fee-ratio-initial-investment.ts b/apps/api/src/models/rules/fees/fee-ratio-initial-investment.ts index 09029fd3..9b1961ed 100644 --- a/apps/api/src/models/rules/fees/fee-ratio-initial-investment.ts +++ b/apps/api/src/models/rules/fees/fee-ratio-initial-investment.ts @@ -43,11 +43,11 @@ export class FeeRatioInitialInvestment extends Rule { }; } - public getSettings(aUserSettings: UserSettings): Settings { + public getSettings({ baseCurrency, xRayRules }: UserSettings): Settings { return { - baseCurrency: aUserSettings.baseCurrency, - isActive: aUserSettings.xRayRules[this.getKey()].isActive, - thresholdMax: 0.01 + baseCurrency, + isActive: xRayRules[this.getKey()].isActive, + thresholdMax: xRayRules[this.getKey()]?.thresholdMax ?? 0.01 }; } } diff --git a/apps/client/src/app/components/rule/rule-settings-dialog/rule-settings-dialog.component.ts b/apps/client/src/app/components/rule/rule-settings-dialog/rule-settings-dialog.component.ts index 41ebf49d..4fb68e78 100644 --- a/apps/client/src/app/components/rule/rule-settings-dialog/rule-settings-dialog.component.ts +++ b/apps/client/src/app/components/rule/rule-settings-dialog/rule-settings-dialog.component.ts @@ -2,6 +2,7 @@ import { PortfolioReportRule } from '@ghostfolio/common/interfaces'; import { CommonModule } from '@angular/common'; import { Component, Inject } from '@angular/core'; +import { FormsModule } from '@angular/forms'; import { MatButtonModule } from '@angular/material/button'; import { MAT_DIALOG_DATA, @@ -16,6 +17,7 @@ import { IRuleSettingsDialogParams } from './interfaces/interfaces'; @Component({ imports: [ CommonModule, + FormsModule, MatButtonModule, MatDialogModule, MatFormFieldModule, diff --git a/apps/client/src/app/components/rule/rule-settings-dialog/rule-settings-dialog.html b/apps/client/src/app/components/rule/rule-settings-dialog/rule-settings-dialog.html index e24db29f..ef86549f 100644 --- a/apps/client/src/app/components/rule/rule-settings-dialog/rule-settings-dialog.html +++ b/apps/client/src/app/components/rule/rule-settings-dialog/rule-settings-dialog.html @@ -1,23 +1,37 @@
{{ data.rule.name }}
- + Threshold Min - + - + Threshold Max - +
-
diff --git a/apps/client/src/app/components/rule/rule.component.html b/apps/client/src/app/components/rule/rule.component.html index f19436ab..5491933c 100644 --- a/apps/client/src/app/components/rule/rule.component.html +++ b/apps/client/src/app/components/rule/rule.component.html @@ -62,7 +62,7 @@ - @if (rule?.isActive && !isEmpty(rule.settings) && false) { + @if (rule?.isActive && !isEmpty(rule.settings)) { diff --git a/apps/client/src/app/components/rule/rule.component.ts b/apps/client/src/app/components/rule/rule.component.ts index e6aafdcb..6e6c368f 100644 --- a/apps/client/src/app/components/rule/rule.component.ts +++ b/apps/client/src/app/components/rule/rule.component.ts @@ -55,16 +55,15 @@ export class RuleComponent implements OnInit { dialogRef .afterClosed() .pipe(takeUntil(this.unsubscribeSubject)) - .subscribe( - ({ settings }: { settings: PortfolioReportRule['settings'] }) => { - if (settings) { - console.log(settings); - - // TODO - // this.ruleUpdated.emit(settings); - } + .subscribe((settings: PortfolioReportRule['settings']) => { + if (settings) { + this.ruleUpdated.emit({ + xRayRules: { + [rule.key]: settings + } + }); } - ); + }); } public onUpdateRule(rule: PortfolioReportRule) { 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 5aca4b37..10a2eb60 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 @@ -134,8 +134,6 @@ export class FirePageComponent implements OnDestroy, OnInit { } public onRulesUpdated(event: UpdateUserSettingDto) { - this.isLoading = true; - this.dataService .putUserSetting(event) .pipe(takeUntil(this.unsubscribeSubject)) diff --git a/libs/common/src/lib/types/x-ray-rules-settings.type.ts b/libs/common/src/lib/types/x-ray-rules-settings.type.ts index bc278254..a55487f0 100644 --- a/libs/common/src/lib/types/x-ray-rules-settings.type.ts +++ b/libs/common/src/lib/types/x-ray-rules-settings.type.ts @@ -1,3 +1,5 @@ +import { PortfolioReportRule } from '@ghostfolio/common/interfaces'; + export type XRayRulesSettings = { AccountClusterRiskCurrentInvestment?: RuleSettings; AccountClusterRiskSingleAccount?: RuleSettings; @@ -7,6 +9,6 @@ export type XRayRulesSettings = { FeeRatioInitialInvestment?: RuleSettings; }; -interface RuleSettings { +interface RuleSettings extends Pick { isActive: boolean; }