From e66df158e949d0bdda3cfcf15d7c80dfd30a111e Mon Sep 17 00:00:00 2001
From: Thomas Kaul <4159106+dtslvr@users.noreply.github.com>
Date: Tue, 23 Jun 2026 17:21:00 +0200
Subject: [PATCH 1/5] Task/extend personal finance tools (20260623) (#7112)
Extend personal finance tools
---
libs/common/src/lib/personal-finance-tools.ts | 51 +++++++++++++++++++
1 file changed, 51 insertions(+)
diff --git a/libs/common/src/lib/personal-finance-tools.ts b/libs/common/src/lib/personal-finance-tools.ts
index 744081464..265d1b6b9 100644
--- a/libs/common/src/lib/personal-finance-tools.ts
+++ b/libs/common/src/lib/personal-finance-tools.ts
@@ -438,6 +438,17 @@ export const personalFinanceTools: Product[] = [
slogan: 'Portfolio Tracker für dein Vermögen',
url: 'https://www.finanzfluss.de/copilot'
},
+ {
+ founded: 2015,
+ hasFreePlan: true,
+ hasSelfHostingAbility: false,
+ key: 'finanzguru',
+ languages: ['Deutsch'],
+ name: 'Finanzguru',
+ origin: 'DE',
+ slogan: 'Finanzen. Magisch. Einfach.',
+ url: 'https://www.finanzguru.de'
+ },
{
founded: 2020,
key: 'finary',
@@ -611,6 +622,15 @@ export const personalFinanceTools: Product[] = [
slogan: 'Finance App for Couples',
url: 'https://www.honeydue.com'
},
+ {
+ founded: 2003,
+ hasSelfHostingAbility: true,
+ isArchived: true,
+ key: 'ibank',
+ name: 'iBank',
+ note: 'Renamed to Banktivity',
+ origin: 'US'
+ },
{
founded: 2022,
key: 'income-reign',
@@ -817,6 +837,17 @@ export const personalFinanceTools: Product[] = [
slogan: 'Personal Finance Manager for Mac, Windows, and Linux',
url: 'https://moneydance.com'
},
+ {
+ founded: 2016,
+ hasFreePlan: true,
+ hasSelfHostingAbility: false,
+ key: 'moneypatrol',
+ name: 'MoneyPatrol',
+ origin: 'US',
+ pricingPerYear: '$29.99',
+ slogan: 'Personal Accounting Made Easy, Accurate, Comprehensive',
+ url: 'https://www.moneypatrol.com'
+ },
{
hasFreePlan: true,
hasSelfHostingAbility: false,
@@ -1390,6 +1421,26 @@ export const personalFinanceTools: Product[] = [
pricingPerYear: '$600',
slogan: 'Make Smarter Investments'
},
+ {
+ founded: 2020,
+ hasFreePlan: true,
+ hasSelfHostingAbility: false,
+ key: 'wallstreetzen',
+ name: 'WallStreetZen',
+ origin: 'HK',
+ pricingPerYear: '$234',
+ slogan: 'Stock market analysis for the serious part-time investor',
+ url: 'https://www.wallstreetzen.com'
+ },
+ {
+ founded: 2015,
+ hasSelfHostingAbility: false,
+ key: 'wealtharc',
+ name: 'WealthArc',
+ origin: 'CH',
+ slogan: 'Manage wealth data more efficiently',
+ url: 'https://www.wealtharc.com'
+ },
{
founded: 2019,
hasFreePlan: false,
From 09486ef56efedbe5beaabbcbfa9b67ac34ad652e Mon Sep 17 00:00:00 2001
From: Thomas Kaul <4159106+dtslvr@users.noreply.github.com>
Date: Tue, 23 Jun 2026 17:21:26 +0200
Subject: [PATCH 2/5] Task/harmonize price column in subscription table of user
detail dialog (#7108)
Harmonize price column
---
.../app/components/user-detail-dialog/user-detail-dialog.html | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/apps/client/src/app/components/user-detail-dialog/user-detail-dialog.html b/apps/client/src/app/components/user-detail-dialog/user-detail-dialog.html
index 18bd00a41..0b0b59e7d 100644
--- a/apps/client/src/app/components/user-detail-dialog/user-detail-dialog.html
+++ b/apps/client/src/app/components/user-detail-dialog/user-detail-dialog.html
@@ -171,7 +171,8 @@
mat-cell
>
@if (element.price === null) {
- —
+ –
+ {{ baseCurrency }}
} @else {
Date: Tue, 23 Jun 2026 17:21:55 +0200
Subject: [PATCH 3/5] Bugfix/disabled state of delete action menu item in
market data of admin control panel (#7111)
* Fix disabled state
* Update changelog
---
CHANGELOG.md | 6 ++++++
.../app/components/admin-market-data/admin-market-data.html | 3 ++-
2 files changed, 8 insertions(+), 1 deletion(-)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index d72694758..bccd353cf 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
+
+### Fixed
+
+- Fixed the disabled state of the delete action in the asset profiles actions menu of the historical market data table in the admin control panel
+
## 3.14.0 - 2026-06-22
### Added
diff --git a/apps/client/src/app/components/admin-market-data/admin-market-data.html b/apps/client/src/app/components/admin-market-data/admin-market-data.html
index 270722a4b..83703b548 100644
--- a/apps/client/src/app/components/admin-market-data/admin-market-data.html
+++ b/apps/client/src/app/components/admin-market-data/admin-market-data.html
@@ -285,7 +285,8 @@
!canDeleteAssetProfile({
activitiesCount: element.activitiesCount,
isBenchmark: element.isBenchmark,
- symbol: element.symbol
+ symbol: element.symbol,
+ watchedByCount: element.watchedByCount
})
"
(click)="
From 608f9673b46cc17e31c45112935d2ff67df588f4 Mon Sep 17 00:00:00 2001
From: Thomas Kaul <4159106+dtslvr@users.noreply.github.com>
Date: Tue, 23 Jun 2026 21:43:58 +0200
Subject: [PATCH 4/5] Task/improve dynamic numerical precision for various
values in account and holding detail dialogs on mobile (#7113)
* Improve dynamic numerical precision
* Update changelog
---
CHANGELOG.md | 5 +++++
.../account-detail-dialog.component.ts | 10 +++++-----
.../holding-detail-dialog.component.ts | 16 ++++++++--------
libs/common/src/lib/config.ts | 1 +
4 files changed, 19 insertions(+), 13 deletions(-)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index bccd353cf..28c2b25c4 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -7,6 +7,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
## Unreleased
+### Changed
+
+- Improved the dynamic numerical precision for various values in the account detail dialog on mobile
+- Improved the dynamic numerical precision for various values in the holding detail dialog on mobile
+
### Fixed
- Fixed the disabled state of the delete action in the asset profiles actions menu of the historical market data table in the admin control panel
diff --git a/apps/client/src/app/components/account-detail-dialog/account-detail-dialog.component.ts b/apps/client/src/app/components/account-detail-dialog/account-detail-dialog.component.ts
index 7cdf3e671..5af8c9d00 100644
--- a/apps/client/src/app/components/account-detail-dialog/account-detail-dialog.component.ts
+++ b/apps/client/src/app/components/account-detail-dialog/account-detail-dialog.component.ts
@@ -3,7 +3,7 @@ import { UserService } from '@ghostfolio/client/services/user/user.service';
import {
DEFAULT_DATE_RANGE,
DEFAULT_PAGE_SIZE,
- NUMERICAL_PRECISION_THRESHOLD_5_FIGURES
+ NUMERICAL_PRECISION_THRESHOLD_4_FIGURES
} from '@ghostfolio/common/config';
import { CreateAccountBalanceDto } from '@ghostfolio/common/dtos';
import { DATE_FORMAT, downloadAsFile } from '@ghostfolio/common/helper';
@@ -245,7 +245,7 @@ export class GfAccountDetailDialogComponent implements OnInit {
this.balance = balance;
if (
- this.balance >= NUMERICAL_PRECISION_THRESHOLD_5_FIGURES &&
+ this.balance >= NUMERICAL_PRECISION_THRESHOLD_4_FIGURES &&
this.data.deviceType === 'mobile'
) {
this.balancePrecision = 0;
@@ -257,7 +257,7 @@ export class GfAccountDetailDialogComponent implements OnInit {
if (
this.data.deviceType === 'mobile' &&
this.dividendInBaseCurrency >=
- NUMERICAL_PRECISION_THRESHOLD_5_FIGURES
+ NUMERICAL_PRECISION_THRESHOLD_4_FIGURES
) {
this.dividendInBaseCurrencyPrecision = 0;
}
@@ -267,7 +267,7 @@ export class GfAccountDetailDialogComponent implements OnInit {
if (
this.data.deviceType === 'mobile' &&
- this.equity >= NUMERICAL_PRECISION_THRESHOLD_5_FIGURES
+ this.equity >= NUMERICAL_PRECISION_THRESHOLD_4_FIGURES
) {
this.equityPrecision = 0;
}
@@ -280,7 +280,7 @@ export class GfAccountDetailDialogComponent implements OnInit {
if (
this.data.deviceType === 'mobile' &&
this.interestInBaseCurrency >=
- NUMERICAL_PRECISION_THRESHOLD_5_FIGURES
+ NUMERICAL_PRECISION_THRESHOLD_4_FIGURES
) {
this.interestInBaseCurrencyPrecision = 0;
}
diff --git a/apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.component.ts b/apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.component.ts
index 1eb0d4ab6..e14c638be 100644
--- a/apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.component.ts
+++ b/apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.component.ts
@@ -2,7 +2,7 @@ import { UserService } from '@ghostfolio/client/services/user/user.service';
import {
DEFAULT_PAGE_SIZE,
NUMERICAL_PRECISION_THRESHOLD_3_FIGURES,
- NUMERICAL_PRECISION_THRESHOLD_5_FIGURES
+ NUMERICAL_PRECISION_THRESHOLD_4_FIGURES
} from '@ghostfolio/common/config';
import { CreateOrderDto } from '@ghostfolio/common/dtos';
import {
@@ -288,7 +288,7 @@ export class GfHoldingDetailDialogComponent implements OnInit {
this.averagePrice = averagePrice;
if (
- this.averagePrice >= NUMERICAL_PRECISION_THRESHOLD_5_FIGURES &&
+ this.averagePrice >= NUMERICAL_PRECISION_THRESHOLD_4_FIGURES &&
this.data.deviceType === 'mobile'
) {
this.averagePricePrecision = 0;
@@ -307,7 +307,7 @@ export class GfHoldingDetailDialogComponent implements OnInit {
if (
this.data.deviceType === 'mobile' &&
this.dividendInBaseCurrency >=
- NUMERICAL_PRECISION_THRESHOLD_5_FIGURES
+ NUMERICAL_PRECISION_THRESHOLD_4_FIGURES
) {
this.dividendInBaseCurrencyPrecision = 0;
}
@@ -345,7 +345,7 @@ export class GfHoldingDetailDialogComponent implements OnInit {
if (
this.data.deviceType === 'mobile' &&
this.investmentInBaseCurrencyWithCurrencyEffect >=
- NUMERICAL_PRECISION_THRESHOLD_5_FIGURES
+ NUMERICAL_PRECISION_THRESHOLD_4_FIGURES
) {
this.investmentInBaseCurrencyWithCurrencyEffectPrecision = 0;
}
@@ -355,7 +355,7 @@ export class GfHoldingDetailDialogComponent implements OnInit {
if (
this.data.deviceType === 'mobile' &&
- this.marketPriceMax >= NUMERICAL_PRECISION_THRESHOLD_5_FIGURES
+ this.marketPriceMax >= NUMERICAL_PRECISION_THRESHOLD_4_FIGURES
) {
this.marketPriceMaxPrecision = 0;
}
@@ -364,14 +364,14 @@ export class GfHoldingDetailDialogComponent implements OnInit {
if (
this.data.deviceType === 'mobile' &&
- this.marketPriceMin >= NUMERICAL_PRECISION_THRESHOLD_5_FIGURES
+ this.marketPriceMin >= NUMERICAL_PRECISION_THRESHOLD_4_FIGURES
) {
this.marketPriceMinPrecision = 0;
}
if (
this.data.deviceType === 'mobile' &&
- this.marketPrice >= NUMERICAL_PRECISION_THRESHOLD_5_FIGURES
+ this.marketPrice >= NUMERICAL_PRECISION_THRESHOLD_4_FIGURES
) {
this.marketPricePrecision = 0;
}
@@ -393,7 +393,7 @@ export class GfHoldingDetailDialogComponent implements OnInit {
if (
this.data.deviceType === 'mobile' &&
this.netPerformanceWithCurrencyEffect >=
- NUMERICAL_PRECISION_THRESHOLD_5_FIGURES
+ NUMERICAL_PRECISION_THRESHOLD_4_FIGURES
) {
this.netPerformanceWithCurrencyEffectPrecision = 0;
}
diff --git a/libs/common/src/lib/config.ts b/libs/common/src/lib/config.ts
index 40412d627..e6d717c7b 100644
--- a/libs/common/src/lib/config.ts
+++ b/libs/common/src/lib/config.ts
@@ -231,6 +231,7 @@ export const HEADER_KEY_SKIP_INTERCEPTOR = 'X-Skip-Interceptor';
export const MAX_TOP_HOLDINGS = 50;
export const NUMERICAL_PRECISION_THRESHOLD_3_FIGURES = 100;
+export const NUMERICAL_PRECISION_THRESHOLD_4_FIGURES = 1000;
export const NUMERICAL_PRECISION_THRESHOLD_5_FIGURES = 10000;
export const NUMERICAL_PRECISION_THRESHOLD_6_FIGURES = 100000;
From 4996ad6425bb73c1bb6b04ab5a0ccb62c7810948 Mon Sep 17 00:00:00 2001
From: Thomas Kaul <4159106+dtslvr@users.noreply.github.com>
Date: Tue, 23 Jun 2026 21:44:51 +0200
Subject: [PATCH 5/5] Bugfix/handle empty locale string in scraper
configuration (#7109)
* Handle empty locale string in scraper configuration
* Update changelog
---
CHANGELOG.md | 1 +
.../asset-profile-dialog/asset-profile-dialog.component.ts | 2 +-
2 files changed, 2 insertions(+), 1 deletion(-)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 28c2b25c4..0faaca8d0 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -15,6 +15,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Fixed
- Fixed the disabled state of the delete action in the asset profiles actions menu of the historical market data table in the admin control panel
+- Fixed the persistence of an empty `locale` string in the scraper configuration
## 3.14.0 - 2026-06-22
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 5ceb5808a..967a289ef 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
@@ -550,7 +550,7 @@ export class GfAssetProfileDialogComponent implements OnInit {
) as Record,
locale:
this.assetProfileForm.controls.scraperConfiguration.controls.locale
- ?.value ?? undefined,
+ ?.value || undefined,
mode:
this.assetProfileForm.controls.scraperConfiguration.controls.mode
?.value ?? undefined,