diff --git a/CHANGELOG.md b/CHANGELOG.md index 9d746a062..78862da6d 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 6ea6d7427..b4d3edb77 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 e25bb2f08..13680270e 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 1f61b9659..feaaf4e38 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 1258eb889..e3050efcc 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 0ba7a109c..c59701438 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 09029fd3e..9b1961ed6 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 41ebf49db..4fb68e780 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 e24db29f7..ef86549f6 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 f19436aba..5491933c0 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 e6aafdcb1..6e6c368f0 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 5aca4b375..10a2eb604 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 bc2782547..a55487f0b 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; }