Browse Source

Cleanups, move x rules updated to fire component

pull/3537/head
Sonlis 1 year ago
committed by Thomas Kaul
parent
commit
6bc6c21eaa
  1. 7
      apps/api/src/app/portfolio/rules.service.ts
  2. 4
      apps/api/src/app/user/update-user-setting.dto.ts
  3. 1
      apps/api/src/app/user/user.controller.ts
  4. 23
      apps/client/src/app/components/rule/rule.component.html
  5. 39
      apps/client/src/app/components/rule/rule.component.ts
  6. 4
      apps/client/src/app/components/rules/rules.component.html
  7. 14
      apps/client/src/app/components/rules/rules.component.ts
  8. 24
      apps/client/src/app/pages/portfolio/fire/fire-page.component.ts
  9. 4
      apps/client/src/app/pages/portfolio/fire/fire-page.html
  10. 1
      libs/common/src/lib/interfaces/portfolio-report-rule.interface.ts
  11. 4
      libs/common/src/lib/interfaces/user-settings.interface.ts
  12. 2
      libs/common/src/lib/interfaces/x-ray-rule.interface.ts

7
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()
};

4
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;
}

1
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

23
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) {
<ion-icon name="checkmark-circle-outline" />
} @else if (rule?.value === false) {
<ion-icon name="warning-outline" />
} @else {
<ion-icon name="close-outline" />
<ion-icon name="warning-outline" />
}
</div>
}
@ -53,10 +50,10 @@
<div class="evaluation">
@if (rule?.evaluation) {
{{ rule?.evaluation }}
} @else {
Rule is disabled
}
<div class="float-right">
</div>
</div>
<div>
<button
class="mx-1 no-min-width px-2"
mat-button
@ -66,19 +63,15 @@
<ion-icon name="ellipsis-horizontal" />
</button>
<mat-menu #accountMenu="matMenu" xPosition="before">
<button mat-menu-item (click)="onUpdateAccount(rule)">
<span class="align-items-center d-flex">
<button mat-menu-item (click)="onUpdateRule(rule)">
@if (rule?.evaluation) {
Disable
<ng-container i18n>Deactivate</ng-container>
} @else {
Enable
<ng-container i18n>Activate</ng-container>
}
</span>
</button>
</mat-menu>
</div>
</div>
</div>
}
</div>
</div>

39
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<void>();
@Output() ruleUpdated = new EventEmitter<UpdateUserSettingDto>();
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);
}
}

4
apps/client/src/app/components/rules/rules.component.html

@ -13,8 +13,8 @@
<gf-rule [isLoading]="true" />
}
@if (rules !== null && rules !== undefined) {
@for (rule of rules; track rule) {
<gf-rule [rule]="rule" />
@for (rule of rules; track rule.key) {
<gf-rule [rule]="rule" (ruleUpdated)="onRulesUpdated($event)" />
}
}
</div>

14
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<UpdateUserSettingDto>();
public constructor() {}
public onRulesUpdated(event: UpdateUserSettingDto) {
this.rulesUpdated.emit(event);
}
}

24
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 })

4
apps/client/src/app/pages/portfolio/fire/fire-page.html

@ -127,6 +127,7 @@
<gf-rules
[hasPermissionToCreateOrder]="hasPermissionToCreateOrder"
[rules]="emergencyFundRules"
(rulesUpdated)="onRulesUpdated($event)"
/>
</div>
<div class="mb-4">
@ -139,6 +140,7 @@
<gf-rules
[hasPermissionToCreateOrder]="hasPermissionToCreateOrder"
[rules]="currencyClusterRiskRules"
(rulesUpdated)="onRulesUpdated($event)"
/>
</div>
<div class="mb-4">
@ -151,6 +153,7 @@
<gf-rules
[hasPermissionToCreateOrder]="hasPermissionToCreateOrder"
[rules]="accountClusterRiskRules"
(rulesUpdated)="onRulesUpdated($event)"
/>
</div>
<div>
@ -163,6 +166,7 @@
<gf-rules
[hasPermissionToCreateOrder]="hasPermissionToCreateOrder"
[rules]="feeRules"
(rulesUpdated)="onRulesUpdated($event)"
/>
</div>
</div>

1
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;

4
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;
}

2
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;

Loading…
Cancel
Save