Browse Source

feat: Show category in rule settings dialog of x-ray

pull/5158/head
Quan Huynh Van 1 month ago
parent
commit
ee0cbbd8d0
  1. 53
      apps/api/src/app/portfolio/rule-category-mapping.ts
  2. 6
      apps/api/src/app/portfolio/rules.service.ts
  3. 8
      apps/client/src/app/components/rule/rule-settings-dialog/rule-settings-dialog.html
  4. 1
      libs/common/src/lib/interfaces/portfolio-report-rule.interface.ts

53
apps/api/src/app/portfolio/rule-category-mapping.ts

@ -0,0 +1,53 @@
import { AccountClusterRiskCurrentInvestment } from '@ghostfolio/api/models/rules/account-cluster-risk/current-investment';
import { AccountClusterRiskSingleAccount } from '@ghostfolio/api/models/rules/account-cluster-risk/single-account';
import { AssetClassClusterRiskEquity } from '@ghostfolio/api/models/rules/asset-class-cluster-risk/equity';
import { AssetClassClusterRiskFixedIncome } from '@ghostfolio/api/models/rules/asset-class-cluster-risk/fixed-income';
import { CurrencyClusterRiskBaseCurrencyCurrentInvestment } from '@ghostfolio/api/models/rules/currency-cluster-risk/base-currency-current-investment';
import { CurrencyClusterRiskCurrentInvestment } from '@ghostfolio/api/models/rules/currency-cluster-risk/current-investment';
import { EconomicMarketClusterRiskDevelopedMarkets } from '@ghostfolio/api/models/rules/economic-market-cluster-risk/developed-markets';
import { EconomicMarketClusterRiskEmergingMarkets } from '@ghostfolio/api/models/rules/economic-market-cluster-risk/emerging-markets';
import { EmergencyFundSetup } from '@ghostfolio/api/models/rules/emergency-fund/emergency-fund-setup';
import { FeeRatioInitialInvestment } from '@ghostfolio/api/models/rules/fees/fee-ratio-initial-investment';
import { RegionalMarketClusterRiskAsiaPacific } from '@ghostfolio/api/models/rules/regional-market-cluster-risk/asia-pacific';
import { RegionalMarketClusterRiskEmergingMarkets } from '@ghostfolio/api/models/rules/regional-market-cluster-risk/emerging-markets';
import { RegionalMarketClusterRiskEurope } from '@ghostfolio/api/models/rules/regional-market-cluster-risk/europe';
import { RegionalMarketClusterRiskJapan } from '@ghostfolio/api/models/rules/regional-market-cluster-risk/japan';
import { RegionalMarketClusterRiskNorthAmerica } from '@ghostfolio/api/models/rules/regional-market-cluster-risk/north-america';
export const RULE_CATEGORY_MAPPING = {
// Account Cluster Risk Rules
[AccountClusterRiskCurrentInvestment.name]: 'Account Cluster Risk',
[AccountClusterRiskSingleAccount.name]: 'Account Cluster Risk',
// Asset Class Cluster Risk Rules
[AssetClassClusterRiskEquity.name]: 'Asset Class Cluster Risk',
[AssetClassClusterRiskFixedIncome.name]: 'Asset Class Cluster Risk',
// Currency Cluster Risk Rules
[CurrencyClusterRiskBaseCurrencyCurrentInvestment.name]:
'Currency Cluster Risk',
[CurrencyClusterRiskCurrentInvestment.name]: 'Currency Cluster Risk',
// Economic Market Cluster Risk Rules
[EconomicMarketClusterRiskDevelopedMarkets.name]:
'Economic Market Cluster Risk',
[EconomicMarketClusterRiskEmergingMarkets.name]:
'Economic Market Cluster Risk',
// Emergency Fund Rules
[EmergencyFundSetup.name]: 'Emergency Fund',
// Fee Rules
[FeeRatioInitialInvestment.name]: 'Fees',
// Regional Market Cluster Risk Rules
[RegionalMarketClusterRiskAsiaPacific.name]: 'Regional Market Cluster Risk',
[RegionalMarketClusterRiskEmergingMarkets.name]:
'Regional Market Cluster Risk',
[RegionalMarketClusterRiskEurope.name]: 'Regional Market Cluster Risk',
[RegionalMarketClusterRiskJapan.name]: 'Regional Market Cluster Risk',
[RegionalMarketClusterRiskNorthAmerica.name]: 'Regional Market Cluster Risk'
} as const;
export type RuleCategoryName =
(typeof RULE_CATEGORY_MAPPING)[keyof typeof RULE_CATEGORY_MAPPING];

6
apps/api/src/app/portfolio/rules.service.ts

@ -7,6 +7,8 @@ import {
import { Injectable } from '@nestjs/common';
import { RULE_CATEGORY_MAPPING } from './rule-category-mapping';
@Injectable()
export class RulesService {
public async evaluate<T extends RuleSettings>(
@ -15,6 +17,8 @@ export class RulesService {
): Promise<PortfolioReportRule[]> {
return aRules.map((rule) => {
const settings = rule.getSettings(aUserSettings);
const category =
RULE_CATEGORY_MAPPING[rule.constructor.name] || 'Unknown';
if (settings?.isActive) {
const { evaluation, value } = rule.evaluate(settings);
@ -22,6 +26,7 @@ export class RulesService {
return {
evaluation,
value,
category,
configuration: rule.getConfiguration(),
isActive: true,
key: rule.getKey(),
@ -29,6 +34,7 @@ export class RulesService {
};
} else {
return {
category,
isActive: false,
key: rule.getKey(),
name: rule.getName()

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

@ -1,4 +1,10 @@
<div mat-dialog-title>{{ data.rule.name }}</div>
<div mat-dialog-title>
@if (data.rule.category) {
{{ data.rule.category }} › {{ data.rule.name }}
} @else {
{{ data.rule.name }}
}
</div>
<div class="py-3" mat-dialog-content>
@if (

1
libs/common/src/lib/interfaces/portfolio-report-rule.interface.ts

@ -1,4 +1,5 @@
export interface PortfolioReportRule {
category?: string;
configuration?: {
threshold?: {
max: number;

Loading…
Cancel
Save