From 1822a09c6a97982a2eb045b3a00e117332f9991a Mon Sep 17 00:00:00 2001 From: Kenrick Tandrian <60643640+KenTandrian@users.noreply.github.com> Date: Sun, 2 Aug 2026 02:40:26 +0700 Subject: [PATCH 1/3] Task/improve language localization for ZH (20260731) (#7490) * Update translations * Update changelog --- CHANGELOG.md | 6 + apps/client/src/locales/messages.zh.xlf | 152 ++++++++++++------------ 2 files changed, 82 insertions(+), 76 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b31046e8cd..cf5ab1a700 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,12 @@ 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 + +### Changed + +- Improved the language localization for Chinese (`zh`) + ## 3.39.0 - 2026-08-01 ### Changed diff --git a/apps/client/src/locales/messages.zh.xlf b/apps/client/src/locales/messages.zh.xlf index a70be75d61..7963e7767f 100644 --- a/apps/client/src/locales/messages.zh.xlf +++ b/apps/client/src/locales/messages.zh.xlf @@ -433,7 +433,7 @@ Copy - Copy + 复制 libs/ui/src/lib/notifications/alert-dialog/alert-dialog.html 20 @@ -605,7 +605,7 @@ Paid - Paid + 付费 apps/client/src/app/components/user-detail-dialog/user-detail-dialog.component.ts 129 @@ -657,7 +657,7 @@ Unknown - Unknown + 未知 libs/ui/src/lib/i18n.ts 88 @@ -701,7 +701,7 @@ and is driven by the efforts of its contributors - 并且得益于其 贡献者 + 并且得益于其 贡献者 apps/client/src/app/pages/about/overview/about-overview-page.html 50 @@ -749,7 +749,7 @@ Find an account... - Find an account... + 查找账户... libs/ui/src/lib/assistant/assistant.component.ts 448 @@ -777,7 +777,7 @@ Watch the Ghostfol.io Trailer on YouTube - Watch the Ghostfol.io Trailer on YouTube + 在 YouTube 上观看 Ghostfol.io 预告片 apps/client/src/app/pages/landing/landing-page.html 19 @@ -813,7 +813,7 @@ Category - Category + 类别 apps/client/src/app/pages/resources/personal-finance-tools/product-page.html 77 @@ -837,7 +837,7 @@ An error occurred while converting the data source to . - An error occurred while converting the data source to . + 将数据源转换为 时发生错误。 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts 482 @@ -885,7 +885,7 @@ Data Gathering Frequency - Data Gathering Frequency + 数据采集频率 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html 468 @@ -921,7 +921,7 @@ Apply current market price - Apply current market price + 应用当前市场价格 apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html 238 @@ -929,7 +929,7 @@ Subscription History - Subscription History + 订阅历史 apps/client/src/app/components/user-detail-dialog/user-detail-dialog.html 141 @@ -965,7 +965,7 @@ Healthcare - Healthcare + 医疗保健 libs/ui/src/lib/i18n.ts 97 @@ -1081,7 +1081,7 @@ Update Activity - Update Activity + 更新活动 libs/common/src/lib/routes/routes.ts 141 @@ -1089,7 +1089,7 @@ Technology - Technology + 科技 libs/ui/src/lib/i18n.ts 101 @@ -1105,7 +1105,7 @@ Total - Total + 总计 apps/client/src/app/components/user-detail-dialog/user-detail-dialog.html 160 @@ -1161,7 +1161,7 @@ Industrials - Industrials + 工业 libs/ui/src/lib/i18n.ts 98 @@ -1197,7 +1197,7 @@ Consumer Cyclical - Consumer Cyclical + 非必需消费品 libs/ui/src/lib/i18n.ts 93 @@ -1705,7 +1705,7 @@ The source code is fully available as open source software (OSS) under the AGPL-3.0 license - 源代码完全可用,作为开源软件 (OSS),遵循AGPL-3.0许可证 + 源代码完全可用,作为开源软件 (OSS),遵循AGPL-3.0许可证 apps/client/src/app/pages/about/overview/about-overview-page.html 16 @@ -1889,7 +1889,7 @@ Energy - Energy + 能源 libs/ui/src/lib/i18n.ts 95 @@ -2265,7 +2265,7 @@ Ghostfolio in Numbers: Monthly Active Users (MAU) - Ghostfolio in Numbers: Monthly Active Users (MAU) + Ghostfolio 数据:月活跃用户数 (MAU) apps/client/src/app/pages/landing/landing-page.html 63 @@ -2305,7 +2305,7 @@ The value has been copied to the clipboard - The value has been copied to the clipboard + 该值已复制到剪贴板 libs/ui/src/lib/notifications/alert-dialog/alert-dialog.component.ts 46 @@ -2357,7 +2357,7 @@ Consumer Defensive - Consumer Defensive + 必需消费品 libs/ui/src/lib/i18n.ts 94 @@ -2429,7 +2429,7 @@ Utilities - Utilities + 公用事业 libs/ui/src/lib/i18n.ts 102 @@ -2461,7 +2461,7 @@ Coupon - Coupon + 优惠券 apps/client/src/app/components/user-detail-dialog/user-detail-dialog.component.ts 134 @@ -2497,7 +2497,7 @@ Close Account - Close Account + 关闭账户 apps/client/src/app/components/user-account-settings/user-account-settings.html 337 @@ -2517,7 +2517,7 @@ Contributors to Ghostfolio - Contributors to Ghostfolio + Ghostfolio 贡献者 apps/client/src/app/pages/about/overview/about-overview-page.html 54 @@ -2561,7 +2561,7 @@ Investments - Investments + 投资 apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html 197 @@ -2853,7 +2853,7 @@ Financial Planning - Financial Planning + 财务规划 libs/ui/src/lib/i18n.ts 109 @@ -3121,7 +3121,7 @@ popular - popular + 热门 apps/client/src/app/components/admin-settings/admin-settings.component.html 79 @@ -3157,7 +3157,7 @@ Invalid API key - Invalid API key + 无效的 API 密钥 apps/client/src/app/components/admin-settings/admin-settings.component.html 112 @@ -3201,7 +3201,7 @@ For security reasons, please delete all activities and accounts first before your Ghostfolio account can be closed. - For security reasons, please delete all activities and accounts first before your Ghostfolio account can be closed. + 出于安全原因,在关闭您的 Ghostfolio 账户之前,请先删除所有活动和账户。 apps/client/src/app/components/user-account-settings/user-account-settings.html 348 @@ -3329,7 +3329,7 @@ Creation - Creation + 创建时间 apps/client/src/app/components/admin-overview/admin-overview.html 185 @@ -3373,7 +3373,7 @@ just now - just now + 刚刚 apps/client/src/app/components/admin-users/admin-users.component.ts 221 @@ -3561,7 +3561,7 @@ Basic Materials - Basic Materials + 基础材料 libs/ui/src/lib/i18n.ts 91 @@ -3705,7 +3705,7 @@ Oops! Could not delete the asset profiles. - Oops! Could not delete the asset profiles. + 哎呀!无法删除资产概况。 apps/client/src/app/components/admin-market-data/admin-market-data.service.ts 52 @@ -3777,7 +3777,7 @@ Add Activity - Add Activity + 添加活动 libs/common/src/lib/routes/routes.ts 134 @@ -3801,7 +3801,7 @@ At Ghostfolio, transparency is at the core of our values. We publish the source code as open source software (OSS) under the AGPL-3.0 license and we openly share aggregated key metrics of the platform’s operational status. - 在 Ghostfolio,透明度是我们价值观的核心。我们将源代码发布为开源软件(OSS)下AGPL-3.0许可证我们公开分享平台运营状态的汇总关键指标。 + 在 Ghostfolio,透明度是我们价值观的核心。我们将源代码发布为开源软件(OSS)下AGPL-3.0许可证我们公开分享平台运营状态的汇总关键指标。 apps/client/src/app/pages/open/open-page.html 7 @@ -3845,7 +3845,7 @@ Convert to - Convert to + 转换为 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html 175 @@ -3897,7 +3897,7 @@ Available on - Available on + 适用于 apps/client/src/app/pages/resources/personal-finance-tools/product-page.html 130 @@ -4197,7 +4197,7 @@ Price - Price + 价格 apps/client/src/app/components/user-detail-dialog/user-detail-dialog.html 176 @@ -4205,7 +4205,7 @@ Do you really want to convert this asset profile to ()? - Do you really want to convert this asset profile to ()? + 您确定要把此资产概况转换为 () 吗? apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts 723 @@ -4305,7 +4305,7 @@ Trial - Trial + 试用 apps/client/src/app/components/user-detail-dialog/user-detail-dialog.component.ts 133 @@ -4605,7 +4605,7 @@ Hourly - Hourly + 每小时 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts 216 @@ -4717,7 +4717,7 @@ Expiration - Expiration + 到期时间 apps/client/src/app/components/user-detail-dialog/user-detail-dialog.html 209 @@ -4970,7 +4970,7 @@ Coupon has been created - Coupon has been created + 优惠券 已创建 apps/client/src/app/components/admin-overview/admin-overview.component.ts 224 @@ -5022,7 +5022,7 @@ Upgrade to Ghostfolio Premium - Upgrade to Ghostfolio Premium + 升级至 Ghostfolio Premium libs/ui/src/lib/premium-indicator/premium-indicator.component.html 4 @@ -5110,7 +5110,7 @@ Stock Tracking - Stock Tracking + 股票追踪 libs/ui/src/lib/i18n.ts 112 @@ -5134,7 +5134,7 @@ Web - Web + 网页 libs/ui/src/lib/i18n.ts 121 @@ -5334,7 +5334,7 @@ Portfolio Filters - Portfolio Filters + 组合筛选器 apps/client/src/app/components/user-account-access/create-or-update-access-dialog/create-or-update-access-dialog.html 63 @@ -5390,7 +5390,7 @@ {VAR_PLURAL, plural, =1 {Profile} other {Profiles}} - {VAR_PLURAL, plural, =1 {Profile} other {Profiles}} + {VAR_PLURAL, plural, =1 {个资产概况} other {个资产概况}} apps/client/src/app/components/admin-market-data/admin-market-data.html 275 @@ -5710,7 +5710,7 @@ Ghostfolio in Numbers: Pulls on Docker Hub - Ghostfolio in Numbers: Pulls on Docker Hub + Ghostfolio 数据:Docker Hub 下载量 apps/client/src/app/pages/landing/landing-page.html 101 @@ -6022,7 +6022,7 @@ Communication Services - Communication Services + 通信服务 libs/ui/src/lib/i18n.ts 92 @@ -6062,7 +6062,7 @@ Invested Capital - Invested Capital + 投入资本 apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html 174 @@ -6346,7 +6346,7 @@ Expires () - Expires () + 到期时间 () apps/client/src/app/components/admin-users/admin-users.html 34 @@ -6386,7 +6386,7 @@ Fetch market price - Fetch market price + 获取市场价格 libs/ui/src/lib/historical-market-data-editor/historical-market-data-editor-dialog/historical-market-data-editor-dialog.html 40 @@ -6479,7 +6479,7 @@ Find a holding... - Find a holding... + 查找持仓... libs/ui/src/lib/assistant/assistant.component.ts 449 @@ -6507,7 +6507,7 @@ Daily - Daily + 每天 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts 212 @@ -6639,7 +6639,7 @@ Jump to a page... - Jump to a page... + 跳转到页面... libs/ui/src/lib/assistant/assistant.component.ts 450 @@ -6687,7 +6687,7 @@ Clone Activity - Clone Activity + 克隆活动 libs/common/src/lib/routes/routes.ts 129 @@ -6835,7 +6835,7 @@ Oops! Could not delete the asset profile. - Oops! Could not delete the asset profile. + 哎呀!无法删除资产概况。 apps/client/src/app/components/admin-market-data/admin-market-data.service.ts 51 @@ -6939,7 +6939,7 @@ Do you really want to delete these asset profiles? - Do you really want to delete these asset profiles? + 您确定要删除这 个资产概况吗? apps/client/src/app/components/admin-market-data/admin-market-data.service.ts 67 @@ -7119,7 +7119,7 @@ Tax Reporting - Tax Reporting + 税务报告 libs/ui/src/lib/i18n.ts 113 @@ -7135,7 +7135,7 @@ Change with currency effect Change - 含货币影响的涨跌 涨跌 + 含货币影响的涨跌 涨跌 apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html 64 @@ -7151,7 +7151,7 @@ Performance with currency effect Performance - 含货币影响的表现 表现 + 含货币影响的表现 表现 apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html 84 @@ -7199,7 +7199,7 @@ has been copied to the clipboard - 已复制到剪贴板 + 已复制到剪贴板 apps/client/src/app/components/admin-overview/admin-overview.component.ts 223 @@ -7219,7 +7219,7 @@ Compare Ghostfolio to - - Compare Ghostfolio to - + 对比 Ghostfolio 与 - apps/client/src/app/pages/resources/personal-finance-tools/personal-finance-tools-page.html 32 @@ -7267,7 +7267,7 @@ Financial Services - Financial Services + 金融服务 libs/ui/src/lib/i18n.ts 96 @@ -7295,7 +7295,7 @@ Delete - Delete + 删除 apps/client/src/app/components/admin-market-data/admin-market-data.html 270 @@ -7355,7 +7355,7 @@ Dividend Tracking - Dividend Tracking + 股息追踪 libs/ui/src/lib/i18n.ts 106 @@ -7415,7 +7415,7 @@ Investment Research - Investment Research + 投资研究 libs/ui/src/lib/i18n.ts 110 @@ -7697,7 +7697,7 @@ Net Worth Tracking - Net Worth Tracking + 净资产追踪 libs/ui/src/lib/i18n.ts 111 @@ -7769,7 +7769,7 @@ Do you really want to convert the data source to ? - Do you really want to convert the data source to ? + 您确定要把数据源转换为 吗? apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts 485 @@ -7837,7 +7837,7 @@ Ghostfolio in Numbers: Stars on GitHub - Ghostfolio in Numbers: Stars on GitHub + Ghostfolio 数据:GitHub Stars 数量 apps/client/src/app/pages/landing/landing-page.html 82 @@ -8167,7 +8167,7 @@ ETF Tracking - ETF Tracking + ETF 追踪 libs/ui/src/lib/i18n.ts 107 @@ -8333,7 +8333,7 @@ Post to Ghostfolio on X (formerly Twitter) - Post to Ghostfolio on X (formerly Twitter) + 在 X (前身为 Twitter) 上发布给 Ghostfolio apps/client/src/app/pages/about/overview/about-overview-page.html 85 @@ -8570,7 +8570,7 @@ If you encounter a bug, would like to suggest an improvement or a new feature, please join the Ghostfolio Slack community, post to @ghostfolio_ - 如果您遇到错误,想要建议改进或新功能,请加入 Ghostfolio Slack 社区,发布到 @ghostfolio_ + 如果您遇到错误,想要建议改进或新功能,请加入 Ghostfolio Slack 社区,发布到 @ghostfolio_ apps/client/src/app/pages/about/overview/about-overview-page.html 71 From c3e70091aee0f08389e4ab5a23425839a9a79379 Mon Sep 17 00:00:00 2001 From: Thomas Kaul <4159106+dtslvr@users.noreply.github.com> Date: Sat, 1 Aug 2026 23:01:38 +0200 Subject: [PATCH 2/3] Bugfix/validation error caused by empty strings in asset profile details dialog (#7509) * Resolve validation error caused by empty strings * Update changelog --- CHANGELOG.md | 4 ++ .../asset-profile-dialog.component.ts | 16 +++-- .../src/lib/dtos/update-asset-profile.dto.ts | 4 +- libs/common/src/lib/helper.spec.ts | 58 +++++++++++++++++++ libs/common/src/lib/helper.ts | 20 +++++++ 5 files changed, 94 insertions(+), 8 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index cf5ab1a700..054a24bdf3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Improved the language localization for Chinese (`zh`) +### Fixed + +- Resolved a validation error caused by empty strings in the asset profile details dialog of the admin control panel + ## 3.39.0 - 2026-08-01 ### Changed diff --git a/apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts b/apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts index c5562740fd..330688da18 100644 --- a/apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts +++ b/apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts @@ -11,6 +11,8 @@ import { DATE_FORMAT, getCountryName, getCurrencyFromSymbol, + getStringOrNull, + getStringOrUndefined, isCurrency } from '@ghostfolio/common/helper'; import { @@ -568,9 +570,10 @@ export class GfAssetProfileDialogComponent implements OnInit { this.assetProfileForm.controls.scraperConfiguration.controls.headers .value ?? '{}' ) as Record, - locale: + locale: getStringOrUndefined( this.assetProfileForm.controls.scraperConfiguration.controls.locale - ?.value ?? undefined, + ?.value + ), mode: this.assetProfileForm.controls.scraperConfiguration.controls.mode ?.value ?? undefined, @@ -619,7 +622,7 @@ export class GfAssetProfileDialogComponent implements OnInit { assetClass: this.assetProfileForm.controls.assetClass.value ?? undefined, assetSubClass: this.assetProfileForm.controls.assetSubClass.value ?? undefined, - comment: this.assetProfileForm.controls.comment.value ?? undefined, + comment: getStringOrNull(this.assetProfileForm.controls.comment.value), currency: this.assetProfileForm.controls.currency.value ?? undefined, dataGatheringFrequency: this.assetProfileForm.controls.dataGatheringFrequency.value ?? @@ -628,7 +631,7 @@ export class GfAssetProfileDialogComponent implements OnInit { ? this.assetProfileForm.controls.isActive.value : undefined, name: this.assetProfileForm.controls.name.value ?? undefined, - url: this.assetProfileForm.controls.url.value ?? undefined + url: getStringOrNull(this.assetProfileForm.controls.url.value) }; try { @@ -737,9 +740,10 @@ export class GfAssetProfileDialogComponent implements OnInit { this.assetProfileForm.controls.scraperConfiguration.controls.headers .value ?? '{}' ) as Record, - locale: + locale: getStringOrUndefined( this.assetProfileForm.controls.scraperConfiguration.controls.locale - ?.value ?? undefined, + ?.value + ), mode: this.assetProfileForm.controls.scraperConfiguration.controls .mode?.value, selector: diff --git a/libs/common/src/lib/dtos/update-asset-profile.dto.ts b/libs/common/src/lib/dtos/update-asset-profile.dto.ts index a6e2230e8e..a8eaad608a 100644 --- a/libs/common/src/lib/dtos/update-asset-profile.dto.ts +++ b/libs/common/src/lib/dtos/update-asset-profile.dto.ts @@ -35,7 +35,7 @@ export class UpdateAssetProfileDto { @IsOptional() @IsString() - comment?: string; + comment?: string | null; @IsArray() @IsOptional() @@ -96,5 +96,5 @@ export class UpdateAssetProfileDto { protocols: ['http', 'https'], require_protocol: true }) - url?: string; + url?: string | null; } diff --git a/libs/common/src/lib/helper.spec.ts b/libs/common/src/lib/helper.spec.ts index d33f104522..7589347240 100644 --- a/libs/common/src/lib/helper.spec.ts +++ b/libs/common/src/lib/helper.spec.ts @@ -1,6 +1,8 @@ import { extractNumberFromString, getNumberFormatGroup, + getStringOrNull, + getStringOrUndefined, isCurrency, isCurrencySymbol } from '@ghostfolio/common/helper'; @@ -139,6 +141,62 @@ describe('Helper', () => { }); }); + describe('Get string or null', () => { + it('String', () => { + expect(getStringOrNull('https://ghostfol.io')).toEqual( + 'https://ghostfol.io' + ); + }); + + it('String (with spaces)', () => { + expect(getStringOrNull(' https://ghostfol.io ')).toEqual( + 'https://ghostfol.io' + ); + }); + + it('Empty string', () => { + expect(getStringOrNull('')).toEqual(null); + }); + + it('Blank string', () => { + expect(getStringOrNull(' ')).toEqual(null); + }); + + it('Null', () => { + expect(getStringOrNull(null)).toEqual(null); + }); + + it('Undefined', () => { + expect(getStringOrNull(undefined)).toEqual(null); + }); + }); + + describe('Get string or undefined', () => { + it('String', () => { + expect(getStringOrUndefined('de-DE')).toEqual('de-DE'); + }); + + it('String (with spaces)', () => { + expect(getStringOrUndefined(' de-DE ')).toEqual('de-DE'); + }); + + it('Empty string', () => { + expect(getStringOrUndefined('')).toEqual(undefined); + }); + + it('Blank string', () => { + expect(getStringOrUndefined(' ')).toEqual(undefined); + }); + + it('Null', () => { + expect(getStringOrUndefined(null)).toEqual(undefined); + }); + + it('Undefined', () => { + expect(getStringOrUndefined(undefined)).toEqual(undefined); + }); + }); + describe('Is currency', () => { it('ISO 4217 currency code', () => { expect(isCurrency('USD')).toEqual(true); diff --git a/libs/common/src/lib/helper.ts b/libs/common/src/lib/helper.ts index db1d3c2a20..7e482838c0 100644 --- a/libs/common/src/lib/helper.ts +++ b/libs/common/src/lib/helper.ts @@ -397,6 +397,26 @@ export function getStartOfUtcDate(aDate: Date) { return date; } +export function getStringOrNull(aString: string | null | undefined) { + const trimmedString = aString?.trim(); + + if (trimmedString) { + return trimmedString; + } + + return null; +} + +export function getStringOrUndefined(aString: string | null | undefined) { + const trimmedString = aString?.trim(); + + if (trimmedString) { + return trimmedString; + } + + return undefined; +} + export function getSum(aArray: Big[]) { if (aArray?.length > 0) { return aArray.reduce((a, b) => a.plus(b), new Big(0)); From fa309b57435df39f0b1ad5a25c2b13c3145e2642 Mon Sep 17 00:00:00 2001 From: Thomas Kaul <4159106+dtslvr@users.noreply.github.com> Date: Sat, 1 Aug 2026 23:16:24 +0200 Subject: [PATCH 3/3] Bugfix/handling of Exclude from Analysis tag in activities table (#7511) * Fix handling of Exclude from Analysis tag * Update changelog --- CHANGELOG.md | 1 + libs/common/src/lib/helper.spec.ts | 27 +++++++++++++++++++ libs/common/src/lib/helper.ts | 4 +-- .../activities-table.component.ts | 2 +- 4 files changed, 31 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 054a24bdf3..1118f2a692 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,6 +13,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Fixed +- Fixed the handling of the _Exclude from Analysis_ tag in the activities table - Resolved a validation error caused by empty strings in the asset profile details dialog of the admin control panel ## 3.39.0 - 2026-08-01 diff --git a/libs/common/src/lib/helper.spec.ts b/libs/common/src/lib/helper.spec.ts index 7589347240..c4947394f6 100644 --- a/libs/common/src/lib/helper.spec.ts +++ b/libs/common/src/lib/helper.spec.ts @@ -1,8 +1,13 @@ +import { + TAG_ID_EMERGENCY_FUND, + TAG_ID_EXCLUDE_FROM_ANALYSIS +} from '@ghostfolio/common/config'; import { extractNumberFromString, getNumberFormatGroup, getStringOrNull, getStringOrUndefined, + isAccountExcluded, isCurrency, isCurrencySymbol } from '@ghostfolio/common/helper'; @@ -197,6 +202,28 @@ describe('Helper', () => { }); }); + describe('Is account excluded', () => { + it('Account with Exclude from Analysis tag', () => { + expect( + isAccountExcluded({ tags: [{ id: TAG_ID_EXCLUDE_FROM_ANALYSIS }] }) + ).toEqual(true); + }); + + it('Account with another tag', () => { + expect( + isAccountExcluded({ tags: [{ id: TAG_ID_EMERGENCY_FUND }] }) + ).toEqual(false); + }); + + it('Account without tags', () => { + expect(isAccountExcluded({ tags: [] })).toEqual(false); + }); + + it('Undefined account', () => { + expect(isAccountExcluded(undefined)).toEqual(false); + }); + }); + describe('Is currency', () => { it('ISO 4217 currency code', () => { expect(isCurrency('USD')).toEqual(true); diff --git a/libs/common/src/lib/helper.ts b/libs/common/src/lib/helper.ts index 7e482838c0..58927337ee 100644 --- a/libs/common/src/lib/helper.ts +++ b/libs/common/src/lib/helper.ts @@ -476,9 +476,9 @@ export function interpolate(template: string, context: any) { }); } -export function isAccountExcluded(account: { tags?: { id: string }[] }) { +export function isAccountExcluded(account?: { tags?: { id: string }[] }) { return ( - account.tags?.some(({ id }) => { + account?.tags?.some(({ id }) => { return id === TAG_ID_EXCLUDE_FROM_ANALYSIS; }) === true ); diff --git a/libs/ui/src/lib/activities-table/activities-table.component.ts b/libs/ui/src/lib/activities-table/activities-table.component.ts index 6fac6d1625..7252b00740 100644 --- a/libs/ui/src/lib/activities-table/activities-table.component.ts +++ b/libs/ui/src/lib/activities-table/activities-table.component.ts @@ -298,7 +298,7 @@ export class GfActivitiesTableComponent implements AfterViewInit, OnInit { public isExcludedFromAnalysis(activity: Activity) { return ( - (activity.account && isAccountExcluded(activity.account)) ?? + isAccountExcluded(activity.account) || activity.tags?.some(({ id }) => { return id === TAG_ID_EXCLUDE_FROM_ANALYSIS; }) === true