Merge branch 'main' of gitea.suda.codes:giteauser/ghostfolio-mirror

This commit is contained in:
ksyasuda 2024-10-01 19:31:03 -07:00
commit a36404d375
25 changed files with 3956 additions and 2277 deletions

View File

@ -5,6 +5,16 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
## Unreleased
### Added
- Added support to customize the rule thresholds in the _X-ray_ section (experimental)
### Changed
- Improved the language localization for German (`de`)
## 2.111.0 - 2024-09-28
### Added

View File

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

View File

@ -76,11 +76,11 @@ export class AccountClusterRiskCurrentInvestment extends Rule<Settings> {
};
}
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
};
}
}

View File

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

View File

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

View File

@ -62,11 +62,11 @@ export class CurrencyClusterRiskCurrentInvestment extends Rule<Settings> {
};
}
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
};
}
}

View File

@ -19,7 +19,7 @@ export class EmergencyFundSetup extends Rule<Settings> {
}
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<Settings> {
};
}
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;
}

View File

@ -43,11 +43,11 @@ export class FeeRatioInitialInvestment extends Rule<Settings> {
};
}
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
};
}
}

View File

@ -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,

View File

@ -1,23 +1,37 @@
<div mat-dialog-title>{{ data.rule.name }}</div>
<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>
<input matInput name="thresholdMin" type="number" />
<input
matInput
name="thresholdMin"
type="number"
[(ngModel)]="settings.thresholdMin"
/>
</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>
<input matInput name="thresholdMax" type="number" />
<input
matInput
name="thresholdMax"
type="number"
[(ngModel)]="settings.thresholdMax"
/>
</mat-form-field>
</div>
<div align="end" mat-dialog-actions>
<button i18n mat-button (click)="dialogRef.close()">Close</button>
<button
color="primary"
mat-flat-button
(click)="dialogRef.close({ settings })"
>
<button color="primary" mat-flat-button (click)="dialogRef.close(settings)">
<ng-container i18n>Save</ng-container>
</button>
</div>

View File

@ -62,7 +62,7 @@
<ion-icon name="ellipsis-horizontal" />
</button>
<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)">
<ng-container i18n>Customize</ng-container>...
</button>

View File

@ -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) {

View File

@ -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))

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -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<PortfolioReportRule, 'settings'> {
isActive: boolean;
}