Browse Source

Merge branch 'main' into yahoo-add-sectors

pull/4258/head
Thomas Kaul 7 months ago
committed by GitHub
parent
commit
2820724809
No known key found for this signature in database GPG Key ID: B5690EEEBB952194
  1. 8
      CHANGELOG.md
  2. 35
      apps/api/src/app/portfolio/portfolio.service.ts
  3. 9
      apps/api/src/app/user/user.service.ts
  4. 82
      apps/api/src/models/rules/regional-market-cluster-risk/north-america.ts
  5. 16
      apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.scss
  6. 87
      apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts
  7. 123
      apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html
  8. 2
      apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.module.ts
  9. 2
      apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.component.ts
  10. 24
      apps/client/src/app/pages/portfolio/x-ray/x-ray-page.component.html
  11. 6
      apps/client/src/app/pages/portfolio/x-ray/x-ray-page.component.ts
  12. 12
      apps/client/src/locales/messages.ca.xlf
  13. 14
      apps/client/src/locales/messages.de.xlf
  14. 12
      apps/client/src/locales/messages.es.xlf
  15. 12
      apps/client/src/locales/messages.fr.xlf
  16. 12
      apps/client/src/locales/messages.it.xlf
  17. 12
      apps/client/src/locales/messages.nl.xlf
  18. 12
      apps/client/src/locales/messages.pl.xlf
  19. 12
      apps/client/src/locales/messages.pt.xlf
  20. 12
      apps/client/src/locales/messages.tr.xlf
  21. 12
      apps/client/src/locales/messages.uk.xlf
  22. 11
      apps/client/src/locales/messages.xlf
  23. 12
      apps/client/src/locales/messages.zh.xlf
  24. 1
      libs/common/src/lib/interfaces/x-ray-rules-settings.interface.ts
  25. 78
      package-lock.json
  26. 4
      package.json

8
CHANGELOG.md

@ -9,14 +9,22 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Added ### Added
- Added a new static portfolio analysis rule: _Regional Market Cluster Risk_ (North America)
- Added support for ETF sector data in the _Yahoo Finance_ data enhancer - Added support for ETF sector data in the _Yahoo Finance_ data enhancer
### Changed ### Changed
- Extracted the scraper configuration to a sub form in the asset profile details dialog of the admin control
- Migrated the database seeding to _TypeScript_ - Migrated the database seeding to _TypeScript_
- Improved the language localization for German (`de`)
- Upgraded `@trivago/prettier-plugin-sort-imports` from version `4.3.0` to `5.2.1` - Upgraded `@trivago/prettier-plugin-sort-imports` from version `4.3.0` to `5.2.1`
- Upgraded `bull` from version `4.16.4` to `4.16.5` - Upgraded `bull` from version `4.16.4` to `4.16.5`
- Upgraded `ng-extract-i18n-merge` from version `2.13.1` to `2.14.1` - Upgraded `ng-extract-i18n-merge` from version `2.13.1` to `2.14.1`
- Upgraded `prisma` from version `6.2.1` to `6.3.0`
### Fixed
- Fixed the dynamic numerical precision for cryptocurrencies in the holding detail dialog
## 2.136.0 - 2025-01-24 ## 2.136.0 - 2025-01-24

35
apps/api/src/app/portfolio/portfolio.service.ts

@ -15,6 +15,7 @@ import { EconomicMarketClusterRiskDevelopedMarkets } from '@ghostfolio/api/model
import { EconomicMarketClusterRiskEmergingMarkets } from '@ghostfolio/api/models/rules/economic-market-cluster-risk/emerging-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 { EmergencyFundSetup } from '@ghostfolio/api/models/rules/emergency-fund/emergency-fund-setup';
import { FeeRatioInitialInvestment } from '@ghostfolio/api/models/rules/fees/fee-ratio-initial-investment'; import { FeeRatioInitialInvestment } from '@ghostfolio/api/models/rules/fees/fee-ratio-initial-investment';
import { RegionalMarketClusterRiskNorthAmerica } from '@ghostfolio/api/models/rules/regional-market-cluster-risk/north-america';
import { DataProviderService } from '@ghostfolio/api/services/data-provider/data-provider.service'; import { DataProviderService } from '@ghostfolio/api/services/data-provider/data-provider.service';
import { ExchangeRateDataService } from '@ghostfolio/api/services/exchange-rate-data/exchange-rate-data.service'; import { ExchangeRateDataService } from '@ghostfolio/api/services/exchange-rate-data/exchange-rate-data.service';
import { ImpersonationService } from '@ghostfolio/api/services/impersonation/impersonation.service'; import { ImpersonationService } from '@ghostfolio/api/services/impersonation/impersonation.service';
@ -1167,12 +1168,19 @@ export class PortfolioService {
const userId = await this.getUserId(impersonationId, this.request.user.id); const userId = await this.getUserId(impersonationId, this.request.user.id);
const userSettings = this.request.user.Settings.settings as UserSettings; const userSettings = this.request.user.Settings.settings as UserSettings;
const { accounts, holdings, markets, summary } = await this.getDetails({ const { accounts, holdings, markets, marketsAdvanced, summary } =
impersonationId, await this.getDetails({
userId, impersonationId,
withMarkets: true, userId,
withSummary: true withMarkets: true,
}); withSummary: true
});
const marketsAdvancedTotalInBaseCurrency = getSum(
Object.values(marketsAdvanced).map(({ valueInBaseCurrency }) => {
return new Big(valueInBaseCurrency);
})
).toNumber();
const marketsTotalInBaseCurrency = getSum( const marketsTotalInBaseCurrency = getSum(
Object.values(markets).map(({ valueInBaseCurrency }) => { Object.values(markets).map(({ valueInBaseCurrency }) => {
@ -1265,7 +1273,20 @@ export class PortfolioService {
) )
], ],
userSettings userSettings
) ),
regionalMarketClusterRisk:
summary.ordersCount > 0
? await this.rulesService.evaluate(
[
new RegionalMarketClusterRiskNorthAmerica(
this.exchangeRateDataService,
marketsAdvancedTotalInBaseCurrency,
marketsAdvanced.northAmerica.valueInBaseCurrency
)
],
userSettings
)
: undefined
}; };
return { rules, statistics: this.getReportStatistics(rules) }; return { rules, statistics: this.getReportStatistics(rules) };

9
apps/api/src/app/user/user.service.ts

@ -13,6 +13,7 @@ import { EconomicMarketClusterRiskDevelopedMarkets } from '@ghostfolio/api/model
import { EconomicMarketClusterRiskEmergingMarkets } from '@ghostfolio/api/models/rules/economic-market-cluster-risk/emerging-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 { EmergencyFundSetup } from '@ghostfolio/api/models/rules/emergency-fund/emergency-fund-setup';
import { FeeRatioInitialInvestment } from '@ghostfolio/api/models/rules/fees/fee-ratio-initial-investment'; import { FeeRatioInitialInvestment } from '@ghostfolio/api/models/rules/fees/fee-ratio-initial-investment';
import { RegionalMarketClusterRiskNorthAmerica } from '@ghostfolio/api/models/rules/regional-market-cluster-risk/north-america';
import { ConfigurationService } from '@ghostfolio/api/services/configuration/configuration.service'; import { ConfigurationService } from '@ghostfolio/api/services/configuration/configuration.service';
import { I18nService } from '@ghostfolio/api/services/i18n/i18n.service'; import { I18nService } from '@ghostfolio/api/services/i18n/i18n.service';
import { PrismaService } from '@ghostfolio/api/services/prisma/prisma.service'; import { PrismaService } from '@ghostfolio/api/services/prisma/prisma.service';
@ -268,7 +269,13 @@ export class UserService {
undefined, undefined,
undefined, undefined,
undefined undefined
).getSettings(user.Settings.settings) ).getSettings(user.Settings.settings),
RegionalMarketClusterRiskNorthAmerica:
new RegionalMarketClusterRiskNorthAmerica(
undefined,
undefined,
undefined
).getSettings(user.Settings.settings)
}; };
let currentPermissions = getPermissions(user.role); let currentPermissions = getPermissions(user.role);

82
apps/api/src/models/rules/regional-market-cluster-risk/north-america.ts

@ -0,0 +1,82 @@
import { RuleSettings } from '@ghostfolio/api/models/interfaces/rule-settings.interface';
import { Rule } from '@ghostfolio/api/models/rule';
import { ExchangeRateDataService } from '@ghostfolio/api/services/exchange-rate-data/exchange-rate-data.service';
import { UserSettings } from '@ghostfolio/common/interfaces';
export class RegionalMarketClusterRiskNorthAmerica extends Rule<Settings> {
private currentValueInBaseCurrency: number;
private northAmericaValueInBaseCurrency: number;
public constructor(
protected exchangeRateDataService: ExchangeRateDataService,
currentValueInBaseCurrency: number,
valueInBaseCurrency
) {
super(exchangeRateDataService, {
key: RegionalMarketClusterRiskNorthAmerica.name,
name: 'North America'
});
this.currentValueInBaseCurrency = currentValueInBaseCurrency;
this.northAmericaValueInBaseCurrency = valueInBaseCurrency;
}
public evaluate(ruleSettings: Settings) {
const northAmericaMarketValueRatio = this.currentValueInBaseCurrency
? this.northAmericaValueInBaseCurrency / this.currentValueInBaseCurrency
: 0;
if (northAmericaMarketValueRatio > ruleSettings.thresholdMax) {
return {
evaluation: `The North America market contribution of your current investment (${(northAmericaMarketValueRatio * 100).toPrecision(3)}%) exceeds ${(
ruleSettings.thresholdMax * 100
).toPrecision(3)}%`,
value: false
};
} else if (northAmericaMarketValueRatio < ruleSettings.thresholdMin) {
return {
evaluation: `The North America market contribution of your current investment (${(northAmericaMarketValueRatio * 100).toPrecision(3)}%) is below ${(
ruleSettings.thresholdMin * 100
).toPrecision(3)}%`,
value: false
};
}
return {
evaluation: `The North America market contribution of your current investment (${(northAmericaMarketValueRatio * 100).toPrecision(3)}%) is within the range of ${(
ruleSettings.thresholdMin * 100
).toPrecision(
3
)}% and ${(ruleSettings.thresholdMax * 100).toPrecision(3)}%`,
value: true
};
}
public getConfiguration() {
return {
threshold: {
max: 1,
min: 0,
step: 0.01,
unit: '%'
},
thresholdMax: true,
thresholdMin: true
};
}
public getSettings({ baseCurrency, xRayRules }: UserSettings): Settings {
return {
baseCurrency,
isActive: xRayRules?.[this.getKey()]?.isActive ?? true,
thresholdMax: xRayRules?.[this.getKey()]?.thresholdMax ?? 0.69,
thresholdMin: xRayRules?.[this.getKey()]?.thresholdMin ?? 0.65
};
}
}
interface Settings extends RuleSettings {
baseCurrency: string;
thresholdMin: number;
thresholdMax: number;
}

16
apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.scss

@ -7,5 +7,21 @@
gf-line-chart { gf-line-chart {
aspect-ratio: 16/9; aspect-ratio: 16/9;
} }
.mat-expansion-panel {
--mat-expansion-container-background-color: transparent;
::ng-deep {
.mat-expansion-panel-body {
padding: 0;
}
}
.mat-expansion-panel-header {
&:hover {
--mat-expansion-header-hover-state-layer-color: transparent;
}
}
}
} }
} }

87
apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts

@ -21,7 +21,8 @@ import {
Component, Component,
Inject, Inject,
OnDestroy, OnDestroy,
OnInit OnInit,
signal
} from '@angular/core'; } from '@angular/core';
import { FormBuilder, FormControl, Validators } from '@angular/forms'; import { FormBuilder, FormControl, Validators } from '@angular/forms';
import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog'; import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog';
@ -64,7 +65,14 @@ export class AssetProfileDialog implements OnDestroy, OnInit {
csvString: '' csvString: ''
}), }),
name: ['', Validators.required], name: ['', Validators.required],
scraperConfiguration: '', scraperConfiguration: this.formBuilder.group({
defaultMarketPrice: null,
headers: JSON.stringify({}),
locale: '',
mode: '',
selector: '',
url: ''
}),
sectors: '', sectors: '',
symbolMapping: '', symbolMapping: '',
url: '' url: ''
@ -79,6 +87,11 @@ export class AssetProfileDialog implements OnDestroy, OnInit {
public historicalDataItems: LineChartItem[]; public historicalDataItems: LineChartItem[];
public isBenchmark = false; public isBenchmark = false;
public marketDataItems: MarketData[] = []; public marketDataItems: MarketData[] = [];
public modeValues = [
{ value: 'lazy', viewValue: $localize`Lazy` },
{ value: 'instant', viewValue: $localize`Instant` }
];
public scraperConfiguationIsExpanded = signal(false);
public sectors: { public sectors: {
[name: string]: { name: string; value: number }; [name: string]: { name: string; value: number };
}; };
@ -181,9 +194,18 @@ export class AssetProfileDialog implements OnDestroy, OnInit {
csvString: AssetProfileDialog.HISTORICAL_DATA_TEMPLATE csvString: AssetProfileDialog.HISTORICAL_DATA_TEMPLATE
}, },
name: this.assetProfile.name ?? this.assetProfile.symbol, name: this.assetProfile.name ?? this.assetProfile.symbol,
scraperConfiguration: JSON.stringify( scraperConfiguration: {
this.assetProfile?.scraperConfiguration ?? {} defaultMarketPrice:
), this.assetProfile?.scraperConfiguration?.defaultMarketPrice ??
null,
headers: JSON.stringify(
this.assetProfile?.scraperConfiguration?.headers ?? {}
),
locale: this.assetProfile?.scraperConfiguration?.locale ?? '',
mode: this.assetProfile?.scraperConfiguration?.mode ?? 'lazy',
selector: this.assetProfile?.scraperConfiguration?.selector ?? '',
url: this.assetProfile?.scraperConfiguration?.url ?? ''
},
sectors: JSON.stringify(this.assetProfile?.sectors ?? []), sectors: JSON.stringify(this.assetProfile?.sectors ?? []),
symbolMapping: JSON.stringify(this.assetProfile?.symbolMapping ?? {}), symbolMapping: JSON.stringify(this.assetProfile?.symbolMapping ?? {}),
url: this.assetProfile?.url ?? '' url: this.assetProfile?.url ?? ''
@ -252,9 +274,31 @@ export class AssetProfileDialog implements OnDestroy, OnInit {
} catch {} } catch {}
try { try {
scraperConfiguration = JSON.parse( scraperConfiguration = {
this.assetProfileForm.get('scraperConfiguration').value defaultMarketPrice:
); this.assetProfileForm.controls['scraperConfiguration'].controls[
'defaultMarketPrice'
].value,
headers: JSON.parse(
this.assetProfileForm.controls['scraperConfiguration'].controls[
'headers'
].value
),
locale:
this.assetProfileForm.controls['scraperConfiguration'].controls[
'locale'
].value,
mode: this.assetProfileForm.controls['scraperConfiguration'].controls[
'mode'
].value,
selector:
this.assetProfileForm.controls['scraperConfiguration'].controls[
'selector'
].value,
url: this.assetProfileForm.controls['scraperConfiguration'].controls[
'url'
].value
};
} catch {} } catch {}
try { try {
@ -306,8 +350,31 @@ export class AssetProfileDialog implements OnDestroy, OnInit {
this.adminService this.adminService
.testMarketData({ .testMarketData({
dataSource: this.data.dataSource, dataSource: this.data.dataSource,
scraperConfiguration: this.assetProfileForm.get('scraperConfiguration') scraperConfiguration: JSON.stringify({
.value, defaultMarketPrice:
this.assetProfileForm.controls['scraperConfiguration'].controls[
'defaultMarketPrice'
].value,
headers: JSON.parse(
this.assetProfileForm.controls['scraperConfiguration'].controls[
'headers'
].value
),
locale:
this.assetProfileForm.controls['scraperConfiguration'].controls[
'locale'
].value,
mode: this.assetProfileForm.controls['scraperConfiguration'].controls[
'mode'
].value,
selector:
this.assetProfileForm.controls['scraperConfiguration'].controls[
'selector'
].value,
url: this.assetProfileForm.controls['scraperConfiguration'].controls[
'url'
].value
}),
symbol: this.data.symbol symbol: this.data.symbol
}) })
.pipe( .pipe(

123
apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html

@ -278,31 +278,106 @@
</mat-form-field> </mat-form-field>
</div> </div>
@if (assetProfile?.dataSource === 'MANUAL') { @if (assetProfile?.dataSource === 'MANUAL') {
<div> <div class="mb-3">
<mat-form-field appearance="outline" class="w-100"> <mat-accordion class="my-3">
<mat-label i18n>Scraper Configuration</mat-label> <mat-expansion-panel
<div class="align-items-end d-flex"> class="shadow-none"
<textarea [expanded]="
cdkTextareaAutosize assetProfileForm.controls.scraperConfiguration.controls.selector
formControlName="scraperConfiguration" .value !== '' &&
matInput assetProfileForm.controls.scraperConfiguration.controls.url
type="text" .value !== ''
(keyup.enter)="$event.stopPropagation()" "
></textarea> (closed)="scraperConfiguationIsExpanded.set(false)"
<button (opened)="scraperConfiguationIsExpanded.set(true)"
color="accent" >
mat-flat-button <mat-expansion-panel-header class="p-0">
type="button" <mat-panel-title i18n>Scraper Configuration</mat-panel-title>
[disabled]=" </mat-expansion-panel-header>
assetProfileForm.get('scraperConfiguration').value === '{}' <div formGroupName="scraperConfiguration">
" <div class="mt-3">
(click)="onTestMarketData()" <mat-form-field appearance="outline" class="w-100 without-hint">
> <mat-label i18n>Default Market Price</mat-label>
<ng-container i18n>Test</ng-container> <input
</button> formControlName="defaultMarketPrice"
</div> matInput
</mat-form-field> type="number"
/>
</mat-form-field>
</div>
<div class="mt-3">
<mat-form-field appearance="outline" class="w-100 without-hint">
<mat-label i18n>Headers</mat-label>
<textarea
cdkTextareaAutosize
formControlName="headers"
matInput
type="text"
[matAutocomplete]="auto"
></textarea>
</mat-form-field>
</div>
<div class="mt-3">
<mat-form-field appearance="outline" class="w-100 without-hint">
<mat-label i18n>Locale</mat-label>
<input formControlName="locale" matInput type="text" />
</mat-form-field>
</div>
<div class="mt-3">
<mat-form-field appearance="outline" class="w-100 without-hint">
<mat-label i18n>Mode</mat-label>
<mat-select formControlName="mode">
@for (modeValue of modeValues; track modeValue) {
<mat-option [value]="modeValue.value">{{
modeValue.viewValue
}}</mat-option>
}
</mat-select>
</mat-form-field>
</div>
<div class="mt-3">
<mat-form-field appearance="outline" class="w-100 without-hint">
<mat-label>
<ng-container i18n>Selector</ng-container>*
</mat-label>
<textarea
cdkTextareaAutosize
formControlName="selector"
matInput
type="text"
></textarea>
</mat-form-field>
</div>
<div class="mt-3">
<mat-form-field appearance="outline" class="w-100 without-hint">
<mat-label>
<ng-container i18n>Url</ng-container>*
</mat-label>
<input formControlName="url" matInput type="text" />
</mat-form-field>
</div>
<div class="my-3 text-right">
<button
color="accent"
mat-flat-button
type="button"
[disabled]="
assetProfileForm.controls.scraperConfiguration.controls
.selector.value === '' ||
assetProfileForm.controls.scraperConfiguration.controls.url
.value === ''
"
(click)="onTestMarketData()"
>
<ng-container i18n>Test</ng-container>
</button>
</div>
</div>
</mat-expansion-panel>
</mat-accordion>
</div> </div>
}
@if (assetProfile?.dataSource === 'MANUAL') {
<div> <div>
<mat-form-field appearance="outline" class="w-100"> <mat-form-field appearance="outline" class="w-100">
<mat-label i18n>Sectors</mat-label> <mat-label i18n>Sectors</mat-label>

2
apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.module.ts

@ -13,6 +13,7 @@ import { FormsModule, ReactiveFormsModule } from '@angular/forms';
import { MatButtonModule } from '@angular/material/button'; import { MatButtonModule } from '@angular/material/button';
import { MatCheckboxModule } from '@angular/material/checkbox'; import { MatCheckboxModule } from '@angular/material/checkbox';
import { MatDialogModule } from '@angular/material/dialog'; import { MatDialogModule } from '@angular/material/dialog';
import { MatExpansionModule } from '@angular/material/expansion';
import { MatInputModule } from '@angular/material/input'; import { MatInputModule } from '@angular/material/input';
import { MatMenuModule } from '@angular/material/menu'; import { MatMenuModule } from '@angular/material/menu';
import { MatSelectModule } from '@angular/material/select'; import { MatSelectModule } from '@angular/material/select';
@ -34,6 +35,7 @@ import { AssetProfileDialog } from './asset-profile-dialog.component';
MatButtonModule, MatButtonModule,
MatCheckboxModule, MatCheckboxModule,
MatDialogModule, MatDialogModule,
MatExpansionModule,
MatInputModule, MatInputModule,
MatMenuModule, MatMenuModule,
MatSelectModule, MatSelectModule,

2
apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.component.ts

@ -296,7 +296,7 @@ export class GfHoldingDetailDialogComponent implements OnDestroy, OnInit {
if (Number.isInteger(this.quantity)) { if (Number.isInteger(this.quantity)) {
this.quantityPrecision = 0; this.quantityPrecision = 0;
} else if (this.SymbolProfile?.assetSubClass === 'CRYPTOCURRENCY') { } else if (SymbolProfile?.assetSubClass === 'CRYPTOCURRENCY') {
if (this.quantity < 1) { if (this.quantity < 1) {
this.quantityPrecision = 7; this.quantityPrecision = 7;
} else if (this.quantity < 1000) { } else if (this.quantity < 1000) {

24
apps/client/src/app/pages/portfolio/x-ray/x-ray-page.component.html

@ -144,6 +144,30 @@
(rulesUpdated)="onRulesUpdated($event)" (rulesUpdated)="onRulesUpdated($event)"
/> />
</div> </div>
<div
class="mb-4"
[ngClass]="{
'd-none': regionalMarketClusterRiskRules?.length === 0
}"
>
<h4 class="align-items-center d-flex m-0">
<span i18n>Regional Market Cluster Risks</span>
@if (user?.subscription?.type === 'Basic') {
<gf-premium-indicator class="ml-1" />
}
</h4>
<gf-rules
[hasPermissionToUpdateUserSettings]="
!hasImpersonationId &&
hasPermissionToUpdateUserSettings &&
user?.settings?.isExperimentalFeatures
"
[isLoading]="isLoading"
[rules]="regionalMarketClusterRiskRules"
[settings]="user?.settings?.xRayRules"
(rulesUpdated)="onRulesUpdated($event)"
/>
</div>
<div <div
class="mb-4" class="mb-4"
[ngClass]="{ [ngClass]="{

6
apps/client/src/app/pages/portfolio/x-ray/x-ray-page.component.ts

@ -29,6 +29,7 @@ export class XRayPageComponent {
public hasPermissionToUpdateUserSettings: boolean; public hasPermissionToUpdateUserSettings: boolean;
public inactiveRules: PortfolioReportRule[]; public inactiveRules: PortfolioReportRule[];
public isLoading = false; public isLoading = false;
public regionalMarketClusterRiskRules: PortfolioReportRule[];
public statistics: PortfolioReportResponse['statistics']; public statistics: PortfolioReportResponse['statistics'];
public user: User; public user: User;
@ -129,6 +130,11 @@ export class XRayPageComponent {
return isActive; return isActive;
}) ?? null; }) ?? null;
this.regionalMarketClusterRiskRules =
rules['regionalMarketClusterRisk']?.filter(({ isActive }) => {
return isActive;
}) ?? null;
this.isLoading = false; this.isLoading = false;
this.changeDetectorRef.markForCheck(); this.changeDetectorRef.markForCheck();

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

@ -2623,7 +2623,7 @@
</context-group> </context-group>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/portfolio/x-ray/x-ray-page.component.html</context> <context context-type="sourcefile">apps/client/src/app/pages/portfolio/x-ray/x-ray-page.component.html</context>
<context context-type="linenumber">154</context> <context context-type="linenumber">178</context>
</context-group> </context-group>
</trans-unit> </trans-unit>
<trans-unit id="f2005fa461c06dc2e04d8918bbabedf23604b5b7" datatype="html"> <trans-unit id="f2005fa461c06dc2e04d8918bbabedf23604b5b7" datatype="html">
@ -7051,7 +7051,7 @@
<target state="new">Inactive</target> <target state="new">Inactive</target>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/portfolio/x-ray/x-ray-page.component.html</context> <context context-type="sourcefile">apps/client/src/app/pages/portfolio/x-ray/x-ray-page.component.html</context>
<context context-type="linenumber">173</context> <context context-type="linenumber">197</context>
</context-group> </context-group>
</trans-unit> </trans-unit>
<trans-unit id="2159130950882492111" datatype="html"> <trans-unit id="2159130950882492111" datatype="html">
@ -7664,6 +7664,14 @@
<context context-type="linenumber">16</context> <context context-type="linenumber">16</context>
</context-group> </context-group>
</trans-unit> </trans-unit>
<trans-unit id="189ecd7821c0e70fd7b29d9255600d3157865b3b" datatype="html">
<source>Regional Market Cluster Risks</source>
<target state="new">Regional Market Cluster Risks</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/portfolio/x-ray/x-ray-page.component.html</context>
<context context-type="linenumber">154</context>
</context-group>
</trans-unit>
</body> </body>
</file> </file>
</xliff> </xliff>

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

@ -3770,7 +3770,7 @@
</context-group> </context-group>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/portfolio/x-ray/x-ray-page.component.html</context> <context context-type="sourcefile">apps/client/src/app/pages/portfolio/x-ray/x-ray-page.component.html</context>
<context context-type="linenumber">154</context> <context context-type="linenumber">178</context>
</context-group> </context-group>
</trans-unit> </trans-unit>
<trans-unit id="a6f322a22d0ae0b95dd9c70d43ba2c92de7ed49b" datatype="html"> <trans-unit id="a6f322a22d0ae0b95dd9c70d43ba2c92de7ed49b" datatype="html">
@ -7051,7 +7051,7 @@
<target state="translated">Inaktiv</target> <target state="translated">Inaktiv</target>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/portfolio/x-ray/x-ray-page.component.html</context> <context context-type="sourcefile">apps/client/src/app/pages/portfolio/x-ray/x-ray-page.component.html</context>
<context context-type="linenumber">173</context> <context context-type="linenumber">197</context>
</context-group> </context-group>
</trans-unit> </trans-unit>
<trans-unit id="2159130950882492111" datatype="html"> <trans-unit id="2159130950882492111" datatype="html">
@ -7658,12 +7658,20 @@
</trans-unit> </trans-unit>
<trans-unit id="4499ce8c46ad55564b23a42ed752e72984c0248f" datatype="html"> <trans-unit id="4499ce8c46ad55564b23a42ed752e72984c0248f" datatype="html">
<source>Early Access</source> <source>Early Access</source>
<target state="new">Early Access</target> <target state="translated">Early Access</target>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-settings/admin-settings.component.html</context> <context context-type="sourcefile">apps/client/src/app/components/admin-settings/admin-settings.component.html</context>
<context context-type="linenumber">16</context> <context context-type="linenumber">16</context>
</context-group> </context-group>
</trans-unit> </trans-unit>
<trans-unit id="189ecd7821c0e70fd7b29d9255600d3157865b3b" datatype="html">
<source>Regional Market Cluster Risks</source>
<target state="translated">Regionale Marktklumpenrisiken</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/portfolio/x-ray/x-ray-page.component.html</context>
<context context-type="linenumber">154</context>
</context-group>
</trans-unit>
</body> </body>
</file> </file>
</xliff> </xliff>

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

@ -3771,7 +3771,7 @@
</context-group> </context-group>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/portfolio/x-ray/x-ray-page.component.html</context> <context context-type="sourcefile">apps/client/src/app/pages/portfolio/x-ray/x-ray-page.component.html</context>
<context context-type="linenumber">154</context> <context context-type="linenumber">178</context>
</context-group> </context-group>
</trans-unit> </trans-unit>
<trans-unit id="a6f322a22d0ae0b95dd9c70d43ba2c92de7ed49b" datatype="html"> <trans-unit id="a6f322a22d0ae0b95dd9c70d43ba2c92de7ed49b" datatype="html">
@ -7052,7 +7052,7 @@
<target state="new">Inactive</target> <target state="new">Inactive</target>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/portfolio/x-ray/x-ray-page.component.html</context> <context context-type="sourcefile">apps/client/src/app/pages/portfolio/x-ray/x-ray-page.component.html</context>
<context context-type="linenumber">173</context> <context context-type="linenumber">197</context>
</context-group> </context-group>
</trans-unit> </trans-unit>
<trans-unit id="2159130950882492111" datatype="html"> <trans-unit id="2159130950882492111" datatype="html">
@ -7665,6 +7665,14 @@
<context context-type="linenumber">16</context> <context context-type="linenumber">16</context>
</context-group> </context-group>
</trans-unit> </trans-unit>
<trans-unit id="189ecd7821c0e70fd7b29d9255600d3157865b3b" datatype="html">
<source>Regional Market Cluster Risks</source>
<target state="new">Regional Market Cluster Risks</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/portfolio/x-ray/x-ray-page.component.html</context>
<context context-type="linenumber">154</context>
</context-group>
</trans-unit>
</body> </body>
</file> </file>
</xliff> </xliff>

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

@ -3770,7 +3770,7 @@
</context-group> </context-group>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/portfolio/x-ray/x-ray-page.component.html</context> <context context-type="sourcefile">apps/client/src/app/pages/portfolio/x-ray/x-ray-page.component.html</context>
<context context-type="linenumber">154</context> <context context-type="linenumber">178</context>
</context-group> </context-group>
</trans-unit> </trans-unit>
<trans-unit id="a6f322a22d0ae0b95dd9c70d43ba2c92de7ed49b" datatype="html"> <trans-unit id="a6f322a22d0ae0b95dd9c70d43ba2c92de7ed49b" datatype="html">
@ -7051,7 +7051,7 @@
<target state="translated">Inactif</target> <target state="translated">Inactif</target>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/portfolio/x-ray/x-ray-page.component.html</context> <context context-type="sourcefile">apps/client/src/app/pages/portfolio/x-ray/x-ray-page.component.html</context>
<context context-type="linenumber">173</context> <context context-type="linenumber">197</context>
</context-group> </context-group>
</trans-unit> </trans-unit>
<trans-unit id="2159130950882492111" datatype="html"> <trans-unit id="2159130950882492111" datatype="html">
@ -7664,6 +7664,14 @@
<context context-type="linenumber">16</context> <context context-type="linenumber">16</context>
</context-group> </context-group>
</trans-unit> </trans-unit>
<trans-unit id="189ecd7821c0e70fd7b29d9255600d3157865b3b" datatype="html">
<source>Regional Market Cluster Risks</source>
<target state="new">Regional Market Cluster Risks</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/portfolio/x-ray/x-ray-page.component.html</context>
<context context-type="linenumber">154</context>
</context-group>
</trans-unit>
</body> </body>
</file> </file>
</xliff> </xliff>

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

@ -3771,7 +3771,7 @@
</context-group> </context-group>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/portfolio/x-ray/x-ray-page.component.html</context> <context context-type="sourcefile">apps/client/src/app/pages/portfolio/x-ray/x-ray-page.component.html</context>
<context context-type="linenumber">154</context> <context context-type="linenumber">178</context>
</context-group> </context-group>
</trans-unit> </trans-unit>
<trans-unit id="a6f322a22d0ae0b95dd9c70d43ba2c92de7ed49b" datatype="html"> <trans-unit id="a6f322a22d0ae0b95dd9c70d43ba2c92de7ed49b" datatype="html">
@ -7052,7 +7052,7 @@
<target state="translated">Inattivo</target> <target state="translated">Inattivo</target>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/portfolio/x-ray/x-ray-page.component.html</context> <context context-type="sourcefile">apps/client/src/app/pages/portfolio/x-ray/x-ray-page.component.html</context>
<context context-type="linenumber">173</context> <context context-type="linenumber">197</context>
</context-group> </context-group>
</trans-unit> </trans-unit>
<trans-unit id="2159130950882492111" datatype="html"> <trans-unit id="2159130950882492111" datatype="html">
@ -7665,6 +7665,14 @@
<context context-type="linenumber">16</context> <context context-type="linenumber">16</context>
</context-group> </context-group>
</trans-unit> </trans-unit>
<trans-unit id="189ecd7821c0e70fd7b29d9255600d3157865b3b" datatype="html">
<source>Regional Market Cluster Risks</source>
<target state="new">Regional Market Cluster Risks</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/portfolio/x-ray/x-ray-page.component.html</context>
<context context-type="linenumber">154</context>
</context-group>
</trans-unit>
</body> </body>
</file> </file>
</xliff> </xliff>

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

@ -3770,7 +3770,7 @@
</context-group> </context-group>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/portfolio/x-ray/x-ray-page.component.html</context> <context context-type="sourcefile">apps/client/src/app/pages/portfolio/x-ray/x-ray-page.component.html</context>
<context context-type="linenumber">154</context> <context context-type="linenumber">178</context>
</context-group> </context-group>
</trans-unit> </trans-unit>
<trans-unit id="a6f322a22d0ae0b95dd9c70d43ba2c92de7ed49b" datatype="html"> <trans-unit id="a6f322a22d0ae0b95dd9c70d43ba2c92de7ed49b" datatype="html">
@ -7051,7 +7051,7 @@
<target state="new">Inactive</target> <target state="new">Inactive</target>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/portfolio/x-ray/x-ray-page.component.html</context> <context context-type="sourcefile">apps/client/src/app/pages/portfolio/x-ray/x-ray-page.component.html</context>
<context context-type="linenumber">173</context> <context context-type="linenumber">197</context>
</context-group> </context-group>
</trans-unit> </trans-unit>
<trans-unit id="2159130950882492111" datatype="html"> <trans-unit id="2159130950882492111" datatype="html">
@ -7664,6 +7664,14 @@
<context context-type="linenumber">16</context> <context context-type="linenumber">16</context>
</context-group> </context-group>
</trans-unit> </trans-unit>
<trans-unit id="189ecd7821c0e70fd7b29d9255600d3157865b3b" datatype="html">
<source>Regional Market Cluster Risks</source>
<target state="new">Regional Market Cluster Risks</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/portfolio/x-ray/x-ray-page.component.html</context>
<context context-type="linenumber">154</context>
</context-group>
</trans-unit>
</body> </body>
</file> </file>
</xliff> </xliff>

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

@ -2599,7 +2599,7 @@
</context-group> </context-group>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/portfolio/x-ray/x-ray-page.component.html</context> <context context-type="sourcefile">apps/client/src/app/pages/portfolio/x-ray/x-ray-page.component.html</context>
<context context-type="linenumber">154</context> <context context-type="linenumber">178</context>
</context-group> </context-group>
</trans-unit> </trans-unit>
<trans-unit id="de518fa0cd3a454e84102c0d9984c4a3cfdb590d" datatype="html"> <trans-unit id="de518fa0cd3a454e84102c0d9984c4a3cfdb590d" datatype="html">
@ -7051,7 +7051,7 @@
<target state="translated">Nieaktywny</target> <target state="translated">Nieaktywny</target>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/portfolio/x-ray/x-ray-page.component.html</context> <context context-type="sourcefile">apps/client/src/app/pages/portfolio/x-ray/x-ray-page.component.html</context>
<context context-type="linenumber">173</context> <context context-type="linenumber">197</context>
</context-group> </context-group>
</trans-unit> </trans-unit>
<trans-unit id="2159130950882492111" datatype="html"> <trans-unit id="2159130950882492111" datatype="html">
@ -7664,6 +7664,14 @@
<context context-type="linenumber">16</context> <context context-type="linenumber">16</context>
</context-group> </context-group>
</trans-unit> </trans-unit>
<trans-unit id="189ecd7821c0e70fd7b29d9255600d3157865b3b" datatype="html">
<source>Regional Market Cluster Risks</source>
<target state="new">Regional Market Cluster Risks</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/portfolio/x-ray/x-ray-page.component.html</context>
<context context-type="linenumber">154</context>
</context-group>
</trans-unit>
</body> </body>
</file> </file>
</xliff> </xliff>

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

@ -3770,7 +3770,7 @@
</context-group> </context-group>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/portfolio/x-ray/x-ray-page.component.html</context> <context context-type="sourcefile">apps/client/src/app/pages/portfolio/x-ray/x-ray-page.component.html</context>
<context context-type="linenumber">154</context> <context context-type="linenumber">178</context>
</context-group> </context-group>
</trans-unit> </trans-unit>
<trans-unit id="a6f322a22d0ae0b95dd9c70d43ba2c92de7ed49b" datatype="html"> <trans-unit id="a6f322a22d0ae0b95dd9c70d43ba2c92de7ed49b" datatype="html">
@ -7051,7 +7051,7 @@
<target state="new">Inactive</target> <target state="new">Inactive</target>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/portfolio/x-ray/x-ray-page.component.html</context> <context context-type="sourcefile">apps/client/src/app/pages/portfolio/x-ray/x-ray-page.component.html</context>
<context context-type="linenumber">173</context> <context context-type="linenumber">197</context>
</context-group> </context-group>
</trans-unit> </trans-unit>
<trans-unit id="2159130950882492111" datatype="html"> <trans-unit id="2159130950882492111" datatype="html">
@ -7664,6 +7664,14 @@
<context context-type="linenumber">16</context> <context context-type="linenumber">16</context>
</context-group> </context-group>
</trans-unit> </trans-unit>
<trans-unit id="189ecd7821c0e70fd7b29d9255600d3157865b3b" datatype="html">
<source>Regional Market Cluster Risks</source>
<target state="new">Regional Market Cluster Risks</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/portfolio/x-ray/x-ray-page.component.html</context>
<context context-type="linenumber">154</context>
</context-group>
</trans-unit>
</body> </body>
</file> </file>
</xliff> </xliff>

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

@ -2639,7 +2639,7 @@
</context-group> </context-group>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/portfolio/x-ray/x-ray-page.component.html</context> <context context-type="sourcefile">apps/client/src/app/pages/portfolio/x-ray/x-ray-page.component.html</context>
<context context-type="linenumber">154</context> <context context-type="linenumber">178</context>
</context-group> </context-group>
</trans-unit> </trans-unit>
<trans-unit id="43d544c2e88959f6c59cc4db419528fb0776bd6c" datatype="html"> <trans-unit id="43d544c2e88959f6c59cc4db419528fb0776bd6c" datatype="html">
@ -7051,7 +7051,7 @@
<target state="new">Inactive</target> <target state="new">Inactive</target>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/portfolio/x-ray/x-ray-page.component.html</context> <context context-type="sourcefile">apps/client/src/app/pages/portfolio/x-ray/x-ray-page.component.html</context>
<context context-type="linenumber">173</context> <context context-type="linenumber">197</context>
</context-group> </context-group>
</trans-unit> </trans-unit>
<trans-unit id="2159130950882492111" datatype="html"> <trans-unit id="2159130950882492111" datatype="html">
@ -7664,6 +7664,14 @@
<context context-type="linenumber">16</context> <context context-type="linenumber">16</context>
</context-group> </context-group>
</trans-unit> </trans-unit>
<trans-unit id="189ecd7821c0e70fd7b29d9255600d3157865b3b" datatype="html">
<source>Regional Market Cluster Risks</source>
<target state="new">Regional Market Cluster Risks</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/portfolio/x-ray/x-ray-page.component.html</context>
<context context-type="linenumber">154</context>
</context-group>
</trans-unit>
</body> </body>
</file> </file>
</xliff> </xliff>

12
apps/client/src/locales/messages.uk.xlf

@ -2751,7 +2751,7 @@
</context-group> </context-group>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/portfolio/x-ray/x-ray-page.component.html</context> <context context-type="sourcefile">apps/client/src/app/pages/portfolio/x-ray/x-ray-page.component.html</context>
<context context-type="linenumber">154</context> <context context-type="linenumber">178</context>
</context-group> </context-group>
</trans-unit> </trans-unit>
<trans-unit id="f2005fa461c06dc2e04d8918bbabedf23604b5b7" datatype="html"> <trans-unit id="f2005fa461c06dc2e04d8918bbabedf23604b5b7" datatype="html">
@ -5591,7 +5591,7 @@
<target state="translated">Неактивний</target> <target state="translated">Неактивний</target>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/portfolio/x-ray/x-ray-page.component.html</context> <context context-type="sourcefile">apps/client/src/app/pages/portfolio/x-ray/x-ray-page.component.html</context>
<context context-type="linenumber">173</context> <context context-type="linenumber">197</context>
</context-group> </context-group>
</trans-unit> </trans-unit>
<trans-unit id="5080775557941296581" datatype="html"> <trans-unit id="5080775557941296581" datatype="html">
@ -7664,6 +7664,14 @@
<context context-type="linenumber">16</context> <context context-type="linenumber">16</context>
</context-group> </context-group>
</trans-unit> </trans-unit>
<trans-unit id="189ecd7821c0e70fd7b29d9255600d3157865b3b" datatype="html">
<source>Regional Market Cluster Risks</source>
<target state="new">Regional Market Cluster Risks</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/portfolio/x-ray/x-ray-page.component.html</context>
<context context-type="linenumber">154</context>
</context-group>
</trans-unit>
</body> </body>
</file> </file>
</xliff> </xliff>

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

@ -2440,7 +2440,7 @@
</context-group> </context-group>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/portfolio/x-ray/x-ray-page.component.html</context> <context context-type="sourcefile">apps/client/src/app/pages/portfolio/x-ray/x-ray-page.component.html</context>
<context context-type="linenumber">154</context> <context context-type="linenumber">178</context>
</context-group> </context-group>
</trans-unit> </trans-unit>
<trans-unit id="de518fa0cd3a454e84102c0d9984c4a3cfdb590d" datatype="html"> <trans-unit id="de518fa0cd3a454e84102c0d9984c4a3cfdb590d" datatype="html">
@ -6394,7 +6394,7 @@
<source>Inactive</source> <source>Inactive</source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/portfolio/x-ray/x-ray-page.component.html</context> <context context-type="sourcefile">apps/client/src/app/pages/portfolio/x-ray/x-ray-page.component.html</context>
<context context-type="linenumber">173</context> <context context-type="linenumber">197</context>
</context-group> </context-group>
</trans-unit> </trans-unit>
<trans-unit id="7819314041543176992" datatype="html"> <trans-unit id="7819314041543176992" datatype="html">
@ -6933,6 +6933,13 @@
<context context-type="linenumber">16</context> <context context-type="linenumber">16</context>
</context-group> </context-group>
</trans-unit> </trans-unit>
<trans-unit id="189ecd7821c0e70fd7b29d9255600d3157865b3b" datatype="html">
<source>Regional Market Cluster Risks</source>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/portfolio/x-ray/x-ray-page.component.html</context>
<context context-type="linenumber">154</context>
</context-group>
</trans-unit>
</body> </body>
</file> </file>
</xliff> </xliff>

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

@ -2616,7 +2616,7 @@
</context-group> </context-group>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/portfolio/x-ray/x-ray-page.component.html</context> <context context-type="sourcefile">apps/client/src/app/pages/portfolio/x-ray/x-ray-page.component.html</context>
<context context-type="linenumber">154</context> <context context-type="linenumber">178</context>
</context-group> </context-group>
</trans-unit> </trans-unit>
<trans-unit id="de518fa0cd3a454e84102c0d9984c4a3cfdb590d" datatype="html"> <trans-unit id="de518fa0cd3a454e84102c0d9984c4a3cfdb590d" datatype="html">
@ -7052,7 +7052,7 @@
<target state="new">Inactive</target> <target state="new">Inactive</target>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/portfolio/x-ray/x-ray-page.component.html</context> <context context-type="sourcefile">apps/client/src/app/pages/portfolio/x-ray/x-ray-page.component.html</context>
<context context-type="linenumber">173</context> <context context-type="linenumber">197</context>
</context-group> </context-group>
</trans-unit> </trans-unit>
<trans-unit id="2159130950882492111" datatype="html"> <trans-unit id="2159130950882492111" datatype="html">
@ -7665,6 +7665,14 @@
<context context-type="linenumber">16</context> <context context-type="linenumber">16</context>
</context-group> </context-group>
</trans-unit> </trans-unit>
<trans-unit id="189ecd7821c0e70fd7b29d9255600d3157865b3b" datatype="html">
<source>Regional Market Cluster Risks</source>
<target state="new">Regional Market Cluster Risks</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/portfolio/x-ray/x-ray-page.component.html</context>
<context context-type="linenumber">154</context>
</context-group>
</trans-unit>
</body> </body>
</file> </file>
</xliff> </xliff>

1
libs/common/src/lib/interfaces/x-ray-rules-settings.interface.ts

@ -9,6 +9,7 @@ export interface XRayRulesSettings {
EconomicMarketClusterRiskEmergingMarkets?: RuleSettings; EconomicMarketClusterRiskEmergingMarkets?: RuleSettings;
EmergencyFundSetup?: RuleSettings; EmergencyFundSetup?: RuleSettings;
FeeRatioInitialInvestment?: RuleSettings; FeeRatioInitialInvestment?: RuleSettings;
RegionalMarketClusterRiskNorthAmerica?: RuleSettings;
} }
interface RuleSettings { interface RuleSettings {

78
package-lock.json

@ -40,7 +40,7 @@
"@nestjs/platform-express": "10.4.15", "@nestjs/platform-express": "10.4.15",
"@nestjs/schedule": "4.1.2", "@nestjs/schedule": "4.1.2",
"@nestjs/serve-static": "4.0.2", "@nestjs/serve-static": "4.0.2",
"@prisma/client": "6.2.1", "@prisma/client": "6.3.0",
"@simplewebauthn/browser": "9.0.1", "@simplewebauthn/browser": "9.0.1",
"@simplewebauthn/server": "9.0.3", "@simplewebauthn/server": "9.0.3",
"@stripe/stripe-js": "5.4.0", "@stripe/stripe-js": "5.4.0",
@ -151,7 +151,7 @@
"nx": "20.3.2", "nx": "20.3.2",
"prettier": "3.4.2", "prettier": "3.4.2",
"prettier-plugin-organize-attributes": "1.0.0", "prettier-plugin-organize-attributes": "1.0.0",
"prisma": "6.2.1", "prisma": "6.3.0",
"react": "18.2.0", "react": "18.2.0",
"react-dom": "18.2.0", "react-dom": "18.2.0",
"replace-in-file": "8.3.0", "replace-in-file": "8.3.0",
@ -8847,71 +8847,75 @@
"license": "MIT" "license": "MIT"
}, },
"node_modules/@prisma/client": { "node_modules/@prisma/client": {
"version": "6.2.1", "version": "6.3.0",
"resolved": "https://registry.npmjs.org/@prisma/client/-/client-6.2.1.tgz", "resolved": "https://registry.npmjs.org/@prisma/client/-/client-6.3.0.tgz",
"integrity": "sha512-msKY2iRLISN8t5X0Tj7hU0UWet1u0KuxSPHWuf3IRkB4J95mCvGpyQBfQ6ufcmvKNOMQSq90O2iUmJEN2e5fiA==", "integrity": "sha512-BY3Fi28PUSk447Bpv22LhZp4HgNPo7NsEN+EteM1CLDnLjig5863jpW+3c3HHLFmml+nB/eJv1CjSriFZ8z7Cg==",
"hasInstallScript": true, "hasInstallScript": true,
"license": "Apache-2.0", "license": "Apache-2.0",
"engines": { "engines": {
"node": ">=18.18" "node": ">=18.18"
}, },
"peerDependencies": { "peerDependencies": {
"prisma": "*" "prisma": "*",
"typescript": ">=5.1.0"
}, },
"peerDependenciesMeta": { "peerDependenciesMeta": {
"prisma": { "prisma": {
"optional": true "optional": true
},
"typescript": {
"optional": true
} }
} }
}, },
"node_modules/@prisma/debug": { "node_modules/@prisma/debug": {
"version": "6.2.1", "version": "6.3.0",
"resolved": "https://registry.npmjs.org/@prisma/debug/-/debug-6.2.1.tgz", "resolved": "https://registry.npmjs.org/@prisma/debug/-/debug-6.3.0.tgz",
"integrity": "sha512-0KItvt39CmQxWkEw6oW+RQMD6RZ43SJWgEUnzxN8VC9ixMysa7MzZCZf22LCK5DSooiLNf8vM3LHZm/I/Ni7bQ==", "integrity": "sha512-m1lQv//0Rc5RG8TBpNUuLCxC35Ghi5XfpPmL83Gh04/GICHD2J5H2ndMlaljrUNaQDF9dOxIuFAYP1rE9wkXkg==",
"devOptional": true, "devOptional": true,
"license": "Apache-2.0" "license": "Apache-2.0"
}, },
"node_modules/@prisma/engines": { "node_modules/@prisma/engines": {
"version": "6.2.1", "version": "6.3.0",
"resolved": "https://registry.npmjs.org/@prisma/engines/-/engines-6.2.1.tgz", "resolved": "https://registry.npmjs.org/@prisma/engines/-/engines-6.3.0.tgz",
"integrity": "sha512-lTBNLJBCxVT9iP5I7Mn6GlwqAxTpS5qMERrhebkUhtXpGVkBNd/jHnNJBZQW4kGDCKaQg/r2vlJYkzOHnAb7ZQ==", "integrity": "sha512-RXqYhlZb9sx/xkUfYIZuEPn7sT0WgTxNOuEYQ7AGw3IMpP9QGVEDVsluc/GcNkM8NTJszeqk8AplJzI9lm7Jxw==",
"devOptional": true, "devOptional": true,
"hasInstallScript": true, "hasInstallScript": true,
"license": "Apache-2.0", "license": "Apache-2.0",
"dependencies": { "dependencies": {
"@prisma/debug": "6.2.1", "@prisma/debug": "6.3.0",
"@prisma/engines-version": "6.2.0-14.4123509d24aa4dede1e864b46351bf2790323b69", "@prisma/engines-version": "6.3.0-17.acc0b9dd43eb689cbd20c9470515d719db10d0b0",
"@prisma/fetch-engine": "6.2.1", "@prisma/fetch-engine": "6.3.0",
"@prisma/get-platform": "6.2.1" "@prisma/get-platform": "6.3.0"
} }
}, },
"node_modules/@prisma/engines-version": { "node_modules/@prisma/engines-version": {
"version": "6.2.0-14.4123509d24aa4dede1e864b46351bf2790323b69", "version": "6.3.0-17.acc0b9dd43eb689cbd20c9470515d719db10d0b0",
"resolved": "https://registry.npmjs.org/@prisma/engines-version/-/engines-version-6.2.0-14.4123509d24aa4dede1e864b46351bf2790323b69.tgz", "resolved": "https://registry.npmjs.org/@prisma/engines-version/-/engines-version-6.3.0-17.acc0b9dd43eb689cbd20c9470515d719db10d0b0.tgz",
"integrity": "sha512-7tw1qs/9GWSX6qbZs4He09TOTg1ff3gYsB3ubaVNN0Pp1zLm9NC5C5MZShtkz7TyQjx7blhpknB7HwEhlG+PrQ==", "integrity": "sha512-R/ZcMuaWZT2UBmgX3Ko6PAV3f8//ZzsjRIG1eKqp3f2rqEqVtCv+mtzuH2rBPUC9ujJ5kCb9wwpxeyCkLcHVyA==",
"devOptional": true, "devOptional": true,
"license": "Apache-2.0" "license": "Apache-2.0"
}, },
"node_modules/@prisma/fetch-engine": { "node_modules/@prisma/fetch-engine": {
"version": "6.2.1", "version": "6.3.0",
"resolved": "https://registry.npmjs.org/@prisma/fetch-engine/-/fetch-engine-6.2.1.tgz", "resolved": "https://registry.npmjs.org/@prisma/fetch-engine/-/fetch-engine-6.3.0.tgz",
"integrity": "sha512-OO7O9d6Mrx2F9i+Gu1LW+DGXXyUFkP7OE5aj9iBfA/2jjDXEJjqa9X0ZmM9NZNo8Uo7ql6zKm6yjDcbAcRrw1A==", "integrity": "sha512-GBy0iT4f1mH31ePzfcpVSUa7JLRTeq4914FG2vR3LqDwRweSm4ja1o5flGDz+eVIa/BNYfkBvRRxv4D6ve6Eew==",
"devOptional": true, "devOptional": true,
"license": "Apache-2.0", "license": "Apache-2.0",
"dependencies": { "dependencies": {
"@prisma/debug": "6.2.1", "@prisma/debug": "6.3.0",
"@prisma/engines-version": "6.2.0-14.4123509d24aa4dede1e864b46351bf2790323b69", "@prisma/engines-version": "6.3.0-17.acc0b9dd43eb689cbd20c9470515d719db10d0b0",
"@prisma/get-platform": "6.2.1" "@prisma/get-platform": "6.3.0"
} }
}, },
"node_modules/@prisma/get-platform": { "node_modules/@prisma/get-platform": {
"version": "6.2.1", "version": "6.3.0",
"resolved": "https://registry.npmjs.org/@prisma/get-platform/-/get-platform-6.2.1.tgz", "resolved": "https://registry.npmjs.org/@prisma/get-platform/-/get-platform-6.3.0.tgz",
"integrity": "sha512-zp53yvroPl5m5/gXYLz7tGCNG33bhG+JYCm74ohxOq1pPnrL47VQYFfF3RbTZ7TzGWCrR3EtoiYMywUBw7UK6Q==", "integrity": "sha512-V8zZ1d0xfyi6FjpNP4AcYuwSpGcdmu35OXWnTPm8IW594PYALzKXHwIa9+o0f+Lo9AecFWrwrwaoYe56UNfTtQ==",
"devOptional": true, "devOptional": true,
"license": "Apache-2.0", "license": "Apache-2.0",
"dependencies": { "dependencies": {
"@prisma/debug": "6.2.1" "@prisma/debug": "6.3.0"
} }
}, },
"node_modules/@redis/bloom": { "node_modules/@redis/bloom": {
@ -27181,14 +27185,14 @@
} }
}, },
"node_modules/prisma": { "node_modules/prisma": {
"version": "6.2.1", "version": "6.3.0",
"resolved": "https://registry.npmjs.org/prisma/-/prisma-6.2.1.tgz", "resolved": "https://registry.npmjs.org/prisma/-/prisma-6.3.0.tgz",
"integrity": "sha512-hhyM0H13pQleQ+br4CkzGizS5I0oInoeTw3JfLw1BRZduBSQxPILlJLwi+46wZzj9Je7ndyQEMGw/n5cN2fknA==", "integrity": "sha512-y+Zh3Qg+xGCWyyrNUUNaFW/OltaV/yXYuTa0WRgYkz5LGyifmAsgpv94I47+qGRocZrMGcbF2A/78/oO2zgifA==",
"devOptional": true, "devOptional": true,
"hasInstallScript": true, "hasInstallScript": true,
"license": "Apache-2.0", "license": "Apache-2.0",
"dependencies": { "dependencies": {
"@prisma/engines": "6.2.1" "@prisma/engines": "6.3.0"
}, },
"bin": { "bin": {
"prisma": "build/index.js" "prisma": "build/index.js"
@ -27198,6 +27202,14 @@
}, },
"optionalDependencies": { "optionalDependencies": {
"fsevents": "2.3.3" "fsevents": "2.3.3"
},
"peerDependencies": {
"typescript": ">=5.1.0"
},
"peerDependenciesMeta": {
"typescript": {
"optional": true
}
} }
}, },
"node_modules/prismjs": { "node_modules/prismjs": {

4
package.json

@ -86,7 +86,7 @@
"@nestjs/platform-express": "10.4.15", "@nestjs/platform-express": "10.4.15",
"@nestjs/schedule": "4.1.2", "@nestjs/schedule": "4.1.2",
"@nestjs/serve-static": "4.0.2", "@nestjs/serve-static": "4.0.2",
"@prisma/client": "6.2.1", "@prisma/client": "6.3.0",
"@simplewebauthn/browser": "9.0.1", "@simplewebauthn/browser": "9.0.1",
"@simplewebauthn/server": "9.0.3", "@simplewebauthn/server": "9.0.3",
"@stripe/stripe-js": "5.4.0", "@stripe/stripe-js": "5.4.0",
@ -197,7 +197,7 @@
"nx": "20.3.2", "nx": "20.3.2",
"prettier": "3.4.2", "prettier": "3.4.2",
"prettier-plugin-organize-attributes": "1.0.0", "prettier-plugin-organize-attributes": "1.0.0",
"prisma": "6.2.1", "prisma": "6.3.0",
"react": "18.2.0", "react": "18.2.0",
"react-dom": "18.2.0", "react-dom": "18.2.0",
"replace-in-file": "8.3.0", "replace-in-file": "8.3.0",

Loading…
Cancel
Save