Browse Source

Merge branch 'main' into compute-snapshot-perf-2

pull/3829/head
Thomas Kaul 11 months ago
committed by GitHub
parent
commit
a0ac2d039d
No known key found for this signature in database GPG Key ID: B5690EEEBB952194
  1. 5
      CHANGELOG.md
  2. 1
      apps/api/src/app/user/update-user-setting.dto.ts
  3. 3054
      apps/api/src/helper/object.helper.spec.ts
  4. 8
      apps/api/src/models/rules/account-cluster-risk/current-investment.ts
  5. 4
      apps/api/src/models/rules/account-cluster-risk/single-account.ts
  6. 6
      apps/api/src/models/rules/currency-cluster-risk/base-currency-current-investment.ts
  7. 8
      apps/api/src/models/rules/currency-cluster-risk/current-investment.ts
  8. 10
      apps/api/src/models/rules/emergency-fund/emergency-fund-setup.ts
  9. 8
      apps/api/src/models/rules/fees/fee-ratio-initial-investment.ts
  10. 2
      apps/client/src/app/components/rule/rule-settings-dialog/rule-settings-dialog.component.ts
  11. 32
      apps/client/src/app/components/rule/rule-settings-dialog/rule-settings-dialog.html
  12. 2
      apps/client/src/app/components/rule/rule.component.html
  13. 17
      apps/client/src/app/components/rule/rule.component.ts
  14. 2
      apps/client/src/app/pages/portfolio/fire/fire-page.component.ts
  15. 548
      apps/client/src/locales/messages.ca.xlf
  16. 548
      apps/client/src/locales/messages.de.xlf
  17. 548
      apps/client/src/locales/messages.es.xlf
  18. 548
      apps/client/src/locales/messages.fr.xlf
  19. 548
      apps/client/src/locales/messages.it.xlf
  20. 548
      apps/client/src/locales/messages.nl.xlf
  21. 548
      apps/client/src/locales/messages.pl.xlf
  22. 548
      apps/client/src/locales/messages.pt.xlf
  23. 548
      apps/client/src/locales/messages.tr.xlf
  24. 529
      apps/client/src/locales/messages.xlf
  25. 548
      apps/client/src/locales/messages.zh.xlf
  26. 4
      libs/common/src/lib/types/x-ray-rules-settings.type.ts
  27. 2
      package.json

5
CHANGELOG.md

@ -7,9 +7,14 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
## Unreleased ## Unreleased
### Added
- Added support to customize the rule thresholds in the _X-ray_ section (experimental)
### Changed ### Changed
- Optimized the portfolio calculations with smarter date interval selection - Optimized the portfolio calculations with smarter date interval selection
- Improved the language localization for German (`de`)
## 2.111.0 - 2024-09-28 ## 2.111.0 - 2024-09-28

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

@ -1,4 +1,5 @@
import { IsCurrencyCode } from '@ghostfolio/api/validators/is-currency-code'; import { IsCurrencyCode } from '@ghostfolio/api/validators/is-currency-code';
import { PortfolioReportRule } from '@ghostfolio/common/interfaces';
import type { import type {
ColorScheme, ColorScheme,
DateRange, DateRange,

3054
apps/api/src/helper/object.helper.spec.ts

File diff suppressed because it is too large

8
apps/api/src/models/rules/account-cluster-risk/current-investment.ts

@ -76,11 +76,11 @@ export class AccountClusterRiskCurrentInvestment extends Rule<Settings> {
}; };
} }
public getSettings(aUserSettings: UserSettings): Settings { public getSettings({ baseCurrency, xRayRules }: UserSettings): Settings {
return { return {
baseCurrency: aUserSettings.baseCurrency, baseCurrency,
isActive: aUserSettings.xRayRules[this.getKey()].isActive, isActive: xRayRules[this.getKey()].isActive,
thresholdMax: 0.5 thresholdMax: xRayRules[this.getKey()]?.thresholdMax ?? 0.5
}; };
} }
} }

4
apps/api/src/models/rules/account-cluster-risk/single-account.ts

@ -34,9 +34,9 @@ export class AccountClusterRiskSingleAccount extends Rule<RuleSettings> {
}; };
} }
public getSettings(aUserSettings: UserSettings): RuleSettings { public getSettings({ xRayRules }: UserSettings): RuleSettings {
return { return {
isActive: aUserSettings.xRayRules[this.getKey()].isActive isActive: xRayRules[this.getKey()].isActive
}; };
} }
} }

6
apps/api/src/models/rules/currency-cluster-risk/base-currency-current-investment.ts

@ -62,10 +62,10 @@ export class CurrencyClusterRiskBaseCurrencyCurrentInvestment extends Rule<Setti
}; };
} }
public getSettings(aUserSettings: UserSettings): Settings { public getSettings({ baseCurrency, xRayRules }: UserSettings): Settings {
return { return {
baseCurrency: aUserSettings.baseCurrency, baseCurrency,
isActive: aUserSettings.xRayRules[this.getKey()].isActive isActive: xRayRules[this.getKey()].isActive
}; };
} }
} }

8
apps/api/src/models/rules/currency-cluster-risk/current-investment.ts

@ -62,11 +62,11 @@ export class CurrencyClusterRiskCurrentInvestment extends Rule<Settings> {
}; };
} }
public getSettings(aUserSettings: UserSettings): Settings { public getSettings({ baseCurrency, xRayRules }: UserSettings): Settings {
return { return {
baseCurrency: aUserSettings.baseCurrency, baseCurrency,
isActive: aUserSettings.xRayRules[this.getKey()].isActive, isActive: xRayRules[this.getKey()].isActive,
thresholdMax: 0.5 thresholdMax: xRayRules[this.getKey()]?.thresholdMax ?? 0.5
}; };
} }
} }

10
apps/api/src/models/rules/emergency-fund/emergency-fund-setup.ts

@ -19,7 +19,7 @@ export class EmergencyFundSetup extends Rule<Settings> {
} }
public evaluate(ruleSettings: Settings) { public evaluate(ruleSettings: Settings) {
if (this.emergencyFund < ruleSettings.thresholdMin) { if (!this.emergencyFund) {
return { return {
evaluation: 'No emergency fund has been set up', evaluation: 'No emergency fund has been set up',
value: false value: false
@ -32,16 +32,14 @@ export class EmergencyFundSetup extends Rule<Settings> {
}; };
} }
public getSettings(aUserSettings: UserSettings): Settings { public getSettings({ baseCurrency, xRayRules }: UserSettings): Settings {
return { return {
baseCurrency: aUserSettings.baseCurrency, baseCurrency,
isActive: aUserSettings.xRayRules[this.getKey()].isActive, isActive: xRayRules[this.getKey()].isActive
thresholdMin: 0
}; };
} }
} }
interface Settings extends RuleSettings { interface Settings extends RuleSettings {
baseCurrency: string; baseCurrency: string;
thresholdMin: number;
} }

8
apps/api/src/models/rules/fees/fee-ratio-initial-investment.ts

@ -43,11 +43,11 @@ export class FeeRatioInitialInvestment extends Rule<Settings> {
}; };
} }
public getSettings(aUserSettings: UserSettings): Settings { public getSettings({ baseCurrency, xRayRules }: UserSettings): Settings {
return { return {
baseCurrency: aUserSettings.baseCurrency, baseCurrency,
isActive: aUserSettings.xRayRules[this.getKey()].isActive, isActive: xRayRules[this.getKey()].isActive,
thresholdMax: 0.01 thresholdMax: xRayRules[this.getKey()]?.thresholdMax ?? 0.01
}; };
} }
} }

2
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 { CommonModule } from '@angular/common';
import { Component, Inject } from '@angular/core'; import { Component, Inject } from '@angular/core';
import { FormsModule } from '@angular/forms';
import { MatButtonModule } from '@angular/material/button'; import { MatButtonModule } from '@angular/material/button';
import { import {
MAT_DIALOG_DATA, MAT_DIALOG_DATA,
@ -16,6 +17,7 @@ import { IRuleSettingsDialogParams } from './interfaces/interfaces';
@Component({ @Component({
imports: [ imports: [
CommonModule, CommonModule,
FormsModule,
MatButtonModule, MatButtonModule,
MatDialogModule, MatDialogModule,
MatFormFieldModule, MatFormFieldModule,

32
apps/client/src/app/components/rule/rule-settings-dialog/rule-settings-dialog.html

@ -1,23 +1,37 @@
<div mat-dialog-title>{{ data.rule.name }}</div> <div mat-dialog-title>{{ data.rule.name }}</div>
<div class="py-3" mat-dialog-content> <div class="py-3" mat-dialog-content>
<mat-form-field appearance="outline" class="w-100"> <mat-form-field
appearance="outline"
class="w-100"
[ngClass]="{ 'd-none': settings.thresholdMin === undefined }"
>
<mat-label i18n>Threshold Min</mat-label> <mat-label i18n>Threshold Min</mat-label>
<input matInput name="thresholdMin" type="number" /> <input
matInput
name="thresholdMin"
type="number"
[(ngModel)]="settings.thresholdMin"
/>
</mat-form-field> </mat-form-field>
<mat-form-field appearance="outline" class="w-100"> <mat-form-field
appearance="outline"
class="w-100"
[ngClass]="{ 'd-none': settings.thresholdMax === undefined }"
>
<mat-label i18n>Threshold Max</mat-label> <mat-label i18n>Threshold Max</mat-label>
<input matInput name="thresholdMax" type="number" /> <input
matInput
name="thresholdMax"
type="number"
[(ngModel)]="settings.thresholdMax"
/>
</mat-form-field> </mat-form-field>
</div> </div>
<div align="end" mat-dialog-actions> <div align="end" mat-dialog-actions>
<button i18n mat-button (click)="dialogRef.close()">Close</button> <button i18n mat-button (click)="dialogRef.close()">Close</button>
<button <button color="primary" mat-flat-button (click)="dialogRef.close(settings)">
color="primary"
mat-flat-button
(click)="dialogRef.close({ settings })"
>
<ng-container i18n>Save</ng-container> <ng-container i18n>Save</ng-container>
</button> </button>
</div> </div>

2
apps/client/src/app/components/rule/rule.component.html

@ -62,7 +62,7 @@
<ion-icon name="ellipsis-horizontal" /> <ion-icon name="ellipsis-horizontal" />
</button> </button>
<mat-menu #rulesMenu="matMenu" xPosition="before"> <mat-menu #rulesMenu="matMenu" xPosition="before">
@if (rule?.isActive && !isEmpty(rule.settings) && false) { @if (rule?.isActive && !isEmpty(rule.settings)) {
<button mat-menu-item (click)="onCustomizeRule(rule)"> <button mat-menu-item (click)="onCustomizeRule(rule)">
<ng-container i18n>Customize</ng-container>... <ng-container i18n>Customize</ng-container>...
</button> </button>

17
apps/client/src/app/components/rule/rule.component.ts

@ -55,16 +55,15 @@ export class RuleComponent implements OnInit {
dialogRef dialogRef
.afterClosed() .afterClosed()
.pipe(takeUntil(this.unsubscribeSubject)) .pipe(takeUntil(this.unsubscribeSubject))
.subscribe( .subscribe((settings: PortfolioReportRule['settings']) => {
({ settings }: { settings: PortfolioReportRule['settings'] }) => { if (settings) {
if (settings) { this.ruleUpdated.emit({
console.log(settings); xRayRules: {
[rule.key]: settings
// TODO }
// this.ruleUpdated.emit(settings); });
}
} }
); });
} }
public onUpdateRule(rule: PortfolioReportRule) { public onUpdateRule(rule: PortfolioReportRule) {

2
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) { public onRulesUpdated(event: UpdateUserSettingDto) {
this.isLoading = true;
this.dataService this.dataService
.putUserSetting(event) .putUserSetting(event)
.pipe(takeUntil(this.unsubscribeSubject)) .pipe(takeUntil(this.unsubscribeSubject))

548
apps/client/src/locales/messages.ca.xlf

File diff suppressed because it is too large

548
apps/client/src/locales/messages.de.xlf

File diff suppressed because it is too large

548
apps/client/src/locales/messages.es.xlf

File diff suppressed because it is too large

548
apps/client/src/locales/messages.fr.xlf

File diff suppressed because it is too large

548
apps/client/src/locales/messages.it.xlf

File diff suppressed because it is too large

548
apps/client/src/locales/messages.nl.xlf

File diff suppressed because it is too large

548
apps/client/src/locales/messages.pl.xlf

File diff suppressed because it is too large

548
apps/client/src/locales/messages.pt.xlf

File diff suppressed because it is too large

548
apps/client/src/locales/messages.tr.xlf

File diff suppressed because it is too large

529
apps/client/src/locales/messages.xlf

File diff suppressed because it is too large

548
apps/client/src/locales/messages.zh.xlf

File diff suppressed because it is too large

4
libs/common/src/lib/types/x-ray-rules-settings.type.ts

@ -1,3 +1,5 @@
import { PortfolioReportRule } from '@ghostfolio/common/interfaces';
export type XRayRulesSettings = { export type XRayRulesSettings = {
AccountClusterRiskCurrentInvestment?: RuleSettings; AccountClusterRiskCurrentInvestment?: RuleSettings;
AccountClusterRiskSingleAccount?: RuleSettings; AccountClusterRiskSingleAccount?: RuleSettings;
@ -7,6 +9,6 @@ export type XRayRulesSettings = {
FeeRatioInitialInvestment?: RuleSettings; FeeRatioInitialInvestment?: RuleSettings;
}; };
interface RuleSettings { interface RuleSettings extends Pick<PortfolioReportRule, 'settings'> {
isActive: boolean; isActive: boolean;
} }

2
package.json

@ -47,7 +47,7 @@
"test": "npm run test:api && npm run test:common", "test": "npm run test:api && npm run test:common",
"test:api": "npx dotenv-cli -e .env.example -- nx test api", "test:api": "npx dotenv-cli -e .env.example -- nx test api",
"test:common": "npx dotenv-cli -e .env.example -- nx test common", "test:common": "npx dotenv-cli -e .env.example -- nx test common",
"test:single": "nx run api:test --test-file portfolio-calculator-novn-buy-and-sell.spec.ts", "test:single": "nx run api:test --test-file object.helper.spec.ts",
"ts-node": "ts-node", "ts-node": "ts-node",
"update": "nx migrate latest", "update": "nx migrate latest",
"watch:server": "nx run api:copy-assets && nx run api:build --watch", "watch:server": "nx run api:copy-assets && nx run api:build --watch",

Loading…
Cancel
Save