diff --git a/CHANGELOG.md b/CHANGELOG.md index a2817c07e..dc4079612 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -18,6 +18,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Improved the language localization for German (`de`) - Upgraded `ionicons` from version `7.4.0` to `8.0.10` +### Fixed + +- Fixed the allocations by asset class for unknown asset classes on the allocations page + ## 2.178.0 - 2025-07-05 ### Changed diff --git a/apps/client/src/app/pages/portfolio/allocations/allocations-page.component.ts b/apps/client/src/app/pages/portfolio/allocations/allocations-page.component.ts index 6c3e2c962..37eeae61f 100644 --- a/apps/client/src/app/pages/portfolio/allocations/allocations-page.component.ts +++ b/apps/client/src/app/pages/portfolio/allocations/allocations-page.component.ts @@ -27,7 +27,13 @@ import { MatCardModule } from '@angular/material/card'; import { MatDialog } from '@angular/material/dialog'; import { MatProgressBarModule } from '@angular/material/progress-bar'; import { ActivatedRoute, Router } from '@angular/router'; -import { Account, AssetClass, DataSource, Platform } from '@prisma/client'; +import { + Account, + AssetClass, + AssetSubClass, + DataSource, + Platform +} from '@prisma/client'; import { isNumber } from 'lodash'; import { DeviceDetectorService } from 'ngx-device-detector'; import { Subject } from 'rxjs'; @@ -63,6 +69,18 @@ export class GfAllocationsPageComponent implements OnDestroy, OnInit { }; public deviceType: string; public hasImpersonationId: boolean; + public holdings: { + [symbol: string]: Pick< + PortfolioPosition, + | 'assetClass' + | 'assetClassLabel' + | 'assetSubClass' + | 'assetSubClassLabel' + | 'currency' + | 'exchange' + | 'name' + > & { etfProvider: string; value: number }; + }; public isLoading = false; public markets: { [key in Market]: { id: Market; valueInPercentage: number }; @@ -81,18 +99,6 @@ export class GfAllocationsPageComponent implements OnDestroy, OnInit { }; }; public portfolioDetails: PortfolioDetails; - public positions: { - [symbol: string]: Pick< - PortfolioPosition, - | 'assetClass' - | 'assetClassLabel' - | 'assetSubClass' - | 'assetSubClassLabel' - | 'currency' - | 'exchange' - | 'name' - > & { etfProvider: string; value: number }; - }; public sectors: { [name: string]: { name: string; value: number }; }; @@ -237,6 +243,7 @@ export class GfAllocationsPageComponent implements OnDestroy, OnInit { value: 0 } }; + this.holdings = {}; this.marketsAdvanced = { [UNKNOWN_KEY]: { id: UNKNOWN_KEY, @@ -282,7 +289,6 @@ export class GfAllocationsPageComponent implements OnDestroy, OnInit { platforms: {}, summary: undefined }; - this.positions = {}; this.sectors = { [UNKNOWN_KEY]: { name: UNKNOWN_KEY, @@ -319,16 +325,6 @@ export class GfAllocationsPageComponent implements OnDestroy, OnInit { }; } - this.markets = this.portfolioDetails.markets; - - Object.values(this.portfolioDetails.marketsAdvanced).forEach( - ({ id, valueInBaseCurrency, valueInPercentage }) => { - this.marketsAdvanced[id].value = isNumber(valueInBaseCurrency) - ? valueInBaseCurrency - : valueInPercentage; - } - ); - for (const [symbol, position] of Object.entries( this.portfolioDetails.holdings )) { @@ -340,12 +336,12 @@ export class GfAllocationsPageComponent implements OnDestroy, OnInit { value = position.valueInBaseCurrency; } - this.positions[symbol] = { + this.holdings[symbol] = { value, - assetClass: position.assetClass, - assetClassLabel: position.assetClassLabel, - assetSubClass: position.assetSubClass, - assetSubClassLabel: position.assetSubClassLabel, + assetClass: position.assetClass || (UNKNOWN_KEY as AssetClass), + assetClassLabel: position.assetClassLabel || UNKNOWN_KEY, + assetSubClass: position.assetSubClass || (UNKNOWN_KEY as AssetSubClass), + assetSubClassLabel: position.assetSubClassLabel || UNKNOWN_KEY, currency: position.currency, etfProvider: this.extractEtfProvider({ assetSubClass: position.assetSubClass, @@ -462,8 +458,8 @@ export class GfAllocationsPageComponent implements OnDestroy, OnInit { } } - if (this.positions[symbol].assetSubClass === 'ETF') { - this.totalValueInEtf += this.positions[symbol].value; + if (this.holdings[symbol].assetSubClass === 'ETF') { + this.totalValueInEtf += this.holdings[symbol].value; } this.symbols[prettifySymbol(symbol)] = { @@ -476,6 +472,16 @@ export class GfAllocationsPageComponent implements OnDestroy, OnInit { }; } + this.markets = this.portfolioDetails.markets; + + Object.values(this.portfolioDetails.marketsAdvanced).forEach( + ({ id, valueInBaseCurrency, valueInPercentage }) => { + this.marketsAdvanced[id].value = isNumber(valueInBaseCurrency) + ? valueInBaseCurrency + : valueInPercentage; + } + ); + for (const [ id, { name, valueInBaseCurrency, valueInPercentage } diff --git a/apps/client/src/app/pages/portfolio/allocations/allocations-page.html b/apps/client/src/app/pages/portfolio/allocations/allocations-page.html index 1436f6ab4..7153e2e53 100644 --- a/apps/client/src/app/pages/portfolio/allocations/allocations-page.html +++ b/apps/client/src/app/pages/portfolio/allocations/allocations-page.html @@ -70,7 +70,7 @@ { - backgroundColorSubCategory.push( - Color(item.color).lighten(lightnessRatio).hex() - ); + if (item.name === UNKNOWN_KEY) { + backgroundColorSubCategory.push(item.color); + } else { + backgroundColorSubCategory.push( + Color(item.color).lighten(lightnessRatio).hex() + ); + } dataSubCategory.push(item.subCategory[subCategory].value.toNumber()); labelSubCategory.push(subCategory); @@ -344,8 +349,14 @@ export class GfPortfolioProportionChartComponent align: 'end', anchor: 'end', formatter: (value, context) => { + const symbol = context.chart.data.labels?.[ + context.dataIndex + ] as string; + return value > 0 - ? context.chart.data.labels?.[context.dataIndex] + ? isUUID(symbol) + ? (translate(this.data[symbol]?.name) ?? symbol) + : symbol : ''; }, offset: 8