From ed29c2ceab548741743577fbff1831be885b5eb3 Mon Sep 17 00:00:00 2001 From: Thomas Kaul <4159106+dtslvr@users.noreply.github.com> Date: Thu, 12 Feb 2026 18:35:45 +0100 Subject: [PATCH 001/224] Bugfix/fix issue in annualized performance calculation (#6310) * Fix issue in annualized performance calculation: Handle case where growthFactor is Infinity * Update changelog --- CHANGELOG.md | 4 ++++ libs/common/src/lib/calculation-helper.ts | 4 ++-- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index edbfa5460..696ed2dbd 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 - Upgraded `twitter-api-v2` from version `1.27.0` to `1.29.0` +### Fixed + +- Fixed an issue in the annualized performance calculation + ## 2.237.0 - 2026-02-08 ### Changed diff --git a/libs/common/src/lib/calculation-helper.ts b/libs/common/src/lib/calculation-helper.ts index d67384a30..76b38f9b2 100644 --- a/libs/common/src/lib/calculation-helper.ts +++ b/libs/common/src/lib/calculation-helper.ts @@ -9,7 +9,7 @@ import { subDays, subYears } from 'date-fns'; -import { isNumber } from 'lodash'; +import { isFinite, isNumber } from 'lodash'; import { resetHours } from './helper'; import { DateRange } from './types'; @@ -28,7 +28,7 @@ export function getAnnualizedPerformancePercent({ exponent ); - if (!isNaN(growthFactor)) { + if (isFinite(growthFactor)) { return new Big(growthFactor).minus(1); } } From 4ba142682a2ff1e09f1e7d183e91f1d51b9cfe97 Mon Sep 17 00:00:00 2001 From: Thomas Kaul <4159106+dtslvr@users.noreply.github.com> Date: Thu, 12 Feb 2026 18:37:40 +0100 Subject: [PATCH 002/224] Task/upgrade ngx-skeleton-loader to version 12.0.0 (#6304) * Upgrade ngx-skeleton-loader to version 12.0.0 * Update changelog --- CHANGELOG.md | 1 + package-lock.json | 8 ++++---- package.json | 2 +- 3 files changed, 6 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 696ed2dbd..2e6feba4a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Changed +- Upgraded `ngx-skeleton-loader` from version `11.3.0` to `12.0.0` - Upgraded `twitter-api-v2` from version `1.27.0` to `1.29.0` ### Fixed diff --git a/package-lock.json b/package-lock.json index d415758b1..4c70d88f6 100644 --- a/package-lock.json +++ b/package-lock.json @@ -75,7 +75,7 @@ "ng-extract-i18n-merge": "3.2.1", "ngx-device-detector": "11.0.0", "ngx-markdown": "21.0.1", - "ngx-skeleton-loader": "11.3.0", + "ngx-skeleton-loader": "12.0.0", "open-color": "1.9.1", "papaparse": "5.3.1", "passport": "0.7.0", @@ -26249,9 +26249,9 @@ } }, "node_modules/ngx-skeleton-loader": { - "version": "11.3.0", - "resolved": "https://registry.npmjs.org/ngx-skeleton-loader/-/ngx-skeleton-loader-11.3.0.tgz", - "integrity": "sha512-MLm5shgXGiCA1W5NEqct6glBFx2AEgEKbk8pDyY15BsZ2zTGUwa5jw4pe6nJdrCj6xcl/d9oFTinQHrO0q+3RA==", + "version": "12.0.0", + "resolved": "https://registry.npmjs.org/ngx-skeleton-loader/-/ngx-skeleton-loader-12.0.0.tgz", + "integrity": "sha512-vGEytpLElYKSLovFHCJkwgPZOdy0lPqyejxuhVFcZJg9dsp07o0/NeM4/Nnc2oCDE8T/wkXSPIbrpKzfTDbMCQ==", "license": "MIT", "dependencies": { "tslib": "^2.0.0" diff --git a/package.json b/package.json index 0f43fff08..93ff182b7 100644 --- a/package.json +++ b/package.json @@ -119,7 +119,7 @@ "ng-extract-i18n-merge": "3.2.1", "ngx-device-detector": "11.0.0", "ngx-markdown": "21.0.1", - "ngx-skeleton-loader": "11.3.0", + "ngx-skeleton-loader": "12.0.0", "open-color": "1.9.1", "papaparse": "5.3.1", "passport": "0.7.0", From e361f093987af52ed2edeac692a4855d4c610e3f Mon Sep 17 00:00:00 2001 From: Thomas Kaul <4159106+dtslvr@users.noreply.github.com> Date: Thu, 12 Feb 2026 19:14:37 +0100 Subject: [PATCH 003/224] Bugfix/expand date range to cover full day in exchange rate calculation (#6311) * Expand date range (start to end of day) * Update changelog --- CHANGELOG.md | 1 + .../src/app/portfolio/calculator/portfolio-calculator.ts | 7 ++++--- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2e6feba4a..bb32902f0 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 an issue in the annualized performance calculation +- Fixed an issue with the exchange rate calculation by expanding the date range to cover the full day (start to end of day) ## 2.237.0 - 2026-02-08 diff --git a/apps/api/src/app/portfolio/calculator/portfolio-calculator.ts b/apps/api/src/app/portfolio/calculator/portfolio-calculator.ts index 2e58a4ef5..553cb8c90 100644 --- a/apps/api/src/app/portfolio/calculator/portfolio-calculator.ts +++ b/apps/api/src/app/portfolio/calculator/portfolio-calculator.ts @@ -53,6 +53,7 @@ import { isBefore, isWithinInterval, min, + startOfDay, startOfYear, subDays } from 'date-fns'; @@ -162,8 +163,8 @@ export abstract class PortfolioCalculator { subDays(dateOfFirstActivity, 1) ); - this.endDate = endDate; - this.startDate = startDate; + this.endDate = endOfDay(endDate); + this.startDate = startOfDay(startDate); this.computeTransactionPoints(); @@ -236,7 +237,7 @@ export abstract class PortfolioCalculator { const exchangeRatesByCurrency = await this.exchangeRateDataService.getExchangeRatesByCurrency({ currencies: Array.from(new Set(Object.values(currencies))), - endDate: endOfDay(this.endDate), + endDate: this.endDate, startDate: this.startDate, targetCurrency: this.currency }); From 373a4857acc161a5556132552f156569ec2a2baf Mon Sep 17 00:00:00 2001 From: Neeraj Bachani <124370566+neerajbachani@users.noreply.github.com> Date: Thu, 12 Feb 2026 23:53:23 +0530 Subject: [PATCH 004/224] Bugfix/reset buy tracking variables when position closes (#6298) * Reset buy tracking variables when position closes * Update changelog --------- Co-authored-by: Thomas Kaul <4159106+dtslvr@users.noreply.github.com> --- CHANGELOG.md | 1 + ...jnug-buy-and-sell-and-buy-and-sell.spec.ts | 190 ++++++++++++++++++ .../calculator/roai/portfolio-calculator.ts | 7 + .../portfolio/current-rate.service.mock.ts | 11 + .../jnug-buy-and-sell-and-buy-and-sell.json | 58 ++++++ 5 files changed, 267 insertions(+) create mode 100644 apps/api/src/app/portfolio/calculator/roai/portfolio-calculator-jnug-buy-and-sell-and-buy-and-sell.spec.ts create mode 100644 test/import/ok/jnug-buy-and-sell-and-buy-and-sell.json diff --git a/CHANGELOG.md b/CHANGELOG.md index bb32902f0..29cec0e76 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,6 +14,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Fixed +- Fixed a performance calculation issue by resetting tracking variables when a holding is fully closed - Fixed an issue in the annualized performance calculation - Fixed an issue with the exchange rate calculation by expanding the date range to cover the full day (start to end of day) diff --git a/apps/api/src/app/portfolio/calculator/roai/portfolio-calculator-jnug-buy-and-sell-and-buy-and-sell.spec.ts b/apps/api/src/app/portfolio/calculator/roai/portfolio-calculator-jnug-buy-and-sell-and-buy-and-sell.spec.ts new file mode 100644 index 000000000..d5b22e864 --- /dev/null +++ b/apps/api/src/app/portfolio/calculator/roai/portfolio-calculator-jnug-buy-and-sell-and-buy-and-sell.spec.ts @@ -0,0 +1,190 @@ +import { + activityDummyData, + loadExportFile, + symbolProfileDummyData, + userDummyData +} from '@ghostfolio/api/app/portfolio/calculator/portfolio-calculator-test-utils'; +import { PortfolioCalculatorFactory } from '@ghostfolio/api/app/portfolio/calculator/portfolio-calculator.factory'; +import { CurrentRateService } from '@ghostfolio/api/app/portfolio/current-rate.service'; +import { CurrentRateServiceMock } from '@ghostfolio/api/app/portfolio/current-rate.service.mock'; +import { RedisCacheService } from '@ghostfolio/api/app/redis-cache/redis-cache.service'; +import { RedisCacheServiceMock } from '@ghostfolio/api/app/redis-cache/redis-cache.service.mock'; +import { ConfigurationService } from '@ghostfolio/api/services/configuration/configuration.service'; +import { ExchangeRateDataService } from '@ghostfolio/api/services/exchange-rate-data/exchange-rate-data.service'; +import { PortfolioSnapshotService } from '@ghostfolio/api/services/queues/portfolio-snapshot/portfolio-snapshot.service'; +import { PortfolioSnapshotServiceMock } from '@ghostfolio/api/services/queues/portfolio-snapshot/portfolio-snapshot.service.mock'; +import { parseDate } from '@ghostfolio/common/helper'; +import { Activity, ExportResponse } from '@ghostfolio/common/interfaces'; +import { PerformanceCalculationType } from '@ghostfolio/common/types/performance-calculation-type.type'; + +import { Big } from 'big.js'; +import { join } from 'node:path'; + +jest.mock('@ghostfolio/api/app/portfolio/current-rate.service', () => { + return { + CurrentRateService: jest.fn().mockImplementation(() => { + return CurrentRateServiceMock; + }) + }; +}); + +jest.mock( + '@ghostfolio/api/services/queues/portfolio-snapshot/portfolio-snapshot.service', + () => { + return { + PortfolioSnapshotService: jest.fn().mockImplementation(() => { + return PortfolioSnapshotServiceMock; + }) + }; + } +); + +jest.mock('@ghostfolio/api/app/redis-cache/redis-cache.service', () => { + return { + RedisCacheService: jest.fn().mockImplementation(() => { + return RedisCacheServiceMock; + }) + }; +}); + +describe('PortfolioCalculator', () => { + let exportResponse: ExportResponse; + + let configurationService: ConfigurationService; + let currentRateService: CurrentRateService; + let exchangeRateDataService: ExchangeRateDataService; + let portfolioCalculatorFactory: PortfolioCalculatorFactory; + let portfolioSnapshotService: PortfolioSnapshotService; + let redisCacheService: RedisCacheService; + + beforeAll(() => { + exportResponse = loadExportFile( + join( + __dirname, + '../../../../../../../test/import/ok/jnug-buy-and-sell-and-buy-and-sell.json' + ) + ); + }); + + beforeEach(() => { + configurationService = new ConfigurationService(); + + currentRateService = new CurrentRateService(null, null, null, null); + + exchangeRateDataService = new ExchangeRateDataService( + null, + null, + null, + null + ); + + portfolioSnapshotService = new PortfolioSnapshotService(null); + + redisCacheService = new RedisCacheService(null, null); + + portfolioCalculatorFactory = new PortfolioCalculatorFactory( + configurationService, + currentRateService, + exchangeRateDataService, + portfolioSnapshotService, + redisCacheService + ); + }); + + describe('get current positions', () => { + it.only('with JNUG buy and sell', async () => { + jest.useFakeTimers().setSystemTime(parseDate('2025-12-28').getTime()); + + const activities: Activity[] = exportResponse.activities.map( + (activity) => ({ + ...activityDummyData, + ...activity, + date: parseDate(activity.date), + feeInAssetProfileCurrency: activity.fee, + feeInBaseCurrency: activity.fee, + SymbolProfile: { + ...symbolProfileDummyData, + currency: activity.currency, + dataSource: activity.dataSource, + name: 'Direxion Daily Junior Gold Miners Index Bull 2X Shares', + symbol: activity.symbol + }, + unitPriceInAssetProfileCurrency: activity.unitPrice + }) + ); + + const portfolioCalculator = portfolioCalculatorFactory.createCalculator({ + activities, + calculationType: PerformanceCalculationType.ROAI, + currency: exportResponse.user.settings.currency, + userId: userDummyData.id + }); + + const portfolioSnapshot = await portfolioCalculator.computeSnapshot(); + + const investments = portfolioCalculator.getInvestments(); + + const investmentsByMonth = portfolioCalculator.getInvestmentsByGroup({ + data: portfolioSnapshot.historicalData, + groupBy: 'month' + }); + + const investmentsByYear = portfolioCalculator.getInvestmentsByGroup({ + data: portfolioSnapshot.historicalData, + groupBy: 'year' + }); + + expect(portfolioSnapshot).toMatchObject({ + currentValueInBaseCurrency: new Big('0'), + errors: [], + hasErrors: false, + positions: [ + { + activitiesCount: 4, + averagePrice: new Big('0'), + currency: 'USD', + dataSource: 'YAHOO', + dateOfFirstActivity: '2025-12-11', + dividend: new Big('0'), + dividendInBaseCurrency: new Big('0'), + fee: new Big('4'), + feeInBaseCurrency: new Big('4'), + grossPerformance: new Big('43.95'), // (1890.00 - 1885.05) + (2080.10 - 2041.10) + grossPerformanceWithCurrencyEffect: new Big('43.95'), // (1890.00 - 1885.05) + (2080.10 - 2041.10) + investment: new Big('0'), + investmentWithCurrencyEffect: new Big('0'), + netPerformance: new Big('39.95'), // (1890.00 - 1885.05) + (2080.10 - 2041.10) - 4 + netPerformanceWithCurrencyEffectMap: { + max: new Big('39.95') // (1890.00 - 1885.05) + (2080.10 - 2041.10) - 4 + }, + marketPrice: 237.8000030517578, + marketPriceInBaseCurrency: 237.8000030517578, + quantity: new Big('0'), + symbol: 'JNUG', + tags: [], + valueInBaseCurrency: new Big('0') + } + ], + totalFeesWithCurrencyEffect: new Big('4'), + totalInterestWithCurrencyEffect: new Big('0'), + totalInvestment: new Big('0'), + totalInvestmentWithCurrencyEffect: new Big('0'), + totalLiabilitiesWithCurrencyEffect: new Big('0') + }); + + expect(investments).toEqual([ + { date: '2025-12-11', investment: new Big('1885.05') }, + { date: '2025-12-18', investment: new Big('2041.1') }, + { date: '2025-12-28', investment: new Big('0') } + ]); + + expect(investmentsByMonth).toEqual([ + { date: '2025-12-01', investment: 0 } + ]); + + expect(investmentsByYear).toEqual([ + { date: '2025-01-01', investment: 0 } + ]); + }); + }); +}); diff --git a/apps/api/src/app/portfolio/calculator/roai/portfolio-calculator.ts b/apps/api/src/app/portfolio/calculator/roai/portfolio-calculator.ts index fe912510a..be69048df 100644 --- a/apps/api/src/app/portfolio/calculator/roai/portfolio-calculator.ts +++ b/apps/api/src/app/portfolio/calculator/roai/portfolio-calculator.ts @@ -626,6 +626,13 @@ export class RoaiPortfolioCalculator extends PortfolioCalculator { totalQuantityFromBuyTransactions ); + if (totalUnits.eq(0)) { + // Reset tracking variables when position is fully closed + totalInvestmentFromBuyTransactions = new Big(0); + totalInvestmentFromBuyTransactionsWithCurrencyEffect = new Big(0); + totalQuantityFromBuyTransactions = new Big(0); + } + if (PortfolioCalculator.ENABLE_LOGGING) { console.log( 'grossPerformanceFromSells', diff --git a/apps/api/src/app/portfolio/current-rate.service.mock.ts b/apps/api/src/app/portfolio/current-rate.service.mock.ts index 4b4b8f00e..8e027f971 100644 --- a/apps/api/src/app/portfolio/current-rate.service.mock.ts +++ b/apps/api/src/app/portfolio/current-rate.service.mock.ts @@ -64,6 +64,17 @@ function mockGetValue(symbol: string, date: Date) { return { marketPrice: 0 }; + case 'JNUG': + if (isSameDay(parseDate('2025-12-10'), date)) { + return { marketPrice: 204.5599975585938 }; + } else if (isSameDay(parseDate('2025-12-17'), date)) { + return { marketPrice: 203.9700012207031 }; + } else if (isSameDay(parseDate('2025-12-28'), date)) { + return { marketPrice: 237.8000030517578 }; + } + + return { marketPrice: 0 }; + case 'MSFT': if (isSameDay(parseDate('2021-09-16'), date)) { return { marketPrice: 89.12 }; diff --git a/test/import/ok/jnug-buy-and-sell-and-buy-and-sell.json b/test/import/ok/jnug-buy-and-sell-and-buy-and-sell.json new file mode 100644 index 000000000..2a14d8afe --- /dev/null +++ b/test/import/ok/jnug-buy-and-sell-and-buy-and-sell.json @@ -0,0 +1,58 @@ +{ + "meta": { + "date": "2026-02-07T02:09:15.272Z", + "version": "dev" + }, + "activities": [ + { + "currency": "USD", + "dataSource": "YAHOO", + "date": "2025-12-11T05:00:00.000Z", + "fee": 1, + "id": "cea33621-9f4b-4cea-9eb7-be38264888aa", + "quantity": 9, + "symbol": "JNUG", + "type": "BUY", + "unitPrice": 209.45 + }, + { + "currency": "USD", + "dataSource": "YAHOO", + "date": "2025-12-18T05:00:00.000Z", + "fee": 1, + "id": "53be2e35-a0af-476c-9e63-9b1a437114a4", + "quantity": 9, + "symbol": "JNUG", + "type": "SELL", + "unitPrice": 210 + }, + { + "currency": "USD", + "dataSource": "YAHOO", + "date": "2025-12-18T05:00:00.000Z", + "fee": 1, + "id": "6648eeeb-8ea5-46b6-9a30-f278a9ed477b", + "quantity": 10, + "symbol": "JNUG", + "type": "BUY", + "unitPrice": 204.11 + }, + { + "currency": "USD", + "dataSource": "YAHOO", + "date": "2025-12-28T05:00:00.000Z", + "fee": 1, + "id": "861e736d-0086-496c-8f85-31328479cf63", + "quantity": 10, + "symbol": "JNUG", + "type": "SELL", + "unitPrice": 208.01 + } + ], + "user": { + "settings": { + "currency": "USD", + "performanceCalculationType": "ROAI" + } + } +} From eb368765d4df711339f629471cf868df8ace1538 Mon Sep 17 00:00:00 2001 From: Thomas Kaul <4159106+dtslvr@users.noreply.github.com> Date: Thu, 12 Feb 2026 19:26:10 +0100 Subject: [PATCH 005/224] Release 2.238.0 (#6312) --- CHANGELOG.md | 2 +- package-lock.json | 4 ++-- package.json | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 29cec0e76..90430f5c4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,7 +5,7 @@ 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 +## 2.238.0 - 2026-02-12 ### Changed diff --git a/package-lock.json b/package-lock.json index 4c70d88f6..1731f1e7a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "ghostfolio", - "version": "2.237.0", + "version": "2.238.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "ghostfolio", - "version": "2.237.0", + "version": "2.238.0", "hasInstallScript": true, "license": "AGPL-3.0", "dependencies": { diff --git a/package.json b/package.json index 93ff182b7..4bfad50ff 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "ghostfolio", - "version": "2.237.0", + "version": "2.238.0", "homepage": "https://ghostfol.io", "license": "AGPL-3.0", "repository": "https://github.com/ghostfolio/ghostfolio", From 0c970e2a14f8a0a2d544adb8ae2d39f7003d228a Mon Sep 17 00:00:00 2001 From: Kenrick Tandrian <60643640+KenTandrian@users.noreply.github.com> Date: Fri, 13 Feb 2026 23:30:53 +0700 Subject: [PATCH 006/224] Task/improve holdings table type safety (#6306) * fix(lib): update displayedColumns type * feat(lib): use input function for holdings * feat(lib): make isLoading a computed signal * feat(lib): make paginator and sort viewchild signals * feat(lib): make dataSource a computed signal * feat(lib): use input function for hasPermission fields * feat(lib): make displayedColumns a computed signal * feat(lib): remove ngOnChanges * feat(lib): update types in holdings mock * fix(lib): update imports for treemap chart component * fix(lib): remove unused routeQueryParams variable * fix(lib): prevent creating new table data source every time the signal changes * fix(lib): remove unused unsubscribe subject as there is no observable subscription * fix(lib): revert changes to dataSource in the template * fix(lib): changed locale to input signal * fix(lib): change ignoreAssetSubClasses to protected * fix(lib): create canShowDetails function * fix(lib): remove unused baseCurrency and deviceType inputs * fix(lib): remove unused baseCurrency and deviceType inputs from stories * feat(lib): make constructor as public --- .../account-detail-dialog.html | 2 - .../home-holdings/home-holdings.html | 2 - .../src/app/pages/public/public-page.html | 1 - .../holdings-table.component.html | 38 +++---- .../holdings-table.component.stories.ts | 4 - .../holdings-table.component.ts | 103 +++++++++--------- libs/ui/src/lib/mocks/holdings.ts | 44 ++++---- .../treemap-chart/treemap-chart.component.ts | 2 +- 8 files changed, 94 insertions(+), 102 deletions(-) diff --git a/apps/client/src/app/components/account-detail-dialog/account-detail-dialog.html b/apps/client/src/app/components/account-detail-dialog/account-detail-dialog.html index 15dd8f13a..e41d3415c 100644 --- a/apps/client/src/app/components/account-detail-dialog/account-detail-dialog.html +++ b/apps/client/src/app/components/account-detail-dialog/account-detail-dialog.html @@ -102,8 +102,6 @@
Holdings
@@ -76,8 +76,8 @@
@@ -100,8 +100,8 @@
@@ -121,8 +121,8 @@
@@ -142,9 +142,9 @@ @@ -166,9 +166,9 @@ - + -@if (isLoading) { +@if (isLoading()) { } -@if (dataSource.data.length > pageSize && !isLoading) { +@if (dataSource.data.length > pageSize && !isLoading()) {
diff --git a/libs/common/src/lib/interfaces/portfolio-performance.interface.ts b/libs/common/src/lib/interfaces/portfolio-performance.interface.ts index c0c3802d8..0698004d5 100644 --- a/libs/common/src/lib/interfaces/portfolio-performance.interface.ts +++ b/libs/common/src/lib/interfaces/portfolio-performance.interface.ts @@ -7,4 +7,5 @@ export interface PortfolioPerformance { netPerformancePercentageWithCurrencyEffect: number; netPerformanceWithCurrencyEffect: number; totalInvestment: number; + totalInvestmentValueWithCurrencyEffect: number; } diff --git a/libs/common/src/lib/interfaces/portfolio-summary.interface.ts b/libs/common/src/lib/interfaces/portfolio-summary.interface.ts index ccf94dcf7..79fbf8707 100644 --- a/libs/common/src/lib/interfaces/portfolio-summary.interface.ts +++ b/libs/common/src/lib/interfaces/portfolio-summary.interface.ts @@ -6,7 +6,10 @@ export interface PortfolioSummary extends PortfolioPerformance { annualizedPerformancePercent: number; annualizedPerformancePercentWithCurrencyEffect: number; cash: number; + + /** @deprecated use totalInvestmentValueWithCurrencyEffect instead */ committedFunds: number; + dateOfFirstActivity: Date; dividendInBaseCurrency: number; emergencyFund: { From e59421f008d9a74e5b36764d6f9d9fc357c1bc9c Mon Sep 17 00:00:00 2001 From: Thomas Kaul <4159106+dtslvr@users.noreply.github.com> Date: Sun, 15 Feb 2026 10:22:36 +0100 Subject: [PATCH 013/224] Feature/add static portfolio analysis fee ratio rule based on total investment volume (#6332) * Add fee ratio rule based on total investment volume * Update changelog --- CHANGELOG.md | 2 + .../src/app/portfolio/portfolio.service.ts | 8 ++ apps/api/src/app/user/user.service.ts | 8 ++ .../fees/fee-ratio-initial-investment.ts | 3 + .../fees/fee-ratio-total-investment-volume.ts | 102 ++++++++++++++++++ apps/client/src/app/pages/i18n/i18n-page.html | 11 +- .../x-ray-rules-settings.interface.ts | 1 + 7 files changed, 134 insertions(+), 1 deletion(-) create mode 100644 apps/api/src/models/rules/fees/fee-ratio-total-investment-volume.ts diff --git a/CHANGELOG.md b/CHANGELOG.md index 9f15ad40a..a282de2b3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,10 +9,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Added +- Added a new static portfolio analysis rule based on the total investment volume: _Fees_ (Fee Ratio) - Extended the content of the _Self-Hosting_ section on the Frequently Asked Questions (FAQ) page with information on derived currencies ### Changed +- Deprecated the existing static portfolio analysis rule: _Fees_ (Fee Ratio) - Ignored nested ETFs when fetching top holdings for ETF and mutual fund assets from _Yahoo Finance_ - Improved the scraper configuration with more detailed error messages - Upgraded `cheerio` from version `1.0.0` to `1.2.0` diff --git a/apps/api/src/app/portfolio/portfolio.service.ts b/apps/api/src/app/portfolio/portfolio.service.ts index a7cee0bc0..b96f5ef70 100644 --- a/apps/api/src/app/portfolio/portfolio.service.ts +++ b/apps/api/src/app/portfolio/portfolio.service.ts @@ -14,6 +14,7 @@ import { EconomicMarketClusterRiskDevelopedMarkets } from '@ghostfolio/api/model import { EconomicMarketClusterRiskEmergingMarkets } from '@ghostfolio/api/models/rules/economic-market-cluster-risk/emerging-markets'; import { EmergencyFundSetup } from '@ghostfolio/api/models/rules/emergency-fund/emergency-fund-setup'; import { FeeRatioInitialInvestment } from '@ghostfolio/api/models/rules/fees/fee-ratio-initial-investment'; +import { FeeRatioTotalInvestmentVolume } from '@ghostfolio/api/models/rules/fees/fee-ratio-total-investment-volume'; import { BuyingPower } from '@ghostfolio/api/models/rules/liquidity/buying-power'; import { RegionalMarketClusterRiskAsiaPacific } from '@ghostfolio/api/models/rules/regional-market-cluster-risk/asia-pacific'; import { RegionalMarketClusterRiskEmergingMarkets } from '@ghostfolio/api/models/rules/regional-market-cluster-risk/emerging-markets'; @@ -1315,6 +1316,13 @@ export class PortfolioService { userSettings.language, summary.committedFunds, summary.fees + ), + new FeeRatioTotalInvestmentVolume( + this.exchangeRateDataService, + this.i18nService, + userSettings.language, + summary.totalBuy + summary.totalSell, + summary.fees ) ], userSettings diff --git a/apps/api/src/app/user/user.service.ts b/apps/api/src/app/user/user.service.ts index def0b94d9..08328851d 100644 --- a/apps/api/src/app/user/user.service.ts +++ b/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 { EmergencyFundSetup } from '@ghostfolio/api/models/rules/emergency-fund/emergency-fund-setup'; import { FeeRatioInitialInvestment } from '@ghostfolio/api/models/rules/fees/fee-ratio-initial-investment'; +import { FeeRatioTotalInvestmentVolume } from '@ghostfolio/api/models/rules/fees/fee-ratio-total-investment-volume'; import { BuyingPower } from '@ghostfolio/api/models/rules/liquidity/buying-power'; import { RegionalMarketClusterRiskAsiaPacific } from '@ghostfolio/api/models/rules/regional-market-cluster-risk/asia-pacific'; import { RegionalMarketClusterRiskEmergingMarkets } from '@ghostfolio/api/models/rules/regional-market-cluster-risk/emerging-markets'; @@ -383,6 +384,13 @@ export class UserService { undefined, undefined ).getSettings(user.settings.settings), + FeeRatioTotalInvestmentVolume: new FeeRatioTotalInvestmentVolume( + undefined, + undefined, + undefined, + undefined, + undefined + ).getSettings(user.settings.settings), RegionalMarketClusterRiskAsiaPacific: new RegionalMarketClusterRiskAsiaPacific( undefined, diff --git a/apps/api/src/models/rules/fees/fee-ratio-initial-investment.ts b/apps/api/src/models/rules/fees/fee-ratio-initial-investment.ts index cb85a73ba..54c2decc9 100644 --- a/apps/api/src/models/rules/fees/fee-ratio-initial-investment.ts +++ b/apps/api/src/models/rules/fees/fee-ratio-initial-investment.ts @@ -3,6 +3,9 @@ import { ExchangeRateDataService } from '@ghostfolio/api/services/exchange-rate- import { I18nService } from '@ghostfolio/api/services/i18n/i18n.service'; import { RuleSettings, UserSettings } from '@ghostfolio/common/interfaces'; +/** + * @deprecated This rule is deprecated in favor of FeeRatioTotalInvestmentVolume + */ export class FeeRatioInitialInvestment extends Rule { private fees: number; private totalInvestment: number; diff --git a/apps/api/src/models/rules/fees/fee-ratio-total-investment-volume.ts b/apps/api/src/models/rules/fees/fee-ratio-total-investment-volume.ts new file mode 100644 index 000000000..07bf5fa2c --- /dev/null +++ b/apps/api/src/models/rules/fees/fee-ratio-total-investment-volume.ts @@ -0,0 +1,102 @@ +import { Rule } from '@ghostfolio/api/models/rule'; +import { ExchangeRateDataService } from '@ghostfolio/api/services/exchange-rate-data/exchange-rate-data.service'; +import { I18nService } from '@ghostfolio/api/services/i18n/i18n.service'; +import { RuleSettings, UserSettings } from '@ghostfolio/common/interfaces'; + +export class FeeRatioTotalInvestmentVolume extends Rule { + private fees: number; + private totalInvestmentVolumeInBaseCurrency: number; + + public constructor( + protected exchangeRateDataService: ExchangeRateDataService, + private i18nService: I18nService, + languageCode: string, + totalInvestmentVolumeInBaseCurrency: number, + fees: number + ) { + super(exchangeRateDataService, { + languageCode, + key: FeeRatioTotalInvestmentVolume.name + }); + + this.fees = fees; + this.totalInvestmentVolumeInBaseCurrency = + totalInvestmentVolumeInBaseCurrency; + } + + public evaluate(ruleSettings: Settings) { + const feeRatio = this.totalInvestmentVolumeInBaseCurrency + ? this.fees / this.totalInvestmentVolumeInBaseCurrency + : 0; + + if (feeRatio > ruleSettings.thresholdMax) { + return { + evaluation: this.i18nService.getTranslation({ + id: 'rule.feeRatioTotalInvestmentVolume.false', + languageCode: this.getLanguageCode(), + placeholders: { + feeRatio: (ruleSettings.thresholdMax * 100).toFixed(2), + thresholdMax: (feeRatio * 100).toPrecision(3) + } + }), + value: false + }; + } + + return { + evaluation: this.i18nService.getTranslation({ + id: 'rule.feeRatioTotalInvestmentVolume.true', + languageCode: this.getLanguageCode(), + placeholders: { + feeRatio: (feeRatio * 100).toPrecision(3), + thresholdMax: (ruleSettings.thresholdMax * 100).toFixed(2) + } + }), + value: true + }; + } + + public getCategoryName() { + return this.i18nService.getTranslation({ + id: 'rule.fees.category', + languageCode: this.getLanguageCode() + }); + } + + public getConfiguration() { + return { + threshold: { + max: 0.1, + min: 0, + step: 0.0025, + unit: '%' + }, + thresholdMax: true + }; + } + + public getName() { + return this.i18nService.getTranslation({ + id: 'rule.feeRatioTotalInvestmentVolume', + languageCode: this.getLanguageCode() + }); + } + + public getSettings({ + baseCurrency, + locale, + xRayRules + }: UserSettings): Settings { + return { + baseCurrency, + locale, + isActive: xRayRules?.[this.getKey()]?.isActive ?? true, + thresholdMax: xRayRules?.[this.getKey()]?.thresholdMax ?? 0.01 + }; + } +} + +interface Settings extends RuleSettings { + baseCurrency: string; + thresholdMax: number; +} diff --git a/apps/client/src/app/pages/i18n/i18n-page.html b/apps/client/src/app/pages/i18n/i18n-page.html index b4297d5ac..8ccd27b64 100644 --- a/apps/client/src/app/pages/i18n/i18n-page.html +++ b/apps/client/src/app/pages/i18n/i18n-page.html @@ -149,7 +149,7 @@
  • An emergency fund has been set up
  • -
  • Fee Ratio
  • +
  • Fee Ratio (lecacy)
  • The fees do exceed ${thresholdMax}% of your initial investment (${feeRatio}%) @@ -158,6 +158,15 @@ The fees do not exceed ${thresholdMax}% of your initial investment (${feeRatio}%)
  • +
  • Fee Ratio
  • +
  • + The fees do exceed ${thresholdMax}% of your total investment + volume (${feeRatio}%) +
  • +
  • + The fees do not exceed ${thresholdMax}% of your total + investment volume (${feeRatio}%) +
  • Fees
  • Regional Market Cluster Risks diff --git a/libs/common/src/lib/interfaces/x-ray-rules-settings.interface.ts b/libs/common/src/lib/interfaces/x-ray-rules-settings.interface.ts index bdef3e169..688d4f2a0 100644 --- a/libs/common/src/lib/interfaces/x-ray-rules-settings.interface.ts +++ b/libs/common/src/lib/interfaces/x-ray-rules-settings.interface.ts @@ -10,6 +10,7 @@ export interface XRayRulesSettings { EconomicMarketClusterRiskEmergingMarkets?: RuleSettings; EmergencyFundSetup?: RuleSettings; FeeRatioInitialInvestment?: RuleSettings; + FeeRatioTotalInvestmentVolume?: RuleSettings; RegionalMarketClusterRiskAsiaPacific?: RuleSettings; RegionalMarketClusterRiskEmergingMarkets?: RuleSettings; RegionalMarketClusterRiskEurope?: RuleSettings; From 2ab3d7daa1ce7d9bd81b7b403c3ec010814e14a6 Mon Sep 17 00:00:00 2001 From: Thomas Kaul <4159106+dtslvr@users.noreply.github.com> Date: Sun, 15 Feb 2026 10:23:30 +0100 Subject: [PATCH 014/224] Task/upgrade simplewebauthn to version 13.2.2 (#6326) * Upgrade simplewebauthn to version 13.2.2 * Update changelog --- CHANGELOG.md | 1 + package-lock.json | 172 +++++++++++++++++++++++++++++++++++++++------- package.json | 4 +- 3 files changed, 149 insertions(+), 28 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a282de2b3..3f53d48c4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -17,6 +17,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Deprecated the existing static portfolio analysis rule: _Fees_ (Fee Ratio) - Ignored nested ETFs when fetching top holdings for ETF and mutual fund assets from _Yahoo Finance_ - Improved the scraper configuration with more detailed error messages +- Upgraded `@simplewebauthn/browser` and `@simplewebauthn/server` from version `13.1.0` to `13.2.2` - Upgraded `cheerio` from version `1.0.0` to `1.2.0` ### Fixed diff --git a/package-lock.json b/package-lock.json index 046ebf083..1dfdcb7fc 100644 --- a/package-lock.json +++ b/package-lock.json @@ -39,8 +39,8 @@ "@nestjs/serve-static": "5.0.4", "@openrouter/ai-sdk-provider": "0.7.2", "@prisma/client": "6.19.0", - "@simplewebauthn/browser": "13.1.0", - "@simplewebauthn/server": "13.1.1", + "@simplewebauthn/browser": "13.2.2", + "@simplewebauthn/server": "13.2.2", "ai": "4.3.16", "alphavantage": "2.2.0", "big.js": "7.0.1", @@ -10220,34 +10220,101 @@ "tslib": "^2.8.1" } }, + "node_modules/@peculiar/asn1-cms": { + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/@peculiar/asn1-cms/-/asn1-cms-2.6.1.tgz", + "integrity": "sha512-vdG4fBF6Lkirkcl53q6eOdn3XYKt+kJTG59edgRZORlg/3atWWEReRCx5rYE1ZzTTX6vLK5zDMjHh7vbrcXGtw==", + "license": "MIT", + "dependencies": { + "@peculiar/asn1-schema": "^2.6.0", + "@peculiar/asn1-x509": "^2.6.1", + "@peculiar/asn1-x509-attr": "^2.6.1", + "asn1js": "^3.0.6", + "tslib": "^2.8.1" + } + }, + "node_modules/@peculiar/asn1-csr": { + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/@peculiar/asn1-csr/-/asn1-csr-2.6.1.tgz", + "integrity": "sha512-WRWnKfIocHyzFYQTka8O/tXCiBquAPSrRjXbOkHbO4qdmS6loffCEGs+rby6WxxGdJCuunnhS2duHURhjyio6w==", + "license": "MIT", + "dependencies": { + "@peculiar/asn1-schema": "^2.6.0", + "@peculiar/asn1-x509": "^2.6.1", + "asn1js": "^3.0.6", + "tslib": "^2.8.1" + } + }, "node_modules/@peculiar/asn1-ecc": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/@peculiar/asn1-ecc/-/asn1-ecc-2.4.0.tgz", - "integrity": "sha512-fJiYUBCJBDkjh347zZe5H81BdJ0+OGIg0X9z06v8xXUoql3MFeENUX0JsjCaVaU9A0L85PefLPGYkIoGpTnXLQ==", + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/@peculiar/asn1-ecc/-/asn1-ecc-2.6.1.tgz", + "integrity": "sha512-+Vqw8WFxrtDIN5ehUdvlN2m73exS2JVG0UAyfVB31gIfor3zWEAQPD+K9ydCxaj3MLen9k0JhKpu9LqviuCE1g==", "license": "MIT", "dependencies": { - "@peculiar/asn1-schema": "^2.4.0", - "@peculiar/asn1-x509": "^2.4.0", + "@peculiar/asn1-schema": "^2.6.0", + "@peculiar/asn1-x509": "^2.6.1", + "asn1js": "^3.0.6", + "tslib": "^2.8.1" + } + }, + "node_modules/@peculiar/asn1-pfx": { + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/@peculiar/asn1-pfx/-/asn1-pfx-2.6.1.tgz", + "integrity": "sha512-nB5jVQy3MAAWvq0KY0R2JUZG8bO/bTLpnwyOzXyEh/e54ynGTatAR+csOnXkkVD9AFZ2uL8Z7EV918+qB1qDvw==", + "license": "MIT", + "dependencies": { + "@peculiar/asn1-cms": "^2.6.1", + "@peculiar/asn1-pkcs8": "^2.6.1", + "@peculiar/asn1-rsa": "^2.6.1", + "@peculiar/asn1-schema": "^2.6.0", + "asn1js": "^3.0.6", + "tslib": "^2.8.1" + } + }, + "node_modules/@peculiar/asn1-pkcs8": { + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/@peculiar/asn1-pkcs8/-/asn1-pkcs8-2.6.1.tgz", + "integrity": "sha512-JB5iQ9Izn5yGMw3ZG4Nw3Xn/hb/G38GYF3lf7WmJb8JZUydhVGEjK/ZlFSWhnlB7K/4oqEs8HnfFIKklhR58Tw==", + "license": "MIT", + "dependencies": { + "@peculiar/asn1-schema": "^2.6.0", + "@peculiar/asn1-x509": "^2.6.1", + "asn1js": "^3.0.6", + "tslib": "^2.8.1" + } + }, + "node_modules/@peculiar/asn1-pkcs9": { + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/@peculiar/asn1-pkcs9/-/asn1-pkcs9-2.6.1.tgz", + "integrity": "sha512-5EV8nZoMSxeWmcxWmmcolg22ojZRgJg+Y9MX2fnE2bGRo5KQLqV5IL9kdSQDZxlHz95tHvIq9F//bvL1OeNILw==", + "license": "MIT", + "dependencies": { + "@peculiar/asn1-cms": "^2.6.1", + "@peculiar/asn1-pfx": "^2.6.1", + "@peculiar/asn1-pkcs8": "^2.6.1", + "@peculiar/asn1-schema": "^2.6.0", + "@peculiar/asn1-x509": "^2.6.1", + "@peculiar/asn1-x509-attr": "^2.6.1", "asn1js": "^3.0.6", "tslib": "^2.8.1" } }, "node_modules/@peculiar/asn1-rsa": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/@peculiar/asn1-rsa/-/asn1-rsa-2.4.0.tgz", - "integrity": "sha512-6PP75voaEnOSlWR9sD25iCQyLgFZHXbmxvUfnnDcfL6Zh5h2iHW38+bve4LfH7a60x7fkhZZNmiYqAlAff9Img==", + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/@peculiar/asn1-rsa/-/asn1-rsa-2.6.1.tgz", + "integrity": "sha512-1nVMEh46SElUt5CB3RUTV4EG/z7iYc7EoaDY5ECwganibQPkZ/Y2eMsTKB/LeyrUJ+W/tKoD9WUqIy8vB+CEdA==", "license": "MIT", "dependencies": { - "@peculiar/asn1-schema": "^2.4.0", - "@peculiar/asn1-x509": "^2.4.0", + "@peculiar/asn1-schema": "^2.6.0", + "@peculiar/asn1-x509": "^2.6.1", "asn1js": "^3.0.6", "tslib": "^2.8.1" } }, "node_modules/@peculiar/asn1-schema": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/@peculiar/asn1-schema/-/asn1-schema-2.4.0.tgz", - "integrity": "sha512-umbembjIWOrPSOzEGG5vxFLkeM8kzIhLkgigtsOrfLKnuzxWxejAcUX+q/SoZCdemlODOcr5WiYa7+dIEzBXZQ==", + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/@peculiar/asn1-schema/-/asn1-schema-2.6.0.tgz", + "integrity": "sha512-xNLYLBFTBKkCzEZIw842BxytQQATQv+lDTCEMZ8C196iJcJJMBUZxrhSTxLaohMyKK8QlzRNTRkUmanucnDSqg==", "license": "MIT", "dependencies": { "asn1js": "^3.0.6", @@ -10256,17 +10323,51 @@ } }, "node_modules/@peculiar/asn1-x509": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/@peculiar/asn1-x509/-/asn1-x509-2.4.0.tgz", - "integrity": "sha512-F7mIZY2Eao2TaoVqigGMLv+NDdpwuBKU1fucHPONfzaBS4JXXCNCmfO0Z3dsy7JzKGqtDcYC1mr9JjaZQZNiuw==", + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/@peculiar/asn1-x509/-/asn1-x509-2.6.1.tgz", + "integrity": "sha512-O9jT5F1A2+t3r7C4VT7LYGXqkGLK7Kj1xFpz7U0isPrubwU5PbDoyYtx6MiGst29yq7pXN5vZbQFKRCP+lLZlA==", "license": "MIT", "dependencies": { - "@peculiar/asn1-schema": "^2.4.0", + "@peculiar/asn1-schema": "^2.6.0", "asn1js": "^3.0.6", "pvtsutils": "^1.3.6", "tslib": "^2.8.1" } }, + "node_modules/@peculiar/asn1-x509-attr": { + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/@peculiar/asn1-x509-attr/-/asn1-x509-attr-2.6.1.tgz", + "integrity": "sha512-tlW6cxoHwgcQghnJwv3YS+9OO1737zgPogZ+CgWRUK4roEwIPzRH4JEiG770xe5HX2ATfCpmX60gurfWIF9dcQ==", + "license": "MIT", + "dependencies": { + "@peculiar/asn1-schema": "^2.6.0", + "@peculiar/asn1-x509": "^2.6.1", + "asn1js": "^3.0.6", + "tslib": "^2.8.1" + } + }, + "node_modules/@peculiar/x509": { + "version": "1.14.3", + "resolved": "https://registry.npmjs.org/@peculiar/x509/-/x509-1.14.3.tgz", + "integrity": "sha512-C2Xj8FZ0uHWeCXXqX5B4/gVFQmtSkiuOolzAgutjTfseNOHT3pUjljDZsTSxXFGgio54bCzVFqmEOUrIVk8RDA==", + "license": "MIT", + "dependencies": { + "@peculiar/asn1-cms": "^2.6.0", + "@peculiar/asn1-csr": "^2.6.0", + "@peculiar/asn1-ecc": "^2.6.0", + "@peculiar/asn1-pkcs9": "^2.6.0", + "@peculiar/asn1-rsa": "^2.6.0", + "@peculiar/asn1-schema": "^2.6.0", + "@peculiar/asn1-x509": "^2.6.0", + "pvtsutils": "^1.3.6", + "reflect-metadata": "^0.2.2", + "tslib": "^2.8.1", + "tsyringe": "^4.10.0" + }, + "engines": { + "node": ">=20.0.0" + } + }, "node_modules/@phenomnomnominal/tsquery": { "version": "6.1.4", "resolved": "https://registry.npmjs.org/@phenomnomnominal/tsquery/-/tsquery-6.1.4.tgz", @@ -11696,15 +11797,15 @@ } }, "node_modules/@simplewebauthn/browser": { - "version": "13.1.0", - "resolved": "https://registry.npmjs.org/@simplewebauthn/browser/-/browser-13.1.0.tgz", - "integrity": "sha512-WuHZ/PYvyPJ9nxSzgHtOEjogBhwJfC8xzYkPC+rR/+8chl/ft4ngjiK8kSU5HtRJfczupyOh33b25TjYbvwAcg==", + "version": "13.2.2", + "resolved": "https://registry.npmjs.org/@simplewebauthn/browser/-/browser-13.2.2.tgz", + "integrity": "sha512-FNW1oLQpTJyqG5kkDg5ZsotvWgmBaC6jCHR7Ej0qUNep36Wl9tj2eZu7J5rP+uhXgHaLk+QQ3lqcw2vS5MX1IA==", "license": "MIT" }, "node_modules/@simplewebauthn/server": { - "version": "13.1.1", - "resolved": "https://registry.npmjs.org/@simplewebauthn/server/-/server-13.1.1.tgz", - "integrity": "sha512-1hsLpRHfSuMB9ee2aAdh0Htza/X3f4djhYISrggqGe3xopNjOcePiSDkDDoPzDYaaMCrbqGP1H2TYU7bgL9PmA==", + "version": "13.2.2", + "resolved": "https://registry.npmjs.org/@simplewebauthn/server/-/server-13.2.2.tgz", + "integrity": "sha512-HcWLW28yTMGXpwE9VLx9J+N2KEUaELadLrkPEEI9tpI5la70xNEVEsu/C+m3u7uoq4FulLqZQhgBCzR9IZhFpA==", "license": "MIT", "dependencies": { "@hexagon/base64": "^1.1.27", @@ -11713,7 +11814,8 @@ "@peculiar/asn1-ecc": "^2.3.8", "@peculiar/asn1-rsa": "^2.3.8", "@peculiar/asn1-schema": "^2.3.8", - "@peculiar/asn1-x509": "^2.3.8" + "@peculiar/asn1-x509": "^2.3.8", + "@peculiar/x509": "^1.13.0" }, "engines": { "node": ">=20.0.0" @@ -33348,6 +33450,24 @@ "node": ">=0.6.x" } }, + "node_modules/tsyringe": { + "version": "4.10.0", + "resolved": "https://registry.npmjs.org/tsyringe/-/tsyringe-4.10.0.tgz", + "integrity": "sha512-axr3IdNuVIxnaK5XGEUFTu3YmAQ6lllgrvqfEoR16g/HGnYY/6We4oWENtAnzK6/LpJ2ur9PAb80RBt7/U4ugw==", + "license": "MIT", + "dependencies": { + "tslib": "^1.9.3" + }, + "engines": { + "node": ">= 6.0.0" + } + }, + "node_modules/tsyringe/node_modules/tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", + "license": "0BSD" + }, "node_modules/tuf-js": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/tuf-js/-/tuf-js-4.1.0.tgz", diff --git a/package.json b/package.json index c70b2c14b..65f98cdff 100644 --- a/package.json +++ b/package.json @@ -83,8 +83,8 @@ "@nestjs/serve-static": "5.0.4", "@openrouter/ai-sdk-provider": "0.7.2", "@prisma/client": "6.19.0", - "@simplewebauthn/browser": "13.1.0", - "@simplewebauthn/server": "13.1.1", + "@simplewebauthn/browser": "13.2.2", + "@simplewebauthn/server": "13.2.2", "ai": "4.3.16", "alphavantage": "2.2.0", "big.js": "7.0.1", From 09968bda7d990a29009a351dcccabd4cbd6e9d22 Mon Sep 17 00:00:00 2001 From: Thomas Kaul <4159106+dtslvr@users.noreply.github.com> Date: Sun, 15 Feb 2026 10:35:16 +0100 Subject: [PATCH 015/224] Bugfix/fix localization in X-ray rule (#6333) * Fix localization --- apps/client/src/app/pages/i18n/i18n-page.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/client/src/app/pages/i18n/i18n-page.html b/apps/client/src/app/pages/i18n/i18n-page.html index 8ccd27b64..a8797c07a 100644 --- a/apps/client/src/app/pages/i18n/i18n-page.html +++ b/apps/client/src/app/pages/i18n/i18n-page.html @@ -149,7 +149,7 @@
  • An emergency fund has been set up
  • -
  • Fee Ratio (lecacy)
  • +
  • Fee Ratio (legacy)
  • The fees do exceed ${thresholdMax}% of your initial investment (${feeRatio}%) From c056045ed03ca7090b5c63e87c24726ec6d62a5e Mon Sep 17 00:00:00 2001 From: Thomas Kaul <4159106+dtslvr@users.noreply.github.com> Date: Sun, 15 Feb 2026 10:45:47 +0100 Subject: [PATCH 016/224] Task/update locales (#6334) * Update locales * Update translations * Update changelog --------- Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> Co-authored-by: github-actions[bot] --- CHANGELOG.md | 1 + apps/client/src/locales/messages.ca.xlf | 198 +++++++++++++---------- apps/client/src/locales/messages.de.xlf | 200 ++++++++++++++---------- apps/client/src/locales/messages.es.xlf | 198 +++++++++++++---------- apps/client/src/locales/messages.fr.xlf | 198 +++++++++++++---------- apps/client/src/locales/messages.it.xlf | 198 +++++++++++++---------- apps/client/src/locales/messages.ko.xlf | 198 +++++++++++++---------- apps/client/src/locales/messages.nl.xlf | 198 +++++++++++++---------- apps/client/src/locales/messages.pl.xlf | 198 +++++++++++++---------- apps/client/src/locales/messages.pt.xlf | 198 +++++++++++++---------- apps/client/src/locales/messages.tr.xlf | 198 +++++++++++++---------- apps/client/src/locales/messages.uk.xlf | 198 +++++++++++++---------- apps/client/src/locales/messages.xlf | 193 +++++++++++++---------- apps/client/src/locales/messages.zh.xlf | 198 +++++++++++++---------- 14 files changed, 1493 insertions(+), 1079 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3f53d48c4..ee27bef6c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -17,6 +17,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Deprecated the existing static portfolio analysis rule: _Fees_ (Fee Ratio) - Ignored nested ETFs when fetching top holdings for ETF and mutual fund assets from _Yahoo Finance_ - Improved the scraper configuration with more detailed error messages +- Improved the language localization for German (`de`) - Upgraded `@simplewebauthn/browser` and `@simplewebauthn/server` from version `13.1.0` to `13.2.2` - Upgraded `cheerio` from version `1.0.0` to `1.2.0` diff --git a/apps/client/src/locales/messages.ca.xlf b/apps/client/src/locales/messages.ca.xlf index a6bec7df3..6400807bd 100644 --- a/apps/client/src/locales/messages.ca.xlf +++ b/apps/client/src/locales/messages.ca.xlf @@ -403,7 +403,7 @@ Balanç de Caixa apps/client/src/app/components/account-detail-dialog/account-detail-dialog.html - 148 + 146 @@ -625,6 +625,10 @@ apps/client/src/app/components/admin-tag/admin-tag.component.html 78 + + apps/client/src/app/components/user-detail-dialog/user-detail-dialog.html + 22 + libs/ui/src/lib/account-balances/account-balances.component.html 80 @@ -647,7 +651,7 @@ Realment vol suprimir aquest compte? libs/ui/src/lib/accounts-table/accounts-table.component.ts - 150 + 148 @@ -867,7 +871,7 @@ apps/client/src/app/pages/public/public-page.html - 96 + 95 @@ -1063,7 +1067,7 @@ apps/client/src/app/components/user-detail-dialog/user-detail-dialog.html - 53 + 72 @@ -1083,7 +1087,7 @@ apps/client/src/app/pages/public/public-page.html - 114 + 113 @@ -1483,7 +1487,7 @@ Està segur que vol eliminar aquest usuari? apps/client/src/app/components/admin-users/admin-users.component.ts - 215 + 218 @@ -1519,7 +1523,7 @@ apps/client/src/app/components/user-detail-dialog/user-detail-dialog.html - 89 + 108 @@ -1743,7 +1747,7 @@ apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 88 + 92 @@ -1767,7 +1771,7 @@ Informar d’un Problema amb les Dades apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html - 451 + 450 @@ -1807,7 +1811,7 @@ Gestionar Activitats apps/client/src/app/components/home-holdings/home-holdings.html - 67 + 65 @@ -1959,7 +1963,7 @@ Import total apps/client/src/app/components/investment-chart/investment-chart.component.ts - 143 + 146 @@ -2095,7 +2099,7 @@ Rendiment brut absolut apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 73 + 77 @@ -2103,7 +2107,7 @@ Rendiment net absolut apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 107 + 111 apps/client/src/app/pages/portfolio/analysis/analysis-page.html @@ -2115,7 +2119,7 @@ Rendiment net apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 123 + 127 apps/client/src/app/pages/portfolio/analysis/analysis-page.html @@ -2127,7 +2131,7 @@ Actius totals apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 149 + 153 @@ -2135,7 +2139,7 @@ Actius apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 226 + 230 @@ -2143,7 +2147,7 @@ Poder adquisitiu apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 241 + 245 @@ -2151,7 +2155,7 @@ Exclòs de l’anàlisi apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 267 + 271 @@ -2159,7 +2163,7 @@ Passius apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 295 + 299 apps/client/src/app/pages/features/features-page.html @@ -2171,7 +2175,7 @@ Valor net apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 317 + 321 @@ -2179,7 +2183,7 @@ Rendiment anualitzat apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 331 + 335 @@ -2451,7 +2455,7 @@ apps/client/src/app/components/user-detail-dialog/user-detail-dialog.html - 11 + 30 @@ -2939,7 +2943,7 @@ apps/client/src/app/components/user-detail-dialog/user-detail-dialog.html - 66 + 85 apps/client/src/app/pages/accounts/accounts-page.html @@ -3039,7 +3043,7 @@ Dades de mercat apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html - 398 + 397 libs/common/src/lib/routes/routes.ts @@ -3436,7 +3440,7 @@ apps/client/src/app/pages/public/public-page.html - 242 + 241 apps/client/src/app/pages/resources/personal-finance-tools/product-page.html @@ -3560,7 +3564,7 @@ Programari de gestió patrimonial de codi obert apps/client/src/app/pages/i18n/i18n-page.html - 237 + 246 @@ -3996,7 +4000,7 @@ apps/client/src/app/components/account-detail-dialog/account-detail-dialog.html - 115 + 113 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html @@ -4020,7 +4024,7 @@ apps/client/src/app/components/user-detail-dialog/user-detail-dialog.html - 75 + 94 apps/client/src/app/pages/portfolio/activities/activities-page.html @@ -4348,7 +4352,7 @@ apps/client/src/app/pages/public/public-page.html - 151 + 150 @@ -4372,7 +4376,7 @@ apps/client/src/app/pages/public/public-page.html - 168 + 167 @@ -4380,7 +4384,7 @@ Latest activities apps/client/src/app/pages/public/public-page.html - 211 + 210 @@ -4392,7 +4396,7 @@ apps/client/src/app/pages/public/public-page.html - 177 + 176 @@ -4404,7 +4408,7 @@ apps/client/src/app/pages/public/public-page.html - 186 + 185 @@ -4480,7 +4484,7 @@ apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 365 + 369 apps/client/src/app/pages/features/features-page.html @@ -4552,7 +4556,7 @@ Close Holding apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html - 442 + 441 @@ -4876,7 +4880,7 @@ Continents apps/client/src/app/pages/public/public-page.html - 132 + 131 @@ -4884,7 +4888,7 @@ Vols refinar la teva estratègia d’inversió personal? apps/client/src/app/pages/public/public-page.html - 234 + 233 @@ -4900,7 +4904,7 @@ Ghostfolio us permet fer un seguiment de la vostra riquesa. apps/client/src/app/pages/public/public-page.html - 238 + 237 @@ -5273,7 +5277,7 @@ Pertinença apps/client/src/app/components/user-detail-dialog/user-detail-dialog.html - 48 + 67 libs/common/src/lib/routes/routes.ts @@ -5405,7 +5409,7 @@ De veritat vols suprimir aquestes activitats? libs/ui/src/lib/activities-table/activities-table.component.ts - 278 + 282 @@ -5413,7 +5417,7 @@ Realment vols suprimir aquesta activitat? libs/ui/src/lib/activities-table/activities-table.component.ts - 288 + 292 @@ -5653,7 +5657,7 @@ apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 352 + 356 libs/ui/src/lib/fire-calculator/fire-calculator.component.ts @@ -5697,7 +5701,7 @@ Mostra-ho tot libs/ui/src/lib/holdings-table/holdings-table.component.html - 216 + 212 @@ -5833,7 +5837,7 @@ Fons d’emergència apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 164 + 168 apps/client/src/app/pages/features/features-page.html @@ -5909,7 +5913,7 @@ libs/ui/src/lib/portfolio-proportion-chart/portfolio-proportion-chart.component.ts - 437 + 449 @@ -6081,7 +6085,7 @@ Efectiu apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 212 + 216 libs/ui/src/lib/i18n.ts @@ -6137,7 +6141,7 @@ Authentication apps/client/src/app/components/user-detail-dialog/user-detail-dialog.html - 35 + 54 @@ -6305,7 +6309,7 @@ apps/client/src/app/pages/public/public-page.html - 196 + 195 libs/ui/src/lib/benchmark/benchmark.component.html @@ -6313,11 +6317,11 @@ libs/ui/src/lib/portfolio-proportion-chart/portfolio-proportion-chart.component.ts - 439 + 451 libs/ui/src/lib/portfolio-proportion-chart/portfolio-proportion-chart.component.ts - 452 + 465 libs/ui/src/lib/top-holdings/top-holdings.component.html @@ -6791,6 +6795,10 @@ apps/client/src/app/components/user-account-access/create-or-update-access-dialog/create-or-update-access-dialog.html 68 + + apps/client/src/app/components/user-detail-dialog/user-detail-dialog.html + 127 + apps/client/src/app/pages/accounts/create-or-update-account-dialog/create-or-update-account-dialog.html 107 @@ -6809,7 +6817,7 @@ Role apps/client/src/app/components/user-detail-dialog/user-detail-dialog.html - 14 + 33 @@ -7215,7 +7223,7 @@ apps/client/src/app/components/user-detail-dialog/user-detail-dialog.html - 98 + 117 @@ -7479,7 +7487,7 @@ libs/ui/src/lib/treemap-chart/treemap-chart.component.ts - 368 + 375 @@ -7499,11 +7507,11 @@ libs/ui/src/lib/treemap-chart/treemap-chart.component.ts - 368 + 375 libs/ui/src/lib/treemap-chart/treemap-chart.component.ts - 381 + 388 @@ -7607,7 +7615,7 @@ Security token apps/client/src/app/components/admin-users/admin-users.component.ts - 236 + 239 apps/client/src/app/components/user-account-access/user-account-access.component.ts @@ -7619,7 +7627,7 @@ Do you really want to generate a new security token for this user? apps/client/src/app/components/admin-users/admin-users.component.ts - 241 + 244 @@ -7873,8 +7881,8 @@ - Fee Ratio - Fee Ratio + Fee Ratio (legacy) + Fee Ratio (legacy) apps/client/src/app/pages/i18n/i18n-page.html 152 @@ -7896,6 +7904,30 @@ 158 + + Fee Ratio + Fee Ratio + + apps/client/src/app/pages/i18n/i18n-page.html + 161 + + + + The fees do exceed ${thresholdMax}% of your total investment volume (${feeRatio}%) + The fees do exceed ${thresholdMax}% of your total investment volume (${feeRatio}%) + + apps/client/src/app/pages/i18n/i18n-page.html + 163 + + + + The fees do not exceed ${thresholdMax}% of your total investment volume (${feeRatio}%) + The fees do not exceed ${thresholdMax}% of your total investment volume (${feeRatio}%) + + apps/client/src/app/pages/i18n/i18n-page.html + 167 + + Quick Links Quick Links @@ -8276,7 +8308,7 @@ Manage Asset Profile apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html - 466 + 465 @@ -8352,7 +8384,7 @@ Fees apps/client/src/app/pages/i18n/i18n-page.html - 161 + 170 @@ -8400,7 +8432,7 @@ Regional Market Cluster Risks apps/client/src/app/pages/i18n/i18n-page.html - 163 + 172 @@ -8496,7 +8528,7 @@ Asia-Pacific apps/client/src/app/pages/i18n/i18n-page.html - 165 + 174 @@ -8504,7 +8536,7 @@ The Asia-Pacific market contribution of your current investment (${valueRatio}%) exceeds ${thresholdMax}% apps/client/src/app/pages/i18n/i18n-page.html - 167 + 176 @@ -8512,7 +8544,7 @@ The Asia-Pacific market contribution of your current investment (${valueRatio}%) is below ${thresholdMin}% apps/client/src/app/pages/i18n/i18n-page.html - 171 + 180 @@ -8520,7 +8552,7 @@ The Asia-Pacific market contribution of your current investment (${valueRatio}%) is within the range of ${thresholdMin}% and ${thresholdMax}% apps/client/src/app/pages/i18n/i18n-page.html - 175 + 184 @@ -8528,7 +8560,7 @@ Emerging Markets apps/client/src/app/pages/i18n/i18n-page.html - 180 + 189 @@ -8536,7 +8568,7 @@ The Emerging Markets contribution of your current investment (${valueRatio}%) exceeds ${thresholdMax}% apps/client/src/app/pages/i18n/i18n-page.html - 183 + 192 @@ -8544,7 +8576,7 @@ The Emerging Markets contribution of your current investment (${valueRatio}%) is below ${thresholdMin}% apps/client/src/app/pages/i18n/i18n-page.html - 187 + 196 @@ -8552,7 +8584,7 @@ The Emerging Markets contribution of your current investment (${valueRatio}%) is within the range of ${thresholdMin}% and ${thresholdMax}% apps/client/src/app/pages/i18n/i18n-page.html - 191 + 200 @@ -8560,7 +8592,7 @@ Europe apps/client/src/app/pages/i18n/i18n-page.html - 195 + 204 @@ -8568,7 +8600,7 @@ The Europe market contribution of your current investment (${valueRatio}%) exceeds ${thresholdMax}% apps/client/src/app/pages/i18n/i18n-page.html - 197 + 206 @@ -8576,7 +8608,7 @@ The Europe market contribution of your current investment (${valueRatio}%) is below ${thresholdMin}% apps/client/src/app/pages/i18n/i18n-page.html - 201 + 210 @@ -8584,7 +8616,7 @@ The Europe market contribution of your current investment (${valueRatio}%) is within the range of ${thresholdMin}% and ${thresholdMax}% apps/client/src/app/pages/i18n/i18n-page.html - 205 + 214 @@ -8592,7 +8624,7 @@ Japan apps/client/src/app/pages/i18n/i18n-page.html - 209 + 218 @@ -8600,7 +8632,7 @@ The Japan market contribution of your current investment (${valueRatio}%) exceeds ${thresholdMax}% apps/client/src/app/pages/i18n/i18n-page.html - 211 + 220 @@ -8608,7 +8640,7 @@ The Japan market contribution of your current investment (${valueRatio}%) is below ${thresholdMin}% apps/client/src/app/pages/i18n/i18n-page.html - 215 + 224 @@ -8616,7 +8648,7 @@ The Japan market contribution of your current investment (${valueRatio}%) is within the range of ${thresholdMin}% and ${thresholdMax}% apps/client/src/app/pages/i18n/i18n-page.html - 219 + 228 @@ -8624,7 +8656,7 @@ North America apps/client/src/app/pages/i18n/i18n-page.html - 223 + 232 @@ -8632,7 +8664,7 @@ The North America market contribution of your current investment (${valueRatio}%) exceeds ${thresholdMax}% apps/client/src/app/pages/i18n/i18n-page.html - 225 + 234 @@ -8640,7 +8672,7 @@ The North America market contribution of your current investment (${valueRatio}%) is below ${thresholdMin}% apps/client/src/app/pages/i18n/i18n-page.html - 229 + 238 @@ -8648,7 +8680,7 @@ The North America market contribution of your current investment (${valueRatio}%) is within the range of ${thresholdMin}% and ${thresholdMax}% apps/client/src/app/pages/i18n/i18n-page.html - 233 + 242 @@ -8696,7 +8728,7 @@ Registration Date apps/client/src/app/components/user-detail-dialog/user-detail-dialog.html - 26 + 45 diff --git a/apps/client/src/locales/messages.de.xlf b/apps/client/src/locales/messages.de.xlf index 44ee607c3..2be7713eb 100644 --- a/apps/client/src/locales/messages.de.xlf +++ b/apps/client/src/locales/messages.de.xlf @@ -272,6 +272,10 @@ apps/client/src/app/components/admin-tag/admin-tag.component.html 78 + + apps/client/src/app/components/user-detail-dialog/user-detail-dialog.html + 22 + libs/ui/src/lib/account-balances/account-balances.component.html 80 @@ -294,7 +298,7 @@ Möchtest du dieses Konto wirklich löschen? libs/ui/src/lib/accounts-table/accounts-table.component.ts - 150 + 148 @@ -646,7 +650,7 @@ Möchtest du diesen Benutzer wirklich löschen? apps/client/src/app/components/admin-users/admin-users.component.ts - 215 + 218 @@ -682,7 +686,7 @@ apps/client/src/app/components/user-detail-dialog/user-detail-dialog.html - 89 + 108 @@ -738,7 +742,7 @@ apps/client/src/app/pages/public/public-page.html - 242 + 241 apps/client/src/app/pages/resources/personal-finance-tools/product-page.html @@ -790,7 +794,7 @@ Aktivitäten verwalten apps/client/src/app/components/home-holdings/home-holdings.html - 67 + 65 @@ -906,7 +910,7 @@ Absolute Brutto Performance apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 73 + 77 @@ -914,7 +918,7 @@ Absolute Netto Performance apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 107 + 111 apps/client/src/app/pages/portfolio/analysis/analysis-page.html @@ -926,7 +930,7 @@ Netto Performance apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 123 + 127 apps/client/src/app/pages/portfolio/analysis/analysis-page.html @@ -938,7 +942,7 @@ Gesamtanlagevermögen apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 149 + 153 @@ -946,7 +950,7 @@ Kaufkraft apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 241 + 245 @@ -954,7 +958,7 @@ Gesamtvermögen apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 317 + 321 @@ -962,7 +966,7 @@ Performance pro Jahr apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 331 + 335 @@ -990,7 +994,7 @@ apps/client/src/app/pages/public/public-page.html - 114 + 113 @@ -1030,7 +1034,7 @@ Datenfehler melden apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html - 451 + 450 @@ -1058,7 +1062,7 @@ Alle anzeigen libs/ui/src/lib/holdings-table/holdings-table.component.html - 216 + 212 @@ -1342,7 +1346,7 @@ apps/client/src/app/components/user-detail-dialog/user-detail-dialog.html - 11 + 30 @@ -1394,7 +1398,7 @@ apps/client/src/app/components/user-detail-dialog/user-detail-dialog.html - 66 + 85 apps/client/src/app/pages/accounts/accounts-page.html @@ -1834,7 +1838,7 @@ apps/client/src/app/pages/public/public-page.html - 151 + 150 @@ -2034,7 +2038,7 @@ apps/client/src/app/components/account-detail-dialog/account-detail-dialog.html - 115 + 113 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html @@ -2058,7 +2062,7 @@ apps/client/src/app/components/user-detail-dialog/user-detail-dialog.html - 75 + 94 apps/client/src/app/pages/portfolio/activities/activities-page.html @@ -2158,7 +2162,7 @@ Kontinente apps/client/src/app/pages/public/public-page.html - 132 + 131 @@ -2174,7 +2178,7 @@ Ghostfolio verschafft dir den Überblick über dein Vermögen. apps/client/src/app/pages/public/public-page.html - 238 + 237 @@ -2322,7 +2326,7 @@ Möchtest du diese Aktivität wirklich löschen? libs/ui/src/lib/activities-table/activities-table.component.ts - 288 + 292 @@ -2454,7 +2458,7 @@ apps/client/src/app/components/user-detail-dialog/user-detail-dialog.html - 53 + 72 @@ -2478,7 +2482,7 @@ apps/client/src/app/pages/public/public-page.html - 168 + 167 @@ -2486,7 +2490,7 @@ Neueste Aktivitäten apps/client/src/app/pages/public/public-page.html - 211 + 210 @@ -2498,7 +2502,7 @@ apps/client/src/app/pages/public/public-page.html - 177 + 176 @@ -2510,7 +2514,7 @@ apps/client/src/app/pages/public/public-page.html - 186 + 185 @@ -2554,7 +2558,7 @@ apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 352 + 356 libs/ui/src/lib/fire-calculator/fire-calculator.component.ts @@ -2702,7 +2706,7 @@ Von der Analyse ausgenommen apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 267 + 271 @@ -2746,7 +2750,7 @@ Gesamtbetrag apps/client/src/app/components/investment-chart/investment-chart.component.ts - 143 + 146 @@ -2862,7 +2866,7 @@ Bargeld apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 212 + 216 libs/ui/src/lib/i18n.ts @@ -2910,7 +2914,7 @@ Authentifizierung apps/client/src/app/components/user-detail-dialog/user-detail-dialog.html - 35 + 54 @@ -2974,7 +2978,7 @@ Notfallfonds apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 164 + 168 apps/client/src/app/pages/features/features-page.html @@ -2994,7 +2998,7 @@ libs/ui/src/lib/portfolio-proportion-chart/portfolio-proportion-chart.component.ts - 437 + 449 @@ -3006,7 +3010,7 @@ apps/client/src/app/pages/public/public-page.html - 196 + 195 libs/ui/src/lib/benchmark/benchmark.component.html @@ -3014,11 +3018,11 @@ libs/ui/src/lib/portfolio-proportion-chart/portfolio-proportion-chart.component.ts - 439 + 451 libs/ui/src/lib/portfolio-proportion-chart/portfolio-proportion-chart.component.ts - 452 + 465 libs/ui/src/lib/top-holdings/top-holdings.component.html @@ -3154,7 +3158,7 @@ apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 365 + 369 apps/client/src/app/pages/features/features-page.html @@ -3238,7 +3242,7 @@ Marktdaten apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html - 398 + 397 libs/common/src/lib/routes/routes.ts @@ -3650,7 +3654,7 @@ apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 88 + 92 @@ -3822,7 +3826,7 @@ Möchtest du diese Aktivitäten wirklich löschen? libs/ui/src/lib/activities-table/activities-table.component.ts - 278 + 282 @@ -4094,7 +4098,7 @@ Verbindlichkeiten apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 295 + 299 apps/client/src/app/pages/features/features-page.html @@ -4510,7 +4514,7 @@ Anlagevermögen apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 226 + 230 @@ -4742,7 +4746,7 @@ apps/client/src/app/pages/public/public-page.html - 96 + 95 @@ -5556,7 +5560,7 @@ Mitgliedschaft apps/client/src/app/components/user-detail-dialog/user-detail-dialog.html - 48 + 67 libs/common/src/lib/routes/routes.ts @@ -5664,7 +5668,7 @@ Open Source Software für die Vermögensverwaltung apps/client/src/app/pages/i18n/i18n-page.html - 237 + 246 @@ -5744,7 +5748,7 @@ Cash-Bestände apps/client/src/app/components/account-detail-dialog/account-detail-dialog.html - 148 + 146 @@ -5900,7 +5904,7 @@ Position abschliessen apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html - 442 + 441 @@ -6353,7 +6357,7 @@ Möchtest du deine persönliche Anlagestrategie verfeinern? apps/client/src/app/pages/public/public-page.html - 234 + 233 @@ -6815,6 +6819,10 @@ apps/client/src/app/components/user-account-access/create-or-update-access-dialog/create-or-update-access-dialog.html 68 + + apps/client/src/app/components/user-detail-dialog/user-detail-dialog.html + 127 + apps/client/src/app/pages/accounts/create-or-update-account-dialog/create-or-update-account-dialog.html 107 @@ -6833,7 +6841,7 @@ Rolle apps/client/src/app/components/user-detail-dialog/user-detail-dialog.html - 14 + 33 @@ -7239,7 +7247,7 @@ apps/client/src/app/components/user-detail-dialog/user-detail-dialog.html - 98 + 117 @@ -7503,7 +7511,7 @@ libs/ui/src/lib/treemap-chart/treemap-chart.component.ts - 368 + 375 @@ -7523,11 +7531,11 @@ libs/ui/src/lib/treemap-chart/treemap-chart.component.ts - 368 + 375 libs/ui/src/lib/treemap-chart/treemap-chart.component.ts - 381 + 388 @@ -7631,7 +7639,7 @@ Sicherheits-Token apps/client/src/app/components/admin-users/admin-users.component.ts - 236 + 239 apps/client/src/app/components/user-account-access/user-account-access.component.ts @@ -7643,7 +7651,7 @@ Möchtest du für diesen Benutzer wirklich ein neues Sicherheits-Token generieren? apps/client/src/app/components/admin-users/admin-users.component.ts - 241 + 244 @@ -7842,7 +7850,7 @@ Sync Demo User Account - Synchronisiere Demo Benutzerkonto + Synchronisiere Demo Benutzerkonto apps/client/src/app/components/admin-overview/admin-overview.html 195 @@ -7873,8 +7881,8 @@ - Fee Ratio - Gebührenverhältnis + Fee Ratio (legacy) + Gebührenverhältnis (veraltet) apps/client/src/app/pages/i18n/i18n-page.html 152 @@ -7896,6 +7904,30 @@ 158 + + Fee Ratio + Gebührenverhältnis + + apps/client/src/app/pages/i18n/i18n-page.html + 161 + + + + The fees do exceed ${thresholdMax}% of your total investment volume (${feeRatio}%) + Die Gebühren übersteigen ${thresholdMax}% deines gesamten Investitionsvolumens (${feeRatio}%) + + apps/client/src/app/pages/i18n/i18n-page.html + 163 + + + + The fees do not exceed ${thresholdMax}% of your total investment volume (${feeRatio}%) + Die Gebühren übersteigen ${thresholdMax}% deines gesamten Investitionsvolumens (${feeRatio}%) nicht + + apps/client/src/app/pages/i18n/i18n-page.html + 167 + + Quick Links Schnellzugriff @@ -8276,7 +8308,7 @@ Anlageprofil verwalten apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html - 466 + 465 @@ -8352,7 +8384,7 @@ Gebühren apps/client/src/app/pages/i18n/i18n-page.html - 161 + 170 @@ -8400,7 +8432,7 @@ Regionale Marktklumpenrisiken apps/client/src/app/pages/i18n/i18n-page.html - 163 + 172 @@ -8496,7 +8528,7 @@ Asien-Pazifik apps/client/src/app/pages/i18n/i18n-page.html - 165 + 174 @@ -8504,7 +8536,7 @@ Der Anteil des Asien-Pazifik-Marktes deiner aktuellen Investition (${valueRatio}%) übersteigt ${thresholdMax}% apps/client/src/app/pages/i18n/i18n-page.html - 167 + 176 @@ -8512,7 +8544,7 @@ Der Anteil des Asien-Pazifik-Marktes deiner aktuellen Investition (${valueRatio}%) liegt unter ${thresholdMin}% apps/client/src/app/pages/i18n/i18n-page.html - 171 + 180 @@ -8520,7 +8552,7 @@ Der Anteil des Asien-Pazifik-Marktes deiner aktuellen Investition (${valueRatio}%) liegt im Bereich zwischen ${thresholdMin}% und ${thresholdMax}% apps/client/src/app/pages/i18n/i18n-page.html - 175 + 184 @@ -8528,7 +8560,7 @@ Schwellenländer apps/client/src/app/pages/i18n/i18n-page.html - 180 + 189 @@ -8536,7 +8568,7 @@ Der Anteil der Schwellenländer deiner aktuellen Investition (${valueRatio}%) übersteigt ${thresholdMax}% apps/client/src/app/pages/i18n/i18n-page.html - 183 + 192 @@ -8544,7 +8576,7 @@ Der Anteil der Schwellenländer deiner aktuellen Investition (${valueRatio}%) liegt unter ${thresholdMin}% apps/client/src/app/pages/i18n/i18n-page.html - 187 + 196 @@ -8552,7 +8584,7 @@ Der Anteil der Schwellenländer deiner aktuellen Investition (${valueRatio}%) liegt im Bereich zwischen ${thresholdMin}% und ${thresholdMax}% apps/client/src/app/pages/i18n/i18n-page.html - 191 + 200 @@ -8560,7 +8592,7 @@ Europa apps/client/src/app/pages/i18n/i18n-page.html - 195 + 204 @@ -8568,7 +8600,7 @@ Der Anteil des europäischen Marktes deiner aktuellen Investition (${valueRatio}%) übersteigt ${thresholdMax}% apps/client/src/app/pages/i18n/i18n-page.html - 197 + 206 @@ -8576,7 +8608,7 @@ Der Anteil des europäischen Marktes deiner aktuellen Investition (${valueRatio}%) liegt unter ${thresholdMin}% apps/client/src/app/pages/i18n/i18n-page.html - 201 + 210 @@ -8584,7 +8616,7 @@ Der Anteil des europäischen Marktes deiner aktuellen Investition (${valueRatio}%) liegt im Bereich zwischen ${thresholdMin}% und ${thresholdMax}% apps/client/src/app/pages/i18n/i18n-page.html - 205 + 214 @@ -8592,7 +8624,7 @@ Japan apps/client/src/app/pages/i18n/i18n-page.html - 209 + 218 @@ -8600,7 +8632,7 @@ Der Anteil des japanischen Marktes deiner aktuellen Investition (${valueRatio}%) übersteigt ${thresholdMax}% apps/client/src/app/pages/i18n/i18n-page.html - 211 + 220 @@ -8608,7 +8640,7 @@ Der Anteil des japanischen Marktes deiner aktuellen Investition (${valueRatio}%) liegt unter ${thresholdMin}% apps/client/src/app/pages/i18n/i18n-page.html - 215 + 224 @@ -8616,7 +8648,7 @@ Der Anteil des japanischen Marktes deiner aktuellen Investition (${valueRatio}%) liegt im Bereich zwischen ${thresholdMin}% und ${thresholdMax}% apps/client/src/app/pages/i18n/i18n-page.html - 219 + 228 @@ -8624,7 +8656,7 @@ Nordamerika apps/client/src/app/pages/i18n/i18n-page.html - 223 + 232 @@ -8632,7 +8664,7 @@ Der Anteil des nordamerikanischen Marktes deiner aktuellen Investition (${valueRatio}%) übersteigt ${thresholdMax}% apps/client/src/app/pages/i18n/i18n-page.html - 225 + 234 @@ -8640,7 +8672,7 @@ Der Anteil des nordamerikanischen Marktes deiner aktuellen Investition (${valueRatio}%) liegt unter ${thresholdMin}% apps/client/src/app/pages/i18n/i18n-page.html - 229 + 238 @@ -8648,7 +8680,7 @@ Der Anteil des nordamerikanischen Marktes deiner aktuellen Investition (${valueRatio}%) liegt im Bereich zwischen ${thresholdMin}% und ${thresholdMax}% apps/client/src/app/pages/i18n/i18n-page.html - 233 + 242 @@ -8696,7 +8728,7 @@ Registrierungsdatum apps/client/src/app/components/user-detail-dialog/user-detail-dialog.html - 26 + 45 diff --git a/apps/client/src/locales/messages.es.xlf b/apps/client/src/locales/messages.es.xlf index 7564e4d80..fb4773203 100644 --- a/apps/client/src/locales/messages.es.xlf +++ b/apps/client/src/locales/messages.es.xlf @@ -273,6 +273,10 @@ apps/client/src/app/components/admin-tag/admin-tag.component.html 78 + + apps/client/src/app/components/user-detail-dialog/user-detail-dialog.html + 22 + libs/ui/src/lib/account-balances/account-balances.component.html 80 @@ -295,7 +299,7 @@ ¿Estás seguro de eliminar esta cuenta? libs/ui/src/lib/accounts-table/accounts-table.component.ts - 150 + 148 @@ -631,7 +635,7 @@ ¿Estás seguro de eliminar este usuario? apps/client/src/app/components/admin-users/admin-users.component.ts - 215 + 218 @@ -667,7 +671,7 @@ apps/client/src/app/components/user-detail-dialog/user-detail-dialog.html - 89 + 108 @@ -723,7 +727,7 @@ apps/client/src/app/pages/public/public-page.html - 242 + 241 apps/client/src/app/pages/resources/personal-finance-tools/product-page.html @@ -775,7 +779,7 @@ Gestión de las operaciones apps/client/src/app/components/home-holdings/home-holdings.html - 67 + 65 @@ -891,7 +895,7 @@ Rendimiento bruto absoluto apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 73 + 77 @@ -899,7 +903,7 @@ Rendimiento neto absoluto apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 107 + 111 apps/client/src/app/pages/portfolio/analysis/analysis-page.html @@ -911,7 +915,7 @@ Rendimiento neto apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 123 + 127 apps/client/src/app/pages/portfolio/analysis/analysis-page.html @@ -923,7 +927,7 @@ Total de activos apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 149 + 153 @@ -931,7 +935,7 @@ Capacidad de compra apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 241 + 245 @@ -939,7 +943,7 @@ Patrimonio neto apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 317 + 321 @@ -947,7 +951,7 @@ Rendimiento anualizado apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 331 + 335 @@ -975,7 +979,7 @@ apps/client/src/app/pages/public/public-page.html - 114 + 113 @@ -1015,7 +1019,7 @@ Reporta un anomalía de los datos apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html - 451 + 450 @@ -1043,7 +1047,7 @@ Mostrar todos libs/ui/src/lib/holdings-table/holdings-table.component.html - 216 + 212 @@ -1327,7 +1331,7 @@ apps/client/src/app/components/user-detail-dialog/user-detail-dialog.html - 11 + 30 @@ -1379,7 +1383,7 @@ apps/client/src/app/components/user-detail-dialog/user-detail-dialog.html - 66 + 85 apps/client/src/app/pages/accounts/accounts-page.html @@ -1819,7 +1823,7 @@ apps/client/src/app/pages/public/public-page.html - 151 + 150 @@ -2019,7 +2023,7 @@ apps/client/src/app/components/account-detail-dialog/account-detail-dialog.html - 115 + 113 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html @@ -2043,7 +2047,7 @@ apps/client/src/app/components/user-detail-dialog/user-detail-dialog.html - 75 + 94 apps/client/src/app/pages/portfolio/activities/activities-page.html @@ -2143,7 +2147,7 @@ Continentes apps/client/src/app/pages/public/public-page.html - 132 + 131 @@ -2159,7 +2163,7 @@ Ghostfolio te permite hacer un seguimiento de tu riqueza. apps/client/src/app/pages/public/public-page.html - 238 + 237 @@ -2307,7 +2311,7 @@ ¿Estás seguro de eliminar esta operación? libs/ui/src/lib/activities-table/activities-table.component.ts - 288 + 292 @@ -2415,7 +2419,7 @@ apps/client/src/app/pages/public/public-page.html - 168 + 167 @@ -2423,7 +2427,7 @@ Últimas actividades apps/client/src/app/pages/public/public-page.html - 211 + 210 @@ -2443,7 +2447,7 @@ apps/client/src/app/pages/public/public-page.html - 186 + 185 @@ -2455,7 +2459,7 @@ apps/client/src/app/pages/public/public-page.html - 177 + 176 @@ -2487,7 +2491,7 @@ apps/client/src/app/components/user-detail-dialog/user-detail-dialog.html - 53 + 72 @@ -2523,7 +2527,7 @@ apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 352 + 356 libs/ui/src/lib/fire-calculator/fire-calculator.component.ts @@ -2687,7 +2691,7 @@ Excluido del análisis apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 267 + 271 @@ -2731,7 +2735,7 @@ Importe total apps/client/src/app/components/investment-chart/investment-chart.component.ts - 143 + 146 @@ -2847,7 +2851,7 @@ Efectivo apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 212 + 216 libs/ui/src/lib/i18n.ts @@ -2895,7 +2899,7 @@ Autenticación apps/client/src/app/components/user-detail-dialog/user-detail-dialog.html - 35 + 54 @@ -2959,7 +2963,7 @@ Fondo de emergencia apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 164 + 168 apps/client/src/app/pages/features/features-page.html @@ -2979,7 +2983,7 @@ libs/ui/src/lib/portfolio-proportion-chart/portfolio-proportion-chart.component.ts - 437 + 449 @@ -2991,7 +2995,7 @@ apps/client/src/app/pages/public/public-page.html - 196 + 195 libs/ui/src/lib/benchmark/benchmark.component.html @@ -2999,11 +3003,11 @@ libs/ui/src/lib/portfolio-proportion-chart/portfolio-proportion-chart.component.ts - 439 + 451 libs/ui/src/lib/portfolio-proportion-chart/portfolio-proportion-chart.component.ts - 452 + 465 libs/ui/src/lib/top-holdings/top-holdings.component.html @@ -3131,7 +3135,7 @@ apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 365 + 369 apps/client/src/app/pages/features/features-page.html @@ -3223,7 +3227,7 @@ Datos del mercado apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html - 398 + 397 libs/common/src/lib/routes/routes.ts @@ -3635,7 +3639,7 @@ apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 88 + 92 @@ -3799,7 +3803,7 @@ ¿Realmente deseas eliminar estas actividades? libs/ui/src/lib/activities-table/activities-table.component.ts - 278 + 282 @@ -4071,7 +4075,7 @@ Pasivos apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 295 + 299 apps/client/src/app/pages/features/features-page.html @@ -4487,7 +4491,7 @@ Activos apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 226 + 230 @@ -4719,7 +4723,7 @@ apps/client/src/app/pages/public/public-page.html - 96 + 95 @@ -5533,7 +5537,7 @@ Membresía apps/client/src/app/components/user-detail-dialog/user-detail-dialog.html - 48 + 67 libs/common/src/lib/routes/routes.ts @@ -5641,7 +5645,7 @@ Software de gestión de patrimonio de código abierto apps/client/src/app/pages/i18n/i18n-page.html - 237 + 246 @@ -5721,7 +5725,7 @@ Saldos de efectivo apps/client/src/app/components/account-detail-dialog/account-detail-dialog.html - 148 + 146 @@ -5877,7 +5881,7 @@ Cerrar posición apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html - 442 + 441 @@ -6330,7 +6334,7 @@ ¿Te gustaría refinar tu estrategia de inversión personal? apps/client/src/app/pages/public/public-page.html - 234 + 233 @@ -6792,6 +6796,10 @@ apps/client/src/app/components/user-account-access/create-or-update-access-dialog/create-or-update-access-dialog.html 68 + + apps/client/src/app/components/user-detail-dialog/user-detail-dialog.html + 127 + apps/client/src/app/pages/accounts/create-or-update-account-dialog/create-or-update-account-dialog.html 107 @@ -6810,7 +6818,7 @@ Rol apps/client/src/app/components/user-detail-dialog/user-detail-dialog.html - 14 + 33 @@ -7216,7 +7224,7 @@ apps/client/src/app/components/user-detail-dialog/user-detail-dialog.html - 98 + 117 @@ -7480,7 +7488,7 @@ libs/ui/src/lib/treemap-chart/treemap-chart.component.ts - 368 + 375 @@ -7500,11 +7508,11 @@ libs/ui/src/lib/treemap-chart/treemap-chart.component.ts - 368 + 375 libs/ui/src/lib/treemap-chart/treemap-chart.component.ts - 381 + 388 @@ -7608,7 +7616,7 @@ Token de seguridad apps/client/src/app/components/admin-users/admin-users.component.ts - 236 + 239 apps/client/src/app/components/user-account-access/user-account-access.component.ts @@ -7620,7 +7628,7 @@ ¿Realmente deseas generar un nuevo token de seguridad para este usuario? apps/client/src/app/components/admin-users/admin-users.component.ts - 241 + 244 @@ -7874,8 +7882,8 @@ - Fee Ratio - Relación de tarifas + Fee Ratio (legacy) + Relación de tarifas apps/client/src/app/pages/i18n/i18n-page.html 152 @@ -7897,6 +7905,30 @@ 158 + + Fee Ratio + Fee Ratio + + apps/client/src/app/pages/i18n/i18n-page.html + 161 + + + + The fees do exceed ${thresholdMax}% of your total investment volume (${feeRatio}%) + The fees do exceed ${thresholdMax}% of your total investment volume (${feeRatio}%) + + apps/client/src/app/pages/i18n/i18n-page.html + 163 + + + + The fees do not exceed ${thresholdMax}% of your total investment volume (${feeRatio}%) + The fees do not exceed ${thresholdMax}% of your total investment volume (${feeRatio}%) + + apps/client/src/app/pages/i18n/i18n-page.html + 167 + + Quick Links Enlaces rápidos @@ -8277,7 +8309,7 @@ Gestionar perfil de activo apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html - 466 + 465 @@ -8353,7 +8385,7 @@ Comisiones apps/client/src/app/pages/i18n/i18n-page.html - 161 + 170 @@ -8401,7 +8433,7 @@ Riesgos de los grupos de mercados regionales apps/client/src/app/pages/i18n/i18n-page.html - 163 + 172 @@ -8497,7 +8529,7 @@ Asia-Pacífico apps/client/src/app/pages/i18n/i18n-page.html - 165 + 174 @@ -8505,7 +8537,7 @@ La contribución al mercado de Asia-Pacífico de tu inversión actual (${valueRatio}%) supera el ${thresholdMax}% apps/client/src/app/pages/i18n/i18n-page.html - 167 + 176 @@ -8513,7 +8545,7 @@ La contribución al mercado de Asia-Pacífico de tu inversión actual (${valueRatio}%) es inferior al ${thresholdMin}% apps/client/src/app/pages/i18n/i18n-page.html - 171 + 180 @@ -8521,7 +8553,7 @@ La contribución al mercado de Asia-Pacífico de tu inversión actual (${valueRatio}%) está dentro del rango de ${thresholdMin}% y ${thresholdMax}% apps/client/src/app/pages/i18n/i18n-page.html - 175 + 184 @@ -8529,7 +8561,7 @@ Mercados emergentes apps/client/src/app/pages/i18n/i18n-page.html - 180 + 189 @@ -8537,7 +8569,7 @@ La contribución a los mercados emergentes de tu inversión actual (${valueRatio}%) supera el ${thresholdMax}% apps/client/src/app/pages/i18n/i18n-page.html - 183 + 192 @@ -8545,7 +8577,7 @@ La contribución a los mercados emergentes de tu inversión actual (${valueRatio}%) es inferior al ${thresholdMin}% apps/client/src/app/pages/i18n/i18n-page.html - 187 + 196 @@ -8553,7 +8585,7 @@ La contribución a los mercados emergentes de tu inversión actual (${valueRatio}%) está dentro del rango de ${thresholdMin}% y ${thresholdMax}% apps/client/src/app/pages/i18n/i18n-page.html - 191 + 200 @@ -8561,7 +8593,7 @@ Europa apps/client/src/app/pages/i18n/i18n-page.html - 195 + 204 @@ -8569,7 +8601,7 @@ La contribución al mercado europeo de tu inversión actual (${valueRatio}%) supera el ${thresholdMax}% apps/client/src/app/pages/i18n/i18n-page.html - 197 + 206 @@ -8577,7 +8609,7 @@ La contribución al mercado europeo de tu inversión actual (${valueRatio}%) es inferior al ${thresholdMin}% apps/client/src/app/pages/i18n/i18n-page.html - 201 + 210 @@ -8585,7 +8617,7 @@ La contribución al mercado europeo de tu inversión actual (${valueRatio}%) está dentro del rango de ${thresholdMin}% y ${thresholdMax}% apps/client/src/app/pages/i18n/i18n-page.html - 205 + 214 @@ -8593,7 +8625,7 @@ Japón apps/client/src/app/pages/i18n/i18n-page.html - 209 + 218 @@ -8601,7 +8633,7 @@ La contribución al mercado japonés de su inversión actual (${valueRatio}%) supera el ${thresholdMax}% apps/client/src/app/pages/i18n/i18n-page.html - 211 + 220 @@ -8609,7 +8641,7 @@ La contribución al mercado japonés de su inversión actual (${valueRatio}%) es inferior a ${thresholdMin}% apps/client/src/app/pages/i18n/i18n-page.html - 215 + 224 @@ -8617,7 +8649,7 @@ La contribución al mercado japonés de su inversión actual (${valueRatio}%) está dentro del rango de ${thresholdMin}% y ${thresholdMax}% apps/client/src/app/pages/i18n/i18n-page.html - 219 + 228 @@ -8625,7 +8657,7 @@ Norteamérica apps/client/src/app/pages/i18n/i18n-page.html - 223 + 232 @@ -8633,7 +8665,7 @@ La contribución del mercado de América del Norte de su inversión actual (${valueRatio}%) supera el ${thresholdMax}% apps/client/src/app/pages/i18n/i18n-page.html - 225 + 234 @@ -8641,7 +8673,7 @@ La contribución al mercado de América del Norte de su inversión actual (${valueRatio}%) es inferior a ${thresholdMin}% apps/client/src/app/pages/i18n/i18n-page.html - 229 + 238 @@ -8649,7 +8681,7 @@ La contribución al mercado de América del Norte de su inversión actual (${valueRatio}%) está dentro del rango de ${thresholdMin}% y ${thresholdMax}% apps/client/src/app/pages/i18n/i18n-page.html - 233 + 242 @@ -8697,7 +8729,7 @@ Fecha de registro apps/client/src/app/components/user-detail-dialog/user-detail-dialog.html - 26 + 45 diff --git a/apps/client/src/locales/messages.fr.xlf b/apps/client/src/locales/messages.fr.xlf index 0da1c3f6a..8cb2b2f48 100644 --- a/apps/client/src/locales/messages.fr.xlf +++ b/apps/client/src/locales/messages.fr.xlf @@ -328,6 +328,10 @@ apps/client/src/app/components/admin-tag/admin-tag.component.html 78 + + apps/client/src/app/components/user-detail-dialog/user-detail-dialog.html + 22 + libs/ui/src/lib/account-balances/account-balances.component.html 80 @@ -350,7 +354,7 @@ Voulez-vous vraiment supprimer ce compte ? libs/ui/src/lib/accounts-table/accounts-table.component.ts - 150 + 148 @@ -634,7 +638,7 @@ apps/client/src/app/components/user-detail-dialog/user-detail-dialog.html - 53 + 72 @@ -654,7 +658,7 @@ apps/client/src/app/pages/public/public-page.html - 114 + 113 @@ -842,7 +846,7 @@ Voulez-vous vraiment supprimer cet·te utilisateur·rice ? apps/client/src/app/components/admin-users/admin-users.component.ts - 215 + 218 @@ -878,7 +882,7 @@ apps/client/src/app/components/user-detail-dialog/user-detail-dialog.html - 89 + 108 @@ -1010,7 +1014,7 @@ Gérer les Activités apps/client/src/app/components/home-holdings/home-holdings.html - 67 + 65 @@ -1062,7 +1066,7 @@ Montant Total apps/client/src/app/components/investment-chart/investment-chart.component.ts - 143 + 146 @@ -1174,7 +1178,7 @@ Performance Absolue Brute apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 73 + 77 @@ -1182,7 +1186,7 @@ Performance Absolue Nette apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 107 + 111 apps/client/src/app/pages/portfolio/analysis/analysis-page.html @@ -1194,7 +1198,7 @@ Performance nette apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 123 + 127 apps/client/src/app/pages/portfolio/analysis/analysis-page.html @@ -1206,7 +1210,7 @@ Actifs Totaux apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 149 + 153 @@ -1214,7 +1218,7 @@ Pouvoir d’Achat apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 241 + 245 @@ -1222,7 +1226,7 @@ Exclus de l’Analyse apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 267 + 271 @@ -1230,7 +1234,7 @@ Fortune apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 317 + 321 @@ -1238,7 +1242,7 @@ Performance annualisée apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 331 + 335 @@ -1290,7 +1294,7 @@ Signaler une Erreur de Données apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html - 451 + 450 @@ -1662,7 +1666,7 @@ apps/client/src/app/components/user-detail-dialog/user-detail-dialog.html - 11 + 30 @@ -1714,7 +1718,7 @@ apps/client/src/app/components/user-detail-dialog/user-detail-dialog.html - 66 + 85 apps/client/src/app/pages/accounts/accounts-page.html @@ -1758,7 +1762,7 @@ Données du marché apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html - 398 + 397 libs/common/src/lib/routes/routes.ts @@ -2042,7 +2046,7 @@ apps/client/src/app/components/account-detail-dialog/account-detail-dialog.html - 115 + 113 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html @@ -2066,7 +2070,7 @@ apps/client/src/app/components/user-detail-dialog/user-detail-dialog.html - 75 + 94 apps/client/src/app/pages/portfolio/activities/activities-page.html @@ -2310,7 +2314,7 @@ apps/client/src/app/pages/public/public-page.html - 151 + 150 @@ -2334,7 +2338,7 @@ apps/client/src/app/pages/public/public-page.html - 168 + 167 @@ -2342,7 +2346,7 @@ Latest activities apps/client/src/app/pages/public/public-page.html - 211 + 210 @@ -2354,7 +2358,7 @@ apps/client/src/app/pages/public/public-page.html - 177 + 176 @@ -2366,7 +2370,7 @@ apps/client/src/app/pages/public/public-page.html - 186 + 185 @@ -2402,7 +2406,7 @@ apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 365 + 369 apps/client/src/app/pages/features/features-page.html @@ -2546,7 +2550,7 @@ Continents apps/client/src/app/pages/public/public-page.html - 132 + 131 @@ -2562,7 +2566,7 @@ Ghostfolio vous aide à garder un aperçu de votre patrimoine. apps/client/src/app/pages/public/public-page.html - 238 + 237 @@ -2590,7 +2594,7 @@ apps/client/src/app/pages/public/public-page.html - 242 + 241 apps/client/src/app/pages/resources/personal-finance-tools/product-page.html @@ -2798,7 +2802,7 @@ Voulez-vous vraiment supprimer cette activité ? libs/ui/src/lib/activities-table/activities-table.component.ts - 288 + 292 @@ -2850,7 +2854,7 @@ apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 352 + 356 libs/ui/src/lib/fire-calculator/fire-calculator.component.ts @@ -2894,7 +2898,7 @@ Montrer tout libs/ui/src/lib/holdings-table/holdings-table.component.html - 216 + 212 @@ -2982,7 +2986,7 @@ Fonds d’Urgence apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 164 + 168 apps/client/src/app/pages/features/features-page.html @@ -3002,7 +3006,7 @@ libs/ui/src/lib/portfolio-proportion-chart/portfolio-proportion-chart.component.ts - 437 + 449 @@ -3050,7 +3054,7 @@ Cash apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 212 + 216 libs/ui/src/lib/i18n.ts @@ -3098,7 +3102,7 @@ Authentication apps/client/src/app/components/user-detail-dialog/user-detail-dialog.html - 35 + 54 @@ -3230,7 +3234,7 @@ apps/client/src/app/pages/public/public-page.html - 196 + 195 libs/ui/src/lib/benchmark/benchmark.component.html @@ -3238,11 +3242,11 @@ libs/ui/src/lib/portfolio-proportion-chart/portfolio-proportion-chart.component.ts - 439 + 451 libs/ui/src/lib/portfolio-proportion-chart/portfolio-proportion-chart.component.ts - 452 + 465 libs/ui/src/lib/top-holdings/top-holdings.component.html @@ -3634,7 +3638,7 @@ apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 88 + 92 @@ -3798,7 +3802,7 @@ Voulez-vous vraiment supprimer toutes vos activités ? libs/ui/src/lib/activities-table/activities-table.component.ts - 278 + 282 @@ -4070,7 +4074,7 @@ Dettes apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 295 + 299 apps/client/src/app/pages/features/features-page.html @@ -4486,7 +4490,7 @@ Actifs apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 226 + 230 @@ -4718,7 +4722,7 @@ apps/client/src/app/pages/public/public-page.html - 96 + 95 @@ -5532,7 +5536,7 @@ Statut apps/client/src/app/components/user-detail-dialog/user-detail-dialog.html - 48 + 67 libs/common/src/lib/routes/routes.ts @@ -5640,7 +5644,7 @@ Logiciel libre de Gestion de Patrimoine apps/client/src/app/pages/i18n/i18n-page.html - 237 + 246 @@ -5720,7 +5724,7 @@ Cash Balances apps/client/src/app/components/account-detail-dialog/account-detail-dialog.html - 148 + 146 @@ -5876,7 +5880,7 @@ Close Holding apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html - 442 + 441 @@ -6329,7 +6333,7 @@ Souhaitez-vous affiner votre stratégie d’investissement personnelle? apps/client/src/app/pages/public/public-page.html - 234 + 233 @@ -6791,6 +6795,10 @@ apps/client/src/app/components/user-account-access/create-or-update-access-dialog/create-or-update-access-dialog.html 68 + + apps/client/src/app/components/user-detail-dialog/user-detail-dialog.html + 127 + apps/client/src/app/pages/accounts/create-or-update-account-dialog/create-or-update-account-dialog.html 107 @@ -6809,7 +6817,7 @@ Role apps/client/src/app/components/user-detail-dialog/user-detail-dialog.html - 14 + 33 @@ -7215,7 +7223,7 @@ apps/client/src/app/components/user-detail-dialog/user-detail-dialog.html - 98 + 117 @@ -7479,7 +7487,7 @@ libs/ui/src/lib/treemap-chart/treemap-chart.component.ts - 368 + 375 @@ -7499,11 +7507,11 @@ libs/ui/src/lib/treemap-chart/treemap-chart.component.ts - 368 + 375 libs/ui/src/lib/treemap-chart/treemap-chart.component.ts - 381 + 388 @@ -7607,7 +7615,7 @@ Jeton de sécurité apps/client/src/app/components/admin-users/admin-users.component.ts - 236 + 239 apps/client/src/app/components/user-account-access/user-account-access.component.ts @@ -7619,7 +7627,7 @@ Voulez-vous vraiment générer un nouveau jeton de sécurité pour cet utilisateur ? apps/client/src/app/components/admin-users/admin-users.component.ts - 241 + 244 @@ -7873,8 +7881,8 @@ - Fee Ratio - Ratio de frais + Fee Ratio (legacy) + Ratio de frais apps/client/src/app/pages/i18n/i18n-page.html 152 @@ -7896,6 +7904,30 @@ 158 + + Fee Ratio + Fee Ratio + + apps/client/src/app/pages/i18n/i18n-page.html + 161 + + + + The fees do exceed ${thresholdMax}% of your total investment volume (${feeRatio}%) + The fees do exceed ${thresholdMax}% of your total investment volume (${feeRatio}%) + + apps/client/src/app/pages/i18n/i18n-page.html + 163 + + + + The fees do not exceed ${thresholdMax}% of your total investment volume (${feeRatio}%) + The fees do not exceed ${thresholdMax}% of your total investment volume (${feeRatio}%) + + apps/client/src/app/pages/i18n/i18n-page.html + 167 + + Quick Links Liens rapides @@ -8276,7 +8308,7 @@ Gérer le profil d’actif apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html - 466 + 465 @@ -8352,7 +8384,7 @@ Fees apps/client/src/app/pages/i18n/i18n-page.html - 161 + 170 @@ -8400,7 +8432,7 @@ Regional Market Cluster Risks apps/client/src/app/pages/i18n/i18n-page.html - 163 + 172 @@ -8496,7 +8528,7 @@ Asia-Pacific apps/client/src/app/pages/i18n/i18n-page.html - 165 + 174 @@ -8504,7 +8536,7 @@ The Asia-Pacific market contribution of your current investment (${valueRatio}%) exceeds ${thresholdMax}% apps/client/src/app/pages/i18n/i18n-page.html - 167 + 176 @@ -8512,7 +8544,7 @@ The Asia-Pacific market contribution of your current investment (${valueRatio}%) is below ${thresholdMin}% apps/client/src/app/pages/i18n/i18n-page.html - 171 + 180 @@ -8520,7 +8552,7 @@ The Asia-Pacific market contribution of your current investment (${valueRatio}%) is within the range of ${thresholdMin}% and ${thresholdMax}% apps/client/src/app/pages/i18n/i18n-page.html - 175 + 184 @@ -8528,7 +8560,7 @@ Emerging Markets apps/client/src/app/pages/i18n/i18n-page.html - 180 + 189 @@ -8536,7 +8568,7 @@ The Emerging Markets contribution of your current investment (${valueRatio}%) exceeds ${thresholdMax}% apps/client/src/app/pages/i18n/i18n-page.html - 183 + 192 @@ -8544,7 +8576,7 @@ The Emerging Markets contribution of your current investment (${valueRatio}%) is below ${thresholdMin}% apps/client/src/app/pages/i18n/i18n-page.html - 187 + 196 @@ -8552,7 +8584,7 @@ The Emerging Markets contribution of your current investment (${valueRatio}%) is within the range of ${thresholdMin}% and ${thresholdMax}% apps/client/src/app/pages/i18n/i18n-page.html - 191 + 200 @@ -8560,7 +8592,7 @@ Europe apps/client/src/app/pages/i18n/i18n-page.html - 195 + 204 @@ -8568,7 +8600,7 @@ The Europe market contribution of your current investment (${valueRatio}%) exceeds ${thresholdMax}% apps/client/src/app/pages/i18n/i18n-page.html - 197 + 206 @@ -8576,7 +8608,7 @@ The Europe market contribution of your current investment (${valueRatio}%) is below ${thresholdMin}% apps/client/src/app/pages/i18n/i18n-page.html - 201 + 210 @@ -8584,7 +8616,7 @@ The Europe market contribution of your current investment (${valueRatio}%) is within the range of ${thresholdMin}% and ${thresholdMax}% apps/client/src/app/pages/i18n/i18n-page.html - 205 + 214 @@ -8592,7 +8624,7 @@ Japan apps/client/src/app/pages/i18n/i18n-page.html - 209 + 218 @@ -8600,7 +8632,7 @@ The Japan market contribution of your current investment (${valueRatio}%) exceeds ${thresholdMax}% apps/client/src/app/pages/i18n/i18n-page.html - 211 + 220 @@ -8608,7 +8640,7 @@ The Japan market contribution of your current investment (${valueRatio}%) is below ${thresholdMin}% apps/client/src/app/pages/i18n/i18n-page.html - 215 + 224 @@ -8616,7 +8648,7 @@ The Japan market contribution of your current investment (${valueRatio}%) is within the range of ${thresholdMin}% and ${thresholdMax}% apps/client/src/app/pages/i18n/i18n-page.html - 219 + 228 @@ -8624,7 +8656,7 @@ North America apps/client/src/app/pages/i18n/i18n-page.html - 223 + 232 @@ -8632,7 +8664,7 @@ The North America market contribution of your current investment (${valueRatio}%) exceeds ${thresholdMax}% apps/client/src/app/pages/i18n/i18n-page.html - 225 + 234 @@ -8640,7 +8672,7 @@ The North America market contribution of your current investment (${valueRatio}%) is below ${thresholdMin}% apps/client/src/app/pages/i18n/i18n-page.html - 229 + 238 @@ -8648,7 +8680,7 @@ The North America market contribution of your current investment (${valueRatio}%) is within the range of ${thresholdMin}% and ${thresholdMax}% apps/client/src/app/pages/i18n/i18n-page.html - 233 + 242 @@ -8696,7 +8728,7 @@ Registration Date apps/client/src/app/components/user-detail-dialog/user-detail-dialog.html - 26 + 45 diff --git a/apps/client/src/locales/messages.it.xlf b/apps/client/src/locales/messages.it.xlf index 746e1fbd1..61b08b673 100644 --- a/apps/client/src/locales/messages.it.xlf +++ b/apps/client/src/locales/messages.it.xlf @@ -273,6 +273,10 @@ apps/client/src/app/components/admin-tag/admin-tag.component.html 78 + + apps/client/src/app/components/user-detail-dialog/user-detail-dialog.html + 22 + libs/ui/src/lib/account-balances/account-balances.component.html 80 @@ -295,7 +299,7 @@ Vuoi davvero eliminare questo account? libs/ui/src/lib/accounts-table/accounts-table.component.ts - 150 + 148 @@ -631,7 +635,7 @@ Vuoi davvero eliminare questo utente? apps/client/src/app/components/admin-users/admin-users.component.ts - 215 + 218 @@ -667,7 +671,7 @@ apps/client/src/app/components/user-detail-dialog/user-detail-dialog.html - 89 + 108 @@ -723,7 +727,7 @@ apps/client/src/app/pages/public/public-page.html - 242 + 241 apps/client/src/app/pages/resources/personal-finance-tools/product-page.html @@ -775,7 +779,7 @@ Gestione delle attività apps/client/src/app/components/home-holdings/home-holdings.html - 67 + 65 @@ -891,7 +895,7 @@ Prestazioni lorde assolute apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 73 + 77 @@ -899,7 +903,7 @@ Prestazioni nette assolute apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 107 + 111 apps/client/src/app/pages/portfolio/analysis/analysis-page.html @@ -911,7 +915,7 @@ Prestazioni nette apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 123 + 127 apps/client/src/app/pages/portfolio/analysis/analysis-page.html @@ -923,7 +927,7 @@ Asset totali apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 149 + 153 @@ -931,7 +935,7 @@ Potere d’acquisto apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 241 + 245 @@ -939,7 +943,7 @@ Patrimonio netto apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 317 + 321 @@ -947,7 +951,7 @@ Prestazioni annualizzate apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 331 + 335 @@ -975,7 +979,7 @@ apps/client/src/app/pages/public/public-page.html - 114 + 113 @@ -1015,7 +1019,7 @@ Segnala un’anomalia dei dati apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html - 451 + 450 @@ -1043,7 +1047,7 @@ Mostra tutti libs/ui/src/lib/holdings-table/holdings-table.component.html - 216 + 212 @@ -1327,7 +1331,7 @@ apps/client/src/app/components/user-detail-dialog/user-detail-dialog.html - 11 + 30 @@ -1379,7 +1383,7 @@ apps/client/src/app/components/user-detail-dialog/user-detail-dialog.html - 66 + 85 apps/client/src/app/pages/accounts/accounts-page.html @@ -1819,7 +1823,7 @@ apps/client/src/app/pages/public/public-page.html - 151 + 150 @@ -2019,7 +2023,7 @@ apps/client/src/app/components/account-detail-dialog/account-detail-dialog.html - 115 + 113 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html @@ -2043,7 +2047,7 @@ apps/client/src/app/components/user-detail-dialog/user-detail-dialog.html - 75 + 94 apps/client/src/app/pages/portfolio/activities/activities-page.html @@ -2143,7 +2147,7 @@ Continenti apps/client/src/app/pages/public/public-page.html - 132 + 131 @@ -2159,7 +2163,7 @@ Ghostfolio ti permette di tenere traccia della tua ricchezza. apps/client/src/app/pages/public/public-page.html - 238 + 237 @@ -2307,7 +2311,7 @@ Vuoi davvero eliminare questa attività? libs/ui/src/lib/activities-table/activities-table.component.ts - 288 + 292 @@ -2415,7 +2419,7 @@ apps/client/src/app/pages/public/public-page.html - 168 + 167 @@ -2423,7 +2427,7 @@ Latest activities apps/client/src/app/pages/public/public-page.html - 211 + 210 @@ -2443,7 +2447,7 @@ apps/client/src/app/pages/public/public-page.html - 186 + 185 @@ -2455,7 +2459,7 @@ apps/client/src/app/pages/public/public-page.html - 177 + 176 @@ -2487,7 +2491,7 @@ apps/client/src/app/components/user-detail-dialog/user-detail-dialog.html - 53 + 72 @@ -2523,7 +2527,7 @@ apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 352 + 356 libs/ui/src/lib/fire-calculator/fire-calculator.component.ts @@ -2687,7 +2691,7 @@ Escluso dall’analisi apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 267 + 271 @@ -2731,7 +2735,7 @@ Importo totale apps/client/src/app/components/investment-chart/investment-chart.component.ts - 143 + 146 @@ -2847,7 +2851,7 @@ Contanti apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 212 + 216 libs/ui/src/lib/i18n.ts @@ -2895,7 +2899,7 @@ Authentication apps/client/src/app/components/user-detail-dialog/user-detail-dialog.html - 35 + 54 @@ -2959,7 +2963,7 @@ Fondo di emergenza apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 164 + 168 apps/client/src/app/pages/features/features-page.html @@ -2979,7 +2983,7 @@ libs/ui/src/lib/portfolio-proportion-chart/portfolio-proportion-chart.component.ts - 437 + 449 @@ -2991,7 +2995,7 @@ apps/client/src/app/pages/public/public-page.html - 196 + 195 libs/ui/src/lib/benchmark/benchmark.component.html @@ -2999,11 +3003,11 @@ libs/ui/src/lib/portfolio-proportion-chart/portfolio-proportion-chart.component.ts - 439 + 451 libs/ui/src/lib/portfolio-proportion-chart/portfolio-proportion-chart.component.ts - 452 + 465 libs/ui/src/lib/top-holdings/top-holdings.component.html @@ -3131,7 +3135,7 @@ apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 365 + 369 apps/client/src/app/pages/features/features-page.html @@ -3223,7 +3227,7 @@ Dati del mercato apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html - 398 + 397 libs/common/src/lib/routes/routes.ts @@ -3635,7 +3639,7 @@ apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 88 + 92 @@ -3799,7 +3803,7 @@ Vuoi davvero eliminare tutte le tue attività? libs/ui/src/lib/activities-table/activities-table.component.ts - 278 + 282 @@ -4071,7 +4075,7 @@ Passività apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 295 + 299 apps/client/src/app/pages/features/features-page.html @@ -4487,7 +4491,7 @@ Asset apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 226 + 230 @@ -4719,7 +4723,7 @@ apps/client/src/app/pages/public/public-page.html - 96 + 95 @@ -5533,7 +5537,7 @@ Iscrizione apps/client/src/app/components/user-detail-dialog/user-detail-dialog.html - 48 + 67 libs/common/src/lib/routes/routes.ts @@ -5641,7 +5645,7 @@ Software Open Source per la gestione della tua ricchezza apps/client/src/app/pages/i18n/i18n-page.html - 237 + 246 @@ -5721,7 +5725,7 @@ Saldi di cassa apps/client/src/app/components/account-detail-dialog/account-detail-dialog.html - 148 + 146 @@ -5877,7 +5881,7 @@ Close Holding apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html - 442 + 441 @@ -6330,7 +6334,7 @@ Vorresti perfezionare la tua strategia personale di investimento? apps/client/src/app/pages/public/public-page.html - 234 + 233 @@ -6792,6 +6796,10 @@ apps/client/src/app/components/user-account-access/create-or-update-access-dialog/create-or-update-access-dialog.html 68 + + apps/client/src/app/components/user-detail-dialog/user-detail-dialog.html + 127 + apps/client/src/app/pages/accounts/create-or-update-account-dialog/create-or-update-account-dialog.html 107 @@ -6810,7 +6818,7 @@ Role apps/client/src/app/components/user-detail-dialog/user-detail-dialog.html - 14 + 33 @@ -7216,7 +7224,7 @@ apps/client/src/app/components/user-detail-dialog/user-detail-dialog.html - 98 + 117 @@ -7480,7 +7488,7 @@ libs/ui/src/lib/treemap-chart/treemap-chart.component.ts - 368 + 375 @@ -7500,11 +7508,11 @@ libs/ui/src/lib/treemap-chart/treemap-chart.component.ts - 368 + 375 libs/ui/src/lib/treemap-chart/treemap-chart.component.ts - 381 + 388 @@ -7608,7 +7616,7 @@ Token di sicurezza apps/client/src/app/components/admin-users/admin-users.component.ts - 236 + 239 apps/client/src/app/components/user-account-access/user-account-access.component.ts @@ -7620,7 +7628,7 @@ Vuoi davvero generare un nuovo token di sicurezza per questo utente? apps/client/src/app/components/admin-users/admin-users.component.ts - 241 + 244 @@ -7874,8 +7882,8 @@ - Fee Ratio - Rapporto tariffario + Fee Ratio (legacy) + Rapporto tariffario apps/client/src/app/pages/i18n/i18n-page.html 152 @@ -7897,6 +7905,30 @@ 158 + + Fee Ratio + Fee Ratio + + apps/client/src/app/pages/i18n/i18n-page.html + 161 + + + + The fees do exceed ${thresholdMax}% of your total investment volume (${feeRatio}%) + The fees do exceed ${thresholdMax}% of your total investment volume (${feeRatio}%) + + apps/client/src/app/pages/i18n/i18n-page.html + 163 + + + + The fees do not exceed ${thresholdMax}% of your total investment volume (${feeRatio}%) + The fees do not exceed ${thresholdMax}% of your total investment volume (${feeRatio}%) + + apps/client/src/app/pages/i18n/i18n-page.html + 167 + + Quick Links Collegamenti rapidi @@ -8277,7 +8309,7 @@ Gestisci profilo risorsa apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html - 466 + 465 @@ -8353,7 +8385,7 @@ Fees apps/client/src/app/pages/i18n/i18n-page.html - 161 + 170 @@ -8401,7 +8433,7 @@ Regional Market Cluster Risks apps/client/src/app/pages/i18n/i18n-page.html - 163 + 172 @@ -8497,7 +8529,7 @@ Asia-Pacific apps/client/src/app/pages/i18n/i18n-page.html - 165 + 174 @@ -8505,7 +8537,7 @@ The Asia-Pacific market contribution of your current investment (${valueRatio}%) exceeds ${thresholdMax}% apps/client/src/app/pages/i18n/i18n-page.html - 167 + 176 @@ -8513,7 +8545,7 @@ The Asia-Pacific market contribution of your current investment (${valueRatio}%) is below ${thresholdMin}% apps/client/src/app/pages/i18n/i18n-page.html - 171 + 180 @@ -8521,7 +8553,7 @@ The Asia-Pacific market contribution of your current investment (${valueRatio}%) is within the range of ${thresholdMin}% and ${thresholdMax}% apps/client/src/app/pages/i18n/i18n-page.html - 175 + 184 @@ -8529,7 +8561,7 @@ Emerging Markets apps/client/src/app/pages/i18n/i18n-page.html - 180 + 189 @@ -8537,7 +8569,7 @@ The Emerging Markets contribution of your current investment (${valueRatio}%) exceeds ${thresholdMax}% apps/client/src/app/pages/i18n/i18n-page.html - 183 + 192 @@ -8545,7 +8577,7 @@ The Emerging Markets contribution of your current investment (${valueRatio}%) is below ${thresholdMin}% apps/client/src/app/pages/i18n/i18n-page.html - 187 + 196 @@ -8553,7 +8585,7 @@ The Emerging Markets contribution of your current investment (${valueRatio}%) is within the range of ${thresholdMin}% and ${thresholdMax}% apps/client/src/app/pages/i18n/i18n-page.html - 191 + 200 @@ -8561,7 +8593,7 @@ Europe apps/client/src/app/pages/i18n/i18n-page.html - 195 + 204 @@ -8569,7 +8601,7 @@ The Europe market contribution of your current investment (${valueRatio}%) exceeds ${thresholdMax}% apps/client/src/app/pages/i18n/i18n-page.html - 197 + 206 @@ -8577,7 +8609,7 @@ The Europe market contribution of your current investment (${valueRatio}%) is below ${thresholdMin}% apps/client/src/app/pages/i18n/i18n-page.html - 201 + 210 @@ -8585,7 +8617,7 @@ The Europe market contribution of your current investment (${valueRatio}%) is within the range of ${thresholdMin}% and ${thresholdMax}% apps/client/src/app/pages/i18n/i18n-page.html - 205 + 214 @@ -8593,7 +8625,7 @@ Japan apps/client/src/app/pages/i18n/i18n-page.html - 209 + 218 @@ -8601,7 +8633,7 @@ The Japan market contribution of your current investment (${valueRatio}%) exceeds ${thresholdMax}% apps/client/src/app/pages/i18n/i18n-page.html - 211 + 220 @@ -8609,7 +8641,7 @@ The Japan market contribution of your current investment (${valueRatio}%) is below ${thresholdMin}% apps/client/src/app/pages/i18n/i18n-page.html - 215 + 224 @@ -8617,7 +8649,7 @@ The Japan market contribution of your current investment (${valueRatio}%) is within the range of ${thresholdMin}% and ${thresholdMax}% apps/client/src/app/pages/i18n/i18n-page.html - 219 + 228 @@ -8625,7 +8657,7 @@ North America apps/client/src/app/pages/i18n/i18n-page.html - 223 + 232 @@ -8633,7 +8665,7 @@ The North America market contribution of your current investment (${valueRatio}%) exceeds ${thresholdMax}% apps/client/src/app/pages/i18n/i18n-page.html - 225 + 234 @@ -8641,7 +8673,7 @@ The North America market contribution of your current investment (${valueRatio}%) is below ${thresholdMin}% apps/client/src/app/pages/i18n/i18n-page.html - 229 + 238 @@ -8649,7 +8681,7 @@ The North America market contribution of your current investment (${valueRatio}%) is within the range of ${thresholdMin}% and ${thresholdMax}% apps/client/src/app/pages/i18n/i18n-page.html - 233 + 242 @@ -8697,7 +8729,7 @@ Registration Date apps/client/src/app/components/user-detail-dialog/user-detail-dialog.html - 26 + 45 diff --git a/apps/client/src/locales/messages.ko.xlf b/apps/client/src/locales/messages.ko.xlf index 67443706b..22c06b596 100644 --- a/apps/client/src/locales/messages.ko.xlf +++ b/apps/client/src/locales/messages.ko.xlf @@ -336,7 +336,7 @@ 현금 잔액 apps/client/src/app/components/account-detail-dialog/account-detail-dialog.html - 148 + 146 @@ -558,6 +558,10 @@ apps/client/src/app/components/admin-tag/admin-tag.component.html 78 + + apps/client/src/app/components/user-detail-dialog/user-detail-dialog.html + 22 + libs/ui/src/lib/account-balances/account-balances.component.html 80 @@ -580,7 +584,7 @@ 이 계정을 정말 삭제하시겠습니까? libs/ui/src/lib/accounts-table/accounts-table.component.ts - 150 + 148 @@ -756,7 +760,7 @@ apps/client/src/app/pages/public/public-page.html - 96 + 95 @@ -944,7 +948,7 @@ apps/client/src/app/components/user-detail-dialog/user-detail-dialog.html - 53 + 72 @@ -964,7 +968,7 @@ apps/client/src/app/pages/public/public-page.html - 114 + 113 @@ -1344,7 +1348,7 @@ 이 사용자를 정말로 삭제하시겠습니까? apps/client/src/app/components/admin-users/admin-users.component.ts - 215 + 218 @@ -1380,7 +1384,7 @@ apps/client/src/app/components/user-detail-dialog/user-detail-dialog.html - 89 + 108 @@ -1536,7 +1540,7 @@ 활동 관리 apps/client/src/app/components/home-holdings/home-holdings.html - 67 + 65 @@ -1688,7 +1692,7 @@ 총액 apps/client/src/app/components/investment-chart/investment-chart.component.ts - 143 + 146 @@ -1800,7 +1804,7 @@ 절대 총 성과 apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 73 + 77 @@ -1812,7 +1816,7 @@ apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 88 + 92 @@ -1820,7 +1824,7 @@ 절대 순 성과 apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 107 + 111 apps/client/src/app/pages/portfolio/analysis/analysis-page.html @@ -1832,7 +1836,7 @@ 순 성과 apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 123 + 127 apps/client/src/app/pages/portfolio/analysis/analysis-page.html @@ -1844,7 +1848,7 @@ 총자산 apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 149 + 153 @@ -1852,7 +1856,7 @@ 자산 apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 226 + 230 @@ -1860,7 +1864,7 @@ 매수 가능 금액 apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 241 + 245 @@ -1868,7 +1872,7 @@ 분석에서 제외됨 apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 267 + 271 @@ -1876,7 +1880,7 @@ 부채 apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 295 + 299 apps/client/src/app/pages/features/features-page.html @@ -1888,7 +1892,7 @@ 순자산 apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 317 + 321 @@ -1896,7 +1900,7 @@ 연환산 성과 apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 331 + 335 @@ -1948,7 +1952,7 @@ 데이터 결함 보고 apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html - 451 + 450 @@ -2448,7 +2452,7 @@ apps/client/src/app/components/user-detail-dialog/user-detail-dialog.html - 11 + 30 @@ -2640,7 +2644,7 @@ apps/client/src/app/components/user-detail-dialog/user-detail-dialog.html - 66 + 85 apps/client/src/app/pages/accounts/accounts-page.html @@ -2732,7 +2736,7 @@ 시장 데이터 apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html - 398 + 397 libs/common/src/lib/routes/routes.ts @@ -3104,7 +3108,7 @@ apps/client/src/app/pages/public/public-page.html - 242 + 241 apps/client/src/app/pages/resources/personal-finance-tools/product-page.html @@ -3220,7 +3224,7 @@ 오픈 소스 자산관리 소프트웨어 apps/client/src/app/pages/i18n/i18n-page.html - 237 + 246 @@ -3648,7 +3652,7 @@ apps/client/src/app/components/account-detail-dialog/account-detail-dialog.html - 115 + 113 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html @@ -3672,7 +3676,7 @@ apps/client/src/app/components/user-detail-dialog/user-detail-dialog.html - 75 + 94 apps/client/src/app/pages/portfolio/activities/activities-page.html @@ -3692,7 +3696,7 @@ 정말로 이 활동을 삭제하시겠습니까? libs/ui/src/lib/activities-table/activities-table.component.ts - 278 + 282 @@ -4008,7 +4012,7 @@ apps/client/src/app/pages/public/public-page.html - 151 + 150 @@ -4032,7 +4036,7 @@ apps/client/src/app/pages/public/public-page.html - 168 + 167 @@ -4040,7 +4044,7 @@ 최신 활동 apps/client/src/app/pages/public/public-page.html - 211 + 210 @@ -4052,7 +4056,7 @@ apps/client/src/app/pages/public/public-page.html - 177 + 176 @@ -4064,7 +4068,7 @@ apps/client/src/app/pages/public/public-page.html - 186 + 185 @@ -4124,7 +4128,7 @@ apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 365 + 369 apps/client/src/app/pages/features/features-page.html @@ -4480,7 +4484,7 @@ 대륙 apps/client/src/app/pages/public/public-page.html - 132 + 131 @@ -4496,7 +4500,7 @@ Ghostfolio는 귀하의 재산을 추적할 수 있도록 해줍니다. apps/client/src/app/pages/public/public-page.html - 238 + 237 @@ -4869,7 +4873,7 @@ 멤버십 apps/client/src/app/components/user-detail-dialog/user-detail-dialog.html - 48 + 67 libs/common/src/lib/routes/routes.ts @@ -4993,7 +4997,7 @@ 정말로 이 활동을 삭제하시겠습니까? libs/ui/src/lib/activities-table/activities-table.component.ts - 288 + 292 @@ -5113,7 +5117,7 @@ apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 352 + 356 libs/ui/src/lib/fire-calculator/fire-calculator.component.ts @@ -5157,7 +5161,7 @@ 모두 표시 libs/ui/src/lib/holdings-table/holdings-table.component.html - 216 + 212 @@ -5285,7 +5289,7 @@ 비상자금 apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 164 + 168 apps/client/src/app/pages/features/features-page.html @@ -5361,7 +5365,7 @@ libs/ui/src/lib/portfolio-proportion-chart/portfolio-proportion-chart.component.ts - 437 + 449 @@ -5533,7 +5537,7 @@ 현금 apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 212 + 216 libs/ui/src/lib/i18n.ts @@ -5581,7 +5585,7 @@ 입증 apps/client/src/app/components/user-detail-dialog/user-detail-dialog.html - 35 + 54 @@ -5749,7 +5753,7 @@ apps/client/src/app/pages/public/public-page.html - 196 + 195 libs/ui/src/lib/benchmark/benchmark.component.html @@ -5757,11 +5761,11 @@ libs/ui/src/lib/portfolio-proportion-chart/portfolio-proportion-chart.component.ts - 439 + 451 libs/ui/src/lib/portfolio-proportion-chart/portfolio-proportion-chart.component.ts - 452 + 465 libs/ui/src/lib/top-holdings/top-holdings.component.html @@ -5877,7 +5881,7 @@ 닫기 보유 apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html - 442 + 441 @@ -6354,7 +6358,7 @@ 개인 투자 전략개선하시겠습니까? apps/client/src/app/pages/public/public-page.html - 234 + 233 @@ -6750,7 +6754,7 @@ 역할 apps/client/src/app/components/user-detail-dialog/user-detail-dialog.html - 14 + 33 @@ -6808,6 +6812,10 @@ apps/client/src/app/components/user-account-access/create-or-update-access-dialog/create-or-update-access-dialog.html 68 + + apps/client/src/app/components/user-detail-dialog/user-detail-dialog.html + 127 + apps/client/src/app/pages/accounts/create-or-update-account-dialog/create-or-update-account-dialog.html 107 @@ -7256,7 +7264,7 @@ apps/client/src/app/components/user-detail-dialog/user-detail-dialog.html - 98 + 117 @@ -7504,7 +7512,7 @@ libs/ui/src/lib/treemap-chart/treemap-chart.component.ts - 368 + 375 @@ -7524,11 +7532,11 @@ libs/ui/src/lib/treemap-chart/treemap-chart.component.ts - 368 + 375 libs/ui/src/lib/treemap-chart/treemap-chart.component.ts - 381 + 388 @@ -7632,7 +7640,7 @@ 정말로 이 사용자에 대한 새 보안 토큰을 생성하시겠습니까? apps/client/src/app/components/admin-users/admin-users.component.ts - 241 + 244 @@ -7648,7 +7656,7 @@ 보안 토큰 apps/client/src/app/components/admin-users/admin-users.component.ts - 236 + 239 apps/client/src/app/components/user-account-access/user-account-access.component.ts @@ -7874,8 +7882,8 @@ - Fee Ratio - 수수료 비율 + Fee Ratio (legacy) + 수수료 비율 apps/client/src/app/pages/i18n/i18n-page.html 152 @@ -7897,6 +7905,30 @@ 158 + + Fee Ratio + Fee Ratio + + apps/client/src/app/pages/i18n/i18n-page.html + 161 + + + + The fees do exceed ${thresholdMax}% of your total investment volume (${feeRatio}%) + The fees do exceed ${thresholdMax}% of your total investment volume (${feeRatio}%) + + apps/client/src/app/pages/i18n/i18n-page.html + 163 + + + + The fees do not exceed ${thresholdMax}% of your total investment volume (${feeRatio}%) + The fees do not exceed ${thresholdMax}% of your total investment volume (${feeRatio}%) + + apps/client/src/app/pages/i18n/i18n-page.html + 167 + + Quick Links 빠른 링크 @@ -8277,7 +8309,7 @@ 자산 프로필 관리 apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html - 466 + 465 @@ -8361,7 +8393,7 @@ 수수료 apps/client/src/app/pages/i18n/i18n-page.html - 161 + 170 @@ -8409,7 +8441,7 @@ 지역 시장 클러스터 위험 apps/client/src/app/pages/i18n/i18n-page.html - 163 + 172 @@ -8497,7 +8529,7 @@ 아시아·태평양 apps/client/src/app/pages/i18n/i18n-page.html - 165 + 174 @@ -8505,7 +8537,7 @@ 현재 투자의 아시아 태평양 시장 기여도(${valueRatio}%)가 ${thresholdMax}%를 초과합니다. apps/client/src/app/pages/i18n/i18n-page.html - 167 + 176 @@ -8513,7 +8545,7 @@ 현재 투자의 아시아 태평양 시장 기여도(${valueRatio}%)가 ${thresholdMin}% 미만입니다. apps/client/src/app/pages/i18n/i18n-page.html - 171 + 180 @@ -8521,7 +8553,7 @@ 현재 투자의 아시아 태평양 시장 기여도(${valueRatio}%)가 ${thresholdMin}% 및 ${thresholdMax}% 범위 내에 있습니다. apps/client/src/app/pages/i18n/i18n-page.html - 175 + 184 @@ -8529,7 +8561,7 @@ 신흥시장 apps/client/src/app/pages/i18n/i18n-page.html - 180 + 189 @@ -8537,7 +8569,7 @@ 현재 투자의 신흥 시장 기여도(${valueRatio}%)가 ${thresholdMax}%를 초과합니다. apps/client/src/app/pages/i18n/i18n-page.html - 183 + 192 @@ -8545,7 +8577,7 @@ 현재 투자의 신흥 시장 기여도(${valueRatio}%)가 ${thresholdMin}% 미만입니다. apps/client/src/app/pages/i18n/i18n-page.html - 187 + 196 @@ -8553,7 +8585,7 @@ 현재 투자의 신흥 시장 기여도(${valueRatio}%)가 ${thresholdMin}% 및 ${thresholdMax}% 범위 내에 있습니다. apps/client/src/app/pages/i18n/i18n-page.html - 191 + 200 @@ -8561,7 +8593,7 @@ 유럽 apps/client/src/app/pages/i18n/i18n-page.html - 195 + 204 @@ -8569,7 +8601,7 @@ 현재 투자의 유럽 시장 기여도(${valueRatio}%)가 ${thresholdMax}%를 초과합니다. apps/client/src/app/pages/i18n/i18n-page.html - 197 + 206 @@ -8577,7 +8609,7 @@ 현재 투자의 유럽 시장 기여도(${valueRatio}%)가 ${thresholdMin}% 미만입니다. apps/client/src/app/pages/i18n/i18n-page.html - 201 + 210 @@ -8585,7 +8617,7 @@ 현재 투자의 유럽 시장 기여도(${valueRatio}%)는 ${thresholdMin}% 및 ${thresholdMax}% 범위 내에 있습니다. apps/client/src/app/pages/i18n/i18n-page.html - 205 + 214 @@ -8593,7 +8625,7 @@ 일본 apps/client/src/app/pages/i18n/i18n-page.html - 209 + 218 @@ -8601,7 +8633,7 @@ 현재 투자의 일본 시장 기여도(${valueRatio}%)가 ${thresholdMax}%를 초과합니다. apps/client/src/app/pages/i18n/i18n-page.html - 211 + 220 @@ -8609,7 +8641,7 @@ 현재 투자의 일본 시장 기여도(${valueRatio}%)가 ${thresholdMin}% 미만입니다. apps/client/src/app/pages/i18n/i18n-page.html - 215 + 224 @@ -8617,7 +8649,7 @@ 현재 투자의 일본 시장 기여도(${valueRatio}%)는 ${thresholdMin}% 및 ${thresholdMax}% 범위 내에 있습니다. apps/client/src/app/pages/i18n/i18n-page.html - 219 + 228 @@ -8625,7 +8657,7 @@ 북미 apps/client/src/app/pages/i18n/i18n-page.html - 223 + 232 @@ -8633,7 +8665,7 @@ 현재 투자의 북미 시장 기여도(${valueRatio}%)가 ${thresholdMax}%를 초과합니다. apps/client/src/app/pages/i18n/i18n-page.html - 225 + 234 @@ -8641,7 +8673,7 @@ 현재 투자의 북미 시장 기여도(${valueRatio}%)가 ${thresholdMin}% 미만입니다. apps/client/src/app/pages/i18n/i18n-page.html - 229 + 238 @@ -8649,7 +8681,7 @@ 현재 투자의 북미 시장 기여도(${valueRatio}%)가 ${thresholdMin}% 및 ${thresholdMax}% 범위 내에 있습니다. apps/client/src/app/pages/i18n/i18n-page.html - 233 + 242 @@ -8697,7 +8729,7 @@ 등록일 apps/client/src/app/components/user-detail-dialog/user-detail-dialog.html - 26 + 45 diff --git a/apps/client/src/locales/messages.nl.xlf b/apps/client/src/locales/messages.nl.xlf index d7d0b71e8..c79ecc1d3 100644 --- a/apps/client/src/locales/messages.nl.xlf +++ b/apps/client/src/locales/messages.nl.xlf @@ -272,6 +272,10 @@ apps/client/src/app/components/admin-tag/admin-tag.component.html 78 + + apps/client/src/app/components/user-detail-dialog/user-detail-dialog.html + 22 + libs/ui/src/lib/account-balances/account-balances.component.html 80 @@ -294,7 +298,7 @@ Wil je deze rekening echt verwijderen? libs/ui/src/lib/accounts-table/accounts-table.component.ts - 150 + 148 @@ -630,7 +634,7 @@ Wilt je deze gebruiker echt verwijderen? apps/client/src/app/components/admin-users/admin-users.component.ts - 215 + 218 @@ -666,7 +670,7 @@ apps/client/src/app/components/user-detail-dialog/user-detail-dialog.html - 89 + 108 @@ -722,7 +726,7 @@ apps/client/src/app/pages/public/public-page.html - 242 + 241 apps/client/src/app/pages/resources/personal-finance-tools/product-page.html @@ -774,7 +778,7 @@ Activiteiten beheren apps/client/src/app/components/home-holdings/home-holdings.html - 67 + 65 @@ -890,7 +894,7 @@ Absoluut bruto rendement apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 73 + 77 @@ -898,7 +902,7 @@ Absoluut netto rendement apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 107 + 111 apps/client/src/app/pages/portfolio/analysis/analysis-page.html @@ -910,7 +914,7 @@ Netto rendement apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 123 + 127 apps/client/src/app/pages/portfolio/analysis/analysis-page.html @@ -922,7 +926,7 @@ Totaal Activa apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 149 + 153 @@ -930,7 +934,7 @@ Koopkracht apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 241 + 245 @@ -938,7 +942,7 @@ Netto waarde apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 317 + 321 @@ -946,7 +950,7 @@ Rendement per jaar apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 331 + 335 @@ -974,7 +978,7 @@ apps/client/src/app/pages/public/public-page.html - 114 + 113 @@ -1014,7 +1018,7 @@ Gegevensstoring melden apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html - 451 + 450 @@ -1042,7 +1046,7 @@ Toon alle libs/ui/src/lib/holdings-table/holdings-table.component.html - 216 + 212 @@ -1326,7 +1330,7 @@ apps/client/src/app/components/user-detail-dialog/user-detail-dialog.html - 11 + 30 @@ -1378,7 +1382,7 @@ apps/client/src/app/components/user-detail-dialog/user-detail-dialog.html - 66 + 85 apps/client/src/app/pages/accounts/accounts-page.html @@ -1818,7 +1822,7 @@ apps/client/src/app/pages/public/public-page.html - 151 + 150 @@ -2018,7 +2022,7 @@ apps/client/src/app/components/account-detail-dialog/account-detail-dialog.html - 115 + 113 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html @@ -2042,7 +2046,7 @@ apps/client/src/app/components/user-detail-dialog/user-detail-dialog.html - 75 + 94 apps/client/src/app/pages/portfolio/activities/activities-page.html @@ -2142,7 +2146,7 @@ Continenten apps/client/src/app/pages/public/public-page.html - 132 + 131 @@ -2158,7 +2162,7 @@ Ghostfolio stelt je in staat om je vermogen bij te houden. apps/client/src/app/pages/public/public-page.html - 238 + 237 @@ -2306,7 +2310,7 @@ Wil je deze activiteit echt verwijderen? libs/ui/src/lib/activities-table/activities-table.component.ts - 288 + 292 @@ -2414,7 +2418,7 @@ apps/client/src/app/pages/public/public-page.html - 168 + 167 @@ -2422,7 +2426,7 @@ Latest activities apps/client/src/app/pages/public/public-page.html - 211 + 210 @@ -2442,7 +2446,7 @@ apps/client/src/app/pages/public/public-page.html - 186 + 185 @@ -2454,7 +2458,7 @@ apps/client/src/app/pages/public/public-page.html - 177 + 176 @@ -2486,7 +2490,7 @@ apps/client/src/app/components/user-detail-dialog/user-detail-dialog.html - 53 + 72 @@ -2522,7 +2526,7 @@ apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 352 + 356 libs/ui/src/lib/fire-calculator/fire-calculator.component.ts @@ -2686,7 +2690,7 @@ Uitgesloten van analyse apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 267 + 271 @@ -2730,7 +2734,7 @@ Totaalbedrag apps/client/src/app/components/investment-chart/investment-chart.component.ts - 143 + 146 @@ -2846,7 +2850,7 @@ Contant geld apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 212 + 216 libs/ui/src/lib/i18n.ts @@ -2894,7 +2898,7 @@ Authentication apps/client/src/app/components/user-detail-dialog/user-detail-dialog.html - 35 + 54 @@ -2958,7 +2962,7 @@ Noodfonds apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 164 + 168 apps/client/src/app/pages/features/features-page.html @@ -2978,7 +2982,7 @@ libs/ui/src/lib/portfolio-proportion-chart/portfolio-proportion-chart.component.ts - 437 + 449 @@ -2990,7 +2994,7 @@ apps/client/src/app/pages/public/public-page.html - 196 + 195 libs/ui/src/lib/benchmark/benchmark.component.html @@ -2998,11 +3002,11 @@ libs/ui/src/lib/portfolio-proportion-chart/portfolio-proportion-chart.component.ts - 439 + 451 libs/ui/src/lib/portfolio-proportion-chart/portfolio-proportion-chart.component.ts - 452 + 465 libs/ui/src/lib/top-holdings/top-holdings.component.html @@ -3130,7 +3134,7 @@ apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 365 + 369 apps/client/src/app/pages/features/features-page.html @@ -3222,7 +3226,7 @@ Marktgegevens apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html - 398 + 397 libs/common/src/lib/routes/routes.ts @@ -3634,7 +3638,7 @@ apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 88 + 92 @@ -3798,7 +3802,7 @@ Weet je zeker dat je alle activiteiten wilt verwijderen? libs/ui/src/lib/activities-table/activities-table.component.ts - 278 + 282 @@ -4070,7 +4074,7 @@ Verplichtingen apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 295 + 299 apps/client/src/app/pages/features/features-page.html @@ -4486,7 +4490,7 @@ Assets apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 226 + 230 @@ -4718,7 +4722,7 @@ apps/client/src/app/pages/public/public-page.html - 96 + 95 @@ -5532,7 +5536,7 @@ Lidmaatschap apps/client/src/app/components/user-detail-dialog/user-detail-dialog.html - 48 + 67 libs/common/src/lib/routes/routes.ts @@ -5640,7 +5644,7 @@ Open Source Vermogensbeheer Software apps/client/src/app/pages/i18n/i18n-page.html - 237 + 246 @@ -5720,7 +5724,7 @@ Contant Saldo apps/client/src/app/components/account-detail-dialog/account-detail-dialog.html - 148 + 146 @@ -5876,7 +5880,7 @@ Close Holding apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html - 442 + 441 @@ -6329,7 +6333,7 @@ Wilt u uw persoonlijke belegginngsstrategie verfijnen? apps/client/src/app/pages/public/public-page.html - 234 + 233 @@ -6791,6 +6795,10 @@ apps/client/src/app/components/user-account-access/create-or-update-access-dialog/create-or-update-access-dialog.html 68 + + apps/client/src/app/components/user-detail-dialog/user-detail-dialog.html + 127 + apps/client/src/app/pages/accounts/create-or-update-account-dialog/create-or-update-account-dialog.html 107 @@ -6809,7 +6817,7 @@ Role apps/client/src/app/components/user-detail-dialog/user-detail-dialog.html - 14 + 33 @@ -7215,7 +7223,7 @@ apps/client/src/app/components/user-detail-dialog/user-detail-dialog.html - 98 + 117 @@ -7479,7 +7487,7 @@ libs/ui/src/lib/treemap-chart/treemap-chart.component.ts - 368 + 375 @@ -7499,11 +7507,11 @@ libs/ui/src/lib/treemap-chart/treemap-chart.component.ts - 368 + 375 libs/ui/src/lib/treemap-chart/treemap-chart.component.ts - 381 + 388 @@ -7607,7 +7615,7 @@ Beveiligingstoken apps/client/src/app/components/admin-users/admin-users.component.ts - 236 + 239 apps/client/src/app/components/user-account-access/user-account-access.component.ts @@ -7619,7 +7627,7 @@ Wilt u echt een nieuw beveiligingstoken voor deze gebruiker aanmaken? apps/client/src/app/components/admin-users/admin-users.component.ts - 241 + 244 @@ -7873,8 +7881,8 @@ - Fee Ratio - Vergoedingsverhouding + Fee Ratio (legacy) + Vergoedingsverhouding apps/client/src/app/pages/i18n/i18n-page.html 152 @@ -7896,6 +7904,30 @@ 158 + + Fee Ratio + Fee Ratio + + apps/client/src/app/pages/i18n/i18n-page.html + 161 + + + + The fees do exceed ${thresholdMax}% of your total investment volume (${feeRatio}%) + The fees do exceed ${thresholdMax}% of your total investment volume (${feeRatio}%) + + apps/client/src/app/pages/i18n/i18n-page.html + 163 + + + + The fees do not exceed ${thresholdMax}% of your total investment volume (${feeRatio}%) + The fees do not exceed ${thresholdMax}% of your total investment volume (${feeRatio}%) + + apps/client/src/app/pages/i18n/i18n-page.html + 167 + + Quick Links Snelle koppelingen @@ -8276,7 +8308,7 @@ Beheer activaprofiel apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html - 466 + 465 @@ -8352,7 +8384,7 @@ Kosten apps/client/src/app/pages/i18n/i18n-page.html - 161 + 170 @@ -8400,7 +8432,7 @@ Risico’s van regionale marktclusters apps/client/src/app/pages/i18n/i18n-page.html - 163 + 172 @@ -8496,7 +8528,7 @@ Azië-Pacific apps/client/src/app/pages/i18n/i18n-page.html - 165 + 174 @@ -8504,7 +8536,7 @@ De bijdrage van de Azië-Pacific markt aan je huidige investering (${valueRatio}%) overschrijdt ${thresholdMax}% apps/client/src/app/pages/i18n/i18n-page.html - 167 + 176 @@ -8512,7 +8544,7 @@ De bijdrage van de Azië-Pacific markt aan je huidige investering (${valueRatio}%) ligt onder ${thresholdMin}% apps/client/src/app/pages/i18n/i18n-page.html - 171 + 180 @@ -8520,7 +8552,7 @@ De bijdrage van de Azië-Pacific markt aan je huidige investering (${valueRatio}%) ligt binnen het bereik van ${thresholdMin}% en ${thresholdMax}% apps/client/src/app/pages/i18n/i18n-page.html - 175 + 184 @@ -8528,7 +8560,7 @@ Opkomende markten apps/client/src/app/pages/i18n/i18n-page.html - 180 + 189 @@ -8536,7 +8568,7 @@ De bijdrage van de opkomende markten aan je huidige investering (${valueRatio}%) overschrijdt ${thresholdMax}% apps/client/src/app/pages/i18n/i18n-page.html - 183 + 192 @@ -8544,7 +8576,7 @@ De bijdrage van de opkomende markten aan je huidige investering (${valueRatio}%) ligt onder ${thresholdMin}% apps/client/src/app/pages/i18n/i18n-page.html - 187 + 196 @@ -8552,7 +8584,7 @@ De bijdrage van de opkomende markten aan je huidige investering (${valueRatio}%) ligt binnen het bereik van ${thresholdMin}% en ${thresholdMax}% apps/client/src/app/pages/i18n/i18n-page.html - 191 + 200 @@ -8560,7 +8592,7 @@ Europa apps/client/src/app/pages/i18n/i18n-page.html - 195 + 204 @@ -8568,7 +8600,7 @@ De bijdrage van de Europese markt aan je huidige investering (${valueRatio}%) overschrijdt ${thresholdMax}% apps/client/src/app/pages/i18n/i18n-page.html - 197 + 206 @@ -8576,7 +8608,7 @@ De bijdrage van de Europese markt aan je huidige investering (${valueRatio}%) ligt onder ${thresholdMin}% apps/client/src/app/pages/i18n/i18n-page.html - 201 + 210 @@ -8584,7 +8616,7 @@ De bijdrage van de Europese markt aan je huidige investering (${valueRatio}%) ligt binnen het bereik van ${thresholdMin}% en ${thresholdMax}% apps/client/src/app/pages/i18n/i18n-page.html - 205 + 214 @@ -8592,7 +8624,7 @@ Japan apps/client/src/app/pages/i18n/i18n-page.html - 209 + 218 @@ -8600,7 +8632,7 @@ De bijdrage van de Japanse markt aan je huidige investering (${valueRatio}%) overschrijdt ${thresholdMax}% apps/client/src/app/pages/i18n/i18n-page.html - 211 + 220 @@ -8608,7 +8640,7 @@ De bijdrage van de Japanse markt aan je huidige investering (${valueRatio}%) ligt onder ${thresholdMin}% apps/client/src/app/pages/i18n/i18n-page.html - 215 + 224 @@ -8616,7 +8648,7 @@ De bijdrage van de Japanse markt aan je huidige investering (${valueRatio}%) ligt binnen het bereik van ${thresholdMin}% en ${thresholdMax}% apps/client/src/app/pages/i18n/i18n-page.html - 219 + 228 @@ -8624,7 +8656,7 @@ Noord-Amerika apps/client/src/app/pages/i18n/i18n-page.html - 223 + 232 @@ -8632,7 +8664,7 @@ De bijdrage van de Noord-Amerikaanse markt aan je huidige investering (${valueRatio}%) overschrijdt ${thresholdMax}% apps/client/src/app/pages/i18n/i18n-page.html - 225 + 234 @@ -8640,7 +8672,7 @@ De bijdrage van de Noord-Amerikaanse markt aan je huidige investering (${valueRatio}%) ligt onder ${thresholdMin}% apps/client/src/app/pages/i18n/i18n-page.html - 229 + 238 @@ -8648,7 +8680,7 @@ De bijdrage van de Noord-Amerikaanse markt aan je huidige investering (${valueRatio}%) ligt binnen het bereik van ${thresholdMin}% en ${thresholdMax}% apps/client/src/app/pages/i18n/i18n-page.html - 233 + 242 @@ -8696,7 +8728,7 @@ Registration Date apps/client/src/app/components/user-detail-dialog/user-detail-dialog.html - 26 + 45 diff --git a/apps/client/src/locales/messages.pl.xlf b/apps/client/src/locales/messages.pl.xlf index a94a76d2f..a7c72f3ca 100644 --- a/apps/client/src/locales/messages.pl.xlf +++ b/apps/client/src/locales/messages.pl.xlf @@ -549,6 +549,10 @@ apps/client/src/app/components/admin-tag/admin-tag.component.html 78 + + apps/client/src/app/components/user-detail-dialog/user-detail-dialog.html + 22 + libs/ui/src/lib/account-balances/account-balances.component.html 80 @@ -571,7 +575,7 @@ Czy na pewno chcesz usunąć to konto? libs/ui/src/lib/accounts-table/accounts-table.component.ts - 150 + 148 @@ -747,7 +751,7 @@ apps/client/src/app/pages/public/public-page.html - 96 + 95 @@ -911,7 +915,7 @@ apps/client/src/app/components/user-detail-dialog/user-detail-dialog.html - 53 + 72 @@ -931,7 +935,7 @@ apps/client/src/app/pages/public/public-page.html - 114 + 113 @@ -1311,7 +1315,7 @@ Czy na pewno chcesz usunąć tego użytkownika? apps/client/src/app/components/admin-users/admin-users.component.ts - 215 + 218 @@ -1347,7 +1351,7 @@ apps/client/src/app/components/user-detail-dialog/user-detail-dialog.html - 89 + 108 @@ -1503,7 +1507,7 @@ Zarządzaj Aktywnościami apps/client/src/app/components/home-holdings/home-holdings.html - 67 + 65 @@ -1655,7 +1659,7 @@ Całkowita Kwota apps/client/src/app/components/investment-chart/investment-chart.component.ts - 143 + 146 @@ -1767,7 +1771,7 @@ Bezwzględne Osiągi Brutto apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 73 + 77 @@ -1779,7 +1783,7 @@ apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 88 + 92 @@ -1787,7 +1791,7 @@ Bezwzględne Osiągi Netto apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 107 + 111 apps/client/src/app/pages/portfolio/analysis/analysis-page.html @@ -1799,7 +1803,7 @@ Osiągi Netto apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 123 + 127 apps/client/src/app/pages/portfolio/analysis/analysis-page.html @@ -1811,7 +1815,7 @@ Suma Aktywów apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 149 + 153 @@ -1819,7 +1823,7 @@ Aktywa apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 226 + 230 @@ -1827,7 +1831,7 @@ Siła Nabywcza apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 241 + 245 @@ -1835,7 +1839,7 @@ Wykluczone z Analizy apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 267 + 271 @@ -1843,7 +1847,7 @@ Pasywa (Zobowiązania Finansowe) apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 295 + 299 apps/client/src/app/pages/features/features-page.html @@ -1855,7 +1859,7 @@ Wartość Netto apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 317 + 321 @@ -1863,7 +1867,7 @@ Osiągi w Ujęciu Rocznym apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 331 + 335 @@ -1915,7 +1919,7 @@ Zgłoś Błąd Danych apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html - 451 + 450 @@ -2415,7 +2419,7 @@ apps/client/src/app/components/user-detail-dialog/user-detail-dialog.html - 11 + 30 @@ -2607,7 +2611,7 @@ apps/client/src/app/components/user-detail-dialog/user-detail-dialog.html - 66 + 85 apps/client/src/app/pages/accounts/accounts-page.html @@ -2699,7 +2703,7 @@ Dane Rynkowe apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html - 398 + 397 libs/common/src/lib/routes/routes.ts @@ -3071,7 +3075,7 @@ apps/client/src/app/pages/public/public-page.html - 242 + 241 apps/client/src/app/pages/resources/personal-finance-tools/product-page.html @@ -3187,7 +3191,7 @@ Oprogramowanie Open Source do Zarządzania Majątkiem apps/client/src/app/pages/i18n/i18n-page.html - 237 + 246 @@ -3615,7 +3619,7 @@ apps/client/src/app/components/account-detail-dialog/account-detail-dialog.html - 115 + 113 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html @@ -3639,7 +3643,7 @@ apps/client/src/app/components/user-detail-dialog/user-detail-dialog.html - 75 + 94 apps/client/src/app/pages/portfolio/activities/activities-page.html @@ -3659,7 +3663,7 @@ Czy na pewno chcesz usunąć te aktywności? libs/ui/src/lib/activities-table/activities-table.component.ts - 278 + 282 @@ -3975,7 +3979,7 @@ apps/client/src/app/pages/public/public-page.html - 151 + 150 @@ -3999,7 +4003,7 @@ apps/client/src/app/pages/public/public-page.html - 168 + 167 @@ -4007,7 +4011,7 @@ Latest activities apps/client/src/app/pages/public/public-page.html - 211 + 210 @@ -4019,7 +4023,7 @@ apps/client/src/app/pages/public/public-page.html - 177 + 176 @@ -4031,7 +4035,7 @@ apps/client/src/app/pages/public/public-page.html - 186 + 185 @@ -4091,7 +4095,7 @@ apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 365 + 369 apps/client/src/app/pages/features/features-page.html @@ -4447,7 +4451,7 @@ Kontynenty apps/client/src/app/pages/public/public-page.html - 132 + 131 @@ -4463,7 +4467,7 @@ Ghostfolio umożliwia śledzenie wartości swojego majątku. apps/client/src/app/pages/public/public-page.html - 238 + 237 @@ -4824,7 +4828,7 @@ Członkostwo apps/client/src/app/components/user-detail-dialog/user-detail-dialog.html - 48 + 67 libs/common/src/lib/routes/routes.ts @@ -4940,7 +4944,7 @@ Czy na pewno chcesz usunąć tę działalność? libs/ui/src/lib/activities-table/activities-table.component.ts - 288 + 292 @@ -5044,7 +5048,7 @@ apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 352 + 356 libs/ui/src/lib/fire-calculator/fire-calculator.component.ts @@ -5088,7 +5092,7 @@ Pokaż wszystko libs/ui/src/lib/holdings-table/holdings-table.component.html - 216 + 212 @@ -5216,7 +5220,7 @@ Fundusz Rezerwowy apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 164 + 168 apps/client/src/app/pages/features/features-page.html @@ -5292,7 +5296,7 @@ libs/ui/src/lib/portfolio-proportion-chart/portfolio-proportion-chart.component.ts - 437 + 449 @@ -5464,7 +5468,7 @@ Gotówka apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 212 + 216 libs/ui/src/lib/i18n.ts @@ -5512,7 +5516,7 @@ Authentication apps/client/src/app/components/user-detail-dialog/user-detail-dialog.html - 35 + 54 @@ -5680,7 +5684,7 @@ apps/client/src/app/pages/public/public-page.html - 196 + 195 libs/ui/src/lib/benchmark/benchmark.component.html @@ -5688,11 +5692,11 @@ libs/ui/src/lib/portfolio-proportion-chart/portfolio-proportion-chart.component.ts - 439 + 451 libs/ui/src/lib/portfolio-proportion-chart/portfolio-proportion-chart.component.ts - 452 + 465 libs/ui/src/lib/top-holdings/top-holdings.component.html @@ -5720,7 +5724,7 @@ Salda Gotówkowe apps/client/src/app/components/account-detail-dialog/account-detail-dialog.html - 148 + 146 @@ -5876,7 +5880,7 @@ Close Holding apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html - 442 + 441 @@ -6329,7 +6333,7 @@ Chcesz udoskonalić swoją osobistą strategię inwestycyjną? apps/client/src/app/pages/public/public-page.html - 234 + 233 @@ -6791,6 +6795,10 @@ apps/client/src/app/components/user-account-access/create-or-update-access-dialog/create-or-update-access-dialog.html 68 + + apps/client/src/app/components/user-detail-dialog/user-detail-dialog.html + 127 + apps/client/src/app/pages/accounts/create-or-update-account-dialog/create-or-update-account-dialog.html 107 @@ -6809,7 +6817,7 @@ Role apps/client/src/app/components/user-detail-dialog/user-detail-dialog.html - 14 + 33 @@ -7215,7 +7223,7 @@ apps/client/src/app/components/user-detail-dialog/user-detail-dialog.html - 98 + 117 @@ -7479,7 +7487,7 @@ libs/ui/src/lib/treemap-chart/treemap-chart.component.ts - 368 + 375 @@ -7499,11 +7507,11 @@ libs/ui/src/lib/treemap-chart/treemap-chart.component.ts - 368 + 375 libs/ui/src/lib/treemap-chart/treemap-chart.component.ts - 381 + 388 @@ -7607,7 +7615,7 @@ Token bezpieczeństwa apps/client/src/app/components/admin-users/admin-users.component.ts - 236 + 239 apps/client/src/app/components/user-account-access/user-account-access.component.ts @@ -7619,7 +7627,7 @@ Czy napewno chcesz wygenerować nowy token bezpieczeństwa dla tego użytkownika? apps/client/src/app/components/admin-users/admin-users.component.ts - 241 + 244 @@ -7873,8 +7881,8 @@ - Fee Ratio - Stosunek opłat + Fee Ratio (legacy) + Stosunek opłat apps/client/src/app/pages/i18n/i18n-page.html 152 @@ -7896,6 +7904,30 @@ 158 + + Fee Ratio + Fee Ratio + + apps/client/src/app/pages/i18n/i18n-page.html + 161 + + + + The fees do exceed ${thresholdMax}% of your total investment volume (${feeRatio}%) + The fees do exceed ${thresholdMax}% of your total investment volume (${feeRatio}%) + + apps/client/src/app/pages/i18n/i18n-page.html + 163 + + + + The fees do not exceed ${thresholdMax}% of your total investment volume (${feeRatio}%) + The fees do not exceed ${thresholdMax}% of your total investment volume (${feeRatio}%) + + apps/client/src/app/pages/i18n/i18n-page.html + 167 + + Quick Links Szybkie linki @@ -8276,7 +8308,7 @@ Zarządzaj profilem aktywów apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html - 466 + 465 @@ -8352,7 +8384,7 @@ Fees apps/client/src/app/pages/i18n/i18n-page.html - 161 + 170 @@ -8400,7 +8432,7 @@ Regional Market Cluster Risks apps/client/src/app/pages/i18n/i18n-page.html - 163 + 172 @@ -8496,7 +8528,7 @@ Asia-Pacific apps/client/src/app/pages/i18n/i18n-page.html - 165 + 174 @@ -8504,7 +8536,7 @@ The Asia-Pacific market contribution of your current investment (${valueRatio}%) exceeds ${thresholdMax}% apps/client/src/app/pages/i18n/i18n-page.html - 167 + 176 @@ -8512,7 +8544,7 @@ The Asia-Pacific market contribution of your current investment (${valueRatio}%) is below ${thresholdMin}% apps/client/src/app/pages/i18n/i18n-page.html - 171 + 180 @@ -8520,7 +8552,7 @@ The Asia-Pacific market contribution of your current investment (${valueRatio}%) is within the range of ${thresholdMin}% and ${thresholdMax}% apps/client/src/app/pages/i18n/i18n-page.html - 175 + 184 @@ -8528,7 +8560,7 @@ Emerging Markets apps/client/src/app/pages/i18n/i18n-page.html - 180 + 189 @@ -8536,7 +8568,7 @@ The Emerging Markets contribution of your current investment (${valueRatio}%) exceeds ${thresholdMax}% apps/client/src/app/pages/i18n/i18n-page.html - 183 + 192 @@ -8544,7 +8576,7 @@ The Emerging Markets contribution of your current investment (${valueRatio}%) is below ${thresholdMin}% apps/client/src/app/pages/i18n/i18n-page.html - 187 + 196 @@ -8552,7 +8584,7 @@ The Emerging Markets contribution of your current investment (${valueRatio}%) is within the range of ${thresholdMin}% and ${thresholdMax}% apps/client/src/app/pages/i18n/i18n-page.html - 191 + 200 @@ -8560,7 +8592,7 @@ Europe apps/client/src/app/pages/i18n/i18n-page.html - 195 + 204 @@ -8568,7 +8600,7 @@ The Europe market contribution of your current investment (${valueRatio}%) exceeds ${thresholdMax}% apps/client/src/app/pages/i18n/i18n-page.html - 197 + 206 @@ -8576,7 +8608,7 @@ The Europe market contribution of your current investment (${valueRatio}%) is below ${thresholdMin}% apps/client/src/app/pages/i18n/i18n-page.html - 201 + 210 @@ -8584,7 +8616,7 @@ The Europe market contribution of your current investment (${valueRatio}%) is within the range of ${thresholdMin}% and ${thresholdMax}% apps/client/src/app/pages/i18n/i18n-page.html - 205 + 214 @@ -8592,7 +8624,7 @@ Japan apps/client/src/app/pages/i18n/i18n-page.html - 209 + 218 @@ -8600,7 +8632,7 @@ The Japan market contribution of your current investment (${valueRatio}%) exceeds ${thresholdMax}% apps/client/src/app/pages/i18n/i18n-page.html - 211 + 220 @@ -8608,7 +8640,7 @@ The Japan market contribution of your current investment (${valueRatio}%) is below ${thresholdMin}% apps/client/src/app/pages/i18n/i18n-page.html - 215 + 224 @@ -8616,7 +8648,7 @@ The Japan market contribution of your current investment (${valueRatio}%) is within the range of ${thresholdMin}% and ${thresholdMax}% apps/client/src/app/pages/i18n/i18n-page.html - 219 + 228 @@ -8624,7 +8656,7 @@ North America apps/client/src/app/pages/i18n/i18n-page.html - 223 + 232 @@ -8632,7 +8664,7 @@ The North America market contribution of your current investment (${valueRatio}%) exceeds ${thresholdMax}% apps/client/src/app/pages/i18n/i18n-page.html - 225 + 234 @@ -8640,7 +8672,7 @@ The North America market contribution of your current investment (${valueRatio}%) is below ${thresholdMin}% apps/client/src/app/pages/i18n/i18n-page.html - 229 + 238 @@ -8648,7 +8680,7 @@ The North America market contribution of your current investment (${valueRatio}%) is within the range of ${thresholdMin}% and ${thresholdMax}% apps/client/src/app/pages/i18n/i18n-page.html - 233 + 242 @@ -8696,7 +8728,7 @@ Registration Date apps/client/src/app/components/user-detail-dialog/user-detail-dialog.html - 26 + 45 diff --git a/apps/client/src/locales/messages.pt.xlf b/apps/client/src/locales/messages.pt.xlf index 2bcd7c401..55d622ed9 100644 --- a/apps/client/src/locales/messages.pt.xlf +++ b/apps/client/src/locales/messages.pt.xlf @@ -328,6 +328,10 @@ apps/client/src/app/components/admin-tag/admin-tag.component.html 78 + + apps/client/src/app/components/user-detail-dialog/user-detail-dialog.html + 22 + libs/ui/src/lib/account-balances/account-balances.component.html 80 @@ -350,7 +354,7 @@ Pretende realmente eliminar esta conta? libs/ui/src/lib/accounts-table/accounts-table.component.ts - 150 + 148 @@ -710,7 +714,7 @@ Deseja realmente excluir este utilizador? apps/client/src/app/components/admin-users/admin-users.component.ts - 215 + 218 @@ -746,7 +750,7 @@ apps/client/src/app/components/user-detail-dialog/user-detail-dialog.html - 89 + 108 @@ -878,7 +882,7 @@ Gerir Atividades apps/client/src/app/components/home-holdings/home-holdings.html - 67 + 65 @@ -946,7 +950,7 @@ Valor Total apps/client/src/app/components/investment-chart/investment-chart.component.ts - 143 + 146 @@ -1058,7 +1062,7 @@ Desempenho Bruto Absoluto apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 73 + 77 @@ -1066,7 +1070,7 @@ Desempenho Líquido Absoluto apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 107 + 111 apps/client/src/app/pages/portfolio/analysis/analysis-page.html @@ -1078,7 +1082,7 @@ Desempenho Líquido apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 123 + 127 apps/client/src/app/pages/portfolio/analysis/analysis-page.html @@ -1090,7 +1094,7 @@ Ativos Totais apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 149 + 153 @@ -1098,7 +1102,7 @@ Poder de Compra apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 241 + 245 @@ -1106,7 +1110,7 @@ Excluído da Análise apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 267 + 271 @@ -1114,7 +1118,7 @@ Valor Líquido apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 317 + 321 @@ -1122,7 +1126,7 @@ Desempenho Anual apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 331 + 335 @@ -1198,7 +1202,7 @@ apps/client/src/app/components/user-detail-dialog/user-detail-dialog.html - 53 + 72 @@ -1218,7 +1222,7 @@ apps/client/src/app/pages/public/public-page.html - 114 + 113 @@ -1258,7 +1262,7 @@ Dados do Relatório com Problema apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html - 451 + 450 @@ -1286,7 +1290,7 @@ Mostrar tudo libs/ui/src/lib/holdings-table/holdings-table.component.html - 216 + 212 @@ -1666,7 +1670,7 @@ apps/client/src/app/components/user-detail-dialog/user-detail-dialog.html - 11 + 30 @@ -1718,7 +1722,7 @@ apps/client/src/app/components/user-detail-dialog/user-detail-dialog.html - 66 + 85 apps/client/src/app/pages/accounts/accounts-page.html @@ -2022,7 +2026,7 @@ apps/client/src/app/components/account-detail-dialog/account-detail-dialog.html - 115 + 113 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html @@ -2046,7 +2050,7 @@ apps/client/src/app/components/user-detail-dialog/user-detail-dialog.html - 75 + 94 apps/client/src/app/pages/portfolio/activities/activities-page.html @@ -2282,7 +2286,7 @@ apps/client/src/app/pages/public/public-page.html - 151 + 150 @@ -2306,7 +2310,7 @@ apps/client/src/app/pages/public/public-page.html - 168 + 167 @@ -2314,7 +2318,7 @@ Latest activities apps/client/src/app/pages/public/public-page.html - 211 + 210 @@ -2326,7 +2330,7 @@ apps/client/src/app/pages/public/public-page.html - 177 + 176 @@ -2338,7 +2342,7 @@ apps/client/src/app/pages/public/public-page.html - 186 + 185 @@ -2482,7 +2486,7 @@ Continentes apps/client/src/app/pages/public/public-page.html - 132 + 131 @@ -2498,7 +2502,7 @@ O Ghostfolio permite-lhe estar a par e gerir a sua riqueza. apps/client/src/app/pages/public/public-page.html - 238 + 237 @@ -2526,7 +2530,7 @@ apps/client/src/app/pages/public/public-page.html - 242 + 241 apps/client/src/app/pages/resources/personal-finance-tools/product-page.html @@ -2698,7 +2702,7 @@ Deseja realmente eliminar esta atividade? libs/ui/src/lib/activities-table/activities-table.component.ts - 288 + 292 @@ -2750,7 +2754,7 @@ apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 352 + 356 libs/ui/src/lib/fire-calculator/fire-calculator.component.ts @@ -2826,7 +2830,7 @@ Fundo de Emergência apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 164 + 168 apps/client/src/app/pages/features/features-page.html @@ -2846,7 +2850,7 @@ libs/ui/src/lib/portfolio-proportion-chart/portfolio-proportion-chart.component.ts - 437 + 449 @@ -2894,7 +2898,7 @@ Dinheiro apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 212 + 216 libs/ui/src/lib/i18n.ts @@ -2942,7 +2946,7 @@ Authentication apps/client/src/app/components/user-detail-dialog/user-detail-dialog.html - 35 + 54 @@ -3074,7 +3078,7 @@ apps/client/src/app/pages/public/public-page.html - 196 + 195 libs/ui/src/lib/benchmark/benchmark.component.html @@ -3082,11 +3086,11 @@ libs/ui/src/lib/portfolio-proportion-chart/portfolio-proportion-chart.component.ts - 439 + 451 libs/ui/src/lib/portfolio-proportion-chart/portfolio-proportion-chart.component.ts - 452 + 465 libs/ui/src/lib/top-holdings/top-holdings.component.html @@ -3130,7 +3134,7 @@ Dados de Mercado apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html - 398 + 397 libs/common/src/lib/routes/routes.ts @@ -3194,7 +3198,7 @@ apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 365 + 369 apps/client/src/app/pages/features/features-page.html @@ -3634,7 +3638,7 @@ apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 88 + 92 @@ -3798,7 +3802,7 @@ Deseja mesmo eliminar estas atividades? libs/ui/src/lib/activities-table/activities-table.component.ts - 278 + 282 @@ -4070,7 +4074,7 @@ Responsabilidades apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 295 + 299 apps/client/src/app/pages/features/features-page.html @@ -4486,7 +4490,7 @@ Ativos apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 226 + 230 @@ -4718,7 +4722,7 @@ apps/client/src/app/pages/public/public-page.html - 96 + 95 @@ -5532,7 +5536,7 @@ Associação apps/client/src/app/components/user-detail-dialog/user-detail-dialog.html - 48 + 67 libs/common/src/lib/routes/routes.ts @@ -5640,7 +5644,7 @@ Software de gerenciamento de patrimônio de código aberto apps/client/src/app/pages/i18n/i18n-page.html - 237 + 246 @@ -5720,7 +5724,7 @@ Saldos de caixa apps/client/src/app/components/account-detail-dialog/account-detail-dialog.html - 148 + 146 @@ -5876,7 +5880,7 @@ Close Holding apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html - 442 + 441 @@ -6329,7 +6333,7 @@ Você gostaria de refinar seu estratégia de investimento pessoal? apps/client/src/app/pages/public/public-page.html - 234 + 233 @@ -6791,6 +6795,10 @@ apps/client/src/app/components/user-account-access/create-or-update-access-dialog/create-or-update-access-dialog.html 68 + + apps/client/src/app/components/user-detail-dialog/user-detail-dialog.html + 127 + apps/client/src/app/pages/accounts/create-or-update-account-dialog/create-or-update-account-dialog.html 107 @@ -6809,7 +6817,7 @@ Role apps/client/src/app/components/user-detail-dialog/user-detail-dialog.html - 14 + 33 @@ -7215,7 +7223,7 @@ apps/client/src/app/components/user-detail-dialog/user-detail-dialog.html - 98 + 117 @@ -7479,7 +7487,7 @@ libs/ui/src/lib/treemap-chart/treemap-chart.component.ts - 368 + 375 @@ -7499,11 +7507,11 @@ libs/ui/src/lib/treemap-chart/treemap-chart.component.ts - 368 + 375 libs/ui/src/lib/treemap-chart/treemap-chart.component.ts - 381 + 388 @@ -7607,7 +7615,7 @@ Security token apps/client/src/app/components/admin-users/admin-users.component.ts - 236 + 239 apps/client/src/app/components/user-account-access/user-account-access.component.ts @@ -7619,7 +7627,7 @@ Do you really want to generate a new security token for this user? apps/client/src/app/components/admin-users/admin-users.component.ts - 241 + 244 @@ -7873,8 +7881,8 @@ - Fee Ratio - Fee Ratio + Fee Ratio (legacy) + Fee Ratio (legacy) apps/client/src/app/pages/i18n/i18n-page.html 152 @@ -7896,6 +7904,30 @@ 158 + + Fee Ratio + Fee Ratio + + apps/client/src/app/pages/i18n/i18n-page.html + 161 + + + + The fees do exceed ${thresholdMax}% of your total investment volume (${feeRatio}%) + The fees do exceed ${thresholdMax}% of your total investment volume (${feeRatio}%) + + apps/client/src/app/pages/i18n/i18n-page.html + 163 + + + + The fees do not exceed ${thresholdMax}% of your total investment volume (${feeRatio}%) + The fees do not exceed ${thresholdMax}% of your total investment volume (${feeRatio}%) + + apps/client/src/app/pages/i18n/i18n-page.html + 167 + + Quick Links Links rápidos @@ -8276,7 +8308,7 @@ Gerenciar perfil de ativos apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html - 466 + 465 @@ -8352,7 +8384,7 @@ Tarifas apps/client/src/app/pages/i18n/i18n-page.html - 161 + 170 @@ -8400,7 +8432,7 @@ Riscos de cluster de mercado regional apps/client/src/app/pages/i18n/i18n-page.html - 163 + 172 @@ -8496,7 +8528,7 @@ Ásia-Pacífico apps/client/src/app/pages/i18n/i18n-page.html - 165 + 174 @@ -8504,7 +8536,7 @@ The Asia-Pacific market contribution of your current investment (${valueRatio}%) exceeds ${thresholdMax}% apps/client/src/app/pages/i18n/i18n-page.html - 167 + 176 @@ -8512,7 +8544,7 @@ The Asia-Pacific market contribution of your current investment (${valueRatio}%) is below ${thresholdMin}% apps/client/src/app/pages/i18n/i18n-page.html - 171 + 180 @@ -8520,7 +8552,7 @@ The Asia-Pacific market contribution of your current investment (${valueRatio}%) is within the range of ${thresholdMin}% and ${thresholdMax}% apps/client/src/app/pages/i18n/i18n-page.html - 175 + 184 @@ -8528,7 +8560,7 @@ Mercados Emergentes apps/client/src/app/pages/i18n/i18n-page.html - 180 + 189 @@ -8536,7 +8568,7 @@ The Emerging Markets contribution of your current investment (${valueRatio}%) exceeds ${thresholdMax}% apps/client/src/app/pages/i18n/i18n-page.html - 183 + 192 @@ -8544,7 +8576,7 @@ The Emerging Markets contribution of your current investment (${valueRatio}%) is below ${thresholdMin}% apps/client/src/app/pages/i18n/i18n-page.html - 187 + 196 @@ -8552,7 +8584,7 @@ The Emerging Markets contribution of your current investment (${valueRatio}%) is within the range of ${thresholdMin}% and ${thresholdMax}% apps/client/src/app/pages/i18n/i18n-page.html - 191 + 200 @@ -8560,7 +8592,7 @@ Europa apps/client/src/app/pages/i18n/i18n-page.html - 195 + 204 @@ -8568,7 +8600,7 @@ The Europe market contribution of your current investment (${valueRatio}%) exceeds ${thresholdMax}% apps/client/src/app/pages/i18n/i18n-page.html - 197 + 206 @@ -8576,7 +8608,7 @@ The Europe market contribution of your current investment (${valueRatio}%) is below ${thresholdMin}% apps/client/src/app/pages/i18n/i18n-page.html - 201 + 210 @@ -8584,7 +8616,7 @@ The Europe market contribution of your current investment (${valueRatio}%) is within the range of ${thresholdMin}% and ${thresholdMax}% apps/client/src/app/pages/i18n/i18n-page.html - 205 + 214 @@ -8592,7 +8624,7 @@ Japão apps/client/src/app/pages/i18n/i18n-page.html - 209 + 218 @@ -8600,7 +8632,7 @@ The Japan market contribution of your current investment (${valueRatio}%) exceeds ${thresholdMax}% apps/client/src/app/pages/i18n/i18n-page.html - 211 + 220 @@ -8608,7 +8640,7 @@ The Japan market contribution of your current investment (${valueRatio}%) is below ${thresholdMin}% apps/client/src/app/pages/i18n/i18n-page.html - 215 + 224 @@ -8616,7 +8648,7 @@ The Japan market contribution of your current investment (${valueRatio}%) is within the range of ${thresholdMin}% and ${thresholdMax}% apps/client/src/app/pages/i18n/i18n-page.html - 219 + 228 @@ -8624,7 +8656,7 @@ América do Norte apps/client/src/app/pages/i18n/i18n-page.html - 223 + 232 @@ -8632,7 +8664,7 @@ The North America market contribution of your current investment (${valueRatio}%) exceeds ${thresholdMax}% apps/client/src/app/pages/i18n/i18n-page.html - 225 + 234 @@ -8640,7 +8672,7 @@ The North America market contribution of your current investment (${valueRatio}%) is below ${thresholdMin}% apps/client/src/app/pages/i18n/i18n-page.html - 229 + 238 @@ -8648,7 +8680,7 @@ The North America market contribution of your current investment (${valueRatio}%) is within the range of ${thresholdMin}% and ${thresholdMax}% apps/client/src/app/pages/i18n/i18n-page.html - 233 + 242 @@ -8696,7 +8728,7 @@ Registration Date apps/client/src/app/components/user-detail-dialog/user-detail-dialog.html - 26 + 45 diff --git a/apps/client/src/locales/messages.tr.xlf b/apps/client/src/locales/messages.tr.xlf index 421ef3855..841da4721 100644 --- a/apps/client/src/locales/messages.tr.xlf +++ b/apps/client/src/locales/messages.tr.xlf @@ -509,6 +509,10 @@ apps/client/src/app/components/admin-tag/admin-tag.component.html 78 + + apps/client/src/app/components/user-detail-dialog/user-detail-dialog.html + 22 + libs/ui/src/lib/account-balances/account-balances.component.html 80 @@ -531,7 +535,7 @@ Bu hesabı silmeyi gerçekten istiyor musunuz? libs/ui/src/lib/accounts-table/accounts-table.component.ts - 150 + 148 @@ -711,7 +715,7 @@ apps/client/src/app/pages/public/public-page.html - 96 + 95 @@ -843,7 +847,7 @@ apps/client/src/app/components/user-detail-dialog/user-detail-dialog.html - 53 + 72 @@ -863,7 +867,7 @@ apps/client/src/app/pages/public/public-page.html - 114 + 113 @@ -1179,7 +1183,7 @@ Bu kullanıcıyı silmeyi gerçekten istiyor musunuz? apps/client/src/app/components/admin-users/admin-users.component.ts - 215 + 218 @@ -1215,7 +1219,7 @@ apps/client/src/app/components/user-detail-dialog/user-detail-dialog.html - 89 + 108 @@ -1371,7 +1375,7 @@ İşlemleri Yönet apps/client/src/app/components/home-holdings/home-holdings.html - 67 + 65 @@ -1523,7 +1527,7 @@ Toplam Tutar apps/client/src/app/components/investment-chart/investment-chart.component.ts - 143 + 146 @@ -1635,7 +1639,7 @@ Toplam Brüt Performans apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 73 + 77 @@ -1643,7 +1647,7 @@ Toplam Net Performans apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 107 + 111 apps/client/src/app/pages/portfolio/analysis/analysis-page.html @@ -1655,7 +1659,7 @@ Net Performans apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 123 + 127 apps/client/src/app/pages/portfolio/analysis/analysis-page.html @@ -1667,7 +1671,7 @@ Toplam Varlıklar apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 149 + 153 @@ -1675,7 +1679,7 @@ Varlıklar apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 226 + 230 @@ -1683,7 +1687,7 @@ Alım Limiti apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 241 + 245 @@ -1691,7 +1695,7 @@ Analize Dahil Edilmemiştir. apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 267 + 271 @@ -1699,7 +1703,7 @@ Yükümlülükler apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 295 + 299 apps/client/src/app/pages/features/features-page.html @@ -1711,7 +1715,7 @@ Toplam Varlık apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 317 + 321 @@ -1719,7 +1723,7 @@ Yıllıklandırılmış Performans apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 331 + 335 @@ -1775,7 +1779,7 @@ apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 88 + 92 @@ -1783,7 +1787,7 @@ Rapor Veri Sorunu apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html - 451 + 450 @@ -2203,7 +2207,7 @@ apps/client/src/app/components/user-detail-dialog/user-detail-dialog.html - 66 + 85 apps/client/src/app/pages/accounts/accounts-page.html @@ -2263,7 +2267,7 @@ Piyasa Verileri apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html - 398 + 397 libs/common/src/lib/routes/routes.ts @@ -2647,7 +2651,7 @@ apps/client/src/app/pages/public/public-page.html - 242 + 241 apps/client/src/app/pages/resources/personal-finance-tools/product-page.html @@ -3115,7 +3119,7 @@ apps/client/src/app/components/account-detail-dialog/account-detail-dialog.html - 115 + 113 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html @@ -3139,7 +3143,7 @@ apps/client/src/app/components/user-detail-dialog/user-detail-dialog.html - 75 + 94 apps/client/src/app/pages/portfolio/activities/activities-page.html @@ -3159,7 +3163,7 @@ Tüm işlemlerinizi silmeyi gerçekten istiyor musunuz? libs/ui/src/lib/activities-table/activities-table.component.ts - 278 + 282 @@ -3459,7 +3463,7 @@ apps/client/src/app/pages/public/public-page.html - 151 + 150 @@ -3483,7 +3487,7 @@ apps/client/src/app/pages/public/public-page.html - 168 + 167 @@ -3491,7 +3495,7 @@ Latest activities apps/client/src/app/pages/public/public-page.html - 211 + 210 @@ -3503,7 +3507,7 @@ apps/client/src/app/pages/public/public-page.html - 177 + 176 @@ -3515,7 +3519,7 @@ apps/client/src/app/pages/public/public-page.html - 186 + 185 @@ -3575,7 +3579,7 @@ apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 365 + 369 apps/client/src/app/pages/features/features-page.html @@ -3931,7 +3935,7 @@ Kıtalar apps/client/src/app/pages/public/public-page.html - 132 + 131 @@ -3947,7 +3951,7 @@ Ghostfolio, varlıklarınızı takip etmenizi sağlar. apps/client/src/app/pages/public/public-page.html - 238 + 237 @@ -4568,7 +4572,7 @@ apps/client/src/app/components/user-detail-dialog/user-detail-dialog.html - 11 + 30 @@ -4664,7 +4668,7 @@ TBu işlemi silmeyi gerçekten istiyor musunuz? libs/ui/src/lib/activities-table/activities-table.component.ts - 288 + 292 @@ -4740,7 +4744,7 @@ apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 352 + 356 libs/ui/src/lib/fire-calculator/fire-calculator.component.ts @@ -4784,7 +4788,7 @@ Tümünü göster libs/ui/src/lib/holdings-table/holdings-table.component.html - 216 + 212 @@ -4912,7 +4916,7 @@ Acil Durum Fonu apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 164 + 168 apps/client/src/app/pages/features/features-page.html @@ -4988,7 +4992,7 @@ libs/ui/src/lib/portfolio-proportion-chart/portfolio-proportion-chart.component.ts - 437 + 449 @@ -5144,7 +5148,7 @@ Nakit apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 212 + 216 libs/ui/src/lib/i18n.ts @@ -5192,7 +5196,7 @@ Authentication apps/client/src/app/components/user-detail-dialog/user-detail-dialog.html - 35 + 54 @@ -5324,7 +5328,7 @@ apps/client/src/app/pages/public/public-page.html - 196 + 195 libs/ui/src/lib/benchmark/benchmark.component.html @@ -5332,11 +5336,11 @@ libs/ui/src/lib/portfolio-proportion-chart/portfolio-proportion-chart.component.ts - 439 + 451 libs/ui/src/lib/portfolio-proportion-chart/portfolio-proportion-chart.component.ts - 452 + 465 libs/ui/src/lib/top-holdings/top-holdings.component.html @@ -5532,7 +5536,7 @@ Üyelik apps/client/src/app/components/user-detail-dialog/user-detail-dialog.html - 48 + 67 libs/common/src/lib/routes/routes.ts @@ -5640,7 +5644,7 @@ Açık Kaynak Varlık Yönetim Yazılımı apps/client/src/app/pages/i18n/i18n-page.html - 237 + 246 @@ -5720,7 +5724,7 @@ Nakit Bakiyeleri apps/client/src/app/components/account-detail-dialog/account-detail-dialog.html - 148 + 146 @@ -5876,7 +5880,7 @@ Close Holding apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html - 442 + 441 @@ -6329,7 +6333,7 @@ Senin özel yatırım stratejinizi iyileştirmek ister misin? apps/client/src/app/pages/public/public-page.html - 234 + 233 @@ -6791,6 +6795,10 @@ apps/client/src/app/components/user-account-access/create-or-update-access-dialog/create-or-update-access-dialog.html 68 + + apps/client/src/app/components/user-detail-dialog/user-detail-dialog.html + 127 + apps/client/src/app/pages/accounts/create-or-update-account-dialog/create-or-update-account-dialog.html 107 @@ -6809,7 +6817,7 @@ Role apps/client/src/app/components/user-detail-dialog/user-detail-dialog.html - 14 + 33 @@ -7215,7 +7223,7 @@ apps/client/src/app/components/user-detail-dialog/user-detail-dialog.html - 98 + 117 @@ -7479,7 +7487,7 @@ libs/ui/src/lib/treemap-chart/treemap-chart.component.ts - 368 + 375 @@ -7499,11 +7507,11 @@ libs/ui/src/lib/treemap-chart/treemap-chart.component.ts - 368 + 375 libs/ui/src/lib/treemap-chart/treemap-chart.component.ts - 381 + 388 @@ -7607,7 +7615,7 @@ Güvenlik belirteci apps/client/src/app/components/admin-users/admin-users.component.ts - 236 + 239 apps/client/src/app/components/user-account-access/user-account-access.component.ts @@ -7619,7 +7627,7 @@ Bu kullanıcı için yeni bir güvenlik belirteci oluşturmak istediğinize emin misiniz? apps/client/src/app/components/admin-users/admin-users.component.ts - 241 + 244 @@ -7873,8 +7881,8 @@ - Fee Ratio - Ücret Oranı + Fee Ratio (legacy) + Ücret Oranı apps/client/src/app/pages/i18n/i18n-page.html 152 @@ -7896,6 +7904,30 @@ 158 + + Fee Ratio + Fee Ratio + + apps/client/src/app/pages/i18n/i18n-page.html + 161 + + + + The fees do exceed ${thresholdMax}% of your total investment volume (${feeRatio}%) + The fees do exceed ${thresholdMax}% of your total investment volume (${feeRatio}%) + + apps/client/src/app/pages/i18n/i18n-page.html + 163 + + + + The fees do not exceed ${thresholdMax}% of your total investment volume (${feeRatio}%) + The fees do not exceed ${thresholdMax}% of your total investment volume (${feeRatio}%) + + apps/client/src/app/pages/i18n/i18n-page.html + 167 + + Quick Links Hızlı Bağlantılar @@ -8276,7 +8308,7 @@ Manage Asset Profile apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html - 466 + 465 @@ -8352,7 +8384,7 @@ Fees apps/client/src/app/pages/i18n/i18n-page.html - 161 + 170 @@ -8400,7 +8432,7 @@ Regional Market Cluster Risks apps/client/src/app/pages/i18n/i18n-page.html - 163 + 172 @@ -8496,7 +8528,7 @@ Asya-Pasifik apps/client/src/app/pages/i18n/i18n-page.html - 165 + 174 @@ -8504,7 +8536,7 @@ The Asia-Pacific market contribution of your current investment (${valueRatio}%) exceeds ${thresholdMax}% apps/client/src/app/pages/i18n/i18n-page.html - 167 + 176 @@ -8512,7 +8544,7 @@ The Asia-Pacific market contribution of your current investment (${valueRatio}%) is below ${thresholdMin}% apps/client/src/app/pages/i18n/i18n-page.html - 171 + 180 @@ -8520,7 +8552,7 @@ The Asia-Pacific market contribution of your current investment (${valueRatio}%) is within the range of ${thresholdMin}% and ${thresholdMax}% apps/client/src/app/pages/i18n/i18n-page.html - 175 + 184 @@ -8528,7 +8560,7 @@ Gelişmekte Olan Piyasalar apps/client/src/app/pages/i18n/i18n-page.html - 180 + 189 @@ -8536,7 +8568,7 @@ The Emerging Markets contribution of your current investment (${valueRatio}%) exceeds ${thresholdMax}% apps/client/src/app/pages/i18n/i18n-page.html - 183 + 192 @@ -8544,7 +8576,7 @@ The Emerging Markets contribution of your current investment (${valueRatio}%) is below ${thresholdMin}% apps/client/src/app/pages/i18n/i18n-page.html - 187 + 196 @@ -8552,7 +8584,7 @@ The Emerging Markets contribution of your current investment (${valueRatio}%) is within the range of ${thresholdMin}% and ${thresholdMax}% apps/client/src/app/pages/i18n/i18n-page.html - 191 + 200 @@ -8560,7 +8592,7 @@ Avrupa apps/client/src/app/pages/i18n/i18n-page.html - 195 + 204 @@ -8568,7 +8600,7 @@ The Europe market contribution of your current investment (${valueRatio}%) exceeds ${thresholdMax}% apps/client/src/app/pages/i18n/i18n-page.html - 197 + 206 @@ -8576,7 +8608,7 @@ The Europe market contribution of your current investment (${valueRatio}%) is below ${thresholdMin}% apps/client/src/app/pages/i18n/i18n-page.html - 201 + 210 @@ -8584,7 +8616,7 @@ The Europe market contribution of your current investment (${valueRatio}%) is within the range of ${thresholdMin}% and ${thresholdMax}% apps/client/src/app/pages/i18n/i18n-page.html - 205 + 214 @@ -8592,7 +8624,7 @@ Japonya apps/client/src/app/pages/i18n/i18n-page.html - 209 + 218 @@ -8600,7 +8632,7 @@ The Japan market contribution of your current investment (${valueRatio}%) exceeds ${thresholdMax}% apps/client/src/app/pages/i18n/i18n-page.html - 211 + 220 @@ -8608,7 +8640,7 @@ The Japan market contribution of your current investment (${valueRatio}%) is below ${thresholdMin}% apps/client/src/app/pages/i18n/i18n-page.html - 215 + 224 @@ -8616,7 +8648,7 @@ The Japan market contribution of your current investment (${valueRatio}%) is within the range of ${thresholdMin}% and ${thresholdMax}% apps/client/src/app/pages/i18n/i18n-page.html - 219 + 228 @@ -8624,7 +8656,7 @@ Kuzey Amerika apps/client/src/app/pages/i18n/i18n-page.html - 223 + 232 @@ -8632,7 +8664,7 @@ The North America market contribution of your current investment (${valueRatio}%) exceeds ${thresholdMax}% apps/client/src/app/pages/i18n/i18n-page.html - 225 + 234 @@ -8640,7 +8672,7 @@ The North America market contribution of your current investment (${valueRatio}%) is below ${thresholdMin}% apps/client/src/app/pages/i18n/i18n-page.html - 229 + 238 @@ -8648,7 +8680,7 @@ The North America market contribution of your current investment (${valueRatio}%) is within the range of ${thresholdMin}% and ${thresholdMax}% apps/client/src/app/pages/i18n/i18n-page.html - 233 + 242 @@ -8696,7 +8728,7 @@ Registration Date apps/client/src/app/components/user-detail-dialog/user-detail-dialog.html - 26 + 45 diff --git a/apps/client/src/locales/messages.uk.xlf b/apps/client/src/locales/messages.uk.xlf index 2fc389030..27c55d792 100644 --- a/apps/client/src/locales/messages.uk.xlf +++ b/apps/client/src/locales/messages.uk.xlf @@ -419,7 +419,7 @@ Баланс готівки apps/client/src/app/components/account-detail-dialog/account-detail-dialog.html - 148 + 146 @@ -641,6 +641,10 @@ apps/client/src/app/components/admin-tag/admin-tag.component.html 78 + + apps/client/src/app/components/user-detail-dialog/user-detail-dialog.html + 22 + libs/ui/src/lib/account-balances/account-balances.component.html 80 @@ -663,7 +667,7 @@ Ви дійсно хочете видалити цей обліковий запис? libs/ui/src/lib/accounts-table/accounts-table.component.ts - 150 + 148 @@ -847,7 +851,7 @@ apps/client/src/app/pages/public/public-page.html - 96 + 95 @@ -1043,7 +1047,7 @@ apps/client/src/app/components/user-detail-dialog/user-detail-dialog.html - 53 + 72 @@ -1063,7 +1067,7 @@ apps/client/src/app/pages/public/public-page.html - 114 + 113 @@ -1607,7 +1611,7 @@ Ви дійсно хочете видалити цього користувача? apps/client/src/app/components/admin-users/admin-users.component.ts - 215 + 218 @@ -1619,7 +1623,7 @@ apps/client/src/app/components/user-detail-dialog/user-detail-dialog.html - 89 + 108 @@ -1631,7 +1635,7 @@ apps/client/src/app/components/user-detail-dialog/user-detail-dialog.html - 98 + 117 @@ -1879,7 +1883,7 @@ apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 88 + 92 @@ -1903,7 +1907,7 @@ Повідомити про збій даних apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html - 451 + 450 @@ -1943,7 +1947,7 @@ Керування діяльністю apps/client/src/app/components/home-holdings/home-holdings.html - 67 + 65 @@ -2095,7 +2099,7 @@ Загальна сума apps/client/src/app/components/investment-chart/investment-chart.component.ts - 143 + 146 @@ -2187,7 +2191,7 @@ Абсолютний валовий дохід apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 73 + 77 @@ -2195,7 +2199,7 @@ Абсолютний чистий прибуток apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 107 + 111 apps/client/src/app/pages/portfolio/analysis/analysis-page.html @@ -2207,7 +2211,7 @@ Чистий прибуток apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 123 + 127 apps/client/src/app/pages/portfolio/analysis/analysis-page.html @@ -2219,7 +2223,7 @@ Загальні активи apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 149 + 153 @@ -2227,7 +2231,7 @@ Активи apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 226 + 230 @@ -2235,7 +2239,7 @@ Купівельна спроможність apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 241 + 245 @@ -2243,7 +2247,7 @@ Виключено з аналізу apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 267 + 271 @@ -2251,7 +2255,7 @@ Зобов’язання apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 295 + 299 apps/client/src/app/pages/features/features-page.html @@ -2263,7 +2267,7 @@ Чиста вартість apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 317 + 321 @@ -2271,7 +2275,7 @@ Річна доходність apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 331 + 335 @@ -2663,7 +2667,7 @@ apps/client/src/app/components/user-detail-dialog/user-detail-dialog.html - 11 + 30 @@ -3211,7 +3215,7 @@ apps/client/src/app/components/user-detail-dialog/user-detail-dialog.html - 66 + 85 apps/client/src/app/pages/accounts/accounts-page.html @@ -3311,7 +3315,7 @@ Ринкові дані apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html - 398 + 397 libs/common/src/lib/routes/routes.ts @@ -3716,7 +3720,7 @@ apps/client/src/app/pages/public/public-page.html - 242 + 241 apps/client/src/app/pages/resources/personal-finance-tools/product-page.html @@ -3840,7 +3844,7 @@ Програмне забезпечення управління багатством з відкритим кодом apps/client/src/app/pages/i18n/i18n-page.html - 237 + 246 @@ -4276,7 +4280,7 @@ apps/client/src/app/components/account-detail-dialog/account-detail-dialog.html - 115 + 113 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html @@ -4300,7 +4304,7 @@ apps/client/src/app/components/user-detail-dialog/user-detail-dialog.html - 75 + 94 apps/client/src/app/pages/portfolio/activities/activities-page.html @@ -4664,7 +4668,7 @@ apps/client/src/app/pages/public/public-page.html - 151 + 150 @@ -4688,7 +4692,7 @@ apps/client/src/app/pages/public/public-page.html - 168 + 167 @@ -4696,7 +4700,7 @@ Latest activities apps/client/src/app/pages/public/public-page.html - 211 + 210 @@ -4708,7 +4712,7 @@ apps/client/src/app/pages/public/public-page.html - 177 + 176 @@ -4720,7 +4724,7 @@ apps/client/src/app/pages/public/public-page.html - 186 + 185 @@ -4796,7 +4800,7 @@ apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 365 + 369 apps/client/src/app/pages/features/features-page.html @@ -4868,7 +4872,7 @@ Close Holding apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html - 442 + 441 @@ -5248,7 +5252,7 @@ Континенти apps/client/src/app/pages/public/public-page.html - 132 + 131 @@ -5256,7 +5260,7 @@ Чи хотіли б ви удосконалити вашу особисту інвестиційну стратегію? apps/client/src/app/pages/public/public-page.html - 234 + 233 @@ -5272,7 +5276,7 @@ Ghostfolio надає можливість вам стежити за вашим багатством. apps/client/src/app/pages/public/public-page.html - 238 + 237 @@ -6003,7 +6007,7 @@ Членство apps/client/src/app/components/user-detail-dialog/user-detail-dialog.html - 48 + 67 libs/common/src/lib/routes/routes.ts @@ -6135,7 +6139,7 @@ Ви дійсно хочете видалити ці дії? libs/ui/src/lib/activities-table/activities-table.component.ts - 278 + 282 @@ -6143,7 +6147,7 @@ Ви дійсно хочете видалити цю активність? libs/ui/src/lib/activities-table/activities-table.component.ts - 288 + 292 @@ -6383,7 +6387,7 @@ apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 352 + 356 libs/ui/src/lib/fire-calculator/fire-calculator.component.ts @@ -6443,7 +6447,7 @@ Показати все libs/ui/src/lib/holdings-table/holdings-table.component.html - 216 + 212 @@ -6637,6 +6641,10 @@ apps/client/src/app/components/user-account-access/create-or-update-access-dialog/create-or-update-access-dialog.html 68 + + apps/client/src/app/components/user-detail-dialog/user-detail-dialog.html + 127 + apps/client/src/app/pages/accounts/create-or-update-account-dialog/create-or-update-account-dialog.html 107 @@ -6679,7 +6687,7 @@ Резервний фонд apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 164 + 168 apps/client/src/app/pages/features/features-page.html @@ -6747,7 +6755,7 @@ libs/ui/src/lib/portfolio-proportion-chart/portfolio-proportion-chart.component.ts - 437 + 449 @@ -6863,7 +6871,7 @@ Role apps/client/src/app/components/user-detail-dialog/user-detail-dialog.html - 14 + 33 @@ -6943,7 +6951,7 @@ Готівка apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 212 + 216 libs/ui/src/lib/i18n.ts @@ -6999,7 +7007,7 @@ Authentication apps/client/src/app/components/user-detail-dialog/user-detail-dialog.html - 35 + 54 @@ -7339,7 +7347,7 @@ apps/client/src/app/pages/public/public-page.html - 196 + 195 libs/ui/src/lib/benchmark/benchmark.component.html @@ -7347,11 +7355,11 @@ libs/ui/src/lib/portfolio-proportion-chart/portfolio-proportion-chart.component.ts - 439 + 451 libs/ui/src/lib/portfolio-proportion-chart/portfolio-proportion-chart.component.ts - 452 + 465 libs/ui/src/lib/top-holdings/top-holdings.component.html @@ -7479,7 +7487,7 @@ libs/ui/src/lib/treemap-chart/treemap-chart.component.ts - 368 + 375 @@ -7499,11 +7507,11 @@ libs/ui/src/lib/treemap-chart/treemap-chart.component.ts - 368 + 375 libs/ui/src/lib/treemap-chart/treemap-chart.component.ts - 381 + 388 @@ -7607,7 +7615,7 @@ Security token apps/client/src/app/components/admin-users/admin-users.component.ts - 236 + 239 apps/client/src/app/components/user-account-access/user-account-access.component.ts @@ -7619,7 +7627,7 @@ Do you really want to generate a new security token for this user? apps/client/src/app/components/admin-users/admin-users.component.ts - 241 + 244 @@ -7873,8 +7881,8 @@ - Fee Ratio - Fee Ratio + Fee Ratio (legacy) + Fee Ratio (legacy) apps/client/src/app/pages/i18n/i18n-page.html 152 @@ -7896,6 +7904,30 @@ 158 + + Fee Ratio + Fee Ratio + + apps/client/src/app/pages/i18n/i18n-page.html + 161 + + + + The fees do exceed ${thresholdMax}% of your total investment volume (${feeRatio}%) + The fees do exceed ${thresholdMax}% of your total investment volume (${feeRatio}%) + + apps/client/src/app/pages/i18n/i18n-page.html + 163 + + + + The fees do not exceed ${thresholdMax}% of your total investment volume (${feeRatio}%) + The fees do not exceed ${thresholdMax}% of your total investment volume (${feeRatio}%) + + apps/client/src/app/pages/i18n/i18n-page.html + 167 + + Quick Links Quick Links @@ -8276,7 +8308,7 @@ Manage Asset Profile apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html - 466 + 465 @@ -8352,7 +8384,7 @@ Fees apps/client/src/app/pages/i18n/i18n-page.html - 161 + 170 @@ -8400,7 +8432,7 @@ Regional Market Cluster Risks apps/client/src/app/pages/i18n/i18n-page.html - 163 + 172 @@ -8496,7 +8528,7 @@ Asia-Pacific apps/client/src/app/pages/i18n/i18n-page.html - 165 + 174 @@ -8504,7 +8536,7 @@ The Asia-Pacific market contribution of your current investment (${valueRatio}%) exceeds ${thresholdMax}% apps/client/src/app/pages/i18n/i18n-page.html - 167 + 176 @@ -8512,7 +8544,7 @@ The Asia-Pacific market contribution of your current investment (${valueRatio}%) is below ${thresholdMin}% apps/client/src/app/pages/i18n/i18n-page.html - 171 + 180 @@ -8520,7 +8552,7 @@ The Asia-Pacific market contribution of your current investment (${valueRatio}%) is within the range of ${thresholdMin}% and ${thresholdMax}% apps/client/src/app/pages/i18n/i18n-page.html - 175 + 184 @@ -8528,7 +8560,7 @@ Emerging Markets apps/client/src/app/pages/i18n/i18n-page.html - 180 + 189 @@ -8536,7 +8568,7 @@ The Emerging Markets contribution of your current investment (${valueRatio}%) exceeds ${thresholdMax}% apps/client/src/app/pages/i18n/i18n-page.html - 183 + 192 @@ -8544,7 +8576,7 @@ The Emerging Markets contribution of your current investment (${valueRatio}%) is below ${thresholdMin}% apps/client/src/app/pages/i18n/i18n-page.html - 187 + 196 @@ -8552,7 +8584,7 @@ The Emerging Markets contribution of your current investment (${valueRatio}%) is within the range of ${thresholdMin}% and ${thresholdMax}% apps/client/src/app/pages/i18n/i18n-page.html - 191 + 200 @@ -8560,7 +8592,7 @@ Europe apps/client/src/app/pages/i18n/i18n-page.html - 195 + 204 @@ -8568,7 +8600,7 @@ The Europe market contribution of your current investment (${valueRatio}%) exceeds ${thresholdMax}% apps/client/src/app/pages/i18n/i18n-page.html - 197 + 206 @@ -8576,7 +8608,7 @@ The Europe market contribution of your current investment (${valueRatio}%) is below ${thresholdMin}% apps/client/src/app/pages/i18n/i18n-page.html - 201 + 210 @@ -8584,7 +8616,7 @@ The Europe market contribution of your current investment (${valueRatio}%) is within the range of ${thresholdMin}% and ${thresholdMax}% apps/client/src/app/pages/i18n/i18n-page.html - 205 + 214 @@ -8592,7 +8624,7 @@ Japan apps/client/src/app/pages/i18n/i18n-page.html - 209 + 218 @@ -8600,7 +8632,7 @@ The Japan market contribution of your current investment (${valueRatio}%) exceeds ${thresholdMax}% apps/client/src/app/pages/i18n/i18n-page.html - 211 + 220 @@ -8608,7 +8640,7 @@ The Japan market contribution of your current investment (${valueRatio}%) is below ${thresholdMin}% apps/client/src/app/pages/i18n/i18n-page.html - 215 + 224 @@ -8616,7 +8648,7 @@ The Japan market contribution of your current investment (${valueRatio}%) is within the range of ${thresholdMin}% and ${thresholdMax}% apps/client/src/app/pages/i18n/i18n-page.html - 219 + 228 @@ -8624,7 +8656,7 @@ North America apps/client/src/app/pages/i18n/i18n-page.html - 223 + 232 @@ -8632,7 +8664,7 @@ The North America market contribution of your current investment (${valueRatio}%) exceeds ${thresholdMax}% apps/client/src/app/pages/i18n/i18n-page.html - 225 + 234 @@ -8640,7 +8672,7 @@ The North America market contribution of your current investment (${valueRatio}%) is below ${thresholdMin}% apps/client/src/app/pages/i18n/i18n-page.html - 229 + 238 @@ -8648,7 +8680,7 @@ The North America market contribution of your current investment (${valueRatio}%) is within the range of ${thresholdMin}% and ${thresholdMax}% apps/client/src/app/pages/i18n/i18n-page.html - 233 + 242 @@ -8696,7 +8728,7 @@ Registration Date apps/client/src/app/components/user-detail-dialog/user-detail-dialog.html - 26 + 45 diff --git a/apps/client/src/locales/messages.xlf b/apps/client/src/locales/messages.xlf index a6907698d..d15b93002 100644 --- a/apps/client/src/locales/messages.xlf +++ b/apps/client/src/locales/messages.xlf @@ -312,7 +312,7 @@ Cash Balances apps/client/src/app/components/account-detail-dialog/account-detail-dialog.html - 148 + 146 @@ -527,6 +527,10 @@ apps/client/src/app/components/admin-tag/admin-tag.component.html 78 + + apps/client/src/app/components/user-detail-dialog/user-detail-dialog.html + 22 + libs/ui/src/lib/account-balances/account-balances.component.html 80 @@ -548,7 +552,7 @@ Do you really want to delete this account? libs/ui/src/lib/accounts-table/accounts-table.component.ts - 150 + 148 @@ -708,7 +712,7 @@ apps/client/src/app/pages/public/public-page.html - 96 + 95 @@ -878,7 +882,7 @@ apps/client/src/app/components/user-detail-dialog/user-detail-dialog.html - 53 + 72 @@ -897,7 +901,7 @@ apps/client/src/app/pages/public/public-page.html - 114 + 113 @@ -1236,7 +1240,7 @@ Do you really want to delete this user? apps/client/src/app/components/admin-users/admin-users.component.ts - 215 + 218 @@ -1269,7 +1273,7 @@ apps/client/src/app/components/user-detail-dialog/user-detail-dialog.html - 89 + 108 @@ -1412,7 +1416,7 @@ Manage Activities apps/client/src/app/components/home-holdings/home-holdings.html - 67 + 65 @@ -1548,7 +1552,7 @@ Total Amount apps/client/src/app/components/investment-chart/investment-chart.component.ts - 143 + 146 @@ -1653,7 +1657,7 @@ Absolute Gross Performance apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 73 + 77 @@ -1664,14 +1668,14 @@ apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 88 + 92 Absolute Net Performance apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 107 + 111 apps/client/src/app/pages/portfolio/analysis/analysis-page.html @@ -1682,7 +1686,7 @@ Net Performance apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 123 + 127 apps/client/src/app/pages/portfolio/analysis/analysis-page.html @@ -1693,35 +1697,35 @@ Total Assets apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 149 + 153 Assets apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 226 + 230 Buying Power apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 241 + 245 Excluded from Analysis apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 267 + 271 Liabilities apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 295 + 299 apps/client/src/app/pages/features/features-page.html @@ -1732,14 +1736,14 @@ Net Worth apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 317 + 321 Annualized Performance apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 331 + 335 @@ -1786,7 +1790,7 @@ Report Data Glitch apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html - 451 + 450 @@ -2240,7 +2244,7 @@ apps/client/src/app/components/user-detail-dialog/user-detail-dialog.html - 11 + 30 @@ -2418,7 +2422,7 @@ apps/client/src/app/components/user-detail-dialog/user-detail-dialog.html - 66 + 85 apps/client/src/app/pages/accounts/accounts-page.html @@ -2501,7 +2505,7 @@ Market Data apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html - 398 + 397 libs/common/src/lib/routes/routes.ts @@ -2850,7 +2854,7 @@ apps/client/src/app/pages/public/public-page.html - 242 + 241 apps/client/src/app/pages/resources/personal-finance-tools/product-page.html @@ -2960,7 +2964,7 @@ Open Source Wealth Management Software apps/client/src/app/pages/i18n/i18n-page.html - 237 + 246 @@ -3344,7 +3348,7 @@ apps/client/src/app/components/account-detail-dialog/account-detail-dialog.html - 115 + 113 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html @@ -3368,7 +3372,7 @@ apps/client/src/app/components/user-detail-dialog/user-detail-dialog.html - 75 + 94 apps/client/src/app/pages/portfolio/activities/activities-page.html @@ -3387,7 +3391,7 @@ Do you really want to delete these activities? libs/ui/src/lib/activities-table/activities-table.component.ts - 278 + 282 @@ -3669,7 +3673,7 @@ apps/client/src/app/pages/public/public-page.html - 151 + 150 @@ -3691,14 +3695,14 @@ apps/client/src/app/pages/public/public-page.html - 168 + 167 Latest activities apps/client/src/app/pages/public/public-page.html - 211 + 210 @@ -3709,7 +3713,7 @@ apps/client/src/app/pages/public/public-page.html - 177 + 176 @@ -3720,7 +3724,7 @@ apps/client/src/app/pages/public/public-page.html - 186 + 185 @@ -3774,7 +3778,7 @@ apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 365 + 369 apps/client/src/app/pages/features/features-page.html @@ -4095,7 +4099,7 @@ Continents apps/client/src/app/pages/public/public-page.html - 132 + 131 @@ -4109,7 +4113,7 @@ Ghostfolio empowers you to keep track of your wealth. apps/client/src/app/pages/public/public-page.html - 238 + 237 @@ -4448,7 +4452,7 @@ Membership apps/client/src/app/components/user-detail-dialog/user-detail-dialog.html - 48 + 67 libs/common/src/lib/routes/routes.ts @@ -4559,7 +4563,7 @@ Do you really want to delete this activity? libs/ui/src/lib/activities-table/activities-table.component.ts - 288 + 292 @@ -4665,7 +4669,7 @@ apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 352 + 356 libs/ui/src/lib/fire-calculator/fire-calculator.component.ts @@ -4706,7 +4710,7 @@ Show all libs/ui/src/lib/holdings-table/holdings-table.component.html - 216 + 212 @@ -4825,7 +4829,7 @@ Emergency Fund apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 164 + 168 apps/client/src/app/pages/features/features-page.html @@ -4893,7 +4897,7 @@ libs/ui/src/lib/portfolio-proportion-chart/portfolio-proportion-chart.component.ts - 437 + 449 @@ -5042,7 +5046,7 @@ Cash apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 212 + 216 libs/ui/src/lib/i18n.ts @@ -5085,7 +5089,7 @@ Authentication apps/client/src/app/components/user-detail-dialog/user-detail-dialog.html - 35 + 54 @@ -5233,7 +5237,7 @@ apps/client/src/app/pages/public/public-page.html - 196 + 195 libs/ui/src/lib/benchmark/benchmark.component.html @@ -5241,11 +5245,11 @@ libs/ui/src/lib/portfolio-proportion-chart/portfolio-proportion-chart.component.ts - 439 + 451 libs/ui/src/lib/portfolio-proportion-chart/portfolio-proportion-chart.component.ts - 452 + 465 libs/ui/src/lib/top-holdings/top-holdings.component.html @@ -5348,7 +5352,7 @@ Close Holding apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html - 442 + 441 @@ -5773,7 +5777,7 @@ Would you like to refine your personal investment strategy? apps/client/src/app/pages/public/public-page.html - 234 + 233 @@ -6133,7 +6137,7 @@ Role apps/client/src/app/components/user-detail-dialog/user-detail-dialog.html - 14 + 33 @@ -6187,6 +6191,10 @@ apps/client/src/app/components/user-account-access/create-or-update-access-dialog/create-or-update-access-dialog.html 68 + + apps/client/src/app/components/user-detail-dialog/user-detail-dialog.html + 127 + apps/client/src/app/pages/accounts/create-or-update-account-dialog/create-or-update-account-dialog.html 107 @@ -6588,7 +6596,7 @@ apps/client/src/app/components/user-detail-dialog/user-detail-dialog.html - 98 + 117 @@ -6811,7 +6819,7 @@ libs/ui/src/lib/treemap-chart/treemap-chart.component.ts - 368 + 375 @@ -6830,11 +6838,11 @@ libs/ui/src/lib/treemap-chart/treemap-chart.component.ts - 368 + 375 libs/ui/src/lib/treemap-chart/treemap-chart.component.ts - 381 + 388 @@ -6925,7 +6933,7 @@ Do you really want to generate a new security token for this user? apps/client/src/app/components/admin-users/admin-users.component.ts - 241 + 244 @@ -6939,7 +6947,7 @@ Security token apps/client/src/app/components/admin-users/admin-users.component.ts - 236 + 239 apps/client/src/app/components/user-account-access/user-account-access.component.ts @@ -7141,7 +7149,7 @@ - Fee Ratio + Fee Ratio (legacy) apps/client/src/app/pages/i18n/i18n-page.html 152 @@ -7161,6 +7169,27 @@ 158 + + Fee Ratio + + apps/client/src/app/pages/i18n/i18n-page.html + 161 + + + + The fees do exceed ${thresholdMax}% of your total investment volume (${feeRatio}%) + + apps/client/src/app/pages/i18n/i18n-page.html + 163 + + + + The fees do not exceed ${thresholdMax}% of your total investment volume (${feeRatio}%) + + apps/client/src/app/pages/i18n/i18n-page.html + 167 + + Quick Links @@ -7499,7 +7528,7 @@ Manage Asset Profile apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html - 466 + 465 @@ -7573,7 +7602,7 @@ Fees apps/client/src/app/pages/i18n/i18n-page.html - 161 + 170 @@ -7615,7 +7644,7 @@ Regional Market Cluster Risks apps/client/src/app/pages/i18n/i18n-page.html - 163 + 172 @@ -7692,140 +7721,140 @@ Asia-Pacific apps/client/src/app/pages/i18n/i18n-page.html - 165 + 174 The Asia-Pacific market contribution of your current investment (${valueRatio}%) exceeds ${thresholdMax}% apps/client/src/app/pages/i18n/i18n-page.html - 167 + 176 The Asia-Pacific market contribution of your current investment (${valueRatio}%) is below ${thresholdMin}% apps/client/src/app/pages/i18n/i18n-page.html - 171 + 180 The Asia-Pacific market contribution of your current investment (${valueRatio}%) is within the range of ${thresholdMin}% and ${thresholdMax}% apps/client/src/app/pages/i18n/i18n-page.html - 175 + 184 Emerging Markets apps/client/src/app/pages/i18n/i18n-page.html - 180 + 189 The Emerging Markets contribution of your current investment (${valueRatio}%) exceeds ${thresholdMax}% apps/client/src/app/pages/i18n/i18n-page.html - 183 + 192 The Emerging Markets contribution of your current investment (${valueRatio}%) is below ${thresholdMin}% apps/client/src/app/pages/i18n/i18n-page.html - 187 + 196 The Emerging Markets contribution of your current investment (${valueRatio}%) is within the range of ${thresholdMin}% and ${thresholdMax}% apps/client/src/app/pages/i18n/i18n-page.html - 191 + 200 Europe apps/client/src/app/pages/i18n/i18n-page.html - 195 + 204 The Europe market contribution of your current investment (${valueRatio}%) exceeds ${thresholdMax}% apps/client/src/app/pages/i18n/i18n-page.html - 197 + 206 The Europe market contribution of your current investment (${valueRatio}%) is below ${thresholdMin}% apps/client/src/app/pages/i18n/i18n-page.html - 201 + 210 The Europe market contribution of your current investment (${valueRatio}%) is within the range of ${thresholdMin}% and ${thresholdMax}% apps/client/src/app/pages/i18n/i18n-page.html - 205 + 214 Japan apps/client/src/app/pages/i18n/i18n-page.html - 209 + 218 The Japan market contribution of your current investment (${valueRatio}%) exceeds ${thresholdMax}% apps/client/src/app/pages/i18n/i18n-page.html - 211 + 220 The Japan market contribution of your current investment (${valueRatio}%) is below ${thresholdMin}% apps/client/src/app/pages/i18n/i18n-page.html - 215 + 224 The Japan market contribution of your current investment (${valueRatio}%) is within the range of ${thresholdMin}% and ${thresholdMax}% apps/client/src/app/pages/i18n/i18n-page.html - 219 + 228 North America apps/client/src/app/pages/i18n/i18n-page.html - 223 + 232 The North America market contribution of your current investment (${valueRatio}%) exceeds ${thresholdMax}% apps/client/src/app/pages/i18n/i18n-page.html - 225 + 234 The North America market contribution of your current investment (${valueRatio}%) is below ${thresholdMin}% apps/client/src/app/pages/i18n/i18n-page.html - 229 + 238 The North America market contribution of your current investment (${valueRatio}%) is within the range of ${thresholdMin}% and ${thresholdMax}% apps/client/src/app/pages/i18n/i18n-page.html - 233 + 242 @@ -7868,7 +7897,7 @@ Registration Date apps/client/src/app/components/user-detail-dialog/user-detail-dialog.html - 26 + 45 diff --git a/apps/client/src/locales/messages.zh.xlf b/apps/client/src/locales/messages.zh.xlf index 7ec9d85a0..08d4f3d43 100644 --- a/apps/client/src/locales/messages.zh.xlf +++ b/apps/client/src/locales/messages.zh.xlf @@ -336,7 +336,7 @@ 现金余额 apps/client/src/app/components/account-detail-dialog/account-detail-dialog.html - 148 + 146 @@ -558,6 +558,10 @@ apps/client/src/app/components/admin-tag/admin-tag.component.html 78 + + apps/client/src/app/components/user-detail-dialog/user-detail-dialog.html + 22 + libs/ui/src/lib/account-balances/account-balances.component.html 80 @@ -580,7 +584,7 @@ 您确定要删除此账户吗? libs/ui/src/lib/accounts-table/accounts-table.component.ts - 150 + 148 @@ -756,7 +760,7 @@ apps/client/src/app/pages/public/public-page.html - 96 + 95 @@ -920,7 +924,7 @@ apps/client/src/app/components/user-detail-dialog/user-detail-dialog.html - 53 + 72 @@ -940,7 +944,7 @@ apps/client/src/app/pages/public/public-page.html - 114 + 113 @@ -1320,7 +1324,7 @@ 您真的要删除该用户吗? apps/client/src/app/components/admin-users/admin-users.component.ts - 215 + 218 @@ -1356,7 +1360,7 @@ apps/client/src/app/components/user-detail-dialog/user-detail-dialog.html - 89 + 108 @@ -1512,7 +1516,7 @@ 管理活动 apps/client/src/app/components/home-holdings/home-holdings.html - 67 + 65 @@ -1664,7 +1668,7 @@ 总金额 apps/client/src/app/components/investment-chart/investment-chart.component.ts - 143 + 146 @@ -1776,7 +1780,7 @@ 绝对总业绩 apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 73 + 77 @@ -1788,7 +1792,7 @@ apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 88 + 92 @@ -1796,7 +1800,7 @@ 绝对净绩效 apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 107 + 111 apps/client/src/app/pages/portfolio/analysis/analysis-page.html @@ -1808,7 +1812,7 @@ 净绩效 apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 123 + 127 apps/client/src/app/pages/portfolio/analysis/analysis-page.html @@ -1820,7 +1824,7 @@ 总资产 apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 149 + 153 @@ -1828,7 +1832,7 @@ 资产 apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 226 + 230 @@ -1836,7 +1840,7 @@ 购买力 apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 241 + 245 @@ -1844,7 +1848,7 @@ 从分析中排除 apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 267 + 271 @@ -1852,7 +1856,7 @@ 负债 apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 295 + 299 apps/client/src/app/pages/features/features-page.html @@ -1864,7 +1868,7 @@ 净值 apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 317 + 321 @@ -1872,7 +1876,7 @@ 年化业绩 apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 331 + 335 @@ -1924,7 +1928,7 @@ 报告数据故障 apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html - 451 + 450 @@ -2424,7 +2428,7 @@ apps/client/src/app/components/user-detail-dialog/user-detail-dialog.html - 11 + 30 @@ -2616,7 +2620,7 @@ apps/client/src/app/components/user-detail-dialog/user-detail-dialog.html - 66 + 85 apps/client/src/app/pages/accounts/accounts-page.html @@ -2708,7 +2712,7 @@ 市场数据 apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html - 398 + 397 libs/common/src/lib/routes/routes.ts @@ -3080,7 +3084,7 @@ apps/client/src/app/pages/public/public-page.html - 242 + 241 apps/client/src/app/pages/resources/personal-finance-tools/product-page.html @@ -3196,7 +3200,7 @@ 开源财富管理软件 apps/client/src/app/pages/i18n/i18n-page.html - 237 + 246 @@ -3632,7 +3636,7 @@ apps/client/src/app/components/account-detail-dialog/account-detail-dialog.html - 115 + 113 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html @@ -3656,7 +3660,7 @@ apps/client/src/app/components/user-detail-dialog/user-detail-dialog.html - 75 + 94 apps/client/src/app/pages/portfolio/activities/activities-page.html @@ -3676,7 +3680,7 @@ 您确定要删除这些活动吗? libs/ui/src/lib/activities-table/activities-table.component.ts - 278 + 282 @@ -3992,7 +3996,7 @@ apps/client/src/app/pages/public/public-page.html - 151 + 150 @@ -4016,7 +4020,7 @@ apps/client/src/app/pages/public/public-page.html - 168 + 167 @@ -4024,7 +4028,7 @@ 最新活动 apps/client/src/app/pages/public/public-page.html - 211 + 210 @@ -4036,7 +4040,7 @@ apps/client/src/app/pages/public/public-page.html - 177 + 176 @@ -4048,7 +4052,7 @@ apps/client/src/app/pages/public/public-page.html - 186 + 185 @@ -4108,7 +4112,7 @@ apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 365 + 369 apps/client/src/app/pages/features/features-page.html @@ -4464,7 +4468,7 @@ 大陆 apps/client/src/app/pages/public/public-page.html - 132 + 131 @@ -4480,7 +4484,7 @@ Ghostfolio 使您能够跟踪您的财富。 apps/client/src/app/pages/public/public-page.html - 238 + 237 @@ -4853,7 +4857,7 @@ 会员资格 apps/client/src/app/components/user-detail-dialog/user-detail-dialog.html - 48 + 67 libs/common/src/lib/routes/routes.ts @@ -4977,7 +4981,7 @@ 您确实要删除此活动吗? libs/ui/src/lib/activities-table/activities-table.component.ts - 288 + 292 @@ -5097,7 +5101,7 @@ apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 352 + 356 libs/ui/src/lib/fire-calculator/fire-calculator.component.ts @@ -5141,7 +5145,7 @@ 显示所有 libs/ui/src/lib/holdings-table/holdings-table.component.html - 216 + 212 @@ -5269,7 +5273,7 @@ 应急基金 apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 164 + 168 apps/client/src/app/pages/features/features-page.html @@ -5345,7 +5349,7 @@ libs/ui/src/lib/portfolio-proportion-chart/portfolio-proportion-chart.component.ts - 437 + 449 @@ -5509,7 +5513,7 @@ 现金 apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 212 + 216 libs/ui/src/lib/i18n.ts @@ -5557,7 +5561,7 @@ 认证 apps/client/src/app/components/user-detail-dialog/user-detail-dialog.html - 35 + 54 @@ -5725,7 +5729,7 @@ apps/client/src/app/pages/public/public-page.html - 196 + 195 libs/ui/src/lib/benchmark/benchmark.component.html @@ -5733,11 +5737,11 @@ libs/ui/src/lib/portfolio-proportion-chart/portfolio-proportion-chart.component.ts - 439 + 451 libs/ui/src/lib/portfolio-proportion-chart/portfolio-proportion-chart.component.ts - 452 + 465 libs/ui/src/lib/top-holdings/top-holdings.component.html @@ -5853,7 +5857,7 @@ 关闭持仓 apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html - 442 + 441 @@ -6330,7 +6334,7 @@ 您想 优化 您的 个人投资策略吗? apps/client/src/app/pages/public/public-page.html - 234 + 233 @@ -6792,6 +6796,10 @@ apps/client/src/app/components/user-account-access/create-or-update-access-dialog/create-or-update-access-dialog.html 68 + + apps/client/src/app/components/user-detail-dialog/user-detail-dialog.html + 127 + apps/client/src/app/pages/accounts/create-or-update-account-dialog/create-or-update-account-dialog.html 107 @@ -6810,7 +6818,7 @@ 角色 apps/client/src/app/components/user-detail-dialog/user-detail-dialog.html - 14 + 33 @@ -7216,7 +7224,7 @@ apps/client/src/app/components/user-detail-dialog/user-detail-dialog.html - 98 + 117 @@ -7480,7 +7488,7 @@ libs/ui/src/lib/treemap-chart/treemap-chart.component.ts - 368 + 375 @@ -7500,11 +7508,11 @@ libs/ui/src/lib/treemap-chart/treemap-chart.component.ts - 368 + 375 libs/ui/src/lib/treemap-chart/treemap-chart.component.ts - 381 + 388 @@ -7608,7 +7616,7 @@ 安全令牌 apps/client/src/app/components/admin-users/admin-users.component.ts - 236 + 239 apps/client/src/app/components/user-account-access/user-account-access.component.ts @@ -7620,7 +7628,7 @@ 您确定要为此用户生成新的安全令牌吗? apps/client/src/app/components/admin-users/admin-users.component.ts - 241 + 244 @@ -7874,8 +7882,8 @@ - Fee Ratio - 费率 + Fee Ratio (legacy) + 费率 apps/client/src/app/pages/i18n/i18n-page.html 152 @@ -7897,6 +7905,30 @@ 158 + + Fee Ratio + Fee Ratio + + apps/client/src/app/pages/i18n/i18n-page.html + 161 + + + + The fees do exceed ${thresholdMax}% of your total investment volume (${feeRatio}%) + The fees do exceed ${thresholdMax}% of your total investment volume (${feeRatio}%) + + apps/client/src/app/pages/i18n/i18n-page.html + 163 + + + + The fees do not exceed ${thresholdMax}% of your total investment volume (${feeRatio}%) + The fees do not exceed ${thresholdMax}% of your total investment volume (${feeRatio}%) + + apps/client/src/app/pages/i18n/i18n-page.html + 167 + + Quick Links 快速链接 @@ -8277,7 +8309,7 @@ 管理资产概况 apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html - 466 + 465 @@ -8353,7 +8385,7 @@ 费用 apps/client/src/app/pages/i18n/i18n-page.html - 161 + 170 @@ -8401,7 +8433,7 @@ 区域市场集群风险 apps/client/src/app/pages/i18n/i18n-page.html - 163 + 172 @@ -8497,7 +8529,7 @@ 亚太地区 apps/client/src/app/pages/i18n/i18n-page.html - 165 + 174 @@ -8505,7 +8537,7 @@ 亚太地区对您的当前投资 (${valueRatio}%) 的贡献超过了 ${thresholdMax}% apps/client/src/app/pages/i18n/i18n-page.html - 167 + 176 @@ -8513,7 +8545,7 @@ 亚太地区对您的当前投资 (${valueRatio}%) 的贡献低于 ${thresholdMin}% apps/client/src/app/pages/i18n/i18n-page.html - 171 + 180 @@ -8521,7 +8553,7 @@ 亚太地区对您的当前投资 (${valueRatio}%) 的贡献在 ${thresholdMin}% 和 ${thresholdMax}% 之间 apps/client/src/app/pages/i18n/i18n-page.html - 175 + 184 @@ -8529,7 +8561,7 @@ 新兴市场 apps/client/src/app/pages/i18n/i18n-page.html - 180 + 189 @@ -8537,7 +8569,7 @@ 新兴市场对您的当前投资 (${valueRatio}%) 的贡献超过了 ${thresholdMax}% apps/client/src/app/pages/i18n/i18n-page.html - 183 + 192 @@ -8545,7 +8577,7 @@ 新兴市场对您的当前投资 (${valueRatio}%) 的贡献低于 ${thresholdMin}% apps/client/src/app/pages/i18n/i18n-page.html - 187 + 196 @@ -8553,7 +8585,7 @@ 新兴市场对您的当前投资 (${valueRatio}%) 的贡献在 ${thresholdMin}% 和 ${thresholdMax}% 之间 apps/client/src/app/pages/i18n/i18n-page.html - 191 + 200 @@ -8561,7 +8593,7 @@ 欧洲市场 apps/client/src/app/pages/i18n/i18n-page.html - 195 + 204 @@ -8569,7 +8601,7 @@ 欧洲市场对您的当前投资 (${valueRatio}%) 的贡献超过了 ${thresholdMax}% apps/client/src/app/pages/i18n/i18n-page.html - 197 + 206 @@ -8577,7 +8609,7 @@ 欧洲市场对您的当前投资 (${valueRatio}%) 的贡献低于 ${thresholdMin}% apps/client/src/app/pages/i18n/i18n-page.html - 201 + 210 @@ -8585,7 +8617,7 @@ 欧洲市场对您的当前投资 (${valueRatio}%) 的贡献在 ${thresholdMin}% 和 ${thresholdMax}% 之间 apps/client/src/app/pages/i18n/i18n-page.html - 205 + 214 @@ -8593,7 +8625,7 @@ 日本市场 apps/client/src/app/pages/i18n/i18n-page.html - 209 + 218 @@ -8601,7 +8633,7 @@ 日本市场对您的当前投资 (${valueRatio}%) 的贡献超过了 ${thresholdMax}% apps/client/src/app/pages/i18n/i18n-page.html - 211 + 220 @@ -8609,7 +8641,7 @@ 日本市场对您的当前投资 (${valueRatio}%) 的贡献低于 ${thresholdMin}% apps/client/src/app/pages/i18n/i18n-page.html - 215 + 224 @@ -8617,7 +8649,7 @@ 日本市场对您的当前投资 (${valueRatio}%) 的贡献在 ${thresholdMin}% 和 ${thresholdMax}% 之间 apps/client/src/app/pages/i18n/i18n-page.html - 219 + 228 @@ -8625,7 +8657,7 @@ 北美市场 apps/client/src/app/pages/i18n/i18n-page.html - 223 + 232 @@ -8633,7 +8665,7 @@ 北美市场对您的当前投资 (${valueRatio}%) 的贡献超过了 ${thresholdMax}% apps/client/src/app/pages/i18n/i18n-page.html - 225 + 234 @@ -8641,7 +8673,7 @@ 北美市场对您的当前投资 (${valueRatio}%) 的贡献低于 ${thresholdMin}% apps/client/src/app/pages/i18n/i18n-page.html - 229 + 238 @@ -8649,7 +8681,7 @@ 北美市场对您的当前投资 (${valueRatio}%) 的贡献在 ${thresholdMin}% 和 ${thresholdMax}% 之间 apps/client/src/app/pages/i18n/i18n-page.html - 233 + 242 @@ -8697,7 +8729,7 @@ 注册日期 apps/client/src/app/components/user-detail-dialog/user-detail-dialog.html - 26 + 45 From 8c33a51ca51cdb9f36f9008c85a2b360befcbfa3 Mon Sep 17 00:00:00 2001 From: Thomas Kaul <4159106+dtslvr@users.noreply.github.com> Date: Sun, 15 Feb 2026 10:49:56 +0100 Subject: [PATCH 017/224] Release 2.239.0 (#6335) --- CHANGELOG.md | 2 +- package-lock.json | 4 ++-- package.json | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ee27bef6c..b28e10ab6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,7 +5,7 @@ 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 +## 2.239.0 - 2026-02-15 ### Added diff --git a/package-lock.json b/package-lock.json index 1dfdcb7fc..b6b7ca647 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "ghostfolio", - "version": "2.238.0", + "version": "2.239.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "ghostfolio", - "version": "2.238.0", + "version": "2.239.0", "hasInstallScript": true, "license": "AGPL-3.0", "dependencies": { diff --git a/package.json b/package.json index 65f98cdff..777dfd6aa 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "ghostfolio", - "version": "2.238.0", + "version": "2.239.0", "homepage": "https://ghostfol.io", "license": "AGPL-3.0", "repository": "https://github.com/ghostfolio/ghostfolio", From 75d3494fa4cf7f1f6dd0fab3e6fb54386ecf074e Mon Sep 17 00:00:00 2001 From: Thomas Kaul <4159106+dtslvr@users.noreply.github.com> Date: Mon, 16 Feb 2026 12:16:13 +0100 Subject: [PATCH 018/224] Task/add support for cryptocurrency Sky (#6338) * Add support for Sky * Update changelog --- CHANGELOG.md | 6 ++++++ apps/api/src/assets/cryptocurrencies/custom.json | 1 + 2 files changed, 7 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index b28e10ab6..864942973 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 + +### Added + +- Added support for the cryptocurrency _Sky_ + ## 2.239.0 - 2026-02-15 ### Added diff --git a/apps/api/src/assets/cryptocurrencies/custom.json b/apps/api/src/assets/cryptocurrencies/custom.json index 814aeec34..a26fc33df 100644 --- a/apps/api/src/assets/cryptocurrencies/custom.json +++ b/apps/api/src/assets/cryptocurrencies/custom.json @@ -4,6 +4,7 @@ "LUNA1": "Terra", "LUNA2": "Terra", "SGB1": "Songbird", + "SKY33038": "Sky", "SMURFCAT": "Real Smurf Cat", "TON11419": "Toncoin", "UNI1": "Uniswap", From d1345b8147c7fee808fd352b28fed7267cd5c053 Mon Sep 17 00:00:00 2001 From: Thomas Kaul <4159106+dtslvr@users.noreply.github.com> Date: Mon, 16 Feb 2026 20:26:42 +0100 Subject: [PATCH 019/224] Task/upgrade ngx-markdown to version 21.1.0 (#6321) * Upgrade ngx-markdown to version 21.1.0 * Update changelog --- CHANGELOG.md | 4 ++++ package-lock.json | 12 ++++++------ package.json | 2 +- 3 files changed, 11 insertions(+), 7 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 864942973..4261653f2 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 - Added support for the cryptocurrency _Sky_ +### Changed + +- Upgraded `ngx-markdown` from version `21.0.1` to `21.1.0` + ## 2.239.0 - 2026-02-15 ### Added diff --git a/package-lock.json b/package-lock.json index b6b7ca647..13d3a99ca 100644 --- a/package-lock.json +++ b/package-lock.json @@ -74,7 +74,7 @@ "ms": "3.0.0-canary.1", "ng-extract-i18n-merge": "3.2.1", "ngx-device-detector": "11.0.0", - "ngx-markdown": "21.0.1", + "ngx-markdown": "21.1.0", "ngx-skeleton-loader": "12.0.0", "open-color": "1.9.1", "papaparse": "5.3.1", @@ -26308,16 +26308,16 @@ } }, "node_modules/ngx-markdown": { - "version": "21.0.1", - "resolved": "https://registry.npmjs.org/ngx-markdown/-/ngx-markdown-21.0.1.tgz", - "integrity": "sha512-TQnxrU9b+JclgXBFVg0Xp/6YEMom+hpiEjBMlE56cIWzONNh7pshMeMkz972wWzvQvTP+55/BmEZQc+4Vq1MWg==", + "version": "21.1.0", + "resolved": "https://registry.npmjs.org/ngx-markdown/-/ngx-markdown-21.1.0.tgz", + "integrity": "sha512-qiyn9Je20F9yS4/q0p1Xhk2b/HW0rHWWlJNRm8DIzJKNck9Rmn/BfFxq0webmQHPPyYkg2AjNq/ZeSqDTQJbsQ==", "license": "MIT", "dependencies": { "tslib": "^2.3.0" }, "optionalDependencies": { "clipboard": "^2.0.11", - "emoji-toolkit": ">= 8.0.0 < 10.0.0", + "emoji-toolkit": ">= 8.0.0 < 11.0.0", "katex": "^0.16.0", "mermaid": ">= 10.6.0 < 12.0.0", "prismjs": "^1.30.0" @@ -26326,7 +26326,7 @@ "@angular/common": "^21.0.0", "@angular/core": "^21.0.0", "@angular/platform-browser": "^21.0.0", - "marked": "^17.0.0 || ^16.0.0", + "marked": "^17.0.0", "rxjs": "^6.5.3 || ^7.4.0", "zone.js": "~0.15.0 || ~0.16.0" } diff --git a/package.json b/package.json index 777dfd6aa..89d6e9f23 100644 --- a/package.json +++ b/package.json @@ -118,7 +118,7 @@ "ms": "3.0.0-canary.1", "ng-extract-i18n-merge": "3.2.1", "ngx-device-detector": "11.0.0", - "ngx-markdown": "21.0.1", + "ngx-markdown": "21.1.0", "ngx-skeleton-loader": "12.0.0", "open-color": "1.9.1", "papaparse": "5.3.1", From 8c88ce918fa95ec89bf1899fc2ec74ae365da102 Mon Sep 17 00:00:00 2001 From: Thomas Kaul <4159106+dtslvr@users.noreply.github.com> Date: Tue, 17 Feb 2026 07:57:52 +0100 Subject: [PATCH 020/224] Feature/add support for custom cryptocurrencies defined in database (#6344) * Add support for custom cryptocurrencies defined in database * Update changelog --- CHANGELOG.md | 1 + .../cryptocurrency/cryptocurrency.module.ts | 7 +++- .../cryptocurrency/cryptocurrency.service.ts | 38 +++++++++++-------- .../yahoo-finance.service.spec.ts | 2 +- libs/common/src/lib/config.ts | 1 + 5 files changed, 31 insertions(+), 18 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4261653f2..7609fa0e4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Added +- Added support for custom cryptocurrencies defined in the database - Added support for the cryptocurrency _Sky_ ### Changed diff --git a/apps/api/src/services/cryptocurrency/cryptocurrency.module.ts b/apps/api/src/services/cryptocurrency/cryptocurrency.module.ts index 8820205eb..e882f4da5 100644 --- a/apps/api/src/services/cryptocurrency/cryptocurrency.module.ts +++ b/apps/api/src/services/cryptocurrency/cryptocurrency.module.ts @@ -1,9 +1,12 @@ +import { PropertyModule } from '@ghostfolio/api/services/property/property.module'; + import { Module } from '@nestjs/common'; import { CryptocurrencyService } from './cryptocurrency.service'; @Module({ - providers: [CryptocurrencyService], - exports: [CryptocurrencyService] + exports: [CryptocurrencyService], + imports: [PropertyModule], + providers: [CryptocurrencyService] }) export class CryptocurrencyModule {} diff --git a/apps/api/src/services/cryptocurrency/cryptocurrency.service.ts b/apps/api/src/services/cryptocurrency/cryptocurrency.service.ts index b814fc186..933029ea2 100644 --- a/apps/api/src/services/cryptocurrency/cryptocurrency.service.ts +++ b/apps/api/src/services/cryptocurrency/cryptocurrency.service.ts @@ -1,31 +1,39 @@ -import { DEFAULT_CURRENCY } from '@ghostfolio/common/config'; +import { PropertyService } from '@ghostfolio/api/services/property/property.service'; +import { + DEFAULT_CURRENCY, + PROPERTY_CUSTOM_CRYPTOCURRENCIES +} from '@ghostfolio/common/config'; -import { Injectable } from '@nestjs/common'; +import { Injectable, OnModuleInit } from '@nestjs/common'; const cryptocurrencies = require('../../assets/cryptocurrencies/cryptocurrencies.json'); const customCryptocurrencies = require('../../assets/cryptocurrencies/custom.json'); @Injectable() -export class CryptocurrencyService { +export class CryptocurrencyService implements OnModuleInit { private combinedCryptocurrencies: string[]; + public constructor(private readonly propertyService: PropertyService) {} + + public async onModuleInit() { + const customCryptocurrenciesFromDatabase = + await this.propertyService.getByKey>( + PROPERTY_CUSTOM_CRYPTOCURRENCIES + ); + + this.combinedCryptocurrencies = [ + ...Object.keys(cryptocurrencies), + ...Object.keys(customCryptocurrencies), + ...Object.keys(customCryptocurrenciesFromDatabase ?? {}) + ]; + } + public isCryptocurrency(aSymbol = '') { const cryptocurrencySymbol = aSymbol.substring(0, aSymbol.length - 3); return ( aSymbol.endsWith(DEFAULT_CURRENCY) && - this.getCryptocurrencies().includes(cryptocurrencySymbol) + this.combinedCryptocurrencies.includes(cryptocurrencySymbol) ); } - - private getCryptocurrencies() { - if (!this.combinedCryptocurrencies) { - this.combinedCryptocurrencies = [ - ...Object.keys(cryptocurrencies), - ...Object.keys(customCryptocurrencies) - ]; - } - - return this.combinedCryptocurrencies; - } } diff --git a/apps/api/src/services/data-provider/data-enhancer/yahoo-finance/yahoo-finance.service.spec.ts b/apps/api/src/services/data-provider/data-enhancer/yahoo-finance/yahoo-finance.service.spec.ts index c37a9fe3e..9335d86d0 100644 --- a/apps/api/src/services/data-provider/data-enhancer/yahoo-finance/yahoo-finance.service.spec.ts +++ b/apps/api/src/services/data-provider/data-enhancer/yahoo-finance/yahoo-finance.service.spec.ts @@ -29,7 +29,7 @@ describe('YahooFinanceDataEnhancerService', () => { let yahooFinanceDataEnhancerService: YahooFinanceDataEnhancerService; beforeAll(async () => { - cryptocurrencyService = new CryptocurrencyService(); + cryptocurrencyService = new CryptocurrencyService(null); yahooFinanceDataEnhancerService = new YahooFinanceDataEnhancerService( cryptocurrencyService diff --git a/libs/common/src/lib/config.ts b/libs/common/src/lib/config.ts index b558ccc42..eae1b73cd 100644 --- a/libs/common/src/lib/config.ts +++ b/libs/common/src/lib/config.ts @@ -199,6 +199,7 @@ export const PROPERTY_BETTER_UPTIME_MONITOR_ID = 'BETTER_UPTIME_MONITOR_ID'; export const PROPERTY_COUNTRIES_OF_SUBSCRIBERS = 'COUNTRIES_OF_SUBSCRIBERS'; export const PROPERTY_COUPONS = 'COUPONS'; export const PROPERTY_CURRENCIES = 'CURRENCIES'; +export const PROPERTY_CUSTOM_CRYPTOCURRENCIES = 'CUSTOM_CRYPTOCURRENCIES'; export const PROPERTY_DATA_SOURCE_MAPPING = 'DATA_SOURCE_MAPPING'; export const PROPERTY_DATA_SOURCES_GHOSTFOLIO_DATA_PROVIDER_MAX_REQUESTS = 'DATA_SOURCES_GHOSTFOLIO_DATA_PROVIDER_MAX_REQUESTS'; From e7df24f899b6af48faf37e7b3b75e821b386a97f Mon Sep 17 00:00:00 2001 From: Kenrick Tandrian <60643640+KenTandrian@users.noreply.github.com> Date: Tue, 17 Feb 2026 23:41:59 +0700 Subject: [PATCH 021/224] Task/enable UI test (#6345) * Create script for ui test and implement parallel test --- package.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/package.json b/package.json index 89d6e9f23..123ce3c54 100644 --- a/package.json +++ b/package.json @@ -43,10 +43,11 @@ "start:production": "npm run database:migrate && npm run database:seed && node main", "start:server": "nx run api:copy-assets && nx run api:serve --watch", "start:storybook": "nx run ui:storybook", - "test": "npm run test:api && npm run test:common", + "test": "npx dotenv-cli -e .env.example -- npx nx run-many --target=test --all --parallel=4", "test:api": "npx dotenv-cli -e .env.example -- nx test api", "test:common": "npx dotenv-cli -e .env.example -- nx test common", "test:single": "nx run api:test --test-file object.helper.spec.ts", + "test:ui": "npx dotenv-cli -e .env.example -- nx test ui", "ts-node": "ts-node", "update": "nx migrate latest", "watch:server": "nx run api:copy-assets && nx run api:build --watch", From 78ccdd8d2da1b1dfc31eaa8f6b615c6f69f6df29 Mon Sep 17 00:00:00 2001 From: Thomas Kaul <4159106+dtslvr@users.noreply.github.com> Date: Tue, 17 Feb 2026 17:43:50 +0100 Subject: [PATCH 022/224] Task/upgrade marked to version 17.0.2 (#6323) * Upgrade marked to version 17.0.2 * Update changelog --- CHANGELOG.md | 1 + package-lock.json | 8 ++++---- package.json | 2 +- 3 files changed, 6 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7609fa0e4..bb9b2e676 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,6 +14,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Changed +- Upgraded `marked` from version `17.0.1` to `17.0.2` - Upgraded `ngx-markdown` from version `21.0.1` to `21.1.0` ## 2.239.0 - 2026-02-15 diff --git a/package-lock.json b/package-lock.json index 13d3a99ca..44d479e7f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -70,7 +70,7 @@ "ionicons": "8.0.13", "jsonpath": "1.1.1", "lodash": "4.17.23", - "marked": "17.0.1", + "marked": "17.0.2", "ms": "3.0.0-canary.1", "ng-extract-i18n-merge": "3.2.1", "ngx-device-detector": "11.0.0", @@ -25625,9 +25625,9 @@ } }, "node_modules/marked": { - "version": "17.0.1", - "resolved": "https://registry.npmjs.org/marked/-/marked-17.0.1.tgz", - "integrity": "sha512-boeBdiS0ghpWcSwoNm/jJBwdpFaMnZWRzjA6SkUMYb40SVaN1x7mmfGKp0jvexGcx+7y2La5zRZsYFZI6Qpypg==", + "version": "17.0.2", + "resolved": "https://registry.npmjs.org/marked/-/marked-17.0.2.tgz", + "integrity": "sha512-s5HZGFQea7Huv5zZcAGhJLT3qLpAfnY7v7GWkICUr0+Wd5TFEtdlRR2XUL5Gg+RH7u2Df595ifrxR03mBaw7gA==", "license": "MIT", "bin": { "marked": "bin/marked.js" diff --git a/package.json b/package.json index 123ce3c54..aaf9df90e 100644 --- a/package.json +++ b/package.json @@ -115,7 +115,7 @@ "ionicons": "8.0.13", "jsonpath": "1.1.1", "lodash": "4.17.23", - "marked": "17.0.1", + "marked": "17.0.2", "ms": "3.0.0-canary.1", "ng-extract-i18n-merge": "3.2.1", "ngx-device-detector": "11.0.0", From 47a054dd00b37469e12fa8716c182ad0421b66dc Mon Sep 17 00:00:00 2001 From: Kenrick Tandrian <60643640+KenTandrian@users.noreply.github.com> Date: Wed, 18 Feb 2026 01:07:27 +0700 Subject: [PATCH 023/224] Task/improve type safety in historical market data editor component (#6337) * feat(lib): resolve ts errors * feat(lib): make days protected and readonly * feat(lib): create formatDay helper function * fix(lib): remove unused eslint-disable * feat(lib): change locale to input signal * feat(lib): change defaultDateFormat to computed signal * feat(lib): change deviceType to computed signal * feat(lib): change marketData to input signal * feat(lib): change historicalDataItems to computed signal * feat(nx): run ui test * feat(lib): update days to improve readability * feat(nx): revert test changes * fix(lib): change logic for locale * fix(lib): disable mutating the injected readonly data * fix(lib): implement takeUntilDestroyed * fix(lib): implement takeUntilDestroyed * fix(lib): organize imports --- ...cal-market-data-editor-dialog.component.ts | 47 ++++--- .../historical-market-data-editor-dialog.html | 3 +- .../interfaces/interfaces.ts | 2 +- ...storical-market-data-editor.component.html | 24 ++-- ...rical-market-data-editor.component.spec.ts | 60 ++++++++ ...historical-market-data-editor.component.ts | 133 ++++++++++-------- 6 files changed, 172 insertions(+), 97 deletions(-) create mode 100644 libs/ui/src/lib/historical-market-data-editor/historical-market-data-editor.component.spec.ts diff --git a/libs/ui/src/lib/historical-market-data-editor/historical-market-data-editor-dialog/historical-market-data-editor-dialog.component.ts b/libs/ui/src/lib/historical-market-data-editor/historical-market-data-editor-dialog/historical-market-data-editor-dialog.component.ts index 7e7094dd3..3e5e3b2e9 100644 --- a/libs/ui/src/lib/historical-market-data-editor/historical-market-data-editor-dialog/historical-market-data-editor-dialog.component.ts +++ b/libs/ui/src/lib/historical-market-data-editor/historical-market-data-editor-dialog/historical-market-data-editor-dialog.component.ts @@ -5,10 +5,12 @@ import { ChangeDetectorRef, Component, CUSTOM_ELEMENTS_SCHEMA, - Inject, - OnDestroy, - OnInit + DestroyRef, + OnInit, + inject, + signal } from '@angular/core'; +import { takeUntilDestroyed } from '@angular/core/rxjs-interop'; import { FormsModule, ReactiveFormsModule } from '@angular/forms'; import { MatButtonModule } from '@angular/material/button'; import { DateAdapter, MAT_DATE_LOCALE } from '@angular/material/core'; @@ -23,7 +25,6 @@ import { MatInputModule } from '@angular/material/input'; import { IonIcon } from '@ionic/angular/standalone'; import { addIcons } from 'ionicons'; import { calendarClearOutline, refreshOutline } from 'ionicons/icons'; -import { Subject, takeUntil } from 'rxjs'; import { HistoricalMarketDataEditorDialogParams } from './interfaces/interfaces'; @@ -45,26 +46,27 @@ import { HistoricalMarketDataEditorDialogParams } from './interfaces/interfaces' styleUrls: ['./historical-market-data-editor-dialog.scss'], templateUrl: 'historical-market-data-editor-dialog.html' }) -export class GfHistoricalMarketDataEditorDialogComponent - implements OnDestroy, OnInit -{ - private unsubscribeSubject = new Subject(); +export class GfHistoricalMarketDataEditorDialogComponent implements OnInit { + public readonly data = + inject(MAT_DIALOG_DATA); + + protected readonly marketPrice = signal(this.data.marketPrice); + + private readonly destroyRef = inject(DestroyRef); + private readonly locale = + this.data.user.settings.locale ?? inject(MAT_DATE_LOCALE); public constructor( private adminService: AdminService, private changeDetectorRef: ChangeDetectorRef, - @Inject(MAT_DIALOG_DATA) - public data: HistoricalMarketDataEditorDialogParams, private dataService: DataService, - private dateAdapter: DateAdapter, - public dialogRef: MatDialogRef, - @Inject(MAT_DATE_LOCALE) private locale: string + private dateAdapter: DateAdapter, + public dialogRef: MatDialogRef ) { addIcons({ calendarClearOutline, refreshOutline }); } public ngOnInit() { - this.locale = this.data.user?.settings?.locale; this.dateAdapter.setLocale(this.locale); } @@ -79,15 +81,19 @@ export class GfHistoricalMarketDataEditorDialogComponent dateString: this.data.dateString, symbol: this.data.symbol }) - .pipe(takeUntil(this.unsubscribeSubject)) + .pipe(takeUntilDestroyed(this.destroyRef)) .subscribe(({ marketPrice }) => { - this.data.marketPrice = marketPrice; + this.marketPrice.set(marketPrice); this.changeDetectorRef.markForCheck(); }); } public onUpdate() { + if (this.marketPrice() === undefined) { + return; + } + this.dataService .postMarketData({ dataSource: this.data.dataSource, @@ -95,20 +101,15 @@ export class GfHistoricalMarketDataEditorDialogComponent marketData: [ { date: this.data.dateString, - marketPrice: this.data.marketPrice + marketPrice: this.marketPrice() } ] }, symbol: this.data.symbol }) - .pipe(takeUntil(this.unsubscribeSubject)) + .pipe(takeUntilDestroyed(this.destroyRef)) .subscribe(() => { this.dialogRef.close({ withRefresh: true }); }); } - - public ngOnDestroy() { - this.unsubscribeSubject.next(); - this.unsubscribeSubject.complete(); - } } diff --git a/libs/ui/src/lib/historical-market-data-editor/historical-market-data-editor-dialog/historical-market-data-editor-dialog.html b/libs/ui/src/lib/historical-market-data-editor/historical-market-data-editor-dialog/historical-market-data-editor-dialog.html index 8e7e30649..7bb5827ef 100644 --- a/libs/ui/src/lib/historical-market-data-editor/historical-market-data-editor-dialog/historical-market-data-editor-dialog.html +++ b/libs/ui/src/lib/historical-market-data-editor/historical-market-data-editor-dialog/historical-market-data-editor-dialog.html @@ -28,7 +28,8 @@ matInput name="marketPrice" type="number" - [(ngModel)]="data.marketPrice" + [ngModel]="marketPrice()" + (ngModelChange)="marketPrice.set($event)" /> {{ data.currency }} diff --git a/libs/ui/src/lib/historical-market-data-editor/historical-market-data-editor-dialog/interfaces/interfaces.ts b/libs/ui/src/lib/historical-market-data-editor/historical-market-data-editor-dialog/interfaces/interfaces.ts index 4248b3fdb..edb9a852f 100644 --- a/libs/ui/src/lib/historical-market-data-editor/historical-market-data-editor-dialog/interfaces/interfaces.ts +++ b/libs/ui/src/lib/historical-market-data-editor/historical-market-data-editor-dialog/interfaces/interfaces.ts @@ -6,7 +6,7 @@ export interface HistoricalMarketDataEditorDialogParams { currency: string; dataSource: DataSource; dateString: string; - marketPrice: number; + marketPrice?: number; symbol: string; user: User; } diff --git a/libs/ui/src/lib/historical-market-data-editor/historical-market-data-editor.component.html b/libs/ui/src/lib/historical-market-data-editor/historical-market-data-editor.component.html index 3c2807146..91e3dd8d7 100644 --- a/libs/ui/src/lib/historical-market-data-editor/historical-market-data-editor.component.html +++ b/libs/ui/src/lib/historical-market-data-editor/historical-market-data-editor.component.html @@ -3,28 +3,24 @@
    {{ itemByMonth.key }}
    - @for (dayItem of days; track dayItem; let i = $index) { + @for (day of days; track day) {
    diff --git a/libs/ui/src/lib/historical-market-data-editor/historical-market-data-editor.component.spec.ts b/libs/ui/src/lib/historical-market-data-editor/historical-market-data-editor.component.spec.ts new file mode 100644 index 000000000..7cb9636f0 --- /dev/null +++ b/libs/ui/src/lib/historical-market-data-editor/historical-market-data-editor.component.spec.ts @@ -0,0 +1,60 @@ +import { DataService } from '@ghostfolio/ui/services'; + +import { signal } from '@angular/core'; +import { ComponentFixture, TestBed } from '@angular/core/testing'; +import { FormBuilder } from '@angular/forms'; +import { MatDialog } from '@angular/material/dialog'; +import { MatSnackBar } from '@angular/material/snack-bar'; +import { DeviceDetectorService } from 'ngx-device-detector'; + +import { GfHistoricalMarketDataEditorComponent } from './historical-market-data-editor.component'; + +jest.mock( + './historical-market-data-editor-dialog/historical-market-data-editor-dialog.component', + () => ({ + GfHistoricalMarketDataEditorDialogComponent: class {} + }) +); + +describe('GfHistoricalMarketDataEditorComponent', () => { + let component: GfHistoricalMarketDataEditorComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + imports: [GfHistoricalMarketDataEditorComponent], + providers: [ + FormBuilder, + { provide: DataService, useValue: {} }, + { + provide: DeviceDetectorService, + useValue: { + deviceInfo: signal({ deviceType: 'desktop' }) + } + }, + { provide: MatDialog, useValue: {} }, + { provide: MatSnackBar, useValue: {} } + ] + }).compileComponents(); + + fixture = TestBed.createComponent(GfHistoricalMarketDataEditorComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); + + describe('formatDay', () => { + it('should pad single digit days with zero', () => { + expect(component.formatDay(1)).toBe('01'); + expect(component.formatDay(9)).toBe('09'); + }); + + it('should not pad double digit days', () => { + expect(component.formatDay(10)).toBe('10'); + expect(component.formatDay(31)).toBe('31'); + }); + }); +}); diff --git a/libs/ui/src/lib/historical-market-data-editor/historical-market-data-editor.component.ts b/libs/ui/src/lib/historical-market-data-editor/historical-market-data-editor.component.ts index 098f4e295..cde180dd9 100644 --- a/libs/ui/src/lib/historical-market-data-editor/historical-market-data-editor.component.ts +++ b/libs/ui/src/lib/historical-market-data-editor/historical-market-data-editor.component.ts @@ -8,16 +8,21 @@ import { LineChartItem, User } from '@ghostfolio/common/interfaces'; import { DataService } from '@ghostfolio/ui/services'; import { CommonModule } from '@angular/common'; +import type { HttpErrorResponse } from '@angular/common/http'; import { ChangeDetectionStrategy, Component, + computed, + DestroyRef, EventEmitter, + inject, + input, Input, OnChanges, - OnDestroy, OnInit, Output } from '@angular/core'; +import { takeUntilDestroyed } from '@angular/core/rxjs-interop'; import { FormBuilder, ReactiveFormsModule } from '@angular/forms'; import { MatButtonModule } from '@angular/material/button'; import { MatDialog } from '@angular/material/dialog'; @@ -40,7 +45,7 @@ import { first, last } from 'lodash'; import ms from 'ms'; import { DeviceDetectorService } from 'ngx-device-detector'; import { parse as csvToJson } from 'papaparse'; -import { EMPTY, Subject, takeUntil } from 'rxjs'; +import { EMPTY } from 'rxjs'; import { catchError } from 'rxjs/operators'; import { GfHistoricalMarketDataEditorDialogComponent } from './historical-market-data-editor-dialog/historical-market-data-editor-dialog.component'; @@ -54,74 +59,80 @@ import { HistoricalMarketDataEditorDialogParams } from './historical-market-data templateUrl: './historical-market-data-editor.component.html' }) export class GfHistoricalMarketDataEditorComponent - implements OnChanges, OnDestroy, OnInit + implements OnChanges, OnInit { + private static readonly HISTORICAL_DATA_TEMPLATE = `date;marketPrice\n${format( + new Date(), + DATE_FORMAT + )};123.45`; + @Input() currency: string; @Input() dataSource: DataSource; @Input() dateOfFirstActivity: string; - @Input() locale = getLocale(); - @Input() marketData: MarketData[]; @Input() symbol: string; @Input() user: User; @Output() marketDataChanged = new EventEmitter(); - public days = Array(31); - public defaultDateFormat: string; - public deviceType: string; public historicalDataForm = this.formBuilder.group({ historicalData: this.formBuilder.group({ csvString: '' }) }); - public historicalDataItems: LineChartItem[]; public marketDataByMonth: { [yearMonth: string]: { - [day: string]: Pick & { day: number }; + [day: string]: { + date: Date; + day: number; + marketPrice?: number; + }; }; } = {}; - private static readonly HISTORICAL_DATA_TEMPLATE = `date;marketPrice\n${format( - new Date(), - DATE_FORMAT - )};123.45`; - - private unsubscribeSubject = new Subject(); + public readonly locale = input(getLocale()); + public readonly marketData = input.required(); + + protected readonly days = Array.from({ length: 31 }, (_, i) => i + 1); + protected readonly defaultDateFormat = computed(() => + getDateFormatString(this.locale()) + ); + + private readonly destroyRef = inject(DestroyRef); + private readonly deviceDetectorService = inject(DeviceDetectorService); + private readonly deviceType = computed( + () => this.deviceDetectorService.deviceInfo().deviceType + ); + private readonly historicalDataItems = computed(() => + this.marketData().map(({ date, marketPrice }) => { + return { + date: format(date, DATE_FORMAT), + value: marketPrice + }; + }) + ); public constructor( private dataService: DataService, - private deviceService: DeviceDetectorService, private dialog: MatDialog, private formBuilder: FormBuilder, private snackBar: MatSnackBar - ) { - this.deviceType = this.deviceService.getDeviceInfo().deviceType; - } + ) {} public ngOnInit() { this.initializeHistoricalDataForm(); } public ngOnChanges() { - this.defaultDateFormat = getDateFormatString(this.locale); - - this.historicalDataItems = this.marketData.map(({ date, marketPrice }) => { - return { - date: format(date, DATE_FORMAT), - value: marketPrice - }; - }); - if (this.dateOfFirstActivity) { let date = parseISO(this.dateOfFirstActivity); - const missingMarketData: Partial[] = []; + const missingMarketData: { date: Date; marketPrice?: number }[] = []; - if (this.historicalDataItems?.[0]?.date) { + if (this.historicalDataItems()?.[0]?.date) { while ( isBefore( date, - parse(this.historicalDataItems[0].date, DATE_FORMAT, new Date()) + parse(this.historicalDataItems()[0].date, DATE_FORMAT, new Date()) ) ) { missingMarketData.push({ @@ -133,9 +144,10 @@ export class GfHistoricalMarketDataEditorComponent } } - const marketDataItems = [...missingMarketData, ...this.marketData]; + const marketDataItems = [...missingMarketData, ...this.marketData()]; - if (!isToday(last(marketDataItems)?.date)) { + const lastDate = last(marketDataItems)?.date; + if (!lastDate || !isToday(lastDate)) { marketDataItems.push({ date: new Date() }); } @@ -160,25 +172,34 @@ export class GfHistoricalMarketDataEditorComponent // Fill up missing months const dates = Object.keys(this.marketDataByMonth).sort(); + const startDateString = first(dates); const startDate = min([ parseISO(this.dateOfFirstActivity), - parseISO(first(dates)) + ...(startDateString ? [parseISO(startDateString)] : []) ]); - const endDate = parseISO(last(dates)); + const endDateString = last(dates); - let currentDate = startDate; + if (endDateString) { + const endDate = parseISO(endDateString); - while (isBefore(currentDate, endDate)) { - const key = format(currentDate, 'yyyy-MM'); - if (!this.marketDataByMonth[key]) { - this.marketDataByMonth[key] = {}; - } + let currentDate = startDate; - currentDate = addMonths(currentDate, 1); + while (isBefore(currentDate, endDate)) { + const key = format(currentDate, 'yyyy-MM'); + if (!this.marketDataByMonth[key]) { + this.marketDataByMonth[key] = {}; + } + + currentDate = addMonths(currentDate, 1); + } } } } + public formatDay(day: number): string { + return day < 10 ? `0${day}` : `${day}`; + } + public isDateOfInterest(aDateString: string) { // Date is valid and in the past const date = parse(aDateString, DATE_FORMAT, new Date()); @@ -201,7 +222,8 @@ export class GfHistoricalMarketDataEditorComponent const dialogRef = this.dialog.open< GfHistoricalMarketDataEditorDialogComponent, - HistoricalMarketDataEditorDialogParams + HistoricalMarketDataEditorDialogParams, + { withRefresh: boolean } >(GfHistoricalMarketDataEditorDialogComponent, { data: { marketPrice, @@ -211,13 +233,13 @@ export class GfHistoricalMarketDataEditorComponent symbol: this.symbol, user: this.user }, - height: this.deviceType === 'mobile' ? '98vh' : '80vh', - width: this.deviceType === 'mobile' ? '100vw' : '50rem' + height: this.deviceType() === 'mobile' ? '98vh' : '80vh', + width: this.deviceType() === 'mobile' ? '100vw' : '50rem' }); dialogRef .afterClosed() - .pipe(takeUntil(this.unsubscribeSubject)) + .pipe(takeUntilDestroyed(this.destroyRef)) .subscribe(({ withRefresh } = { withRefresh: false }) => { this.marketDataChanged.emit(withRefresh); }); @@ -225,15 +247,15 @@ export class GfHistoricalMarketDataEditorComponent public onImportHistoricalData() { try { - const marketData = csvToJson( - this.historicalDataForm.controls['historicalData'].controls['csvString'] - .value, + const marketData = csvToJson( + this.historicalDataForm.controls.historicalData.controls.csvString + .value ?? '', { dynamicTyping: true, header: true, skipEmptyLines: true } - ).data as UpdateMarketDataDto[]; + ).data; this.dataService .postMarketData({ @@ -244,13 +266,13 @@ export class GfHistoricalMarketDataEditorComponent symbol: this.symbol }) .pipe( - catchError(({ error, message }) => { + catchError(({ error, message }: HttpErrorResponse) => { this.snackBar.open(`${error}: ${message[0]}`, undefined, { duration: ms('3 seconds') }); return EMPTY; }), - takeUntil(this.unsubscribeSubject) + takeUntilDestroyed(this.destroyRef) ) .subscribe(() => { this.initializeHistoricalDataForm(); @@ -268,11 +290,6 @@ export class GfHistoricalMarketDataEditorComponent } } - public ngOnDestroy() { - this.unsubscribeSubject.next(); - this.unsubscribeSubject.complete(); - } - private initializeHistoricalDataForm() { this.historicalDataForm.setValue({ historicalData: { From 0d67478cc3c1e180397f9e6950c0f48a54ea750a Mon Sep 17 00:00:00 2001 From: Thomas Kaul <4159106+dtslvr@users.noreply.github.com> Date: Wed, 18 Feb 2026 20:54:12 +0100 Subject: [PATCH 024/224] Task/harmonize validation for create activity endpoint with existing import activity logic (#6349) * Harmonize validation * Update changelog --- CHANGELOG.md | 1 + apps/api/src/app/import/import.service.ts | 134 +----------------- apps/api/src/app/order/order.controller.ts | 25 ++++ .../data-provider/data-provider.service.ts | 118 +++++++++++++++ 4 files changed, 146 insertions(+), 132 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index bb9b2e676..2e2312b89 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,6 +14,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Changed +- Harmonized the validation for the create activity endpoint with the existing import activity logic - Upgraded `marked` from version `17.0.1` to `17.0.2` - Upgraded `ngx-markdown` from version `21.0.1` to `21.1.0` diff --git a/apps/api/src/app/import/import.service.ts b/apps/api/src/app/import/import.service.ts index a787927b5..497b8a7e9 100644 --- a/apps/api/src/app/import/import.service.ts +++ b/apps/api/src/app/import/import.service.ts @@ -3,7 +3,6 @@ import { OrderService } from '@ghostfolio/api/app/order/order.service'; import { PlatformService } from '@ghostfolio/api/app/platform/platform.service'; import { PortfolioService } from '@ghostfolio/api/app/portfolio/portfolio.service'; import { ApiService } from '@ghostfolio/api/services/api/api.service'; -import { ConfigurationService } from '@ghostfolio/api/services/configuration/configuration.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 { MarketDataService } from '@ghostfolio/api/services/market-data/market-data.service'; @@ -33,7 +32,7 @@ import { } from '@ghostfolio/common/types'; import { Injectable } from '@nestjs/common'; -import { DataSource, Prisma, SymbolProfile } from '@prisma/client'; +import { DataSource, Prisma } from '@prisma/client'; import { Big } from 'big.js'; import { endOfToday, isAfter, isSameSecond, parseISO } from 'date-fns'; import { omit, uniqBy } from 'lodash'; @@ -46,7 +45,6 @@ export class ImportService { public constructor( private readonly accountService: AccountService, private readonly apiService: ApiService, - private readonly configurationService: ConfigurationService, private readonly dataGatheringService: DataGatheringService, private readonly dataProviderService: DataProviderService, private readonly exchangeRateDataService: ExchangeRateDataService, @@ -395,7 +393,7 @@ export class ImportService { } } - const assetProfiles = await this.validateActivities({ + const assetProfiles = await this.dataProviderService.validateActivities({ activitiesDto, assetProfilesWithMarketDataDto, maxActivitiesToImport, @@ -729,132 +727,4 @@ export class ImportService { return uniqueAccountIds.size === 1; } - - private async validateActivities({ - activitiesDto, - assetProfilesWithMarketDataDto, - maxActivitiesToImport, - user - }: { - activitiesDto: Partial[]; - assetProfilesWithMarketDataDto: ImportDataDto['assetProfiles']; - maxActivitiesToImport: number; - user: UserWithSettings; - }) { - if (activitiesDto?.length > maxActivitiesToImport) { - throw new Error(`Too many activities (${maxActivitiesToImport} at most)`); - } - - const assetProfiles: { - [assetProfileIdentifier: string]: Partial; - } = {}; - const dataSources = await this.dataProviderService.getDataSources(); - - for (const [ - index, - { currency, dataSource, symbol, type } - ] of activitiesDto.entries()) { - if (!dataSources.includes(dataSource)) { - throw new Error( - `activities.${index}.dataSource ("${dataSource}") is not valid` - ); - } - - if ( - this.configurationService.get('ENABLE_FEATURE_SUBSCRIPTION') && - user.subscription.type === 'Basic' - ) { - const dataProvider = this.dataProviderService.getDataProvider( - DataSource[dataSource] - ); - - if (dataProvider.getDataProviderInfo().isPremium) { - throw new Error( - `activities.${index}.dataSource ("${dataSource}") is not valid` - ); - } - } - - if (!assetProfiles[getAssetProfileIdentifier({ dataSource, symbol })]) { - if (['FEE', 'INTEREST', 'LIABILITY'].includes(type)) { - // Skip asset profile validation for FEE, INTEREST, and LIABILITY - // as these activity types don't require asset profiles - const assetProfileInImport = assetProfilesWithMarketDataDto?.find( - (profile) => { - return ( - profile.dataSource === dataSource && profile.symbol === symbol - ); - } - ); - - assetProfiles[getAssetProfileIdentifier({ dataSource, symbol })] = { - currency, - dataSource, - symbol, - name: assetProfileInImport?.name - }; - - continue; - } - - let assetProfile: Partial = { currency }; - - try { - assetProfile = ( - await this.dataProviderService.getAssetProfiles([ - { dataSource, symbol } - ]) - )?.[symbol]; - } catch {} - - if (!assetProfile?.name) { - const assetProfileInImport = assetProfilesWithMarketDataDto?.find( - (profile) => { - return ( - profile.dataSource === dataSource && profile.symbol === symbol - ); - } - ); - - if (assetProfileInImport) { - // Merge all fields of custom asset profiles into the validation object - Object.assign(assetProfile, { - assetClass: assetProfileInImport.assetClass, - assetSubClass: assetProfileInImport.assetSubClass, - comment: assetProfileInImport.comment, - countries: assetProfileInImport.countries, - currency: assetProfileInImport.currency, - cusip: assetProfileInImport.cusip, - dataSource: assetProfileInImport.dataSource, - figi: assetProfileInImport.figi, - figiComposite: assetProfileInImport.figiComposite, - figiShareClass: assetProfileInImport.figiShareClass, - holdings: assetProfileInImport.holdings, - isActive: assetProfileInImport.isActive, - isin: assetProfileInImport.isin, - name: assetProfileInImport.name, - scraperConfiguration: assetProfileInImport.scraperConfiguration, - sectors: assetProfileInImport.sectors, - symbol: assetProfileInImport.symbol, - symbolMapping: assetProfileInImport.symbolMapping, - url: assetProfileInImport.url - }); - } - } - - if (!['FEE', 'INTEREST', 'LIABILITY'].includes(type)) { - if (!assetProfile?.name) { - throw new Error( - `activities.${index}.symbol ("${symbol}") is not valid for the specified data source ("${dataSource}")` - ); - } - } - - assetProfiles[getAssetProfileIdentifier({ dataSource, symbol })] = - assetProfile; - } - } - - return assetProfiles; - } } diff --git a/apps/api/src/app/order/order.controller.ts b/apps/api/src/app/order/order.controller.ts index 73c295f1b..c7021809e 100644 --- a/apps/api/src/app/order/order.controller.ts +++ b/apps/api/src/app/order/order.controller.ts @@ -4,6 +4,7 @@ import { RedactValuesInResponseInterceptor } from '@ghostfolio/api/interceptors/ import { TransformDataSourceInRequestInterceptor } from '@ghostfolio/api/interceptors/transform-data-source-in-request/transform-data-source-in-request.interceptor'; import { TransformDataSourceInResponseInterceptor } from '@ghostfolio/api/interceptors/transform-data-source-in-response/transform-data-source-in-response.interceptor'; import { ApiService } from '@ghostfolio/api/services/api/api.service'; +import { DataProviderService } from '@ghostfolio/api/services/data-provider/data-provider.service'; import { ImpersonationService } from '@ghostfolio/api/services/impersonation/impersonation.service'; import { DataGatheringService } from '@ghostfolio/api/services/queues/data-gathering/data-gathering.service'; import { getIntervalFromDateRange } from '@ghostfolio/common/calculation-helper'; @@ -46,6 +47,7 @@ import { OrderService } from './order.service'; export class OrderController { public constructor( private readonly apiService: ApiService, + private readonly dataProviderService: DataProviderService, private readonly dataGatheringService: DataGatheringService, private readonly impersonationService: ImpersonationService, private readonly orderService: OrderService, @@ -190,6 +192,29 @@ export class OrderController { @UseGuards(AuthGuard('jwt'), HasPermissionGuard) @UseInterceptors(TransformDataSourceInRequestInterceptor) public async createOrder(@Body() data: CreateOrderDto): Promise { + try { + await this.dataProviderService.validateActivities({ + activitiesDto: [ + { + currency: data.currency, + dataSource: data.dataSource, + symbol: data.symbol, + type: data.type + } + ], + maxActivitiesToImport: 1, + user: this.request.user + }); + } catch (error) { + throw new HttpException( + { + error: getReasonPhrase(StatusCodes.BAD_REQUEST), + message: [error.message] + }, + StatusCodes.BAD_REQUEST + ); + } + const currency = data.currency; const customCurrency = data.customCurrency; const dataSource = data.dataSource; diff --git a/apps/api/src/services/data-provider/data-provider.service.ts b/apps/api/src/services/data-provider/data-provider.service.ts index 5a088c0e4..eb9816c67 100644 --- a/apps/api/src/services/data-provider/data-provider.service.ts +++ b/apps/api/src/services/data-provider/data-provider.service.ts @@ -1,3 +1,4 @@ +import { ImportDataDto } from '@ghostfolio/api/app/import/import-data.dto'; import { RedisCacheService } from '@ghostfolio/api/app/redis-cache/redis-cache.service'; import { ConfigurationService } from '@ghostfolio/api/services/configuration/configuration.service'; import { DataProviderInterface } from '@ghostfolio/api/services/data-provider/interfaces/data-provider.interface'; @@ -10,8 +11,10 @@ import { PROPERTY_API_KEY_GHOSTFOLIO, PROPERTY_DATA_SOURCE_MAPPING } from '@ghostfolio/common/config'; +import { CreateOrderDto } from '@ghostfolio/common/dtos'; import { DATE_FORMAT, + getAssetProfileIdentifier, getCurrencyFromSymbol, getStartOfUtcDate, isCurrency, @@ -185,6 +188,121 @@ export class DataProviderService implements OnModuleInit { return dataSources.sort(); } + public async validateActivities({ + activitiesDto, + assetProfilesWithMarketDataDto, + maxActivitiesToImport, + user + }: { + activitiesDto: Pick< + Partial, + 'currency' | 'dataSource' | 'symbol' | 'type' + >[]; + assetProfilesWithMarketDataDto?: ImportDataDto['assetProfiles']; + maxActivitiesToImport: number; + user: UserWithSettings; + }) { + if (activitiesDto?.length > maxActivitiesToImport) { + throw new Error(`Too many activities (${maxActivitiesToImport} at most)`); + } + + const assetProfiles: { + [assetProfileIdentifier: string]: Partial; + } = {}; + + const dataSources = await this.getDataSources(); + + for (const [ + index, + { currency, dataSource, symbol, type } + ] of activitiesDto.entries()) { + const activityPath = + maxActivitiesToImport === 1 ? 'activity' : `activities.${index}`; + + if (!dataSources.includes(dataSource)) { + throw new Error( + `${activityPath}.dataSource ("${dataSource}") is not valid` + ); + } + + if ( + this.configurationService.get('ENABLE_FEATURE_SUBSCRIPTION') && + user.subscription.type === 'Basic' + ) { + const dataProvider = this.getDataProvider(DataSource[dataSource]); + + if (dataProvider.getDataProviderInfo().isPremium) { + throw new Error( + `${activityPath}.dataSource ("${dataSource}") is not valid` + ); + } + } + + const assetProfileIdentifier = getAssetProfileIdentifier({ + dataSource, + symbol + }); + + if (!assetProfiles[assetProfileIdentifier]) { + if (['FEE', 'INTEREST', 'LIABILITY'].includes(type)) { + const assetProfileInImport = assetProfilesWithMarketDataDto?.find( + (profile) => { + return ( + profile.dataSource === dataSource && profile.symbol === symbol + ); + } + ); + + assetProfiles[assetProfileIdentifier] = { + currency, + dataSource, + symbol, + name: assetProfileInImport?.name + }; + + continue; + } + + let assetProfile: Partial = { currency }; + + try { + assetProfile = ( + await this.getAssetProfiles([ + { + dataSource, + symbol + } + ]) + )?.[symbol]; + } catch {} + + if (!assetProfile?.name) { + const assetProfileInImport = assetProfilesWithMarketDataDto?.find( + (profile) => { + return ( + profile.dataSource === dataSource && profile.symbol === symbol + ); + } + ); + + if (assetProfileInImport) { + Object.assign(assetProfile, assetProfileInImport); + } + } + + if (!assetProfile?.name) { + throw new Error( + `activities.${index}.symbol ("${symbol}") is not valid for the specified data source ("${dataSource}")` + ); + } + + assetProfiles[assetProfileIdentifier] = assetProfile; + } + } + + return assetProfiles; + } + public async getDividends({ dataSource, from, From 117a938bad9c2d1bd62123d5d06964694b5eceb9 Mon Sep 17 00:00:00 2001 From: David Requeno <108202767+DavidReque@users.noreply.github.com> Date: Wed, 18 Feb 2026 14:04:37 -0600 Subject: [PATCH 025/224] Feature/add new market data preset (#6346) * Add new market data preset (no activities) * Update changelog --- CHANGELOG.md | 1 + apps/api/src/app/admin/admin.service.ts | 4 ++++ .../admin-market-data/admin-market-data.component.ts | 5 +++++ libs/common/src/lib/types/market-data-preset.type.ts | 3 ++- 4 files changed, 12 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2e2312b89..ea423e8f4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Added +- Added a _No Activities_ preset to the historical market data table of the admin control panel - Added support for custom cryptocurrencies defined in the database - Added support for the cryptocurrency _Sky_ diff --git a/apps/api/src/app/admin/admin.service.ts b/apps/api/src/app/admin/admin.service.ts index 2cc8bbfb8..d77fde346 100644 --- a/apps/api/src/app/admin/admin.service.ts +++ b/apps/api/src/app/admin/admin.service.ts @@ -225,6 +225,10 @@ export class AdminService { presetId === 'ETF_WITHOUT_SECTORS' ) { filters = [{ id: 'ETF', type: 'ASSET_SUB_CLASS' }]; + } else if (presetId === 'NO_ACTIVITIES') { + where.activities = { + none: {} + }; } const searchQuery = filters.find(({ type }) => { diff --git a/apps/client/src/app/components/admin-market-data/admin-market-data.component.ts b/apps/client/src/app/components/admin-market-data/admin-market-data.component.ts index 8f956b782..6a079c20a 100644 --- a/apps/client/src/app/components/admin-market-data/admin-market-data.component.ts +++ b/apps/client/src/app/components/admin-market-data/admin-market-data.component.ts @@ -140,6 +140,11 @@ export class GfAdminMarketDataComponent id: 'ETF_WITHOUT_SECTORS', label: $localize`ETFs without Sectors`, type: 'PRESET_ID' as Filter['type'] + }, + { + id: 'NO_ACTIVITIES', + label: $localize`No Activities`, + type: 'PRESET_ID' as Filter['type'] } ]; public benchmarks: Partial[]; diff --git a/libs/common/src/lib/types/market-data-preset.type.ts b/libs/common/src/lib/types/market-data-preset.type.ts index 0dbf914fa..2622feac3 100644 --- a/libs/common/src/lib/types/market-data-preset.type.ts +++ b/libs/common/src/lib/types/market-data-preset.type.ts @@ -2,4 +2,5 @@ export type MarketDataPreset = | 'BENCHMARKS' | 'CURRENCIES' | 'ETF_WITHOUT_COUNTRIES' - | 'ETF_WITHOUT_SECTORS'; + | 'ETF_WITHOUT_SECTORS' + | 'NO_ACTIVITIES'; From 2ef9c01d8dfbd85f2c219f395d84c93c306ca939 Mon Sep 17 00:00:00 2001 From: Thomas Kaul <4159106+dtslvr@users.noreply.github.com> Date: Wed, 18 Feb 2026 21:07:17 +0100 Subject: [PATCH 026/224] Release 2.240.0 (#6351) --- CHANGELOG.md | 2 +- package-lock.json | 4 ++-- package.json | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ea423e8f4..3a9c1b3c7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,7 +5,7 @@ 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 +## 2.240.0 - 2026-02-18 ### Added diff --git a/package-lock.json b/package-lock.json index 44d479e7f..636147048 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "ghostfolio", - "version": "2.239.0", + "version": "2.240.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "ghostfolio", - "version": "2.239.0", + "version": "2.240.0", "hasInstallScript": true, "license": "AGPL-3.0", "dependencies": { diff --git a/package.json b/package.json index aaf9df90e..4bfdd1cb1 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "ghostfolio", - "version": "2.239.0", + "version": "2.240.0", "homepage": "https://ghostfol.io", "license": "AGPL-3.0", "repository": "https://github.com/ghostfolio/ghostfolio", From b888005144ca24ae7fd301f2d5d48d6b2bfd71a9 Mon Sep 17 00:00:00 2001 From: Thomas Kaul <4159106+dtslvr@users.noreply.github.com> Date: Thu, 19 Feb 2026 07:59:46 +0100 Subject: [PATCH 027/224] Task/refresh cryptocurrencies list 20260216 (#6342) * Update cryptocurrencies.json * Update changelog --- CHANGELOG.md | 6 +++ .../cryptocurrencies/cryptocurrencies.json | 43 +++++++++++++++---- 2 files changed, 40 insertions(+), 9 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3a9c1b3c7..4aa50fcb5 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 + +- Refreshed the cryptocurrencies list + ## 2.240.0 - 2026-02-18 ### Added diff --git a/apps/api/src/assets/cryptocurrencies/cryptocurrencies.json b/apps/api/src/assets/cryptocurrencies/cryptocurrencies.json index e456f6f1d..d00ded6ef 100644 --- a/apps/api/src/assets/cryptocurrencies/cryptocurrencies.json +++ b/apps/api/src/assets/cryptocurrencies/cryptocurrencies.json @@ -421,6 +421,7 @@ "AGS": "Aegis", "AGT": "Alaya Governance Token", "AGURI": "Aguri-Chan", + "AGUSTO": "Agusto", "AGV": "Astra Guild Ventures", "AGVC": "AgaveCoin", "AGVE": "Agave", @@ -662,6 +663,7 @@ "ALN": "Aluna", "ALNV1": "Aluna v1", "ALOHA": "Aloha", + "ALOKA": "ALOKA", "ALON": "Alon", "ALOR": "The Algorix", "ALOT": "Dexalot", @@ -708,6 +710,7 @@ "AMADEUS": "AMADEUS", "AMAL": "AMAL", "AMAPT": "Amnis Finance", + "AMARA": "AMARA", "AMATEN": "Amaten", "AMATO": "AMATO", "AMAZINGTEAM": "AmazingTeamDAO", @@ -1344,6 +1347,7 @@ "AZIT": "Azit", "AZNX": "AstraZeneca xStock", "AZR": "Azure", + "AZTEC": "AZTEC", "AZU": "Azultec", "AZUKI": "Azuki", "AZUKI2": "AZUKI 2.0", @@ -1373,6 +1377,7 @@ "BABI": "Babylons", "BABL": "Babylon Finance", "BABY": "Babylon", + "BABY4": "Baby 4", "BABYANDY": "Baby Andy", "BABYASTER": "Baby Aster", "BABYB": "Baby Bali", @@ -2342,6 +2347,7 @@ "BNPL": "BNPL Pay", "BNR": "BiNeuro", "BNRTX": "BnrtxCoin", + "BNRY": "Binary Coin", "BNS": "BNS token", "BNSAI": "bonsAI Network", "BNSD": "BNSD Finance", @@ -2526,9 +2532,10 @@ "BOSSCOQ": "THE COQFATHER", "BOST": "BoostCoin", "BOSU": "Bosu Inu", - "BOT": "Bot Planet", + "BOT": "HyperBot", "BOTC": "BotChain", "BOTIFY": "BOTIFY", + "BOTPLANET": "Bot Planet", "BOTS": "ArkDAO", "BOTTO": "Botto", "BOTX": "BOTXCOIN", @@ -3201,6 +3208,7 @@ "CATCO": "CatCoin", "CATCOIN": "CatCoin", "CATCOINETH": "Catcoin", + "CATCOINIO": "Catcoin", "CATCOINOFSOL": "Cat Coin", "CATCOINV2": "CatCoin Cash", "CATDOG": "Cat-Dog", @@ -3583,6 +3591,7 @@ "CIC": "Crazy Internet Coin", "CICHAIN": "CIChain", "CIF": "Crypto Improvement Fund", + "CIFRON": "Cipher Mining (Ondo Tokenized)", "CIG": "cig", "CIM": "COINCOME", "CIN": "CinderCoin", @@ -3718,6 +3727,7 @@ "CMPT": "Spatial Computing", "CMPV2": "Caduceus Protocol", "CMQ": "Communique", + "CMR": "U.S Critical Mineral Reserve", "CMS": "COMSA", "CMSN": "The Commission", "CMT": "CyberMiles", @@ -4630,6 +4640,7 @@ "DEFIL": "DeFIL", "DEFILAB": "Defi", "DEFISCALE": "DeFiScale", + "DEFISSI": "DEFI.ssi", "DEFIT": "Digital Fitness", "DEFLA": "Defla", "DEFLCT": "Deflect", @@ -6323,7 +6334,7 @@ "FIFTY": "FIFTYONEFIFTY", "FIG": "FlowCom", "FIGH": "FIGHT FIGHT FIGHT", - "FIGHT": "Fight to MAGA", + "FIGHT2MAGA": "Fight to MAGA", "FIGHTMAGA": "FIGHT MAGA", "FIGHTPEPE": "FIGHT PEPE", "FIGHTRUMP": "FIGHT TRUMP", @@ -8039,6 +8050,7 @@ "HONOR": "HonorLand", "HONX": "Honeywell xStock", "HOODOG": "Hoodog", + "HOODON": "Robinhood Markets (Ondo Tokenized)", "HOODRAT": "Hoodrat Coin", "HOODX": "Robinhood xStock", "HOOF": "Metaderby Hoof", @@ -8395,6 +8407,7 @@ "IMS": "Independent Money System", "IMST": "Imsmart", "IMT": "Immortal Token", + "IMU": "Immunefi", "IMUSIFY": "imusify", "IMVR": "ImmVRse", "IMX": "Immutable X", @@ -8750,6 +8763,7 @@ "JFIVE": "Jonny Five", "JFOX": "JuniperFox AI", "JFP": "JUSTICE FOR PEANUT", + "JGGL": "JGGL Token", "JGLP": "Jones GLP", "JGN": "Juggernaut", "JHH": "Jen-Hsun Huang", @@ -9891,7 +9905,7 @@ "LRN": "Loopring [NEO]", "LRT": "LandRocker", "LSC": "LS Coin", - "LSD": "Pontem Liquidswap", + "LSD": "LSD", "LSDOGE": "LSDoge", "LSETH": "Liquid Staked ETH", "LSHARE": "LSHARE", @@ -10167,8 +10181,7 @@ "MANUSAI": "Manus AI Agent", "MANYU": "Manyu", "MANYUDOG": "MANYU", - "MAO": "MAO", - "MAOMEME": "Mao", + "MAO": "Mao", "MAOW": "MAOW", "MAP": "MAP Protocol", "MAPC": "MapCoin", @@ -10631,6 +10644,7 @@ "MICRO": "Micro GPT", "MICRODOGE": "MicroDoge", "MICROMINES": "Micromines", + "MICROVISION": "MicroVisionChain", "MIDAI": "Midway AI", "MIDAS": "Midas", "MIDASDOLLAR": "Midas Dollar Share", @@ -13146,6 +13160,7 @@ "PONKE": "Ponke", "PONKEBNB": "Ponke BNB", "PONKEI": "Chinese Ponkei the Original", + "PONTEM": "Pontem Liquidswap", "PONYO": "Ponyo Impact", "PONZI": "Ponzi", "PONZIO": "Ponzio The Cat", @@ -13573,6 +13588,7 @@ "QNX": "QueenDex Coin", "QOBI": "Qobit", "QOM": "Shiba Predator", + "QONE": "QONE", "QOOB": "QOOBER", "QORA": "QoraCoin", "QORPO": "QORPO WORLD", @@ -15153,6 +15169,7 @@ "SNAP": "SnapEx", "SNAPCAT": "Snapcat", "SNAPKERO": "SNAP", + "SNAPON": "Snap (Ondo Tokenized)", "SNB": "SynchroBitcoin", "SNC": "SunContract", "SNCT": "SnakeCity", @@ -15380,7 +15397,7 @@ "SP8DE": "Sp8de", "SPA": "Sperax", "SPAC": "SPACE DOGE", - "SPACE": "MicroVisionChain", + "SPACE": "Spacecoin", "SPACECOIN": "SpaceCoin", "SPACED": "SPACE DRAGON", "SPACEHAMSTER": "Space Hamster", @@ -15868,6 +15885,7 @@ "SUPERCYCLE": "Crypto SuperCycle", "SUPERDAPP": "SuperDapp", "SUPERF": "SUPER FLOKI", + "SUPERFL": "Superfluid", "SUPERGROK": "SuperGrok", "SUPEROETHB": "Super OETH", "SUPERT": "Super Trump", @@ -16790,6 +16808,7 @@ "TSLAON": "Tesla (Ondo Tokenized)", "TSLAX": "Tesla xStock", "TSLT": "Tamkin", + "TSMON": "Taiwan Semiconductor Manufacturing (Ondo Tokenized)", "TSN": "Tsunami Exchange Token", "TSO": "Thesirion", "TSOTCHKE": "tsotchke", @@ -17181,8 +17200,10 @@ "USDL": "Lift Dollar", "USDM": "USDM", "USDMA": "USD mars", - "USDN": "Neutral AI", + "USDN": "Ultimate Synthetic Delta Neutral", + "USDNEUTRAL": "Neutral AI", "USDO": "USD Open Dollar", + "USDON": "U.S. Dollar Tokenized Currency (Ondo)", "USDP": "Pax Dollar", "USDPLUS": "Overnight.fi USD+", "USDQ": "Quantoz USDQ", @@ -17456,6 +17477,7 @@ "VIDZ": "PureVidz", "VIEW": "Viewly", "VIG": "TheVig", + "VIGI": "Vigi", "VIK": "VIKTAMA", "VIKITA": "VIKITA", "VIKKY": "VikkyToken", @@ -17513,6 +17535,7 @@ "VLC": "Volcano Uni", "VLDY": "Validity", "VLK": "Vulkania", + "VLR": "Velora", "VLS": "Veles", "VLT": "Veltor", "VLTC": "Venus LTC", @@ -17733,6 +17756,7 @@ "WANUSDT": "wanUSDT", "WAP": "Wet Ass Pussy", "WAR": "WAR", + "WARD": "Warden", "WARP": "WarpCoin", "WARPED": "Warped Games", "WARPIE": "Warpie", @@ -18494,6 +18518,7 @@ "XP": "Xphere", "XPA": "XPA", "XPARTY": "X Party", + "XPASS": "XPASS Token", "XPAT": "Bitnation Pangea", "XPAY": "Wallet Pay", "XPB": "Pebble Coin", @@ -18869,8 +18894,7 @@ "ZEBU": "ZEBU", "ZEC": "ZCash", "ZECD": "ZCashDarkCoin", - "ZED": "ZED Token", - "ZEDCOIN": "ZedCoin", + "ZED": "ZedCoins", "ZEDD": "ZedDex", "ZEDTOKEN": "Zed Token", "ZEDX": "ZEDX Сoin", @@ -19108,6 +19132,7 @@ "币安人生": "币安人生", "恶俗企鹅": "恶俗企鹅", "我踏马来了": "我踏马来了", + "狗屎": "狗屎", "老子": "老子", "雪球": "雪球", "黑马": "黑马" From bccc52e83acf43882e36e184ebd00105c69e543a Mon Sep 17 00:00:00 2001 From: slegarraga <64795732+slegarraga@users.noreply.github.com> Date: Thu, 19 Feb 2026 13:48:16 -0300 Subject: [PATCH 028/224] Task/improve language localization for ES 20260219 (#6353) * Improve language localization * Update changelog --- CHANGELOG.md | 1 + apps/client/src/locales/messages.es.xlf | 8 ++++---- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4aa50fcb5..c7188d7db 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Changed - Refreshed the cryptocurrencies list +- Improved the language localization for Spanish (`es`) ## 2.240.0 - 2026-02-18 diff --git a/apps/client/src/locales/messages.es.xlf b/apps/client/src/locales/messages.es.xlf index fb4773203..77d82abbd 100644 --- a/apps/client/src/locales/messages.es.xlf +++ b/apps/client/src/locales/messages.es.xlf @@ -7883,7 +7883,7 @@ Fee Ratio (legacy) - Relación de tarifas + Relación de tarifas (heredado) apps/client/src/app/pages/i18n/i18n-page.html 152 @@ -7907,7 +7907,7 @@ Fee Ratio - Fee Ratio + Relación de tarifas apps/client/src/app/pages/i18n/i18n-page.html 161 @@ -7915,7 +7915,7 @@ The fees do exceed ${thresholdMax}% of your total investment volume (${feeRatio}%) - The fees do exceed ${thresholdMax}% of your total investment volume (${feeRatio}%) + Las tarifas superan el ${thresholdMax}% de su volumen total de inversión (${feeRatio}%) apps/client/src/app/pages/i18n/i18n-page.html 163 @@ -7923,7 +7923,7 @@ The fees do not exceed ${thresholdMax}% of your total investment volume (${feeRatio}%) - The fees do not exceed ${thresholdMax}% of your total investment volume (${feeRatio}%) + Las tarifas no superan el ${thresholdMax}% de su volumen total de inversión (${feeRatio}%) apps/client/src/app/pages/i18n/i18n-page.html 167 From 6afba53fa778c6378b3314e3db48b304e4fd9005 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Thu, 19 Feb 2026 18:07:17 +0100 Subject: [PATCH 029/224] Task/update locales (#6274) * Update locales --- apps/client/src/locales/messages.ca.xlf | 20 ++++++++++++++------ apps/client/src/locales/messages.de.xlf | 20 ++++++++++++++------ apps/client/src/locales/messages.es.xlf | 20 ++++++++++++++------ apps/client/src/locales/messages.fr.xlf | 20 ++++++++++++++------ apps/client/src/locales/messages.it.xlf | 20 ++++++++++++++------ apps/client/src/locales/messages.ko.xlf | 20 ++++++++++++++------ apps/client/src/locales/messages.nl.xlf | 20 ++++++++++++++------ apps/client/src/locales/messages.pl.xlf | 20 ++++++++++++++------ apps/client/src/locales/messages.pt.xlf | 20 ++++++++++++++------ apps/client/src/locales/messages.tr.xlf | 20 ++++++++++++++------ apps/client/src/locales/messages.uk.xlf | 20 ++++++++++++++------ apps/client/src/locales/messages.xlf | 19 +++++++++++++------ apps/client/src/locales/messages.zh.xlf | 20 ++++++++++++++------ 13 files changed, 181 insertions(+), 78 deletions(-) diff --git a/apps/client/src/locales/messages.ca.xlf b/apps/client/src/locales/messages.ca.xlf index 6400807bd..585a3d779 100644 --- a/apps/client/src/locales/messages.ca.xlf +++ b/apps/client/src/locales/messages.ca.xlf @@ -895,7 +895,7 @@ Filtra per... apps/client/src/app/components/admin-market-data/admin-market-data.component.ts - 385 + 390 @@ -935,7 +935,7 @@ libs/ui/src/lib/historical-market-data-editor/historical-market-data-editor.component.html - 44 + 40 @@ -1003,7 +1003,7 @@ Oooh! No s’han pogut recopilar les dades históriques. libs/ui/src/lib/historical-market-data-editor/historical-market-data-editor.component.ts - 262 + 284 @@ -1035,7 +1035,7 @@ libs/ui/src/lib/historical-market-data-editor/historical-market-data-editor.component.html - 71 + 67 @@ -5924,6 +5924,14 @@ 27 + + No Activities + No Activities + + apps/client/src/app/components/admin-market-data/admin-market-data.component.ts + 146 + + Retirement Provision Provisió de jubilació @@ -6757,7 +6765,7 @@ libs/ui/src/lib/historical-market-data-editor/historical-market-data-editor-dialog/historical-market-data-editor-dialog.html - 46 + 47 libs/ui/src/lib/i18n.ts @@ -7335,7 +7343,7 @@ libs/ui/src/lib/historical-market-data-editor/historical-market-data-editor-dialog/historical-market-data-editor-dialog.html - 48 + 49 diff --git a/apps/client/src/locales/messages.de.xlf b/apps/client/src/locales/messages.de.xlf index 2be7713eb..38f0b4c66 100644 --- a/apps/client/src/locales/messages.de.xlf +++ b/apps/client/src/locales/messages.de.xlf @@ -506,7 +506,7 @@ libs/ui/src/lib/historical-market-data-editor/historical-market-data-editor.component.html - 44 + 40 @@ -2630,7 +2630,7 @@ Filtern nach... apps/client/src/app/components/admin-market-data/admin-market-data.component.ts - 385 + 390 @@ -3234,7 +3234,7 @@ libs/ui/src/lib/historical-market-data-editor/historical-market-data-editor.component.html - 71 + 67 @@ -3357,6 +3357,14 @@ 22 + + No Activities + No Activities + + apps/client/src/app/components/admin-market-data/admin-market-data.component.ts + 146 + + Retirement Provision Altersvorsorge @@ -5716,7 +5724,7 @@ Ups! Die historischen Daten konnten nicht geparsed werden. libs/ui/src/lib/historical-market-data-editor/historical-market-data-editor.component.ts - 262 + 284 @@ -6781,7 +6789,7 @@ libs/ui/src/lib/historical-market-data-editor/historical-market-data-editor-dialog/historical-market-data-editor-dialog.html - 46 + 47 libs/ui/src/lib/i18n.ts @@ -7359,7 +7367,7 @@ libs/ui/src/lib/historical-market-data-editor/historical-market-data-editor-dialog/historical-market-data-editor-dialog.html - 48 + 49 diff --git a/apps/client/src/locales/messages.es.xlf b/apps/client/src/locales/messages.es.xlf index 77d82abbd..ceb7d5b06 100644 --- a/apps/client/src/locales/messages.es.xlf +++ b/apps/client/src/locales/messages.es.xlf @@ -507,7 +507,7 @@ libs/ui/src/lib/historical-market-data-editor/historical-market-data-editor.component.html - 44 + 40 @@ -2615,7 +2615,7 @@ Filtrar por... apps/client/src/app/components/admin-market-data/admin-market-data.component.ts - 385 + 390 @@ -3219,7 +3219,7 @@ libs/ui/src/lib/historical-market-data-editor/historical-market-data-editor.component.html - 71 + 67 @@ -3342,6 +3342,14 @@ 22 + + No Activities + No Activities + + apps/client/src/app/components/admin-market-data/admin-market-data.component.ts + 146 + + Retirement Provision Provisión de jubilación @@ -5693,7 +5701,7 @@ ¡Ups! No se pudieron analizar los datos históricos. libs/ui/src/lib/historical-market-data-editor/historical-market-data-editor.component.ts - 262 + 284 @@ -6758,7 +6766,7 @@ libs/ui/src/lib/historical-market-data-editor/historical-market-data-editor-dialog/historical-market-data-editor-dialog.html - 46 + 47 libs/ui/src/lib/i18n.ts @@ -7336,7 +7344,7 @@ libs/ui/src/lib/historical-market-data-editor/historical-market-data-editor-dialog/historical-market-data-editor-dialog.html - 48 + 49 diff --git a/apps/client/src/locales/messages.fr.xlf b/apps/client/src/locales/messages.fr.xlf index 8cb2b2f48..f3a8d4942 100644 --- a/apps/client/src/locales/messages.fr.xlf +++ b/apps/client/src/locales/messages.fr.xlf @@ -530,7 +530,7 @@ Filtrer par... apps/client/src/app/components/admin-market-data/admin-market-data.component.ts - 385 + 390 @@ -570,7 +570,7 @@ libs/ui/src/lib/historical-market-data-editor/historical-market-data-editor.component.html - 44 + 40 @@ -2222,7 +2222,7 @@ libs/ui/src/lib/historical-market-data-editor/historical-market-data-editor.component.html - 71 + 67 @@ -3341,6 +3341,14 @@ 22 + + No Activities + No Activities + + apps/client/src/app/components/admin-market-data/admin-market-data.component.ts + 146 + + Retirement Provision Réserve pour retraite @@ -5692,7 +5700,7 @@ Oops! Echec du parsing des données historiques. libs/ui/src/lib/historical-market-data-editor/historical-market-data-editor.component.ts - 262 + 284 @@ -6757,7 +6765,7 @@ libs/ui/src/lib/historical-market-data-editor/historical-market-data-editor-dialog/historical-market-data-editor-dialog.html - 46 + 47 libs/ui/src/lib/i18n.ts @@ -7335,7 +7343,7 @@ libs/ui/src/lib/historical-market-data-editor/historical-market-data-editor-dialog/historical-market-data-editor-dialog.html - 48 + 49 diff --git a/apps/client/src/locales/messages.it.xlf b/apps/client/src/locales/messages.it.xlf index 61b08b673..f021dae49 100644 --- a/apps/client/src/locales/messages.it.xlf +++ b/apps/client/src/locales/messages.it.xlf @@ -507,7 +507,7 @@ libs/ui/src/lib/historical-market-data-editor/historical-market-data-editor.component.html - 44 + 40 @@ -2615,7 +2615,7 @@ Filtra per... apps/client/src/app/components/admin-market-data/admin-market-data.component.ts - 385 + 390 @@ -3219,7 +3219,7 @@ libs/ui/src/lib/historical-market-data-editor/historical-market-data-editor.component.html - 71 + 67 @@ -3342,6 +3342,14 @@ 22 + + No Activities + No Activities + + apps/client/src/app/components/admin-market-data/admin-market-data.component.ts + 146 + + Retirement Provision Fondo pensione @@ -5693,7 +5701,7 @@ Ops! Impossibile elaborare i dati storici. libs/ui/src/lib/historical-market-data-editor/historical-market-data-editor.component.ts - 262 + 284 @@ -6758,7 +6766,7 @@ libs/ui/src/lib/historical-market-data-editor/historical-market-data-editor-dialog/historical-market-data-editor-dialog.html - 46 + 47 libs/ui/src/lib/i18n.ts @@ -7336,7 +7344,7 @@ libs/ui/src/lib/historical-market-data-editor/historical-market-data-editor-dialog/historical-market-data-editor-dialog.html - 48 + 49 diff --git a/apps/client/src/locales/messages.ko.xlf b/apps/client/src/locales/messages.ko.xlf index 22c06b596..f188d4924 100644 --- a/apps/client/src/locales/messages.ko.xlf +++ b/apps/client/src/locales/messages.ko.xlf @@ -792,7 +792,7 @@ 다음 기준으로 필터... apps/client/src/app/components/admin-market-data/admin-market-data.component.ts - 385 + 390 @@ -832,7 +832,7 @@ libs/ui/src/lib/historical-market-data-editor/historical-market-data-editor.component.html - 44 + 40 @@ -884,7 +884,7 @@ 이런! 과거 데이터를 파싱할 수 없습니다. libs/ui/src/lib/historical-market-data-editor/historical-market-data-editor.component.ts - 262 + 284 @@ -916,7 +916,7 @@ libs/ui/src/lib/historical-market-data-editor/historical-market-data-editor.component.html - 71 + 67 @@ -5376,6 +5376,14 @@ 27 + + No Activities + No Activities + + apps/client/src/app/components/admin-market-data/admin-market-data.component.ts + 146 + + Retirement Provision 퇴직금 @@ -6742,7 +6750,7 @@ libs/ui/src/lib/historical-market-data-editor/historical-market-data-editor-dialog/historical-market-data-editor-dialog.html - 46 + 47 libs/ui/src/lib/i18n.ts @@ -7360,7 +7368,7 @@ libs/ui/src/lib/historical-market-data-editor/historical-market-data-editor-dialog/historical-market-data-editor-dialog.html - 48 + 49 diff --git a/apps/client/src/locales/messages.nl.xlf b/apps/client/src/locales/messages.nl.xlf index c79ecc1d3..76a74e6fd 100644 --- a/apps/client/src/locales/messages.nl.xlf +++ b/apps/client/src/locales/messages.nl.xlf @@ -506,7 +506,7 @@ libs/ui/src/lib/historical-market-data-editor/historical-market-data-editor.component.html - 44 + 40 @@ -2614,7 +2614,7 @@ Filter op... apps/client/src/app/components/admin-market-data/admin-market-data.component.ts - 385 + 390 @@ -3218,7 +3218,7 @@ libs/ui/src/lib/historical-market-data-editor/historical-market-data-editor.component.html - 71 + 67 @@ -3341,6 +3341,14 @@ 22 + + No Activities + No Activities + + apps/client/src/app/components/admin-market-data/admin-market-data.component.ts + 146 + + Retirement Provision Pensioen @@ -5692,7 +5700,7 @@ Oeps! Ophalen van historische data is mislukt. libs/ui/src/lib/historical-market-data-editor/historical-market-data-editor.component.ts - 262 + 284 @@ -6757,7 +6765,7 @@ libs/ui/src/lib/historical-market-data-editor/historical-market-data-editor-dialog/historical-market-data-editor-dialog.html - 46 + 47 libs/ui/src/lib/i18n.ts @@ -7335,7 +7343,7 @@ libs/ui/src/lib/historical-market-data-editor/historical-market-data-editor-dialog/historical-market-data-editor-dialog.html - 48 + 49 diff --git a/apps/client/src/locales/messages.pl.xlf b/apps/client/src/locales/messages.pl.xlf index a7c72f3ca..fdc528254 100644 --- a/apps/client/src/locales/messages.pl.xlf +++ b/apps/client/src/locales/messages.pl.xlf @@ -783,7 +783,7 @@ Filtruj według... apps/client/src/app/components/admin-market-data/admin-market-data.component.ts - 385 + 390 @@ -823,7 +823,7 @@ libs/ui/src/lib/historical-market-data-editor/historical-market-data-editor.component.html - 44 + 40 @@ -859,7 +859,7 @@ Ups! Nie udało się sparsować danych historycznych. libs/ui/src/lib/historical-market-data-editor/historical-market-data-editor.component.ts - 262 + 284 @@ -883,7 +883,7 @@ libs/ui/src/lib/historical-market-data-editor/historical-market-data-editor.component.html - 71 + 67 @@ -5307,6 +5307,14 @@ 27 + + No Activities + No Activities + + apps/client/src/app/components/admin-market-data/admin-market-data.component.ts + 146 + + Retirement Provision Świadczenia Emerytalne @@ -6757,7 +6765,7 @@ libs/ui/src/lib/historical-market-data-editor/historical-market-data-editor-dialog/historical-market-data-editor-dialog.html - 46 + 47 libs/ui/src/lib/i18n.ts @@ -7335,7 +7343,7 @@ libs/ui/src/lib/historical-market-data-editor/historical-market-data-editor-dialog/historical-market-data-editor-dialog.html - 48 + 49 diff --git a/apps/client/src/locales/messages.pt.xlf b/apps/client/src/locales/messages.pt.xlf index 55d622ed9..194922435 100644 --- a/apps/client/src/locales/messages.pt.xlf +++ b/apps/client/src/locales/messages.pt.xlf @@ -530,7 +530,7 @@ Filtrar por... apps/client/src/app/components/admin-market-data/admin-market-data.component.ts - 385 + 390 @@ -570,7 +570,7 @@ libs/ui/src/lib/historical-market-data-editor/historical-market-data-editor.component.html - 44 + 40 @@ -3174,7 +3174,7 @@ libs/ui/src/lib/historical-market-data-editor/historical-market-data-editor.component.html - 71 + 67 @@ -3341,6 +3341,14 @@ 22 + + No Activities + No Activities + + apps/client/src/app/components/admin-market-data/admin-market-data.component.ts + 146 + + Retirement Provision Provisão de Reforma @@ -5692,7 +5700,7 @@ Ops! Não foi possível analisar os dados históricos. libs/ui/src/lib/historical-market-data-editor/historical-market-data-editor.component.ts - 262 + 284 @@ -6757,7 +6765,7 @@ libs/ui/src/lib/historical-market-data-editor/historical-market-data-editor-dialog/historical-market-data-editor-dialog.html - 46 + 47 libs/ui/src/lib/i18n.ts @@ -7335,7 +7343,7 @@ libs/ui/src/lib/historical-market-data-editor/historical-market-data-editor-dialog/historical-market-data-editor-dialog.html - 48 + 49 diff --git a/apps/client/src/locales/messages.tr.xlf b/apps/client/src/locales/messages.tr.xlf index 841da4721..a7b86f624 100644 --- a/apps/client/src/locales/messages.tr.xlf +++ b/apps/client/src/locales/messages.tr.xlf @@ -739,7 +739,7 @@ Filtrele... apps/client/src/app/components/admin-market-data/admin-market-data.component.ts - 385 + 390 @@ -779,7 +779,7 @@ libs/ui/src/lib/historical-market-data-editor/historical-market-data-editor.component.html - 44 + 40 @@ -3371,7 +3371,7 @@ libs/ui/src/lib/historical-market-data-editor/historical-market-data-editor.component.html - 71 + 67 @@ -5003,6 +5003,14 @@ 27 + + No Activities + No Activities + + apps/client/src/app/components/admin-market-data/admin-market-data.component.ts + 146 + + Retirement Provision Yaşlılık Provizyonu @@ -5692,7 +5700,7 @@ Hay Allah! Geçmiş veriler ayrıştırılamadı. libs/ui/src/lib/historical-market-data-editor/historical-market-data-editor.component.ts - 262 + 284 @@ -6757,7 +6765,7 @@ libs/ui/src/lib/historical-market-data-editor/historical-market-data-editor-dialog/historical-market-data-editor-dialog.html - 46 + 47 libs/ui/src/lib/i18n.ts @@ -7335,7 +7343,7 @@ libs/ui/src/lib/historical-market-data-editor/historical-market-data-editor-dialog/historical-market-data-editor-dialog.html - 48 + 49 diff --git a/apps/client/src/locales/messages.uk.xlf b/apps/client/src/locales/messages.uk.xlf index 27c55d792..61cebd47a 100644 --- a/apps/client/src/locales/messages.uk.xlf +++ b/apps/client/src/locales/messages.uk.xlf @@ -875,7 +875,7 @@ Фільтрувати за... apps/client/src/app/components/admin-market-data/admin-market-data.component.ts - 385 + 390 @@ -931,7 +931,7 @@ libs/ui/src/lib/historical-market-data-editor/historical-market-data-editor.component.html - 44 + 40 @@ -2323,7 +2323,7 @@ libs/ui/src/lib/historical-market-data-editor/historical-market-data-editor-dialog/historical-market-data-editor-dialog.html - 48 + 49 @@ -4576,7 +4576,7 @@ libs/ui/src/lib/historical-market-data-editor/historical-market-data-editor.component.html - 71 + 67 @@ -6419,7 +6419,7 @@ Упс! Не вдалося отримати історичні дані. libs/ui/src/lib/historical-market-data-editor/historical-market-data-editor.component.ts - 262 + 284 @@ -6595,7 +6595,7 @@ libs/ui/src/lib/historical-market-data-editor/historical-market-data-editor-dialog/historical-market-data-editor-dialog.html - 46 + 47 libs/ui/src/lib/i18n.ts @@ -6774,6 +6774,14 @@ 27 + + No Activities + No Activities + + apps/client/src/app/components/admin-market-data/admin-market-data.component.ts + 146 + + Retirement Provision Пенсійне накопичення diff --git a/apps/client/src/locales/messages.xlf b/apps/client/src/locales/messages.xlf index d15b93002..03644820a 100644 --- a/apps/client/src/locales/messages.xlf +++ b/apps/client/src/locales/messages.xlf @@ -740,7 +740,7 @@ Filter by... apps/client/src/app/components/admin-market-data/admin-market-data.component.ts - 385 + 390 @@ -777,7 +777,7 @@ libs/ui/src/lib/historical-market-data-editor/historical-market-data-editor.component.html - 44 + 40 @@ -823,7 +823,7 @@ Oops! Could not parse historical data. libs/ui/src/lib/historical-market-data-editor/historical-market-data-editor.component.ts - 262 + 284 @@ -852,7 +852,7 @@ libs/ui/src/lib/historical-market-data-editor/historical-market-data-editor.component.html - 71 + 67 @@ -4907,6 +4907,13 @@ 27 + + No Activities + + apps/client/src/app/components/admin-market-data/admin-market-data.component.ts + 146 + + Retirement Provision @@ -6126,7 +6133,7 @@ libs/ui/src/lib/historical-market-data-editor/historical-market-data-editor-dialog/historical-market-data-editor-dialog.html - 46 + 47 libs/ui/src/lib/i18n.ts @@ -6685,7 +6692,7 @@ libs/ui/src/lib/historical-market-data-editor/historical-market-data-editor-dialog/historical-market-data-editor-dialog.html - 48 + 49 diff --git a/apps/client/src/locales/messages.zh.xlf b/apps/client/src/locales/messages.zh.xlf index 08d4f3d43..9feb0e546 100644 --- a/apps/client/src/locales/messages.zh.xlf +++ b/apps/client/src/locales/messages.zh.xlf @@ -792,7 +792,7 @@ 过滤... apps/client/src/app/components/admin-market-data/admin-market-data.component.ts - 385 + 390 @@ -832,7 +832,7 @@ libs/ui/src/lib/historical-market-data-editor/historical-market-data-editor.component.html - 44 + 40 @@ -868,7 +868,7 @@ 哎呀!无法解析历史数据。 libs/ui/src/lib/historical-market-data-editor/historical-market-data-editor.component.ts - 262 + 284 @@ -892,7 +892,7 @@ libs/ui/src/lib/historical-market-data-editor/historical-market-data-editor.component.html - 71 + 67 @@ -5360,6 +5360,14 @@ 27 + + No Activities + No Activities + + apps/client/src/app/components/admin-market-data/admin-market-data.component.ts + 146 + + Retirement Provision 退休金 @@ -6758,7 +6766,7 @@ libs/ui/src/lib/historical-market-data-editor/historical-market-data-editor-dialog/historical-market-data-editor-dialog.html - 46 + 47 libs/ui/src/lib/i18n.ts @@ -7336,7 +7344,7 @@ libs/ui/src/lib/historical-market-data-editor/historical-market-data-editor-dialog/historical-market-data-editor-dialog.html - 48 + 49 From 6c6f20c3fdbc1dc636bfc50532cf01dbac05ff7e Mon Sep 17 00:00:00 2001 From: Kenrick Tandrian <60643640+KenTandrian@users.noreply.github.com> Date: Fri, 20 Feb 2026 23:28:06 +0700 Subject: [PATCH 030/224] Task/improve type safety in account balances component (#6352) * fix(lib): add type annotations for date adapter * fix(lib): handle form value possibly null * fix(lint): use arrow fn for validators * fix(lib): accounts table typings * fix(lib): remove unsubscribeSubject due to lack of observable * fix(lib): remove validators variable * feat(lib): implement inject functions * feat(lib): make locale an input signal * feat(lib): make showActions an input signal * feat(lib): make accountId an input signal * feat(lib): make accountCurrency an input signal * feat(lib): make accountBalances an input signal * feat(lib): make sort a viewChild signal * feat(lib): implement isNil --- .../account-balances.component.html | 10 +-- .../account-balances.component.ts | 68 +++++++++---------- .../accounts-table.component.ts | 2 +- 3 files changed, 37 insertions(+), 43 deletions(-) diff --git a/libs/ui/src/lib/account-balances/account-balances.component.html b/libs/ui/src/lib/account-balances/account-balances.component.html index caef922ed..29037a985 100644 --- a/libs/ui/src/lib/account-balances/account-balances.component.html +++ b/libs/ui/src/lib/account-balances/account-balances.component.html @@ -12,7 +12,7 @@ Date - + @@ -37,7 +37,7 @@
    @@ -48,7 +48,7 @@
    - {{ accountCurrency }} + {{ accountCurrency() }}
    @@ -58,7 +58,7 @@ - @if (showActions) { + @if (showActions()) { @@ -23,7 +23,7 @@ [matAutocomplete]="autocomplete" [matChipInputFor]="chipList" [matChipInputSeparatorKeyCodes]="separatorKeysCodes" - [placeholder]="placeholder" + [placeholder]="placeholder()" (matChipInputTokenEnd)="onAddFilter($event)" /> @@ -35,7 +35,7 @@ @for (filter of filterGroup.filters; track filter) { - {{ filter.label | gfSymbol }} + {{ filter.label ?? '' | gfSymbol }} } @@ -46,7 +46,7 @@ disabled mat-icon-button matSuffix - [ngClass]="{ 'd-none': !isLoading }" + [ngClass]="{ 'd-none': !isLoading() }" > diff --git a/libs/ui/src/lib/activities-filter/activities-filter.component.ts b/libs/ui/src/lib/activities-filter/activities-filter.component.ts index 34f883c67..25fad683d 100644 --- a/libs/ui/src/lib/activities-filter/activities-filter.component.ts +++ b/libs/ui/src/lib/activities-filter/activities-filter.component.ts @@ -8,14 +8,14 @@ import { ChangeDetectionStrategy, Component, ElementRef, - EventEmitter, Input, OnChanges, - OnDestroy, - Output, SimpleChanges, - ViewChild + ViewChild, + input, + output } from '@angular/core'; +import { takeUntilDestroyed } from '@angular/core/rxjs-interop'; import { FormControl, ReactiveFormsModule } from '@angular/forms'; import { MatAutocomplete, @@ -30,8 +30,7 @@ import { IonIcon } from '@ionic/angular/standalone'; import { addIcons } from 'ionicons'; import { closeOutline, searchOutline } from 'ionicons/icons'; import { groupBy } from 'lodash'; -import { BehaviorSubject, Observable, Subject } from 'rxjs'; -import { takeUntil } from 'rxjs/operators'; +import { BehaviorSubject } from 'rxjs'; import { translate } from '../i18n'; @@ -53,28 +52,26 @@ import { translate } from '../i18n'; styleUrls: ['./activities-filter.component.scss'], templateUrl: './activities-filter.component.html' }) -export class GfActivitiesFilterComponent implements OnChanges, OnDestroy { +export class GfActivitiesFilterComponent implements OnChanges { @Input() allFilters: Filter[]; - @Input() isLoading: boolean; - @Input() placeholder: string; - @Output() valueChanged = new EventEmitter(); + @ViewChild('autocomplete') protected matAutocomplete: MatAutocomplete; + @ViewChild('searchInput') protected searchInput: ElementRef; - @ViewChild('autocomplete') matAutocomplete: MatAutocomplete; - @ViewChild('searchInput') searchInput: ElementRef; + public readonly isLoading = input.required(); + public readonly placeholder = input.required(); + public readonly valueChanged = output(); - public filterGroups$: Subject = new BehaviorSubject([]); - public filters$: Subject = new BehaviorSubject([]); - public filters: Observable = this.filters$.asObservable(); - public searchControl = new FormControl(undefined); - public selectedFilters: Filter[] = []; - public separatorKeysCodes: number[] = [ENTER, COMMA]; - - private unsubscribeSubject = new Subject(); + protected readonly filterGroups$ = new BehaviorSubject([]); + protected readonly searchControl = new FormControl( + null + ); + protected selectedFilters: Filter[] = []; + protected readonly separatorKeysCodes: number[] = [ENTER, COMMA]; public constructor() { this.searchControl.valueChanges - .pipe(takeUntil(this.unsubscribeSubject)) + .pipe(takeUntilDestroyed()) .subscribe((filterOrSearchTerm) => { if (filterOrSearchTerm) { const searchTerm = @@ -97,41 +94,39 @@ export class GfActivitiesFilterComponent implements OnChanges, OnDestroy { } } - public onAddFilter({ input, value }: MatChipInputEvent) { + public onAddFilter({ chipInput, value }: MatChipInputEvent) { if (value?.trim()) { this.updateFilters(); } // Reset the input value - if (input) { - input.value = ''; + if (chipInput.inputElement) { + chipInput.inputElement.value = ''; } - this.searchControl.setValue(undefined); + this.searchControl.setValue(null); } public onRemoveFilter(aFilter: Filter) { - this.selectedFilters = this.selectedFilters.filter((filter) => { - return filter.id !== aFilter.id; + this.selectedFilters = this.selectedFilters.filter(({ id }) => { + return id !== aFilter.id; }); this.updateFilters(); } public onSelectFilter(event: MatAutocompleteSelectedEvent) { - this.selectedFilters.push( - this.allFilters.find((filter) => { - return filter.id === event.option.value; - }) - ); + const filter = this.allFilters.find(({ id }) => { + return id === event.option.value; + }); + + if (filter) { + this.selectedFilters.push(filter); + } + this.updateFilters(); this.searchInput.nativeElement.value = ''; - this.searchControl.setValue(undefined); - } - - public ngOnDestroy() { - this.unsubscribeSubject.next(); - this.unsubscribeSubject.complete(); + this.searchControl.setValue(null); } private getGroupedFilters(searchTerm?: string) { @@ -139,23 +134,23 @@ export class GfActivitiesFilterComponent implements OnChanges, OnDestroy { this.allFilters .filter((filter) => { // Filter selected filters - return !this.selectedFilters.some((selectedFilter) => { - return selectedFilter.id === filter.id; + return !this.selectedFilters.some(({ id }) => { + return id === filter.id; }); }) .filter((filter) => { if (searchTerm) { // Filter by search term return filter.label - .toLowerCase() + ?.toLowerCase() .includes(searchTerm.toLowerCase()); } return filter; }) - .sort((a, b) => a.label?.localeCompare(b.label)), - (filter) => { - return filter.type; + .sort((a, b) => (a.label ?? '').localeCompare(b.label ?? '')), + ({ type }) => { + return type; } ); From 25200bfd6d45871d109db8eca2f4004029d2a58c Mon Sep 17 00:00:00 2001 From: Thomas Kaul <4159106+dtslvr@users.noreply.github.com> Date: Sat, 21 Feb 2026 08:33:51 +0100 Subject: [PATCH 034/224] Task/improve usability of portfolio summary in presenter view (#6360) * Improve usability in presenter view * Update changelog --- CHANGELOG.md | 1 + .../portfolio-summary/portfolio-summary.component.html | 7 +++++-- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c0fb2b2e4..594b8faa1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Changed +- Improved the usability of the portfolio summary tab on the home page in the _Presenter View_ - Refreshed the cryptocurrencies list - Improved the language localization for German (`de`) - Improved the language localization for Spanish (`es`) diff --git a/apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html b/apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html index 99e0c9a53..0e26a49a8 100644 --- a/apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html +++ b/apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html @@ -184,18 +184,21 @@ [ngClass]="{ 'cursor-pointer': hasPermissionToUpdateUserSettings && + !user?.settings?.isRestrictedView && user?.subscription?.type !== 'Basic' }" (click)=" hasPermissionToUpdateUserSettings && + !user?.settings?.isRestrictedView && user?.subscription?.type !== 'Basic' && onEditEmergencyFund() " > @if ( hasPermissionToUpdateUserSettings && - user?.subscription?.type !== 'Basic' && - !isLoading + !isLoading && + !user?.settings?.isRestrictedView && + user?.subscription?.type !== 'Basic' ) { Date: Sat, 21 Feb 2026 08:37:55 +0100 Subject: [PATCH 035/224] Release 2.241.0 (#6361) --- CHANGELOG.md | 2 +- package-lock.json | 4 ++-- package.json | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 594b8faa1..6f485abeb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,7 +5,7 @@ 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 +## 2.241.0 - 2026-02-21 ### Changed diff --git a/package-lock.json b/package-lock.json index 636147048..2a6d30cc8 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "ghostfolio", - "version": "2.240.0", + "version": "2.241.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "ghostfolio", - "version": "2.240.0", + "version": "2.241.0", "hasInstallScript": true, "license": "AGPL-3.0", "dependencies": { diff --git a/package.json b/package.json index 4bfdd1cb1..3dcfde537 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "ghostfolio", - "version": "2.240.0", + "version": "2.241.0", "homepage": "https://ghostfol.io", "license": "AGPL-3.0", "repository": "https://github.com/ghostfolio/ghostfolio", From ec92116acc0ec327c24622dd79b3ef58197accf0 Mon Sep 17 00:00:00 2001 From: Thomas Kaul <4159106+dtslvr@users.noreply.github.com> Date: Sun, 22 Feb 2026 08:59:52 +0100 Subject: [PATCH 036/224] Task/remove unused OnDestroy hook in admin page component (#6366) * Remove unused OnDestroy hook --- .../src/app/pages/admin/admin-page.component.ts | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/apps/client/src/app/pages/admin/admin-page.component.ts b/apps/client/src/app/pages/admin/admin-page.component.ts index b9243dcb9..284d3c41d 100644 --- a/apps/client/src/app/pages/admin/admin-page.component.ts +++ b/apps/client/src/app/pages/admin/admin-page.component.ts @@ -1,7 +1,7 @@ import { TabConfiguration } from '@ghostfolio/common/interfaces'; import { internalRoutes } from '@ghostfolio/common/routes/routes'; -import { Component, OnDestroy, OnInit } from '@angular/core'; +import { Component, OnInit } from '@angular/core'; import { MatTabsModule } from '@angular/material/tabs'; import { RouterModule } from '@angular/router'; import { IonIcon } from '@ionic/angular/standalone'; @@ -14,7 +14,6 @@ import { settingsOutline } from 'ionicons/icons'; import { DeviceDetectorService } from 'ngx-device-detector'; -import { Subject } from 'rxjs'; @Component({ host: { class: 'page has-tabs' }, @@ -23,12 +22,10 @@ import { Subject } from 'rxjs'; styleUrls: ['./admin-page.scss'], templateUrl: './admin-page.html' }) -export class AdminPageComponent implements OnDestroy, OnInit { +export class AdminPageComponent implements OnInit { public deviceType: string; public tabs: TabConfiguration[] = []; - private unsubscribeSubject = new Subject(); - public constructor(private deviceService: DeviceDetectorService) { addIcons({ flashOutline, @@ -74,9 +71,4 @@ export class AdminPageComponent implements OnDestroy, OnInit { } ]; } - - public ngOnDestroy() { - this.unsubscribeSubject.next(); - this.unsubscribeSubject.complete(); - } } From e3579f6811df4e83f7e566f57b7a8b94f971b7f2 Mon Sep 17 00:00:00 2001 From: Thomas Kaul <4159106+dtslvr@users.noreply.github.com> Date: Sun, 22 Feb 2026 09:00:45 +0100 Subject: [PATCH 037/224] Task/add missing OnDestroy hook in user account registration dialog (#6368) * Add missing OnDestroy hook --- .../user-account-registration-dialog.component.ts | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/apps/client/src/app/pages/register/user-account-registration-dialog/user-account-registration-dialog.component.ts b/apps/client/src/app/pages/register/user-account-registration-dialog/user-account-registration-dialog.component.ts index a7707ad3b..4cc0f52f8 100644 --- a/apps/client/src/app/pages/register/user-account-registration-dialog/user-account-registration-dialog.component.ts +++ b/apps/client/src/app/pages/register/user-account-registration-dialog/user-account-registration-dialog.component.ts @@ -9,6 +9,7 @@ import { Component, CUSTOM_ELEMENTS_SCHEMA, Inject, + OnDestroy, ViewChild } from '@angular/core'; import { FormsModule, ReactiveFormsModule } from '@angular/forms'; @@ -52,7 +53,7 @@ import { UserAccountRegistrationDialogParams } from './interfaces/interfaces'; styleUrls: ['./user-account-registration-dialog.scss'], templateUrl: 'user-account-registration-dialog.html' }) -export class GfUserAccountRegistrationDialogComponent { +export class GfUserAccountRegistrationDialogComponent implements OnDestroy { @ViewChild(MatStepper) stepper!: MatStepper; public accessToken: string; @@ -95,4 +96,9 @@ export class GfUserAccountRegistrationDialogComponent { public onChangeDislaimerChecked() { this.isDisclaimerChecked = !this.isDisclaimerChecked; } + + public ngOnDestroy() { + this.unsubscribeSubject.next(); + this.unsubscribeSubject.complete(); + } } From 5acbe25d2504a675043199a2c3cc5ab62a33e58d Mon Sep 17 00:00:00 2001 From: Thomas Kaul <4159106+dtslvr@users.noreply.github.com> Date: Sun, 22 Feb 2026 09:01:48 +0100 Subject: [PATCH 038/224] Task/clean up changelog (#6362) * Clean up --- CHANGELOG.md | 1 - 1 file changed, 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6f485abeb..2627f1a19 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -19,7 +19,6 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Fixed an issue with `balanceInBaseCurrency` of the accounts in the value redaction interceptor for the impersonation mode - Fixed an issue with `comment` of the accounts in the value redaction interceptor for the impersonation mode - Fixed an issue with `dividendInBaseCurrency` of the accounts in the value redaction interceptor for the impersonation mode -- Fixed an issue with `dividendInBaseCurrency` of the accounts in the value redaction interceptor for the impersonation mode - Fixed an issue with `interestInBaseCurrency` of the accounts in the value redaction interceptor for the impersonation mode - Fixed an issue with `value` of the accounts in the value redaction interceptor for the impersonation mode From 97915a3ca9acaece4da9f844c566fad4fd4643ea Mon Sep 17 00:00:00 2001 From: Thomas Kaul <4159106+dtslvr@users.noreply.github.com> Date: Sun, 22 Feb 2026 09:02:37 +0100 Subject: [PATCH 039/224] Bugfix/fix page size for presets in market data table of admin control panel (#6363) * Fix page size for presets * Update changelog --- CHANGELOG.md | 6 ++++++ .../admin-market-data/admin-market-data.component.ts | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2627f1a19..f4a857ab3 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 page size for presets in the historical market data table of the admin control panel + ## 2.241.0 - 2026-02-21 ### Changed diff --git a/apps/client/src/app/components/admin-market-data/admin-market-data.component.ts b/apps/client/src/app/components/admin-market-data/admin-market-data.component.ts index 6a079c20a..0beca6f3c 100644 --- a/apps/client/src/app/components/admin-market-data/admin-market-data.component.ts +++ b/apps/client/src/app/components/admin-market-data/admin-market-data.component.ts @@ -379,7 +379,7 @@ export class GfAdminMarketDataComponent this.pageSize = this.activeFilters.length === 1 && this.activeFilters[0].type === 'PRESET_ID' - ? undefined + ? Number.MAX_SAFE_INTEGER : DEFAULT_PAGE_SIZE; if (pageIndex === 0 && this.paginator) { From 4897f34d51e0451b18a88cded85c5bfd41d009e0 Mon Sep 17 00:00:00 2001 From: Thomas Kaul <4159106+dtslvr@users.noreply.github.com> Date: Sun, 22 Feb 2026 10:31:59 +0100 Subject: [PATCH 040/224] Task/change account field to optional in create or update activity dialog (#6371) * Change account field to optional for every case * Update changelog --- CHANGELOG.md | 4 ++++ .../create-or-update-activity-dialog.component.ts | 15 +-------------- .../create-or-update-activity-dialog.html | 8 ++------ 3 files changed, 7 insertions(+), 20 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f4a857ab3..ecd2ce5c8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## Unreleased +### Changed + +- Changed the account field to optional in the create or update activity dialog + ### Fixed - Fixed the page size for presets in the historical market data table of the admin control panel diff --git a/apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.component.ts b/apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.component.ts index 8695f04ed..fc42a504d 100644 --- a/apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.component.ts +++ b/apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.component.ts @@ -188,8 +188,7 @@ export class GfCreateOrUpdateActivityDialogComponent implements OnDestroy { !this.data.activity?.accountId && this.mode === 'create' ? this.data.accounts[0].id - : this.data.activity?.accountId, - Validators.required + : this.data.activity?.accountId ], assetClass: [this.data.activity?.SymbolProfile?.assetClass], assetSubClass: [this.data.activity?.SymbolProfile?.assetSubClass], @@ -365,11 +364,6 @@ export class GfCreateOrUpdateActivityDialogComponent implements OnDestroy { (this.activityForm.get('dataSource').value === 'MANUAL' && type === 'BUY') ) { - this.activityForm - .get('accountId') - .removeValidators(Validators.required); - this.activityForm.get('accountId').updateValueAndValidity(); - const currency = this.data.accounts.find(({ id }) => { return id === this.activityForm.get('accountId').value; @@ -397,11 +391,6 @@ export class GfCreateOrUpdateActivityDialogComponent implements OnDestroy { this.activityForm.get('updateAccountBalance').disable(); this.activityForm.get('updateAccountBalance').setValue(false); } else if (['FEE', 'INTEREST', 'LIABILITY'].includes(type)) { - this.activityForm - .get('accountId') - .removeValidators(Validators.required); - this.activityForm.get('accountId').updateValueAndValidity(); - const currency = this.data.accounts.find(({ id }) => { return id === this.activityForm.get('accountId').value; @@ -447,8 +436,6 @@ export class GfCreateOrUpdateActivityDialogComponent implements OnDestroy { this.activityForm.get('updateAccountBalance').setValue(false); } } else { - this.activityForm.get('accountId').setValidators(Validators.required); - this.activityForm.get('accountId').updateValueAndValidity(); this.activityForm .get('dataSource') .setValidators(Validators.required); diff --git a/apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html b/apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html index 42fbd0ebf..278ddcbbd 100644 --- a/apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html +++ b/apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html @@ -84,12 +84,8 @@ > Account - @if ( - !activityForm.get('accountId').hasValidator(Validators.required) || - (!activityForm.get('accountId').value && mode === 'update') - ) { - - } + + @for (account of data.accounts; track account) {
    From 3eb9d53220dd158917281db85c62dc23876e36e9 Mon Sep 17 00:00:00 2001 From: Thomas Kaul <4159106+dtslvr@users.noreply.github.com> Date: Sun, 22 Feb 2026 10:45:14 +0100 Subject: [PATCH 041/224] Bugfix/validation of valuables (#6372) * Fix validation of valuables * Update changelog --- CHANGELOG.md | 1 + .../services/data-provider/data-provider.service.ts | 12 ++++++++---- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ecd2ce5c8..34aff43e1 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 a validation issue for valuables used in the create and import activity logic - Fixed the page size for presets in the historical market data table of the admin control panel ## 2.241.0 - 2026-02-21 diff --git a/apps/api/src/services/data-provider/data-provider.service.ts b/apps/api/src/services/data-provider/data-provider.service.ts index eb9816c67..8ee8761c0 100644 --- a/apps/api/src/services/data-provider/data-provider.service.ts +++ b/apps/api/src/services/data-provider/data-provider.service.ts @@ -244,11 +244,15 @@ export class DataProviderService implements OnModuleInit { }); if (!assetProfiles[assetProfileIdentifier]) { - if (['FEE', 'INTEREST', 'LIABILITY'].includes(type)) { + if ( + (dataSource === DataSource.MANUAL && type === 'BUY') || + ['FEE', 'INTEREST', 'LIABILITY'].includes(type) + ) { const assetProfileInImport = assetProfilesWithMarketDataDto?.find( - (profile) => { + (assetProfile) => { return ( - profile.dataSource === dataSource && profile.symbol === symbol + assetProfile.dataSource === dataSource && + assetProfile.symbol === symbol ); } ); @@ -257,7 +261,7 @@ export class DataProviderService implements OnModuleInit { currency, dataSource, symbol, - name: assetProfileInImport?.name + name: assetProfileInImport?.name ?? symbol }; continue; From 98891e195c569b762389723a5258c0c8c084a945 Mon Sep 17 00:00:00 2001 From: Thomas Kaul <4159106+dtslvr@users.noreply.github.com> Date: Sun, 22 Feb 2026 11:01:18 +0100 Subject: [PATCH 042/224] Release 2.242.0 (#6375) * Release 2.242.0 * Update changelog --- CHANGELOG.md | 2 +- package-lock.json | 4 ++-- package.json | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 34aff43e1..91f80d3ba 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,7 +5,7 @@ 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 +## 2.242.0 - 2026-02-22 ### Changed diff --git a/package-lock.json b/package-lock.json index 2a6d30cc8..7a1ebfa67 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "ghostfolio", - "version": "2.241.0", + "version": "2.242.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "ghostfolio", - "version": "2.241.0", + "version": "2.242.0", "hasInstallScript": true, "license": "AGPL-3.0", "dependencies": { diff --git a/package.json b/package.json index 3dcfde537..2bf5eebe0 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "ghostfolio", - "version": "2.241.0", + "version": "2.242.0", "homepage": "https://ghostfol.io", "license": "AGPL-3.0", "repository": "https://github.com/ghostfolio/ghostfolio", From 14f0d2bd8b827c1cc9fe5851c604b02c897fb792 Mon Sep 17 00:00:00 2001 From: Thomas Kaul <4159106+dtslvr@users.noreply.github.com> Date: Mon, 23 Feb 2026 17:27:04 +0100 Subject: [PATCH 043/224] Task/remove unused OnDestroy hook in OSS friends page component (#6374) * Remove unused OnDestroy hook --- .../about/oss-friends/oss-friends-page.component.ts | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/apps/client/src/app/pages/about/oss-friends/oss-friends-page.component.ts b/apps/client/src/app/pages/about/oss-friends/oss-friends-page.component.ts index bdbbdf9a7..c2e500a52 100644 --- a/apps/client/src/app/pages/about/oss-friends/oss-friends-page.component.ts +++ b/apps/client/src/app/pages/about/oss-friends/oss-friends-page.component.ts @@ -1,10 +1,9 @@ -import { Component, OnDestroy } from '@angular/core'; +import { Component } from '@angular/core'; import { MatButtonModule } from '@angular/material/button'; import { MatCardModule } from '@angular/material/card'; import { IonIcon } from '@ionic/angular/standalone'; import { addIcons } from 'ionicons'; import { arrowForwardOutline } from 'ionicons/icons'; -import { Subject } from 'rxjs'; const ossFriends = require('../../../../assets/oss-friends.json'); @@ -14,17 +13,10 @@ const ossFriends = require('../../../../assets/oss-friends.json'); styleUrls: ['./oss-friends-page.scss'], templateUrl: './oss-friends-page.html' }) -export class GfOpenSourceSoftwareFriendsPageComponent implements OnDestroy { +export class GfOpenSourceSoftwareFriendsPageComponent { public ossFriends = ossFriends.data; - private unsubscribeSubject = new Subject(); - public constructor() { addIcons({ arrowForwardOutline }); } - - public ngOnDestroy() { - this.unsubscribeSubject.next(); - this.unsubscribeSubject.complete(); - } } From c7cfc87e208d584d43875c7c336a0e171f65d371 Mon Sep 17 00:00:00 2001 From: Thomas Kaul <4159106+dtslvr@users.noreply.github.com> Date: Mon, 23 Feb 2026 17:29:32 +0100 Subject: [PATCH 044/224] Task/remove unused OnDestroy hook in changelog page component (#6373) * Remove unused OnDestroy hook --- .../about/changelog/changelog-page.component.ts | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/apps/client/src/app/pages/about/changelog/changelog-page.component.ts b/apps/client/src/app/pages/about/changelog/changelog-page.component.ts index 69b397370..d7f583bd1 100644 --- a/apps/client/src/app/pages/about/changelog/changelog-page.component.ts +++ b/apps/client/src/app/pages/about/changelog/changelog-page.component.ts @@ -1,7 +1,6 @@ -import { Component, OnDestroy } from '@angular/core'; +import { Component } from '@angular/core'; import { MarkdownModule } from 'ngx-markdown'; import { NgxSkeletonLoaderModule } from 'ngx-skeleton-loader'; -import { Subject } from 'rxjs'; @Component({ imports: [MarkdownModule, NgxSkeletonLoaderModule], @@ -9,17 +8,10 @@ import { Subject } from 'rxjs'; styleUrls: ['./changelog-page.scss'], templateUrl: './changelog-page.html' }) -export class GfChangelogPageComponent implements OnDestroy { +export class GfChangelogPageComponent { public isLoading = true; - private unsubscribeSubject = new Subject(); - public onLoad() { this.isLoading = false; } - - public ngOnDestroy() { - this.unsubscribeSubject.next(); - this.unsubscribeSubject.complete(); - } } From f5d99bad241440651f9fe473d3f2113b44635400 Mon Sep 17 00:00:00 2001 From: Thomas Kaul <4159106+dtslvr@users.noreply.github.com> Date: Mon, 23 Feb 2026 20:05:04 +0100 Subject: [PATCH 045/224] Bugfix/create activities of type fee, interest or liability (#6378) * Fix creation of activities with type FEE, INTEREST or LIABILITY * Update changelog --- CHANGELOG.md | 6 ++++++ .../create-or-update-activity-dialog.component.ts | 9 +++++---- 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 91f80d3ba..160b4cbf0 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 an issue when creating activities of type `FEE`, `INTEREST` or `LIABILITY` + ## 2.242.0 - 2026-02-22 ### Changed diff --git a/apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.component.ts b/apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.component.ts index fc42a504d..c7cd63191 100644 --- a/apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.component.ts +++ b/apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.component.ts @@ -501,11 +501,12 @@ export class GfCreateOrUpdateActivityDialogComponent implements OnDestroy { comment: this.activityForm.get('comment').value || null, currency: this.activityForm.get('currency').value, customCurrency: this.activityForm.get('currencyOfUnitPrice').value, + dataSource: ['FEE', 'INTEREST', 'LIABILITY', 'VALUABLE'].includes( + this.activityForm.get('type').value + ) + ? 'MANUAL' + : this.activityForm.get('dataSource').value, date: this.activityForm.get('date').value, - dataSource: - this.activityForm.get('type').value === 'VALUABLE' - ? 'MANUAL' - : this.activityForm.get('dataSource').value, fee: this.activityForm.get('fee').value, quantity: this.activityForm.get('quantity').value, symbol: From 7bcd18711a3cae44636f6877a3005faf5c97d193 Mon Sep 17 00:00:00 2001 From: Vic Chen Date: Tue, 24 Feb 2026 03:17:31 +0800 Subject: [PATCH 046/224] Task/improve language localization for ZH 20260217 (#6348) * Improve language localization for ZH * Update changelog --- CHANGELOG.md | 4 ++++ apps/client/src/locales/messages.zh.xlf | 8 ++++---- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 160b4cbf0..b87e4822d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## Unreleased +### Changed + +- Improved the language localization for Chinese (`zh`) + ### Fixed - Fixed an issue when creating activities of type `FEE`, `INTEREST` or `LIABILITY` diff --git a/apps/client/src/locales/messages.zh.xlf b/apps/client/src/locales/messages.zh.xlf index 9feb0e546..67007cdef 100644 --- a/apps/client/src/locales/messages.zh.xlf +++ b/apps/client/src/locales/messages.zh.xlf @@ -7891,7 +7891,7 @@ Fee Ratio (legacy) - 费率 + 费率(旧版) apps/client/src/app/pages/i18n/i18n-page.html 152 @@ -7915,7 +7915,7 @@ Fee Ratio - Fee Ratio + 费率 apps/client/src/app/pages/i18n/i18n-page.html 161 @@ -7923,7 +7923,7 @@ The fees do exceed ${thresholdMax}% of your total investment volume (${feeRatio}%) - The fees do exceed ${thresholdMax}% of your total investment volume (${feeRatio}%) + 费用已超过您总投资金额的 ${thresholdMax}%(${feeRatio}%) apps/client/src/app/pages/i18n/i18n-page.html 163 @@ -7931,7 +7931,7 @@ The fees do not exceed ${thresholdMax}% of your total investment volume (${feeRatio}%) - The fees do not exceed ${thresholdMax}% of your total investment volume (${feeRatio}%) + 费用未超过您总投资金额的 ${thresholdMax}%(${feeRatio}%) apps/client/src/app/pages/i18n/i18n-page.html 167 From 236e1aacf56e9d876f17ebdcef4328a4141fa034 Mon Sep 17 00:00:00 2001 From: Thomas Kaul <4159106+dtslvr@users.noreply.github.com> Date: Mon, 23 Feb 2026 20:29:07 +0100 Subject: [PATCH 047/224] Task/upgrade nestjs to version 11.1.14 (#6379) * Upgrade nestjs to version 11.1.14 * Update changelog --- CHANGELOG.md | 1 + package-lock.json | 223 +++++++++++++++++++--------------------------- package.json | 16 ++-- 3 files changed, 100 insertions(+), 140 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b87e4822d..a482c10e8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Changed - Improved the language localization for Chinese (`zh`) +- Upgraded `nestjs` from version `11.1.8` to `11.1.14` ### Fixed diff --git a/package-lock.json b/package-lock.json index 7a1ebfa67..9d022919b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -27,15 +27,15 @@ "@ionic/angular": "8.7.8", "@keyv/redis": "4.4.0", "@nestjs/bull": "11.0.4", - "@nestjs/cache-manager": "3.0.1", - "@nestjs/common": "11.1.8", - "@nestjs/config": "4.0.2", - "@nestjs/core": "11.1.8", + "@nestjs/cache-manager": "3.1.0", + "@nestjs/common": "11.1.14", + "@nestjs/config": "4.0.3", + "@nestjs/core": "11.1.14", "@nestjs/event-emitter": "3.0.1", - "@nestjs/jwt": "11.0.1", + "@nestjs/jwt": "11.0.2", "@nestjs/passport": "11.0.5", - "@nestjs/platform-express": "11.1.8", - "@nestjs/schedule": "6.0.1", + "@nestjs/platform-express": "11.1.14", + "@nestjs/schedule": "6.1.1", "@nestjs/serve-static": "5.0.4", "@openrouter/ai-sdk-provider": "0.7.2", "@prisma/client": "6.19.0", @@ -107,7 +107,7 @@ "@eslint/eslintrc": "3.3.1", "@eslint/js": "9.35.0", "@nestjs/schematics": "11.0.9", - "@nestjs/testing": "11.1.8", + "@nestjs/testing": "11.1.14", "@nx/angular": "22.4.5", "@nx/eslint-plugin": "22.4.5", "@nx/jest": "22.4.5", @@ -3617,6 +3617,16 @@ "dev": true, "license": "MIT" }, + "node_modules/@borewit/text-codec": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/@borewit/text-codec/-/text-codec-0.2.1.tgz", + "integrity": "sha512-k7vvKPbf7J2fZ5klGRD9AeKfUvojuZIQ3BT5u7Jfv+puwXkUBUT5PVyMDfJZpy30CBDXGMgw7fguK/lpOMBvgw==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/Borewit" + } + }, "node_modules/@braintree/sanitize-url": { "version": "7.1.1", "resolved": "https://registry.npmjs.org/@braintree/sanitize-url/-/sanitize-url-7.1.1.tgz", @@ -7531,9 +7541,9 @@ } }, "node_modules/@nestjs/cache-manager": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/@nestjs/cache-manager/-/cache-manager-3.0.1.tgz", - "integrity": "sha512-4UxTnR0fsmKL5YDalU2eLFVnL+OBebWUpX+hEduKGncrVKH4PPNoiRn1kXyOCjmzb0UvWgqubpssNouc8e0MCw==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@nestjs/cache-manager/-/cache-manager-3.1.0.tgz", + "integrity": "sha512-pEIqYZrBcE8UdkJmZRduurvoUfdU+3kRPeO1R2muiMbZnRuqlki5klFFNllO9LyYWzrx98bd1j0PSPKSJk1Wbw==", "license": "MIT", "peerDependencies": { "@nestjs/common": "^9.0.0 || ^10.0.0 || ^11.0.0", @@ -7544,12 +7554,12 @@ } }, "node_modules/@nestjs/common": { - "version": "11.1.8", - "resolved": "https://registry.npmjs.org/@nestjs/common/-/common-11.1.8.tgz", - "integrity": "sha512-bbsOqwld/GdBfiRNc4nnjyWWENDEicq4SH+R5AuYatvf++vf1x5JIsHB1i1KtfZMD3eRte0D4K9WXuAYil6XAg==", + "version": "11.1.14", + "resolved": "https://registry.npmjs.org/@nestjs/common/-/common-11.1.14.tgz", + "integrity": "sha512-IN/tlqd7Nl9gl6f0jsWEuOrQDaCI9vHzxv0fisHysfBQzfQIkqlv5A7w4Qge02BUQyczXT9HHPgHtWHCxhjRng==", "license": "MIT", "dependencies": { - "file-type": "21.0.0", + "file-type": "21.3.0", "iterare": "1.2.1", "load-esm": "1.0.3", "tslib": "2.8.1", @@ -7575,57 +7585,24 @@ } }, "node_modules/@nestjs/config": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/@nestjs/config/-/config-4.0.2.tgz", - "integrity": "sha512-McMW6EXtpc8+CwTUwFdg6h7dYcBUpH5iUILCclAsa+MbCEvC9ZKu4dCHRlJqALuhjLw97pbQu62l4+wRwGeZqA==", + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/@nestjs/config/-/config-4.0.3.tgz", + "integrity": "sha512-FQ3M3Ohqfl+nHAn5tp7++wUQw0f2nAk+SFKe8EpNRnIifPqvfJP6JQxPKtFLMOHbyer4X646prFG4zSRYEssQQ==", "license": "MIT", "dependencies": { - "dotenv": "16.4.7", - "dotenv-expand": "12.0.1", - "lodash": "4.17.21" + "dotenv": "17.2.3", + "dotenv-expand": "12.0.3", + "lodash": "4.17.23" }, "peerDependencies": { "@nestjs/common": "^10.0.0 || ^11.0.0", "rxjs": "^7.1.0" } }, - "node_modules/@nestjs/config/node_modules/dotenv": { - "version": "16.4.7", - "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.4.7.tgz", - "integrity": "sha512-47qPchRCykZC03FhkYAhrvwU4xDBFIj1QPqaarj6mdM/hgUzfPHcpkHJOn3mJAufFeeAxAzeGsr5X0M4k6fLZQ==", - "license": "BSD-2-Clause", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://dotenvx.com" - } - }, - "node_modules/@nestjs/config/node_modules/dotenv-expand": { - "version": "12.0.1", - "resolved": "https://registry.npmjs.org/dotenv-expand/-/dotenv-expand-12.0.1.tgz", - "integrity": "sha512-LaKRbou8gt0RNID/9RoI+J2rvXsBRPMV7p+ElHlPhcSARbCPDYcYG2s1TIzAfWv4YSgyY5taidWzzs31lNV3yQ==", - "license": "BSD-2-Clause", - "dependencies": { - "dotenv": "^16.4.5" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://dotenvx.com" - } - }, - "node_modules/@nestjs/config/node_modules/lodash": { - "version": "4.17.21", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", - "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", - "license": "MIT" - }, "node_modules/@nestjs/core": { - "version": "11.1.8", - "resolved": "https://registry.npmjs.org/@nestjs/core/-/core-11.1.8.tgz", - "integrity": "sha512-7riWfmTmMhCJHZ5ZiaG+crj4t85IPCq/wLRuOUSigBYyFT2JZj0lVHtAdf4Davp9ouNI8GINBDt9h9b5Gz9nTw==", + "version": "11.1.14", + "resolved": "https://registry.npmjs.org/@nestjs/core/-/core-11.1.14.tgz", + "integrity": "sha512-7OXPPMoDr6z+5NkoQKu4hOhfjz/YYqM3bNilPqv1WVFWrzSmuNXxvhbX69YMmNmRYascPXiwESqf5jJdjKXEww==", "hasInstallScript": true, "license": "MIT", "dependencies": { @@ -7677,13 +7654,13 @@ } }, "node_modules/@nestjs/jwt": { - "version": "11.0.1", - "resolved": "https://registry.npmjs.org/@nestjs/jwt/-/jwt-11.0.1.tgz", - "integrity": "sha512-HXSsc7SAnCnjA98TsZqrE7trGtHDnYXWp4Ffy6LwSmck1QvbGYdMzBquXofX5l6tIRpeY4Qidl2Ti2CVG77Pdw==", + "version": "11.0.2", + "resolved": "https://registry.npmjs.org/@nestjs/jwt/-/jwt-11.0.2.tgz", + "integrity": "sha512-rK8aE/3/Ma45gAWfCksAXUNbOoSOUudU0Kn3rT39htPF7wsYXtKfjALKeKKJbFrIWbLjsbqfXX5bIJNvgBugGA==", "license": "MIT", "dependencies": { "@types/jsonwebtoken": "9.0.10", - "jsonwebtoken": "9.0.2" + "jsonwebtoken": "9.0.3" }, "peerDependencies": { "@nestjs/common": "^8.0.0 || ^9.0.0 || ^10.0.0 || ^11.0.0" @@ -7700,13 +7677,13 @@ } }, "node_modules/@nestjs/platform-express": { - "version": "11.1.8", - "resolved": "https://registry.npmjs.org/@nestjs/platform-express/-/platform-express-11.1.8.tgz", - "integrity": "sha512-rL6pZH9BW7BnL5X2eWbJMtt86uloAKjFgyY5+L2UkizgfEp7rgAs0+Z1z0BcW2Pgu5+q8O7RKPNyHJ/9ZNz/ZQ==", + "version": "11.1.14", + "resolved": "https://registry.npmjs.org/@nestjs/platform-express/-/platform-express-11.1.14.tgz", + "integrity": "sha512-Fs+/j+mBSBSXErOQJ/YdUn/HqJGSJ4pGfiJyYOyz04l42uNVnqEakvu1kXLbxMabR6vd6/h9d6Bi4tso9p7o4Q==", "license": "MIT", "dependencies": { - "cors": "2.8.5", - "express": "5.1.0", + "cors": "2.8.6", + "express": "5.2.1", "multer": "2.0.2", "path-to-regexp": "8.3.0", "tslib": "2.8.1" @@ -7721,12 +7698,12 @@ } }, "node_modules/@nestjs/schedule": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/@nestjs/schedule/-/schedule-6.0.1.tgz", - "integrity": "sha512-v3yO6cSPAoBSSyH67HWnXHzuhPhSNZhRmLY38JvCt2sqY8sPMOODpcU1D79iUMFf7k16DaMEbL4Mgx61ZhiC8Q==", + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/@nestjs/schedule/-/schedule-6.1.1.tgz", + "integrity": "sha512-kQl1RRgi02GJ0uaUGCrXHCcwISsCsJDciCKe38ykJZgnAeeoeVWs8luWtBo4AqAAXm4nS5K8RlV0smHUJ4+2FA==", "license": "MIT", "dependencies": { - "cron": "4.3.3" + "cron": "4.4.0" }, "peerDependencies": { "@nestjs/common": "^10.0.0 || ^11.0.0", @@ -7910,9 +7887,9 @@ } }, "node_modules/@nestjs/testing": { - "version": "11.1.8", - "resolved": "https://registry.npmjs.org/@nestjs/testing/-/testing-11.1.8.tgz", - "integrity": "sha512-E6K+0UTKztcPxJzLnQa7S34lFjZbrj3Z1r7c5y5WDrL1m5HD1H4AeyBhicHgdaFmxjLAva2bq0sYKy/S7cdeYA==", + "version": "11.1.14", + "resolved": "https://registry.npmjs.org/@nestjs/testing/-/testing-11.1.14.tgz", + "integrity": "sha512-cQxX0ronsTbpfHz8/LYOVWXxoTxv6VoxrnuZoQaVX7QV2PSMqxWE7/9jSQR0GcqAFUEmFP34c6EJqfkjfX/k4Q==", "dev": true, "license": "MIT", "dependencies": { @@ -12408,14 +12385,13 @@ } }, "node_modules/@tokenizer/inflate": { - "version": "0.2.7", - "resolved": "https://registry.npmjs.org/@tokenizer/inflate/-/inflate-0.2.7.tgz", - "integrity": "sha512-MADQgmZT1eKjp06jpI2yozxaU9uVs4GzzgSL+uEq7bVcJ9V1ZXQkeGNql1fsSI0gMy1vhvNTNbUqrx+pZfJVmg==", + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/@tokenizer/inflate/-/inflate-0.4.1.tgz", + "integrity": "sha512-2mAv+8pkG6GIZiF1kNg1jAjh27IDxEPKwdGul3snfztFerfPGI1LjDezZp3i7BElXompqEtPmoPx6c2wgtWsOA==", "license": "MIT", "dependencies": { - "debug": "^4.4.0", - "fflate": "^0.8.2", - "token-types": "^6.0.0" + "debug": "^4.4.3", + "token-types": "^6.1.1" }, "engines": { "node": ">=18" @@ -16984,9 +16960,9 @@ "license": "MIT" }, "node_modules/cors": { - "version": "2.8.5", - "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz", - "integrity": "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==", + "version": "2.8.6", + "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.6.tgz", + "integrity": "sha512-tJtZBBHA6vjIAaF6EnIaq6laBBP9aq/Y3ouVJjEfoHbRBcHBAHYcMh/w8LDrk2PvIMMq8gmopa5D4V8RmbrxGw==", "license": "MIT", "dependencies": { "object-assign": "^4", @@ -16994,6 +16970,10 @@ }, "engines": { "node": ">= 0.10" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" } }, "node_modules/corser": { @@ -17073,9 +17053,9 @@ "license": "MIT" }, "node_modules/cron": { - "version": "4.3.3", - "resolved": "https://registry.npmjs.org/cron/-/cron-4.3.3.tgz", - "integrity": "sha512-B/CJj5yL3sjtlun6RtYHvoSB26EmQ2NUmhq9ZiJSyKIM4K/fqfh9aelDFlIayD2YMeFZqWLi9hHV+c+pq2Djkw==", + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/cron/-/cron-4.4.0.tgz", + "integrity": "sha512-fkdfq+b+AHI4cKdhZlppHveI/mgz2qpiYxcm+t5E5TsxX7QrLS1VE0+7GENEk9z0EeGPcpSciGv6ez24duWhwQ==", "license": "MIT", "dependencies": { "@types/luxon": "~3.7.0", @@ -17083,6 +17063,10 @@ }, "engines": { "node": ">=18.x" + }, + "funding": { + "type": "ko-fi", + "url": "https://ko-fi.com/intcreator" } }, "node_modules/cron-parser": { @@ -19852,18 +19836,19 @@ "license": "Apache-2.0" }, "node_modules/express": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/express/-/express-5.1.0.tgz", - "integrity": "sha512-DT9ck5YIRU+8GYzzU5kT3eHGA5iL+1Zd0EutOmTE9Dtk+Tvuzd23VBU+ec7HPNSTxXYO55gPV/hq4pSBJDjFpA==", + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/express/-/express-5.2.1.tgz", + "integrity": "sha512-hIS4idWWai69NezIdRt2xFVofaF4j+6INOpJlVOLDO8zXGpUVEVzIYk12UUi2JzjEzWL3IOAxcTubgz9Po0yXw==", "license": "MIT", "dependencies": { "accepts": "^2.0.0", - "body-parser": "^2.2.0", + "body-parser": "^2.2.1", "content-disposition": "^1.0.0", "content-type": "^1.0.5", "cookie": "^0.7.1", "cookie-signature": "^1.2.1", "debug": "^4.4.0", + "depd": "^2.0.0", "encodeurl": "^2.0.0", "escape-html": "^1.0.3", "etag": "^1.8.1", @@ -20129,12 +20114,6 @@ "filenamify-url": "2.1.2" } }, - "node_modules/fflate": { - "version": "0.8.2", - "resolved": "https://registry.npmjs.org/fflate/-/fflate-0.8.2.tgz", - "integrity": "sha512-cPJU47OaAoCbg0pBvzsgpTPhmhqI5eJjh/JIu8tPj5q+T7iLvW/JAYUqmE7KOB4R1ZyEhzBaIQpQpardBF5z8A==", - "license": "MIT" - }, "node_modules/figures": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/figures/-/figures-3.2.0.tgz", @@ -20175,14 +20154,14 @@ } }, "node_modules/file-type": { - "version": "21.0.0", - "resolved": "https://registry.npmjs.org/file-type/-/file-type-21.0.0.tgz", - "integrity": "sha512-ek5xNX2YBYlXhiUXui3D/BXa3LdqPmoLJ7rqEx2bKJ7EAUEfmXgW0Das7Dc6Nr9MvqaOnIqiPV0mZk/r/UpNAg==", + "version": "21.3.0", + "resolved": "https://registry.npmjs.org/file-type/-/file-type-21.3.0.tgz", + "integrity": "sha512-8kPJMIGz1Yt/aPEwOsrR97ZyZaD1Iqm8PClb1nYFclUCkBi0Ma5IsYNQzvSFS9ib51lWyIw5mIT9rWzI/xjpzA==", "license": "MIT", "dependencies": { - "@tokenizer/inflate": "^0.2.7", - "strtok3": "^10.2.2", - "token-types": "^6.0.0", + "@tokenizer/inflate": "^0.4.1", + "strtok3": "^10.3.4", + "token-types": "^6.1.1", "uint8array-extras": "^1.4.0" }, "engines": { @@ -24592,12 +24571,12 @@ } }, "node_modules/jsonwebtoken": { - "version": "9.0.2", - "resolved": "https://registry.npmjs.org/jsonwebtoken/-/jsonwebtoken-9.0.2.tgz", - "integrity": "sha512-PRp66vJ865SSqOlgqS8hujT5U4AOgMfhrwYIuIhfKaoSCZcirrmASQr8CX7cUg+RMih+hgznrjp99o+W4pJLHQ==", + "version": "9.0.3", + "resolved": "https://registry.npmjs.org/jsonwebtoken/-/jsonwebtoken-9.0.3.tgz", + "integrity": "sha512-MT/xP0CrubFRNLNKvxJ2BYfy53Zkm++5bX9dtuPbqAeQpTVe0MQTFhao8+Cp//EmJp244xt6Drw/GVEGCUj40g==", "license": "MIT", "dependencies": { - "jws": "^3.2.2", + "jws": "^4.0.1", "lodash.includes": "^4.3.0", "lodash.isboolean": "^3.0.3", "lodash.isinteger": "^4.0.4", @@ -24613,27 +24592,6 @@ "npm": ">=6" } }, - "node_modules/jsonwebtoken/node_modules/jwa": { - "version": "1.4.2", - "resolved": "https://registry.npmjs.org/jwa/-/jwa-1.4.2.tgz", - "integrity": "sha512-eeH5JO+21J78qMvTIDdBXidBd6nG2kZjg5Ohz/1fpa28Z4CcsWUzJ1ZZyFq/3z3N17aZy+ZuBoHljASbL1WfOw==", - "license": "MIT", - "dependencies": { - "buffer-equal-constant-time": "^1.0.1", - "ecdsa-sig-formatter": "1.0.11", - "safe-buffer": "^5.0.1" - } - }, - "node_modules/jsonwebtoken/node_modules/jws": { - "version": "3.2.3", - "resolved": "https://registry.npmjs.org/jws/-/jws-3.2.3.tgz", - "integrity": "sha512-byiJ0FLRdLdSVSReO/U4E7RoEyOCKnEnEPMjq3HxWtvzLsV08/i5RQKsFVNkCldrCaPr2vDNAOMsfs8T/Hze7g==", - "license": "MIT", - "dependencies": { - "jwa": "^1.4.2", - "safe-buffer": "^5.0.1" - } - }, "node_modules/jsonwebtoken/node_modules/ms": { "version": "2.1.3", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", @@ -32900,11 +32858,12 @@ } }, "node_modules/token-types": { - "version": "6.0.4", - "resolved": "https://registry.npmjs.org/token-types/-/token-types-6.0.4.tgz", - "integrity": "sha512-MD9MjpVNhVyH4fyd5rKphjvt/1qj+PtQUz65aFqAZA6XniWAuSFRjLk3e2VALEFlh9OwBpXUN7rfeqSnT/Fmkw==", + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/token-types/-/token-types-6.1.2.tgz", + "integrity": "sha512-dRXchy+C0IgK8WPC6xvCHFRIWYUbqqdEIKPaKo/AcTUNzwLTK6AH7RjdLWsEZcAN/TBdtfUw3PYEgPr5VPr6ww==", "license": "MIT", "dependencies": { + "@borewit/text-codec": "^0.2.1", "@tokenizer/token": "^0.3.0", "ieee754": "^1.2.1" }, @@ -33690,9 +33649,9 @@ "license": "MIT" }, "node_modules/uint8array-extras": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/uint8array-extras/-/uint8array-extras-1.4.0.tgz", - "integrity": "sha512-ZPtzy0hu4cZjv3z5NW9gfKnNLjoz4y6uv4HlelAjDK7sY/xOkKZv9xK/WQpcsBB3jEybChz9DPC2U/+cusjJVQ==", + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/uint8array-extras/-/uint8array-extras-1.5.0.tgz", + "integrity": "sha512-rvKSBiC5zqCCiDZ9kAOszZcDvdAHwwIKJG33Ykj43OKcWsnmcBRL09YTU4nOeHZ8Y2a7l1MgTd08SBe9A8Qj6A==", "license": "MIT", "engines": { "node": ">=18" diff --git a/package.json b/package.json index 2bf5eebe0..5f80c3627 100644 --- a/package.json +++ b/package.json @@ -72,15 +72,15 @@ "@ionic/angular": "8.7.8", "@keyv/redis": "4.4.0", "@nestjs/bull": "11.0.4", - "@nestjs/cache-manager": "3.0.1", - "@nestjs/common": "11.1.8", - "@nestjs/config": "4.0.2", - "@nestjs/core": "11.1.8", + "@nestjs/cache-manager": "3.1.0", + "@nestjs/common": "11.1.14", + "@nestjs/config": "4.0.3", + "@nestjs/core": "11.1.14", "@nestjs/event-emitter": "3.0.1", - "@nestjs/jwt": "11.0.1", + "@nestjs/jwt": "11.0.2", "@nestjs/passport": "11.0.5", - "@nestjs/platform-express": "11.1.8", - "@nestjs/schedule": "6.0.1", + "@nestjs/platform-express": "11.1.14", + "@nestjs/schedule": "6.1.1", "@nestjs/serve-static": "5.0.4", "@openrouter/ai-sdk-provider": "0.7.2", "@prisma/client": "6.19.0", @@ -152,7 +152,7 @@ "@eslint/eslintrc": "3.3.1", "@eslint/js": "9.35.0", "@nestjs/schematics": "11.0.9", - "@nestjs/testing": "11.1.8", + "@nestjs/testing": "11.1.14", "@nx/angular": "22.4.5", "@nx/eslint-plugin": "22.4.5", "@nx/jest": "22.4.5", From cc92ecf62a014b27146338bb7a20ed6eeb525fba Mon Sep 17 00:00:00 2001 From: Thomas Kaul <4159106+dtslvr@users.noreply.github.com> Date: Mon, 23 Feb 2026 20:30:53 +0100 Subject: [PATCH 048/224] Release 2.243.0 (#6384) --- CHANGELOG.md | 2 +- package-lock.json | 4 ++-- package.json | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a482c10e8..f806a260e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,7 +5,7 @@ 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 +## 2.243.0 - 2026-02-23 ### Changed diff --git a/package-lock.json b/package-lock.json index 9d022919b..fadeca52d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "ghostfolio", - "version": "2.242.0", + "version": "2.243.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "ghostfolio", - "version": "2.242.0", + "version": "2.243.0", "hasInstallScript": true, "license": "AGPL-3.0", "dependencies": { diff --git a/package.json b/package.json index 5f80c3627..ad615c3a0 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "ghostfolio", - "version": "2.242.0", + "version": "2.243.0", "homepage": "https://ghostfol.io", "license": "AGPL-3.0", "repository": "https://github.com/ghostfolio/ghostfolio", From 90cc7af87c10a4bfc9eb00b218b2046b246c3aa6 Mon Sep 17 00:00:00 2001 From: Kenrick Tandrian <60643640+KenTandrian@users.noreply.github.com> Date: Tue, 24 Feb 2026 23:42:41 +0400 Subject: [PATCH 049/224] Task/improve type safety in fire calculator component (#6385) * fix(lib): resolve typescript errors * fix(lib): make unsubscribeSubject readonly * feat(lib): migrate outputs to signals * feat(lib): implement takeUntilDestroyed * feat(lib): add linebreak --- .../fire-calculator.component.ts | 128 ++++++++++-------- 1 file changed, 72 insertions(+), 56 deletions(-) diff --git a/libs/ui/src/lib/fire-calculator/fire-calculator.component.ts b/libs/ui/src/lib/fire-calculator/fire-calculator.component.ts index 7461f6729..8b472fc47 100644 --- a/libs/ui/src/lib/fire-calculator/fire-calculator.component.ts +++ b/libs/ui/src/lib/fire-calculator/fire-calculator.component.ts @@ -13,13 +13,13 @@ import { ChangeDetectorRef, Component, ElementRef, - EventEmitter, Input, OnChanges, OnDestroy, - Output, - ViewChild + ViewChild, + output } from '@angular/core'; +import { takeUntilDestroyed } from '@angular/core/rxjs-interop'; import { FormBuilder, FormControl, @@ -55,9 +55,9 @@ import { startOfMonth, sub } from 'date-fns'; -import { isNumber } from 'lodash'; +import { isNil, isNumber } from 'lodash'; import { NgxSkeletonLoaderModule } from 'ngx-skeleton-loader'; -import { Subject, debounceTime, takeUntil } from 'rxjs'; +import { debounceTime } from 'rxjs'; import { FireCalculatorService } from './fire-calculator.service'; @@ -90,32 +90,31 @@ export class GfFireCalculatorComponent implements OnChanges, OnDestroy { @Input() retirementDate: Date; @Input() savingsRate = 0; - @Output() annualInterestRateChanged = new EventEmitter(); - @Output() calculationCompleted = - new EventEmitter(); - @Output() projectedTotalAmountChanged = new EventEmitter(); - @Output() retirementDateChanged = new EventEmitter(); - @Output() savingsRateChanged = new EventEmitter(); - @ViewChild('chartCanvas') chartCanvas: ElementRef; public calculatorForm = this.formBuilder.group({ - annualInterestRate: new FormControl(undefined), - paymentPerPeriod: new FormControl(undefined), - principalInvestmentAmount: new FormControl(undefined), - projectedTotalAmount: new FormControl(undefined), - retirementDate: new FormControl(undefined) + annualInterestRate: new FormControl(null), + paymentPerPeriod: new FormControl(null), + principalInvestmentAmount: new FormControl(null), + projectedTotalAmount: new FormControl(null), + retirementDate: new FormControl(null) }); public chart: Chart<'bar'>; public isLoading = true; public minDate = addDays(new Date(), 1); public periodsToRetire = 0; + protected readonly annualInterestRateChanged = output(); + protected readonly calculationCompleted = + output(); + protected readonly projectedTotalAmountChanged = output(); + protected readonly retirementDateChanged = output(); + protected readonly savingsRateChanged = output(); + private readonly CONTRIBUTION_PERIOD = 12; private readonly DEFAULT_RETIREMENT_DATE = startOfMonth( addYears(new Date(), 10) ); - private unsubscribeSubject = new Subject(); public constructor( private changeDetectorRef: ChangeDetectorRef, @@ -131,46 +130,56 @@ export class GfFireCalculatorComponent implements OnChanges, OnDestroy { ); this.calculatorForm.valueChanges - .pipe(takeUntil(this.unsubscribeSubject)) + .pipe(takeUntilDestroyed()) .subscribe(() => { this.initialize(); }); this.calculatorForm.valueChanges - .pipe(debounceTime(500), takeUntil(this.unsubscribeSubject)) + .pipe(debounceTime(500), takeUntilDestroyed()) .subscribe(() => { const { projectedTotalAmount, retirementDate } = this.calculatorForm.getRawValue(); - this.calculationCompleted.emit({ - projectedTotalAmount, - retirementDate - }); + if (projectedTotalAmount !== null && retirementDate !== null) { + this.calculationCompleted.emit({ + projectedTotalAmount, + retirementDate + }); + } }); this.calculatorForm .get('annualInterestRate') - .valueChanges.pipe(debounceTime(500), takeUntil(this.unsubscribeSubject)) + ?.valueChanges.pipe(debounceTime(500), takeUntilDestroyed()) .subscribe((annualInterestRate) => { - this.annualInterestRateChanged.emit(annualInterestRate); + if (annualInterestRate !== null) { + this.annualInterestRateChanged.emit(annualInterestRate); + } }); this.calculatorForm .get('paymentPerPeriod') - .valueChanges.pipe(debounceTime(500), takeUntil(this.unsubscribeSubject)) + ?.valueChanges.pipe(debounceTime(500), takeUntilDestroyed()) .subscribe((savingsRate) => { - this.savingsRateChanged.emit(savingsRate); + if (savingsRate !== null) { + this.savingsRateChanged.emit(savingsRate); + } }); this.calculatorForm .get('projectedTotalAmount') - .valueChanges.pipe(debounceTime(500), takeUntil(this.unsubscribeSubject)) + ?.valueChanges.pipe(debounceTime(500), takeUntilDestroyed()) .subscribe((projectedTotalAmount) => { - this.projectedTotalAmountChanged.emit(projectedTotalAmount); + if (projectedTotalAmount !== null) { + this.projectedTotalAmountChanged.emit(projectedTotalAmount); + } }); this.calculatorForm .get('retirementDate') - .valueChanges.pipe(debounceTime(500), takeUntil(this.unsubscribeSubject)) + ?.valueChanges.pipe(debounceTime(500), takeUntilDestroyed()) .subscribe((retirementDate) => { - this.retirementDateChanged.emit(retirementDate); + if (retirementDate !== null) { + this.retirementDateChanged.emit(retirementDate); + } }); } @@ -196,11 +205,11 @@ export class GfFireCalculatorComponent implements OnChanges, OnDestroy { this.calculatorForm.patchValue( { annualInterestRate: - this.calculatorForm.get('annualInterestRate').value, + this.calculatorForm.get('annualInterestRate')?.value, paymentPerPeriod: this.getPMT(), principalInvestmentAmount: this.calculatorForm.get( 'principalInvestmentAmount' - ).value, + )?.value, projectedTotalAmount: Math.round(this.getProjectedTotalAmount()) || 0, retirementDate: @@ -210,7 +219,7 @@ export class GfFireCalculatorComponent implements OnChanges, OnDestroy { emitEvent: false } ); - this.calculatorForm.get('principalInvestmentAmount').disable(); + this.calculatorForm.get('principalInvestmentAmount')?.disable(); this.changeDetectorRef.markForCheck(); }); @@ -219,42 +228,43 @@ export class GfFireCalculatorComponent implements OnChanges, OnDestroy { if (this.hasPermissionToUpdateUserSettings === true) { this.calculatorForm .get('annualInterestRate') - .enable({ emitEvent: false }); - this.calculatorForm.get('paymentPerPeriod').enable({ emitEvent: false }); + ?.enable({ emitEvent: false }); + this.calculatorForm.get('paymentPerPeriod')?.enable({ emitEvent: false }); this.calculatorForm .get('projectedTotalAmount') - .enable({ emitEvent: false }); + ?.enable({ emitEvent: false }); } else { this.calculatorForm .get('annualInterestRate') - .disable({ emitEvent: false }); - this.calculatorForm.get('paymentPerPeriod').disable({ emitEvent: false }); + ?.disable({ emitEvent: false }); + this.calculatorForm + .get('paymentPerPeriod') + ?.disable({ emitEvent: false }); this.calculatorForm .get('projectedTotalAmount') - .disable({ emitEvent: false }); + ?.disable({ emitEvent: false }); } - this.calculatorForm.get('retirementDate').disable({ emitEvent: false }); + this.calculatorForm.get('retirementDate')?.disable({ emitEvent: false }); } public setMonthAndYear( normalizedMonthAndYear: Date, datepicker: MatDatepicker ) { - const retirementDate = this.calculatorForm.get('retirementDate').value; + const retirementDate = + this.calculatorForm.get('retirementDate')?.value ?? + this.DEFAULT_RETIREMENT_DATE; const newRetirementDate = setMonth( setYear(retirementDate, normalizedMonthAndYear.getFullYear()), normalizedMonthAndYear.getMonth() ); - this.calculatorForm.get('retirementDate').setValue(newRetirementDate); + this.calculatorForm.get('retirementDate')?.setValue(newRetirementDate); datepicker.close(); } public ngOnDestroy() { this.chart?.destroy(); - - this.unsubscribeSubject.next(); - this.unsubscribeSubject.complete(); } private initialize() { @@ -288,8 +298,6 @@ export class GfFireCalculatorComponent implements OnChanges, OnDestroy { return `Total: ${new Intl.NumberFormat(this.locale, { currency: this.currency, - // eslint-disable-next-line @typescript-eslint/ban-ts-comment - // @ts-ignore: Only supported from ES2020 or later currencyDisplay: 'code', style: 'currency' }).format(totalAmount)}`; @@ -426,12 +434,16 @@ export class GfFireCalculatorComponent implements OnChanges, OnDestroy { } private getPeriodsToRetire(): number { - if (this.calculatorForm.get('projectedTotalAmount').value) { + const projectedTotalAmount = this.calculatorForm.get( + 'projectedTotalAmount' + )?.value; + + if (projectedTotalAmount) { let periods = this.fireCalculatorService.calculatePeriodsToRetire({ P: this.getP(), PMT: this.getPMT(), r: this.getR(), - totalAmount: this.calculatorForm.get('projectedTotalAmount').value + totalAmount: projectedTotalAmount }); if (periods === Infinity) { @@ -453,12 +465,16 @@ export class GfFireCalculatorComponent implements OnChanges, OnDestroy { } private getPMT() { - return this.calculatorForm.get('paymentPerPeriod').value; + return this.calculatorForm.get('paymentPerPeriod')?.value ?? 0; } private getProjectedTotalAmount() { - if (this.calculatorForm.get('projectedTotalAmount').value) { - return this.calculatorForm.get('projectedTotalAmount').value; + const projectedTotalAmount = this.calculatorForm.get( + 'projectedTotalAmount' + )?.value; + + if (!isNil(projectedTotalAmount)) { + return projectedTotalAmount; } const { totalAmount } = @@ -473,12 +489,12 @@ export class GfFireCalculatorComponent implements OnChanges, OnDestroy { } private getR() { - return this.calculatorForm.get('annualInterestRate').value / 100; + return (this.calculatorForm.get('annualInterestRate')?.value ?? 0) / 100; } private getRetirementDate(): Date { if (this.periodsToRetire === Number.MAX_SAFE_INTEGER) { - return undefined; + return this.DEFAULT_RETIREMENT_DATE; } const monthsToRetire = this.periodsToRetire % 12; From 2e01c121e451406b0b4c47e76c84de627a9bd1b1 Mon Sep 17 00:00:00 2001 From: Thomas Kaul <4159106+dtslvr@users.noreply.github.com> Date: Tue, 24 Feb 2026 20:43:17 +0100 Subject: [PATCH 050/224] Task/remove unused OnDestroy hook in resources page component (#6367) * Remove unused OnDestroy hook --- .../src/app/pages/resources/resources-page.component.ts | 8 -------- 1 file changed, 8 deletions(-) diff --git a/apps/client/src/app/pages/resources/resources-page.component.ts b/apps/client/src/app/pages/resources/resources-page.component.ts index 9db996f57..c25ef00d6 100644 --- a/apps/client/src/app/pages/resources/resources-page.component.ts +++ b/apps/client/src/app/pages/resources/resources-page.component.ts @@ -13,7 +13,6 @@ import { readerOutline } from 'ionicons/icons'; import { DeviceDetectorService } from 'ngx-device-detector'; -import { Subject } from 'rxjs'; @Component({ host: { class: 'page has-tabs' }, @@ -47,8 +46,6 @@ export class ResourcesPageComponent implements OnInit { } ]; - private unsubscribeSubject = new Subject(); - public constructor(private deviceService: DeviceDetectorService) { addIcons({ bookOutline, libraryOutline, newspaperOutline, readerOutline }); } @@ -56,9 +53,4 @@ export class ResourcesPageComponent implements OnInit { public ngOnInit() { this.deviceType = this.deviceService.getDeviceInfo().deviceType; } - - public ngOnDestroy() { - this.unsubscribeSubject.next(); - this.unsubscribeSubject.complete(); - } } From 386a77c8f746f9413f0cdb837a4fe234059963cf Mon Sep 17 00:00:00 2001 From: Kenrick Tandrian <60643640+KenTandrian@users.noreply.github.com> Date: Wed, 25 Feb 2026 22:15:06 +0400 Subject: [PATCH 051/224] Task/improve type safety in assistant components (#6396) * feat(lib): resolve typescript errors in assistant * feat(lib): resolve typescript errors in assistant list item * feat(lib): implement output signals * fix(lint): resolve warnings * fix(lib): implement inject function * fix(lib): handle errors in html files --- .../assistant-list-item.component.ts | 24 +++-- .../assistant-list-item.html | 2 +- .../src/lib/assistant/assistant.component.ts | 102 +++++++++--------- libs/ui/src/lib/assistant/assistant.html | 2 +- .../portfolio-filter-form-value.interface.ts | 8 +- 5 files changed, 70 insertions(+), 68 deletions(-) diff --git a/libs/ui/src/lib/assistant/assistant-list-item/assistant-list-item.component.ts b/libs/ui/src/lib/assistant/assistant-list-item/assistant-list-item.component.ts index c2ad2462e..05750cea4 100644 --- a/libs/ui/src/lib/assistant/assistant-list-item/assistant-list-item.component.ts +++ b/libs/ui/src/lib/assistant/assistant-list-item/assistant-list-item.component.ts @@ -7,12 +7,12 @@ import { ChangeDetectorRef, Component, ElementRef, - EventEmitter, HostBinding, Input, OnChanges, - Output, - ViewChild + ViewChild, + inject, + output } from '@angular/core'; import { Params, RouterModule } from '@angular/router'; @@ -33,21 +33,23 @@ export class GfAssistantListItemComponent implements FocusableOption, OnChanges { @HostBinding('attr.tabindex') tabindex = -1; - @HostBinding('class.has-focus') get getHasFocus() { - return this.hasFocus; - } @Input() item: SearchResultItem; - @Output() clicked = new EventEmitter(); - - @ViewChild('link') public linkElement: ElementRef; + @ViewChild('link') public linkElement: ElementRef; public hasFocus = false; public queryParams: Params; public routerLink: string[]; - public constructor(private changeDetectorRef: ChangeDetectorRef) {} + protected readonly clicked = output(); + + private readonly changeDetectorRef = inject(ChangeDetectorRef); + + @HostBinding('class.has-focus') + public get getHasFocus() { + return this.hasFocus; + } public ngOnChanges() { if (this.item?.mode === SearchMode.ACCOUNT) { @@ -65,7 +67,7 @@ export class GfAssistantListItemComponent }; this.routerLink = - internalRoutes.adminControl.subRoutes.marketData.routerLink; + internalRoutes.adminControl.subRoutes?.marketData.routerLink ?? []; } else if (this.item?.mode === SearchMode.HOLDING) { this.queryParams = { dataSource: this.item.dataSource, diff --git a/libs/ui/src/lib/assistant/assistant-list-item/assistant-list-item.html b/libs/ui/src/lib/assistant/assistant-list-item/assistant-list-item.html index fd2c4011d..36179b719 100644 --- a/libs/ui/src/lib/assistant/assistant-list-item/assistant-list-item.html +++ b/libs/ui/src/lib/assistant/assistant-list-item/assistant-list-item.html @@ -8,7 +8,7 @@ @if (item && isAsset(item)) {
    {{ item?.symbol | gfSymbol }} · {{ item?.currency }} + >{{ item?.symbol ?? '' | gfSymbol }} · {{ item?.currency }} @if (item?.assetSubClassString) { · {{ item.assetSubClassString }} } diff --git a/libs/ui/src/lib/assistant/assistant.component.ts b/libs/ui/src/lib/assistant/assistant.component.ts index 2b0216613..1c67e4fa2 100644 --- a/libs/ui/src/lib/assistant/assistant.component.ts +++ b/libs/ui/src/lib/assistant/assistant.component.ts @@ -12,16 +12,15 @@ import { ChangeDetectorRef, Component, ElementRef, - EventEmitter, HostListener, Input, OnChanges, OnDestroy, OnInit, - Output, QueryList, ViewChild, - ViewChildren + ViewChildren, + output } from '@angular/core'; import { FormControl, FormsModule, ReactiveFormsModule } from '@angular/forms'; import { MatButtonModule } from '@angular/material/button'; @@ -86,37 +85,7 @@ import { templateUrl: './assistant.html' }) export class GfAssistantComponent implements OnChanges, OnDestroy, OnInit { - @HostListener('document:keydown', ['$event']) onKeydown( - event: KeyboardEvent - ) { - if (!this.isOpen) { - return; - } - - if (event.key === 'ArrowDown' || event.key === 'ArrowUp') { - for (const item of this.assistantListItems) { - item.removeFocus(); - } - - this.keyManager.onKeydown(event); - - const currentAssistantListItem = this.getCurrentAssistantListItem(); - - if (currentAssistantListItem?.linkElement) { - currentAssistantListItem.linkElement.nativeElement?.scrollIntoView({ - behavior: 'smooth', - block: 'center' - }); - } - } else if (event.key === 'Enter') { - const currentAssistantListItem = this.getCurrentAssistantListItem(); - - if (currentAssistantListItem?.linkElement) { - currentAssistantListItem.linkElement.nativeElement?.click(); - event.stopPropagation(); - } - } - } + public static readonly SEARCH_RESULTS_DEFAULT_LIMIT = 5; @Input() deviceType: string; @Input() hasPermissionToAccessAdminControl: boolean; @@ -124,21 +93,16 @@ export class GfAssistantComponent implements OnChanges, OnDestroy, OnInit { @Input() hasPermissionToChangeFilters: boolean; @Input() user: User; - @Output() closed = new EventEmitter(); - @Output() dateRangeChanged = new EventEmitter(); - @Output() filtersChanged = new EventEmitter(); - @ViewChild('menuTrigger') menuTriggerElement: MatMenuTrigger; - @ViewChild('search', { static: true }) searchElement: ElementRef; + @ViewChild('search', { static: true }) + searchElement: ElementRef; @ViewChildren(GfAssistantListItemComponent) assistantListItems: QueryList; - public static readonly SEARCH_RESULTS_DEFAULT_LIMIT = 5; - public accounts: AccountWithPlatform[] = []; public assetClasses: Filter[] = []; - public dateRangeFormControl = new FormControl(undefined); + public dateRangeFormControl = new FormControl(null); public dateRangeOptions: DateRangeOption[] = []; public holdings: PortfolioPosition[] = []; public isLoading = { @@ -166,6 +130,10 @@ export class GfAssistantComponent implements OnChanges, OnDestroy, OnInit { }; public tags: Filter[] = []; + protected readonly closed = output(); + protected readonly dateRangeChanged = output(); + protected readonly filtersChanged = output(); + private readonly PRESELECTION_DELAY = 100; private filterTypes: Filter['type'][] = [ @@ -188,6 +156,37 @@ export class GfAssistantComponent implements OnChanges, OnDestroy, OnInit { addIcons({ closeCircleOutline, closeOutline, searchOutline }); } + @HostListener('document:keydown', ['$event']) + public onKeydown(event: KeyboardEvent) { + if (!this.isOpen) { + return; + } + + if (event.key === 'ArrowDown' || event.key === 'ArrowUp') { + for (const item of this.assistantListItems) { + item.removeFocus(); + } + + this.keyManager.onKeydown(event); + + const currentAssistantListItem = this.getCurrentAssistantListItem(); + + if (currentAssistantListItem?.linkElement) { + currentAssistantListItem.linkElement.nativeElement?.scrollIntoView({ + behavior: 'smooth', + block: 'center' + }); + } + } else if (event.key === 'Enter') { + const currentAssistantListItem = this.getCurrentAssistantListItem(); + + if (currentAssistantListItem?.linkElement) { + currentAssistantListItem.linkElement.nativeElement?.click(); + event.stopPropagation(); + } + } + } + public ngOnInit() { this.assetClasses = Object.keys(AssetClass).map((assetClass) => { return { @@ -482,7 +481,7 @@ export class GfAssistantComponent implements OnChanges, OnDestroy, OnInit { .subscribe(({ holdings }) => { this.holdings = holdings .filter(({ assetSubClass }) => { - return !['CASH'].includes(assetSubClass); + return assetSubClass && !['CASH'].includes(assetSubClass); }) .sort((a, b) => { return a.name?.localeCompare(b.name); @@ -499,23 +498,23 @@ export class GfAssistantComponent implements OnChanges, OnDestroy, OnInit { this.filtersChanged.emit([ { - id: filterValue?.account, + id: filterValue?.account ?? '', type: 'ACCOUNT' }, { - id: filterValue?.assetClass, + id: filterValue?.assetClass ?? '', type: 'ASSET_CLASS' }, { - id: filterValue?.holding?.dataSource, + id: filterValue?.holding?.dataSource ?? '', type: 'DATA_SOURCE' }, { - id: filterValue?.holding?.symbol, + id: filterValue?.holding?.symbol ?? '', type: 'SYMBOL' }, { - id: filterValue?.tag, + id: filterValue?.tag ?? '', type: 'TAG' } ]); @@ -541,7 +540,7 @@ export class GfAssistantComponent implements OnChanges, OnDestroy, OnInit { this.filterTypes.map((type) => { return { type, - id: null + id: '' }; }) ); @@ -673,7 +672,7 @@ export class GfAssistantComponent implements OnChanges, OnDestroy, OnInit { dataSource, name, symbol, - assetSubClassString: translate(assetSubClass), + assetSubClassString: translate(assetSubClass ?? ''), mode: SearchMode.ASSET_PROFILE as const }; } @@ -705,7 +704,7 @@ export class GfAssistantComponent implements OnChanges, OnDestroy, OnInit { dataSource, name, symbol, - assetSubClassString: translate(assetSubClass), + assetSubClassString: translate(assetSubClass ?? ''), mode: SearchMode.HOLDING as const }; } @@ -755,6 +754,7 @@ export class GfAssistantComponent implements OnChanges, OnDestroy, OnInit { const symbol = this.user?.settings?.['filters.symbol']; const selectedHolding = this.holdings.find((holding) => { return ( + !!(dataSource && symbol) && getAssetProfileIdentifier({ dataSource: holding.dataSource, symbol: holding.symbol diff --git a/libs/ui/src/lib/assistant/assistant.html b/libs/ui/src/lib/assistant/assistant.html index 307269262..7e19833a9 100644 --- a/libs/ui/src/lib/assistant/assistant.html +++ b/libs/ui/src/lib/assistant/assistant.html @@ -186,7 +186,7 @@
    Date: Wed, 25 Feb 2026 14:50:36 -0500 Subject: [PATCH 052/224] Bugfix/handle X-ray rule exception when market price is missing (#6397) * Handle X-ray rule exception when market price is missing * Update changelog --- CHANGELOG.md | 6 ++++++ apps/api/src/models/rule.ts | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f806a260e..6b1a1c978 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 an exception by adding a fallback for missing market price values on the _X-ray_ page + ## 2.243.0 - 2026-02-23 ### Changed diff --git a/apps/api/src/models/rule.ts b/apps/api/src/models/rule.ts index 9c27e0018..622375b5b 100644 --- a/apps/api/src/models/rule.ts +++ b/apps/api/src/models/rule.ts @@ -57,7 +57,7 @@ export abstract class Rule implements RuleInterface { previousValue + this.exchangeRateDataService.toCurrency( new Big(currentValue.quantity) - .mul(currentValue.marketPrice) + .mul(currentValue.marketPrice ?? 0) .toNumber(), currentValue.currency, baseCurrency From 4cf16b8c58440d2408ab4594a10fe6b17d06de3f Mon Sep 17 00:00:00 2001 From: Thomas Kaul <4159106+dtslvr@users.noreply.github.com> Date: Thu, 26 Feb 2026 17:26:00 +0100 Subject: [PATCH 053/224] Task/remove unused OnDestroy hook in license page component (#6380) * Remove unused OnDestroy hook --- .../pages/about/license/license-page.component.ts | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/apps/client/src/app/pages/about/license/license-page.component.ts b/apps/client/src/app/pages/about/license/license-page.component.ts index 0dc5b2f51..d530d0418 100644 --- a/apps/client/src/app/pages/about/license/license-page.component.ts +++ b/apps/client/src/app/pages/about/license/license-page.component.ts @@ -1,6 +1,5 @@ -import { Component, OnDestroy } from '@angular/core'; +import { Component } from '@angular/core'; import { MarkdownModule } from 'ngx-markdown'; -import { Subject } from 'rxjs'; @Component({ imports: [MarkdownModule], @@ -8,11 +7,4 @@ import { Subject } from 'rxjs'; styleUrls: ['./license-page.scss'], templateUrl: './license-page.html' }) -export class GfLicensePageComponent implements OnDestroy { - private unsubscribeSubject = new Subject(); - - public ngOnDestroy() { - this.unsubscribeSubject.next(); - this.unsubscribeSubject.complete(); - } -} +export class GfLicensePageComponent {} From 69740db29215439e44d0c0a139d7f8072d4cbe7c Mon Sep 17 00:00:00 2001 From: Kenrick Tandrian <60643640+KenTandrian@users.noreply.github.com> Date: Thu, 26 Feb 2026 20:26:21 +0400 Subject: [PATCH 054/224] Task/improve type safety in currency selector (#6402) * feat(lib): resolve typescript errors * feat(lib): make input a view child signal * feat(lib): remove unsubscribe subject * feat(lib): remove ngOnDestroy * feat(lib): make currencies an input signal * feat(lib): make formControlName an input signal --- .../currency-selector.component.ts | 90 +++++++++---------- 1 file changed, 42 insertions(+), 48 deletions(-) diff --git a/libs/ui/src/lib/currency-selector/currency-selector.component.ts b/libs/ui/src/lib/currency-selector/currency-selector.component.ts index 35a911716..7b6236fbb 100644 --- a/libs/ui/src/lib/currency-selector/currency-selector.component.ts +++ b/libs/ui/src/lib/currency-selector/currency-selector.component.ts @@ -4,13 +4,16 @@ import { ChangeDetectionStrategy, ChangeDetectorRef, Component, + DestroyRef, DoCheck, ElementRef, - Input, - OnDestroy, OnInit, - ViewChild + ViewChild, + inject, + input, + viewChild } from '@angular/core'; +import { takeUntilDestroyed } from '@angular/core/rxjs-interop'; import { FormControl, FormGroupDirective, @@ -21,15 +24,14 @@ import { import { MatAutocomplete, MatAutocompleteModule, - MatAutocompleteSelectedEvent + MatOption } from '@angular/material/autocomplete'; import { MatFormFieldControl, MatFormFieldModule } from '@angular/material/form-field'; import { MatInput, MatInputModule } from '@angular/material/input'; -import { Subject } from 'rxjs'; -import { map, startWith, takeUntil } from 'rxjs/operators'; +import { map, startWith } from 'rxjs/operators'; import { AbstractMatFormField } from '../shared/abstract-mat-form-field'; @@ -58,21 +60,19 @@ import { AbstractMatFormField } from '../shared/abstract-mat-form-field'; templateUrl: 'currency-selector.component.html' }) export class GfCurrencySelectorComponent - extends AbstractMatFormField - implements DoCheck, OnDestroy, OnInit + extends AbstractMatFormField + implements DoCheck, OnInit { - @Input() private currencies: string[] = []; - @Input() private formControlName: string; - - @ViewChild(MatInput) private input: MatInput; - @ViewChild('currencyAutocomplete') public currencyAutocomplete: MatAutocomplete; - public control = new FormControl(); + public readonly control = new FormControl(null); + public readonly currencies = input.required(); public filteredCurrencies: string[] = []; + public readonly formControlName = input.required(); - private unsubscribeSubject = new Subject(); + private readonly destroyRef = inject(DestroyRef); + private readonly input = viewChild.required(MatInput); public constructor( public readonly _elementRef: ElementRef, @@ -86,6 +86,19 @@ export class GfCurrencySelectorComponent this.controlType = 'currency-selector'; } + public get empty() { + return this.input().empty; + } + + public set value(value: string | null) { + this.control.setValue(value); + super.value = value; + } + + public focus() { + this.input().focus(); + } + public ngOnInit() { if (this.disabled) { this.control.disable(); @@ -94,17 +107,18 @@ export class GfCurrencySelectorComponent const formGroup = this.formGroupDirective.form; if (formGroup) { - const control = formGroup.get(this.formControlName); + const control = formGroup.get(this.formControlName()); if (control) { - this.value = this.currencies.find((value) => { - return value === control.value; - }); + this.value = + this.currencies().find((value) => { + return value === control.value; + }) ?? null; } } this.control.valueChanges - .pipe(takeUntil(this.unsubscribeSubject)) + .pipe(takeUntilDestroyed(this.destroyRef)) .subscribe(() => { if (super.value) { super.value = null; @@ -113,10 +127,10 @@ export class GfCurrencySelectorComponent this.control.valueChanges .pipe( - takeUntil(this.unsubscribeSubject), + takeUntilDestroyed(this.destroyRef), startWith(''), map((value) => { - return value ? this.filter(value) : this.currencies.slice(); + return value ? this.filter(value) : this.currencies().slice(); }) ) .subscribe((values) => { @@ -124,42 +138,22 @@ export class GfCurrencySelectorComponent }); } - public get empty() { - return this.input?.empty; - } - - public focus() { - this.input.focus(); - } - public ngDoCheck() { if (this.ngControl) { this.validateRequired(); - this.errorState = this.ngControl.invalid && this.ngControl.touched; + this.errorState = !!(this.ngControl.invalid && this.ngControl.touched); this.stateChanges.next(); } } - public onUpdateCurrency(event: MatAutocompleteSelectedEvent) { - super.value = event.option.value; - } - - public set value(value: string) { - this.control.setValue(value); - super.value = value; - } - - public ngOnDestroy() { - super.ngOnDestroy(); - - this.unsubscribeSubject.next(); - this.unsubscribeSubject.complete(); + public onUpdateCurrency({ option }: { option: MatOption }) { + super.value = option.value; } private filter(value: string) { - const filterValue = value?.toLowerCase(); + const filterValue = value.toLowerCase(); - return this.currencies.filter((currency) => { + return this.currencies().filter((currency) => { return currency.toLowerCase().startsWith(filterValue); }); } @@ -168,7 +162,7 @@ export class GfCurrencySelectorComponent const requiredCheck = super.required ? !super.value : false; if (requiredCheck) { - this.ngControl.control.setErrors({ invalidData: true }); + this.ngControl.control?.setErrors({ invalidData: true }); } } } From d4a0f48ca24ab925990853b59016b73fd2c1fa96 Mon Sep 17 00:00:00 2001 From: Thomas Kaul <4159106+dtslvr@users.noreply.github.com> Date: Fri, 27 Feb 2026 19:50:04 +0100 Subject: [PATCH 055/224] Task/remove unused OnDestroy hook in demo page component (#6383) * Remove unused OnDestroy hook --- .../client/src/app/pages/demo/demo-page.component.ts | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/apps/client/src/app/pages/demo/demo-page.component.ts b/apps/client/src/app/pages/demo/demo-page.component.ts index 5b94fd541..235805dcc 100644 --- a/apps/client/src/app/pages/demo/demo-page.component.ts +++ b/apps/client/src/app/pages/demo/demo-page.component.ts @@ -3,9 +3,8 @@ import { InfoItem } from '@ghostfolio/common/interfaces'; import { NotificationService } from '@ghostfolio/ui/notifications'; import { DataService } from '@ghostfolio/ui/services'; -import { Component, OnDestroy } from '@angular/core'; +import { Component } from '@angular/core'; import { Router } from '@angular/router'; -import { Subject } from 'rxjs'; @Component({ host: { class: 'page' }, @@ -13,11 +12,9 @@ import { Subject } from 'rxjs'; standalone: true, templateUrl: './demo-page.html' }) -export class GfDemoPageComponent implements OnDestroy { +export class GfDemoPageComponent { public info: InfoItem; - private unsubscribeSubject = new Subject(); - public constructor( private dataService: DataService, private notificationService: NotificationService, @@ -40,9 +37,4 @@ export class GfDemoPageComponent implements OnDestroy { this.router.navigate(['/']); } - - public ngOnDestroy() { - this.unsubscribeSubject.next(); - this.unsubscribeSubject.complete(); - } } From a7434c9ba7cc9b13aed168a51bebe827951e982d Mon Sep 17 00:00:00 2001 From: Thomas Kaul <4159106+dtslvr@users.noreply.github.com> Date: Sat, 28 Feb 2026 08:49:15 +0100 Subject: [PATCH 056/224] Task/remove deprecated fee ratio X-ray rule (#6364) * Remove deprecated static portfolio analysis rule: Fees (Fee Ratio) * Update changelog --- CHANGELOG.md | 4 + .../src/app/portfolio/portfolio.service.ts | 8 -- apps/api/src/app/user/user.service.ts | 8 -- .../fees/fee-ratio-initial-investment.ts | 104 ------------------ apps/client/src/app/pages/i18n/i18n-page.html | 9 -- .../x-ray-rules-settings.interface.ts | 1 - 6 files changed, 4 insertions(+), 130 deletions(-) delete mode 100644 apps/api/src/models/rules/fees/fee-ratio-initial-investment.ts diff --git a/CHANGELOG.md b/CHANGELOG.md index 6b1a1c978..0b25ff7e6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## Unreleased +### Changed + +- Removed the deprecated static portfolio analysis rule: _Fees_ (Fee Ratio) + ### Fixed - Fixed an exception by adding a fallback for missing market price values on the _X-ray_ page diff --git a/apps/api/src/app/portfolio/portfolio.service.ts b/apps/api/src/app/portfolio/portfolio.service.ts index b96f5ef70..17bd01ce4 100644 --- a/apps/api/src/app/portfolio/portfolio.service.ts +++ b/apps/api/src/app/portfolio/portfolio.service.ts @@ -13,7 +13,6 @@ import { CurrencyClusterRiskCurrentInvestment } from '@ghostfolio/api/models/rul import { EconomicMarketClusterRiskDevelopedMarkets } from '@ghostfolio/api/models/rules/economic-market-cluster-risk/developed-markets'; import { EconomicMarketClusterRiskEmergingMarkets } from '@ghostfolio/api/models/rules/economic-market-cluster-risk/emerging-markets'; import { EmergencyFundSetup } from '@ghostfolio/api/models/rules/emergency-fund/emergency-fund-setup'; -import { FeeRatioInitialInvestment } from '@ghostfolio/api/models/rules/fees/fee-ratio-initial-investment'; import { FeeRatioTotalInvestmentVolume } from '@ghostfolio/api/models/rules/fees/fee-ratio-total-investment-volume'; import { BuyingPower } from '@ghostfolio/api/models/rules/liquidity/buying-power'; import { RegionalMarketClusterRiskAsiaPacific } from '@ghostfolio/api/models/rules/regional-market-cluster-risk/asia-pacific'; @@ -1310,13 +1309,6 @@ export class PortfolioService { }), rules: await this.rulesService.evaluate( [ - new FeeRatioInitialInvestment( - this.exchangeRateDataService, - this.i18nService, - userSettings.language, - summary.committedFunds, - summary.fees - ), new FeeRatioTotalInvestmentVolume( this.exchangeRateDataService, this.i18nService, diff --git a/apps/api/src/app/user/user.service.ts b/apps/api/src/app/user/user.service.ts index 08328851d..97ab8a59f 100644 --- a/apps/api/src/app/user/user.service.ts +++ b/apps/api/src/app/user/user.service.ts @@ -12,7 +12,6 @@ import { CurrencyClusterRiskCurrentInvestment } from '@ghostfolio/api/models/rul import { EconomicMarketClusterRiskDevelopedMarkets } from '@ghostfolio/api/models/rules/economic-market-cluster-risk/developed-markets'; import { EconomicMarketClusterRiskEmergingMarkets } from '@ghostfolio/api/models/rules/economic-market-cluster-risk/emerging-markets'; import { EmergencyFundSetup } from '@ghostfolio/api/models/rules/emergency-fund/emergency-fund-setup'; -import { FeeRatioInitialInvestment } from '@ghostfolio/api/models/rules/fees/fee-ratio-initial-investment'; import { FeeRatioTotalInvestmentVolume } from '@ghostfolio/api/models/rules/fees/fee-ratio-total-investment-volume'; import { BuyingPower } from '@ghostfolio/api/models/rules/liquidity/buying-power'; import { RegionalMarketClusterRiskAsiaPacific } from '@ghostfolio/api/models/rules/regional-market-cluster-risk/asia-pacific'; @@ -377,13 +376,6 @@ export class UserService { undefined, undefined ).getSettings(user.settings.settings), - FeeRatioInitialInvestment: new FeeRatioInitialInvestment( - undefined, - undefined, - undefined, - undefined, - undefined - ).getSettings(user.settings.settings), FeeRatioTotalInvestmentVolume: new FeeRatioTotalInvestmentVolume( undefined, undefined, diff --git a/apps/api/src/models/rules/fees/fee-ratio-initial-investment.ts b/apps/api/src/models/rules/fees/fee-ratio-initial-investment.ts deleted file mode 100644 index 54c2decc9..000000000 --- a/apps/api/src/models/rules/fees/fee-ratio-initial-investment.ts +++ /dev/null @@ -1,104 +0,0 @@ -import { Rule } from '@ghostfolio/api/models/rule'; -import { ExchangeRateDataService } from '@ghostfolio/api/services/exchange-rate-data/exchange-rate-data.service'; -import { I18nService } from '@ghostfolio/api/services/i18n/i18n.service'; -import { RuleSettings, UserSettings } from '@ghostfolio/common/interfaces'; - -/** - * @deprecated This rule is deprecated in favor of FeeRatioTotalInvestmentVolume - */ -export class FeeRatioInitialInvestment extends Rule { - private fees: number; - private totalInvestment: number; - - public constructor( - protected exchangeRateDataService: ExchangeRateDataService, - private i18nService: I18nService, - languageCode: string, - totalInvestment: number, - fees: number - ) { - super(exchangeRateDataService, { - languageCode, - key: FeeRatioInitialInvestment.name - }); - - this.fees = fees; - this.totalInvestment = totalInvestment; - } - - public evaluate(ruleSettings: Settings) { - const feeRatio = this.totalInvestment - ? this.fees / this.totalInvestment - : 0; - - if (feeRatio > ruleSettings.thresholdMax) { - return { - evaluation: this.i18nService.getTranslation({ - id: 'rule.feeRatioInitialInvestment.false', - languageCode: this.getLanguageCode(), - placeholders: { - feeRatio: (ruleSettings.thresholdMax * 100).toFixed(2), - thresholdMax: (feeRatio * 100).toPrecision(3) - } - }), - value: false - }; - } - - return { - evaluation: this.i18nService.getTranslation({ - id: 'rule.feeRatioInitialInvestment.true', - languageCode: this.getLanguageCode(), - placeholders: { - feeRatio: (feeRatio * 100).toPrecision(3), - thresholdMax: (ruleSettings.thresholdMax * 100).toFixed(2) - } - }), - value: true - }; - } - - public getCategoryName() { - return this.i18nService.getTranslation({ - id: 'rule.fees.category', - languageCode: this.getLanguageCode() - }); - } - - public getConfiguration() { - return { - threshold: { - max: 0.1, - min: 0, - step: 0.0025, - unit: '%' - }, - thresholdMax: true - }; - } - - public getName() { - return this.i18nService.getTranslation({ - id: 'rule.feeRatioInitialInvestment', - languageCode: this.getLanguageCode() - }); - } - - public getSettings({ - baseCurrency, - locale, - xRayRules - }: UserSettings): Settings { - return { - baseCurrency, - locale, - isActive: xRayRules?.[this.getKey()]?.isActive ?? true, - thresholdMax: xRayRules?.[this.getKey()]?.thresholdMax ?? 0.01 - }; - } -} - -interface Settings extends RuleSettings { - baseCurrency: string; - thresholdMax: number; -} diff --git a/apps/client/src/app/pages/i18n/i18n-page.html b/apps/client/src/app/pages/i18n/i18n-page.html index a8797c07a..99ef3039e 100644 --- a/apps/client/src/app/pages/i18n/i18n-page.html +++ b/apps/client/src/app/pages/i18n/i18n-page.html @@ -149,15 +149,6 @@
  • An emergency fund has been set up
  • -
  • Fee Ratio (legacy)
  • -
  • - The fees do exceed ${thresholdMax}% of your initial investment - (${feeRatio}%) -
  • -
  • - The fees do not exceed ${thresholdMax}% of your initial - investment (${feeRatio}%) -
  • Fee Ratio
  • The fees do exceed ${thresholdMax}% of your total investment diff --git a/libs/common/src/lib/interfaces/x-ray-rules-settings.interface.ts b/libs/common/src/lib/interfaces/x-ray-rules-settings.interface.ts index 688d4f2a0..60a76d468 100644 --- a/libs/common/src/lib/interfaces/x-ray-rules-settings.interface.ts +++ b/libs/common/src/lib/interfaces/x-ray-rules-settings.interface.ts @@ -9,7 +9,6 @@ export interface XRayRulesSettings { EconomicMarketClusterRiskDevelopedMarkets?: RuleSettings; EconomicMarketClusterRiskEmergingMarkets?: RuleSettings; EmergencyFundSetup?: RuleSettings; - FeeRatioInitialInvestment?: RuleSettings; FeeRatioTotalInvestmentVolume?: RuleSettings; RegionalMarketClusterRiskAsiaPacific?: RuleSettings; RegionalMarketClusterRiskEmergingMarkets?: RuleSettings; From 3f14e5ad3a82cdb15651778b2e23a1fe30b4d4bd Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Sat, 28 Feb 2026 10:43:15 +0100 Subject: [PATCH 057/224] Task/update locales (#6356) * Update locales --- apps/client/src/locales/messages.ca.xlf | 180 ++++++++++-------------- apps/client/src/locales/messages.de.xlf | 180 ++++++++++-------------- apps/client/src/locales/messages.es.xlf | 180 ++++++++++-------------- apps/client/src/locales/messages.fr.xlf | 180 ++++++++++-------------- apps/client/src/locales/messages.it.xlf | 180 ++++++++++-------------- apps/client/src/locales/messages.ko.xlf | 180 ++++++++++-------------- apps/client/src/locales/messages.nl.xlf | 180 ++++++++++-------------- apps/client/src/locales/messages.pl.xlf | 180 ++++++++++-------------- apps/client/src/locales/messages.pt.xlf | 180 ++++++++++-------------- apps/client/src/locales/messages.tr.xlf | 180 ++++++++++-------------- apps/client/src/locales/messages.uk.xlf | 180 ++++++++++-------------- apps/client/src/locales/messages.xlf | 177 ++++++++++------------- apps/client/src/locales/messages.zh.xlf | 180 ++++++++++-------------- 13 files changed, 1014 insertions(+), 1323 deletions(-) diff --git a/apps/client/src/locales/messages.ca.xlf b/apps/client/src/locales/messages.ca.xlf index 585a3d779..d878a63bf 100644 --- a/apps/client/src/locales/messages.ca.xlf +++ b/apps/client/src/locales/messages.ca.xlf @@ -455,7 +455,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 139 + 135 libs/ui/src/lib/accounts-table/accounts-table.component.html @@ -511,7 +511,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 145 + 141 libs/ui/src/lib/accounts-table/accounts-table.component.html @@ -531,15 +531,15 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 205 + 201 apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 208 + 204 apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 211 + 207 libs/ui/src/lib/account-balances/account-balances.component.html @@ -711,7 +711,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 155 + 151 libs/ui/src/lib/i18n.ts @@ -823,7 +823,7 @@ Data apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 161 + 157 libs/ui/src/lib/account-balances/account-balances.component.html @@ -1179,7 +1179,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 275 + 271 @@ -1223,7 +1223,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 124 + 120 @@ -1719,7 +1719,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 189 + 185 libs/ui/src/lib/activities-table/activities-table.component.html @@ -2139,7 +2139,7 @@ Actius apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 230 + 233 @@ -2147,7 +2147,7 @@ Poder adquisitiu apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 245 + 248 @@ -2155,7 +2155,7 @@ Exclòs de l’anàlisi apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 271 + 274 @@ -2163,7 +2163,7 @@ Passius apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 299 + 302 apps/client/src/app/pages/features/features-page.html @@ -2175,7 +2175,7 @@ Valor net apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 321 + 324 @@ -2183,7 +2183,7 @@ Rendiment anualitzat apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 335 + 338 @@ -2343,7 +2343,7 @@ libs/ui/src/lib/assistant/assistant.component.ts - 363 + 362 @@ -2355,7 +2355,7 @@ libs/ui/src/lib/assistant/assistant.component.ts - 375 + 374 @@ -2367,7 +2367,7 @@ libs/ui/src/lib/assistant/assistant.component.ts - 385 + 384 @@ -2379,7 +2379,7 @@ libs/ui/src/lib/assistant/assistant.component.ts - 409 + 408 @@ -2399,7 +2399,7 @@ libs/ui/src/lib/assistant/assistant.component.ts - 415 + 414 @@ -3095,11 +3095,11 @@ apps/client/src/app/pages/admin/admin-page.component.ts - 48 + 45 apps/client/src/app/pages/resources/resources-page.component.ts - 30 + 29 libs/common/src/lib/routes/routes.ts @@ -3243,7 +3243,7 @@ Com que ja has iniciat sessió, no pots accedir al compte de demostració. apps/client/src/app/pages/demo/demo-page.component.ts - 35 + 32 @@ -3516,7 +3516,7 @@ apps/client/src/app/pages/resources/resources-page.component.ts - 40 + 39 libs/common/src/lib/routes/routes.ts @@ -3564,7 +3564,7 @@ Programari de gestió patrimonial de codi obert apps/client/src/app/pages/i18n/i18n-page.html - 246 + 237 @@ -4104,7 +4104,7 @@ Actualitzar el saldo d’efectiu apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 112 + 108 @@ -4112,7 +4112,7 @@ Preu unitari apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 214 + 210 libs/ui/src/lib/activities-table/activities-table.component.html @@ -4484,7 +4484,7 @@ apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 369 + 372 apps/client/src/app/pages/features/features-page.html @@ -4492,7 +4492,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 202 + 198 apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts @@ -5345,7 +5345,7 @@ Realment voleu eliminar el saldo d’aquest compte? libs/ui/src/lib/account-balances/account-balances.component.ts - 120 + 113 @@ -5425,7 +5425,7 @@ Setmana fins avui libs/ui/src/lib/assistant/assistant.component.ts - 367 + 366 @@ -5437,7 +5437,7 @@ libs/ui/src/lib/assistant/assistant.component.ts - 367 + 366 @@ -5445,7 +5445,7 @@ Mes fins a la data libs/ui/src/lib/assistant/assistant.component.ts - 371 + 370 @@ -5457,7 +5457,7 @@ libs/ui/src/lib/assistant/assistant.component.ts - 371 + 370 @@ -5465,7 +5465,7 @@ Any fins a la data libs/ui/src/lib/assistant/assistant.component.ts - 375 + 374 @@ -5485,7 +5485,7 @@ libs/ui/src/lib/assistant/assistant.component.ts - 385 + 384 @@ -5497,7 +5497,7 @@ libs/ui/src/lib/assistant/assistant.component.ts - 409 + 408 @@ -5645,7 +5645,7 @@ Dipòsit libs/ui/src/lib/fire-calculator/fire-calculator.component.ts - 377 + 385 @@ -5657,11 +5657,11 @@ apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 356 + 359 libs/ui/src/lib/fire-calculator/fire-calculator.component.ts - 387 + 395 libs/ui/src/lib/i18n.ts @@ -5673,7 +5673,7 @@ Estalvi libs/ui/src/lib/fire-calculator/fire-calculator.component.ts - 397 + 405 @@ -5753,7 +5753,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 290 + 286 libs/ui/src/lib/i18n.ts @@ -5785,7 +5785,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 309 + 305 libs/ui/src/lib/i18n.ts @@ -6049,7 +6049,7 @@ Comissió apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 262 + 258 libs/ui/src/lib/activities-table/activities-table.component.html @@ -6093,7 +6093,7 @@ Efectiu apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 216 + 219 libs/ui/src/lib/i18n.ts @@ -6757,7 +6757,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 345 + 341 apps/client/src/app/pages/register/user-account-registration-dialog/user-account-registration-dialog.html @@ -6813,7 +6813,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 347 + 343 libs/ui/src/lib/i18n.ts @@ -7117,7 +7117,7 @@ apps/client/src/app/pages/resources/resources-page.component.ts - 45 + 44 libs/common/src/lib/routes/routes.ts @@ -7133,7 +7133,7 @@ apps/client/src/app/pages/resources/resources-page.component.ts - 34 + 33 libs/common/src/lib/routes/routes.ts @@ -7339,7 +7339,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 356 + 352 libs/ui/src/lib/historical-market-data-editor/historical-market-data-editor-dialog/historical-market-data-editor-dialog.html @@ -7643,7 +7643,7 @@ Find account, holding or page... libs/ui/src/lib/assistant/assistant.component.ts - 151 + 115 @@ -7888,36 +7888,12 @@ 150 - - Fee Ratio (legacy) - Fee Ratio (legacy) - - apps/client/src/app/pages/i18n/i18n-page.html - 152 - - - - The fees do exceed ${thresholdMax}% of your initial investment (${feeRatio}%) - The fees do exceed ${thresholdMax}% of your initial investment (${feeRatio}%) - - apps/client/src/app/pages/i18n/i18n-page.html - 154 - - - - The fees do not exceed ${thresholdMax}% of your initial investment (${feeRatio}%) - The fees do not exceed ${thresholdMax}% of your initial investment (${feeRatio}%) - - apps/client/src/app/pages/i18n/i18n-page.html - 158 - - Fee Ratio Fee Ratio apps/client/src/app/pages/i18n/i18n-page.html - 161 + 152 @@ -7925,7 +7901,7 @@ The fees do exceed ${thresholdMax}% of your total investment volume (${feeRatio}%) apps/client/src/app/pages/i18n/i18n-page.html - 163 + 154 @@ -7933,7 +7909,7 @@ The fees do not exceed ${thresholdMax}% of your total investment volume (${feeRatio}%) apps/client/src/app/pages/i18n/i18n-page.html - 167 + 158 @@ -8103,7 +8079,7 @@ apps/client/src/app/pages/admin/admin-page.component.ts - 56 + 53 @@ -8392,7 +8368,7 @@ Fees apps/client/src/app/pages/i18n/i18n-page.html - 170 + 161 @@ -8440,7 +8416,7 @@ Regional Market Cluster Risks apps/client/src/app/pages/i18n/i18n-page.html - 172 + 163 @@ -8536,7 +8512,7 @@ Asia-Pacific apps/client/src/app/pages/i18n/i18n-page.html - 174 + 165 @@ -8544,7 +8520,7 @@ The Asia-Pacific market contribution of your current investment (${valueRatio}%) exceeds ${thresholdMax}% apps/client/src/app/pages/i18n/i18n-page.html - 176 + 167 @@ -8552,7 +8528,7 @@ The Asia-Pacific market contribution of your current investment (${valueRatio}%) is below ${thresholdMin}% apps/client/src/app/pages/i18n/i18n-page.html - 180 + 171 @@ -8560,7 +8536,7 @@ The Asia-Pacific market contribution of your current investment (${valueRatio}%) is within the range of ${thresholdMin}% and ${thresholdMax}% apps/client/src/app/pages/i18n/i18n-page.html - 184 + 175 @@ -8568,7 +8544,7 @@ Emerging Markets apps/client/src/app/pages/i18n/i18n-page.html - 189 + 180 @@ -8576,7 +8552,7 @@ The Emerging Markets contribution of your current investment (${valueRatio}%) exceeds ${thresholdMax}% apps/client/src/app/pages/i18n/i18n-page.html - 192 + 183 @@ -8584,7 +8560,7 @@ The Emerging Markets contribution of your current investment (${valueRatio}%) is below ${thresholdMin}% apps/client/src/app/pages/i18n/i18n-page.html - 196 + 187 @@ -8592,7 +8568,7 @@ The Emerging Markets contribution of your current investment (${valueRatio}%) is within the range of ${thresholdMin}% and ${thresholdMax}% apps/client/src/app/pages/i18n/i18n-page.html - 200 + 191 @@ -8600,7 +8576,7 @@ Europe apps/client/src/app/pages/i18n/i18n-page.html - 204 + 195 @@ -8608,7 +8584,7 @@ The Europe market contribution of your current investment (${valueRatio}%) exceeds ${thresholdMax}% apps/client/src/app/pages/i18n/i18n-page.html - 206 + 197 @@ -8616,7 +8592,7 @@ The Europe market contribution of your current investment (${valueRatio}%) is below ${thresholdMin}% apps/client/src/app/pages/i18n/i18n-page.html - 210 + 201 @@ -8624,7 +8600,7 @@ The Europe market contribution of your current investment (${valueRatio}%) is within the range of ${thresholdMin}% and ${thresholdMax}% apps/client/src/app/pages/i18n/i18n-page.html - 214 + 205 @@ -8632,7 +8608,7 @@ Japan apps/client/src/app/pages/i18n/i18n-page.html - 218 + 209 @@ -8640,7 +8616,7 @@ The Japan market contribution of your current investment (${valueRatio}%) exceeds ${thresholdMax}% apps/client/src/app/pages/i18n/i18n-page.html - 220 + 211 @@ -8648,7 +8624,7 @@ The Japan market contribution of your current investment (${valueRatio}%) is below ${thresholdMin}% apps/client/src/app/pages/i18n/i18n-page.html - 224 + 215 @@ -8656,7 +8632,7 @@ The Japan market contribution of your current investment (${valueRatio}%) is within the range of ${thresholdMin}% and ${thresholdMax}% apps/client/src/app/pages/i18n/i18n-page.html - 228 + 219 @@ -8664,7 +8640,7 @@ North America apps/client/src/app/pages/i18n/i18n-page.html - 232 + 223 @@ -8672,7 +8648,7 @@ The North America market contribution of your current investment (${valueRatio}%) exceeds ${thresholdMax}% apps/client/src/app/pages/i18n/i18n-page.html - 234 + 225 @@ -8680,7 +8656,7 @@ The North America market contribution of your current investment (${valueRatio}%) is below ${thresholdMin}% apps/client/src/app/pages/i18n/i18n-page.html - 238 + 229 @@ -8688,7 +8664,7 @@ The North America market contribution of your current investment (${valueRatio}%) is within the range of ${thresholdMin}% and ${thresholdMax}% apps/client/src/app/pages/i18n/i18n-page.html - 242 + 233 diff --git a/apps/client/src/locales/messages.de.xlf b/apps/client/src/locales/messages.de.xlf index 2ca3a95bf..54c3f7de8 100644 --- a/apps/client/src/locales/messages.de.xlf +++ b/apps/client/src/locales/messages.de.xlf @@ -134,7 +134,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 139 + 135 libs/ui/src/lib/accounts-table/accounts-table.component.html @@ -178,15 +178,15 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 205 + 201 apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 208 + 204 apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 211 + 207 libs/ui/src/lib/account-balances/account-balances.component.html @@ -326,7 +326,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 155 + 151 libs/ui/src/lib/i18n.ts @@ -438,7 +438,7 @@ Datum apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 161 + 157 libs/ui/src/lib/account-balances/account-balances.component.html @@ -950,7 +950,7 @@ Kaufkraft apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 245 + 248 @@ -958,7 +958,7 @@ Gesamtvermögen apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 321 + 324 @@ -966,7 +966,7 @@ Performance pro Jahr apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 335 + 338 @@ -1074,7 +1074,7 @@ libs/ui/src/lib/assistant/assistant.component.ts - 363 + 362 @@ -1086,7 +1086,7 @@ libs/ui/src/lib/assistant/assistant.component.ts - 375 + 374 @@ -1098,7 +1098,7 @@ libs/ui/src/lib/assistant/assistant.component.ts - 385 + 384 @@ -1110,7 +1110,7 @@ libs/ui/src/lib/assistant/assistant.component.ts - 409 + 408 @@ -1130,7 +1130,7 @@ libs/ui/src/lib/assistant/assistant.component.ts - 415 + 414 @@ -1450,7 +1450,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 145 + 141 libs/ui/src/lib/accounts-table/accounts-table.component.html @@ -1630,7 +1630,7 @@ Da du bereits eingeloggt bist, kannst du nicht auf die Live Demo zugreifen. apps/client/src/app/pages/demo/demo-page.component.ts - 35 + 32 @@ -1694,11 +1694,11 @@ apps/client/src/app/pages/admin/admin-page.component.ts - 48 + 45 apps/client/src/app/pages/resources/resources-page.component.ts - 30 + 29 libs/common/src/lib/routes/routes.ts @@ -1738,7 +1738,7 @@ apps/client/src/app/pages/resources/resources-page.component.ts - 40 + 39 libs/common/src/lib/routes/routes.ts @@ -1978,7 +1978,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 124 + 120 @@ -1990,7 +1990,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 189 + 185 libs/ui/src/lib/activities-table/activities-table.component.html @@ -2006,7 +2006,7 @@ Stückpreis apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 214 + 210 libs/ui/src/lib/activities-table/activities-table.component.html @@ -2026,7 +2026,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 275 + 271 @@ -2546,7 +2546,7 @@ Einlage libs/ui/src/lib/fire-calculator/fire-calculator.component.ts - 377 + 385 @@ -2558,11 +2558,11 @@ apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 356 + 359 libs/ui/src/lib/fire-calculator/fire-calculator.component.ts - 387 + 395 libs/ui/src/lib/i18n.ts @@ -2574,7 +2574,7 @@ Ersparnisse libs/ui/src/lib/fire-calculator/fire-calculator.component.ts - 397 + 405 @@ -2706,7 +2706,7 @@ Von der Analyse ausgenommen apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 271 + 274 @@ -2810,7 +2810,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 290 + 286 libs/ui/src/lib/i18n.ts @@ -2866,7 +2866,7 @@ Bargeld apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 216 + 219 libs/ui/src/lib/i18n.ts @@ -3158,7 +3158,7 @@ apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 369 + 372 apps/client/src/app/pages/features/features-page.html @@ -3166,7 +3166,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 202 + 198 apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts @@ -3198,7 +3198,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 309 + 305 libs/ui/src/lib/i18n.ts @@ -3926,7 +3926,7 @@ Cash-Bestand aktualisieren apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 112 + 108 @@ -4106,7 +4106,7 @@ Verbindlichkeiten apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 299 + 302 apps/client/src/app/pages/features/features-page.html @@ -4522,7 +4522,7 @@ Anlagevermögen apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 230 + 233 @@ -5468,7 +5468,7 @@ Gebühr apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 262 + 258 libs/ui/src/lib/activities-table/activities-table.component.html @@ -5676,7 +5676,7 @@ Open Source Software für die Vermögensverwaltung apps/client/src/app/pages/i18n/i18n-page.html - 246 + 237 @@ -5776,7 +5776,7 @@ Möchtest du diesen Cash-Bestand wirklich löschen? libs/ui/src/lib/account-balances/account-balances.component.ts - 120 + 113 @@ -5952,7 +5952,7 @@ Seit Wochenbeginn libs/ui/src/lib/assistant/assistant.component.ts - 367 + 366 @@ -5964,7 +5964,7 @@ libs/ui/src/lib/assistant/assistant.component.ts - 367 + 366 @@ -5972,7 +5972,7 @@ Seit Monatsbeginn libs/ui/src/lib/assistant/assistant.component.ts - 371 + 370 @@ -5984,7 +5984,7 @@ libs/ui/src/lib/assistant/assistant.component.ts - 371 + 370 @@ -5992,7 +5992,7 @@ Seit Jahresbeginn libs/ui/src/lib/assistant/assistant.component.ts - 375 + 374 @@ -6040,7 +6040,7 @@ libs/ui/src/lib/assistant/assistant.component.ts - 385 + 384 @@ -6052,7 +6052,7 @@ libs/ui/src/lib/assistant/assistant.component.ts - 409 + 408 @@ -6781,7 +6781,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 345 + 341 apps/client/src/app/pages/register/user-account-registration-dialog/user-account-registration-dialog.html @@ -6837,7 +6837,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 347 + 343 libs/ui/src/lib/i18n.ts @@ -7141,7 +7141,7 @@ apps/client/src/app/pages/resources/resources-page.component.ts - 45 + 44 libs/common/src/lib/routes/routes.ts @@ -7157,7 +7157,7 @@ apps/client/src/app/pages/resources/resources-page.component.ts - 34 + 33 libs/common/src/lib/routes/routes.ts @@ -7363,7 +7363,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 356 + 352 libs/ui/src/lib/historical-market-data-editor/historical-market-data-editor-dialog/historical-market-data-editor-dialog.html @@ -7667,7 +7667,7 @@ Konto, Position oder Seite finden... libs/ui/src/lib/assistant/assistant.component.ts - 151 + 115 @@ -7888,36 +7888,12 @@ 150 - - Fee Ratio (legacy) - Gebührenverhältnis (veraltet) - - apps/client/src/app/pages/i18n/i18n-page.html - 152 - - - - The fees do exceed ${thresholdMax}% of your initial investment (${feeRatio}%) - Die Gebühren übersteigen ${thresholdMax}% deiner ursprünglichen Investition (${feeRatio}%) - - apps/client/src/app/pages/i18n/i18n-page.html - 154 - - - - The fees do not exceed ${thresholdMax}% of your initial investment (${feeRatio}%) - Die Gebühren übersteigen ${thresholdMax}% deiner ursprünglichen Investition (${feeRatio}%) nicht - - apps/client/src/app/pages/i18n/i18n-page.html - 158 - - Fee Ratio Gebührenverhältnis apps/client/src/app/pages/i18n/i18n-page.html - 161 + 152 @@ -7925,7 +7901,7 @@ Die Gebühren übersteigen ${thresholdMax}% deines gesamten Investitionsvolumens (${feeRatio}%) apps/client/src/app/pages/i18n/i18n-page.html - 163 + 154 @@ -7933,7 +7909,7 @@ Die Gebühren übersteigen ${thresholdMax}% deines gesamten Investitionsvolumens (${feeRatio}%) nicht apps/client/src/app/pages/i18n/i18n-page.html - 167 + 158 @@ -8103,7 +8079,7 @@ apps/client/src/app/pages/admin/admin-page.component.ts - 56 + 53 @@ -8392,7 +8368,7 @@ Gebühren apps/client/src/app/pages/i18n/i18n-page.html - 170 + 161 @@ -8440,7 +8416,7 @@ Regionale Marktklumpenrisiken apps/client/src/app/pages/i18n/i18n-page.html - 172 + 163 @@ -8536,7 +8512,7 @@ Asien-Pazifik apps/client/src/app/pages/i18n/i18n-page.html - 174 + 165 @@ -8544,7 +8520,7 @@ Der Anteil des Asien-Pazifik-Marktes deiner aktuellen Investition (${valueRatio}%) übersteigt ${thresholdMax}% apps/client/src/app/pages/i18n/i18n-page.html - 176 + 167 @@ -8552,7 +8528,7 @@ Der Anteil des Asien-Pazifik-Marktes deiner aktuellen Investition (${valueRatio}%) liegt unter ${thresholdMin}% apps/client/src/app/pages/i18n/i18n-page.html - 180 + 171 @@ -8560,7 +8536,7 @@ Der Anteil des Asien-Pazifik-Marktes deiner aktuellen Investition (${valueRatio}%) liegt im Bereich zwischen ${thresholdMin}% und ${thresholdMax}% apps/client/src/app/pages/i18n/i18n-page.html - 184 + 175 @@ -8568,7 +8544,7 @@ Schwellenländer apps/client/src/app/pages/i18n/i18n-page.html - 189 + 180 @@ -8576,7 +8552,7 @@ Der Anteil der Schwellenländer deiner aktuellen Investition (${valueRatio}%) übersteigt ${thresholdMax}% apps/client/src/app/pages/i18n/i18n-page.html - 192 + 183 @@ -8584,7 +8560,7 @@ Der Anteil der Schwellenländer deiner aktuellen Investition (${valueRatio}%) liegt unter ${thresholdMin}% apps/client/src/app/pages/i18n/i18n-page.html - 196 + 187 @@ -8592,7 +8568,7 @@ Der Anteil der Schwellenländer deiner aktuellen Investition (${valueRatio}%) liegt im Bereich zwischen ${thresholdMin}% und ${thresholdMax}% apps/client/src/app/pages/i18n/i18n-page.html - 200 + 191 @@ -8600,7 +8576,7 @@ Europa apps/client/src/app/pages/i18n/i18n-page.html - 204 + 195 @@ -8608,7 +8584,7 @@ Der Anteil des europäischen Marktes deiner aktuellen Investition (${valueRatio}%) übersteigt ${thresholdMax}% apps/client/src/app/pages/i18n/i18n-page.html - 206 + 197 @@ -8616,7 +8592,7 @@ Der Anteil des europäischen Marktes deiner aktuellen Investition (${valueRatio}%) liegt unter ${thresholdMin}% apps/client/src/app/pages/i18n/i18n-page.html - 210 + 201 @@ -8624,7 +8600,7 @@ Der Anteil des europäischen Marktes deiner aktuellen Investition (${valueRatio}%) liegt im Bereich zwischen ${thresholdMin}% und ${thresholdMax}% apps/client/src/app/pages/i18n/i18n-page.html - 214 + 205 @@ -8632,7 +8608,7 @@ Japan apps/client/src/app/pages/i18n/i18n-page.html - 218 + 209 @@ -8640,7 +8616,7 @@ Der Anteil des japanischen Marktes deiner aktuellen Investition (${valueRatio}%) übersteigt ${thresholdMax}% apps/client/src/app/pages/i18n/i18n-page.html - 220 + 211 @@ -8648,7 +8624,7 @@ Der Anteil des japanischen Marktes deiner aktuellen Investition (${valueRatio}%) liegt unter ${thresholdMin}% apps/client/src/app/pages/i18n/i18n-page.html - 224 + 215 @@ -8656,7 +8632,7 @@ Der Anteil des japanischen Marktes deiner aktuellen Investition (${valueRatio}%) liegt im Bereich zwischen ${thresholdMin}% und ${thresholdMax}% apps/client/src/app/pages/i18n/i18n-page.html - 228 + 219 @@ -8664,7 +8640,7 @@ Nordamerika apps/client/src/app/pages/i18n/i18n-page.html - 232 + 223 @@ -8672,7 +8648,7 @@ Der Anteil des nordamerikanischen Marktes deiner aktuellen Investition (${valueRatio}%) übersteigt ${thresholdMax}% apps/client/src/app/pages/i18n/i18n-page.html - 234 + 225 @@ -8680,7 +8656,7 @@ Der Anteil des nordamerikanischen Marktes deiner aktuellen Investition (${valueRatio}%) liegt unter ${thresholdMin}% apps/client/src/app/pages/i18n/i18n-page.html - 238 + 229 @@ -8688,7 +8664,7 @@ Der Anteil des nordamerikanischen Marktes deiner aktuellen Investition (${valueRatio}%) liegt im Bereich zwischen ${thresholdMin}% und ${thresholdMax}% apps/client/src/app/pages/i18n/i18n-page.html - 242 + 233 diff --git a/apps/client/src/locales/messages.es.xlf b/apps/client/src/locales/messages.es.xlf index ceb7d5b06..74e0810c1 100644 --- a/apps/client/src/locales/messages.es.xlf +++ b/apps/client/src/locales/messages.es.xlf @@ -135,7 +135,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 139 + 135 libs/ui/src/lib/accounts-table/accounts-table.component.html @@ -179,15 +179,15 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 205 + 201 apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 208 + 204 apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 211 + 207 libs/ui/src/lib/account-balances/account-balances.component.html @@ -327,7 +327,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 155 + 151 libs/ui/src/lib/i18n.ts @@ -439,7 +439,7 @@ Fecha apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 161 + 157 libs/ui/src/lib/account-balances/account-balances.component.html @@ -935,7 +935,7 @@ Capacidad de compra apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 245 + 248 @@ -943,7 +943,7 @@ Patrimonio neto apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 321 + 324 @@ -951,7 +951,7 @@ Rendimiento anualizado apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 335 + 338 @@ -1059,7 +1059,7 @@ libs/ui/src/lib/assistant/assistant.component.ts - 363 + 362 @@ -1071,7 +1071,7 @@ libs/ui/src/lib/assistant/assistant.component.ts - 375 + 374 @@ -1083,7 +1083,7 @@ libs/ui/src/lib/assistant/assistant.component.ts - 385 + 384 @@ -1095,7 +1095,7 @@ libs/ui/src/lib/assistant/assistant.component.ts - 409 + 408 @@ -1115,7 +1115,7 @@ libs/ui/src/lib/assistant/assistant.component.ts - 415 + 414 @@ -1435,7 +1435,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 145 + 141 libs/ui/src/lib/accounts-table/accounts-table.component.html @@ -1615,7 +1615,7 @@ Como estás conectado, no puedes acceder a la cuenta de demostración. apps/client/src/app/pages/demo/demo-page.component.ts - 35 + 32 @@ -1679,11 +1679,11 @@ apps/client/src/app/pages/admin/admin-page.component.ts - 48 + 45 apps/client/src/app/pages/resources/resources-page.component.ts - 30 + 29 libs/common/src/lib/routes/routes.ts @@ -1723,7 +1723,7 @@ apps/client/src/app/pages/resources/resources-page.component.ts - 40 + 39 libs/common/src/lib/routes/routes.ts @@ -1963,7 +1963,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 124 + 120 @@ -1975,7 +1975,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 189 + 185 libs/ui/src/lib/activities-table/activities-table.component.html @@ -1991,7 +1991,7 @@ Precio unitario apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 214 + 210 libs/ui/src/lib/activities-table/activities-table.component.html @@ -2011,7 +2011,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 275 + 271 @@ -2515,7 +2515,7 @@ Ahorros libs/ui/src/lib/fire-calculator/fire-calculator.component.ts - 397 + 405 @@ -2527,11 +2527,11 @@ apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 356 + 359 libs/ui/src/lib/fire-calculator/fire-calculator.component.ts - 387 + 395 libs/ui/src/lib/i18n.ts @@ -2551,7 +2551,7 @@ Depósito libs/ui/src/lib/fire-calculator/fire-calculator.component.ts - 377 + 385 @@ -2691,7 +2691,7 @@ Excluido del análisis apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 271 + 274 @@ -2795,7 +2795,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 290 + 286 libs/ui/src/lib/i18n.ts @@ -2851,7 +2851,7 @@ Efectivo apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 216 + 219 libs/ui/src/lib/i18n.ts @@ -3135,7 +3135,7 @@ apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 369 + 372 apps/client/src/app/pages/features/features-page.html @@ -3143,7 +3143,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 202 + 198 apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts @@ -3183,7 +3183,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 309 + 305 libs/ui/src/lib/i18n.ts @@ -3903,7 +3903,7 @@ Actualizar saldo en efectivo apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 112 + 108 @@ -4083,7 +4083,7 @@ Pasivos apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 299 + 302 apps/client/src/app/pages/features/features-page.html @@ -4499,7 +4499,7 @@ Activos apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 230 + 233 @@ -5445,7 +5445,7 @@ Tarifa apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 262 + 258 libs/ui/src/lib/activities-table/activities-table.component.html @@ -5653,7 +5653,7 @@ Software de gestión de patrimonio de código abierto apps/client/src/app/pages/i18n/i18n-page.html - 246 + 237 @@ -5753,7 +5753,7 @@ ¿Realmente desea eliminar el saldo de esta cuenta? libs/ui/src/lib/account-balances/account-balances.component.ts - 120 + 113 @@ -5929,7 +5929,7 @@ Semana hasta la fecha libs/ui/src/lib/assistant/assistant.component.ts - 367 + 366 @@ -5941,7 +5941,7 @@ libs/ui/src/lib/assistant/assistant.component.ts - 367 + 366 @@ -5949,7 +5949,7 @@ Mes hasta la fecha libs/ui/src/lib/assistant/assistant.component.ts - 371 + 370 @@ -5961,7 +5961,7 @@ libs/ui/src/lib/assistant/assistant.component.ts - 371 + 370 @@ -5969,7 +5969,7 @@ El año hasta la fecha libs/ui/src/lib/assistant/assistant.component.ts - 375 + 374 @@ -6017,7 +6017,7 @@ libs/ui/src/lib/assistant/assistant.component.ts - 385 + 384 @@ -6029,7 +6029,7 @@ libs/ui/src/lib/assistant/assistant.component.ts - 409 + 408 @@ -6758,7 +6758,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 345 + 341 apps/client/src/app/pages/register/user-account-registration-dialog/user-account-registration-dialog.html @@ -6814,7 +6814,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 347 + 343 libs/ui/src/lib/i18n.ts @@ -7118,7 +7118,7 @@ apps/client/src/app/pages/resources/resources-page.component.ts - 45 + 44 libs/common/src/lib/routes/routes.ts @@ -7134,7 +7134,7 @@ apps/client/src/app/pages/resources/resources-page.component.ts - 34 + 33 libs/common/src/lib/routes/routes.ts @@ -7340,7 +7340,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 356 + 352 libs/ui/src/lib/historical-market-data-editor/historical-market-data-editor-dialog/historical-market-data-editor-dialog.html @@ -7644,7 +7644,7 @@ Buscar cuenta, posición o página... libs/ui/src/lib/assistant/assistant.component.ts - 151 + 115 @@ -7889,36 +7889,12 @@ 150 - - Fee Ratio (legacy) - Relación de tarifas (heredado) - - apps/client/src/app/pages/i18n/i18n-page.html - 152 - - - - The fees do exceed ${thresholdMax}% of your initial investment (${feeRatio}%) - Las tarifas superan el ${thresholdMax}% de su inversión inicial (${feeRatio}%) - - apps/client/src/app/pages/i18n/i18n-page.html - 154 - - - - The fees do not exceed ${thresholdMax}% of your initial investment (${feeRatio}%) - Las tarifas no superan el ${thresholdMax}% de su inversión inicial (${feeRatio}%) - - apps/client/src/app/pages/i18n/i18n-page.html - 158 - - Fee Ratio Relación de tarifas apps/client/src/app/pages/i18n/i18n-page.html - 161 + 152 @@ -7926,7 +7902,7 @@ Las tarifas superan el ${thresholdMax}% de su volumen total de inversión (${feeRatio}%) apps/client/src/app/pages/i18n/i18n-page.html - 163 + 154 @@ -7934,7 +7910,7 @@ Las tarifas no superan el ${thresholdMax}% de su volumen total de inversión (${feeRatio}%) apps/client/src/app/pages/i18n/i18n-page.html - 167 + 158 @@ -8104,7 +8080,7 @@ apps/client/src/app/pages/admin/admin-page.component.ts - 56 + 53 @@ -8393,7 +8369,7 @@ Comisiones apps/client/src/app/pages/i18n/i18n-page.html - 170 + 161 @@ -8441,7 +8417,7 @@ Riesgos de los grupos de mercados regionales apps/client/src/app/pages/i18n/i18n-page.html - 172 + 163 @@ -8537,7 +8513,7 @@ Asia-Pacífico apps/client/src/app/pages/i18n/i18n-page.html - 174 + 165 @@ -8545,7 +8521,7 @@ La contribución al mercado de Asia-Pacífico de tu inversión actual (${valueRatio}%) supera el ${thresholdMax}% apps/client/src/app/pages/i18n/i18n-page.html - 176 + 167 @@ -8553,7 +8529,7 @@ La contribución al mercado de Asia-Pacífico de tu inversión actual (${valueRatio}%) es inferior al ${thresholdMin}% apps/client/src/app/pages/i18n/i18n-page.html - 180 + 171 @@ -8561,7 +8537,7 @@ La contribución al mercado de Asia-Pacífico de tu inversión actual (${valueRatio}%) está dentro del rango de ${thresholdMin}% y ${thresholdMax}% apps/client/src/app/pages/i18n/i18n-page.html - 184 + 175 @@ -8569,7 +8545,7 @@ Mercados emergentes apps/client/src/app/pages/i18n/i18n-page.html - 189 + 180 @@ -8577,7 +8553,7 @@ La contribución a los mercados emergentes de tu inversión actual (${valueRatio}%) supera el ${thresholdMax}% apps/client/src/app/pages/i18n/i18n-page.html - 192 + 183 @@ -8585,7 +8561,7 @@ La contribución a los mercados emergentes de tu inversión actual (${valueRatio}%) es inferior al ${thresholdMin}% apps/client/src/app/pages/i18n/i18n-page.html - 196 + 187 @@ -8593,7 +8569,7 @@ La contribución a los mercados emergentes de tu inversión actual (${valueRatio}%) está dentro del rango de ${thresholdMin}% y ${thresholdMax}% apps/client/src/app/pages/i18n/i18n-page.html - 200 + 191 @@ -8601,7 +8577,7 @@ Europa apps/client/src/app/pages/i18n/i18n-page.html - 204 + 195 @@ -8609,7 +8585,7 @@ La contribución al mercado europeo de tu inversión actual (${valueRatio}%) supera el ${thresholdMax}% apps/client/src/app/pages/i18n/i18n-page.html - 206 + 197 @@ -8617,7 +8593,7 @@ La contribución al mercado europeo de tu inversión actual (${valueRatio}%) es inferior al ${thresholdMin}% apps/client/src/app/pages/i18n/i18n-page.html - 210 + 201 @@ -8625,7 +8601,7 @@ La contribución al mercado europeo de tu inversión actual (${valueRatio}%) está dentro del rango de ${thresholdMin}% y ${thresholdMax}% apps/client/src/app/pages/i18n/i18n-page.html - 214 + 205 @@ -8633,7 +8609,7 @@ Japón apps/client/src/app/pages/i18n/i18n-page.html - 218 + 209 @@ -8641,7 +8617,7 @@ La contribución al mercado japonés de su inversión actual (${valueRatio}%) supera el ${thresholdMax}% apps/client/src/app/pages/i18n/i18n-page.html - 220 + 211 @@ -8649,7 +8625,7 @@ La contribución al mercado japonés de su inversión actual (${valueRatio}%) es inferior a ${thresholdMin}% apps/client/src/app/pages/i18n/i18n-page.html - 224 + 215 @@ -8657,7 +8633,7 @@ La contribución al mercado japonés de su inversión actual (${valueRatio}%) está dentro del rango de ${thresholdMin}% y ${thresholdMax}% apps/client/src/app/pages/i18n/i18n-page.html - 228 + 219 @@ -8665,7 +8641,7 @@ Norteamérica apps/client/src/app/pages/i18n/i18n-page.html - 232 + 223 @@ -8673,7 +8649,7 @@ La contribución del mercado de América del Norte de su inversión actual (${valueRatio}%) supera el ${thresholdMax}% apps/client/src/app/pages/i18n/i18n-page.html - 234 + 225 @@ -8681,7 +8657,7 @@ La contribución al mercado de América del Norte de su inversión actual (${valueRatio}%) es inferior a ${thresholdMin}% apps/client/src/app/pages/i18n/i18n-page.html - 238 + 229 @@ -8689,7 +8665,7 @@ La contribución al mercado de América del Norte de su inversión actual (${valueRatio}%) está dentro del rango de ${thresholdMin}% y ${thresholdMax}% apps/client/src/app/pages/i18n/i18n-page.html - 242 + 233 diff --git a/apps/client/src/locales/messages.fr.xlf b/apps/client/src/locales/messages.fr.xlf index f3a8d4942..f343cb2ad 100644 --- a/apps/client/src/locales/messages.fr.xlf +++ b/apps/client/src/locales/messages.fr.xlf @@ -142,7 +142,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 139 + 135 libs/ui/src/lib/accounts-table/accounts-table.component.html @@ -198,7 +198,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 145 + 141 libs/ui/src/lib/accounts-table/accounts-table.component.html @@ -234,15 +234,15 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 205 + 201 apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 208 + 204 apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 211 + 207 libs/ui/src/lib/account-balances/account-balances.component.html @@ -374,7 +374,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 155 + 151 libs/ui/src/lib/i18n.ts @@ -494,7 +494,7 @@ Date apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 161 + 157 libs/ui/src/lib/account-balances/account-balances.component.html @@ -698,7 +698,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 275 + 271 @@ -1218,7 +1218,7 @@ Pouvoir d’Achat apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 245 + 248 @@ -1226,7 +1226,7 @@ Exclus de l’Analyse apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 271 + 274 @@ -1234,7 +1234,7 @@ Fortune apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 321 + 324 @@ -1242,7 +1242,7 @@ Performance annualisée apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 335 + 338 @@ -1278,7 +1278,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 189 + 185 libs/ui/src/lib/activities-table/activities-table.component.html @@ -1306,7 +1306,7 @@ libs/ui/src/lib/assistant/assistant.component.ts - 363 + 362 @@ -1318,7 +1318,7 @@ libs/ui/src/lib/assistant/assistant.component.ts - 375 + 374 @@ -1330,7 +1330,7 @@ libs/ui/src/lib/assistant/assistant.component.ts - 385 + 384 @@ -1342,7 +1342,7 @@ libs/ui/src/lib/assistant/assistant.component.ts - 409 + 408 @@ -1362,7 +1362,7 @@ libs/ui/src/lib/assistant/assistant.component.ts - 415 + 414 @@ -1906,7 +1906,7 @@ Puisque vous êtes déjà connecté·e, vous ne pouvez pas accéder au compte de démonstration. apps/client/src/app/pages/demo/demo-page.component.ts - 35 + 32 @@ -2018,7 +2018,7 @@ apps/client/src/app/pages/resources/resources-page.component.ts - 40 + 39 libs/common/src/lib/routes/routes.ts @@ -2142,7 +2142,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 124 + 120 @@ -2150,7 +2150,7 @@ Prix Unitaire apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 214 + 210 libs/ui/src/lib/activities-table/activities-table.component.html @@ -2406,7 +2406,7 @@ apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 369 + 372 apps/client/src/app/pages/features/features-page.html @@ -2414,7 +2414,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 202 + 198 apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts @@ -2438,7 +2438,7 @@ Dépôt libs/ui/src/lib/fire-calculator/fire-calculator.component.ts - 377 + 385 @@ -2718,11 +2718,11 @@ apps/client/src/app/pages/admin/admin-page.component.ts - 48 + 45 apps/client/src/app/pages/resources/resources-page.component.ts - 30 + 29 libs/common/src/lib/routes/routes.ts @@ -2854,11 +2854,11 @@ apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 356 + 359 libs/ui/src/lib/fire-calculator/fire-calculator.component.ts - 387 + 395 libs/ui/src/lib/i18n.ts @@ -2870,7 +2870,7 @@ Épargne libs/ui/src/lib/fire-calculator/fire-calculator.component.ts - 397 + 405 @@ -2942,7 +2942,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 290 + 286 libs/ui/src/lib/i18n.ts @@ -2974,7 +2974,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 309 + 305 libs/ui/src/lib/i18n.ts @@ -3054,7 +3054,7 @@ Cash apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 216 + 219 libs/ui/src/lib/i18n.ts @@ -3902,7 +3902,7 @@ Mettre à jour le Solde apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 112 + 108 @@ -4082,7 +4082,7 @@ Dettes apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 299 + 302 apps/client/src/app/pages/features/features-page.html @@ -4498,7 +4498,7 @@ Actifs apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 230 + 233 @@ -5444,7 +5444,7 @@ Frais apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 262 + 258 libs/ui/src/lib/activities-table/activities-table.component.html @@ -5652,7 +5652,7 @@ Logiciel libre de Gestion de Patrimoine apps/client/src/app/pages/i18n/i18n-page.html - 246 + 237 @@ -5752,7 +5752,7 @@ Voulez-vous vraiment supprimer ce solde de compte ? libs/ui/src/lib/account-balances/account-balances.component.ts - 120 + 113 @@ -5928,7 +5928,7 @@ Week to date libs/ui/src/lib/assistant/assistant.component.ts - 367 + 366 @@ -5940,7 +5940,7 @@ libs/ui/src/lib/assistant/assistant.component.ts - 367 + 366 @@ -5948,7 +5948,7 @@ Month to date libs/ui/src/lib/assistant/assistant.component.ts - 371 + 370 @@ -5960,7 +5960,7 @@ libs/ui/src/lib/assistant/assistant.component.ts - 371 + 370 @@ -5968,7 +5968,7 @@ Year to date libs/ui/src/lib/assistant/assistant.component.ts - 375 + 374 @@ -6016,7 +6016,7 @@ libs/ui/src/lib/assistant/assistant.component.ts - 385 + 384 @@ -6028,7 +6028,7 @@ libs/ui/src/lib/assistant/assistant.component.ts - 409 + 408 @@ -6757,7 +6757,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 345 + 341 apps/client/src/app/pages/register/user-account-registration-dialog/user-account-registration-dialog.html @@ -6813,7 +6813,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 347 + 343 libs/ui/src/lib/i18n.ts @@ -7117,7 +7117,7 @@ apps/client/src/app/pages/resources/resources-page.component.ts - 45 + 44 libs/common/src/lib/routes/routes.ts @@ -7133,7 +7133,7 @@ apps/client/src/app/pages/resources/resources-page.component.ts - 34 + 33 libs/common/src/lib/routes/routes.ts @@ -7339,7 +7339,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 356 + 352 libs/ui/src/lib/historical-market-data-editor/historical-market-data-editor-dialog/historical-market-data-editor-dialog.html @@ -7643,7 +7643,7 @@ Find account, holding or page... libs/ui/src/lib/assistant/assistant.component.ts - 151 + 115 @@ -7888,36 +7888,12 @@ 150 - - Fee Ratio (legacy) - Ratio de frais - - apps/client/src/app/pages/i18n/i18n-page.html - 152 - - - - The fees do exceed ${thresholdMax}% of your initial investment (${feeRatio}%) - Les frais dépassent ${thresholdMax}% de votre investissement initial (${feeRatio}%) - - apps/client/src/app/pages/i18n/i18n-page.html - 154 - - - - The fees do not exceed ${thresholdMax}% of your initial investment (${feeRatio}%) - Les frais ne dépassent pas ${thresholdMax}% de votre investissement initial (${feeRatio}%) - - apps/client/src/app/pages/i18n/i18n-page.html - 158 - - Fee Ratio Fee Ratio apps/client/src/app/pages/i18n/i18n-page.html - 161 + 152 @@ -7925,7 +7901,7 @@ The fees do exceed ${thresholdMax}% of your total investment volume (${feeRatio}%) apps/client/src/app/pages/i18n/i18n-page.html - 163 + 154 @@ -7933,7 +7909,7 @@ The fees do not exceed ${thresholdMax}% of your total investment volume (${feeRatio}%) apps/client/src/app/pages/i18n/i18n-page.html - 167 + 158 @@ -8103,7 +8079,7 @@ apps/client/src/app/pages/admin/admin-page.component.ts - 56 + 53 @@ -8392,7 +8368,7 @@ Fees apps/client/src/app/pages/i18n/i18n-page.html - 170 + 161 @@ -8440,7 +8416,7 @@ Regional Market Cluster Risks apps/client/src/app/pages/i18n/i18n-page.html - 172 + 163 @@ -8536,7 +8512,7 @@ Asia-Pacific apps/client/src/app/pages/i18n/i18n-page.html - 174 + 165 @@ -8544,7 +8520,7 @@ The Asia-Pacific market contribution of your current investment (${valueRatio}%) exceeds ${thresholdMax}% apps/client/src/app/pages/i18n/i18n-page.html - 176 + 167 @@ -8552,7 +8528,7 @@ The Asia-Pacific market contribution of your current investment (${valueRatio}%) is below ${thresholdMin}% apps/client/src/app/pages/i18n/i18n-page.html - 180 + 171 @@ -8560,7 +8536,7 @@ The Asia-Pacific market contribution of your current investment (${valueRatio}%) is within the range of ${thresholdMin}% and ${thresholdMax}% apps/client/src/app/pages/i18n/i18n-page.html - 184 + 175 @@ -8568,7 +8544,7 @@ Emerging Markets apps/client/src/app/pages/i18n/i18n-page.html - 189 + 180 @@ -8576,7 +8552,7 @@ The Emerging Markets contribution of your current investment (${valueRatio}%) exceeds ${thresholdMax}% apps/client/src/app/pages/i18n/i18n-page.html - 192 + 183 @@ -8584,7 +8560,7 @@ The Emerging Markets contribution of your current investment (${valueRatio}%) is below ${thresholdMin}% apps/client/src/app/pages/i18n/i18n-page.html - 196 + 187 @@ -8592,7 +8568,7 @@ The Emerging Markets contribution of your current investment (${valueRatio}%) is within the range of ${thresholdMin}% and ${thresholdMax}% apps/client/src/app/pages/i18n/i18n-page.html - 200 + 191 @@ -8600,7 +8576,7 @@ Europe apps/client/src/app/pages/i18n/i18n-page.html - 204 + 195 @@ -8608,7 +8584,7 @@ The Europe market contribution of your current investment (${valueRatio}%) exceeds ${thresholdMax}% apps/client/src/app/pages/i18n/i18n-page.html - 206 + 197 @@ -8616,7 +8592,7 @@ The Europe market contribution of your current investment (${valueRatio}%) is below ${thresholdMin}% apps/client/src/app/pages/i18n/i18n-page.html - 210 + 201 @@ -8624,7 +8600,7 @@ The Europe market contribution of your current investment (${valueRatio}%) is within the range of ${thresholdMin}% and ${thresholdMax}% apps/client/src/app/pages/i18n/i18n-page.html - 214 + 205 @@ -8632,7 +8608,7 @@ Japan apps/client/src/app/pages/i18n/i18n-page.html - 218 + 209 @@ -8640,7 +8616,7 @@ The Japan market contribution of your current investment (${valueRatio}%) exceeds ${thresholdMax}% apps/client/src/app/pages/i18n/i18n-page.html - 220 + 211 @@ -8648,7 +8624,7 @@ The Japan market contribution of your current investment (${valueRatio}%) is below ${thresholdMin}% apps/client/src/app/pages/i18n/i18n-page.html - 224 + 215 @@ -8656,7 +8632,7 @@ The Japan market contribution of your current investment (${valueRatio}%) is within the range of ${thresholdMin}% and ${thresholdMax}% apps/client/src/app/pages/i18n/i18n-page.html - 228 + 219 @@ -8664,7 +8640,7 @@ North America apps/client/src/app/pages/i18n/i18n-page.html - 232 + 223 @@ -8672,7 +8648,7 @@ The North America market contribution of your current investment (${valueRatio}%) exceeds ${thresholdMax}% apps/client/src/app/pages/i18n/i18n-page.html - 234 + 225 @@ -8680,7 +8656,7 @@ The North America market contribution of your current investment (${valueRatio}%) is below ${thresholdMin}% apps/client/src/app/pages/i18n/i18n-page.html - 238 + 229 @@ -8688,7 +8664,7 @@ The North America market contribution of your current investment (${valueRatio}%) is within the range of ${thresholdMin}% and ${thresholdMax}% apps/client/src/app/pages/i18n/i18n-page.html - 242 + 233 diff --git a/apps/client/src/locales/messages.it.xlf b/apps/client/src/locales/messages.it.xlf index f021dae49..05bb6afb2 100644 --- a/apps/client/src/locales/messages.it.xlf +++ b/apps/client/src/locales/messages.it.xlf @@ -135,7 +135,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 139 + 135 libs/ui/src/lib/accounts-table/accounts-table.component.html @@ -179,15 +179,15 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 205 + 201 apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 208 + 204 apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 211 + 207 libs/ui/src/lib/account-balances/account-balances.component.html @@ -327,7 +327,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 155 + 151 libs/ui/src/lib/i18n.ts @@ -439,7 +439,7 @@ Data apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 161 + 157 libs/ui/src/lib/account-balances/account-balances.component.html @@ -935,7 +935,7 @@ Potere d’acquisto apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 245 + 248 @@ -943,7 +943,7 @@ Patrimonio netto apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 321 + 324 @@ -951,7 +951,7 @@ Prestazioni annualizzate apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 335 + 338 @@ -1059,7 +1059,7 @@ libs/ui/src/lib/assistant/assistant.component.ts - 363 + 362 @@ -1071,7 +1071,7 @@ libs/ui/src/lib/assistant/assistant.component.ts - 375 + 374 @@ -1083,7 +1083,7 @@ libs/ui/src/lib/assistant/assistant.component.ts - 385 + 384 @@ -1095,7 +1095,7 @@ libs/ui/src/lib/assistant/assistant.component.ts - 409 + 408 @@ -1115,7 +1115,7 @@ libs/ui/src/lib/assistant/assistant.component.ts - 415 + 414 @@ -1435,7 +1435,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 145 + 141 libs/ui/src/lib/accounts-table/accounts-table.component.html @@ -1615,7 +1615,7 @@ Poiché hai già effettuato l’accesso, non puoi accedere all’account demo. apps/client/src/app/pages/demo/demo-page.component.ts - 35 + 32 @@ -1679,11 +1679,11 @@ apps/client/src/app/pages/admin/admin-page.component.ts - 48 + 45 apps/client/src/app/pages/resources/resources-page.component.ts - 30 + 29 libs/common/src/lib/routes/routes.ts @@ -1723,7 +1723,7 @@ apps/client/src/app/pages/resources/resources-page.component.ts - 40 + 39 libs/common/src/lib/routes/routes.ts @@ -1963,7 +1963,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 124 + 120 @@ -1975,7 +1975,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 189 + 185 libs/ui/src/lib/activities-table/activities-table.component.html @@ -1991,7 +1991,7 @@ Prezzo unitario apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 214 + 210 libs/ui/src/lib/activities-table/activities-table.component.html @@ -2011,7 +2011,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 275 + 271 @@ -2515,7 +2515,7 @@ Risparmio libs/ui/src/lib/fire-calculator/fire-calculator.component.ts - 397 + 405 @@ -2527,11 +2527,11 @@ apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 356 + 359 libs/ui/src/lib/fire-calculator/fire-calculator.component.ts - 387 + 395 libs/ui/src/lib/i18n.ts @@ -2551,7 +2551,7 @@ Deposito libs/ui/src/lib/fire-calculator/fire-calculator.component.ts - 377 + 385 @@ -2691,7 +2691,7 @@ Escluso dall’analisi apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 271 + 274 @@ -2795,7 +2795,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 290 + 286 libs/ui/src/lib/i18n.ts @@ -2851,7 +2851,7 @@ Contanti apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 216 + 219 libs/ui/src/lib/i18n.ts @@ -3135,7 +3135,7 @@ apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 369 + 372 apps/client/src/app/pages/features/features-page.html @@ -3143,7 +3143,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 202 + 198 apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts @@ -3183,7 +3183,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 309 + 305 libs/ui/src/lib/i18n.ts @@ -3903,7 +3903,7 @@ Aggiornamento del saldo di cassa apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 112 + 108 @@ -4083,7 +4083,7 @@ Passività apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 299 + 302 apps/client/src/app/pages/features/features-page.html @@ -4499,7 +4499,7 @@ Asset apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 230 + 233 @@ -5445,7 +5445,7 @@ Commissione apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 262 + 258 libs/ui/src/lib/activities-table/activities-table.component.html @@ -5653,7 +5653,7 @@ Software Open Source per la gestione della tua ricchezza apps/client/src/app/pages/i18n/i18n-page.html - 246 + 237 @@ -5753,7 +5753,7 @@ Vuoi veramente elimnare il saldo di questo conto? libs/ui/src/lib/account-balances/account-balances.component.ts - 120 + 113 @@ -5929,7 +5929,7 @@ Da inizio settimana libs/ui/src/lib/assistant/assistant.component.ts - 367 + 366 @@ -5941,7 +5941,7 @@ libs/ui/src/lib/assistant/assistant.component.ts - 367 + 366 @@ -5949,7 +5949,7 @@ Da inizio mese libs/ui/src/lib/assistant/assistant.component.ts - 371 + 370 @@ -5961,7 +5961,7 @@ libs/ui/src/lib/assistant/assistant.component.ts - 371 + 370 @@ -5969,7 +5969,7 @@ Da inizio anno libs/ui/src/lib/assistant/assistant.component.ts - 375 + 374 @@ -6017,7 +6017,7 @@ libs/ui/src/lib/assistant/assistant.component.ts - 385 + 384 @@ -6029,7 +6029,7 @@ libs/ui/src/lib/assistant/assistant.component.ts - 409 + 408 @@ -6758,7 +6758,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 345 + 341 apps/client/src/app/pages/register/user-account-registration-dialog/user-account-registration-dialog.html @@ -6814,7 +6814,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 347 + 343 libs/ui/src/lib/i18n.ts @@ -7118,7 +7118,7 @@ apps/client/src/app/pages/resources/resources-page.component.ts - 45 + 44 libs/common/src/lib/routes/routes.ts @@ -7134,7 +7134,7 @@ apps/client/src/app/pages/resources/resources-page.component.ts - 34 + 33 libs/common/src/lib/routes/routes.ts @@ -7340,7 +7340,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 356 + 352 libs/ui/src/lib/historical-market-data-editor/historical-market-data-editor-dialog/historical-market-data-editor-dialog.html @@ -7644,7 +7644,7 @@ Find account, holding or page... libs/ui/src/lib/assistant/assistant.component.ts - 151 + 115 @@ -7889,36 +7889,12 @@ 150 - - Fee Ratio (legacy) - Rapporto tariffario - - apps/client/src/app/pages/i18n/i18n-page.html - 152 - - - - The fees do exceed ${thresholdMax}% of your initial investment (${feeRatio}%) - Le commissioni superano il ${thresholdMax}% del tuo investimento iniziale (${feeRatio}%) - - apps/client/src/app/pages/i18n/i18n-page.html - 154 - - - - The fees do not exceed ${thresholdMax}% of your initial investment (${feeRatio}%) - Le commissioni non superano il ${thresholdMax}% del tuo investimento iniziale (${feeRatio}%) - - apps/client/src/app/pages/i18n/i18n-page.html - 158 - - Fee Ratio Fee Ratio apps/client/src/app/pages/i18n/i18n-page.html - 161 + 152 @@ -7926,7 +7902,7 @@ The fees do exceed ${thresholdMax}% of your total investment volume (${feeRatio}%) apps/client/src/app/pages/i18n/i18n-page.html - 163 + 154 @@ -7934,7 +7910,7 @@ The fees do not exceed ${thresholdMax}% of your total investment volume (${feeRatio}%) apps/client/src/app/pages/i18n/i18n-page.html - 167 + 158 @@ -8104,7 +8080,7 @@ apps/client/src/app/pages/admin/admin-page.component.ts - 56 + 53 @@ -8393,7 +8369,7 @@ Fees apps/client/src/app/pages/i18n/i18n-page.html - 170 + 161 @@ -8441,7 +8417,7 @@ Regional Market Cluster Risks apps/client/src/app/pages/i18n/i18n-page.html - 172 + 163 @@ -8537,7 +8513,7 @@ Asia-Pacific apps/client/src/app/pages/i18n/i18n-page.html - 174 + 165 @@ -8545,7 +8521,7 @@ The Asia-Pacific market contribution of your current investment (${valueRatio}%) exceeds ${thresholdMax}% apps/client/src/app/pages/i18n/i18n-page.html - 176 + 167 @@ -8553,7 +8529,7 @@ The Asia-Pacific market contribution of your current investment (${valueRatio}%) is below ${thresholdMin}% apps/client/src/app/pages/i18n/i18n-page.html - 180 + 171 @@ -8561,7 +8537,7 @@ The Asia-Pacific market contribution of your current investment (${valueRatio}%) is within the range of ${thresholdMin}% and ${thresholdMax}% apps/client/src/app/pages/i18n/i18n-page.html - 184 + 175 @@ -8569,7 +8545,7 @@ Emerging Markets apps/client/src/app/pages/i18n/i18n-page.html - 189 + 180 @@ -8577,7 +8553,7 @@ The Emerging Markets contribution of your current investment (${valueRatio}%) exceeds ${thresholdMax}% apps/client/src/app/pages/i18n/i18n-page.html - 192 + 183 @@ -8585,7 +8561,7 @@ The Emerging Markets contribution of your current investment (${valueRatio}%) is below ${thresholdMin}% apps/client/src/app/pages/i18n/i18n-page.html - 196 + 187 @@ -8593,7 +8569,7 @@ The Emerging Markets contribution of your current investment (${valueRatio}%) is within the range of ${thresholdMin}% and ${thresholdMax}% apps/client/src/app/pages/i18n/i18n-page.html - 200 + 191 @@ -8601,7 +8577,7 @@ Europe apps/client/src/app/pages/i18n/i18n-page.html - 204 + 195 @@ -8609,7 +8585,7 @@ The Europe market contribution of your current investment (${valueRatio}%) exceeds ${thresholdMax}% apps/client/src/app/pages/i18n/i18n-page.html - 206 + 197 @@ -8617,7 +8593,7 @@ The Europe market contribution of your current investment (${valueRatio}%) is below ${thresholdMin}% apps/client/src/app/pages/i18n/i18n-page.html - 210 + 201 @@ -8625,7 +8601,7 @@ The Europe market contribution of your current investment (${valueRatio}%) is within the range of ${thresholdMin}% and ${thresholdMax}% apps/client/src/app/pages/i18n/i18n-page.html - 214 + 205 @@ -8633,7 +8609,7 @@ Japan apps/client/src/app/pages/i18n/i18n-page.html - 218 + 209 @@ -8641,7 +8617,7 @@ The Japan market contribution of your current investment (${valueRatio}%) exceeds ${thresholdMax}% apps/client/src/app/pages/i18n/i18n-page.html - 220 + 211 @@ -8649,7 +8625,7 @@ The Japan market contribution of your current investment (${valueRatio}%) is below ${thresholdMin}% apps/client/src/app/pages/i18n/i18n-page.html - 224 + 215 @@ -8657,7 +8633,7 @@ The Japan market contribution of your current investment (${valueRatio}%) is within the range of ${thresholdMin}% and ${thresholdMax}% apps/client/src/app/pages/i18n/i18n-page.html - 228 + 219 @@ -8665,7 +8641,7 @@ North America apps/client/src/app/pages/i18n/i18n-page.html - 232 + 223 @@ -8673,7 +8649,7 @@ The North America market contribution of your current investment (${valueRatio}%) exceeds ${thresholdMax}% apps/client/src/app/pages/i18n/i18n-page.html - 234 + 225 @@ -8681,7 +8657,7 @@ The North America market contribution of your current investment (${valueRatio}%) is below ${thresholdMin}% apps/client/src/app/pages/i18n/i18n-page.html - 238 + 229 @@ -8689,7 +8665,7 @@ The North America market contribution of your current investment (${valueRatio}%) is within the range of ${thresholdMin}% and ${thresholdMax}% apps/client/src/app/pages/i18n/i18n-page.html - 242 + 233 diff --git a/apps/client/src/locales/messages.ko.xlf b/apps/client/src/locales/messages.ko.xlf index f188d4924..9b7c4192e 100644 --- a/apps/client/src/locales/messages.ko.xlf +++ b/apps/client/src/locales/messages.ko.xlf @@ -388,7 +388,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 139 + 135 libs/ui/src/lib/accounts-table/accounts-table.component.html @@ -444,7 +444,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 145 + 141 libs/ui/src/lib/accounts-table/accounts-table.component.html @@ -464,15 +464,15 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 205 + 201 apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 208 + 204 apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 211 + 207 libs/ui/src/lib/account-balances/account-balances.component.html @@ -624,7 +624,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 155 + 151 libs/ui/src/lib/i18n.ts @@ -720,7 +720,7 @@ 날짜 apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 161 + 157 libs/ui/src/lib/account-balances/account-balances.component.html @@ -1024,7 +1024,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 275 + 271 @@ -1068,7 +1068,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 124 + 120 @@ -1856,7 +1856,7 @@ 자산 apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 230 + 233 @@ -1864,7 +1864,7 @@ 매수 가능 금액 apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 245 + 248 @@ -1872,7 +1872,7 @@ 분석에서 제외됨 apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 271 + 274 @@ -1880,7 +1880,7 @@ 부채 apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 299 + 302 apps/client/src/app/pages/features/features-page.html @@ -1892,7 +1892,7 @@ 순자산 apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 321 + 324 @@ -1900,7 +1900,7 @@ 연환산 성과 apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 335 + 338 @@ -1936,7 +1936,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 189 + 185 libs/ui/src/lib/activities-table/activities-table.component.html @@ -2132,7 +2132,7 @@ libs/ui/src/lib/assistant/assistant.component.ts - 363 + 362 @@ -2144,7 +2144,7 @@ libs/ui/src/lib/assistant/assistant.component.ts - 375 + 374 @@ -2156,7 +2156,7 @@ libs/ui/src/lib/assistant/assistant.component.ts - 385 + 384 @@ -2168,7 +2168,7 @@ libs/ui/src/lib/assistant/assistant.component.ts - 409 + 408 @@ -2188,7 +2188,7 @@ libs/ui/src/lib/assistant/assistant.component.ts - 415 + 414 @@ -2788,11 +2788,11 @@ apps/client/src/app/pages/admin/admin-page.component.ts - 48 + 45 apps/client/src/app/pages/resources/resources-page.component.ts - 30 + 29 libs/common/src/lib/routes/routes.ts @@ -2936,7 +2936,7 @@ 이미 로그인되어 있으므로 데모 계정에 접근할 수 없습니다. apps/client/src/app/pages/demo/demo-page.component.ts - 35 + 32 @@ -3184,7 +3184,7 @@ apps/client/src/app/pages/resources/resources-page.component.ts - 40 + 39 libs/common/src/lib/routes/routes.ts @@ -3224,7 +3224,7 @@ 오픈 소스 자산관리 소프트웨어 apps/client/src/app/pages/i18n/i18n-page.html - 246 + 237 @@ -3764,7 +3764,7 @@ 현금 잔액 업데이트 apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 112 + 108 @@ -3772,7 +3772,7 @@ 단가 apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 214 + 210 libs/ui/src/lib/activities-table/activities-table.component.html @@ -4128,7 +4128,7 @@ apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 369 + 372 apps/client/src/app/pages/features/features-page.html @@ -4136,7 +4136,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 202 + 198 apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts @@ -4160,7 +4160,7 @@ 보증금 libs/ui/src/lib/fire-calculator/fire-calculator.component.ts - 377 + 385 @@ -4941,7 +4941,7 @@ 정말로 이 계정 잔액을 삭제하시겠습니까? libs/ui/src/lib/account-balances/account-balances.component.ts - 120 + 113 @@ -5117,11 +5117,11 @@ apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 356 + 359 libs/ui/src/lib/fire-calculator/fire-calculator.component.ts - 387 + 395 libs/ui/src/lib/i18n.ts @@ -5133,7 +5133,7 @@ 저금 libs/ui/src/lib/fire-calculator/fire-calculator.component.ts - 397 + 405 @@ -5213,7 +5213,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 290 + 286 libs/ui/src/lib/i18n.ts @@ -5245,7 +5245,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 309 + 305 libs/ui/src/lib/i18n.ts @@ -5501,7 +5501,7 @@ 요금 apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 262 + 258 libs/ui/src/lib/activities-table/activities-table.component.html @@ -5545,7 +5545,7 @@ 현금 apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 216 + 219 libs/ui/src/lib/i18n.ts @@ -5953,7 +5953,7 @@ 연초 현재 libs/ui/src/lib/assistant/assistant.component.ts - 375 + 374 @@ -5961,7 +5961,7 @@ 이번주 현재까지 libs/ui/src/lib/assistant/assistant.component.ts - 367 + 366 @@ -5969,7 +5969,7 @@ 월간 누계 libs/ui/src/lib/assistant/assistant.component.ts - 371 + 370 @@ -5981,7 +5981,7 @@ libs/ui/src/lib/assistant/assistant.component.ts - 371 + 370 @@ -5993,7 +5993,7 @@ libs/ui/src/lib/assistant/assistant.component.ts - 367 + 366 @@ -6041,7 +6041,7 @@ libs/ui/src/lib/assistant/assistant.component.ts - 385 + 384 @@ -6053,7 +6053,7 @@ libs/ui/src/lib/assistant/assistant.component.ts - 409 + 408 @@ -6742,7 +6742,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 345 + 341 apps/client/src/app/pages/register/user-account-registration-dialog/user-account-registration-dialog.html @@ -6830,7 +6830,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 347 + 343 libs/ui/src/lib/i18n.ts @@ -7142,7 +7142,7 @@ apps/client/src/app/pages/resources/resources-page.component.ts - 45 + 44 libs/common/src/lib/routes/routes.ts @@ -7171,7 +7171,7 @@ apps/client/src/app/pages/resources/resources-page.component.ts - 34 + 33 libs/common/src/lib/routes/routes.ts @@ -7364,7 +7364,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 356 + 352 libs/ui/src/lib/historical-market-data-editor/historical-market-data-editor-dialog/historical-market-data-editor-dialog.html @@ -7656,7 +7656,7 @@ 계정, 보유 또는 페이지 찾기... libs/ui/src/lib/assistant/assistant.component.ts - 151 + 115 @@ -7889,36 +7889,12 @@ 150 - - Fee Ratio (legacy) - 수수료 비율 - - apps/client/src/app/pages/i18n/i18n-page.html - 152 - - - - The fees do exceed ${thresholdMax}% of your initial investment (${feeRatio}%) - 수수료가 초기 투자금(${feeRatio}%)의 ${thresholdMax}%를 초과합니다. - - apps/client/src/app/pages/i18n/i18n-page.html - 154 - - - - The fees do not exceed ${thresholdMax}% of your initial investment (${feeRatio}%) - 수수료는 초기 투자금의 ${thresholdMax}%(${feeRatio}%)를 초과하지 않습니다. - - apps/client/src/app/pages/i18n/i18n-page.html - 158 - - Fee Ratio Fee Ratio apps/client/src/app/pages/i18n/i18n-page.html - 161 + 152 @@ -7926,7 +7902,7 @@ The fees do exceed ${thresholdMax}% of your total investment volume (${feeRatio}%) apps/client/src/app/pages/i18n/i18n-page.html - 163 + 154 @@ -7934,7 +7910,7 @@ The fees do not exceed ${thresholdMax}% of your total investment volume (${feeRatio}%) apps/client/src/app/pages/i18n/i18n-page.html - 167 + 158 @@ -8104,7 +8080,7 @@ apps/client/src/app/pages/admin/admin-page.component.ts - 56 + 53 @@ -8401,7 +8377,7 @@ 수수료 apps/client/src/app/pages/i18n/i18n-page.html - 170 + 161 @@ -8449,7 +8425,7 @@ 지역 시장 클러스터 위험 apps/client/src/app/pages/i18n/i18n-page.html - 172 + 163 @@ -8537,7 +8513,7 @@ 아시아·태평양 apps/client/src/app/pages/i18n/i18n-page.html - 174 + 165 @@ -8545,7 +8521,7 @@ 현재 투자의 아시아 태평양 시장 기여도(${valueRatio}%)가 ${thresholdMax}%를 초과합니다. apps/client/src/app/pages/i18n/i18n-page.html - 176 + 167 @@ -8553,7 +8529,7 @@ 현재 투자의 아시아 태평양 시장 기여도(${valueRatio}%)가 ${thresholdMin}% 미만입니다. apps/client/src/app/pages/i18n/i18n-page.html - 180 + 171 @@ -8561,7 +8537,7 @@ 현재 투자의 아시아 태평양 시장 기여도(${valueRatio}%)가 ${thresholdMin}% 및 ${thresholdMax}% 범위 내에 있습니다. apps/client/src/app/pages/i18n/i18n-page.html - 184 + 175 @@ -8569,7 +8545,7 @@ 신흥시장 apps/client/src/app/pages/i18n/i18n-page.html - 189 + 180 @@ -8577,7 +8553,7 @@ 현재 투자의 신흥 시장 기여도(${valueRatio}%)가 ${thresholdMax}%를 초과합니다. apps/client/src/app/pages/i18n/i18n-page.html - 192 + 183 @@ -8585,7 +8561,7 @@ 현재 투자의 신흥 시장 기여도(${valueRatio}%)가 ${thresholdMin}% 미만입니다. apps/client/src/app/pages/i18n/i18n-page.html - 196 + 187 @@ -8593,7 +8569,7 @@ 현재 투자의 신흥 시장 기여도(${valueRatio}%)가 ${thresholdMin}% 및 ${thresholdMax}% 범위 내에 있습니다. apps/client/src/app/pages/i18n/i18n-page.html - 200 + 191 @@ -8601,7 +8577,7 @@ 유럽 apps/client/src/app/pages/i18n/i18n-page.html - 204 + 195 @@ -8609,7 +8585,7 @@ 현재 투자의 유럽 시장 기여도(${valueRatio}%)가 ${thresholdMax}%를 초과합니다. apps/client/src/app/pages/i18n/i18n-page.html - 206 + 197 @@ -8617,7 +8593,7 @@ 현재 투자의 유럽 시장 기여도(${valueRatio}%)가 ${thresholdMin}% 미만입니다. apps/client/src/app/pages/i18n/i18n-page.html - 210 + 201 @@ -8625,7 +8601,7 @@ 현재 투자의 유럽 시장 기여도(${valueRatio}%)는 ${thresholdMin}% 및 ${thresholdMax}% 범위 내에 있습니다. apps/client/src/app/pages/i18n/i18n-page.html - 214 + 205 @@ -8633,7 +8609,7 @@ 일본 apps/client/src/app/pages/i18n/i18n-page.html - 218 + 209 @@ -8641,7 +8617,7 @@ 현재 투자의 일본 시장 기여도(${valueRatio}%)가 ${thresholdMax}%를 초과합니다. apps/client/src/app/pages/i18n/i18n-page.html - 220 + 211 @@ -8649,7 +8625,7 @@ 현재 투자의 일본 시장 기여도(${valueRatio}%)가 ${thresholdMin}% 미만입니다. apps/client/src/app/pages/i18n/i18n-page.html - 224 + 215 @@ -8657,7 +8633,7 @@ 현재 투자의 일본 시장 기여도(${valueRatio}%)는 ${thresholdMin}% 및 ${thresholdMax}% 범위 내에 있습니다. apps/client/src/app/pages/i18n/i18n-page.html - 228 + 219 @@ -8665,7 +8641,7 @@ 북미 apps/client/src/app/pages/i18n/i18n-page.html - 232 + 223 @@ -8673,7 +8649,7 @@ 현재 투자의 북미 시장 기여도(${valueRatio}%)가 ${thresholdMax}%를 초과합니다. apps/client/src/app/pages/i18n/i18n-page.html - 234 + 225 @@ -8681,7 +8657,7 @@ 현재 투자의 북미 시장 기여도(${valueRatio}%)가 ${thresholdMin}% 미만입니다. apps/client/src/app/pages/i18n/i18n-page.html - 238 + 229 @@ -8689,7 +8665,7 @@ 현재 투자의 북미 시장 기여도(${valueRatio}%)가 ${thresholdMin}% 및 ${thresholdMax}% 범위 내에 있습니다. apps/client/src/app/pages/i18n/i18n-page.html - 242 + 233 diff --git a/apps/client/src/locales/messages.nl.xlf b/apps/client/src/locales/messages.nl.xlf index 76a74e6fd..58928387b 100644 --- a/apps/client/src/locales/messages.nl.xlf +++ b/apps/client/src/locales/messages.nl.xlf @@ -134,7 +134,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 139 + 135 libs/ui/src/lib/accounts-table/accounts-table.component.html @@ -178,15 +178,15 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 205 + 201 apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 208 + 204 apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 211 + 207 libs/ui/src/lib/account-balances/account-balances.component.html @@ -326,7 +326,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 155 + 151 libs/ui/src/lib/i18n.ts @@ -438,7 +438,7 @@ Datum apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 161 + 157 libs/ui/src/lib/account-balances/account-balances.component.html @@ -934,7 +934,7 @@ Koopkracht apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 245 + 248 @@ -942,7 +942,7 @@ Netto waarde apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 321 + 324 @@ -950,7 +950,7 @@ Rendement per jaar apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 335 + 338 @@ -1058,7 +1058,7 @@ libs/ui/src/lib/assistant/assistant.component.ts - 363 + 362 @@ -1070,7 +1070,7 @@ libs/ui/src/lib/assistant/assistant.component.ts - 375 + 374 @@ -1082,7 +1082,7 @@ libs/ui/src/lib/assistant/assistant.component.ts - 385 + 384 @@ -1094,7 +1094,7 @@ libs/ui/src/lib/assistant/assistant.component.ts - 409 + 408 @@ -1114,7 +1114,7 @@ libs/ui/src/lib/assistant/assistant.component.ts - 415 + 414 @@ -1434,7 +1434,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 145 + 141 libs/ui/src/lib/accounts-table/accounts-table.component.html @@ -1614,7 +1614,7 @@ Aangezien je al ingelogd bent, heb je geen toegang tot de demo-account. apps/client/src/app/pages/demo/demo-page.component.ts - 35 + 32 @@ -1678,11 +1678,11 @@ apps/client/src/app/pages/admin/admin-page.component.ts - 48 + 45 apps/client/src/app/pages/resources/resources-page.component.ts - 30 + 29 libs/common/src/lib/routes/routes.ts @@ -1722,7 +1722,7 @@ apps/client/src/app/pages/resources/resources-page.component.ts - 40 + 39 libs/common/src/lib/routes/routes.ts @@ -1962,7 +1962,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 124 + 120 @@ -1974,7 +1974,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 189 + 185 libs/ui/src/lib/activities-table/activities-table.component.html @@ -1990,7 +1990,7 @@ Prijs per eenheid apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 214 + 210 libs/ui/src/lib/activities-table/activities-table.component.html @@ -2010,7 +2010,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 275 + 271 @@ -2514,7 +2514,7 @@ Besparingen libs/ui/src/lib/fire-calculator/fire-calculator.component.ts - 397 + 405 @@ -2526,11 +2526,11 @@ apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 356 + 359 libs/ui/src/lib/fire-calculator/fire-calculator.component.ts - 387 + 395 libs/ui/src/lib/i18n.ts @@ -2550,7 +2550,7 @@ Storting libs/ui/src/lib/fire-calculator/fire-calculator.component.ts - 377 + 385 @@ -2690,7 +2690,7 @@ Uitgesloten van analyse apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 271 + 274 @@ -2794,7 +2794,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 290 + 286 libs/ui/src/lib/i18n.ts @@ -2850,7 +2850,7 @@ Contant geld apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 216 + 219 libs/ui/src/lib/i18n.ts @@ -3134,7 +3134,7 @@ apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 369 + 372 apps/client/src/app/pages/features/features-page.html @@ -3142,7 +3142,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 202 + 198 apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts @@ -3182,7 +3182,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 309 + 305 libs/ui/src/lib/i18n.ts @@ -3902,7 +3902,7 @@ Saldo bijwerken apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 112 + 108 @@ -4082,7 +4082,7 @@ Verplichtingen apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 299 + 302 apps/client/src/app/pages/features/features-page.html @@ -4498,7 +4498,7 @@ Assets apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 230 + 233 @@ -5444,7 +5444,7 @@ Kosten apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 262 + 258 libs/ui/src/lib/activities-table/activities-table.component.html @@ -5652,7 +5652,7 @@ Open Source Vermogensbeheer Software apps/client/src/app/pages/i18n/i18n-page.html - 246 + 237 @@ -5752,7 +5752,7 @@ Wilt u dit rekeningsaldo echt verwijderen? libs/ui/src/lib/account-balances/account-balances.component.ts - 120 + 113 @@ -5928,7 +5928,7 @@ Week tot nu toe libs/ui/src/lib/assistant/assistant.component.ts - 367 + 366 @@ -5940,7 +5940,7 @@ libs/ui/src/lib/assistant/assistant.component.ts - 367 + 366 @@ -5948,7 +5948,7 @@ Maand tot nu toe libs/ui/src/lib/assistant/assistant.component.ts - 371 + 370 @@ -5960,7 +5960,7 @@ libs/ui/src/lib/assistant/assistant.component.ts - 371 + 370 @@ -5968,7 +5968,7 @@ Jaar tot nu toe libs/ui/src/lib/assistant/assistant.component.ts - 375 + 374 @@ -6016,7 +6016,7 @@ libs/ui/src/lib/assistant/assistant.component.ts - 385 + 384 @@ -6028,7 +6028,7 @@ libs/ui/src/lib/assistant/assistant.component.ts - 409 + 408 @@ -6757,7 +6757,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 345 + 341 apps/client/src/app/pages/register/user-account-registration-dialog/user-account-registration-dialog.html @@ -6813,7 +6813,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 347 + 343 libs/ui/src/lib/i18n.ts @@ -7117,7 +7117,7 @@ apps/client/src/app/pages/resources/resources-page.component.ts - 45 + 44 libs/common/src/lib/routes/routes.ts @@ -7133,7 +7133,7 @@ apps/client/src/app/pages/resources/resources-page.component.ts - 34 + 33 libs/common/src/lib/routes/routes.ts @@ -7339,7 +7339,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 356 + 352 libs/ui/src/lib/historical-market-data-editor/historical-market-data-editor-dialog/historical-market-data-editor-dialog.html @@ -7643,7 +7643,7 @@ Find account, holding or page... libs/ui/src/lib/assistant/assistant.component.ts - 151 + 115 @@ -7888,36 +7888,12 @@ 150 - - Fee Ratio (legacy) - Vergoedingsverhouding - - apps/client/src/app/pages/i18n/i18n-page.html - 152 - - - - The fees do exceed ${thresholdMax}% of your initial investment (${feeRatio}%) - De kosten overschrijden ${thresholdMax}% van uw initiële investering (${feeRatio}%) - - apps/client/src/app/pages/i18n/i18n-page.html - 154 - - - - The fees do not exceed ${thresholdMax}% of your initial investment (${feeRatio}%) - De kosten bedragen niet meer dan ${thresholdMax}% van uw initiële investering (${feeRatio}%) - - apps/client/src/app/pages/i18n/i18n-page.html - 158 - - Fee Ratio Fee Ratio apps/client/src/app/pages/i18n/i18n-page.html - 161 + 152 @@ -7925,7 +7901,7 @@ The fees do exceed ${thresholdMax}% of your total investment volume (${feeRatio}%) apps/client/src/app/pages/i18n/i18n-page.html - 163 + 154 @@ -7933,7 +7909,7 @@ The fees do not exceed ${thresholdMax}% of your total investment volume (${feeRatio}%) apps/client/src/app/pages/i18n/i18n-page.html - 167 + 158 @@ -8103,7 +8079,7 @@ apps/client/src/app/pages/admin/admin-page.component.ts - 56 + 53 @@ -8392,7 +8368,7 @@ Kosten apps/client/src/app/pages/i18n/i18n-page.html - 170 + 161 @@ -8440,7 +8416,7 @@ Risico’s van regionale marktclusters apps/client/src/app/pages/i18n/i18n-page.html - 172 + 163 @@ -8536,7 +8512,7 @@ Azië-Pacific apps/client/src/app/pages/i18n/i18n-page.html - 174 + 165 @@ -8544,7 +8520,7 @@ De bijdrage van de Azië-Pacific markt aan je huidige investering (${valueRatio}%) overschrijdt ${thresholdMax}% apps/client/src/app/pages/i18n/i18n-page.html - 176 + 167 @@ -8552,7 +8528,7 @@ De bijdrage van de Azië-Pacific markt aan je huidige investering (${valueRatio}%) ligt onder ${thresholdMin}% apps/client/src/app/pages/i18n/i18n-page.html - 180 + 171 @@ -8560,7 +8536,7 @@ De bijdrage van de Azië-Pacific markt aan je huidige investering (${valueRatio}%) ligt binnen het bereik van ${thresholdMin}% en ${thresholdMax}% apps/client/src/app/pages/i18n/i18n-page.html - 184 + 175 @@ -8568,7 +8544,7 @@ Opkomende markten apps/client/src/app/pages/i18n/i18n-page.html - 189 + 180 @@ -8576,7 +8552,7 @@ De bijdrage van de opkomende markten aan je huidige investering (${valueRatio}%) overschrijdt ${thresholdMax}% apps/client/src/app/pages/i18n/i18n-page.html - 192 + 183 @@ -8584,7 +8560,7 @@ De bijdrage van de opkomende markten aan je huidige investering (${valueRatio}%) ligt onder ${thresholdMin}% apps/client/src/app/pages/i18n/i18n-page.html - 196 + 187 @@ -8592,7 +8568,7 @@ De bijdrage van de opkomende markten aan je huidige investering (${valueRatio}%) ligt binnen het bereik van ${thresholdMin}% en ${thresholdMax}% apps/client/src/app/pages/i18n/i18n-page.html - 200 + 191 @@ -8600,7 +8576,7 @@ Europa apps/client/src/app/pages/i18n/i18n-page.html - 204 + 195 @@ -8608,7 +8584,7 @@ De bijdrage van de Europese markt aan je huidige investering (${valueRatio}%) overschrijdt ${thresholdMax}% apps/client/src/app/pages/i18n/i18n-page.html - 206 + 197 @@ -8616,7 +8592,7 @@ De bijdrage van de Europese markt aan je huidige investering (${valueRatio}%) ligt onder ${thresholdMin}% apps/client/src/app/pages/i18n/i18n-page.html - 210 + 201 @@ -8624,7 +8600,7 @@ De bijdrage van de Europese markt aan je huidige investering (${valueRatio}%) ligt binnen het bereik van ${thresholdMin}% en ${thresholdMax}% apps/client/src/app/pages/i18n/i18n-page.html - 214 + 205 @@ -8632,7 +8608,7 @@ Japan apps/client/src/app/pages/i18n/i18n-page.html - 218 + 209 @@ -8640,7 +8616,7 @@ De bijdrage van de Japanse markt aan je huidige investering (${valueRatio}%) overschrijdt ${thresholdMax}% apps/client/src/app/pages/i18n/i18n-page.html - 220 + 211 @@ -8648,7 +8624,7 @@ De bijdrage van de Japanse markt aan je huidige investering (${valueRatio}%) ligt onder ${thresholdMin}% apps/client/src/app/pages/i18n/i18n-page.html - 224 + 215 @@ -8656,7 +8632,7 @@ De bijdrage van de Japanse markt aan je huidige investering (${valueRatio}%) ligt binnen het bereik van ${thresholdMin}% en ${thresholdMax}% apps/client/src/app/pages/i18n/i18n-page.html - 228 + 219 @@ -8664,7 +8640,7 @@ Noord-Amerika apps/client/src/app/pages/i18n/i18n-page.html - 232 + 223 @@ -8672,7 +8648,7 @@ De bijdrage van de Noord-Amerikaanse markt aan je huidige investering (${valueRatio}%) overschrijdt ${thresholdMax}% apps/client/src/app/pages/i18n/i18n-page.html - 234 + 225 @@ -8680,7 +8656,7 @@ De bijdrage van de Noord-Amerikaanse markt aan je huidige investering (${valueRatio}%) ligt onder ${thresholdMin}% apps/client/src/app/pages/i18n/i18n-page.html - 238 + 229 @@ -8688,7 +8664,7 @@ De bijdrage van de Noord-Amerikaanse markt aan je huidige investering (${valueRatio}%) ligt binnen het bereik van ${thresholdMin}% en ${thresholdMax}% apps/client/src/app/pages/i18n/i18n-page.html - 242 + 233 diff --git a/apps/client/src/locales/messages.pl.xlf b/apps/client/src/locales/messages.pl.xlf index fdc528254..bc8b948cd 100644 --- a/apps/client/src/locales/messages.pl.xlf +++ b/apps/client/src/locales/messages.pl.xlf @@ -379,7 +379,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 139 + 135 libs/ui/src/lib/accounts-table/accounts-table.component.html @@ -435,7 +435,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 145 + 141 libs/ui/src/lib/accounts-table/accounts-table.component.html @@ -455,15 +455,15 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 205 + 201 apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 208 + 204 apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 211 + 207 libs/ui/src/lib/account-balances/account-balances.component.html @@ -615,7 +615,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 155 + 151 libs/ui/src/lib/i18n.ts @@ -711,7 +711,7 @@ Data apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 161 + 157 libs/ui/src/lib/account-balances/account-balances.component.html @@ -991,7 +991,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 275 + 271 @@ -1035,7 +1035,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 124 + 120 @@ -1823,7 +1823,7 @@ Aktywa apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 230 + 233 @@ -1831,7 +1831,7 @@ Siła Nabywcza apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 245 + 248 @@ -1839,7 +1839,7 @@ Wykluczone z Analizy apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 271 + 274 @@ -1847,7 +1847,7 @@ Pasywa (Zobowiązania Finansowe) apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 299 + 302 apps/client/src/app/pages/features/features-page.html @@ -1859,7 +1859,7 @@ Wartość Netto apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 321 + 324 @@ -1867,7 +1867,7 @@ Osiągi w Ujęciu Rocznym apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 335 + 338 @@ -1903,7 +1903,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 189 + 185 libs/ui/src/lib/activities-table/activities-table.component.html @@ -2099,7 +2099,7 @@ libs/ui/src/lib/assistant/assistant.component.ts - 363 + 362 @@ -2111,7 +2111,7 @@ libs/ui/src/lib/assistant/assistant.component.ts - 375 + 374 @@ -2123,7 +2123,7 @@ libs/ui/src/lib/assistant/assistant.component.ts - 385 + 384 @@ -2135,7 +2135,7 @@ libs/ui/src/lib/assistant/assistant.component.ts - 409 + 408 @@ -2155,7 +2155,7 @@ libs/ui/src/lib/assistant/assistant.component.ts - 415 + 414 @@ -2755,11 +2755,11 @@ apps/client/src/app/pages/admin/admin-page.component.ts - 48 + 45 apps/client/src/app/pages/resources/resources-page.component.ts - 30 + 29 libs/common/src/lib/routes/routes.ts @@ -2903,7 +2903,7 @@ Ponieważ jesteś już zalogowany, nie możesz uzyskać dostępu do konta demo. apps/client/src/app/pages/demo/demo-page.component.ts - 35 + 32 @@ -3151,7 +3151,7 @@ apps/client/src/app/pages/resources/resources-page.component.ts - 40 + 39 libs/common/src/lib/routes/routes.ts @@ -3191,7 +3191,7 @@ Oprogramowanie Open Source do Zarządzania Majątkiem apps/client/src/app/pages/i18n/i18n-page.html - 246 + 237 @@ -3731,7 +3731,7 @@ Zaktualizuj Saldo Gotówkowe apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 112 + 108 @@ -3739,7 +3739,7 @@ Cena Jednostkowa apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 214 + 210 libs/ui/src/lib/activities-table/activities-table.component.html @@ -4095,7 +4095,7 @@ apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 369 + 372 apps/client/src/app/pages/features/features-page.html @@ -4103,7 +4103,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 202 + 198 apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts @@ -4127,7 +4127,7 @@ Depozyt libs/ui/src/lib/fire-calculator/fire-calculator.component.ts - 377 + 385 @@ -5048,11 +5048,11 @@ apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 356 + 359 libs/ui/src/lib/fire-calculator/fire-calculator.component.ts - 387 + 395 libs/ui/src/lib/i18n.ts @@ -5064,7 +5064,7 @@ Oszczędności libs/ui/src/lib/fire-calculator/fire-calculator.component.ts - 397 + 405 @@ -5144,7 +5144,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 290 + 286 libs/ui/src/lib/i18n.ts @@ -5176,7 +5176,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 309 + 305 libs/ui/src/lib/i18n.ts @@ -5432,7 +5432,7 @@ Opłata apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 262 + 258 libs/ui/src/lib/activities-table/activities-table.component.html @@ -5476,7 +5476,7 @@ Gotówka apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 216 + 219 libs/ui/src/lib/i18n.ts @@ -5752,7 +5752,7 @@ Czy na pewno chcesz usunąć saldo tego konta? libs/ui/src/lib/account-balances/account-balances.component.ts - 120 + 113 @@ -5928,7 +5928,7 @@ Dotychczasowy tydzień libs/ui/src/lib/assistant/assistant.component.ts - 367 + 366 @@ -5940,7 +5940,7 @@ libs/ui/src/lib/assistant/assistant.component.ts - 367 + 366 @@ -5948,7 +5948,7 @@ Od początku miesiąca libs/ui/src/lib/assistant/assistant.component.ts - 371 + 370 @@ -5960,7 +5960,7 @@ libs/ui/src/lib/assistant/assistant.component.ts - 371 + 370 @@ -5968,7 +5968,7 @@ Od początku roku libs/ui/src/lib/assistant/assistant.component.ts - 375 + 374 @@ -6016,7 +6016,7 @@ libs/ui/src/lib/assistant/assistant.component.ts - 385 + 384 @@ -6028,7 +6028,7 @@ libs/ui/src/lib/assistant/assistant.component.ts - 409 + 408 @@ -6757,7 +6757,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 345 + 341 apps/client/src/app/pages/register/user-account-registration-dialog/user-account-registration-dialog.html @@ -6813,7 +6813,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 347 + 343 libs/ui/src/lib/i18n.ts @@ -7117,7 +7117,7 @@ apps/client/src/app/pages/resources/resources-page.component.ts - 45 + 44 libs/common/src/lib/routes/routes.ts @@ -7133,7 +7133,7 @@ apps/client/src/app/pages/resources/resources-page.component.ts - 34 + 33 libs/common/src/lib/routes/routes.ts @@ -7339,7 +7339,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 356 + 352 libs/ui/src/lib/historical-market-data-editor/historical-market-data-editor-dialog/historical-market-data-editor-dialog.html @@ -7643,7 +7643,7 @@ Find account, holding or page... libs/ui/src/lib/assistant/assistant.component.ts - 151 + 115 @@ -7888,36 +7888,12 @@ 150 - - Fee Ratio (legacy) - Stosunek opłat - - apps/client/src/app/pages/i18n/i18n-page.html - 152 - - - - The fees do exceed ${thresholdMax}% of your initial investment (${feeRatio}%) - Opłaty przekraczają ${thresholdMax}% początkowej inwestycji (${feeRatio}%) - - apps/client/src/app/pages/i18n/i18n-page.html - 154 - - - - The fees do not exceed ${thresholdMax}% of your initial investment (${feeRatio}%) - Opłaty nie przekraczają ${thresholdMax}% początkowej inwestycji (${feeRatio}%) - - apps/client/src/app/pages/i18n/i18n-page.html - 158 - - Fee Ratio Fee Ratio apps/client/src/app/pages/i18n/i18n-page.html - 161 + 152 @@ -7925,7 +7901,7 @@ The fees do exceed ${thresholdMax}% of your total investment volume (${feeRatio}%) apps/client/src/app/pages/i18n/i18n-page.html - 163 + 154 @@ -7933,7 +7909,7 @@ The fees do not exceed ${thresholdMax}% of your total investment volume (${feeRatio}%) apps/client/src/app/pages/i18n/i18n-page.html - 167 + 158 @@ -8103,7 +8079,7 @@ apps/client/src/app/pages/admin/admin-page.component.ts - 56 + 53 @@ -8392,7 +8368,7 @@ Fees apps/client/src/app/pages/i18n/i18n-page.html - 170 + 161 @@ -8440,7 +8416,7 @@ Regional Market Cluster Risks apps/client/src/app/pages/i18n/i18n-page.html - 172 + 163 @@ -8536,7 +8512,7 @@ Asia-Pacific apps/client/src/app/pages/i18n/i18n-page.html - 174 + 165 @@ -8544,7 +8520,7 @@ The Asia-Pacific market contribution of your current investment (${valueRatio}%) exceeds ${thresholdMax}% apps/client/src/app/pages/i18n/i18n-page.html - 176 + 167 @@ -8552,7 +8528,7 @@ The Asia-Pacific market contribution of your current investment (${valueRatio}%) is below ${thresholdMin}% apps/client/src/app/pages/i18n/i18n-page.html - 180 + 171 @@ -8560,7 +8536,7 @@ The Asia-Pacific market contribution of your current investment (${valueRatio}%) is within the range of ${thresholdMin}% and ${thresholdMax}% apps/client/src/app/pages/i18n/i18n-page.html - 184 + 175 @@ -8568,7 +8544,7 @@ Emerging Markets apps/client/src/app/pages/i18n/i18n-page.html - 189 + 180 @@ -8576,7 +8552,7 @@ The Emerging Markets contribution of your current investment (${valueRatio}%) exceeds ${thresholdMax}% apps/client/src/app/pages/i18n/i18n-page.html - 192 + 183 @@ -8584,7 +8560,7 @@ The Emerging Markets contribution of your current investment (${valueRatio}%) is below ${thresholdMin}% apps/client/src/app/pages/i18n/i18n-page.html - 196 + 187 @@ -8592,7 +8568,7 @@ The Emerging Markets contribution of your current investment (${valueRatio}%) is within the range of ${thresholdMin}% and ${thresholdMax}% apps/client/src/app/pages/i18n/i18n-page.html - 200 + 191 @@ -8600,7 +8576,7 @@ Europe apps/client/src/app/pages/i18n/i18n-page.html - 204 + 195 @@ -8608,7 +8584,7 @@ The Europe market contribution of your current investment (${valueRatio}%) exceeds ${thresholdMax}% apps/client/src/app/pages/i18n/i18n-page.html - 206 + 197 @@ -8616,7 +8592,7 @@ The Europe market contribution of your current investment (${valueRatio}%) is below ${thresholdMin}% apps/client/src/app/pages/i18n/i18n-page.html - 210 + 201 @@ -8624,7 +8600,7 @@ The Europe market contribution of your current investment (${valueRatio}%) is within the range of ${thresholdMin}% and ${thresholdMax}% apps/client/src/app/pages/i18n/i18n-page.html - 214 + 205 @@ -8632,7 +8608,7 @@ Japan apps/client/src/app/pages/i18n/i18n-page.html - 218 + 209 @@ -8640,7 +8616,7 @@ The Japan market contribution of your current investment (${valueRatio}%) exceeds ${thresholdMax}% apps/client/src/app/pages/i18n/i18n-page.html - 220 + 211 @@ -8648,7 +8624,7 @@ The Japan market contribution of your current investment (${valueRatio}%) is below ${thresholdMin}% apps/client/src/app/pages/i18n/i18n-page.html - 224 + 215 @@ -8656,7 +8632,7 @@ The Japan market contribution of your current investment (${valueRatio}%) is within the range of ${thresholdMin}% and ${thresholdMax}% apps/client/src/app/pages/i18n/i18n-page.html - 228 + 219 @@ -8664,7 +8640,7 @@ North America apps/client/src/app/pages/i18n/i18n-page.html - 232 + 223 @@ -8672,7 +8648,7 @@ The North America market contribution of your current investment (${valueRatio}%) exceeds ${thresholdMax}% apps/client/src/app/pages/i18n/i18n-page.html - 234 + 225 @@ -8680,7 +8656,7 @@ The North America market contribution of your current investment (${valueRatio}%) is below ${thresholdMin}% apps/client/src/app/pages/i18n/i18n-page.html - 238 + 229 @@ -8688,7 +8664,7 @@ The North America market contribution of your current investment (${valueRatio}%) is within the range of ${thresholdMin}% and ${thresholdMax}% apps/client/src/app/pages/i18n/i18n-page.html - 242 + 233 diff --git a/apps/client/src/locales/messages.pt.xlf b/apps/client/src/locales/messages.pt.xlf index 194922435..e49f13b96 100644 --- a/apps/client/src/locales/messages.pt.xlf +++ b/apps/client/src/locales/messages.pt.xlf @@ -142,7 +142,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 139 + 135 libs/ui/src/lib/accounts-table/accounts-table.component.html @@ -198,7 +198,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 145 + 141 libs/ui/src/lib/accounts-table/accounts-table.component.html @@ -234,15 +234,15 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 205 + 201 apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 208 + 204 apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 211 + 207 libs/ui/src/lib/account-balances/account-balances.component.html @@ -374,7 +374,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 155 + 151 libs/ui/src/lib/i18n.ts @@ -494,7 +494,7 @@ Data apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 161 + 157 libs/ui/src/lib/account-balances/account-balances.component.html @@ -942,7 +942,7 @@ Depósito libs/ui/src/lib/fire-calculator/fire-calculator.component.ts - 377 + 385 @@ -1102,7 +1102,7 @@ Poder de Compra apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 245 + 248 @@ -1110,7 +1110,7 @@ Excluído da Análise apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 271 + 274 @@ -1118,7 +1118,7 @@ Valor Líquido apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 321 + 324 @@ -1126,7 +1126,7 @@ Desempenho Anual apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 335 + 338 @@ -1162,7 +1162,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 189 + 185 libs/ui/src/lib/activities-table/activities-table.component.html @@ -1302,7 +1302,7 @@ libs/ui/src/lib/assistant/assistant.component.ts - 363 + 362 @@ -1314,7 +1314,7 @@ libs/ui/src/lib/assistant/assistant.component.ts - 375 + 374 @@ -1326,7 +1326,7 @@ libs/ui/src/lib/assistant/assistant.component.ts - 385 + 384 @@ -1338,7 +1338,7 @@ libs/ui/src/lib/assistant/assistant.component.ts - 409 + 408 @@ -1358,7 +1358,7 @@ libs/ui/src/lib/assistant/assistant.component.ts - 415 + 414 @@ -1890,7 +1890,7 @@ Como já tem sessão iniciada, não pode aceder à conta de demonstração. apps/client/src/app/pages/demo/demo-page.component.ts - 35 + 32 @@ -1954,11 +1954,11 @@ apps/client/src/app/pages/admin/admin-page.component.ts - 48 + 45 apps/client/src/app/pages/resources/resources-page.component.ts - 30 + 29 libs/common/src/lib/routes/routes.ts @@ -1998,7 +1998,7 @@ apps/client/src/app/pages/resources/resources-page.component.ts - 40 + 39 libs/common/src/lib/routes/routes.ts @@ -2122,7 +2122,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 124 + 120 @@ -2130,7 +2130,7 @@ Preço por Unidade apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 214 + 210 libs/ui/src/lib/activities-table/activities-table.component.html @@ -2150,7 +2150,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 275 + 271 @@ -2754,11 +2754,11 @@ apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 356 + 359 libs/ui/src/lib/fire-calculator/fire-calculator.component.ts - 387 + 395 libs/ui/src/lib/i18n.ts @@ -2770,7 +2770,7 @@ Poupanças libs/ui/src/lib/fire-calculator/fire-calculator.component.ts - 397 + 405 @@ -2814,7 +2814,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 290 + 286 libs/ui/src/lib/i18n.ts @@ -2898,7 +2898,7 @@ Dinheiro apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 216 + 219 libs/ui/src/lib/i18n.ts @@ -3198,7 +3198,7 @@ apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 369 + 372 apps/client/src/app/pages/features/features-page.html @@ -3206,7 +3206,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 202 + 198 apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts @@ -3246,7 +3246,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 309 + 305 libs/ui/src/lib/i18n.ts @@ -3902,7 +3902,7 @@ Atualizar saldo em Dinheiro apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 112 + 108 @@ -4082,7 +4082,7 @@ Responsabilidades apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 299 + 302 apps/client/src/app/pages/features/features-page.html @@ -4498,7 +4498,7 @@ Ativos apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 230 + 233 @@ -5444,7 +5444,7 @@ Taxa apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 262 + 258 libs/ui/src/lib/activities-table/activities-table.component.html @@ -5652,7 +5652,7 @@ Software de gerenciamento de patrimônio de código aberto apps/client/src/app/pages/i18n/i18n-page.html - 246 + 237 @@ -5752,7 +5752,7 @@ Você realmente deseja excluir o saldo desta conta? libs/ui/src/lib/account-balances/account-balances.component.ts - 120 + 113 @@ -5928,7 +5928,7 @@ Semana até agora libs/ui/src/lib/assistant/assistant.component.ts - 367 + 366 @@ -5940,7 +5940,7 @@ libs/ui/src/lib/assistant/assistant.component.ts - 367 + 366 @@ -5948,7 +5948,7 @@ Do mês até a data libs/ui/src/lib/assistant/assistant.component.ts - 371 + 370 @@ -5960,7 +5960,7 @@ libs/ui/src/lib/assistant/assistant.component.ts - 371 + 370 @@ -5968,7 +5968,7 @@ No acumulado do ano libs/ui/src/lib/assistant/assistant.component.ts - 375 + 374 @@ -6016,7 +6016,7 @@ libs/ui/src/lib/assistant/assistant.component.ts - 385 + 384 @@ -6028,7 +6028,7 @@ libs/ui/src/lib/assistant/assistant.component.ts - 409 + 408 @@ -6757,7 +6757,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 345 + 341 apps/client/src/app/pages/register/user-account-registration-dialog/user-account-registration-dialog.html @@ -6813,7 +6813,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 347 + 343 libs/ui/src/lib/i18n.ts @@ -7117,7 +7117,7 @@ apps/client/src/app/pages/resources/resources-page.component.ts - 45 + 44 libs/common/src/lib/routes/routes.ts @@ -7133,7 +7133,7 @@ apps/client/src/app/pages/resources/resources-page.component.ts - 34 + 33 libs/common/src/lib/routes/routes.ts @@ -7339,7 +7339,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 356 + 352 libs/ui/src/lib/historical-market-data-editor/historical-market-data-editor-dialog/historical-market-data-editor-dialog.html @@ -7643,7 +7643,7 @@ Find account, holding or page... libs/ui/src/lib/assistant/assistant.component.ts - 151 + 115 @@ -7888,36 +7888,12 @@ 150 - - Fee Ratio (legacy) - Fee Ratio (legacy) - - apps/client/src/app/pages/i18n/i18n-page.html - 152 - - - - The fees do exceed ${thresholdMax}% of your initial investment (${feeRatio}%) - The fees do exceed ${thresholdMax}% of your initial investment (${feeRatio}%) - - apps/client/src/app/pages/i18n/i18n-page.html - 154 - - - - The fees do not exceed ${thresholdMax}% of your initial investment (${feeRatio}%) - The fees do not exceed ${thresholdMax}% of your initial investment (${feeRatio}%) - - apps/client/src/app/pages/i18n/i18n-page.html - 158 - - Fee Ratio Fee Ratio apps/client/src/app/pages/i18n/i18n-page.html - 161 + 152 @@ -7925,7 +7901,7 @@ The fees do exceed ${thresholdMax}% of your total investment volume (${feeRatio}%) apps/client/src/app/pages/i18n/i18n-page.html - 163 + 154 @@ -7933,7 +7909,7 @@ The fees do not exceed ${thresholdMax}% of your total investment volume (${feeRatio}%) apps/client/src/app/pages/i18n/i18n-page.html - 167 + 158 @@ -8103,7 +8079,7 @@ apps/client/src/app/pages/admin/admin-page.component.ts - 56 + 53 @@ -8392,7 +8368,7 @@ Tarifas apps/client/src/app/pages/i18n/i18n-page.html - 170 + 161 @@ -8440,7 +8416,7 @@ Riscos de cluster de mercado regional apps/client/src/app/pages/i18n/i18n-page.html - 172 + 163 @@ -8536,7 +8512,7 @@ Ásia-Pacífico apps/client/src/app/pages/i18n/i18n-page.html - 174 + 165 @@ -8544,7 +8520,7 @@ The Asia-Pacific market contribution of your current investment (${valueRatio}%) exceeds ${thresholdMax}% apps/client/src/app/pages/i18n/i18n-page.html - 176 + 167 @@ -8552,7 +8528,7 @@ The Asia-Pacific market contribution of your current investment (${valueRatio}%) is below ${thresholdMin}% apps/client/src/app/pages/i18n/i18n-page.html - 180 + 171 @@ -8560,7 +8536,7 @@ The Asia-Pacific market contribution of your current investment (${valueRatio}%) is within the range of ${thresholdMin}% and ${thresholdMax}% apps/client/src/app/pages/i18n/i18n-page.html - 184 + 175 @@ -8568,7 +8544,7 @@ Mercados Emergentes apps/client/src/app/pages/i18n/i18n-page.html - 189 + 180 @@ -8576,7 +8552,7 @@ The Emerging Markets contribution of your current investment (${valueRatio}%) exceeds ${thresholdMax}% apps/client/src/app/pages/i18n/i18n-page.html - 192 + 183 @@ -8584,7 +8560,7 @@ The Emerging Markets contribution of your current investment (${valueRatio}%) is below ${thresholdMin}% apps/client/src/app/pages/i18n/i18n-page.html - 196 + 187 @@ -8592,7 +8568,7 @@ The Emerging Markets contribution of your current investment (${valueRatio}%) is within the range of ${thresholdMin}% and ${thresholdMax}% apps/client/src/app/pages/i18n/i18n-page.html - 200 + 191 @@ -8600,7 +8576,7 @@ Europa apps/client/src/app/pages/i18n/i18n-page.html - 204 + 195 @@ -8608,7 +8584,7 @@ The Europe market contribution of your current investment (${valueRatio}%) exceeds ${thresholdMax}% apps/client/src/app/pages/i18n/i18n-page.html - 206 + 197 @@ -8616,7 +8592,7 @@ The Europe market contribution of your current investment (${valueRatio}%) is below ${thresholdMin}% apps/client/src/app/pages/i18n/i18n-page.html - 210 + 201 @@ -8624,7 +8600,7 @@ The Europe market contribution of your current investment (${valueRatio}%) is within the range of ${thresholdMin}% and ${thresholdMax}% apps/client/src/app/pages/i18n/i18n-page.html - 214 + 205 @@ -8632,7 +8608,7 @@ Japão apps/client/src/app/pages/i18n/i18n-page.html - 218 + 209 @@ -8640,7 +8616,7 @@ The Japan market contribution of your current investment (${valueRatio}%) exceeds ${thresholdMax}% apps/client/src/app/pages/i18n/i18n-page.html - 220 + 211 @@ -8648,7 +8624,7 @@ The Japan market contribution of your current investment (${valueRatio}%) is below ${thresholdMin}% apps/client/src/app/pages/i18n/i18n-page.html - 224 + 215 @@ -8656,7 +8632,7 @@ The Japan market contribution of your current investment (${valueRatio}%) is within the range of ${thresholdMin}% and ${thresholdMax}% apps/client/src/app/pages/i18n/i18n-page.html - 228 + 219 @@ -8664,7 +8640,7 @@ América do Norte apps/client/src/app/pages/i18n/i18n-page.html - 232 + 223 @@ -8672,7 +8648,7 @@ The North America market contribution of your current investment (${valueRatio}%) exceeds ${thresholdMax}% apps/client/src/app/pages/i18n/i18n-page.html - 234 + 225 @@ -8680,7 +8656,7 @@ The North America market contribution of your current investment (${valueRatio}%) is below ${thresholdMin}% apps/client/src/app/pages/i18n/i18n-page.html - 238 + 229 @@ -8688,7 +8664,7 @@ The North America market contribution of your current investment (${valueRatio}%) is within the range of ${thresholdMin}% and ${thresholdMax}% apps/client/src/app/pages/i18n/i18n-page.html - 242 + 233 diff --git a/apps/client/src/locales/messages.tr.xlf b/apps/client/src/locales/messages.tr.xlf index a7b86f624..abe33aa80 100644 --- a/apps/client/src/locales/messages.tr.xlf +++ b/apps/client/src/locales/messages.tr.xlf @@ -339,7 +339,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 139 + 135 libs/ui/src/lib/accounts-table/accounts-table.component.html @@ -395,7 +395,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 145 + 141 libs/ui/src/lib/accounts-table/accounts-table.component.html @@ -415,15 +415,15 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 205 + 201 apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 208 + 204 apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 211 + 207 libs/ui/src/lib/account-balances/account-balances.component.html @@ -555,7 +555,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 155 + 151 libs/ui/src/lib/i18n.ts @@ -675,7 +675,7 @@ Tarih apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 161 + 157 libs/ui/src/lib/account-balances/account-balances.component.html @@ -923,7 +923,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 275 + 271 @@ -951,7 +951,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 124 + 120 @@ -1679,7 +1679,7 @@ Varlıklar apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 230 + 233 @@ -1687,7 +1687,7 @@ Alım Limiti apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 245 + 248 @@ -1695,7 +1695,7 @@ Analize Dahil Edilmemiştir. apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 271 + 274 @@ -1703,7 +1703,7 @@ Yükümlülükler apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 299 + 302 apps/client/src/app/pages/features/features-page.html @@ -1715,7 +1715,7 @@ Toplam Varlık apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 321 + 324 @@ -1723,7 +1723,7 @@ Yıllıklandırılmış Performans apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 335 + 338 @@ -1759,7 +1759,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 189 + 185 libs/ui/src/lib/activities-table/activities-table.component.html @@ -1967,7 +1967,7 @@ libs/ui/src/lib/assistant/assistant.component.ts - 363 + 362 @@ -1979,7 +1979,7 @@ libs/ui/src/lib/assistant/assistant.component.ts - 375 + 374 @@ -1991,7 +1991,7 @@ libs/ui/src/lib/assistant/assistant.component.ts - 385 + 384 @@ -2003,7 +2003,7 @@ libs/ui/src/lib/assistant/assistant.component.ts - 409 + 408 @@ -2023,7 +2023,7 @@ libs/ui/src/lib/assistant/assistant.component.ts - 415 + 414 @@ -2319,11 +2319,11 @@ apps/client/src/app/pages/admin/admin-page.component.ts - 48 + 45 apps/client/src/app/pages/resources/resources-page.component.ts - 30 + 29 libs/common/src/lib/routes/routes.ts @@ -2467,7 +2467,7 @@ Oturum açmış olduğunuz için demo hesabına erişemezsiniz. apps/client/src/app/pages/demo/demo-page.component.ts - 35 + 32 @@ -2727,7 +2727,7 @@ apps/client/src/app/pages/resources/resources-page.component.ts - 40 + 39 libs/common/src/lib/routes/routes.ts @@ -3207,7 +3207,7 @@ Nakit Bakiyesini Güncelle apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 112 + 108 @@ -3215,7 +3215,7 @@ Birim Fiyat apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 214 + 210 libs/ui/src/lib/activities-table/activities-table.component.html @@ -3579,7 +3579,7 @@ apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 369 + 372 apps/client/src/app/pages/features/features-page.html @@ -3587,7 +3587,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 202 + 198 apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts @@ -3611,7 +3611,7 @@ Para Yatırma libs/ui/src/lib/fire-calculator/fire-calculator.component.ts - 377 + 385 @@ -4744,11 +4744,11 @@ apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 356 + 359 libs/ui/src/lib/fire-calculator/fire-calculator.component.ts - 387 + 395 libs/ui/src/lib/i18n.ts @@ -4760,7 +4760,7 @@ Tasarruflar libs/ui/src/lib/fire-calculator/fire-calculator.component.ts - 397 + 405 @@ -4840,7 +4840,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 290 + 286 libs/ui/src/lib/i18n.ts @@ -4872,7 +4872,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 309 + 305 libs/ui/src/lib/i18n.ts @@ -5156,7 +5156,7 @@ Nakit apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 216 + 219 libs/ui/src/lib/i18n.ts @@ -5452,7 +5452,7 @@ Ücret apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 262 + 258 libs/ui/src/lib/activities-table/activities-table.component.html @@ -5652,7 +5652,7 @@ Açık Kaynak Varlık Yönetim Yazılımı apps/client/src/app/pages/i18n/i18n-page.html - 246 + 237 @@ -5752,7 +5752,7 @@ Bu nakit bakiyesini silmeyi gerçekten istiyor musunuz? libs/ui/src/lib/account-balances/account-balances.component.ts - 120 + 113 @@ -5928,7 +5928,7 @@ Hafta içi libs/ui/src/lib/assistant/assistant.component.ts - 367 + 366 @@ -5940,7 +5940,7 @@ libs/ui/src/lib/assistant/assistant.component.ts - 367 + 366 @@ -5948,7 +5948,7 @@ Ay içi libs/ui/src/lib/assistant/assistant.component.ts - 371 + 370 @@ -5960,7 +5960,7 @@ libs/ui/src/lib/assistant/assistant.component.ts - 371 + 370 @@ -5968,7 +5968,7 @@ Yıl içi libs/ui/src/lib/assistant/assistant.component.ts - 375 + 374 @@ -6016,7 +6016,7 @@ libs/ui/src/lib/assistant/assistant.component.ts - 385 + 384 @@ -6028,7 +6028,7 @@ libs/ui/src/lib/assistant/assistant.component.ts - 409 + 408 @@ -6757,7 +6757,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 345 + 341 apps/client/src/app/pages/register/user-account-registration-dialog/user-account-registration-dialog.html @@ -6813,7 +6813,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 347 + 343 libs/ui/src/lib/i18n.ts @@ -7117,7 +7117,7 @@ apps/client/src/app/pages/resources/resources-page.component.ts - 45 + 44 libs/common/src/lib/routes/routes.ts @@ -7133,7 +7133,7 @@ apps/client/src/app/pages/resources/resources-page.component.ts - 34 + 33 libs/common/src/lib/routes/routes.ts @@ -7339,7 +7339,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 356 + 352 libs/ui/src/lib/historical-market-data-editor/historical-market-data-editor-dialog/historical-market-data-editor-dialog.html @@ -7643,7 +7643,7 @@ Find account, holding or page... libs/ui/src/lib/assistant/assistant.component.ts - 151 + 115 @@ -7888,36 +7888,12 @@ 150 - - Fee Ratio (legacy) - Ücret Oranı - - apps/client/src/app/pages/i18n/i18n-page.html - 152 - - - - The fees do exceed ${thresholdMax}% of your initial investment (${feeRatio}%) - Ücretler, ilk yatırımınızın %${thresholdMax} kadarını aşıyor (${feeRatio}%) - - apps/client/src/app/pages/i18n/i18n-page.html - 154 - - - - The fees do not exceed ${thresholdMax}% of your initial investment (${feeRatio}%) - Ücretler, ilk yatırımınızın %${thresholdMax}’ını (${feeRatio}%) aşmaz - - apps/client/src/app/pages/i18n/i18n-page.html - 158 - - Fee Ratio Fee Ratio apps/client/src/app/pages/i18n/i18n-page.html - 161 + 152 @@ -7925,7 +7901,7 @@ The fees do exceed ${thresholdMax}% of your total investment volume (${feeRatio}%) apps/client/src/app/pages/i18n/i18n-page.html - 163 + 154 @@ -7933,7 +7909,7 @@ The fees do not exceed ${thresholdMax}% of your total investment volume (${feeRatio}%) apps/client/src/app/pages/i18n/i18n-page.html - 167 + 158 @@ -8103,7 +8079,7 @@ apps/client/src/app/pages/admin/admin-page.component.ts - 56 + 53 @@ -8392,7 +8368,7 @@ Fees apps/client/src/app/pages/i18n/i18n-page.html - 170 + 161 @@ -8440,7 +8416,7 @@ Regional Market Cluster Risks apps/client/src/app/pages/i18n/i18n-page.html - 172 + 163 @@ -8536,7 +8512,7 @@ Asya-Pasifik apps/client/src/app/pages/i18n/i18n-page.html - 174 + 165 @@ -8544,7 +8520,7 @@ The Asia-Pacific market contribution of your current investment (${valueRatio}%) exceeds ${thresholdMax}% apps/client/src/app/pages/i18n/i18n-page.html - 176 + 167 @@ -8552,7 +8528,7 @@ The Asia-Pacific market contribution of your current investment (${valueRatio}%) is below ${thresholdMin}% apps/client/src/app/pages/i18n/i18n-page.html - 180 + 171 @@ -8560,7 +8536,7 @@ The Asia-Pacific market contribution of your current investment (${valueRatio}%) is within the range of ${thresholdMin}% and ${thresholdMax}% apps/client/src/app/pages/i18n/i18n-page.html - 184 + 175 @@ -8568,7 +8544,7 @@ Gelişmekte Olan Piyasalar apps/client/src/app/pages/i18n/i18n-page.html - 189 + 180 @@ -8576,7 +8552,7 @@ The Emerging Markets contribution of your current investment (${valueRatio}%) exceeds ${thresholdMax}% apps/client/src/app/pages/i18n/i18n-page.html - 192 + 183 @@ -8584,7 +8560,7 @@ The Emerging Markets contribution of your current investment (${valueRatio}%) is below ${thresholdMin}% apps/client/src/app/pages/i18n/i18n-page.html - 196 + 187 @@ -8592,7 +8568,7 @@ The Emerging Markets contribution of your current investment (${valueRatio}%) is within the range of ${thresholdMin}% and ${thresholdMax}% apps/client/src/app/pages/i18n/i18n-page.html - 200 + 191 @@ -8600,7 +8576,7 @@ Avrupa apps/client/src/app/pages/i18n/i18n-page.html - 204 + 195 @@ -8608,7 +8584,7 @@ The Europe market contribution of your current investment (${valueRatio}%) exceeds ${thresholdMax}% apps/client/src/app/pages/i18n/i18n-page.html - 206 + 197 @@ -8616,7 +8592,7 @@ The Europe market contribution of your current investment (${valueRatio}%) is below ${thresholdMin}% apps/client/src/app/pages/i18n/i18n-page.html - 210 + 201 @@ -8624,7 +8600,7 @@ The Europe market contribution of your current investment (${valueRatio}%) is within the range of ${thresholdMin}% and ${thresholdMax}% apps/client/src/app/pages/i18n/i18n-page.html - 214 + 205 @@ -8632,7 +8608,7 @@ Japonya apps/client/src/app/pages/i18n/i18n-page.html - 218 + 209 @@ -8640,7 +8616,7 @@ The Japan market contribution of your current investment (${valueRatio}%) exceeds ${thresholdMax}% apps/client/src/app/pages/i18n/i18n-page.html - 220 + 211 @@ -8648,7 +8624,7 @@ The Japan market contribution of your current investment (${valueRatio}%) is below ${thresholdMin}% apps/client/src/app/pages/i18n/i18n-page.html - 224 + 215 @@ -8656,7 +8632,7 @@ The Japan market contribution of your current investment (${valueRatio}%) is within the range of ${thresholdMin}% and ${thresholdMax}% apps/client/src/app/pages/i18n/i18n-page.html - 228 + 219 @@ -8664,7 +8640,7 @@ Kuzey Amerika apps/client/src/app/pages/i18n/i18n-page.html - 232 + 223 @@ -8672,7 +8648,7 @@ The North America market contribution of your current investment (${valueRatio}%) exceeds ${thresholdMax}% apps/client/src/app/pages/i18n/i18n-page.html - 234 + 225 @@ -8680,7 +8656,7 @@ The North America market contribution of your current investment (${valueRatio}%) is below ${thresholdMin}% apps/client/src/app/pages/i18n/i18n-page.html - 238 + 229 @@ -8688,7 +8664,7 @@ The North America market contribution of your current investment (${valueRatio}%) is within the range of ${thresholdMin}% and ${thresholdMax}% apps/client/src/app/pages/i18n/i18n-page.html - 242 + 233 diff --git a/apps/client/src/locales/messages.uk.xlf b/apps/client/src/locales/messages.uk.xlf index 61cebd47a..95ad50c7c 100644 --- a/apps/client/src/locales/messages.uk.xlf +++ b/apps/client/src/locales/messages.uk.xlf @@ -471,7 +471,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 139 + 135 libs/ui/src/lib/accounts-table/accounts-table.component.html @@ -527,7 +527,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 145 + 141 libs/ui/src/lib/accounts-table/accounts-table.component.html @@ -547,15 +547,15 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 205 + 201 apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 208 + 204 apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 211 + 207 libs/ui/src/lib/account-balances/account-balances.component.html @@ -735,7 +735,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 155 + 151 libs/ui/src/lib/i18n.ts @@ -1159,7 +1159,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 275 + 271 @@ -1211,7 +1211,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 124 + 120 @@ -1855,7 +1855,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 189 + 185 libs/ui/src/lib/activities-table/activities-table.component.html @@ -2231,7 +2231,7 @@ Активи apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 230 + 233 @@ -2239,7 +2239,7 @@ Купівельна спроможність apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 245 + 248 @@ -2247,7 +2247,7 @@ Виключено з аналізу apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 271 + 274 @@ -2255,7 +2255,7 @@ Зобов’язання apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 299 + 302 apps/client/src/app/pages/features/features-page.html @@ -2267,7 +2267,7 @@ Чиста вартість apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 321 + 324 @@ -2275,7 +2275,7 @@ Річна доходність apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 335 + 338 @@ -2319,7 +2319,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 356 + 352 libs/ui/src/lib/historical-market-data-editor/historical-market-data-editor-dialog/historical-market-data-editor-dialog.html @@ -2555,7 +2555,7 @@ libs/ui/src/lib/assistant/assistant.component.ts - 363 + 362 @@ -2567,7 +2567,7 @@ libs/ui/src/lib/assistant/assistant.component.ts - 375 + 374 @@ -2579,7 +2579,7 @@ libs/ui/src/lib/assistant/assistant.component.ts - 385 + 384 @@ -2591,7 +2591,7 @@ libs/ui/src/lib/assistant/assistant.component.ts - 409 + 408 @@ -2611,7 +2611,7 @@ libs/ui/src/lib/assistant/assistant.component.ts - 415 + 414 @@ -3367,11 +3367,11 @@ apps/client/src/app/pages/admin/admin-page.component.ts - 48 + 45 apps/client/src/app/pages/resources/resources-page.component.ts - 30 + 29 libs/common/src/lib/routes/routes.ts @@ -3523,7 +3523,7 @@ Оскільки ви вже ввійшли, ви не можете отримати доступ до демонстраційного обліковий запис. apps/client/src/app/pages/demo/demo-page.component.ts - 35 + 32 @@ -3796,7 +3796,7 @@ apps/client/src/app/pages/resources/resources-page.component.ts - 40 + 39 libs/common/src/lib/routes/routes.ts @@ -3844,7 +3844,7 @@ Програмне забезпечення управління багатством з відкритим кодом apps/client/src/app/pages/i18n/i18n-page.html - 246 + 237 @@ -4384,7 +4384,7 @@ Оновити баланс готівки apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 112 + 108 @@ -4392,7 +4392,7 @@ Дата apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 161 + 157 libs/ui/src/lib/account-balances/account-balances.component.html @@ -4412,7 +4412,7 @@ Ціна за одиницю apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 214 + 210 libs/ui/src/lib/activities-table/activities-table.component.html @@ -4800,7 +4800,7 @@ apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 369 + 372 apps/client/src/app/pages/features/features-page.html @@ -4808,7 +4808,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 202 + 198 apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts @@ -5316,7 +5316,7 @@ apps/client/src/app/pages/resources/resources-page.component.ts - 45 + 44 libs/common/src/lib/routes/routes.ts @@ -5332,7 +5332,7 @@ apps/client/src/app/pages/resources/resources-page.component.ts - 34 + 33 libs/common/src/lib/routes/routes.ts @@ -6075,7 +6075,7 @@ Ви дійсно хочете видалити цей рахунок? libs/ui/src/lib/account-balances/account-balances.component.ts - 120 + 113 @@ -6155,7 +6155,7 @@ Тиждень до дати libs/ui/src/lib/assistant/assistant.component.ts - 367 + 366 @@ -6167,7 +6167,7 @@ libs/ui/src/lib/assistant/assistant.component.ts - 367 + 366 @@ -6175,7 +6175,7 @@ Місяць до дати libs/ui/src/lib/assistant/assistant.component.ts - 371 + 370 @@ -6187,7 +6187,7 @@ libs/ui/src/lib/assistant/assistant.component.ts - 371 + 370 @@ -6195,7 +6195,7 @@ Рік до дати libs/ui/src/lib/assistant/assistant.component.ts - 375 + 374 @@ -6215,7 +6215,7 @@ libs/ui/src/lib/assistant/assistant.component.ts - 385 + 384 @@ -6227,7 +6227,7 @@ libs/ui/src/lib/assistant/assistant.component.ts - 409 + 408 @@ -6375,7 +6375,7 @@ Депозит libs/ui/src/lib/fire-calculator/fire-calculator.component.ts - 377 + 385 @@ -6387,11 +6387,11 @@ apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 356 + 359 libs/ui/src/lib/fire-calculator/fire-calculator.component.ts - 387 + 395 libs/ui/src/lib/i18n.ts @@ -6403,7 +6403,7 @@ Заощадження libs/ui/src/lib/fire-calculator/fire-calculator.component.ts - 397 + 405 @@ -6499,7 +6499,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 290 + 286 libs/ui/src/lib/i18n.ts @@ -6531,7 +6531,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 309 + 305 libs/ui/src/lib/i18n.ts @@ -6587,7 +6587,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 345 + 341 apps/client/src/app/pages/register/user-account-registration-dialog/user-account-registration-dialog.html @@ -6651,7 +6651,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 347 + 343 libs/ui/src/lib/i18n.ts @@ -6915,7 +6915,7 @@ Комісія apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 262 + 258 libs/ui/src/lib/activities-table/activities-table.component.html @@ -6959,7 +6959,7 @@ Готівка apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 216 + 219 libs/ui/src/lib/i18n.ts @@ -7643,7 +7643,7 @@ Find account, holding or page... libs/ui/src/lib/assistant/assistant.component.ts - 151 + 115 @@ -7888,36 +7888,12 @@ 150 - - Fee Ratio (legacy) - Fee Ratio (legacy) - - apps/client/src/app/pages/i18n/i18n-page.html - 152 - - - - The fees do exceed ${thresholdMax}% of your initial investment (${feeRatio}%) - The fees do exceed ${thresholdMax}% of your initial investment (${feeRatio}%) - - apps/client/src/app/pages/i18n/i18n-page.html - 154 - - - - The fees do not exceed ${thresholdMax}% of your initial investment (${feeRatio}%) - The fees do not exceed ${thresholdMax}% of your initial investment (${feeRatio}%) - - apps/client/src/app/pages/i18n/i18n-page.html - 158 - - Fee Ratio Fee Ratio apps/client/src/app/pages/i18n/i18n-page.html - 161 + 152 @@ -7925,7 +7901,7 @@ The fees do exceed ${thresholdMax}% of your total investment volume (${feeRatio}%) apps/client/src/app/pages/i18n/i18n-page.html - 163 + 154 @@ -7933,7 +7909,7 @@ The fees do not exceed ${thresholdMax}% of your total investment volume (${feeRatio}%) apps/client/src/app/pages/i18n/i18n-page.html - 167 + 158 @@ -8103,7 +8079,7 @@ apps/client/src/app/pages/admin/admin-page.component.ts - 56 + 53 @@ -8392,7 +8368,7 @@ Fees apps/client/src/app/pages/i18n/i18n-page.html - 170 + 161 @@ -8440,7 +8416,7 @@ Regional Market Cluster Risks apps/client/src/app/pages/i18n/i18n-page.html - 172 + 163 @@ -8536,7 +8512,7 @@ Asia-Pacific apps/client/src/app/pages/i18n/i18n-page.html - 174 + 165 @@ -8544,7 +8520,7 @@ The Asia-Pacific market contribution of your current investment (${valueRatio}%) exceeds ${thresholdMax}% apps/client/src/app/pages/i18n/i18n-page.html - 176 + 167 @@ -8552,7 +8528,7 @@ The Asia-Pacific market contribution of your current investment (${valueRatio}%) is below ${thresholdMin}% apps/client/src/app/pages/i18n/i18n-page.html - 180 + 171 @@ -8560,7 +8536,7 @@ The Asia-Pacific market contribution of your current investment (${valueRatio}%) is within the range of ${thresholdMin}% and ${thresholdMax}% apps/client/src/app/pages/i18n/i18n-page.html - 184 + 175 @@ -8568,7 +8544,7 @@ Emerging Markets apps/client/src/app/pages/i18n/i18n-page.html - 189 + 180 @@ -8576,7 +8552,7 @@ The Emerging Markets contribution of your current investment (${valueRatio}%) exceeds ${thresholdMax}% apps/client/src/app/pages/i18n/i18n-page.html - 192 + 183 @@ -8584,7 +8560,7 @@ The Emerging Markets contribution of your current investment (${valueRatio}%) is below ${thresholdMin}% apps/client/src/app/pages/i18n/i18n-page.html - 196 + 187 @@ -8592,7 +8568,7 @@ The Emerging Markets contribution of your current investment (${valueRatio}%) is within the range of ${thresholdMin}% and ${thresholdMax}% apps/client/src/app/pages/i18n/i18n-page.html - 200 + 191 @@ -8600,7 +8576,7 @@ Europe apps/client/src/app/pages/i18n/i18n-page.html - 204 + 195 @@ -8608,7 +8584,7 @@ The Europe market contribution of your current investment (${valueRatio}%) exceeds ${thresholdMax}% apps/client/src/app/pages/i18n/i18n-page.html - 206 + 197 @@ -8616,7 +8592,7 @@ The Europe market contribution of your current investment (${valueRatio}%) is below ${thresholdMin}% apps/client/src/app/pages/i18n/i18n-page.html - 210 + 201 @@ -8624,7 +8600,7 @@ The Europe market contribution of your current investment (${valueRatio}%) is within the range of ${thresholdMin}% and ${thresholdMax}% apps/client/src/app/pages/i18n/i18n-page.html - 214 + 205 @@ -8632,7 +8608,7 @@ Japan apps/client/src/app/pages/i18n/i18n-page.html - 218 + 209 @@ -8640,7 +8616,7 @@ The Japan market contribution of your current investment (${valueRatio}%) exceeds ${thresholdMax}% apps/client/src/app/pages/i18n/i18n-page.html - 220 + 211 @@ -8648,7 +8624,7 @@ The Japan market contribution of your current investment (${valueRatio}%) is below ${thresholdMin}% apps/client/src/app/pages/i18n/i18n-page.html - 224 + 215 @@ -8656,7 +8632,7 @@ The Japan market contribution of your current investment (${valueRatio}%) is within the range of ${thresholdMin}% and ${thresholdMax}% apps/client/src/app/pages/i18n/i18n-page.html - 228 + 219 @@ -8664,7 +8640,7 @@ North America apps/client/src/app/pages/i18n/i18n-page.html - 232 + 223 @@ -8672,7 +8648,7 @@ The North America market contribution of your current investment (${valueRatio}%) exceeds ${thresholdMax}% apps/client/src/app/pages/i18n/i18n-page.html - 234 + 225 @@ -8680,7 +8656,7 @@ The North America market contribution of your current investment (${valueRatio}%) is below ${thresholdMin}% apps/client/src/app/pages/i18n/i18n-page.html - 238 + 229 @@ -8688,7 +8664,7 @@ The North America market contribution of your current investment (${valueRatio}%) is within the range of ${thresholdMin}% and ${thresholdMax}% apps/client/src/app/pages/i18n/i18n-page.html - 242 + 233 diff --git a/apps/client/src/locales/messages.xlf b/apps/client/src/locales/messages.xlf index 03644820a..b6a54edfe 100644 --- a/apps/client/src/locales/messages.xlf +++ b/apps/client/src/locales/messages.xlf @@ -362,7 +362,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 139 + 135 libs/ui/src/lib/accounts-table/accounts-table.component.html @@ -416,7 +416,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 145 + 141 libs/ui/src/lib/accounts-table/accounts-table.component.html @@ -435,15 +435,15 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 205 + 201 apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 208 + 204 apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 211 + 207 libs/ui/src/lib/account-balances/account-balances.component.html @@ -589,7 +589,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 155 + 151 libs/ui/src/lib/i18n.ts @@ -674,7 +674,7 @@ Date apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 161 + 157 libs/ui/src/lib/account-balances/account-balances.component.html @@ -952,7 +952,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 275 + 271 @@ -992,7 +992,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 124 + 120 @@ -1704,28 +1704,28 @@ Assets apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 230 + 233 Buying Power apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 245 + 248 Excluded from Analysis apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 271 + 274 Liabilities apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 299 + 302 apps/client/src/app/pages/features/features-page.html @@ -1736,14 +1736,14 @@ Net Worth apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 321 + 324 Annualized Performance apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 335 + 338 @@ -1775,7 +1775,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 189 + 185 libs/ui/src/lib/activities-table/activities-table.component.html @@ -1958,7 +1958,7 @@ libs/ui/src/lib/assistant/assistant.component.ts - 363 + 362 @@ -1969,7 +1969,7 @@ libs/ui/src/lib/assistant/assistant.component.ts - 375 + 374 @@ -1980,7 +1980,7 @@ libs/ui/src/lib/assistant/assistant.component.ts - 385 + 384 @@ -1991,7 +1991,7 @@ libs/ui/src/lib/assistant/assistant.component.ts - 409 + 408 @@ -2009,7 +2009,7 @@ libs/ui/src/lib/assistant/assistant.component.ts - 415 + 414 @@ -2554,11 +2554,11 @@ apps/client/src/app/pages/admin/admin-page.component.ts - 48 + 45 apps/client/src/app/pages/resources/resources-page.component.ts - 30 + 29 libs/common/src/lib/routes/routes.ts @@ -2698,7 +2698,7 @@ As you are already logged in, you cannot access the demo account. apps/client/src/app/pages/demo/demo-page.component.ts - 35 + 32 @@ -2927,7 +2927,7 @@ apps/client/src/app/pages/resources/resources-page.component.ts - 40 + 39 libs/common/src/lib/routes/routes.ts @@ -2964,7 +2964,7 @@ Open Source Wealth Management Software apps/client/src/app/pages/i18n/i18n-page.html - 246 + 237 @@ -3451,14 +3451,14 @@ Update Cash Balance apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 112 + 108 Unit Price apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 214 + 210 libs/ui/src/lib/activities-table/activities-table.component.html @@ -3778,7 +3778,7 @@ apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 369 + 372 apps/client/src/app/pages/features/features-page.html @@ -3786,7 +3786,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 202 + 198 apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts @@ -3808,7 +3808,7 @@ Deposit libs/ui/src/lib/fire-calculator/fire-calculator.component.ts - 377 + 385 @@ -4513,7 +4513,7 @@ Do you really want to delete this account balance? libs/ui/src/lib/account-balances/account-balances.component.ts - 120 + 113 @@ -4669,11 +4669,11 @@ apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 356 + 359 libs/ui/src/lib/fire-calculator/fire-calculator.component.ts - 387 + 395 libs/ui/src/lib/i18n.ts @@ -4684,7 +4684,7 @@ Savings libs/ui/src/lib/fire-calculator/fire-calculator.component.ts - 397 + 405 @@ -4759,7 +4759,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 290 + 286 libs/ui/src/lib/i18n.ts @@ -4790,7 +4790,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 309 + 305 libs/ui/src/lib/i18n.ts @@ -5013,7 +5013,7 @@ Fee apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 262 + 258 libs/ui/src/lib/activities-table/activities-table.component.html @@ -5053,7 +5053,7 @@ Cash apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 216 + 219 libs/ui/src/lib/i18n.ts @@ -5417,21 +5417,21 @@ Year to date libs/ui/src/lib/assistant/assistant.component.ts - 375 + 374 Week to date libs/ui/src/lib/assistant/assistant.component.ts - 367 + 366 Month to date libs/ui/src/lib/assistant/assistant.component.ts - 371 + 370 @@ -5442,7 +5442,7 @@ libs/ui/src/lib/assistant/assistant.component.ts - 371 + 370 @@ -5453,7 +5453,7 @@ libs/ui/src/lib/assistant/assistant.component.ts - 367 + 366 @@ -5497,7 +5497,7 @@ libs/ui/src/lib/assistant/assistant.component.ts - 385 + 384 @@ -5508,7 +5508,7 @@ libs/ui/src/lib/assistant/assistant.component.ts - 409 + 408 @@ -6125,7 +6125,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 345 + 341 apps/client/src/app/pages/register/user-account-registration-dialog/user-account-registration-dialog.html @@ -6208,7 +6208,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 347 + 343 libs/ui/src/lib/i18n.ts @@ -6486,7 +6486,7 @@ apps/client/src/app/pages/resources/resources-page.component.ts - 45 + 44 libs/common/src/lib/routes/routes.ts @@ -6513,7 +6513,7 @@ apps/client/src/app/pages/resources/resources-page.component.ts - 34 + 33 libs/common/src/lib/routes/routes.ts @@ -6688,7 +6688,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 356 + 352 libs/ui/src/lib/historical-market-data-editor/historical-market-data-editor-dialog/historical-market-data-editor-dialog.html @@ -6947,7 +6947,7 @@ Find account, holding or page... libs/ui/src/lib/assistant/assistant.component.ts - 151 + 115 @@ -7155,46 +7155,25 @@ 150 - - Fee Ratio (legacy) - - apps/client/src/app/pages/i18n/i18n-page.html - 152 - - - - The fees do exceed ${thresholdMax}% of your initial investment (${feeRatio}%) - - apps/client/src/app/pages/i18n/i18n-page.html - 154 - - - - The fees do not exceed ${thresholdMax}% of your initial investment (${feeRatio}%) - - apps/client/src/app/pages/i18n/i18n-page.html - 158 - - Fee Ratio apps/client/src/app/pages/i18n/i18n-page.html - 161 + 152 The fees do exceed ${thresholdMax}% of your total investment volume (${feeRatio}%) apps/client/src/app/pages/i18n/i18n-page.html - 163 + 154 The fees do not exceed ${thresholdMax}% of your total investment volume (${feeRatio}%) apps/client/src/app/pages/i18n/i18n-page.html - 167 + 158 @@ -7347,7 +7326,7 @@ apps/client/src/app/pages/admin/admin-page.component.ts - 56 + 53 @@ -7609,7 +7588,7 @@ Fees apps/client/src/app/pages/i18n/i18n-page.html - 170 + 161 @@ -7651,7 +7630,7 @@ Regional Market Cluster Risks apps/client/src/app/pages/i18n/i18n-page.html - 172 + 163 @@ -7728,140 +7707,140 @@ Asia-Pacific apps/client/src/app/pages/i18n/i18n-page.html - 174 + 165 The Asia-Pacific market contribution of your current investment (${valueRatio}%) exceeds ${thresholdMax}% apps/client/src/app/pages/i18n/i18n-page.html - 176 + 167 The Asia-Pacific market contribution of your current investment (${valueRatio}%) is below ${thresholdMin}% apps/client/src/app/pages/i18n/i18n-page.html - 180 + 171 The Asia-Pacific market contribution of your current investment (${valueRatio}%) is within the range of ${thresholdMin}% and ${thresholdMax}% apps/client/src/app/pages/i18n/i18n-page.html - 184 + 175 Emerging Markets apps/client/src/app/pages/i18n/i18n-page.html - 189 + 180 The Emerging Markets contribution of your current investment (${valueRatio}%) exceeds ${thresholdMax}% apps/client/src/app/pages/i18n/i18n-page.html - 192 + 183 The Emerging Markets contribution of your current investment (${valueRatio}%) is below ${thresholdMin}% apps/client/src/app/pages/i18n/i18n-page.html - 196 + 187 The Emerging Markets contribution of your current investment (${valueRatio}%) is within the range of ${thresholdMin}% and ${thresholdMax}% apps/client/src/app/pages/i18n/i18n-page.html - 200 + 191 Europe apps/client/src/app/pages/i18n/i18n-page.html - 204 + 195 The Europe market contribution of your current investment (${valueRatio}%) exceeds ${thresholdMax}% apps/client/src/app/pages/i18n/i18n-page.html - 206 + 197 The Europe market contribution of your current investment (${valueRatio}%) is below ${thresholdMin}% apps/client/src/app/pages/i18n/i18n-page.html - 210 + 201 The Europe market contribution of your current investment (${valueRatio}%) is within the range of ${thresholdMin}% and ${thresholdMax}% apps/client/src/app/pages/i18n/i18n-page.html - 214 + 205 Japan apps/client/src/app/pages/i18n/i18n-page.html - 218 + 209 The Japan market contribution of your current investment (${valueRatio}%) exceeds ${thresholdMax}% apps/client/src/app/pages/i18n/i18n-page.html - 220 + 211 The Japan market contribution of your current investment (${valueRatio}%) is below ${thresholdMin}% apps/client/src/app/pages/i18n/i18n-page.html - 224 + 215 The Japan market contribution of your current investment (${valueRatio}%) is within the range of ${thresholdMin}% and ${thresholdMax}% apps/client/src/app/pages/i18n/i18n-page.html - 228 + 219 North America apps/client/src/app/pages/i18n/i18n-page.html - 232 + 223 The North America market contribution of your current investment (${valueRatio}%) exceeds ${thresholdMax}% apps/client/src/app/pages/i18n/i18n-page.html - 234 + 225 The North America market contribution of your current investment (${valueRatio}%) is below ${thresholdMin}% apps/client/src/app/pages/i18n/i18n-page.html - 238 + 229 The North America market contribution of your current investment (${valueRatio}%) is within the range of ${thresholdMin}% and ${thresholdMax}% apps/client/src/app/pages/i18n/i18n-page.html - 242 + 233 diff --git a/apps/client/src/locales/messages.zh.xlf b/apps/client/src/locales/messages.zh.xlf index 67007cdef..ac81eebc7 100644 --- a/apps/client/src/locales/messages.zh.xlf +++ b/apps/client/src/locales/messages.zh.xlf @@ -388,7 +388,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 139 + 135 libs/ui/src/lib/accounts-table/accounts-table.component.html @@ -444,7 +444,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 145 + 141 libs/ui/src/lib/accounts-table/accounts-table.component.html @@ -464,15 +464,15 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 205 + 201 apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 208 + 204 apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 211 + 207 libs/ui/src/lib/account-balances/account-balances.component.html @@ -624,7 +624,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 155 + 151 libs/ui/src/lib/i18n.ts @@ -720,7 +720,7 @@ 日期 apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 161 + 157 libs/ui/src/lib/account-balances/account-balances.component.html @@ -1000,7 +1000,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 275 + 271 @@ -1044,7 +1044,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 124 + 120 @@ -1832,7 +1832,7 @@ 资产 apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 230 + 233 @@ -1840,7 +1840,7 @@ 购买力 apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 245 + 248 @@ -1848,7 +1848,7 @@ 从分析中排除 apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 271 + 274 @@ -1856,7 +1856,7 @@ 负债 apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 299 + 302 apps/client/src/app/pages/features/features-page.html @@ -1868,7 +1868,7 @@ 净值 apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 321 + 324 @@ -1876,7 +1876,7 @@ 年化业绩 apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 335 + 338 @@ -1912,7 +1912,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 189 + 185 libs/ui/src/lib/activities-table/activities-table.component.html @@ -2108,7 +2108,7 @@ libs/ui/src/lib/assistant/assistant.component.ts - 363 + 362 @@ -2120,7 +2120,7 @@ libs/ui/src/lib/assistant/assistant.component.ts - 375 + 374 @@ -2132,7 +2132,7 @@ libs/ui/src/lib/assistant/assistant.component.ts - 385 + 384 @@ -2144,7 +2144,7 @@ libs/ui/src/lib/assistant/assistant.component.ts - 409 + 408 @@ -2164,7 +2164,7 @@ libs/ui/src/lib/assistant/assistant.component.ts - 415 + 414 @@ -2764,11 +2764,11 @@ apps/client/src/app/pages/admin/admin-page.component.ts - 48 + 45 apps/client/src/app/pages/resources/resources-page.component.ts - 30 + 29 libs/common/src/lib/routes/routes.ts @@ -2912,7 +2912,7 @@ 由于您已经登录,因此无法访问模拟帐户。 apps/client/src/app/pages/demo/demo-page.component.ts - 35 + 32 @@ -3160,7 +3160,7 @@ apps/client/src/app/pages/resources/resources-page.component.ts - 40 + 39 libs/common/src/lib/routes/routes.ts @@ -3200,7 +3200,7 @@ 开源财富管理软件 apps/client/src/app/pages/i18n/i18n-page.html - 246 + 237 @@ -3748,7 +3748,7 @@ 更新现金余额 apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 112 + 108 @@ -3756,7 +3756,7 @@ 单价 apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 214 + 210 libs/ui/src/lib/activities-table/activities-table.component.html @@ -4112,7 +4112,7 @@ apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 369 + 372 apps/client/src/app/pages/features/features-page.html @@ -4120,7 +4120,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 202 + 198 apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts @@ -4144,7 +4144,7 @@ 存款 libs/ui/src/lib/fire-calculator/fire-calculator.component.ts - 377 + 385 @@ -4925,7 +4925,7 @@ 您确实要删除该帐户余额吗? libs/ui/src/lib/account-balances/account-balances.component.ts - 120 + 113 @@ -5101,11 +5101,11 @@ apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 356 + 359 libs/ui/src/lib/fire-calculator/fire-calculator.component.ts - 387 + 395 libs/ui/src/lib/i18n.ts @@ -5117,7 +5117,7 @@ 储蓄 libs/ui/src/lib/fire-calculator/fire-calculator.component.ts - 397 + 405 @@ -5197,7 +5197,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 290 + 286 libs/ui/src/lib/i18n.ts @@ -5229,7 +5229,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 309 + 305 libs/ui/src/lib/i18n.ts @@ -5477,7 +5477,7 @@ 费用 apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 262 + 258 libs/ui/src/lib/activities-table/activities-table.component.html @@ -5521,7 +5521,7 @@ 现金 apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 216 + 219 libs/ui/src/lib/i18n.ts @@ -5929,7 +5929,7 @@ 今年迄今为止 libs/ui/src/lib/assistant/assistant.component.ts - 375 + 374 @@ -5937,7 +5937,7 @@ 本周至今 libs/ui/src/lib/assistant/assistant.component.ts - 367 + 366 @@ -5945,7 +5945,7 @@ 本月至今 libs/ui/src/lib/assistant/assistant.component.ts - 371 + 370 @@ -5957,7 +5957,7 @@ libs/ui/src/lib/assistant/assistant.component.ts - 371 + 370 @@ -5969,7 +5969,7 @@ libs/ui/src/lib/assistant/assistant.component.ts - 367 + 366 @@ -6017,7 +6017,7 @@ libs/ui/src/lib/assistant/assistant.component.ts - 385 + 384 @@ -6029,7 +6029,7 @@ libs/ui/src/lib/assistant/assistant.component.ts - 409 + 408 @@ -6758,7 +6758,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 345 + 341 apps/client/src/app/pages/register/user-account-registration-dialog/user-account-registration-dialog.html @@ -6814,7 +6814,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 347 + 343 libs/ui/src/lib/i18n.ts @@ -7118,7 +7118,7 @@ apps/client/src/app/pages/resources/resources-page.component.ts - 45 + 44 libs/common/src/lib/routes/routes.ts @@ -7134,7 +7134,7 @@ apps/client/src/app/pages/resources/resources-page.component.ts - 34 + 33 libs/common/src/lib/routes/routes.ts @@ -7340,7 +7340,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 356 + 352 libs/ui/src/lib/historical-market-data-editor/historical-market-data-editor-dialog/historical-market-data-editor-dialog.html @@ -7644,7 +7644,7 @@ 查找账户、持仓或页面... libs/ui/src/lib/assistant/assistant.component.ts - 151 + 115 @@ -7889,36 +7889,12 @@ 150 - - Fee Ratio (legacy) - 费率(旧版) - - apps/client/src/app/pages/i18n/i18n-page.html - 152 - - - - The fees do exceed ${thresholdMax}% of your initial investment (${feeRatio}%) - 费用超过了您初始投资的 ${thresholdMax}% (${feeRatio}%) - - apps/client/src/app/pages/i18n/i18n-page.html - 154 - - - - The fees do not exceed ${thresholdMax}% of your initial investment (${feeRatio}%) - 费用未超过您初始投资的 ${thresholdMax}% (${feeRatio}%) - - apps/client/src/app/pages/i18n/i18n-page.html - 158 - - Fee Ratio 费率 apps/client/src/app/pages/i18n/i18n-page.html - 161 + 152 @@ -7926,7 +7902,7 @@ 费用已超过您总投资金额的 ${thresholdMax}%(${feeRatio}%) apps/client/src/app/pages/i18n/i18n-page.html - 163 + 154 @@ -7934,7 +7910,7 @@ 费用未超过您总投资金额的 ${thresholdMax}%(${feeRatio}%) apps/client/src/app/pages/i18n/i18n-page.html - 167 + 158 @@ -8104,7 +8080,7 @@ apps/client/src/app/pages/admin/admin-page.component.ts - 56 + 53 @@ -8393,7 +8369,7 @@ 费用 apps/client/src/app/pages/i18n/i18n-page.html - 170 + 161 @@ -8441,7 +8417,7 @@ 区域市场集群风险 apps/client/src/app/pages/i18n/i18n-page.html - 172 + 163 @@ -8537,7 +8513,7 @@ 亚太地区 apps/client/src/app/pages/i18n/i18n-page.html - 174 + 165 @@ -8545,7 +8521,7 @@ 亚太地区对您的当前投资 (${valueRatio}%) 的贡献超过了 ${thresholdMax}% apps/client/src/app/pages/i18n/i18n-page.html - 176 + 167 @@ -8553,7 +8529,7 @@ 亚太地区对您的当前投资 (${valueRatio}%) 的贡献低于 ${thresholdMin}% apps/client/src/app/pages/i18n/i18n-page.html - 180 + 171 @@ -8561,7 +8537,7 @@ 亚太地区对您的当前投资 (${valueRatio}%) 的贡献在 ${thresholdMin}% 和 ${thresholdMax}% 之间 apps/client/src/app/pages/i18n/i18n-page.html - 184 + 175 @@ -8569,7 +8545,7 @@ 新兴市场 apps/client/src/app/pages/i18n/i18n-page.html - 189 + 180 @@ -8577,7 +8553,7 @@ 新兴市场对您的当前投资 (${valueRatio}%) 的贡献超过了 ${thresholdMax}% apps/client/src/app/pages/i18n/i18n-page.html - 192 + 183 @@ -8585,7 +8561,7 @@ 新兴市场对您的当前投资 (${valueRatio}%) 的贡献低于 ${thresholdMin}% apps/client/src/app/pages/i18n/i18n-page.html - 196 + 187 @@ -8593,7 +8569,7 @@ 新兴市场对您的当前投资 (${valueRatio}%) 的贡献在 ${thresholdMin}% 和 ${thresholdMax}% 之间 apps/client/src/app/pages/i18n/i18n-page.html - 200 + 191 @@ -8601,7 +8577,7 @@ 欧洲市场 apps/client/src/app/pages/i18n/i18n-page.html - 204 + 195 @@ -8609,7 +8585,7 @@ 欧洲市场对您的当前投资 (${valueRatio}%) 的贡献超过了 ${thresholdMax}% apps/client/src/app/pages/i18n/i18n-page.html - 206 + 197 @@ -8617,7 +8593,7 @@ 欧洲市场对您的当前投资 (${valueRatio}%) 的贡献低于 ${thresholdMin}% apps/client/src/app/pages/i18n/i18n-page.html - 210 + 201 @@ -8625,7 +8601,7 @@ 欧洲市场对您的当前投资 (${valueRatio}%) 的贡献在 ${thresholdMin}% 和 ${thresholdMax}% 之间 apps/client/src/app/pages/i18n/i18n-page.html - 214 + 205 @@ -8633,7 +8609,7 @@ 日本市场 apps/client/src/app/pages/i18n/i18n-page.html - 218 + 209 @@ -8641,7 +8617,7 @@ 日本市场对您的当前投资 (${valueRatio}%) 的贡献超过了 ${thresholdMax}% apps/client/src/app/pages/i18n/i18n-page.html - 220 + 211 @@ -8649,7 +8625,7 @@ 日本市场对您的当前投资 (${valueRatio}%) 的贡献低于 ${thresholdMin}% apps/client/src/app/pages/i18n/i18n-page.html - 224 + 215 @@ -8657,7 +8633,7 @@ 日本市场对您的当前投资 (${valueRatio}%) 的贡献在 ${thresholdMin}% 和 ${thresholdMax}% 之间 apps/client/src/app/pages/i18n/i18n-page.html - 228 + 219 @@ -8665,7 +8641,7 @@ 北美市场 apps/client/src/app/pages/i18n/i18n-page.html - 232 + 223 @@ -8673,7 +8649,7 @@ 北美市场对您的当前投资 (${valueRatio}%) 的贡献超过了 ${thresholdMax}% apps/client/src/app/pages/i18n/i18n-page.html - 234 + 225 @@ -8681,7 +8657,7 @@ 北美市场对您的当前投资 (${valueRatio}%) 的贡献低于 ${thresholdMin}% apps/client/src/app/pages/i18n/i18n-page.html - 238 + 229 @@ -8689,7 +8665,7 @@ 北美市场对您的当前投资 (${valueRatio}%) 的贡献在 ${thresholdMin}% 和 ${thresholdMax}% 之间 apps/client/src/app/pages/i18n/i18n-page.html - 242 + 233 From f2c81ada90d040da961702d702a3daf93ec1b9b9 Mon Sep 17 00:00:00 2001 From: Thomas Kaul <4159106+dtslvr@users.noreply.github.com> Date: Sat, 28 Feb 2026 10:43:52 +0100 Subject: [PATCH 058/224] Task/refactor $queryRawUnsafe() in data provider service (#6408) * Refactor $queryRawUnsafe() * Update changelog --- CHANGELOG.md | 1 + .../data-provider/data-provider.service.ts | 33 +++++++++---------- 2 files changed, 17 insertions(+), 17 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0b25ff7e6..7b79e434f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Changed - Removed the deprecated static portfolio analysis rule: _Fees_ (Fee Ratio) +- Refactored queries in the data provider service to use Prisma’s safe query methods ### Fixed diff --git a/apps/api/src/services/data-provider/data-provider.service.ts b/apps/api/src/services/data-provider/data-provider.service.ts index 8ee8761c0..a6b12cce2 100644 --- a/apps/api/src/services/data-provider/data-provider.service.ts +++ b/apps/api/src/services/data-provider/data-provider.service.ts @@ -30,7 +30,7 @@ import { import type { Granularity, UserWithSettings } from '@ghostfolio/common/types'; import { Inject, Injectable, Logger, OnModuleInit } from '@nestjs/common'; -import { DataSource, MarketData, SymbolProfile } from '@prisma/client'; +import { DataSource, MarketData, Prisma, SymbolProfile } from '@prisma/client'; import { Big } from 'big.js'; import { eachDayOfInterval, format, isValid } from 'date-fns'; import { groupBy, isEmpty, isNumber, uniqWith } from 'lodash'; @@ -347,36 +347,35 @@ export class DataProviderService implements OnModuleInit { const granularityQuery = aGranularity === 'month' - ? `AND (date_part('day', date) = 1 OR date >= TIMESTAMP 'yesterday')` - : ''; + ? Prisma.sql`AND (date_part('day', date) = 1 OR date >= TIMESTAMP 'yesterday')` + : Prisma.empty; const rangeQuery = from && to - ? `AND date >= '${format(from, DATE_FORMAT)}' AND date <= '${format( + ? Prisma.sql`AND date >= ${format(from, DATE_FORMAT)}::timestamp AND date <= ${format( to, DATE_FORMAT - )}'` - : ''; + )}::timestamp` + : Prisma.empty; const dataSources = aItems.map(({ dataSource }) => { return dataSource; }); + const symbols = aItems.map(({ symbol }) => { return symbol; }); try { - const queryRaw = ` - SELECT * - FROM "MarketData" - WHERE "dataSource" IN ('${dataSources.join(`','`)}') - AND "symbol" IN ('${symbols.join( - `','` - )}') ${granularityQuery} ${rangeQuery} - ORDER BY date;`; - - const marketDataByGranularity: MarketData[] = - await this.prismaService.$queryRawUnsafe(queryRaw); + const marketDataByGranularity: MarketData[] = await this.prismaService + .$queryRaw` + SELECT * + FROM "MarketData" + WHERE "dataSource"::text IN (${Prisma.join(dataSources)}) + AND "symbol" IN (${Prisma.join(symbols)}) + ${granularityQuery} + ${rangeQuery} + ORDER BY date;`; response = marketDataByGranularity.reduce((r, marketData) => { const { date, marketPrice, symbol } = marketData; From 9493f79f8e288581e0e9f2b539b69041731c0028 Mon Sep 17 00:00:00 2001 From: Kenrick Tandrian <60643640+KenTandrian@users.noreply.github.com> Date: Sat, 28 Feb 2026 13:46:37 +0400 Subject: [PATCH 059/224] Task/improve type safety in portfolio filter form component (#6404) * fix(lib): resolve typescript errors in portfolio filter form * fix(lib): type safety in template * feat(lib): implement takeUntilDestroyed * feat(lib): replace constructor params with injections * feat(lib): change accounts to input signal * feat(lib): change assetClasses to input signal * feat(lib): change holdings to input signal * feat(lib): change tags to input signal * fix(lib): implement signal for disabled * fix(lib): implement model signal for disabled * fix(lib): reduce any types --- .../portfolio-filter-form.component.html | 12 ++-- ...portfolio-filter-form.component.stories.ts | 4 +- .../portfolio-filter-form.component.ts | 69 ++++++++++--------- 3 files changed, 43 insertions(+), 42 deletions(-) diff --git a/libs/ui/src/lib/portfolio-filter-form/portfolio-filter-form.component.html b/libs/ui/src/lib/portfolio-filter-form/portfolio-filter-form.component.html index e017d33d6..f5dbac698 100644 --- a/libs/ui/src/lib/portfolio-filter-form/portfolio-filter-form.component.html +++ b/libs/ui/src/lib/portfolio-filter-form/portfolio-filter-form.component.html @@ -4,14 +4,14 @@ Account - @for (account of accounts; track account.id) { + @for (account of accounts(); track account.id) {
    @if (account.platform?.url) { } {{ account.name }} @@ -32,7 +32,7 @@ filterForm.get('holding')?.value?.name }} - @for (holding of holdings; track holding.name) { + @for (holding of holdings(); track holding.name) {
    Tag - @for (tag of tags; track tag.id) { + @for (tag of tags(); track tag.id) { {{ tag.label }} } @@ -64,7 +64,7 @@ Asset Class - @for (assetClass of assetClasses; track assetClass.id) { + @for (assetClass of assetClasses(); track assetClass.id) { {{ assetClass.label }} diff --git a/libs/ui/src/lib/portfolio-filter-form/portfolio-filter-form.component.stories.ts b/libs/ui/src/lib/portfolio-filter-form/portfolio-filter-form.component.stories.ts index 710a4e9c5..665bec3e4 100644 --- a/libs/ui/src/lib/portfolio-filter-form/portfolio-filter-form.component.stories.ts +++ b/libs/ui/src/lib/portfolio-filter-form/portfolio-filter-form.component.stories.ts @@ -40,7 +40,7 @@ export const Default: Story = { { id: 'COMMODITY', label: 'Commodity', type: 'ASSET_CLASS' }, { id: 'EQUITY', label: 'Equity', type: 'ASSET_CLASS' }, { id: 'FIXED_INCOME', label: 'Fixed Income', type: 'ASSET_CLASS' } - ] as any, + ], holdings: [ { currency: 'USD', @@ -66,7 +66,7 @@ export const Default: Story = { label: 'Retirement Fund', type: 'TAG' } - ] as any, + ], disabled: false } }; diff --git a/libs/ui/src/lib/portfolio-filter-form/portfolio-filter-form.component.ts b/libs/ui/src/lib/portfolio-filter-form/portfolio-filter-form.component.ts index afbe5af4e..c1f82315c 100644 --- a/libs/ui/src/lib/portfolio-filter-form/portfolio-filter-form.component.ts +++ b/libs/ui/src/lib/portfolio-filter-form/portfolio-filter-form.component.ts @@ -8,12 +8,15 @@ import { ChangeDetectionStrategy, ChangeDetectorRef, Component, - Input, + DestroyRef, OnChanges, - OnDestroy, OnInit, - forwardRef + forwardRef, + inject, + input, + model } from '@angular/core'; +import { takeUntilDestroyed } from '@angular/core/rxjs-interop'; import { ControlValueAccessor, FormBuilder, @@ -25,7 +28,6 @@ import { } from '@angular/forms'; import { MatFormFieldModule } from '@angular/material/form-field'; import { MatSelectModule } from '@angular/material/select'; -import { Subject, takeUntil } from 'rxjs'; import { GfEntityLogoComponent } from '../entity-logo/entity-logo.component'; import { PortfolioFilterFormValue } from './interfaces'; @@ -53,33 +55,37 @@ import { PortfolioFilterFormValue } from './interfaces'; templateUrl: './portfolio-filter-form.component.html' }) export class GfPortfolioFilterFormComponent - implements ControlValueAccessor, OnInit, OnChanges, OnDestroy + implements ControlValueAccessor, OnChanges, OnInit { - @Input() accounts: AccountWithPlatform[] = []; - @Input() assetClasses: Filter[] = []; - @Input() holdings: PortfolioPosition[] = []; - @Input() tags: Filter[] = []; - @Input() disabled = false; - - public filterForm: FormGroup; - - private unsubscribeSubject = new Subject(); - - public constructor( - private changeDetectorRef: ChangeDetectorRef, - private formBuilder: FormBuilder - ) { + public readonly accounts = input([]); + public readonly assetClasses = input([]); + public readonly disabled = model(false); + public readonly holdings = input([]); + public readonly tags = input([]); + + public filterForm: FormGroup<{ + account: FormControl; + assetClass: FormControl; + holding: FormControl; + tag: FormControl; + }>; + + private readonly changeDetectorRef = inject(ChangeDetectorRef); + private readonly destroyRef = inject(DestroyRef); + private readonly formBuilder = inject(FormBuilder); + + public constructor() { this.filterForm = this.formBuilder.group({ - account: new FormControl(null), - assetClass: new FormControl(null), - holding: new FormControl(null), - tag: new FormControl(null) + account: new FormControl(null), + assetClass: new FormControl(null), + holding: new FormControl(null), + tag: new FormControl(null) }); } public ngOnInit() { this.filterForm.valueChanges - .pipe(takeUntil(this.unsubscribeSubject)) + .pipe(takeUntilDestroyed(this.destroyRef)) .subscribe((value) => { this.onChange(value as PortfolioFilterFormValue); this.onTouched(); @@ -108,7 +114,7 @@ export class GfPortfolioFilterFormComponent } public ngOnChanges() { - if (this.disabled) { + if (this.disabled()) { this.filterForm.disable({ emitEvent: false }); } else { this.filterForm.enable({ emitEvent: false }); @@ -116,9 +122,9 @@ export class GfPortfolioFilterFormComponent const tagControl = this.filterForm.get('tag'); - if (this.tags.length === 0) { + if (this.tags().length === 0) { tagControl?.disable({ emitEvent: false }); - } else if (!this.disabled) { + } else if (!this.disabled()) { tagControl?.enable({ emitEvent: false }); } @@ -134,9 +140,9 @@ export class GfPortfolioFilterFormComponent } public setDisabledState(isDisabled: boolean) { - this.disabled = isDisabled; + this.disabled.set(isDisabled); - if (this.disabled) { + if (this.disabled()) { this.filterForm.disable({ emitEvent: false }); } else { this.filterForm.enable({ emitEvent: false }); @@ -161,11 +167,6 @@ export class GfPortfolioFilterFormComponent } } - public ngOnDestroy() { - this.unsubscribeSubject.next(); - this.unsubscribeSubject.complete(); - } - // eslint-disable-next-line @typescript-eslint/no-unused-vars private onChange = (_value: PortfolioFilterFormValue): void => { // ControlValueAccessor onChange callback From 98fb0b86af0f1bac6bd54499be38feada9bd3bcd Mon Sep 17 00:00:00 2001 From: Thomas Kaul <4159106+dtslvr@users.noreply.github.com> Date: Sat, 28 Feb 2026 10:47:09 +0100 Subject: [PATCH 060/224] Task/improve usability of asset profile details dialog for currencies (#6406) * Improve usability * Update changelog --- CHANGELOG.md | 1 + apps/api/src/app/admin/admin.service.ts | 6 ++++- .../asset-profile-dialog.component.ts | 24 +++++++++++++++---- .../asset-profile-dialog.html | 11 +++++++-- 4 files changed, 35 insertions(+), 7 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7b79e434f..08e1b0f1c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Changed +- Improved the usability of the asset profile details dialog in the admin control panel for currencies - Removed the deprecated static portfolio analysis rule: _Fees_ (Fee Ratio) - Refactored queries in the data provider service to use Prisma’s safe query methods diff --git a/apps/api/src/app/admin/admin.service.ts b/apps/api/src/app/admin/admin.service.ts index d77fde346..1f8745cd1 100644 --- a/apps/api/src/app/admin/admin.service.ts +++ b/apps/api/src/app/admin/admin.service.ts @@ -470,7 +470,9 @@ export class AdminService { let currency: EnhancedSymbolProfile['currency'] = '-'; let dateOfFirstActivity: EnhancedSymbolProfile['dateOfFirstActivity']; - if (isCurrency(getCurrencyFromSymbol(symbol))) { + const isCurrencyAssetProfile = isCurrency(getCurrencyFromSymbol(symbol)); + + if (isCurrencyAssetProfile) { currency = getCurrencyFromSymbol(symbol); ({ activitiesCount, dateOfFirstActivity } = await this.orderService.getStatisticsByCurrency(currency)); @@ -508,6 +510,8 @@ export class AdminService { dataSource, dateOfFirstActivity, symbol, + assetClass: isCurrencyAssetProfile ? AssetClass.LIQUIDITY : undefined, + assetSubClass: isCurrencyAssetProfile ? AssetSubClass.CASH : undefined, isActive: true } }; 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 cbd8deba3..b1519e35b 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 @@ -5,7 +5,11 @@ import { PROPERTY_IS_DATA_GATHERING_ENABLED } from '@ghostfolio/common/config'; import { UpdateAssetProfileDto } from '@ghostfolio/common/dtos'; -import { DATE_FORMAT } from '@ghostfolio/common/helper'; +import { + DATE_FORMAT, + getCurrencyFromSymbol, + isCurrency +} from '@ghostfolio/common/helper'; import { AdminMarketDataDetails, AssetClassSelectorOption, @@ -138,7 +142,6 @@ export class GfAssetProfileDialogComponent implements OnDestroy, OnInit { }); public assetSubClassOptions: AssetClassSelectorOption[] = []; - public assetProfile: AdminMarketDataDetails['assetProfile']; public assetProfileForm = this.formBuilder.group({ @@ -180,12 +183,14 @@ export class GfAssetProfileDialogComponent implements OnDestroy, OnInit { ); public benchmarks: Partial[]; + public canEditAssetProfile = true; public countries: { [code: string]: { name: string; value: number }; }; public currencies: string[] = []; + public dateRangeOptions = [ { label: $localize`Current week` + ' (' + $localize`WTD` + ')', @@ -260,7 +265,7 @@ export class GfAssetProfileDialogComponent implements OnDestroy, OnInit { } public get canSaveAssetProfileIdentifier() { - return !this.assetProfileForm.dirty; + return !this.assetProfileForm.dirty && this.canEditAssetProfile; } public ngOnInit() { @@ -324,6 +329,11 @@ export class GfAssetProfileDialogComponent implements OnDestroy, OnInit { this.assetClassLabel = translate(this.assetProfile?.assetClass); this.assetSubClassLabel = translate(this.assetProfile?.assetSubClass); + + this.canEditAssetProfile = !isCurrency( + getCurrencyFromSymbol(this.data.symbol) + ); + this.countries = {}; this.isBenchmark = this.benchmarks.some(({ id }) => { @@ -390,6 +400,10 @@ export class GfAssetProfileDialogComponent implements OnDestroy, OnInit { url: this.assetProfile?.url ?? '' }); + if (!this.canEditAssetProfile) { + this.assetProfileForm.disable(); + } + this.assetProfileForm.markAsPristine(); this.changeDetectorRef.markForCheck(); @@ -399,7 +413,9 @@ export class GfAssetProfileDialogComponent implements OnDestroy, OnInit { public onCancelEditAssetProfileIdentifierMode() { this.isEditAssetProfileIdentifierMode = false; - this.assetProfileForm.enable(); + if (this.canEditAssetProfile) { + this.assetProfileForm.enable(); + } this.assetProfileIdentifierForm.reset(); } diff --git a/apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html b/apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html index a60e10edc..6b3141bfe 100644 --- a/apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html +++ b/apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html @@ -300,6 +300,7 @@
    Data Gathering From 0fee18908f37792e38080b3b0686f81802f635aa Mon Sep 17 00:00:00 2001 From: Thomas Kaul <4159106+dtslvr@users.noreply.github.com> Date: Sat, 28 Feb 2026 10:49:41 +0100 Subject: [PATCH 061/224] Release 2.244.0 (#6409) --- CHANGELOG.md | 2 +- package-lock.json | 4 ++-- package.json | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 08e1b0f1c..90026ee7d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,7 +5,7 @@ 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 +## 2.244.0 - 2026-02-28 ### Changed diff --git a/package-lock.json b/package-lock.json index fadeca52d..dbe97b386 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "ghostfolio", - "version": "2.243.0", + "version": "2.244.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "ghostfolio", - "version": "2.243.0", + "version": "2.244.0", "hasInstallScript": true, "license": "AGPL-3.0", "dependencies": { diff --git a/package.json b/package.json index ad615c3a0..d1d0df2bb 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "ghostfolio", - "version": "2.243.0", + "version": "2.244.0", "homepage": "https://ghostfol.io", "license": "AGPL-3.0", "repository": "https://github.com/ghostfolio/ghostfolio", From da13d62703113eb00897b12ef1fe54a8f8202e67 Mon Sep 17 00:00:00 2001 From: Erwin-N <111194281+Erwin-N@users.noreply.github.com> Date: Sun, 1 Mar 2026 09:44:46 +0100 Subject: [PATCH 062/224] Task/improve language localization for NL (#6414) * Improve language localization for NL * Update changelog --- CHANGELOG.md | 6 ++ apps/client/src/locales/messages.nl.xlf | 136 ++++++++++++------------ 2 files changed, 74 insertions(+), 68 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 90026ee7d..ac47df943 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 Dutch (`nl`) + ## 2.244.0 - 2026-02-28 ### Changed diff --git a/apps/client/src/locales/messages.nl.xlf b/apps/client/src/locales/messages.nl.xlf index 58928387b..158ff4fb1 100644 --- a/apps/client/src/locales/messages.nl.xlf +++ b/apps/client/src/locales/messages.nl.xlf @@ -39,7 +39,7 @@ please - please + alsjeblieft apps/client/src/app/pages/pricing/pricing-page.html 333 @@ -83,7 +83,7 @@ with - with + met apps/client/src/app/components/subscription-interstitial-dialog/subscription-interstitial-dialog.html 87 @@ -371,7 +371,7 @@ and is driven by the efforts of its contributors - and is driven by the efforts of its contributors + en wordt gedreven door de inspanningen van zijn bijdragers apps/client/src/app/pages/about/overview/about-overview-page.html 49 @@ -655,7 +655,7 @@ No auto-renewal on membership. - No auto-renewal on membership. + Het lidmaatschap wordt niet automatisch verlengd. apps/client/src/app/components/user-account-membership/user-account-membership.html 74 @@ -1099,7 +1099,7 @@ Performance with currency effect - Performance with currency effect + Prestaties met valuta-effect apps/client/src/app/pages/portfolio/analysis/analysis-page.html 135 @@ -1915,7 +1915,7 @@ Current week - Current week + Huidige week apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts 191 @@ -2079,7 +2079,7 @@ or start a discussion at - or start a discussion at + of start een discussie op apps/client/src/app/pages/about/overview/about-overview-page.html 94 @@ -2151,7 +2151,7 @@ Sustainable retirement income - Sustainable retirement income + Duurzaam pensioeninkomen apps/client/src/app/pages/portfolio/fire/fire-page.html 41 @@ -2323,7 +2323,7 @@ contact us - contact us + contacteer ons apps/client/src/app/pages/pricing/pricing-page.html 336 @@ -2399,7 +2399,7 @@ Exclude from Analysis - Exclude from Analysis + Uitsluiten van analyse apps/client/src/app/pages/accounts/create-or-update-account-dialog/create-or-update-account-dialog.html 90 @@ -2423,7 +2423,7 @@ Latest activities - Latest activities + Laatste activiteiten apps/client/src/app/pages/public/public-page.html 210 @@ -2539,7 +2539,7 @@ annual interest rate - annual interest rate + jaarlijkse rente apps/client/src/app/pages/portfolio/fire/fire-page.html 185 @@ -2659,7 +2659,7 @@ Could not validate form - Could not validate form + Het formulier kon niet worden gevalideerd. apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts 554 @@ -2895,7 +2895,7 @@ Authentication - Authentication + Authenticatie apps/client/src/app/components/user-detail-dialog/user-detail-dialog.html 54 @@ -3047,7 +3047,7 @@ If you retire today, you would be able to withdraw - If you retire today, you would be able to withdraw + Als u vandaag met pensioen gaat, kunt u apps/client/src/app/pages/portfolio/fire/fire-page.html 68 @@ -3115,7 +3115,7 @@ Looking for a student discount? - Looking for a student discount? + Op zoek naar studentenkorting? apps/client/src/app/pages/pricing/pricing-page.html 342 @@ -3343,7 +3343,7 @@ No Activities - No Activities + Geen activiteiten apps/client/src/app/components/admin-market-data/admin-market-data.component.ts 146 @@ -3359,7 +3359,7 @@ Everything in Basic, plus - Everything in Basic, plus + Alles van Basic, plus apps/client/src/app/pages/pricing/pricing-page.html 199 @@ -3619,7 +3619,7 @@ Could not save asset profile - Could not save asset profile + Kon het assetprofiel niet opslaan apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts 588 @@ -3823,7 +3823,7 @@ By - By + Door apps/client/src/app/pages/portfolio/fire/fire-page.html 139 @@ -3839,7 +3839,7 @@ Current year - Current year + Huidig jaar apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts 199 @@ -3875,7 +3875,7 @@ Asset profile has been saved - Asset profile has been saved + Het activaprofiel is opgeslagen. apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts 578 @@ -4067,7 +4067,7 @@ View Details - View Details + Bekijk details apps/client/src/app/components/admin-users/admin-users.html 225 @@ -4203,7 +4203,7 @@ per week - per week + per week apps/client/src/app/components/subscription-interstitial-dialog/subscription-interstitial-dialog.html 130 @@ -4227,7 +4227,7 @@ and we share aggregated key metrics of the platform’s performance - and we share aggregated key metrics of the platform’s performance + en we delen geaggregeerde belangrijke prestatiegegevens van het platform apps/client/src/app/pages/about/overview/about-overview-page.html 32 @@ -4271,7 +4271,7 @@ Website of Thomas Kaul - Website of Thomas Kaul + Website van Thomas Kaul apps/client/src/app/pages/about/overview/about-overview-page.html 44 @@ -4451,7 +4451,7 @@ Sign in with OpenID Connect - Sign in with OpenID Connect + Meld je aan met OpenID Connect apps/client/src/app/components/login-with-access-token-dialog/login-with-access-token-dialog.html 55 @@ -4543,7 +4543,7 @@ The source code is fully available as open source software (OSS) under the AGPL-3.0 license - The source code is fully available as open source software (OSS) under the AGPL-3.0 license + De broncode is volledig beschikbaar als open source software (OSS) onder de AGPL-3.0-licentie apps/client/src/app/pages/about/overview/about-overview-page.html 16 @@ -4615,7 +4615,7 @@ this is projected to increase to - this is projected to increase to + zal dit naar verwachting stijgen tot apps/client/src/app/pages/portfolio/fire/fire-page.html 147 @@ -4667,7 +4667,7 @@ Job ID - Job ID + Opdracht ID apps/client/src/app/components/admin-jobs/admin-jobs.html 34 @@ -4751,7 +4751,7 @@ for - for + voor apps/client/src/app/components/subscription-interstitial-dialog/subscription-interstitial-dialog.html 128 @@ -4775,7 +4775,7 @@ Could not parse scraper configuration - Could not parse scraper configuration + De scraperconfiguratie kon niet worden geparseerd apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts 509 @@ -4819,7 +4819,7 @@ Edit access - Edit access + Toegang bewerken apps/client/src/app/components/user-account-access/create-or-update-access-dialog/create-or-update-access-dialog.html 11 @@ -4891,7 +4891,7 @@ Get access to 80’000+ tickers from over 50 exchanges - Get access to 80’000+ tickers from over 50 exchanges + Krijg toegang tot meer dan 80.000+ tickers van meer dan 50 beurzen apps/client/src/app/components/subscription-interstitial-dialog/subscription-interstitial-dialog.html 84 @@ -5075,7 +5075,7 @@ less than - less than + minder dan apps/client/src/app/components/subscription-interstitial-dialog/subscription-interstitial-dialog.html 129 @@ -5365,7 +5365,7 @@ Ghostfolio Status - Ghostfolio Status + Ghostfolio Status apps/client/src/app/pages/about/overview/about-overview-page.html 62 @@ -5373,7 +5373,7 @@ with your university e-mail address - with your university e-mail address + met uw universitaire e-mailadres apps/client/src/app/pages/pricing/pricing-page.html 348 @@ -5393,7 +5393,7 @@ and a safe withdrawal rate (SWR) of - and a safe withdrawal rate (SWR) of + en een veilige opnameratio (SWR) van apps/client/src/app/pages/portfolio/fire/fire-page.html 108 @@ -5557,7 +5557,7 @@ Request it - Request it + Aanvragen apps/client/src/app/pages/pricing/pricing-page.html 344 @@ -5613,7 +5613,7 @@ , - , + , apps/client/src/app/pages/portfolio/fire/fire-page.html 145 @@ -5629,7 +5629,7 @@ per month - per month + per maand apps/client/src/app/pages/portfolio/fire/fire-page.html 94 @@ -5821,7 +5821,7 @@ Argentina - Argentina + Argentinië libs/ui/src/lib/i18n.ts 78 @@ -5877,7 +5877,7 @@ here - here + hier apps/client/src/app/pages/pricing/pricing-page.html 347 @@ -5885,7 +5885,7 @@ Close Holding - Close Holding + Sluit Holding apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html 441 @@ -6266,7 +6266,7 @@ Include in - Include in + Opnemen in apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html 374 @@ -6550,7 +6550,7 @@ View Holding - View Holding + Bekijk Holding libs/ui/src/lib/activities-table/activities-table.component.html 450 @@ -6694,7 +6694,7 @@ Oops! Could not update access. - Oops! Could not update access. + Oops! Kan de toegang niet updaten. apps/client/src/app/components/user-account-access/create-or-update-access-dialog/create-or-update-access-dialog.component.ts 178 @@ -6702,7 +6702,7 @@ , based on your total assets of - , based on your total assets of + opnemen, dit is gebaseerd op uw totale vermogen van apps/client/src/app/pages/portfolio/fire/fire-page.html 96 @@ -6822,7 +6822,7 @@ Role - Role + Rol apps/client/src/app/components/user-detail-dialog/user-detail-dialog.html 33 @@ -6862,7 +6862,7 @@ If you plan to open an account at - If you plan to open an account at + Als u van plan bent een rekening te openen bij apps/client/src/app/pages/pricing/pricing-page.html 312 @@ -6894,7 +6894,7 @@ send an e-mail to - send an e-mail to + stuur een e-mail naar apps/client/src/app/pages/about/overview/about-overview-page.html 87 @@ -6966,7 +6966,7 @@ , assuming a - , assuming a + , uitgaande van apps/client/src/app/pages/portfolio/fire/fire-page.html 174 @@ -7054,7 +7054,7 @@ Ghostfolio is a lightweight wealth management application for individuals to keep track of stocks, ETFs or cryptocurrencies and make solid, data-driven investment decisions. - Ghostfolio is a lightweight wealth management application for individuals to keep track of stocks, ETFs or cryptocurrencies and make solid, data-driven investment decisions. + Ghostfolio is een gebruiksvriendelijke applicatie voor vermogensbeheer waarmee particulieren hun aandelen, ETF's of cryptovaluta kunnen volgen en weloverwogen, datagestuurde beleggingsbeslissingen kunnen nemen. apps/client/src/app/pages/about/overview/about-overview-page.html 10 @@ -7384,7 +7384,7 @@ Change with currency effect - Change with currency effect + Verandering met valuta-effect apps/client/src/app/pages/portfolio/analysis/analysis-page.html 116 @@ -7524,7 +7524,7 @@ The project has been initiated by - The project has been initiated by + Het project is geïnitieerd door apps/client/src/app/pages/about/overview/about-overview-page.html 40 @@ -7548,7 +7548,7 @@ Total amount - Total amount + Totaal bedrag apps/client/src/app/pages/portfolio/analysis/analysis-page.html 95 @@ -7640,7 +7640,7 @@ Find account, holding or page... - Find account, holding or page... + Vindt een account, holding of pagina... libs/ui/src/lib/assistant/assistant.component.ts 115 @@ -7890,7 +7890,7 @@ Fee Ratio - Fee Ratio + Vergoedingsverhouding apps/client/src/app/pages/i18n/i18n-page.html 152 @@ -7898,7 +7898,7 @@ The fees do exceed ${thresholdMax}% of your total investment volume (${feeRatio}%) - The fees do exceed ${thresholdMax}% of your total investment volume (${feeRatio}%) + De kosten overschrijden ${thresholdMax}% van uw totale investeringsvolume (${feeRatio}%) apps/client/src/app/pages/i18n/i18n-page.html 154 @@ -7906,7 +7906,7 @@ The fees do not exceed ${thresholdMax}% of your total investment volume (${feeRatio}%) - The fees do not exceed ${thresholdMax}% of your total investment volume (${feeRatio}%) + De kosten bedragen maximaal ${thresholdMax}% van uw totale investeringsvolume (${feeRatio}%) apps/client/src/app/pages/i18n/i18n-page.html 158 @@ -8064,7 +8064,7 @@ Current month - Current month + Huidige maand apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts 195 @@ -8249,7 +8249,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_ - If you encounter a bug, would like to suggest an improvement or a new feature, please join the Ghostfolio Slack community, post to @ghostfolio_ + Als je een bug tegenkomt, een verbetering wilt voorstellen of een nieuwe functie wilt toevoegen, word dan lid van de Ghostfolio Slack-community. Stuur een bericht naar @ghostfolio_ apps/client/src/app/pages/about/overview/about-overview-page.html 69 @@ -8373,7 +8373,7 @@ Liquidity - Liquidity + Liquiditeit apps/client/src/app/pages/i18n/i18n-page.html 70 @@ -8381,7 +8381,7 @@ Buying Power - Buying Power + Koopkracht apps/client/src/app/pages/i18n/i18n-page.html 71 @@ -8389,7 +8389,7 @@ Your buying power is below ${thresholdMin} ${baseCurrency} - Your buying power is below ${thresholdMin} ${baseCurrency} + Uw koopkracht ligt onder ${thresholdMin} ${baseCurrency} apps/client/src/app/pages/i18n/i18n-page.html 73 @@ -8397,7 +8397,7 @@ Your buying power is 0 ${baseCurrency} - Your buying power is 0 ${baseCurrency} + Uw koopkracht is 0 ${baseCurrency} apps/client/src/app/pages/i18n/i18n-page.html 77 @@ -8405,7 +8405,7 @@ Your buying power exceeds ${thresholdMin} ${baseCurrency} - Your buying power exceeds ${thresholdMin} ${baseCurrency} + Uw koopkracht overschrijdt ${thresholdMin} ${baseCurrency} apps/client/src/app/pages/i18n/i18n-page.html 80 @@ -8709,7 +8709,7 @@ Registration Date - Registration Date + Registratiedatum apps/client/src/app/components/user-detail-dialog/user-detail-dialog.html 45 From 8b714d18ab37e340a454a3b5d1c648bd319dbf8b Mon Sep 17 00:00:00 2001 From: Davide Riccobelli <49486400+riccobelli@users.noreply.github.com> Date: Sun, 1 Mar 2026 09:58:50 +0100 Subject: [PATCH 063/224] Task/improve language localization for IT (#6416) * Improve language localization for IT * Update changelog --- CHANGELOG.md | 1 + apps/client/src/locales/messages.it.xlf | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ac47df943..667b25e5d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Changed - Improved the language localization for Dutch (`nl`) +- Improved the language localization for Italian (`it`) ## 2.244.0 - 2026-02-28 diff --git a/apps/client/src/locales/messages.it.xlf b/apps/client/src/locales/messages.it.xlf index 05bb6afb2..20bfd1b33 100644 --- a/apps/client/src/locales/messages.it.xlf +++ b/apps/client/src/locales/messages.it.xlf @@ -3244,7 +3244,7 @@ Summary - Summario + Riepilogo apps/client/src/app/components/home-summary/home-summary.html 2 From 08c04e69cf74e499fd766c1356a6485a1d9b61d6 Mon Sep 17 00:00:00 2001 From: Thomas Kaul <4159106+dtslvr@users.noreply.github.com> Date: Sun, 1 Mar 2026 10:01:59 +0100 Subject: [PATCH 064/224] Task/exclude scraper configuration and symbol mapping from import and export functionality (#6415) * Exclude scraper configuration and symbol mapping from import and export * Update changelog --- CHANGELOG.md | 2 ++ apps/api/src/app/export/export.service.ts | 5 ----- .../src/app/services/import-activities.service.ts | 2 -- libs/common/src/lib/dtos/create-asset-profile.dto.ts | 11 ----------- .../interfaces/responses/export-response.interface.ts | 7 ++++++- test/import/ok/penthouse-apartment.json | 2 -- test/import/ok/sample.json | 4 ---- 7 files changed, 8 insertions(+), 25 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 667b25e5d..65d27e77a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Changed +- Excluded the scraper configuration from the import and export functionality +- Excluded the symbol mapping from the import and export functionality - Improved the language localization for Dutch (`nl`) - Improved the language localization for Italian (`it`) diff --git a/apps/api/src/app/export/export.service.ts b/apps/api/src/app/export/export.service.ts index d07b199be..55f8d7dc9 100644 --- a/apps/api/src/app/export/export.service.ts +++ b/apps/api/src/app/export/export.service.ts @@ -182,10 +182,8 @@ export class ExportService { isActive, isin, name, - scraperConfiguration, sectors, symbol, - symbolMapping, url }) => { return { @@ -204,11 +202,8 @@ export class ExportService { isin, marketData: marketDataByAssetProfile[id], name, - scraperConfiguration: - scraperConfiguration as unknown as Prisma.JsonArray, sectors: sectors as unknown as Prisma.JsonArray, symbol, - symbolMapping, url }; } diff --git a/apps/client/src/app/services/import-activities.service.ts b/apps/client/src/app/services/import-activities.service.ts index 94d8470f7..55b5c44d5 100644 --- a/apps/client/src/app/services/import-activities.service.ts +++ b/apps/client/src/app/services/import-activities.service.ts @@ -97,9 +97,7 @@ export class ImportActivitiesService { isin: null, marketData: [], name: symbol, - scraperConfiguration: null, sectors: [], - symbolMapping: {}, url: null }); } diff --git a/libs/common/src/lib/dtos/create-asset-profile.dto.ts b/libs/common/src/lib/dtos/create-asset-profile.dto.ts index 80d45ba42..85ad73cc0 100644 --- a/libs/common/src/lib/dtos/create-asset-profile.dto.ts +++ b/libs/common/src/lib/dtos/create-asset-profile.dto.ts @@ -5,7 +5,6 @@ import { IsArray, IsBoolean, IsEnum, - IsObject, IsOptional, IsString, IsUrl @@ -66,10 +65,6 @@ export class CreateAssetProfileDto { @IsString() name?: string; - @IsObject() - @IsOptional() - scraperConfiguration?: Prisma.InputJsonObject; - @IsArray() @IsOptional() sectors?: Prisma.InputJsonArray; @@ -77,12 +72,6 @@ export class CreateAssetProfileDto { @IsString() symbol: string; - @IsObject() - @IsOptional() - symbolMapping?: { - [dataProvider: string]: string; - }; - @IsOptional() @IsUrl({ protocols: ['https'], diff --git a/libs/common/src/lib/interfaces/responses/export-response.interface.ts b/libs/common/src/lib/interfaces/responses/export-response.interface.ts index 8b1697ca4..fa592faf2 100644 --- a/libs/common/src/lib/interfaces/responses/export-response.interface.ts +++ b/libs/common/src/lib/interfaces/responses/export-response.interface.ts @@ -27,7 +27,12 @@ export interface ExportResponse { > & { dataSource: DataSource; date: string; symbol: string })[]; assetProfiles: (Omit< SymbolProfile, - 'createdAt' | 'id' | 'updatedAt' | 'userId' + | 'createdAt' + | 'id' + | 'scraperConfiguration' + | 'symbolMapping' + | 'updatedAt' + | 'userId' > & { marketData: MarketData[]; })[]; diff --git a/test/import/ok/penthouse-apartment.json b/test/import/ok/penthouse-apartment.json index 0c35521e6..3b5e5420b 100644 --- a/test/import/ok/penthouse-apartment.json +++ b/test/import/ok/penthouse-apartment.json @@ -21,10 +21,8 @@ "isin": null, "marketData": [], "name": "Penthouse Apartment", - "scraperConfiguration": null, "sectors": [], "symbol": "7e91b7d4-1430-4212-8380-289a06c9bbc1", - "symbolMapping": {}, "url": null } ], diff --git a/test/import/ok/sample.json b/test/import/ok/sample.json index bc2798718..be385812a 100644 --- a/test/import/ok/sample.json +++ b/test/import/ok/sample.json @@ -41,10 +41,8 @@ "isin": null, "marketData": [], "name": "Account Opening Fee", - "scraperConfiguration": null, "sectors": [], "symbol": "14a69cb9-1e31-43fa-b320-83703d8ed74b", - "symbolMapping": {}, "url": null }, { @@ -63,10 +61,8 @@ "isin": null, "marketData": [], "name": "Penthouse Apartment", - "scraperConfiguration": null, "sectors": [], "symbol": "7e91b7d4-1430-4212-8380-289a06c9bbc1", - "symbolMapping": {}, "url": null } ], From b5eb7d988462578426b0712b0e763f806b30d0f0 Mon Sep 17 00:00:00 2001 From: Thomas Kaul <4159106+dtslvr@users.noreply.github.com> Date: Sun, 1 Mar 2026 10:02:36 +0100 Subject: [PATCH 065/224] Bugfix/resolve data source transformation in export and performance endpoint (#6411) * Resolve data source transformation in errors of performance endpoint and export functionality * Update changelog --- CHANGELOG.md | 5 +++++ .../transform-data-source-in-response.interceptor.ts | 2 ++ 2 files changed, 7 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 65d27e77a..684d41096 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,6 +14,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Improved the language localization for Dutch (`nl`) - Improved the language localization for Italian (`it`) +### Fixed + +- Resolved the data source transformation in the errors of the performance endpoint +- Resolved the data source transformation in the export functionality + ## 2.244.0 - 2026-02-28 ### Changed diff --git a/apps/api/src/interceptors/transform-data-source-in-response/transform-data-source-in-response.interceptor.ts b/apps/api/src/interceptors/transform-data-source-in-response/transform-data-source-in-response.interceptor.ts index eaa6dd08c..3cccd6efa 100644 --- a/apps/api/src/interceptors/transform-data-source-in-response/transform-data-source-in-response.interceptor.ts +++ b/apps/api/src/interceptors/transform-data-source-in-response/transform-data-source-in-response.interceptor.ts @@ -62,8 +62,10 @@ export class TransformDataSourceInResponseInterceptor< valueMap, object: data, paths: [ + 'activities[*].dataSource', 'activities[*].SymbolProfile.dataSource', 'benchmarks[*].dataSource', + 'errors[*].dataSource', 'fearAndGreedIndex.CRYPTOCURRENCIES.dataSource', 'fearAndGreedIndex.STOCKS.dataSource', 'holdings[*].dataSource', From 5bcdaa396fd6964348c7f9992265ad1fd261de1e Mon Sep 17 00:00:00 2001 From: Ariel Pons <78991076+arielpons@users.noreply.github.com> Date: Sun, 1 Mar 2026 06:05:45 -0300 Subject: [PATCH 066/224] Task/improve language localization for ES (#6417) * Improve language localization for ES * Update changelog --- CHANGELOG.md | 1 + apps/client/src/locales/messages.es.xlf | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 684d41096..5c1cbfa79 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 - Excluded the symbol mapping from the import and export functionality - Improved the language localization for Dutch (`nl`) - Improved the language localization for Italian (`it`) +- Improved the language localization for Spanish (`es`) ### Fixed diff --git a/apps/client/src/locales/messages.es.xlf b/apps/client/src/locales/messages.es.xlf index 74e0810c1..ba5a38d67 100644 --- a/apps/client/src/locales/messages.es.xlf +++ b/apps/client/src/locales/messages.es.xlf @@ -3344,7 +3344,7 @@ No Activities - No Activities + Sin actividades apps/client/src/app/components/admin-market-data/admin-market-data.component.ts 146 From 83347ba5dd307326e7664ed005751b95186c7370 Mon Sep 17 00:00:00 2001 From: Thomas Kaul <4159106+dtslvr@users.noreply.github.com> Date: Sun, 1 Mar 2026 10:07:50 +0100 Subject: [PATCH 067/224] Release 2.245.0 (#6418) --- CHANGELOG.md | 2 +- package-lock.json | 4 ++-- package.json | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5c1cbfa79..e34823b31 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,7 +5,7 @@ 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 +## 2.245.0 - 2026-03-01 ### Changed diff --git a/package-lock.json b/package-lock.json index dbe97b386..f7371da13 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "ghostfolio", - "version": "2.244.0", + "version": "2.245.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "ghostfolio", - "version": "2.244.0", + "version": "2.245.0", "hasInstallScript": true, "license": "AGPL-3.0", "dependencies": { diff --git a/package.json b/package.json index d1d0df2bb..794a09ea7 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "ghostfolio", - "version": "2.244.0", + "version": "2.245.0", "homepage": "https://ghostfol.io", "license": "AGPL-3.0", "repository": "https://github.com/ghostfolio/ghostfolio", From ddd36a1c7d7af0aa1027f6dcc10f1c07eb327843 Mon Sep 17 00:00:00 2001 From: Thomas Kaul <4159106+dtslvr@users.noreply.github.com> Date: Sun, 1 Mar 2026 12:35:29 +0100 Subject: [PATCH 068/224] Task/eliminate OnDestroy lifecycle hook from about overview page (#6419) * Eliminate OnDestroy lifecycle hook --- .../overview/about-overview-page.component.ts | 17 +++++------------ 1 file changed, 5 insertions(+), 12 deletions(-) diff --git a/apps/client/src/app/pages/about/overview/about-overview-page.component.ts b/apps/client/src/app/pages/about/overview/about-overview-page.component.ts index bea19a1b9..9c399762b 100644 --- a/apps/client/src/app/pages/about/overview/about-overview-page.component.ts +++ b/apps/client/src/app/pages/about/overview/about-overview-page.component.ts @@ -9,9 +9,10 @@ import { ChangeDetectorRef, Component, CUSTOM_ELEMENTS_SCHEMA, - OnDestroy, + DestroyRef, OnInit } from '@angular/core'; +import { takeUntilDestroyed } from '@angular/core/rxjs-interop'; import { MatButtonModule } from '@angular/material/button'; import { RouterModule } from '@angular/router'; import { IonIcon } from '@ionic/angular/standalone'; @@ -23,8 +24,6 @@ import { logoX, mail } from 'ionicons/icons'; -import { Subject } from 'rxjs'; -import { takeUntil } from 'rxjs/operators'; @Component({ imports: [CommonModule, IonIcon, MatButtonModule, RouterModule], @@ -33,7 +32,7 @@ import { takeUntil } from 'rxjs/operators'; styleUrls: ['./about-overview-page.scss'], templateUrl: './about-overview-page.html' }) -export class GfAboutOverviewPageComponent implements OnDestroy, OnInit { +export class GfAboutOverviewPageComponent implements OnInit { public hasPermissionForStatistics: boolean; public hasPermissionForSubscription: boolean; public isLoggedIn: boolean; @@ -43,11 +42,10 @@ export class GfAboutOverviewPageComponent implements OnDestroy, OnInit { public routerLinkOpenStartup = publicRoutes.openStartup.routerLink; public user: User; - private unsubscribeSubject = new Subject(); - public constructor( private changeDetectorRef: ChangeDetectorRef, private dataService: DataService, + private destroyRef: DestroyRef, private userService: UserService ) { const { globalPermissions } = this.dataService.fetchInfo(); @@ -67,7 +65,7 @@ export class GfAboutOverviewPageComponent implements OnDestroy, OnInit { public ngOnInit() { this.userService.stateChanged - .pipe(takeUntil(this.unsubscribeSubject)) + .pipe(takeUntilDestroyed(this.destroyRef)) .subscribe((state) => { if (state?.user) { this.user = state.user; @@ -76,9 +74,4 @@ export class GfAboutOverviewPageComponent implements OnDestroy, OnInit { } }); } - - public ngOnDestroy() { - this.unsubscribeSubject.next(); - this.unsubscribeSubject.complete(); - } } From 02a61b373ceebec54e7228e3e34f60a69f366083 Mon Sep 17 00:00:00 2001 From: slegarraga <64795732+slegarraga@users.noreply.github.com> Date: Sun, 1 Mar 2026 11:37:33 -0300 Subject: [PATCH 069/224] Task/eliminate OnDestroy lifecycle hook from register page (#6433) * Eliminate OnDestroy lifecycle hook --- .../pages/register/register-page.component.ts | 17 +++++------------ 1 file changed, 5 insertions(+), 12 deletions(-) diff --git a/apps/client/src/app/pages/register/register-page.component.ts b/apps/client/src/app/pages/register/register-page.component.ts index 21b26944e..3678f0249 100644 --- a/apps/client/src/app/pages/register/register-page.component.ts +++ b/apps/client/src/app/pages/register/register-page.component.ts @@ -7,15 +7,14 @@ import { DataService } from '@ghostfolio/ui/services'; import { Component, CUSTOM_ELEMENTS_SCHEMA, - OnDestroy, + DestroyRef, OnInit } from '@angular/core'; +import { takeUntilDestroyed } from '@angular/core/rxjs-interop'; import { MatButtonModule } from '@angular/material/button'; import { MatDialog } from '@angular/material/dialog'; import { Router, RouterModule } from '@angular/router'; import { DeviceDetectorService } from 'ngx-device-detector'; -import { Subject } from 'rxjs'; -import { takeUntil } from 'rxjs/operators'; import { UserAccountRegistrationDialogParams } from './user-account-registration-dialog/interfaces/interfaces'; import { GfUserAccountRegistrationDialogComponent } from './user-account-registration-dialog/user-account-registration-dialog.component'; @@ -28,7 +27,7 @@ import { GfUserAccountRegistrationDialogComponent } from './user-account-registr styleUrls: ['./register-page.scss'], templateUrl: './register-page.html' }) -export class GfRegisterPageComponent implements OnDestroy, OnInit { +export class GfRegisterPageComponent implements OnInit { public deviceType: string; public hasPermissionForAuthGoogle: boolean; public hasPermissionForAuthToken: boolean; @@ -37,10 +36,9 @@ export class GfRegisterPageComponent implements OnDestroy, OnInit { public historicalDataItems: LineChartItem[]; public info: InfoItem; - private unsubscribeSubject = new Subject(); - public constructor( private dataService: DataService, + private destroyRef: DestroyRef, private deviceService: DeviceDetectorService, private dialog: MatDialog, private router: Router, @@ -93,7 +91,7 @@ export class GfRegisterPageComponent implements OnDestroy, OnInit { dialogRef .afterClosed() - .pipe(takeUntil(this.unsubscribeSubject)) + .pipe(takeUntilDestroyed(this.destroyRef)) .subscribe((authToken) => { if (authToken) { this.tokenStorageService.saveToken(authToken, true); @@ -102,9 +100,4 @@ export class GfRegisterPageComponent implements OnDestroy, OnInit { } }); } - - public ngOnDestroy() { - this.unsubscribeSubject.next(); - this.unsubscribeSubject.complete(); - } } From 41de73fe41b6dfa835acbfff42ca992824be95b6 Mon Sep 17 00:00:00 2001 From: slegarraga <64795732+slegarraga@users.noreply.github.com> Date: Sun, 1 Mar 2026 12:06:26 -0300 Subject: [PATCH 070/224] Task/eliminate OnDestroy lifecycle hook from features page (#6431) * Eliminate OnDestroy lifecycle hook --- .../pages/features/features-page.component.ts | 16 +++++----------- 1 file changed, 5 insertions(+), 11 deletions(-) diff --git a/apps/client/src/app/pages/features/features-page.component.ts b/apps/client/src/app/pages/features/features-page.component.ts index b9eb91fe2..cef90f2e5 100644 --- a/apps/client/src/app/pages/features/features-page.component.ts +++ b/apps/client/src/app/pages/features/features-page.component.ts @@ -5,11 +5,11 @@ import { publicRoutes } from '@ghostfolio/common/routes/routes'; import { GfPremiumIndicatorComponent } from '@ghostfolio/ui/premium-indicator'; import { DataService } from '@ghostfolio/ui/services'; -import { ChangeDetectorRef, Component, OnDestroy } from '@angular/core'; +import { ChangeDetectorRef, Component, DestroyRef } from '@angular/core'; +import { takeUntilDestroyed } from '@angular/core/rxjs-interop'; import { MatButtonModule } from '@angular/material/button'; import { MatCardModule } from '@angular/material/card'; import { RouterModule } from '@angular/router'; -import { Subject, takeUntil } from 'rxjs'; @Component({ host: { class: 'page' }, @@ -23,7 +23,7 @@ import { Subject, takeUntil } from 'rxjs'; styleUrls: ['./features-page.scss'], templateUrl: './features-page.html' }) -export class GfFeaturesPageComponent implements OnDestroy { +export class GfFeaturesPageComponent { public hasPermissionForSubscription: boolean; public hasPermissionToCreateUser: boolean; public info: InfoItem; @@ -31,11 +31,10 @@ export class GfFeaturesPageComponent implements OnDestroy { public routerLinkResources = publicRoutes.resources.routerLink; public user: User; - private unsubscribeSubject = new Subject(); - public constructor( private changeDetectorRef: ChangeDetectorRef, private dataService: DataService, + private destroyRef: DestroyRef, private userService: UserService ) { this.info = this.dataService.fetchInfo(); @@ -43,7 +42,7 @@ export class GfFeaturesPageComponent implements OnDestroy { public ngOnInit() { this.userService.stateChanged - .pipe(takeUntil(this.unsubscribeSubject)) + .pipe(takeUntilDestroyed(this.destroyRef)) .subscribe((state) => { if (state?.user) { this.user = state.user; @@ -62,9 +61,4 @@ export class GfFeaturesPageComponent implements OnDestroy { permissions.createUserAccount ); } - - public ngOnDestroy() { - this.unsubscribeSubject.next(); - this.unsubscribeSubject.complete(); - } } From 8c83742d9c741db13e63fea943129eef43bb01a8 Mon Sep 17 00:00:00 2001 From: slegarraga <64795732+slegarraga@users.noreply.github.com> Date: Sun, 1 Mar 2026 12:07:50 -0300 Subject: [PATCH 071/224] Task/eliminate OnDestroy lifecycle hook from webauthn page (#6429) * Eliminate OnDestroy lifecycle hook --- .../pages/webauthn/webauthn-page.component.ts | 24 +++++++++---------- 1 file changed, 11 insertions(+), 13 deletions(-) diff --git a/apps/client/src/app/pages/webauthn/webauthn-page.component.ts b/apps/client/src/app/pages/webauthn/webauthn-page.component.ts index 74631eeca..8e7e58fd1 100644 --- a/apps/client/src/app/pages/webauthn/webauthn-page.component.ts +++ b/apps/client/src/app/pages/webauthn/webauthn-page.component.ts @@ -2,12 +2,16 @@ import { TokenStorageService } from '@ghostfolio/client/services/token-storage.s import { WebAuthnService } from '@ghostfolio/client/services/web-authn.service'; import { GfLogoComponent } from '@ghostfolio/ui/logo'; -import { ChangeDetectorRef, Component, OnDestroy, OnInit } from '@angular/core'; +import { + ChangeDetectorRef, + Component, + DestroyRef, + OnInit +} from '@angular/core'; +import { takeUntilDestroyed } from '@angular/core/rxjs-interop'; import { MatButtonModule } from '@angular/material/button'; import { MatProgressSpinnerModule } from '@angular/material/progress-spinner'; import { Router } from '@angular/router'; -import { Subject } from 'rxjs'; -import { takeUntil } from 'rxjs/operators'; @Component({ host: { class: 'page' }, @@ -16,13 +20,12 @@ import { takeUntil } from 'rxjs/operators'; styleUrls: ['./webauthn-page.scss'], templateUrl: './webauthn-page.html' }) -export class GfWebauthnPageComponent implements OnDestroy, OnInit { +export class GfWebauthnPageComponent implements OnInit { public hasError = false; - private unsubscribeSubject = new Subject(); - public constructor( private changeDetectorRef: ChangeDetectorRef, + private destroyRef: DestroyRef, private router: Router, private tokenStorageService: TokenStorageService, private webAuthnService: WebAuthnService @@ -35,7 +38,7 @@ export class GfWebauthnPageComponent implements OnDestroy, OnInit { public deregisterDevice() { this.webAuthnService .deregister() - .pipe(takeUntil(this.unsubscribeSubject)) + .pipe(takeUntilDestroyed(this.destroyRef)) .subscribe(() => { this.router.navigate(['/']); }); @@ -46,7 +49,7 @@ export class GfWebauthnPageComponent implements OnDestroy, OnInit { this.webAuthnService .login() - .pipe(takeUntil(this.unsubscribeSubject)) + .pipe(takeUntilDestroyed(this.destroyRef)) .subscribe( ({ authToken }) => { this.tokenStorageService.saveToken(authToken, false); @@ -59,9 +62,4 @@ export class GfWebauthnPageComponent implements OnDestroy, OnInit { } ); } - - public ngOnDestroy() { - this.unsubscribeSubject.next(); - this.unsubscribeSubject.complete(); - } } From 412b37956ae26298556c1c0573d9da1033c82c34 Mon Sep 17 00:00:00 2001 From: slegarraga <64795732+slegarraga@users.noreply.github.com> Date: Sun, 1 Mar 2026 12:09:23 -0300 Subject: [PATCH 072/224] Task/eliminate OnDestroy lifecycle hook from portfolio page (#6430) * Eliminate OnDestroy lifecycle hook --- .../portfolio/portfolio-page.component.ts | 22 +++++++++---------- 1 file changed, 10 insertions(+), 12 deletions(-) diff --git a/apps/client/src/app/pages/portfolio/portfolio-page.component.ts b/apps/client/src/app/pages/portfolio/portfolio-page.component.ts index 387e3fd0f..eb4935127 100644 --- a/apps/client/src/app/pages/portfolio/portfolio-page.component.ts +++ b/apps/client/src/app/pages/portfolio/portfolio-page.component.ts @@ -2,7 +2,13 @@ import { UserService } from '@ghostfolio/client/services/user/user.service'; import { TabConfiguration, User } from '@ghostfolio/common/interfaces'; import { internalRoutes } from '@ghostfolio/common/routes/routes'; -import { ChangeDetectorRef, Component, OnDestroy, OnInit } from '@angular/core'; +import { + ChangeDetectorRef, + Component, + DestroyRef, + OnInit +} from '@angular/core'; +import { takeUntilDestroyed } from '@angular/core/rxjs-interop'; import { MatTabsModule } from '@angular/material/tabs'; import { RouterModule } from '@angular/router'; import { addIcons } from 'ionicons'; @@ -14,8 +20,6 @@ import { swapVerticalOutline } from 'ionicons/icons'; import { DeviceDetectorService } from 'ngx-device-detector'; -import { Subject } from 'rxjs'; -import { takeUntil } from 'rxjs/operators'; @Component({ host: { class: 'page has-tabs' }, @@ -24,20 +28,19 @@ import { takeUntil } from 'rxjs/operators'; styleUrls: ['./portfolio-page.scss'], templateUrl: './portfolio-page.html' }) -export class PortfolioPageComponent implements OnDestroy, OnInit { +export class PortfolioPageComponent implements OnInit { public deviceType: string; public tabs: TabConfiguration[] = []; public user: User; - private unsubscribeSubject = new Subject(); - public constructor( private changeDetectorRef: ChangeDetectorRef, + private destroyRef: DestroyRef, private deviceService: DeviceDetectorService, private userService: UserService ) { this.userService.stateChanged - .pipe(takeUntil(this.unsubscribeSubject)) + .pipe(takeUntilDestroyed(this.destroyRef)) .subscribe((state) => { if (state?.user) { this.tabs = [ @@ -87,9 +90,4 @@ export class PortfolioPageComponent implements OnDestroy, OnInit { public ngOnInit() { this.deviceType = this.deviceService.getDeviceInfo().deviceType; } - - public ngOnDestroy() { - this.unsubscribeSubject.next(); - this.unsubscribeSubject.complete(); - } } From 28bf3dff079326ad190f9ecccf3487c02584c512 Mon Sep 17 00:00:00 2001 From: Thomas Kaul <4159106+dtslvr@users.noreply.github.com> Date: Sun, 1 Mar 2026 17:17:18 +0100 Subject: [PATCH 073/224] Task/remove unused OnDestroy hook in privacy policy page component (#6381) * Remove unused OnDestroy hook --- .../privacy-policy/privacy-policy-page.component.ts | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/apps/client/src/app/pages/about/privacy-policy/privacy-policy-page.component.ts b/apps/client/src/app/pages/about/privacy-policy/privacy-policy-page.component.ts index 78881cd2c..50e4e3e2f 100644 --- a/apps/client/src/app/pages/about/privacy-policy/privacy-policy-page.component.ts +++ b/apps/client/src/app/pages/about/privacy-policy/privacy-policy-page.component.ts @@ -1,6 +1,5 @@ -import { Component, OnDestroy } from '@angular/core'; +import { Component } from '@angular/core'; import { MarkdownModule } from 'ngx-markdown'; -import { Subject } from 'rxjs'; @Component({ imports: [MarkdownModule], @@ -8,11 +7,4 @@ import { Subject } from 'rxjs'; styleUrls: ['./privacy-policy-page.scss'], templateUrl: './privacy-policy-page.html' }) -export class GfPrivacyPolicyPageComponent implements OnDestroy { - private unsubscribeSubject = new Subject(); - - public ngOnDestroy() { - this.unsubscribeSubject.next(); - this.unsubscribeSubject.complete(); - } -} +export class GfPrivacyPolicyPageComponent {} From f3f655591149286b9e724b95a76188fbba8ac6ff Mon Sep 17 00:00:00 2001 From: Thomas Kaul <4159106+dtslvr@users.noreply.github.com> Date: Sun, 1 Mar 2026 17:17:53 +0100 Subject: [PATCH 074/224] Task/remove unused OnDestroy hook in blog page component (#6382) * Remove unused OnDestroy hook --- .../client/src/app/pages/blog/blog-page.component.ts | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/apps/client/src/app/pages/blog/blog-page.component.ts b/apps/client/src/app/pages/blog/blog-page.component.ts index 8a379a7e4..7f2c56d2d 100644 --- a/apps/client/src/app/pages/blog/blog-page.component.ts +++ b/apps/client/src/app/pages/blog/blog-page.component.ts @@ -1,13 +1,12 @@ import { hasPermission, permissions } from '@ghostfolio/common/permissions'; import { DataService } from '@ghostfolio/ui/services'; -import { Component, CUSTOM_ELEMENTS_SCHEMA, OnDestroy } from '@angular/core'; +import { Component, CUSTOM_ELEMENTS_SCHEMA } from '@angular/core'; import { MatCardModule } from '@angular/material/card'; import { RouterModule } from '@angular/router'; import { IonIcon } from '@ionic/angular/standalone'; import { addIcons } from 'ionicons'; import { chevronForwardOutline } from 'ionicons/icons'; -import { Subject } from 'rxjs'; @Component({ host: { class: 'page' }, @@ -17,11 +16,9 @@ import { Subject } from 'rxjs'; styleUrls: ['./blog-page.scss'], templateUrl: './blog-page.html' }) -export class GfBlogPageComponent implements OnDestroy { +export class GfBlogPageComponent { public hasPermissionForSubscription: boolean; - private unsubscribeSubject = new Subject(); - public constructor(private dataService: DataService) { const info = this.dataService.fetchInfo(); @@ -32,9 +29,4 @@ export class GfBlogPageComponent implements OnDestroy { addIcons({ chevronForwardOutline }); } - - public ngOnDestroy() { - this.unsubscribeSubject.next(); - this.unsubscribeSubject.complete(); - } } From 1ffe64e8066067da6366cd896de69ba5535b80d1 Mon Sep 17 00:00:00 2001 From: Thomas Kaul <4159106+dtslvr@users.noreply.github.com> Date: Sun, 1 Mar 2026 18:00:26 +0100 Subject: [PATCH 075/224] Task/upgrade Nx to version 22.5.3 (#6444) * Upgrade Nx to version 22.5.3 * Update changelog --- CHANGELOG.md | 6 + package-lock.json | 665 ++++++++++++++++++++++++---------------------- package.json | 22 +- 3 files changed, 370 insertions(+), 323 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e34823b31..d7ebb665c 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 + +- Upgraded `Nx` from version `22.4.5` to `22.5.3` + ## 2.245.0 - 2026-03-01 ### Changed diff --git a/package-lock.json b/package-lock.json index f7371da13..52b460666 100644 --- a/package-lock.json +++ b/package-lock.json @@ -108,16 +108,16 @@ "@eslint/js": "9.35.0", "@nestjs/schematics": "11.0.9", "@nestjs/testing": "11.1.14", - "@nx/angular": "22.4.5", - "@nx/eslint-plugin": "22.4.5", - "@nx/jest": "22.4.5", - "@nx/js": "22.4.5", - "@nx/module-federation": "22.4.5", - "@nx/nest": "22.4.5", - "@nx/node": "22.4.5", - "@nx/storybook": "22.4.5", - "@nx/web": "22.4.5", - "@nx/workspace": "22.4.5", + "@nx/angular": "22.5.3", + "@nx/eslint-plugin": "22.5.3", + "@nx/jest": "22.5.3", + "@nx/js": "22.5.3", + "@nx/module-federation": "22.5.3", + "@nx/nest": "22.5.3", + "@nx/node": "22.5.3", + "@nx/storybook": "22.5.3", + "@nx/web": "22.5.3", + "@nx/workspace": "22.5.3", "@schematics/angular": "21.1.1", "@storybook/addon-docs": "10.1.10", "@storybook/angular": "10.1.10", @@ -142,7 +142,7 @@ "jest": "30.2.0", "jest-environment-jsdom": "30.2.0", "jest-preset-angular": "16.0.0", - "nx": "22.4.5", + "nx": "22.5.3", "prettier": "3.8.1", "prettier-plugin-organize-attributes": "1.0.0", "prisma": "6.19.0", @@ -6672,15 +6672,15 @@ } }, "node_modules/@module-federation/node": { - "version": "2.7.31", - "resolved": "https://registry.npmjs.org/@module-federation/node/-/node-2.7.31.tgz", - "integrity": "sha512-NSa0PFDKDLxmtfmCVHW9RhtfD9mcNOrp1d+cjVEoxb5x8dDI4jQTi1o3nsa9ettxs3bVtWhAUEQUNQBQ6ZA+Hw==", + "version": "2.7.32", + "resolved": "https://registry.npmjs.org/@module-federation/node/-/node-2.7.32.tgz", + "integrity": "sha512-hUj5v2GGwpNzl2gaJS4AyzCYRzJBhN8875A+ucKF9tq3jaQb5zpy3izYMISqqbN2q9a7jz3nEUgwAh3pjri+rQ==", "dev": true, "license": "MIT", "dependencies": { - "@module-federation/enhanced": "2.0.0", - "@module-federation/runtime": "2.0.0", - "@module-federation/sdk": "2.0.0", + "@module-federation/enhanced": "2.0.1", + "@module-federation/runtime": "2.0.1", + "@module-federation/sdk": "2.0.1", "btoa": "1.2.1", "encoding": "^0.1.13", "node-fetch": "2.7.0" @@ -6695,26 +6695,26 @@ } }, "node_modules/@module-federation/node/node_modules/@module-federation/bridge-react-webpack-plugin": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@module-federation/bridge-react-webpack-plugin/-/bridge-react-webpack-plugin-2.0.0.tgz", - "integrity": "sha512-AVT/rZK6RHva6ZTYfsyQ8oP4xYNTws3OzqKW/YxWaLXwQ3oG9ZbF7fKl4jIKoMKuuy2L9MGVXS4CYPZy0s8fXg==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@module-federation/bridge-react-webpack-plugin/-/bridge-react-webpack-plugin-2.0.1.tgz", + "integrity": "sha512-D7LMW5EMAJShOMR1aZDAJ6s+MdsYDHaQyJADLQ3LaY0sne/BkVqkPikUwcO1IwOwKbXjYsDlQVOEvk9wZVRFhA==", "dev": true, "license": "MIT", "dependencies": { - "@module-federation/sdk": "2.0.0", + "@module-federation/sdk": "2.0.1", "@types/semver": "7.5.8", "semver": "7.6.3" } }, "node_modules/@module-federation/node/node_modules/@module-federation/cli": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@module-federation/cli/-/cli-2.0.0.tgz", - "integrity": "sha512-IWGWbdgoeNcuA5jzqPr6pLTN1hovMQh9A1lgJp5fAvKfICfFXKq7K8nwMAQrWD6iEKApIenI0madk1Dg2PU3pw==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@module-federation/cli/-/cli-2.0.1.tgz", + "integrity": "sha512-2SL5Y8iODNX10y9T3CBLhHjSXo4afnA1BK82m4sNfZebuVO+o34bxewqwod9xfWq9xhTZmOSFZ+n+lgTKRv+CQ==", "dev": true, "license": "MIT", "dependencies": { - "@module-federation/dts-plugin": "2.0.0", - "@module-federation/sdk": "2.0.0", + "@module-federation/dts-plugin": "2.0.1", + "@module-federation/sdk": "2.0.1", "chalk": "3.0.0", "commander": "11.1.0", "jiti": "2.4.2" @@ -6727,14 +6727,14 @@ } }, "node_modules/@module-federation/node/node_modules/@module-federation/data-prefetch": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@module-federation/data-prefetch/-/data-prefetch-2.0.0.tgz", - "integrity": "sha512-KPyZoqNrb5WgFY2owYnMaO2Mg2DYD6KXLVI7GPguj7Z/4pPKEC+SUjWU2FuSfTeyE6ZIi0iFGdwerxzlQ6nfmw==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@module-federation/data-prefetch/-/data-prefetch-2.0.1.tgz", + "integrity": "sha512-Kq0P1OABGt6QAvs6TaE/zY9Ut9Y/oJFrzoSF3eWaCYbUAr2KD2SpTyMsPz4ssBzjeKXTgimugh6tHHd6mpCBIQ==", "dev": true, "license": "MIT", "dependencies": { - "@module-federation/runtime": "2.0.0", - "@module-federation/sdk": "2.0.0", + "@module-federation/runtime": "2.0.1", + "@module-federation/sdk": "2.0.1", "fs-extra": "9.1.0" }, "peerDependencies": { @@ -6751,16 +6751,16 @@ } }, "node_modules/@module-federation/node/node_modules/@module-federation/dts-plugin": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@module-federation/dts-plugin/-/dts-plugin-2.0.0.tgz", - "integrity": "sha512-YyYMgLNARKdf3FLihnIzzUTgafHrqzR9YnKPmrfuCm2Jit+USqFT4QO58hcb0F5KSEyjB2ARPz9RM4XAVZhzMg==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@module-federation/dts-plugin/-/dts-plugin-2.0.1.tgz", + "integrity": "sha512-PLneTsf1fQS5/RTBedtLAAmCPRdMfIlhfJkOa8QH3WDJaQsqm8Wb3r2cTUBf2aNj/bP3aH/y6Hs9JFB/4x0l5g==", "dev": true, "license": "MIT", "dependencies": { - "@module-federation/error-codes": "2.0.0", - "@module-federation/managers": "2.0.0", - "@module-federation/sdk": "2.0.0", - "@module-federation/third-party-dts-extractor": "2.0.0", + "@module-federation/error-codes": "2.0.1", + "@module-federation/managers": "2.0.1", + "@module-federation/sdk": "2.0.1", + "@module-federation/third-party-dts-extractor": "2.0.1", "adm-zip": "^0.5.10", "ansi-colors": "^4.1.3", "axios": "^1.12.0", @@ -6785,23 +6785,23 @@ } }, "node_modules/@module-federation/node/node_modules/@module-federation/enhanced": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@module-federation/enhanced/-/enhanced-2.0.0.tgz", - "integrity": "sha512-xeVrGvypYMvN8gJulbro3j1t8+aS1f9xjj4quwAAqgJF0Nz8bt7sXUYJyjUHPmC2UZsShZ0GnPHJNtI8/2GYjA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@module-federation/bridge-react-webpack-plugin": "2.0.0", - "@module-federation/cli": "2.0.0", - "@module-federation/data-prefetch": "2.0.0", - "@module-federation/dts-plugin": "2.0.0", - "@module-federation/error-codes": "2.0.0", - "@module-federation/inject-external-runtime-core-plugin": "2.0.0", - "@module-federation/managers": "2.0.0", - "@module-federation/manifest": "2.0.0", - "@module-federation/rspack": "2.0.0", - "@module-federation/runtime-tools": "2.0.0", - "@module-federation/sdk": "2.0.0", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@module-federation/enhanced/-/enhanced-2.0.1.tgz", + "integrity": "sha512-EZIARQ/8ScoTP6PV8+E4SsmMYWK4ErrikZJ0G/FX8wvK8mCtdoKatFtvDN9++P6Nl78kN9zHYgAV4AHKdBVjfQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@module-federation/bridge-react-webpack-plugin": "2.0.1", + "@module-federation/cli": "2.0.1", + "@module-federation/data-prefetch": "2.0.1", + "@module-federation/dts-plugin": "2.0.1", + "@module-federation/error-codes": "2.0.1", + "@module-federation/inject-external-runtime-core-plugin": "2.0.1", + "@module-federation/managers": "2.0.1", + "@module-federation/manifest": "2.0.1", + "@module-federation/rspack": "2.0.1", + "@module-federation/runtime-tools": "2.0.1", + "@module-federation/sdk": "2.0.1", "btoa": "^1.2.1", "schema-utils": "^4.3.0", "upath": "2.0.1" @@ -6827,62 +6827,62 @@ } }, "node_modules/@module-federation/node/node_modules/@module-federation/error-codes": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@module-federation/error-codes/-/error-codes-2.0.0.tgz", - "integrity": "sha512-9oE+hXuPv2zej7AxJ5hOgeRqlPs98meooV2FiutTfftLAyy2N6+Kwmmz5NR9d9t91weJj8N0cSHFoyenNHKTVg==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@module-federation/error-codes/-/error-codes-2.0.1.tgz", + "integrity": "sha512-2bJF/ft+qL9L6Zvq2t/G9/f/0wFL73cM8/NJ04uyYz9BjIgvx28K5qu8/6+IwgEEKATG7vOhBBVj6wH3S+5ASA==", "dev": true, "license": "MIT" }, "node_modules/@module-federation/node/node_modules/@module-federation/inject-external-runtime-core-plugin": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@module-federation/inject-external-runtime-core-plugin/-/inject-external-runtime-core-plugin-2.0.0.tgz", - "integrity": "sha512-aZ6f4UU7KM5zBnHf3xsb2guqsfaEd6IlmuldbpED3JPk4ITwZk0DbvxRMr4prde7cfj8RH0nKMz2kmMncp+lIQ==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@module-federation/inject-external-runtime-core-plugin/-/inject-external-runtime-core-plugin-2.0.1.tgz", + "integrity": "sha512-oAA7G+4GCHM+WRYfscR/x4GwCyM9CEqfdD9/x2L6y8mtLWK9anRLKTocsI759AvzXsbT1m3EQ5ki1O6wlwDu3g==", "dev": true, "license": "MIT", "peerDependencies": { - "@module-federation/runtime-tools": "2.0.0" + "@module-federation/runtime-tools": "2.0.1" } }, "node_modules/@module-federation/node/node_modules/@module-federation/managers": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@module-federation/managers/-/managers-2.0.0.tgz", - "integrity": "sha512-ZmkRIujH+T3xvkmy04TNvviFH8xFOrNeKCLb4tlH4ifU/kLfjTu+PYO/KAEIsgtmrDnd52zTf22dg3ok85OAHA==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@module-federation/managers/-/managers-2.0.1.tgz", + "integrity": "sha512-KR01lSlcYRQ9C6hW2a8CQQtAE0LvfTLgtV/6ZNUTagw8sRfeDln+ggrZsYilKu9zl0i8RPDgpv/kS60o4lcxCQ==", "dev": true, "license": "MIT", "dependencies": { - "@module-federation/sdk": "2.0.0", + "@module-federation/sdk": "2.0.1", "find-pkg": "2.0.0", "fs-extra": "9.1.0" } }, "node_modules/@module-federation/node/node_modules/@module-federation/manifest": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@module-federation/manifest/-/manifest-2.0.0.tgz", - "integrity": "sha512-AXwYyGiDJdfP9MteKyIdJrLwG5tp4qKaq0uOPiWHilYN3/21G0DM7f30HgJqgx3WSTFSh7hcq0a3V3EZHH/9TA==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@module-federation/manifest/-/manifest-2.0.1.tgz", + "integrity": "sha512-p8nYGjHWp17MsYdW/Vv0ogBDiTTsI1PHWPQbvVIqLQXDqwiesaRSRR1zziECXQoEL8lV5Bs+uSkcaJGhea9P+A==", "dev": true, "license": "MIT", "dependencies": { - "@module-federation/dts-plugin": "2.0.0", - "@module-federation/managers": "2.0.0", - "@module-federation/sdk": "2.0.0", + "@module-federation/dts-plugin": "2.0.1", + "@module-federation/managers": "2.0.1", + "@module-federation/sdk": "2.0.1", "chalk": "3.0.0", "find-pkg": "2.0.0" } }, "node_modules/@module-federation/node/node_modules/@module-federation/rspack": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@module-federation/rspack/-/rspack-2.0.0.tgz", - "integrity": "sha512-1kziarKrPRM+rJax/AaMEZTwu7ORGed2xSxfdoP9GEbAFEGyNliadvw4kB6PqAfLad3PI4lQMX2vGMLI1KoyVQ==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@module-federation/rspack/-/rspack-2.0.1.tgz", + "integrity": "sha512-SAlNE8iclFmzrKtx3/C2GivXYx6nPzx4MgQV01QG/a4LpnLbwlxzdZu3rqQ2swp4NNWT/t/GT7Y+7gfhyVa7mg==", "dev": true, "license": "MIT", "dependencies": { - "@module-federation/bridge-react-webpack-plugin": "2.0.0", - "@module-federation/dts-plugin": "2.0.0", - "@module-federation/inject-external-runtime-core-plugin": "2.0.0", - "@module-federation/managers": "2.0.0", - "@module-federation/manifest": "2.0.0", - "@module-federation/runtime-tools": "2.0.0", - "@module-federation/sdk": "2.0.0", + "@module-federation/bridge-react-webpack-plugin": "2.0.1", + "@module-federation/dts-plugin": "2.0.1", + "@module-federation/inject-external-runtime-core-plugin": "2.0.1", + "@module-federation/managers": "2.0.1", + "@module-federation/manifest": "2.0.1", + "@module-federation/runtime-tools": "2.0.1", + "@module-federation/sdk": "2.0.1", "btoa": "1.2.1" }, "peerDependencies": { @@ -6900,50 +6900,50 @@ } }, "node_modules/@module-federation/node/node_modules/@module-federation/runtime": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@module-federation/runtime/-/runtime-2.0.0.tgz", - "integrity": "sha512-vPxQrmQNq3Z1T+1fkHEvFwTdJq9wuCLvdp/lpu9k2Oy7QP/Pj6QoQ/S7J5MCIAoRwj8Wj3z3ma21/DyHwLGvzA==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@module-federation/runtime/-/runtime-2.0.1.tgz", + "integrity": "sha512-UQ72P5Oo40dS6vdhHetwTtIsbGciEr+bjoYvDgh1WLPfFlTYd8zo9cLfqaf3juuPfV3cMVARAVPmh16lQYpUGA==", "dev": true, "license": "MIT", "dependencies": { - "@module-federation/error-codes": "2.0.0", - "@module-federation/runtime-core": "2.0.0", - "@module-federation/sdk": "2.0.0" + "@module-federation/error-codes": "2.0.1", + "@module-federation/runtime-core": "2.0.1", + "@module-federation/sdk": "2.0.1" } }, "node_modules/@module-federation/node/node_modules/@module-federation/runtime-core": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@module-federation/runtime-core/-/runtime-core-2.0.0.tgz", - "integrity": "sha512-UhIGUs7Mg+TwMI2lgaLnj4UehpoyXbR7HDb2+vLikgBulPmFtodeWfsxCgENEwKsIY1vS0lOun15lNOn1vo3Xg==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@module-federation/runtime-core/-/runtime-core-2.0.1.tgz", + "integrity": "sha512-gOuCPSHoQGUGwlxfSTMInFX+QvLxdEWegGGMiLdU5vqbXuva4E9M+kXBBO7/0MkcBPMmVs0wOJGm0XOLeV2f1Q==", "dev": true, "license": "MIT", "dependencies": { - "@module-federation/error-codes": "2.0.0", - "@module-federation/sdk": "2.0.0" + "@module-federation/error-codes": "2.0.1", + "@module-federation/sdk": "2.0.1" } }, "node_modules/@module-federation/node/node_modules/@module-federation/runtime-tools": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@module-federation/runtime-tools/-/runtime-tools-2.0.0.tgz", - "integrity": "sha512-eMDQN4hYpwvUnCNMjfQdtPVzYaO2DdauemHVc4HnyibgqijRzBwJh9bI2ph4R1xfYEm18+QmTrfXrRlaK2Xizw==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@module-federation/runtime-tools/-/runtime-tools-2.0.1.tgz", + "integrity": "sha512-AStdwBtsGB3jIfDg9oP+KyVPsimdaeHsP855gqCxDp1hi2+GKjlZWZx9ThkS8NytVSXSUysxqoUL1ivDoKgcCQ==", "dev": true, "license": "MIT", "dependencies": { - "@module-federation/runtime": "2.0.0", - "@module-federation/webpack-bundler-runtime": "2.0.0" + "@module-federation/runtime": "2.0.1", + "@module-federation/webpack-bundler-runtime": "2.0.1" } }, "node_modules/@module-federation/node/node_modules/@module-federation/sdk": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@module-federation/sdk/-/sdk-2.0.0.tgz", - "integrity": "sha512-JYd1wTulsaoLT7HTk2oXL5y5797Z+H4mzxuUEKnSJo7R34RZSqehsqPSND7n0HT/1nf7uyn0Rb4qBfR3BVvdHQ==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@module-federation/sdk/-/sdk-2.0.1.tgz", + "integrity": "sha512-32PwudojGjog51cwpTali7D6ud82oVgsyvOx9JjAzhvXBX96YI4mRsursuWcthDxmigJP9ZvUTXDuRUEDh1OQA==", "dev": true, "license": "MIT" }, "node_modules/@module-federation/node/node_modules/@module-federation/third-party-dts-extractor": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@module-federation/third-party-dts-extractor/-/third-party-dts-extractor-2.0.0.tgz", - "integrity": "sha512-B99+Wkbd2xIodVTjNCeFtFC89Uh2/AtYkSESlz4+6Cec42wyqrGxyfYm4qRY0LhJI+YmZXLk/RTm85m15eBKKg==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@module-federation/third-party-dts-extractor/-/third-party-dts-extractor-2.0.1.tgz", + "integrity": "sha512-neKSr6FNUeGRh+YR57l/QZUzPytJXuJx+babF7j5iGJG3FP+kfizr6QD0hgVis5KEoXMVbQ8yyvG0slERizeyw==", "dev": true, "license": "MIT", "dependencies": { @@ -6953,14 +6953,14 @@ } }, "node_modules/@module-federation/node/node_modules/@module-federation/webpack-bundler-runtime": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@module-federation/webpack-bundler-runtime/-/webpack-bundler-runtime-2.0.0.tgz", - "integrity": "sha512-XxiFR/A1G1fa9hTyylWNbs6yEU2hC7FqHAArFptD4U9qp/xyoLgqbK4M8LwltOAyAM8hRofcMdSyiRKVlWqAfQ==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@module-federation/webpack-bundler-runtime/-/webpack-bundler-runtime-2.0.1.tgz", + "integrity": "sha512-u1NId3SF4lHDTmD2CHFEszulmXmIq1TGw9JYvnLx5rKJL7xt3aNxcb1GvkaYbRNVBXhSMjJ75E5LsQlZzyBx9A==", "dev": true, "license": "MIT", "dependencies": { - "@module-federation/runtime": "2.0.0", - "@module-federation/sdk": "2.0.0" + "@module-federation/runtime": "2.0.1", + "@module-federation/sdk": "2.0.1" } }, "node_modules/@module-federation/node/node_modules/jiti": { @@ -8282,20 +8282,20 @@ } }, "node_modules/@nx/angular": { - "version": "22.4.5", - "resolved": "https://registry.npmjs.org/@nx/angular/-/angular-22.4.5.tgz", - "integrity": "sha512-mwffAG7qhElwtWCEIaH7bTJuE3foaFBa3LWReqNc9HkIZmka0BDHRReg3wyhfSGq4ZQlYXK5sQS2uDJd+Qj97Q==", + "version": "22.5.3", + "resolved": "https://registry.npmjs.org/@nx/angular/-/angular-22.5.3.tgz", + "integrity": "sha512-Z5vNcPl95CsTnRhDszWZ0ort22dEtMxdqJFkVzdNwolhfiLm1eKP2Rc8q9MnUdrZMeTqDKnCckG2qs12FZrIkw==", "dev": true, "license": "MIT", "dependencies": { - "@nx/devkit": "22.4.5", - "@nx/eslint": "22.4.5", - "@nx/js": "22.4.5", - "@nx/module-federation": "22.4.5", - "@nx/rspack": "22.4.5", - "@nx/web": "22.4.5", - "@nx/webpack": "22.4.5", - "@nx/workspace": "22.4.5", + "@nx/devkit": "22.5.3", + "@nx/eslint": "22.5.3", + "@nx/js": "22.5.3", + "@nx/module-federation": "22.5.3", + "@nx/rspack": "22.5.3", + "@nx/web": "22.5.3", + "@nx/webpack": "22.5.3", + "@nx/workspace": "22.5.3", "@phenomnomnominal/tsquery": "~6.1.4", "@typescript-eslint/type-utils": "^8.0.0", "enquirer": "~2.3.6", @@ -8343,15 +8343,15 @@ } }, "node_modules/@nx/cypress": { - "version": "22.4.5", - "resolved": "https://registry.npmjs.org/@nx/cypress/-/cypress-22.4.5.tgz", - "integrity": "sha512-FAGLQa7dnMW5Z93bS5isw9WgVNapCOgRFgxl9sA1ePstte3Vh0ajRpvVjVoeVHyA3qg6aQbE41ctErOdq/p5bg==", + "version": "22.5.3", + "resolved": "https://registry.npmjs.org/@nx/cypress/-/cypress-22.5.3.tgz", + "integrity": "sha512-0jIYOhU1sFv5w2NYmyxIdpT4pC7QvUphrM4QLyUk8nEfO5gwfmON7JLNbtDveX+FeGpjy1zDjoBdd2OBzqUEcA==", "dev": true, "license": "MIT", "dependencies": { - "@nx/devkit": "22.4.5", - "@nx/eslint": "22.4.5", - "@nx/js": "22.4.5", + "@nx/devkit": "22.5.3", + "@nx/eslint": "22.5.3", + "@nx/js": "22.5.3", "@phenomnomnominal/tsquery": "~6.1.4", "detect-port": "^1.5.1", "semver": "^7.6.3", @@ -8368,16 +8368,16 @@ } }, "node_modules/@nx/devkit": { - "version": "22.4.5", - "resolved": "https://registry.npmjs.org/@nx/devkit/-/devkit-22.4.5.tgz", - "integrity": "sha512-mw5G6k/XTkL675eVIcFpyZdfdIc3wQMSSGWzfA6tQGmANDYc/NFGeZR9wDqXDceHXnYKoRO6g6GhKTOHUCW23Q==", + "version": "22.5.3", + "resolved": "https://registry.npmjs.org/@nx/devkit/-/devkit-22.5.3.tgz", + "integrity": "sha512-zhRNTFsi4pbwg7L/zhBHtTOSevlgwm1iKlhPlQWoOv2PR6b+3JvjL8o4P1MbkIkut3Lsn+oTuJJ1LUPlr5vprg==", "dev": true, "license": "MIT", "dependencies": { "@zkochan/js-yaml": "0.0.7", "ejs": "^3.1.7", "enquirer": "~2.3.6", - "minimatch": "10.1.1", + "minimatch": "10.2.1", "semver": "^7.6.3", "tslib": "^2.3.0", "yargs-parser": "21.1.1" @@ -8386,14 +8386,37 @@ "nx": ">= 21 <= 23 || ^22.0.0-0" } }, + "node_modules/@nx/devkit/node_modules/balanced-match": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-4.0.4.tgz", + "integrity": "sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==", + "dev": true, + "license": "MIT", + "engines": { + "node": "18 || 20 || >=22" + } + }, + "node_modules/@nx/devkit/node_modules/brace-expansion": { + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.4.tgz", + "integrity": "sha512-h+DEnpVvxmfVefa4jFbCf5HdH5YMDXRsmKflpf1pILZWRFlTbJpxeU55nJl4Smt5HQaGzg1o6RHFPJaOqnmBDg==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^4.0.2" + }, + "engines": { + "node": "18 || 20 || >=22" + } + }, "node_modules/@nx/devkit/node_modules/minimatch": { - "version": "10.1.1", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.1.1.tgz", - "integrity": "sha512-enIvLvRAFZYXJzkCYG5RKmPfrFArdLv+R+lbQ53BmIMLIry74bjKzX6iHAm8WYamJkhSSEabrWN5D97XnKObjQ==", + "version": "10.2.1", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.1.tgz", + "integrity": "sha512-MClCe8IL5nRRmawL6ib/eT4oLyeKMGCghibcDWK+J0hh0Q8kqSdia6BvbRMVk6mPa6WqUa5uR2oxt6C5jd533A==", "dev": true, "license": "BlueOak-1.0.0", "dependencies": { - "@isaacs/brace-expansion": "^5.0.0" + "brace-expansion": "^5.0.2" }, "engines": { "node": "20 || >=22" @@ -8403,33 +8426,33 @@ } }, "node_modules/@nx/docker": { - "version": "22.4.5", - "resolved": "https://registry.npmjs.org/@nx/docker/-/docker-22.4.5.tgz", - "integrity": "sha512-ZgBjd/HCgqkulYJwUH+xQvgsoupVD+2leiFmK5lFjb6IDny/W1uB3EVL5BZxrz8ftMoqiq+AP6Ubiaj99V4hzQ==", + "version": "22.5.3", + "resolved": "https://registry.npmjs.org/@nx/docker/-/docker-22.5.3.tgz", + "integrity": "sha512-4BO1hAyun2MM15w1oldUZtCvZEZlDXOCeEkimVij9znk6t4FUBnH7v87Uj4w5dhJAWB7yJFgQbF5w1fZbhRXfw==", "dev": true, "license": "MIT", "dependencies": { - "@nx/devkit": "22.4.5", + "@nx/devkit": "22.5.3", "enquirer": "~2.3.6", "tslib": "^2.3.0" } }, "node_modules/@nx/eslint": { - "version": "22.4.5", - "resolved": "https://registry.npmjs.org/@nx/eslint/-/eslint-22.4.5.tgz", - "integrity": "sha512-/N/kG86gqagDziC7Ij/WwAnjjXx55E1Jbpp3kkau3Ncj+wjPoLqCebpg6aW83VJQ7a4SUU0BO3U5bkqQZPGBXQ==", + "version": "22.5.3", + "resolved": "https://registry.npmjs.org/@nx/eslint/-/eslint-22.5.3.tgz", + "integrity": "sha512-XJKpwnSJRCat+81sUDdJWWvKz3vKo/3X9oHMGDzTYx3mexCgKgpmHBuRVgnZ9n2IVDx8S5ye4ICc9qiY6oHWIA==", "dev": true, "license": "MIT", "dependencies": { - "@nx/devkit": "22.4.5", - "@nx/js": "22.4.5", + "@nx/devkit": "22.5.3", + "@nx/js": "22.5.3", "semver": "^7.6.3", "tslib": "^2.3.0", "typescript": "~5.9.2" }, "peerDependencies": { "@zkochan/js-yaml": "0.0.7", - "eslint": "^8.0.0 || ^9.0.0" + "eslint": "^8.0.0 || ^9.0.0 || ^10.0.0" }, "peerDependenciesMeta": { "@zkochan/js-yaml": { @@ -8438,14 +8461,14 @@ } }, "node_modules/@nx/eslint-plugin": { - "version": "22.4.5", - "resolved": "https://registry.npmjs.org/@nx/eslint-plugin/-/eslint-plugin-22.4.5.tgz", - "integrity": "sha512-Kb3owVrbhRkJAjqEDsgDs8eSlI2/uEFOS35a8Z1drHIpMF6Zt9OHQf6bKELeXzG3fC2AGM3pyunauhbJ/ZmqMw==", + "version": "22.5.3", + "resolved": "https://registry.npmjs.org/@nx/eslint-plugin/-/eslint-plugin-22.5.3.tgz", + "integrity": "sha512-dFz3nSUOV+VLc+ZQxWncKINhych6h5oEfInWp1+5WkeUBW5/x77IsM3Hpq1JrjAK6dqXjmzTsFnoU8c5Cf1Q4w==", "dev": true, "license": "MIT", "dependencies": { - "@nx/devkit": "22.4.5", - "@nx/js": "22.4.5", + "@nx/devkit": "22.5.3", + "@nx/js": "22.5.3", "@phenomnomnominal/tsquery": "~6.1.4", "@typescript-eslint/type-utils": "^8.0.0", "@typescript-eslint/utils": "^8.0.0", @@ -8497,22 +8520,22 @@ } }, "node_modules/@nx/jest": { - "version": "22.4.5", - "resolved": "https://registry.npmjs.org/@nx/jest/-/jest-22.4.5.tgz", - "integrity": "sha512-qlEJc0Jbp8E14g7+piHH8DXsAm6C3w1CLuvtE57+LFMhM2zbBDiQ8oeXBdFPEHLCfpbSK/4yCSEmkUj1Yyrs2A==", + "version": "22.5.3", + "resolved": "https://registry.npmjs.org/@nx/jest/-/jest-22.5.3.tgz", + "integrity": "sha512-4yaGlApTR09zdz4fC4Ep0aENcaon5rDRDOUnEJblU67ik35jds9mczHq2rBMJO4Cnjj1pM9acm08Vb0Wg+9cuQ==", "dev": true, "license": "MIT", "dependencies": { "@jest/reporters": "^30.0.2", "@jest/test-result": "^30.0.2", - "@nx/devkit": "22.4.5", - "@nx/js": "22.4.5", + "@nx/devkit": "22.5.3", + "@nx/js": "22.5.3", "@phenomnomnominal/tsquery": "~6.1.4", "identity-obj-proxy": "3.0.0", "jest-config": "^30.0.2", "jest-resolve": "^30.0.2", "jest-util": "^30.0.2", - "minimatch": "10.1.1", + "minimatch": "10.2.1", "picocolors": "^1.1.0", "resolve.exports": "2.0.3", "semver": "^7.6.3", @@ -8520,14 +8543,37 @@ "yargs-parser": "21.1.1" } }, + "node_modules/@nx/jest/node_modules/balanced-match": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-4.0.4.tgz", + "integrity": "sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==", + "dev": true, + "license": "MIT", + "engines": { + "node": "18 || 20 || >=22" + } + }, + "node_modules/@nx/jest/node_modules/brace-expansion": { + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.4.tgz", + "integrity": "sha512-h+DEnpVvxmfVefa4jFbCf5HdH5YMDXRsmKflpf1pILZWRFlTbJpxeU55nJl4Smt5HQaGzg1o6RHFPJaOqnmBDg==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^4.0.2" + }, + "engines": { + "node": "18 || 20 || >=22" + } + }, "node_modules/@nx/jest/node_modules/minimatch": { - "version": "10.1.1", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.1.1.tgz", - "integrity": "sha512-enIvLvRAFZYXJzkCYG5RKmPfrFArdLv+R+lbQ53BmIMLIry74bjKzX6iHAm8WYamJkhSSEabrWN5D97XnKObjQ==", + "version": "10.2.1", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.1.tgz", + "integrity": "sha512-MClCe8IL5nRRmawL6ib/eT4oLyeKMGCghibcDWK+J0hh0Q8kqSdia6BvbRMVk6mPa6WqUa5uR2oxt6C5jd533A==", "dev": true, "license": "BlueOak-1.0.0", "dependencies": { - "@isaacs/brace-expansion": "^5.0.0" + "brace-expansion": "^5.0.2" }, "engines": { "node": "20 || >=22" @@ -8537,9 +8583,9 @@ } }, "node_modules/@nx/js": { - "version": "22.4.5", - "resolved": "https://registry.npmjs.org/@nx/js/-/js-22.4.5.tgz", - "integrity": "sha512-t8972z2uF6X5i4FFmTlnvSwwxfHkk87zBpKQK0yMH5CzOENViVFNbiPnbvCIJcGNrgVUSALL3f2ngwKcTZObmA==", + "version": "22.5.3", + "resolved": "https://registry.npmjs.org/@nx/js/-/js-22.5.3.tgz", + "integrity": "sha512-gglQYL6GeSH0mt6NpEFTXMFFFePU3B7TEyZq7LLUYZDH5y65izgNpdSAuEqYR7xHLtahVnesDlhPw3rtRiwMwA==", "dev": true, "license": "MIT", "dependencies": { @@ -8550,8 +8596,8 @@ "@babel/preset-env": "^7.23.2", "@babel/preset-typescript": "^7.22.5", "@babel/runtime": "^7.22.6", - "@nx/devkit": "22.4.5", - "@nx/workspace": "22.4.5", + "@nx/devkit": "22.5.3", + "@nx/workspace": "22.5.3", "@zkochan/js-yaml": "0.0.7", "babel-plugin-const-enum": "^1.0.1", "babel-plugin-macros": "^3.1.0", @@ -8625,18 +8671,18 @@ } }, "node_modules/@nx/module-federation": { - "version": "22.4.5", - "resolved": "https://registry.npmjs.org/@nx/module-federation/-/module-federation-22.4.5.tgz", - "integrity": "sha512-aNO595Xk0B4av9tpAaePF0jjDooAiXN34xEpFleSCmf8y31371JfkI8WMSnIZLa5ehyk1U+oMxHyYtt7v0RFWw==", + "version": "22.5.3", + "resolved": "https://registry.npmjs.org/@nx/module-federation/-/module-federation-22.5.3.tgz", + "integrity": "sha512-dKRkT/ULV+nXr7O25YMDwQu/4nxl27AcHJfOmVBVKquXrtrBu/d6dbypfFDMyr5pXqR5gb2euEw0mGVMyHLTiA==", "dev": true, "license": "MIT", "dependencies": { "@module-federation/enhanced": "^0.21.2", "@module-federation/node": "^2.7.21", "@module-federation/sdk": "^0.21.2", - "@nx/devkit": "22.4.5", - "@nx/js": "22.4.5", - "@nx/web": "22.4.5", + "@nx/devkit": "22.5.3", + "@nx/js": "22.5.3", + "@nx/web": "22.5.3", "@rspack/core": "1.6.8", "express": "^4.21.2", "http-proxy-middleware": "^3.0.5", @@ -8947,41 +8993,41 @@ } }, "node_modules/@nx/nest": { - "version": "22.4.5", - "resolved": "https://registry.npmjs.org/@nx/nest/-/nest-22.4.5.tgz", - "integrity": "sha512-cFufm3cPuy7Cj10D8BB2Y+Vo1w/1ihQGeduXprC0gs719dI5zvyG8bVOYJ+m87HHdFVQ8ckIVVifO6T7ujWgFw==", + "version": "22.5.3", + "resolved": "https://registry.npmjs.org/@nx/nest/-/nest-22.5.3.tgz", + "integrity": "sha512-DShcD4HdaABg9L7/qgLVgZj0LLSaaYa7Rrj8zquMGGZXrxozCTKzn/7vWrN7Am9hY4wEwaXTXwauHAFoIj9C9A==", "dev": true, "license": "MIT", "dependencies": { "@nestjs/schematics": "^11.0.0", - "@nx/devkit": "22.4.5", - "@nx/eslint": "22.4.5", - "@nx/js": "22.4.5", - "@nx/node": "22.4.5", + "@nx/devkit": "22.5.3", + "@nx/eslint": "22.5.3", + "@nx/js": "22.5.3", + "@nx/node": "22.5.3", "tslib": "^2.3.0" } }, "node_modules/@nx/node": { - "version": "22.4.5", - "resolved": "https://registry.npmjs.org/@nx/node/-/node-22.4.5.tgz", - "integrity": "sha512-ZYN3uIeUs0jKPX9Io75DkISMo5ha15djVLPNFhsh6qgQkL7+mqXGeW3QiEso16XZqbl0Iw2Ye5msrBO6UShFkQ==", + "version": "22.5.3", + "resolved": "https://registry.npmjs.org/@nx/node/-/node-22.5.3.tgz", + "integrity": "sha512-szdpsyRUzXBhMIiEk+zI3XPP/e0U1wNmIzkvgCS1e+ejsA1jq0EF5sppkdwJEQVAb6O5hiCPKED+1sSo4TR4/A==", "dev": true, "license": "MIT", "dependencies": { - "@nx/devkit": "22.4.5", - "@nx/docker": "22.4.5", - "@nx/eslint": "22.4.5", - "@nx/jest": "22.4.5", - "@nx/js": "22.4.5", + "@nx/devkit": "22.5.3", + "@nx/docker": "22.5.3", + "@nx/eslint": "22.5.3", + "@nx/jest": "22.5.3", + "@nx/js": "22.5.3", "kill-port": "^1.6.1", "tcp-port-used": "^1.0.2", "tslib": "^2.3.0" } }, "node_modules/@nx/nx-darwin-arm64": { - "version": "22.4.5", - "resolved": "https://registry.npmjs.org/@nx/nx-darwin-arm64/-/nx-darwin-arm64-22.4.5.tgz", - "integrity": "sha512-zdRHZv1AMvzgp+5g2VZNXXuqk0/n1wOFksOeZ6BRyKg6hC2YkjGyn5xle/UK668MDAwe9KKm4jizvztK/LlPuA==", + "version": "22.5.3", + "resolved": "https://registry.npmjs.org/@nx/nx-darwin-arm64/-/nx-darwin-arm64-22.5.3.tgz", + "integrity": "sha512-cKXBq5bJanXp8uv6+wPvx/G4q4oFpOxMSPGaeFOVhbul2QHGGq+XMcSo+D8aYJCsk1YnbyAnnQ8r8RH/kTK5Mw==", "cpu": [ "arm64" ], @@ -8993,9 +9039,9 @@ ] }, "node_modules/@nx/nx-darwin-x64": { - "version": "22.4.5", - "resolved": "https://registry.npmjs.org/@nx/nx-darwin-x64/-/nx-darwin-x64-22.4.5.tgz", - "integrity": "sha512-1NVWaSgpa8yawi2UILX4NE9UcMuNzAAGh95JSV2yJovRfKxFQgQSB6hj0gpJu+TLLVCroTqy4woSQ2a0SPodeQ==", + "version": "22.5.3", + "resolved": "https://registry.npmjs.org/@nx/nx-darwin-x64/-/nx-darwin-x64-22.5.3.tgz", + "integrity": "sha512-mToS41o8I+8CfxYVRMTISkgT7I1cnazgwMf7U9DoLqKOwOZzj9WD3NmsWc1h69QNJPltbeRPS8y/wnhu7RHzRA==", "cpu": [ "x64" ], @@ -9007,9 +9053,9 @@ ] }, "node_modules/@nx/nx-freebsd-x64": { - "version": "22.4.5", - "resolved": "https://registry.npmjs.org/@nx/nx-freebsd-x64/-/nx-freebsd-x64-22.4.5.tgz", - "integrity": "sha512-baaLz53wr/HsVfSJ7ZgIFCPAb/OtP7yPPasb3eIu65oVhSswGfgvz9+YINhuInUgW7x7STmRnhGeR8pj6iqFqw==", + "version": "22.5.3", + "resolved": "https://registry.npmjs.org/@nx/nx-freebsd-x64/-/nx-freebsd-x64-22.5.3.tgz", + "integrity": "sha512-CAWysdFSZVbTfdjNXojd9TgXbZiK9i0k3njROeV+jORsDWw4Eth3PDmK94Wk916b3n2hS0UjyI6RZaMy2GEqzA==", "cpu": [ "x64" ], @@ -9021,9 +9067,9 @@ ] }, "node_modules/@nx/nx-linux-arm-gnueabihf": { - "version": "22.4.5", - "resolved": "https://registry.npmjs.org/@nx/nx-linux-arm-gnueabihf/-/nx-linux-arm-gnueabihf-22.4.5.tgz", - "integrity": "sha512-wRBPv/l39tz+sQjZUH4hygCsd/DoUXUbDYkR6lnNXWHAVyPUh48/27JozM8hD3o/G3O2Vd8PFQasIXtvy2GS0Q==", + "version": "22.5.3", + "resolved": "https://registry.npmjs.org/@nx/nx-linux-arm-gnueabihf/-/nx-linux-arm-gnueabihf-22.5.3.tgz", + "integrity": "sha512-PRjPrijQQbdrvYwNuA3xQ3VXEQ4zfhnPjy+S2ZlQZqhFI4mlP22xfhOH1bQ7pIfzCNC2f/J9UMNYOrq/bEFjBg==", "cpu": [ "arm" ], @@ -9035,9 +9081,9 @@ ] }, "node_modules/@nx/nx-linux-arm64-gnu": { - "version": "22.4.5", - "resolved": "https://registry.npmjs.org/@nx/nx-linux-arm64-gnu/-/nx-linux-arm64-gnu-22.4.5.tgz", - "integrity": "sha512-6B/yCFiqjvV2Bkz6MKUtfFWjwtiF53DN07K1BFksMpQef+h2yE1IrGaG/OCl6VaVl4VRzQgLOluqP96M1yhDgg==", + "version": "22.5.3", + "resolved": "https://registry.npmjs.org/@nx/nx-linux-arm64-gnu/-/nx-linux-arm64-gnu-22.5.3.tgz", + "integrity": "sha512-dmDBio/5z4Zch2VlRMdgBPm53d8xwq1l7xLj1dFMKjfE7ByfPukjPM7ZEYBiPckfiQfJBRh6HKDN7uEkA/y8CQ==", "cpu": [ "arm64" ], @@ -9049,9 +9095,9 @@ ] }, "node_modules/@nx/nx-linux-arm64-musl": { - "version": "22.4.5", - "resolved": "https://registry.npmjs.org/@nx/nx-linux-arm64-musl/-/nx-linux-arm64-musl-22.4.5.tgz", - "integrity": "sha512-n0v60vRYn7BDHWB588snPZntLO2XC8/pvLd+QunneM2VGEPf51n5llX5U3AwTt/ybaZHWhbuHv0sJBIbT4I0GA==", + "version": "22.5.3", + "resolved": "https://registry.npmjs.org/@nx/nx-linux-arm64-musl/-/nx-linux-arm64-musl-22.5.3.tgz", + "integrity": "sha512-E81ET/MnnKfuLhKiovF5ueJirHOMjhC1eK0MDM2Do9wdPyusZzfGSVFQ9DOHtg7L37dAE95NNd1lCVO8gJ96vg==", "cpu": [ "arm64" ], @@ -9063,9 +9109,9 @@ ] }, "node_modules/@nx/nx-linux-x64-gnu": { - "version": "22.4.5", - "resolved": "https://registry.npmjs.org/@nx/nx-linux-x64-gnu/-/nx-linux-x64-gnu-22.4.5.tgz", - "integrity": "sha512-zT7nb1PRE3NcW/HFnbgKJ9ZPtCOeVDpbJ5J4ZhHj36ZAUWZVXFEIPq9VTIZFy5+0pioLUIClQQY7OUfwnV/Zig==", + "version": "22.5.3", + "resolved": "https://registry.npmjs.org/@nx/nx-linux-x64-gnu/-/nx-linux-x64-gnu-22.5.3.tgz", + "integrity": "sha512-AgXCsPCzC0sAu2VRclMjs7LrvPQfqS3sFiehlXWTbNHQitPZLuAmQGb2l4T8lbMOs0Xn3EIrg6BF6/ntTTp6Xg==", "cpu": [ "x64" ], @@ -9077,9 +9123,9 @@ ] }, "node_modules/@nx/nx-linux-x64-musl": { - "version": "22.4.5", - "resolved": "https://registry.npmjs.org/@nx/nx-linux-x64-musl/-/nx-linux-x64-musl-22.4.5.tgz", - "integrity": "sha512-r8Rls5BS7lGQbUNX1Z1S370XrOacOU1bQ/dxY8i7qahFQKnMwpFo0W8odhgzjk+vrC/WLf9jOgz5/JPzehQBIw==", + "version": "22.5.3", + "resolved": "https://registry.npmjs.org/@nx/nx-linux-x64-musl/-/nx-linux-x64-musl-22.5.3.tgz", + "integrity": "sha512-sKs4bFQRu8Btxf5rMYKPsRVNxkQ2ey8sqoCyhJj8fwJF05DayK2ErJAR/rhtBK0c1NV7kQiKJA8nWBV3jnCdsg==", "cpu": [ "x64" ], @@ -9091,9 +9137,9 @@ ] }, "node_modules/@nx/nx-win32-arm64-msvc": { - "version": "22.4.5", - "resolved": "https://registry.npmjs.org/@nx/nx-win32-arm64-msvc/-/nx-win32-arm64-msvc-22.4.5.tgz", - "integrity": "sha512-Lv81LTnG6sSvBOq2vDSeyfzpF9X0cTGlJdzJOJzPZXCZGFhTV1ig9TdLiij/GM2JwV4Kvq5Co6YzA5dxtGUphQ==", + "version": "22.5.3", + "resolved": "https://registry.npmjs.org/@nx/nx-win32-arm64-msvc/-/nx-win32-arm64-msvc-22.5.3.tgz", + "integrity": "sha512-KOCQLakSO5vl4D6et9qPytOAmkgq2IIuhI8A/g0xbD1LqrIlRPa+bdkZqOGpODYAk3NyKAk7hWHsqfXKHwwX6w==", "cpu": [ "arm64" ], @@ -9105,9 +9151,9 @@ ] }, "node_modules/@nx/nx-win32-x64-msvc": { - "version": "22.4.5", - "resolved": "https://registry.npmjs.org/@nx/nx-win32-x64-msvc/-/nx-win32-x64-msvc-22.4.5.tgz", - "integrity": "sha512-52RfBcq9PXt76soCAZAJcNmCYrdsg6BvhBmjf0IFTMZ8IaeqZ9ktxAy1TZf/gCkOaM3ly4htbYMStiZ4MHX7Eg==", + "version": "22.5.3", + "resolved": "https://registry.npmjs.org/@nx/nx-win32-x64-msvc/-/nx-win32-x64-msvc-22.5.3.tgz", + "integrity": "sha512-a6ZB2La82RIHcz4nrt3H6RZaOa+xkC2IPzhU9hMo2gbkLdIxn8wyof8uGA0frncmIVHuLc3nFAhpBOgf4j6tMA==", "cpu": [ "x64" ], @@ -9119,16 +9165,16 @@ ] }, "node_modules/@nx/rspack": { - "version": "22.4.5", - "resolved": "https://registry.npmjs.org/@nx/rspack/-/rspack-22.4.5.tgz", - "integrity": "sha512-pqaJ713Jv82abDGisArEtKprAO0DuGxp7zddwpYW04J4Y8YmRAQFA3KriMPqjWTXuV3l4kpaqU7FtZ/3Xn1ShA==", + "version": "22.5.3", + "resolved": "https://registry.npmjs.org/@nx/rspack/-/rspack-22.5.3.tgz", + "integrity": "sha512-2T5dkoC08FJGF8ZMiJDaKN6giXAljV0+LK7q5GJpSEUm+wtjZ/DRVoWSnlf8Dj/e0/cLb2GMElVcfjyDDDeV9w==", "dev": true, "license": "MIT", "dependencies": { - "@nx/devkit": "22.4.5", - "@nx/js": "22.4.5", - "@nx/module-federation": "22.4.5", - "@nx/web": "22.4.5", + "@nx/devkit": "22.5.3", + "@nx/js": "22.5.3", + "@nx/module-federation": "22.5.3", + "@nx/web": "22.5.3", "@phenomnomnominal/tsquery": "~6.1.4", "@rspack/core": "1.6.8", "@rspack/dev-server": "^1.1.4", @@ -9550,16 +9596,16 @@ } }, "node_modules/@nx/storybook": { - "version": "22.4.5", - "resolved": "https://registry.npmjs.org/@nx/storybook/-/storybook-22.4.5.tgz", - "integrity": "sha512-cxJDYpfpYcK0iuiJMHk6InLXXNLedj8VlOkRtcnZKuwDlC8quMSOuHKrdvBOjeOLV4C390/94BlzkToUZSey6g==", + "version": "22.5.3", + "resolved": "https://registry.npmjs.org/@nx/storybook/-/storybook-22.5.3.tgz", + "integrity": "sha512-eP7cpRKnC1oYlOjSZU07Kf8BV8hNRPPXRib7BVdwwIUZ2v4K/b/cje2WCG729q4gk8fyoV8o7JNVgM+QGT8kBQ==", "dev": true, "license": "MIT", "dependencies": { - "@nx/cypress": "22.4.5", - "@nx/devkit": "22.4.5", - "@nx/eslint": "22.4.5", - "@nx/js": "22.4.5", + "@nx/cypress": "22.5.3", + "@nx/devkit": "22.5.3", + "@nx/eslint": "22.5.3", + "@nx/js": "22.5.3", "@phenomnomnominal/tsquery": "~6.1.4", "semver": "^7.6.3", "tslib": "^2.3.0" @@ -9569,14 +9615,14 @@ } }, "node_modules/@nx/web": { - "version": "22.4.5", - "resolved": "https://registry.npmjs.org/@nx/web/-/web-22.4.5.tgz", - "integrity": "sha512-VXXkONZS7DEDDKUE8EUCiV7XhC+HmotExPKznU6NquoFpBZqvWCfC0rt/gKk2uIxJGu8qoISqtIIHFc6iO65RA==", + "version": "22.5.3", + "resolved": "https://registry.npmjs.org/@nx/web/-/web-22.5.3.tgz", + "integrity": "sha512-Z7FYN5e9HIJAuJV0MU8jHaoEv9vgiLbpe1bbWPItfzIy02kWtSiS/aGZcLa34LDuWBfBaJVHZqFVp7OOPU26ew==", "dev": true, "license": "MIT", "dependencies": { - "@nx/devkit": "22.4.5", - "@nx/js": "22.4.5", + "@nx/devkit": "22.5.3", + "@nx/js": "22.5.3", "detect-port": "^1.5.1", "http-server": "^14.1.0", "picocolors": "^1.1.0", @@ -9584,15 +9630,15 @@ } }, "node_modules/@nx/webpack": { - "version": "22.4.5", - "resolved": "https://registry.npmjs.org/@nx/webpack/-/webpack-22.4.5.tgz", - "integrity": "sha512-3NZnJwkP1ztPc4Inz0g04rWf78P3U2np/kg3nKNf2I6kowWpcJakQCsWLufBzP48ooUtE3iPDVQoFIo3SgWqDg==", + "version": "22.5.3", + "resolved": "https://registry.npmjs.org/@nx/webpack/-/webpack-22.5.3.tgz", + "integrity": "sha512-fEWvmynjxAfdyCH00Z3oaEedv/wKZAdHl8kz7UEiOJ7eKdGbbJIK0RuobXC1r2e2ERZ35vDrOiPYdruyfi35Jg==", "dev": true, "license": "MIT", "dependencies": { "@babel/core": "^7.23.2", - "@nx/devkit": "22.4.5", - "@nx/js": "22.4.5", + "@nx/devkit": "22.5.3", + "@nx/js": "22.5.3", "@phenomnomnominal/tsquery": "~6.1.4", "ajv": "^8.12.0", "autoprefixer": "^10.4.9", @@ -9801,17 +9847,17 @@ } }, "node_modules/@nx/workspace": { - "version": "22.4.5", - "resolved": "https://registry.npmjs.org/@nx/workspace/-/workspace-22.4.5.tgz", - "integrity": "sha512-QGapABrqBnRpEWbnd5UpbVCBzsYD+RlC1lWShXPpCM+dosR3qkGb+pSmxeSCsKbNVtCwYyyuRW+PvlF5Q5sU9A==", + "version": "22.5.3", + "resolved": "https://registry.npmjs.org/@nx/workspace/-/workspace-22.5.3.tgz", + "integrity": "sha512-pioGwlt5zKB9PhX36I5KAeSml19Mq+g2KyQ9mh3F+3Lvft2JM4nIMELBaUfwPicPAOwNmrsx806IXO67Q4UHxQ==", "dev": true, "license": "MIT", "dependencies": { - "@nx/devkit": "22.4.5", + "@nx/devkit": "22.5.3", "@zkochan/js-yaml": "0.0.7", "chalk": "^4.1.0", "enquirer": "~2.3.6", - "nx": "22.4.5", + "nx": "22.5.3", "picomatch": "4.0.2", "semver": "^7.6.3", "tslib": "^2.3.0", @@ -11651,9 +11697,9 @@ "license": "MIT" }, "node_modules/@rspack/plugin-react-refresh": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/@rspack/plugin-react-refresh/-/plugin-react-refresh-1.6.0.tgz", - "integrity": "sha512-OO53gkrte/Ty4iRXxxM6lkwPGxsSsupFKdrPFnjwFIYrPvFLjeolAl5cTx+FzO5hYygJiGnw7iEKTmD+ptxqDA==", + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/@rspack/plugin-react-refresh/-/plugin-react-refresh-1.6.1.tgz", + "integrity": "sha512-eqqW5645VG3CzGzFgNg5HqNdHVXY+567PGjtDhhrM8t67caxmsSzRmT5qfoEIfBcGgFkH9vEg7kzXwmCYQdQDw==", "dev": true, "license": "MIT", "dependencies": { @@ -15017,14 +15063,14 @@ } }, "node_modules/axios": { - "version": "1.13.4", - "resolved": "https://registry.npmjs.org/axios/-/axios-1.13.4.tgz", - "integrity": "sha512-1wVkUaAO6WyaYtCkcYCOx12ZgpGf9Zif+qXa4n+oYzK558YryKqiL6UWwd5DqiH3VRW0GYhTZQ/vlgJrCoNQlg==", + "version": "1.13.6", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.13.6.tgz", + "integrity": "sha512-ChTCHMouEe2kn713WHbQGcuYrr6fXTBiu460OTwWrWob16g1bXn4vtz07Ope7ewMozJAnEquLk5lWQWtBig9DQ==", "dev": true, "license": "MIT", "dependencies": { - "follow-redirects": "^1.15.6", - "form-data": "^4.0.4", + "follow-redirects": "^1.15.11", + "form-data": "^4.0.5", "proxy-from-env": "^1.1.0" } }, @@ -20394,9 +20440,9 @@ "license": "ISC" }, "node_modules/follow-redirects": { - "version": "1.15.9", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.9.tgz", - "integrity": "sha512-gew4GsXizNgdoRyqmyfMHyAmXsZDk6mHkSxZFCzW9gwlbtOW44CDtYavM+y+72qD/Vq2l550kMF52DT8fOLJqQ==", + "version": "1.15.11", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.11.tgz", + "integrity": "sha512-deG2P0JfjrTxl50XGCDyfI97ZGVCxIpfKYmfyrQ54n5FO/0gfIES8C/Psl6kWVDolizcaaxZJnTS0QSMxvnsBQ==", "funding": [ { "type": "individual", @@ -20482,9 +20528,9 @@ } }, "node_modules/fork-ts-checker-webpack-plugin/node_modules/ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "version": "6.14.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.14.0.tgz", + "integrity": "sha512-IWrosm/yrn43eiKqkfkHis7QioDleaXQHdDVPKg0FSwwd/DuvyX79TZnFOnYpB7dcsFAMmtFztZuXPDvSePkFw==", "dev": true, "license": "MIT", "dependencies": { @@ -26663,9 +26709,9 @@ "license": "MIT" }, "node_modules/nx": { - "version": "22.4.5", - "resolved": "https://registry.npmjs.org/nx/-/nx-22.4.5.tgz", - "integrity": "sha512-l68kzhnemXXGCDS9/W8eccZ7Bzse9pw1oJ466pzDM89MbA6hEaOQ0p+eDXZI++iWl0T+lYJ56EDhO23syKzt9g==", + "version": "22.5.3", + "resolved": "https://registry.npmjs.org/nx/-/nx-22.5.3.tgz", + "integrity": "sha512-IaEPqdgaFBIr0Bfmnt6WAcX3t660sOuDXQ71lpoS8GgpD8cqX1LIW2ZyzEAdOvCP1iD6HCZehpofcVvaaL1GNQ==", "dev": true, "hasInstallScript": true, "license": "MIT", @@ -26675,12 +26721,12 @@ "@yarnpkg/parsers": "3.0.2", "@zkochan/js-yaml": "0.0.7", "axios": "^1.12.0", - "chalk": "^4.1.0", "cli-cursor": "3.1.0", "cli-spinners": "2.6.1", "cliui": "^8.0.1", "dotenv": "~16.4.5", "dotenv-expand": "~11.0.6", + "ejs": "^3.1.7", "enquirer": "~2.3.6", "figures": "3.2.0", "flat": "^5.0.2", @@ -26689,11 +26735,12 @@ "jest-diff": "^30.0.2", "jsonc-parser": "3.2.0", "lines-and-columns": "2.0.3", - "minimatch": "10.1.1", + "minimatch": "10.2.1", "node-machine-id": "1.1.12", "npm-run-path": "^4.0.1", "open": "^8.4.0", "ora": "5.3.0", + "picocolors": "^1.1.0", "resolve.exports": "2.0.3", "semver": "^7.6.3", "string-width": "^4.2.3", @@ -26711,20 +26758,20 @@ "nx-cloud": "bin/nx-cloud.js" }, "optionalDependencies": { - "@nx/nx-darwin-arm64": "22.4.5", - "@nx/nx-darwin-x64": "22.4.5", - "@nx/nx-freebsd-x64": "22.4.5", - "@nx/nx-linux-arm-gnueabihf": "22.4.5", - "@nx/nx-linux-arm64-gnu": "22.4.5", - "@nx/nx-linux-arm64-musl": "22.4.5", - "@nx/nx-linux-x64-gnu": "22.4.5", - "@nx/nx-linux-x64-musl": "22.4.5", - "@nx/nx-win32-arm64-msvc": "22.4.5", - "@nx/nx-win32-x64-msvc": "22.4.5" + "@nx/nx-darwin-arm64": "22.5.3", + "@nx/nx-darwin-x64": "22.5.3", + "@nx/nx-freebsd-x64": "22.5.3", + "@nx/nx-linux-arm-gnueabihf": "22.5.3", + "@nx/nx-linux-arm64-gnu": "22.5.3", + "@nx/nx-linux-arm64-musl": "22.5.3", + "@nx/nx-linux-x64-gnu": "22.5.3", + "@nx/nx-linux-x64-musl": "22.5.3", + "@nx/nx-win32-arm64-msvc": "22.5.3", + "@nx/nx-win32-x64-msvc": "22.5.3" }, "peerDependencies": { - "@swc-node/register": "^1.8.0", - "@swc/core": "^1.3.85" + "@swc-node/register": "^1.11.1", + "@swc/core": "^1.15.8" }, "peerDependenciesMeta": { "@swc-node/register": { @@ -26757,6 +26804,29 @@ "tslib": "^2.4.0" } }, + "node_modules/nx/node_modules/balanced-match": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-4.0.4.tgz", + "integrity": "sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==", + "dev": true, + "license": "MIT", + "engines": { + "node": "18 || 20 || >=22" + } + }, + "node_modules/nx/node_modules/brace-expansion": { + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.4.tgz", + "integrity": "sha512-h+DEnpVvxmfVefa4jFbCf5HdH5YMDXRsmKflpf1pILZWRFlTbJpxeU55nJl4Smt5HQaGzg1o6RHFPJaOqnmBDg==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^4.0.2" + }, + "engines": { + "node": "18 || 20 || >=22" + } + }, "node_modules/nx/node_modules/chalk": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", @@ -26870,13 +26940,13 @@ "license": "MIT" }, "node_modules/nx/node_modules/minimatch": { - "version": "10.1.1", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.1.1.tgz", - "integrity": "sha512-enIvLvRAFZYXJzkCYG5RKmPfrFArdLv+R+lbQ53BmIMLIry74bjKzX6iHAm8WYamJkhSSEabrWN5D97XnKObjQ==", + "version": "10.2.1", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.1.tgz", + "integrity": "sha512-MClCe8IL5nRRmawL6ib/eT4oLyeKMGCghibcDWK+J0hh0Q8kqSdia6BvbRMVk6mPa6WqUa5uR2oxt6C5jd533A==", "dev": true, "license": "BlueOak-1.0.0", "dependencies": { - "@isaacs/brace-expansion": "^5.0.0" + "brace-expansion": "^5.0.2" }, "engines": { "node": "20 || >=22" @@ -32997,18 +33067,15 @@ } }, "node_modules/ts-checker-rspack-plugin": { - "version": "1.2.6", - "resolved": "https://registry.npmjs.org/ts-checker-rspack-plugin/-/ts-checker-rspack-plugin-1.2.6.tgz", - "integrity": "sha512-aAJIfoNr2cPu8G6mqp/oPoNlUT/LgNoqt2n3SsbxWG0TwQogbjsYsr2f/fdsufUDoGDu8Jolmpf3L4PmIH/cEg==", + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/ts-checker-rspack-plugin/-/ts-checker-rspack-plugin-1.3.0.tgz", + "integrity": "sha512-89oK/BtApjdid1j9CGjPGiYry+EZBhsnTAM481/8ipgr/y2IOgCbW1HPnan+fs5FnzlpUgf9dWGNZ4Ayw3Bd8A==", "dev": true, "license": "MIT", "dependencies": { - "@babel/code-frame": "^7.27.1", "@rspack/lite-tapable": "^1.1.0", "chokidar": "^3.6.0", - "is-glob": "^4.0.3", - "memfs": "^4.51.1", - "minimatch": "^9.0.5", + "memfs": "^4.56.10", "picocolors": "^1.1.1" }, "peerDependencies": { @@ -33021,16 +33088,6 @@ } } }, - "node_modules/ts-checker-rspack-plugin/node_modules/brace-expansion": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz", - "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "balanced-match": "^1.0.0" - } - }, "node_modules/ts-checker-rspack-plugin/node_modules/chokidar": { "version": "3.6.0", "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", @@ -33099,22 +33156,6 @@ "tslib": "2" } }, - "node_modules/ts-checker-rspack-plugin/node_modules/minimatch": { - "version": "9.0.5", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", - "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", - "dev": true, - "license": "ISC", - "dependencies": { - "brace-expansion": "^2.0.1" - }, - "engines": { - "node": ">=16 || 14 >=14.17" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, "node_modules/ts-checker-rspack-plugin/node_modules/picomatch": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", diff --git a/package.json b/package.json index 794a09ea7..8871e8acc 100644 --- a/package.json +++ b/package.json @@ -153,16 +153,16 @@ "@eslint/js": "9.35.0", "@nestjs/schematics": "11.0.9", "@nestjs/testing": "11.1.14", - "@nx/angular": "22.4.5", - "@nx/eslint-plugin": "22.4.5", - "@nx/jest": "22.4.5", - "@nx/js": "22.4.5", - "@nx/module-federation": "22.4.5", - "@nx/nest": "22.4.5", - "@nx/node": "22.4.5", - "@nx/storybook": "22.4.5", - "@nx/web": "22.4.5", - "@nx/workspace": "22.4.5", + "@nx/angular": "22.5.3", + "@nx/eslint-plugin": "22.5.3", + "@nx/jest": "22.5.3", + "@nx/js": "22.5.3", + "@nx/module-federation": "22.5.3", + "@nx/nest": "22.5.3", + "@nx/node": "22.5.3", + "@nx/storybook": "22.5.3", + "@nx/web": "22.5.3", + "@nx/workspace": "22.5.3", "@schematics/angular": "21.1.1", "@storybook/addon-docs": "10.1.10", "@storybook/angular": "10.1.10", @@ -187,7 +187,7 @@ "jest": "30.2.0", "jest-environment-jsdom": "30.2.0", "jest-preset-angular": "16.0.0", - "nx": "22.4.5", + "nx": "22.5.3", "prettier": "3.8.1", "prettier-plugin-organize-attributes": "1.0.0", "prisma": "6.19.0", From 2cc36d002f87c19051f4dfed925bc4785eb3740d Mon Sep 17 00:00:00 2001 From: Thomas Kaul <4159106+dtslvr@users.noreply.github.com> Date: Sun, 1 Mar 2026 20:27:13 +0100 Subject: [PATCH 076/224] Task/restructure sponsors section in README.md (#6412) * Restructure sponsors section --- README.md | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 3be15e49f..44212b607 100644 --- a/README.md +++ b/README.md @@ -313,10 +313,12 @@ Ghostfolio is **100% free** and **open source**. We encourage and support an act Not sure what to work on? We have [some ideas](https://github.com/ghostfolio/ghostfolio/issues?q=is%3Aissue+is%3Aopen+label%3A%22help+wanted%22%20no%3Aassignee), even for [newcomers](https://github.com/ghostfolio/ghostfolio/issues?q=is%3Aissue+is%3Aopen+label%3A%22good+first+issue%22%20no%3Aassignee). Please join the Ghostfolio [Slack](https://join.slack.com/t/ghostfolio/shared_invite/zt-vsaan64h-F_I0fEo5M0P88lP9ibCxFg) channel or post to [@ghostfolio\_](https://x.com/ghostfolio_) on _X_. We would love to hear from you. -If you like to support this project, become a [**Sponsor**](https://github.com/sponsors/ghostfolio), get [**Ghostfolio Premium**](https://ghostfol.io/en/pricing) or [**Buy me a coffee**](https://www.buymeacoffee.com/ghostfolio). - ## Sponsors +If you like to support this project, get [**Ghostfolio Premium**](https://ghostfol.io/en/pricing), become a [**Sponsor**](https://github.com/sponsors/ghostfolio) or [**Buy me a coffee**](https://www.buymeacoffee.com/ghostfolio). + +
    +
    TestMu AI Logo From 8b187c96b567edce6b0fa1763cca032206bc7686 Mon Sep 17 00:00:00 2001 From: DmytroSkachko Date: Mon, 2 Mar 2026 12:13:24 +0100 Subject: [PATCH 077/224] Task/eliminate OnDestroy hook from ZEN page (#6452) * Eliminate OnDestroy hook --- .../src/app/pages/zen/zen-page.component.ts | 22 +++++++++---------- 1 file changed, 10 insertions(+), 12 deletions(-) diff --git a/apps/client/src/app/pages/zen/zen-page.component.ts b/apps/client/src/app/pages/zen/zen-page.component.ts index 280f33c25..633f15885 100644 --- a/apps/client/src/app/pages/zen/zen-page.component.ts +++ b/apps/client/src/app/pages/zen/zen-page.component.ts @@ -2,15 +2,19 @@ import { UserService } from '@ghostfolio/client/services/user/user.service'; import { TabConfiguration, User } from '@ghostfolio/common/interfaces'; import { internalRoutes } from '@ghostfolio/common/routes/routes'; -import { ChangeDetectorRef, Component, OnDestroy, OnInit } from '@angular/core'; +import { + ChangeDetectorRef, + Component, + DestroyRef, + OnInit +} from '@angular/core'; +import { takeUntilDestroyed } from '@angular/core/rxjs-interop'; import { MatTabsModule } from '@angular/material/tabs'; import { RouterModule } from '@angular/router'; import { IonIcon } from '@ionic/angular/standalone'; import { addIcons } from 'ionicons'; import { albumsOutline, analyticsOutline } from 'ionicons/icons'; import { DeviceDetectorService } from 'ngx-device-detector'; -import { Subject } from 'rxjs'; -import { takeUntil } from 'rxjs/operators'; @Component({ host: { class: 'page has-tabs' }, @@ -19,20 +23,19 @@ import { takeUntil } from 'rxjs/operators'; styleUrls: ['./zen-page.scss'], templateUrl: './zen-page.html' }) -export class GfZenPageComponent implements OnDestroy, OnInit { +export class GfZenPageComponent implements OnInit { public deviceType: string; public tabs: TabConfiguration[] = []; public user: User; - private unsubscribeSubject = new Subject(); - public constructor( private changeDetectorRef: ChangeDetectorRef, + private destroyRef: DestroyRef, private deviceService: DeviceDetectorService, private userService: UserService ) { this.userService.stateChanged - .pipe(takeUntil(this.unsubscribeSubject)) + .pipe(takeUntilDestroyed(this.destroyRef)) .subscribe((state) => { if (state?.user) { this.tabs = [ @@ -59,9 +62,4 @@ export class GfZenPageComponent implements OnDestroy, OnInit { public ngOnInit() { this.deviceType = this.deviceService.getDeviceInfo().deviceType; } - - public ngOnDestroy() { - this.unsubscribeSubject.next(); - this.unsubscribeSubject.complete(); - } } From cbf43340af06b1288ab2f36ab73800a7237678a9 Mon Sep 17 00:00:00 2001 From: Parth Sharma <99757071+pswitchy@users.noreply.github.com> Date: Mon, 2 Mar 2026 19:01:44 +0530 Subject: [PATCH 078/224] Task/eliminate OnDestroy lifecycle hook from user account page (#6461) * Eliminate OnDestroy lifecycle hook --- .../user-account/user-account-page.component.ts | 16 +++++----------- 1 file changed, 5 insertions(+), 11 deletions(-) diff --git a/apps/client/src/app/pages/user-account/user-account-page.component.ts b/apps/client/src/app/pages/user-account/user-account-page.component.ts index 7341660f2..24c150408 100644 --- a/apps/client/src/app/pages/user-account/user-account-page.component.ts +++ b/apps/client/src/app/pages/user-account/user-account-page.component.ts @@ -6,16 +6,16 @@ import { ChangeDetectorRef, Component, CUSTOM_ELEMENTS_SCHEMA, - OnDestroy, + DestroyRef, OnInit } from '@angular/core'; +import { takeUntilDestroyed } from '@angular/core/rxjs-interop'; import { MatTabsModule } from '@angular/material/tabs'; import { RouterModule } from '@angular/router'; import { IonIcon } from '@ionic/angular/standalone'; import { addIcons } from 'ionicons'; import { diamondOutline, keyOutline, settingsOutline } from 'ionicons/icons'; import { DeviceDetectorService } from 'ngx-device-detector'; -import { Subject, takeUntil } from 'rxjs'; @Component({ host: { class: 'page has-tabs' }, @@ -25,20 +25,19 @@ import { Subject, takeUntil } from 'rxjs'; styleUrls: ['./user-account-page.scss'], templateUrl: './user-account-page.html' }) -export class GfUserAccountPageComponent implements OnDestroy, OnInit { +export class GfUserAccountPageComponent implements OnInit { public deviceType: string; public tabs: TabConfiguration[] = []; public user: User; - private unsubscribeSubject = new Subject(); - public constructor( private changeDetectorRef: ChangeDetectorRef, + private destroyRef: DestroyRef, private deviceService: DeviceDetectorService, private userService: UserService ) { this.userService.stateChanged - .pipe(takeUntil(this.unsubscribeSubject)) + .pipe(takeUntilDestroyed(this.destroyRef)) .subscribe((state) => { if (state?.user) { this.user = state.user; @@ -73,9 +72,4 @@ export class GfUserAccountPageComponent implements OnDestroy, OnInit { public ngOnInit() { this.deviceType = this.deviceService.getDeviceInfo().deviceType; } - - public ngOnDestroy() { - this.unsubscribeSubject.next(); - this.unsubscribeSubject.complete(); - } } From c9924e030aa9df55ca9920d4f202c02059733e09 Mon Sep 17 00:00:00 2001 From: Parth Sharma <99757071+pswitchy@users.noreply.github.com> Date: Mon, 2 Mar 2026 19:28:03 +0530 Subject: [PATCH 079/224] Task/eliminate OnDestroy lifecycle hook from home page (#6462) * Eliminate OnDestroy lifecycle hook --- .../src/app/pages/home/home-page.component.ts | 19 ++++++------------- 1 file changed, 6 insertions(+), 13 deletions(-) diff --git a/apps/client/src/app/pages/home/home-page.component.ts b/apps/client/src/app/pages/home/home-page.component.ts index fd860ced5..5130c8166 100644 --- a/apps/client/src/app/pages/home/home-page.component.ts +++ b/apps/client/src/app/pages/home/home-page.component.ts @@ -8,9 +8,10 @@ import { ChangeDetectorRef, Component, CUSTOM_ELEMENTS_SCHEMA, - OnDestroy, + DestroyRef, OnInit } from '@angular/core'; +import { takeUntilDestroyed } from '@angular/core/rxjs-interop'; import { MatTabsModule } from '@angular/material/tabs'; import { RouterModule } from '@angular/router'; import { IonIcon } from '@ionic/angular/standalone'; @@ -23,8 +24,6 @@ import { readerOutline } from 'ionicons/icons'; import { DeviceDetectorService } from 'ngx-device-detector'; -import { Subject } from 'rxjs'; -import { takeUntil } from 'rxjs/operators'; @Component({ host: { class: 'page has-tabs' }, @@ -34,22 +33,21 @@ import { takeUntil } from 'rxjs/operators'; styleUrls: ['./home-page.scss'], templateUrl: './home-page.html' }) -export class GfHomePageComponent implements OnDestroy, OnInit { +export class GfHomePageComponent implements OnInit { public deviceType: string; public hasImpersonationId: boolean; public tabs: TabConfiguration[] = []; public user: User; - private unsubscribeSubject = new Subject(); - public constructor( private changeDetectorRef: ChangeDetectorRef, + private destroyRef: DestroyRef, private deviceService: DeviceDetectorService, private impersonationStorageService: ImpersonationStorageService, private userService: UserService ) { this.userService.stateChanged - .pipe(takeUntil(this.unsubscribeSubject)) + .pipe(takeUntilDestroyed(this.destroyRef)) .subscribe((state) => { if (state?.user) { this.user = state.user; @@ -110,14 +108,9 @@ export class GfHomePageComponent implements OnDestroy, OnInit { this.impersonationStorageService .onChangeHasImpersonation() - .pipe(takeUntil(this.unsubscribeSubject)) + .pipe(takeUntilDestroyed(this.destroyRef)) .subscribe((impersonationId) => { this.hasImpersonationId = !!impersonationId; }); } - - public ngOnDestroy() { - this.unsubscribeSubject.next(); - this.unsubscribeSubject.complete(); - } } From e273bfcbea492901b330e8a18d3ddeab9d4359c6 Mon Sep 17 00:00:00 2001 From: Parth Sharma <99757071+pswitchy@users.noreply.github.com> Date: Mon, 2 Mar 2026 23:48:41 +0530 Subject: [PATCH 080/224] Task/eliminate OnDestroy lifecycle hook from allocations page (#6463) * Eliminate OnDestroy lifecycle hook --- .../allocations/allocations-page.component.ts | 30 +++++++++---------- 1 file changed, 14 insertions(+), 16 deletions(-) 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 70fa09eb1..a98adc438 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 @@ -22,7 +22,13 @@ import { GfValueComponent } from '@ghostfolio/ui/value'; import { GfWorldMapChartComponent } from '@ghostfolio/ui/world-map-chart'; import { NgClass } from '@angular/common'; -import { ChangeDetectorRef, Component, OnDestroy, OnInit } from '@angular/core'; +import { + ChangeDetectorRef, + Component, + DestroyRef, + OnInit +} from '@angular/core'; +import { takeUntilDestroyed } from '@angular/core/rxjs-interop'; import { MatCardModule } from '@angular/material/card'; import { MatDialog } from '@angular/material/dialog'; import { MatProgressBarModule } from '@angular/material/progress-bar'; @@ -36,8 +42,6 @@ import { } from '@prisma/client'; import { isNumber } from 'lodash'; import { DeviceDetectorService } from 'ngx-device-detector'; -import { Subject } from 'rxjs'; -import { takeUntil } from 'rxjs/operators'; @Component({ imports: [ @@ -54,7 +58,7 @@ import { takeUntil } from 'rxjs/operators'; styleUrls: ['./allocations-page.scss'], templateUrl: './allocations-page.html' }) -export class GfAllocationsPageComponent implements OnDestroy, OnInit { +export class GfAllocationsPageComponent implements OnInit { public accounts: { [id: string]: Pick & { id: string; @@ -119,11 +123,10 @@ export class GfAllocationsPageComponent implements OnDestroy, OnInit { public user: User; public worldMapChartFormat: string; - private unsubscribeSubject = new Subject(); - public constructor( private changeDetectorRef: ChangeDetectorRef, private dataService: DataService, + private destroyRef: DestroyRef, private deviceService: DeviceDetectorService, private dialog: MatDialog, private impersonationStorageService: ImpersonationStorageService, @@ -132,7 +135,7 @@ export class GfAllocationsPageComponent implements OnDestroy, OnInit { private userService: UserService ) { this.route.queryParams - .pipe(takeUntil(this.unsubscribeSubject)) + .pipe(takeUntilDestroyed(this.destroyRef)) .subscribe((params) => { if (params['accountId'] && params['accountDetailDialog']) { this.openAccountDetailDialog(params['accountId']); @@ -145,13 +148,13 @@ export class GfAllocationsPageComponent implements OnDestroy, OnInit { this.impersonationStorageService .onChangeHasImpersonation() - .pipe(takeUntil(this.unsubscribeSubject)) + .pipe(takeUntilDestroyed(this.destroyRef)) .subscribe((impersonationId) => { this.hasImpersonationId = !!impersonationId; }); this.userService.stateChanged - .pipe(takeUntil(this.unsubscribeSubject)) + .pipe(takeUntilDestroyed(this.destroyRef)) .subscribe((state) => { if (state?.user) { this.user = state.user; @@ -166,7 +169,7 @@ export class GfAllocationsPageComponent implements OnDestroy, OnInit { this.initialize(); this.fetchPortfolioDetails() - .pipe(takeUntil(this.unsubscribeSubject)) + .pipe(takeUntilDestroyed(this.destroyRef)) .subscribe((portfolioDetails) => { this.initialize(); @@ -202,11 +205,6 @@ export class GfAllocationsPageComponent implements OnDestroy, OnInit { } } - public ngOnDestroy() { - this.unsubscribeSubject.next(); - this.unsubscribeSubject.complete(); - } - private extractEtfProvider({ assetSubClass, name @@ -578,7 +576,7 @@ export class GfAllocationsPageComponent implements OnDestroy, OnInit { dialogRef .afterClosed() - .pipe(takeUntil(this.unsubscribeSubject)) + .pipe(takeUntilDestroyed(this.destroyRef)) .subscribe(() => { this.router.navigate(['.'], { relativeTo: this.route }); }); From 9fb02dac0ebe8093dbe5dbd8cedf48c11535148b Mon Sep 17 00:00:00 2001 From: Thomas Kaul <4159106+dtslvr@users.noreply.github.com> Date: Mon, 2 Mar 2026 19:29:12 +0100 Subject: [PATCH 081/224] Task/remove unused OnDestroy hook in personal finance tools page (#6443) * Remove unused OnDestroy hook --- .../personal-finance-tools-page.component.ts | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/apps/client/src/app/pages/resources/personal-finance-tools/personal-finance-tools-page.component.ts b/apps/client/src/app/pages/resources/personal-finance-tools/personal-finance-tools-page.component.ts index c4cfd184e..bb4ae3889 100644 --- a/apps/client/src/app/pages/resources/personal-finance-tools/personal-finance-tools-page.component.ts +++ b/apps/client/src/app/pages/resources/personal-finance-tools/personal-finance-tools-page.component.ts @@ -1,13 +1,12 @@ import { personalFinanceTools } from '@ghostfolio/common/personal-finance-tools'; import { publicRoutes } from '@ghostfolio/common/routes/routes'; -import { Component, OnDestroy } from '@angular/core'; +import { Component } from '@angular/core'; import { MatCardModule } from '@angular/material/card'; import { RouterModule } from '@angular/router'; import { IonIcon } from '@ionic/angular/standalone'; import { addIcons } from 'ionicons'; import { chevronForwardOutline } from 'ionicons/icons'; -import { Subject } from 'rxjs'; @Component({ host: { class: 'page' }, @@ -16,7 +15,7 @@ import { Subject } from 'rxjs'; styleUrls: ['./personal-finance-tools-page.scss'], templateUrl: './personal-finance-tools-page.html' }) -export class PersonalFinanceToolsPageComponent implements OnDestroy { +export class PersonalFinanceToolsPageComponent { public pathAlternativeTo = publicRoutes.resources.subRoutes.personalFinanceTools.subRoutes.product .path + '-'; @@ -28,14 +27,7 @@ export class PersonalFinanceToolsPageComponent implements OnDestroy { }); public routerLinkAbout = publicRoutes.about.routerLink; - private unsubscribeSubject = new Subject(); - public constructor() { addIcons({ chevronForwardOutline }); } - - public ngOnDestroy() { - this.unsubscribeSubject.next(); - this.unsubscribeSubject.complete(); - } } From 55952d3cc81eea937265b492c120515320b50096 Mon Sep 17 00:00:00 2001 From: Thomas Kaul <4159106+dtslvr@users.noreply.github.com> Date: Mon, 2 Mar 2026 19:30:50 +0100 Subject: [PATCH 082/224] Task/remove unused OnDestroy hook in i18n page component (#6441) * Remove unused OnDestroy hook --- apps/client/src/app/pages/i18n/i18n-page.component.ts | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/apps/client/src/app/pages/i18n/i18n-page.component.ts b/apps/client/src/app/pages/i18n/i18n-page.component.ts index 19ecd222e..76d123914 100644 --- a/apps/client/src/app/pages/i18n/i18n-page.component.ts +++ b/apps/client/src/app/pages/i18n/i18n-page.component.ts @@ -1,5 +1,4 @@ import { Component } from '@angular/core'; -import { Subject } from 'rxjs'; @Component({ host: { class: 'page' }, @@ -8,11 +7,4 @@ import { Subject } from 'rxjs'; styleUrls: ['./i18n-page.scss'], templateUrl: './i18n-page.html' }) -export class GfI18nPageComponent { - private unsubscribeSubject = new Subject(); - - public ngOnDestroy() { - this.unsubscribeSubject.next(); - this.unsubscribeSubject.complete(); - } -} +export class GfI18nPageComponent {} From f8ca87fadb8260aaff55d650feffde6451f6a393 Mon Sep 17 00:00:00 2001 From: Thomas Kaul <4159106+dtslvr@users.noreply.github.com> Date: Mon, 2 Mar 2026 19:31:33 +0100 Subject: [PATCH 083/224] Task/remove unused OnDestroy hook in self-hosting FAQ page component (#6436) * Remove unused OnDestroy hook --- .../faq/self-hosting/self-hosting-page.component.ts | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/apps/client/src/app/pages/faq/self-hosting/self-hosting-page.component.ts b/apps/client/src/app/pages/faq/self-hosting/self-hosting-page.component.ts index ed1d74395..f2468c7d4 100644 --- a/apps/client/src/app/pages/faq/self-hosting/self-hosting-page.component.ts +++ b/apps/client/src/app/pages/faq/self-hosting/self-hosting-page.component.ts @@ -1,10 +1,9 @@ import { publicRoutes } from '@ghostfolio/common/routes/routes'; import { GfPremiumIndicatorComponent } from '@ghostfolio/ui/premium-indicator'; -import { CUSTOM_ELEMENTS_SCHEMA, Component, OnDestroy } from '@angular/core'; +import { CUSTOM_ELEMENTS_SCHEMA, Component } from '@angular/core'; import { MatCardModule } from '@angular/material/card'; import { RouterModule } from '@angular/router'; -import { Subject } from 'rxjs'; @Component({ host: { class: 'page' }, @@ -14,13 +13,6 @@ import { Subject } from 'rxjs'; styleUrls: ['./self-hosting-page.scss'], templateUrl: './self-hosting-page.html' }) -export class GfSelfHostingPageComponent implements OnDestroy { +export class GfSelfHostingPageComponent { public pricingUrl = `https://ghostfol.io/${document.documentElement.lang}/${publicRoutes.pricing.path}`; - - private unsubscribeSubject = new Subject(); - - public ngOnDestroy() { - this.unsubscribeSubject.next(); - this.unsubscribeSubject.complete(); - } } From 794c8f8016f20e0e71518437aa527e8a12f2f058 Mon Sep 17 00:00:00 2001 From: Thomas Kaul <4159106+dtslvr@users.noreply.github.com> Date: Mon, 2 Mar 2026 19:32:12 +0100 Subject: [PATCH 084/224] Task/remove unused OnDestroy hook in FAQ page component (#6437) * Remove unused OnDestroy hook --- .../src/app/pages/faq/faq-page.component.ts | 17 ++--------------- 1 file changed, 2 insertions(+), 15 deletions(-) diff --git a/apps/client/src/app/pages/faq/faq-page.component.ts b/apps/client/src/app/pages/faq/faq-page.component.ts index caf4217ca..83171254a 100644 --- a/apps/client/src/app/pages/faq/faq-page.component.ts +++ b/apps/client/src/app/pages/faq/faq-page.component.ts @@ -3,19 +3,13 @@ import { hasPermission, permissions } from '@ghostfolio/common/permissions'; import { publicRoutes } from '@ghostfolio/common/routes/routes'; import { DataService } from '@ghostfolio/ui/services'; -import { - CUSTOM_ELEMENTS_SCHEMA, - Component, - OnDestroy, - OnInit -} from '@angular/core'; +import { CUSTOM_ELEMENTS_SCHEMA, Component, OnInit } from '@angular/core'; import { MatTabsModule } from '@angular/material/tabs'; import { RouterModule } from '@angular/router'; import { IonIcon } from '@ionic/angular/standalone'; import { addIcons } from 'ionicons'; import { cloudyOutline, readerOutline, serverOutline } from 'ionicons/icons'; import { DeviceDetectorService } from 'ngx-device-detector'; -import { Subject } from 'rxjs'; @Component({ host: { class: 'page has-tabs' }, @@ -25,13 +19,11 @@ import { Subject } from 'rxjs'; styleUrls: ['./faq-page.scss'], templateUrl: './faq-page.html' }) -export class GfFaqPageComponent implements OnDestroy, OnInit { +export class GfFaqPageComponent implements OnInit { public deviceType: string; public hasPermissionForSubscription: boolean; public tabs: TabConfiguration[] = []; - private unsubscribeSubject = new Subject(); - public constructor( private dataService: DataService, private deviceService: DeviceDetectorService @@ -68,9 +60,4 @@ export class GfFaqPageComponent implements OnDestroy, OnInit { public ngOnInit() { this.deviceType = this.deviceService.getDeviceInfo().deviceType; } - - public ngOnDestroy() { - this.unsubscribeSubject.next(); - this.unsubscribeSubject.complete(); - } } From a5d1f5988cd2f3c535244d6d4a28691a5267cb6e Mon Sep 17 00:00:00 2001 From: Thomas Kaul <4159106+dtslvr@users.noreply.github.com> Date: Mon, 2 Mar 2026 19:32:39 +0100 Subject: [PATCH 085/224] Task/remove unused OnDestroy hook in terms of service page component (#6440) * Remove unused OnDestroy hook --- .../terms-of-service-page.component.ts | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/apps/client/src/app/pages/about/terms-of-service/terms-of-service-page.component.ts b/apps/client/src/app/pages/about/terms-of-service/terms-of-service-page.component.ts index dbf07ef19..7899f0187 100644 --- a/apps/client/src/app/pages/about/terms-of-service/terms-of-service-page.component.ts +++ b/apps/client/src/app/pages/about/terms-of-service/terms-of-service-page.component.ts @@ -1,6 +1,5 @@ -import { Component, OnDestroy } from '@angular/core'; +import { Component } from '@angular/core'; import { MarkdownModule } from 'ngx-markdown'; -import { Subject } from 'rxjs'; @Component({ imports: [MarkdownModule], @@ -8,11 +7,4 @@ import { Subject } from 'rxjs'; styleUrls: ['./terms-of-service-page.scss'], templateUrl: './terms-of-service-page.html' }) -export class GfTermsOfServicePageComponent implements OnDestroy { - private unsubscribeSubject = new Subject(); - - public ngOnDestroy() { - this.unsubscribeSubject.next(); - this.unsubscribeSubject.complete(); - } -} +export class GfTermsOfServicePageComponent {} From 1de4d053e5782b2af37763d5babc5ac535d7b4bf Mon Sep 17 00:00:00 2001 From: Thomas Kaul <4159106+dtslvr@users.noreply.github.com> Date: Mon, 2 Mar 2026 19:33:06 +0100 Subject: [PATCH 086/224] Task/remove unused OnDestroy hook in transfer balance dialog component (#6438) * Remove unused OnDestroy hook --- .../transfer-balance-dialog.component.ts | 17 ++--------------- 1 file changed, 2 insertions(+), 15 deletions(-) diff --git a/apps/client/src/app/pages/accounts/transfer-balance/transfer-balance-dialog.component.ts b/apps/client/src/app/pages/accounts/transfer-balance/transfer-balance-dialog.component.ts index 85d2e60bf..34a66b156 100644 --- a/apps/client/src/app/pages/accounts/transfer-balance/transfer-balance-dialog.component.ts +++ b/apps/client/src/app/pages/accounts/transfer-balance/transfer-balance-dialog.component.ts @@ -1,12 +1,7 @@ import { TransferBalanceDto } from '@ghostfolio/common/dtos'; import { GfEntityLogoComponent } from '@ghostfolio/ui/entity-logo'; -import { - ChangeDetectionStrategy, - Component, - Inject, - OnDestroy -} from '@angular/core'; +import { ChangeDetectionStrategy, Component, Inject } from '@angular/core'; import { AbstractControl, FormBuilder, @@ -25,7 +20,6 @@ import { MatFormFieldModule } from '@angular/material/form-field'; import { MatInputModule } from '@angular/material/input'; import { MatSelectModule } from '@angular/material/select'; import { Account } from '@prisma/client'; -import { Subject } from 'rxjs'; import { TransferBalanceDialogParams } from './interfaces/interfaces'; @@ -45,13 +39,11 @@ import { TransferBalanceDialogParams } from './interfaces/interfaces'; styleUrls: ['./transfer-balance-dialog.scss'], templateUrl: 'transfer-balance-dialog.html' }) -export class GfTransferBalanceDialogComponent implements OnDestroy { +export class GfTransferBalanceDialogComponent { public accounts: Account[] = []; public currency: string; public transferBalanceForm: FormGroup; - private unsubscribeSubject = new Subject(); - public constructor( @Inject(MAT_DIALOG_DATA) public data: TransferBalanceDialogParams, public dialogRef: MatDialogRef, @@ -93,11 +85,6 @@ export class GfTransferBalanceDialogComponent implements OnDestroy { this.dialogRef.close({ account }); } - public ngOnDestroy() { - this.unsubscribeSubject.next(); - this.unsubscribeSubject.complete(); - } - private compareAccounts(control: AbstractControl): ValidationErrors { const accountFrom = control.get('fromAccount'); const accountTo = control.get('toAccount'); From ab07fba16b28b46848aae821482b1780cdf91a51 Mon Sep 17 00:00:00 2001 From: Thomas Kaul <4159106+dtslvr@users.noreply.github.com> Date: Mon, 2 Mar 2026 19:33:43 +0100 Subject: [PATCH 087/224] Task/remove unused OnDestroy hook in create or update account dialog component (#6439) * Remove unused OnDestroy hook --- ...reate-or-update-account-dialog.component.ts | 18 +++--------------- 1 file changed, 3 insertions(+), 15 deletions(-) diff --git a/apps/client/src/app/pages/accounts/create-or-update-account-dialog/create-or-update-account-dialog.component.ts b/apps/client/src/app/pages/accounts/create-or-update-account-dialog/create-or-update-account-dialog.component.ts index f4c68e70f..6cdd18251 100644 --- a/apps/client/src/app/pages/accounts/create-or-update-account-dialog/create-or-update-account-dialog.component.ts +++ b/apps/client/src/app/pages/accounts/create-or-update-account-dialog/create-or-update-account-dialog.component.ts @@ -5,12 +5,7 @@ import { GfEntityLogoComponent } from '@ghostfolio/ui/entity-logo'; import { DataService } from '@ghostfolio/ui/services'; import { CommonModule, NgClass } from '@angular/common'; -import { - ChangeDetectionStrategy, - Component, - Inject, - OnDestroy -} from '@angular/core'; +import { ChangeDetectionStrategy, Component, Inject } from '@angular/core'; import { AbstractControl, FormBuilder, @@ -30,7 +25,7 @@ import { import { MatFormFieldModule } from '@angular/material/form-field'; import { MatInputModule } from '@angular/material/input'; import { Platform } from '@prisma/client'; -import { Observable, Subject } from 'rxjs'; +import { Observable } from 'rxjs'; import { map, startWith } from 'rxjs/operators'; import { CreateOrUpdateAccountDialogParams } from './interfaces/interfaces'; @@ -55,14 +50,12 @@ import { CreateOrUpdateAccountDialogParams } from './interfaces/interfaces'; styleUrls: ['./create-or-update-account-dialog.scss'], templateUrl: 'create-or-update-account-dialog.html' }) -export class GfCreateOrUpdateAccountDialogComponent implements OnDestroy { +export class GfCreateOrUpdateAccountDialogComponent { public accountForm: FormGroup; public currencies: string[] = []; public filteredPlatforms: Observable; public platforms: Platform[] = []; - private unsubscribeSubject = new Subject(); - public constructor( @Inject(MAT_DIALOG_DATA) public data: CreateOrUpdateAccountDialogParams, private dataService: DataService, @@ -170,11 +163,6 @@ export class GfCreateOrUpdateAccountDialogComponent implements OnDestroy { } } - public ngOnDestroy() { - this.unsubscribeSubject.next(); - this.unsubscribeSubject.complete(); - } - private autocompleteObjectValidator(): ValidatorFn { return (control: AbstractControl) => { if (control.value && typeof control.value === 'string') { From 9bd4fe53cec45b4599dde796ecee1403a99c16a5 Mon Sep 17 00:00:00 2001 From: Thomas Kaul <4159106+dtslvr@users.noreply.github.com> Date: Mon, 2 Mar 2026 20:06:26 +0100 Subject: [PATCH 088/224] Task/extend personal finance tools 20260302 (#6464) * Extend personal finance tools --- libs/common/src/lib/personal-finance-tools.ts | 40 +++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/libs/common/src/lib/personal-finance-tools.ts b/libs/common/src/lib/personal-finance-tools.ts index 6d0a85fb2..063b4254c 100644 --- a/libs/common/src/lib/personal-finance-tools.ts +++ b/libs/common/src/lib/personal-finance-tools.ts @@ -33,6 +33,15 @@ export const personalFinanceTools: Product[] = [ origin: 'Switzerland', slogan: 'Simplicity for Complex Wealth' }, + { + founded: 2018, + hasFreePlan: false, + hasSelfHostingAbility: false, + key: 'altruist', + name: 'Altruist', + origin: 'United States', + slogan: 'The wealth platform built for independent advisors' + }, { founded: 2023, hasFreePlan: false, @@ -116,6 +125,17 @@ export const personalFinanceTools: Product[] = [ origin: 'Switzerland', slogan: 'Schweizer Budget App für einfache & smarte Budgetplanung' }, + { + founded: 2015, + hasFreePlan: true, + hasSelfHostingAbility: false, + key: 'boldin', + name: 'Boldin', + note: 'Originally named as NewRetirement', + origin: 'United States', + pricingPerYear: '$144', + slogan: 'Take control with retirement planning tools that begin with you' + }, { key: 'budgetpulse', name: 'BudgetPulse', @@ -841,6 +861,16 @@ export const personalFinanceTools: Product[] = [ pricingPerYear: '$108', slogan: 'Build Financial Plans You Love.' }, + { + founded: 2022, + hasFreePlan: false, + hasSelfHostingAbility: false, + key: 'prostocktracker', + name: 'Pro Stock Tracker', + origin: 'United Kingdom', + pricingPerYear: '$60', + slogan: 'The stock portfolio tracker built for long-term investors' + }, { founded: 2015, hasSelfHostingAbility: false, @@ -1014,6 +1044,16 @@ export const personalFinanceTools: Product[] = [ regions: ['Austria', 'Germany', 'Switzerland'], slogan: 'Dein Vermögen immer im Blick' }, + { + founded: 2025, + hasFreePlan: false, + hasSelfHostingAbility: false, + key: 'turbobulls', + name: 'Turbobulls', + origin: 'Romania', + pricingPerYear: '€39.99', + slogan: 'Your complete financial dashboard. Actually private.' + }, { hasFreePlan: true, hasSelfHostingAbility: false, From 8e47e198fa9218c123fc37cfb7a60f466affe93a Mon Sep 17 00:00:00 2001 From: Thomas Kaul <4159106+dtslvr@users.noreply.github.com> Date: Mon, 2 Mar 2026 20:06:53 +0100 Subject: [PATCH 089/224] Task/remove deprecated committed funds from summary of portfolio details (#6442) * Remove deprecated committedFunds * Update changelog --- CHANGELOG.md | 1 + apps/api/src/app/portfolio/portfolio.controller.ts | 1 - apps/api/src/app/portfolio/portfolio.service.ts | 3 --- apps/api/src/helper/object.helper.spec.ts | 2 -- libs/common/src/lib/interfaces/portfolio-summary.interface.ts | 4 ---- 5 files changed, 1 insertion(+), 10 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d7ebb665c..ddcb68ad8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Changed +- Removed the deprecated `committedFunds` from the summary of the portfolio details endpoint - Upgraded `Nx` from version `22.4.5` to `22.5.3` ## 2.245.0 - 2026-03-01 diff --git a/apps/api/src/app/portfolio/portfolio.controller.ts b/apps/api/src/app/portfolio/portfolio.controller.ts index 5ed3c0009..67b5229c1 100644 --- a/apps/api/src/app/portfolio/portfolio.controller.ts +++ b/apps/api/src/app/portfolio/portfolio.controller.ts @@ -187,7 +187,6 @@ export class PortfolioController { portfolioSummary = nullifyValuesInObject(summary, [ 'cash', - 'committedFunds', 'currentNetWorth', 'currentValueInBaseCurrency', 'dividendInBaseCurrency', diff --git a/apps/api/src/app/portfolio/portfolio.service.ts b/apps/api/src/app/portfolio/portfolio.service.ts index 17bd01ce4..26d16bf75 100644 --- a/apps/api/src/app/portfolio/portfolio.service.ts +++ b/apps/api/src/app/portfolio/portfolio.service.ts @@ -1914,8 +1914,6 @@ export class PortfolioService { .plus(emergencyFundHoldingsValueInBaseCurrency) .toNumber(); - const committedFunds = new Big(totalBuy).minus(totalSell); - const totalOfExcludedActivities = this.getSumOfActivityType({ userCurrency, activities: excludedActivities, @@ -1979,7 +1977,6 @@ export class PortfolioService { activityCount: activities.filter(({ type }) => { return ['BUY', 'SELL'].includes(type); }).length, - committedFunds: committedFunds.toNumber(), currentValueInBaseCurrency: currentValueInBaseCurrency.toNumber(), dividendInBaseCurrency: dividendInBaseCurrency.toNumber(), emergencyFund: { diff --git a/apps/api/src/helper/object.helper.spec.ts b/apps/api/src/helper/object.helper.spec.ts index eed261f3e..ba8760c70 100644 --- a/apps/api/src/helper/object.helper.spec.ts +++ b/apps/api/src/helper/object.helper.spec.ts @@ -1540,7 +1540,6 @@ describe('redactAttributes', () => { netPerformanceWithCurrencyEffect: null, totalBuy: null, totalSell: null, - committedFunds: null, currentValueInBaseCurrency: null, dividendInBaseCurrency: null, emergencyFund: null, @@ -3017,7 +3016,6 @@ describe('redactAttributes', () => { netPerformanceWithCurrencyEffect: null, totalBuy: null, totalSell: null, - committedFunds: null, currentValueInBaseCurrency: null, dividendInBaseCurrency: null, emergencyFund: null, diff --git a/libs/common/src/lib/interfaces/portfolio-summary.interface.ts b/libs/common/src/lib/interfaces/portfolio-summary.interface.ts index 79fbf8707..8db6b39bb 100644 --- a/libs/common/src/lib/interfaces/portfolio-summary.interface.ts +++ b/libs/common/src/lib/interfaces/portfolio-summary.interface.ts @@ -6,10 +6,6 @@ export interface PortfolioSummary extends PortfolioPerformance { annualizedPerformancePercent: number; annualizedPerformancePercentWithCurrencyEffect: number; cash: number; - - /** @deprecated use totalInvestmentValueWithCurrencyEffect instead */ - committedFunds: number; - dateOfFirstActivity: Date; dividendInBaseCurrency: number; emergencyFund: { From 27b1e74d2350a0227b93ed639ee625b559fe735c Mon Sep 17 00:00:00 2001 From: Thomas Kaul <4159106+dtslvr@users.noreply.github.com> Date: Tue, 3 Mar 2026 20:33:19 +0100 Subject: [PATCH 090/224] Bugfix/disabled buttons in assistant component (#6471) * Fix signal accessors * Update changelog --- CHANGELOG.md | 4 ++++ libs/ui/src/lib/assistant/assistant.html | 4 ++-- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ddcb68ad8..18055ec4b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,6 +12,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Removed the deprecated `committedFunds` from the summary of the portfolio details endpoint - Upgraded `Nx` from version `22.4.5` to `22.5.3` +### Fixed + +- Fixed an issue where the apply and reset filter buttons remained disabled in the assistant + ## 2.245.0 - 2026-03-01 ### Changed diff --git a/libs/ui/src/lib/assistant/assistant.html b/libs/ui/src/lib/assistant/assistant.html index 7e19833a9..79e2f31a1 100644 --- a/libs/ui/src/lib/assistant/assistant.html +++ b/libs/ui/src/lib/assistant/assistant.html @@ -197,7 +197,7 @@ mat-button type="button" [disabled]=" - !portfolioFilterForm.hasFilters() || portfolioFilterForm.disabled + !portfolioFilterForm.hasFilters() || portfolioFilterForm.disabled() " (click)="onResetFilters()" > @@ -210,7 +210,7 @@ type="button" [disabled]=" !portfolioFilterForm.filterForm.dirty || - portfolioFilterForm.disabled + portfolioFilterForm.disabled() " (click)="onApplyFilters()" > From 0883c7c5bf74282cad926c99d011c75b6894550d Mon Sep 17 00:00:00 2001 From: Thomas Kaul <4159106+dtslvr@users.noreply.github.com> Date: Tue, 3 Mar 2026 20:35:26 +0100 Subject: [PATCH 091/224] Release 2.246.0 (#6472) --- CHANGELOG.md | 2 +- package-lock.json | 4 ++-- package.json | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 18055ec4b..b5575e543 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,7 +5,7 @@ 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 +## 2.246.0 - 2026-03-03 ### Changed diff --git a/package-lock.json b/package-lock.json index 52b460666..87e61400d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "ghostfolio", - "version": "2.245.0", + "version": "2.246.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "ghostfolio", - "version": "2.245.0", + "version": "2.246.0", "hasInstallScript": true, "license": "AGPL-3.0", "dependencies": { diff --git a/package.json b/package.json index 8871e8acc..f3e74f28e 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "ghostfolio", - "version": "2.245.0", + "version": "2.246.0", "homepage": "https://ghostfol.io", "license": "AGPL-3.0", "repository": "https://github.com/ghostfolio/ghostfolio", From f92bb665e413729ffe83a3ccc068ef5061be45cc Mon Sep 17 00:00:00 2001 From: Lucas Macedo <83371481+lmaced0@users.noreply.github.com> Date: Wed, 4 Mar 2026 00:27:45 -0700 Subject: [PATCH 092/224] Task/upgrade yahoo-finance2 to version 3.13.1 (#6475) * Upgrade yahoo-finance2 to version 3.13.1 * Update changelog --- CHANGELOG.md | 6 ++++++ package-lock.json | 8 ++++---- package.json | 2 +- 3 files changed, 11 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b5575e543..25f00db9d 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 + +- Upgraded `yahoo-finance2` from version `3.13.0` to `3.13.1` + ## 2.246.0 - 2026-03-03 ### Changed diff --git a/package-lock.json b/package-lock.json index 87e61400d..370325602 100644 --- a/package-lock.json +++ b/package-lock.json @@ -89,7 +89,7 @@ "svgmap": "2.14.0", "tablemark": "4.1.0", "twitter-api-v2": "1.29.0", - "yahoo-finance2": "3.13.0", + "yahoo-finance2": "3.13.1", "zone.js": "0.16.0" }, "devDependencies": { @@ -35476,9 +35476,9 @@ } }, "node_modules/yahoo-finance2": { - "version": "3.13.0", - "resolved": "https://registry.npmjs.org/yahoo-finance2/-/yahoo-finance2-3.13.0.tgz", - "integrity": "sha512-czBj2q/MD68YEsB7aXNnGhJvWxYZn01O5r/i7VYiQV2m2sWwhca6tKgjwf/LT7zHHEVxhKNiGLB46glLnmq9Ag==", + "version": "3.13.1", + "resolved": "https://registry.npmjs.org/yahoo-finance2/-/yahoo-finance2-3.13.1.tgz", + "integrity": "sha512-kn3unY2OflG1NbeONedWxFDzq5QDyMYYAnr6VjRIOsMv5Q7ZXZZYFM8OadNZrOev4ikQjbYcMLLjogpVaez/vQ==", "license": "MIT", "dependencies": { "@deno/shim-deno": "~0.18.0", diff --git a/package.json b/package.json index f3e74f28e..f3397832e 100644 --- a/package.json +++ b/package.json @@ -134,7 +134,7 @@ "svgmap": "2.14.0", "tablemark": "4.1.0", "twitter-api-v2": "1.29.0", - "yahoo-finance2": "3.13.0", + "yahoo-finance2": "3.13.1", "zone.js": "0.16.0" }, "devDependencies": { From 2bd8463cafff181b3d82bc4c82fe714028d34c91 Mon Sep 17 00:00:00 2001 From: Thomas Kaul <4159106+dtslvr@users.noreply.github.com> Date: Wed, 4 Mar 2026 08:43:43 +0100 Subject: [PATCH 093/224] Task/upgrade yahoo-finance2 to version 3.13.2 (#6477) * Upgrade yahoo-finance2 to version 3.13.2 * Update changelog --- CHANGELOG.md | 2 +- package-lock.json | 8 ++++---- package.json | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 25f00db9d..6d5fa1836 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,7 +9,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Changed -- Upgraded `yahoo-finance2` from version `3.13.0` to `3.13.1` +- Upgraded `yahoo-finance2` from version `3.13.0` to `3.13.2` ## 2.246.0 - 2026-03-03 diff --git a/package-lock.json b/package-lock.json index 370325602..2744da2c3 100644 --- a/package-lock.json +++ b/package-lock.json @@ -89,7 +89,7 @@ "svgmap": "2.14.0", "tablemark": "4.1.0", "twitter-api-v2": "1.29.0", - "yahoo-finance2": "3.13.1", + "yahoo-finance2": "3.13.2", "zone.js": "0.16.0" }, "devDependencies": { @@ -35476,9 +35476,9 @@ } }, "node_modules/yahoo-finance2": { - "version": "3.13.1", - "resolved": "https://registry.npmjs.org/yahoo-finance2/-/yahoo-finance2-3.13.1.tgz", - "integrity": "sha512-kn3unY2OflG1NbeONedWxFDzq5QDyMYYAnr6VjRIOsMv5Q7ZXZZYFM8OadNZrOev4ikQjbYcMLLjogpVaez/vQ==", + "version": "3.13.2", + "resolved": "https://registry.npmjs.org/yahoo-finance2/-/yahoo-finance2-3.13.2.tgz", + "integrity": "sha512-aAOJEjuLClfDxVPRKxjcwFoyzMr8BE/svgUqr5IjnQR+kppYbKO92Wl3SbAGz5DRghy6FiUfqi5FBDSBA/e2jg==", "license": "MIT", "dependencies": { "@deno/shim-deno": "~0.18.0", diff --git a/package.json b/package.json index f3397832e..536f7fe80 100644 --- a/package.json +++ b/package.json @@ -134,7 +134,7 @@ "svgmap": "2.14.0", "tablemark": "4.1.0", "twitter-api-v2": "1.29.0", - "yahoo-finance2": "3.13.1", + "yahoo-finance2": "3.13.2", "zone.js": "0.16.0" }, "devDependencies": { From 53d9fd42d8d34bd5b5c00a0a3665ea2de8cd6366 Mon Sep 17 00:00:00 2001 From: Thomas Kaul <4159106+dtslvr@users.noreply.github.com> Date: Wed, 4 Mar 2026 08:46:04 +0100 Subject: [PATCH 094/224] Release 2.247.0 (#6478) --- CHANGELOG.md | 2 +- package-lock.json | 4 ++-- package.json | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6d5fa1836..37ff3cf87 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,7 +5,7 @@ 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 +## 2.247.0 - 2026-03-04 ### Changed diff --git a/package-lock.json b/package-lock.json index 2744da2c3..8dbc7866a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "ghostfolio", - "version": "2.246.0", + "version": "2.247.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "ghostfolio", - "version": "2.246.0", + "version": "2.247.0", "hasInstallScript": true, "license": "AGPL-3.0", "dependencies": { diff --git a/package.json b/package.json index 536f7fe80..628de4a9d 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "ghostfolio", - "version": "2.246.0", + "version": "2.247.0", "homepage": "https://ghostfol.io", "license": "AGPL-3.0", "repository": "https://github.com/ghostfolio/ghostfolio", From 945450f3e00b498a609a8879e0f90f00bc008207 Mon Sep 17 00:00:00 2001 From: Thomas Kaul <4159106+dtslvr@users.noreply.github.com> Date: Wed, 4 Mar 2026 19:39:29 +0100 Subject: [PATCH 095/224] Task/upgrade jsonpath to version 1.2.1 (#6465) * Upgrade jsonpath to version 1.2.1 * Update changelog --- CHANGELOG.md | 6 ++ package-lock.json | 160 +++++++++++++++------------------------------- package.json | 2 +- 3 files changed, 58 insertions(+), 110 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 37ff3cf87..f536f143b 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 + +- Upgraded `jsonpath` from version `1.1.1` to `1.2.1` + ## 2.247.0 - 2026-03-04 ### Changed diff --git a/package-lock.json b/package-lock.json index 8dbc7866a..8fb2f8bb1 100644 --- a/package-lock.json +++ b/package-lock.json @@ -68,7 +68,7 @@ "helmet": "7.0.0", "http-status-codes": "2.3.0", "ionicons": "8.0.13", - "jsonpath": "1.1.1", + "jsonpath": "1.2.1", "lodash": "4.17.23", "marked": "17.0.2", "ms": "3.0.0-canary.1", @@ -18320,6 +18320,7 @@ "version": "0.1.4", "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", + "dev": true, "license": "MIT" }, "node_modules/deepmerge": { @@ -19280,6 +19281,37 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/escodegen": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-2.1.0.tgz", + "integrity": "sha512-2NlIDTwUWJN0mRPQOdtQBzbUHvdGY2P1VXSyU83Q3xKxM7WHX2Ql8dKq782Q9TgQUNOLEzEYu9bzLNj1q88I5w==", + "license": "BSD-2-Clause", + "dependencies": { + "esprima": "^4.0.1", + "estraverse": "^5.2.0", + "esutils": "^2.0.2" + }, + "bin": { + "escodegen": "bin/escodegen.js", + "esgenerate": "bin/esgenerate.js" + }, + "engines": { + "node": ">=6.0" + }, + "optionalDependencies": { + "source-map": "~0.6.1" + } + }, + "node_modules/escodegen/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "license": "BSD-3-Clause", + "optional": true, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/eslint": { "version": "9.35.0", "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.35.0.tgz", @@ -19713,7 +19745,6 @@ "version": "5.3.0", "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", - "dev": true, "license": "BSD-2-Clause", "engines": { "node": ">=4.0" @@ -20061,6 +20092,7 @@ "version": "2.0.6", "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", + "dev": true, "license": "MIT" }, "node_modules/fast-redact": { @@ -24594,20 +24626,20 @@ "license": "MIT" }, "node_modules/jsonpath": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/jsonpath/-/jsonpath-1.1.1.tgz", - "integrity": "sha512-l6Cg7jRpixfbgoWgkrl77dgEj8RPvND0wMH6TwQmi9Qs4TFfS9u5cUFnbeKTwj5ga5Y3BTGGNI28k117LJ009w==", + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/jsonpath/-/jsonpath-1.2.1.tgz", + "integrity": "sha512-Jl6Jhk0jG+kP3yk59SSeGq7LFPR4JQz1DU0K+kXTysUhMostbhU3qh5mjTuf0PqFcXpAT7kvmMt9WxV10NyIgQ==", "license": "MIT", "dependencies": { - "esprima": "1.2.2", - "static-eval": "2.0.2", - "underscore": "1.12.1" + "esprima": "1.2.5", + "static-eval": "2.1.1", + "underscore": "1.13.6" } }, "node_modules/jsonpath/node_modules/esprima": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-1.2.2.tgz", - "integrity": "sha512-+JpPZam9w5DuJ3Q67SqsMGtiHKENSMRVoxvArfJZK01/BfLEObtZ6orJa/MtoGNR/rfMgp5837T41PAmTwAv/A==", + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-1.2.5.tgz", + "integrity": "sha512-S9VbPDU0adFErpDai3qDkjq8+G05ONtKzcyNrPKg/ZKa+tf879nX2KexNU95b31UoTJjRLInNBHHHjFPoCd7lQ==", "bin": { "esparse": "bin/esparse.js", "esvalidate": "bin/esvalidate.js" @@ -31771,103 +31803,12 @@ "license": "MIT" }, "node_modules/static-eval": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/static-eval/-/static-eval-2.0.2.tgz", - "integrity": "sha512-N/D219Hcr2bPjLxPiV+TQE++Tsmrady7TqAJugLy7Xk1EumfDWS/f5dtBbkRCGE7wKKXuYockQoj8Rm2/pVKyg==", - "license": "MIT", - "dependencies": { - "escodegen": "^1.8.1" - } - }, - "node_modules/static-eval/node_modules/escodegen": { - "version": "1.14.3", - "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-1.14.3.tgz", - "integrity": "sha512-qFcX0XJkdg+PB3xjZZG/wKSuT1PnQWx57+TVSjIMmILd2yC/6ByYElPwJnslDsuWuSAp4AwJGumarAAmJch5Kw==", - "license": "BSD-2-Clause", - "dependencies": { - "esprima": "^4.0.1", - "estraverse": "^4.2.0", - "esutils": "^2.0.2", - "optionator": "^0.8.1" - }, - "bin": { - "escodegen": "bin/escodegen.js", - "esgenerate": "bin/esgenerate.js" - }, - "engines": { - "node": ">=4.0" - }, - "optionalDependencies": { - "source-map": "~0.6.1" - } - }, - "node_modules/static-eval/node_modules/estraverse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", - "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", - "license": "BSD-2-Clause", - "engines": { - "node": ">=4.0" - } - }, - "node_modules/static-eval/node_modules/levn": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", - "integrity": "sha512-0OO4y2iOHix2W6ujICbKIaEQXvFQHue65vUG3pb5EUomzPI90z9hsA1VsO/dbIIpC53J8gxM9Q4Oho0jrCM/yA==", - "license": "MIT", - "dependencies": { - "prelude-ls": "~1.1.2", - "type-check": "~0.3.2" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/static-eval/node_modules/optionator": { - "version": "0.8.3", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.3.tgz", - "integrity": "sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==", - "license": "MIT", - "dependencies": { - "deep-is": "~0.1.3", - "fast-levenshtein": "~2.0.6", - "levn": "~0.3.0", - "prelude-ls": "~1.1.2", - "type-check": "~0.3.2", - "word-wrap": "~1.2.3" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/static-eval/node_modules/prelude-ls": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", - "integrity": "sha512-ESF23V4SKG6lVSGZgYNpbsiaAkdab6ZgOxe52p7+Kid3W3u3bxR4Vfd/o21dmN7jSt0IwgZ4v5MUd26FEtXE9w==", - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/static-eval/node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "license": "BSD-3-Clause", - "optional": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/static-eval/node_modules/type-check": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", - "integrity": "sha512-ZCmOJdvOWDBYJlzAoFkC+Q0+bUyEOS1ltgp1MGU03fqHG+dbi9tBFU2Rd9QKiDZFAYrhPh2JUf7rZRIuHRKtOg==", + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/static-eval/-/static-eval-2.1.1.tgz", + "integrity": "sha512-MgWpQ/ZjGieSVB3eOJVs4OA2LT/q1vx98KPCTTQPzq/aLr0YUXTsgryTXr4SLfR0ZfUUCiedM9n/ABeDIyy4mA==", "license": "MIT", "dependencies": { - "prelude-ls": "~1.1.2" - }, - "engines": { - "node": ">= 0.8.0" + "escodegen": "^2.1.0" } }, "node_modules/statuses": { @@ -33721,9 +33662,9 @@ } }, "node_modules/underscore": { - "version": "1.12.1", - "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.12.1.tgz", - "integrity": "sha512-hEQt0+ZLDVUMhebKxL4x1BTtDY7bavVofhZ9KZ4aI26X9SRaE+Y3m83XUL1UP2jn8ynjndwCCpEHdUG+9pP1Tw==", + "version": "1.13.6", + "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.13.6.tgz", + "integrity": "sha512-+A5Sja4HP1M08MaXya7p5LvjuM7K6q/2EaC0+iovj/wOcMsTzMvDFbasi/oSapiwOlt252IqsKqPjCl7huKS0A==", "license": "MIT" }, "node_modules/undici": { @@ -35326,6 +35267,7 @@ "version": "1.2.5", "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==", + "dev": true, "license": "MIT", "engines": { "node": ">=0.10.0" diff --git a/package.json b/package.json index 628de4a9d..0e2c3ccc1 100644 --- a/package.json +++ b/package.json @@ -113,7 +113,7 @@ "helmet": "7.0.0", "http-status-codes": "2.3.0", "ionicons": "8.0.13", - "jsonpath": "1.1.1", + "jsonpath": "1.2.1", "lodash": "4.17.23", "marked": "17.0.2", "ms": "3.0.0-canary.1", From 86d4d6ed649f99e3e5b307d6f15590feead134eb Mon Sep 17 00:00:00 2001 From: Thomas Kaul <4159106+dtslvr@users.noreply.github.com> Date: Thu, 5 Mar 2026 22:29:11 +0100 Subject: [PATCH 096/224] Task/implement OnModuleInit interface in TwitterBotService (#6447) * Implement OnModuleInit interface --- apps/api/src/services/twitter-bot/twitter-bot.service.ts | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/apps/api/src/services/twitter-bot/twitter-bot.service.ts b/apps/api/src/services/twitter-bot/twitter-bot.service.ts index ee951820d..b424f7198 100644 --- a/apps/api/src/services/twitter-bot/twitter-bot.service.ts +++ b/apps/api/src/services/twitter-bot/twitter-bot.service.ts @@ -10,19 +10,21 @@ import { resolveMarketCondition } from '@ghostfolio/common/helper'; -import { Injectable, Logger } from '@nestjs/common'; +import { Injectable, Logger, OnModuleInit } from '@nestjs/common'; import { isWeekend } from 'date-fns'; import { TwitterApi, TwitterApiReadWrite } from 'twitter-api-v2'; @Injectable() -export class TwitterBotService { +export class TwitterBotService implements OnModuleInit { private twitterClient: TwitterApiReadWrite; public constructor( private readonly benchmarkService: BenchmarkService, private readonly configurationService: ConfigurationService, private readonly symbolService: SymbolService - ) { + ) {} + + public onModuleInit() { this.twitterClient = new TwitterApi({ accessSecret: this.configurationService.get( 'TWITTER_ACCESS_TOKEN_SECRET' From 3d07f69e176d4f87996fc682f6e4a26add6c0ea5 Mon Sep 17 00:00:00 2001 From: DmytroSkachko Date: Thu, 5 Mar 2026 22:45:14 +0100 Subject: [PATCH 097/224] Task/reuse value component in tag component of Admin Control panel (#6467) * Reuse value component * Update changelog --- CHANGELOG.md | 1 + .../components/admin-settings/admin-settings.component.html | 2 +- .../components/admin-settings/admin-settings.component.ts | 2 +- .../src/app/components/admin-tag/admin-tag.component.html | 6 +++++- .../src/app/components/admin-tag/admin-tag.component.ts | 6 ++++++ 5 files changed, 14 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f536f143b..0aa2e9459 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Changed +- Reused the value component in the tag management of the admin control panel - Upgraded `jsonpath` from version `1.1.1` to `1.2.1` ## 2.247.0 - 2026-03-04 diff --git a/apps/client/src/app/components/admin-settings/admin-settings.component.html b/apps/client/src/app/components/admin-settings/admin-settings.component.html index af64f034b..571e45afa 100644 --- a/apps/client/src/app/components/admin-settings/admin-settings.component.html +++ b/apps/client/src/app/components/admin-settings/admin-settings.component.html @@ -199,7 +199,7 @@

    Tags

    - +
    diff --git a/apps/client/src/app/components/admin-settings/admin-settings.component.ts b/apps/client/src/app/components/admin-settings/admin-settings.component.ts index 446221058..219fd2847 100644 --- a/apps/client/src/app/components/admin-settings/admin-settings.component.ts +++ b/apps/client/src/app/components/admin-settings/admin-settings.component.ts @@ -74,9 +74,9 @@ export class GfAdminSettingsComponent implements OnDestroy, OnInit { public isGhostfolioApiKeyValid: boolean; public isLoading = false; public pricingUrl: string; + public user: User; private unsubscribeSubject = new Subject(); - private user: User; public constructor( private adminService: AdminService, diff --git a/apps/client/src/app/components/admin-tag/admin-tag.component.html b/apps/client/src/app/components/admin-tag/admin-tag.component.html index 98919abd8..463a817ff 100644 --- a/apps/client/src/app/components/admin-tag/admin-tag.component.html +++ b/apps/client/src/app/components/admin-tag/admin-tag.component.html @@ -45,7 +45,11 @@ Activities - {{ element.activityCount }} + diff --git a/apps/client/src/app/components/admin-tag/admin-tag.component.ts b/apps/client/src/app/components/admin-tag/admin-tag.component.ts index ca7950291..0b64a4ca1 100644 --- a/apps/client/src/app/components/admin-tag/admin-tag.component.ts +++ b/apps/client/src/app/components/admin-tag/admin-tag.component.ts @@ -1,13 +1,16 @@ import { UserService } from '@ghostfolio/client/services/user/user.service'; import { CreateTagDto, UpdateTagDto } from '@ghostfolio/common/dtos'; import { ConfirmationDialogType } from '@ghostfolio/common/enums'; +import { getLocale } from '@ghostfolio/common/helper'; import { NotificationService } from '@ghostfolio/ui/notifications'; import { DataService } from '@ghostfolio/ui/services'; +import { GfValueComponent } from '@ghostfolio/ui/value'; import { ChangeDetectionStrategy, ChangeDetectorRef, Component, + Input, OnDestroy, OnInit, ViewChild @@ -36,6 +39,7 @@ import { CreateOrUpdateTagDialogParams } from './create-or-update-tag-dialog/int @Component({ changeDetection: ChangeDetectionStrategy.OnPush, imports: [ + GfValueComponent, IonIcon, MatButtonModule, MatMenuModule, @@ -48,6 +52,8 @@ import { CreateOrUpdateTagDialogParams } from './create-or-update-tag-dialog/int templateUrl: './admin-tag.component.html' }) export class GfAdminTagComponent implements OnDestroy, OnInit { + @Input() locale = getLocale(); + @ViewChild(MatSort) sort: MatSort; public dataSource = new MatTableDataSource(); From 3c886f134d73be38abdf5aeb55977d17fc1db9cf Mon Sep 17 00:00:00 2001 From: Winn Cook <111204176+WinnCook@users.noreply.github.com> Date: Fri, 6 Mar 2026 00:18:07 -0700 Subject: [PATCH 098/224] Task/reuse value component in platform component of Admin Control panel (#6470) * Reuse value component * Update changelog --------- Co-authored-by: Thomas Kaul <4159106+dtslvr@users.noreply.github.com> --- CHANGELOG.md | 1 + .../components/admin-platform/admin-platform.component.html | 6 +++++- .../components/admin-platform/admin-platform.component.ts | 6 ++++++ .../components/admin-settings/admin-settings.component.html | 2 +- 4 files changed, 13 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0aa2e9459..0ce9598e3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Changed +- Reused the value component in the platform management of the admin control panel - Reused the value component in the tag management of the admin control panel - Upgraded `jsonpath` from version `1.1.1` to `1.2.1` diff --git a/apps/client/src/app/components/admin-platform/admin-platform.component.html b/apps/client/src/app/components/admin-platform/admin-platform.component.html index 367827878..7370a19ae 100644 --- a/apps/client/src/app/components/admin-platform/admin-platform.component.html +++ b/apps/client/src/app/components/admin-platform/admin-platform.component.html @@ -52,7 +52,11 @@ Accounts - {{ element.accountCount }} + diff --git a/apps/client/src/app/components/admin-platform/admin-platform.component.ts b/apps/client/src/app/components/admin-platform/admin-platform.component.ts index 02a2eed64..2a04f86cc 100644 --- a/apps/client/src/app/components/admin-platform/admin-platform.component.ts +++ b/apps/client/src/app/components/admin-platform/admin-platform.component.ts @@ -1,14 +1,17 @@ import { UserService } from '@ghostfolio/client/services/user/user.service'; import { CreatePlatformDto, UpdatePlatformDto } from '@ghostfolio/common/dtos'; import { ConfirmationDialogType } from '@ghostfolio/common/enums'; +import { getLocale } from '@ghostfolio/common/helper'; import { GfEntityLogoComponent } from '@ghostfolio/ui/entity-logo'; import { NotificationService } from '@ghostfolio/ui/notifications'; import { AdminService, DataService } from '@ghostfolio/ui/services'; +import { GfValueComponent } from '@ghostfolio/ui/value'; import { ChangeDetectionStrategy, ChangeDetectorRef, Component, + Input, OnDestroy, OnInit, ViewChild @@ -38,6 +41,7 @@ import { CreateOrUpdatePlatformDialogParams } from './create-or-update-platform- changeDetection: ChangeDetectionStrategy.OnPush, imports: [ GfEntityLogoComponent, + GfValueComponent, IonIcon, MatButtonModule, MatMenuModule, @@ -50,6 +54,8 @@ import { CreateOrUpdatePlatformDialogParams } from './create-or-update-platform- templateUrl: './admin-platform.component.html' }) export class GfAdminPlatformComponent implements OnDestroy, OnInit { + @Input() locale = getLocale(); + @ViewChild(MatSort) sort: MatSort; public dataSource = new MatTableDataSource(); diff --git a/apps/client/src/app/components/admin-settings/admin-settings.component.html b/apps/client/src/app/components/admin-settings/admin-settings.component.html index 571e45afa..41a9992c9 100644 --- a/apps/client/src/app/components/admin-settings/admin-settings.component.html +++ b/apps/client/src/app/components/admin-settings/admin-settings.component.html @@ -193,7 +193,7 @@

    Platforms

    - +
    From a1283e40f50a86dc2a4975d03b1d8e55ec44a2cd Mon Sep 17 00:00:00 2001 From: Thomas Kaul <4159106+dtslvr@users.noreply.github.com> Date: Sat, 7 Mar 2026 08:53:11 +0100 Subject: [PATCH 099/224] Task/upgrade @types/passport-google-oauth20 to version 2.0.17 (#6325) * Upgrade @types/passport-google-oauth20 to version 2.0.17 --- package-lock.json | 8 ++++---- package.json | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package-lock.json b/package-lock.json index 8fb2f8bb1..0ea9bbdce 100644 --- a/package-lock.json +++ b/package-lock.json @@ -130,7 +130,7 @@ "@types/lodash": "4.17.23", "@types/node": "22.15.17", "@types/papaparse": "5.3.7", - "@types/passport-google-oauth20": "2.0.16", + "@types/passport-google-oauth20": "2.0.17", "@types/passport-openidconnect": "0.1.3", "@typescript-eslint/eslint-plugin": "8.43.0", "@typescript-eslint/parser": "8.43.0", @@ -13304,9 +13304,9 @@ } }, "node_modules/@types/passport-google-oauth20": { - "version": "2.0.16", - "resolved": "https://registry.npmjs.org/@types/passport-google-oauth20/-/passport-google-oauth20-2.0.16.tgz", - "integrity": "sha512-ayXK2CJ7uVieqhYOc6k/pIr5pcQxOLB6kBev+QUGS7oEZeTgIs1odDobXRqgfBPvXzl0wXCQHftV5220czZCPA==", + "version": "2.0.17", + "resolved": "https://registry.npmjs.org/@types/passport-google-oauth20/-/passport-google-oauth20-2.0.17.tgz", + "integrity": "sha512-MHNOd2l7gOTCn3iS+wInPQMiukliAUvMpODO3VlXxOiwNEMSyzV7UNvAdqxSN872o8OXx1SqPDVT6tLW74AtqQ==", "dev": true, "license": "MIT", "dependencies": { diff --git a/package.json b/package.json index 0e2c3ccc1..47c9e9ade 100644 --- a/package.json +++ b/package.json @@ -175,7 +175,7 @@ "@types/lodash": "4.17.23", "@types/node": "22.15.17", "@types/papaparse": "5.3.7", - "@types/passport-google-oauth20": "2.0.16", + "@types/passport-google-oauth20": "2.0.17", "@types/passport-openidconnect": "0.1.3", "@typescript-eslint/eslint-plugin": "8.43.0", "@typescript-eslint/parser": "8.43.0", From b7d976d2ff5c8fbf1972d9b6eaaa309acd2ae51c Mon Sep 17 00:00:00 2001 From: Thomas Kaul <4159106+dtslvr@users.noreply.github.com> Date: Sat, 7 Mar 2026 08:58:59 +0100 Subject: [PATCH 100/224] Task/add asset profile to portfolio position interface (#6473) * Add asset profile * Update changelog --- CHANGELOG.md | 2 + .../app/endpoints/public/public.controller.ts | 1 + .../src/app/portfolio/portfolio.service.ts | 31 ++++ ...orm-data-source-in-response.interceptor.ts | 1 + .../portfolio-position.interface.ts | 45 +++++ .../public-portfolio-response.interface.ts | 15 ++ libs/ui/src/lib/mocks/holdings.ts | 155 ++++++++++++++++-- 7 files changed, 240 insertions(+), 10 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0ce9598e3..b2b2eb1ca 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Changed +- Included asset profile data in the endpoint `GET api/v1/portfolio/holdings` +- Included asset profile data in the holdings of the public page - Reused the value component in the platform management of the admin control panel - Reused the value component in the tag management of the admin control panel - Upgraded `jsonpath` from version `1.1.1` to `1.2.1` diff --git a/apps/api/src/app/endpoints/public/public.controller.ts b/apps/api/src/app/endpoints/public/public.controller.ts index b4ecd37ba..a1b2b7864 100644 --- a/apps/api/src/app/endpoints/public/public.controller.ts +++ b/apps/api/src/app/endpoints/public/public.controller.ts @@ -167,6 +167,7 @@ export class PublicController { allocationInPercentage: portfolioPosition.valueInBaseCurrency / totalValue, assetClass: hasDetails ? portfolioPosition.assetClass : undefined, + assetProfile: hasDetails ? portfolioPosition.assetProfile : undefined, countries: hasDetails ? portfolioPosition.countries : [], currency: hasDetails ? portfolioPosition.currency : undefined, dataSource: portfolioPosition.dataSource, diff --git a/apps/api/src/app/portfolio/portfolio.service.ts b/apps/api/src/app/portfolio/portfolio.service.ts index 26d16bf75..1bfad8395 100644 --- a/apps/api/src/app/portfolio/portfolio.service.ts +++ b/apps/api/src/app/portfolio/portfolio.service.ts @@ -623,6 +623,27 @@ export class PortfolioService { ? 0 : valueInBaseCurrency.div(filteredValueInBaseCurrency).toNumber(), assetClass: assetProfile.assetClass, + assetProfile: { + assetClass: assetProfile.assetClass, + assetSubClass: assetProfile.assetSubClass, + countries: assetProfile.countries, + dataSource: assetProfile.dataSource, + holdings: assetProfile.holdings.map( + ({ allocationInPercentage, name }) => { + return { + allocationInPercentage, + name, + valueInBaseCurrency: valueInBaseCurrency + .mul(allocationInPercentage) + .toNumber() + }; + } + ), + name: assetProfile.name, + sectors: assetProfile.sectors, + symbol: assetProfile.symbol, + url: assetProfile.url + }, assetSubClass: assetProfile.assetSubClass, countries: assetProfile.countries, dataSource: assetProfile.dataSource, @@ -1672,6 +1693,16 @@ export class PortfolioService { allocationInPercentage: 0, assetClass: AssetClass.LIQUIDITY, assetSubClass: AssetSubClass.CASH, + assetProfile: { + assetClass: AssetClass.LIQUIDITY, + assetSubClass: AssetSubClass.CASH, + countries: [], + dataSource: undefined, + holdings: [], + name: currency, + sectors: [], + symbol: currency + }, countries: [], dataSource: undefined, dateOfFirstActivity: undefined, diff --git a/apps/api/src/interceptors/transform-data-source-in-response/transform-data-source-in-response.interceptor.ts b/apps/api/src/interceptors/transform-data-source-in-response/transform-data-source-in-response.interceptor.ts index 3cccd6efa..57643f76c 100644 --- a/apps/api/src/interceptors/transform-data-source-in-response/transform-data-source-in-response.interceptor.ts +++ b/apps/api/src/interceptors/transform-data-source-in-response/transform-data-source-in-response.interceptor.ts @@ -68,6 +68,7 @@ export class TransformDataSourceInResponseInterceptor< 'errors[*].dataSource', 'fearAndGreedIndex.CRYPTOCURRENCIES.dataSource', 'fearAndGreedIndex.STOCKS.dataSource', + 'holdings[*].assetProfile.dataSource', 'holdings[*].dataSource', 'items[*].dataSource', 'SymbolProfile.dataSource', diff --git a/libs/common/src/lib/interfaces/portfolio-position.interface.ts b/libs/common/src/lib/interfaces/portfolio-position.interface.ts index 620cc00e9..742e63d7a 100644 --- a/libs/common/src/lib/interfaces/portfolio-position.interface.ts +++ b/libs/common/src/lib/interfaces/portfolio-position.interface.ts @@ -3,19 +3,50 @@ import { Market, MarketAdvanced } from '@ghostfolio/common/types'; import { AssetClass, AssetSubClass, DataSource, Tag } from '@prisma/client'; import { Country } from './country.interface'; +import { EnhancedSymbolProfile } from './enhanced-symbol-profile.interface'; import { Holding } from './holding.interface'; import { Sector } from './sector.interface'; export interface PortfolioPosition { activitiesCount: number; allocationInPercentage: number; + + /** @deprecated */ assetClass?: AssetClass; + + /** @deprecated */ assetClassLabel?: string; + + assetProfile: Pick< + EnhancedSymbolProfile, + | 'assetClass' + | 'assetSubClass' + | 'countries' + | 'dataSource' + | 'holdings' + | 'name' + | 'sectors' + | 'symbol' + | 'url' + > & { + assetClassLabel?: string; + assetSubClassLabel?: string; + }; + + /** @deprecated */ assetSubClass?: AssetSubClass; + + /** @deprecated */ assetSubClassLabel?: string; + + /** @deprecated */ countries: Country[]; + currency: string; + + /** @deprecated */ dataSource: DataSource; + dateOfFirstActivity: Date; dividend: number; exchange?: string; @@ -23,24 +54,38 @@ export interface PortfolioPosition { grossPerformancePercent: number; grossPerformancePercentWithCurrencyEffect: number; grossPerformanceWithCurrencyEffect: number; + + /** @deprecated */ holdings: Holding[]; + investment: number; marketChange?: number; marketChangePercent?: number; marketPrice: number; markets?: { [key in Market]: number }; marketsAdvanced?: { [key in MarketAdvanced]: number }; + + /** @deprecated */ name: string; + netPerformance: number; netPerformancePercent: number; netPerformancePercentWithCurrencyEffect: number; netPerformanceWithCurrencyEffect: number; quantity: number; + + /** @deprecated */ sectors: Sector[]; + + /** @deprecated */ symbol: string; + tags?: Tag[]; type?: string; + + /** @deprecated */ url?: string; + valueInBaseCurrency?: number; valueInPercentage?: number; } diff --git a/libs/common/src/lib/interfaces/responses/public-portfolio-response.interface.ts b/libs/common/src/lib/interfaces/responses/public-portfolio-response.interface.ts index 4a087ad16..eae14cec6 100644 --- a/libs/common/src/lib/interfaces/responses/public-portfolio-response.interface.ts +++ b/libs/common/src/lib/interfaces/responses/public-portfolio-response.interface.ts @@ -14,16 +14,31 @@ export interface PublicPortfolioResponse extends PublicPortfolioResponseV1 { [symbol: string]: Pick< PortfolioPosition, | 'allocationInPercentage' + + /** @deprecated */ | 'assetClass' + | 'assetProfile' + + /** @deprecated */ | 'countries' | 'currency' + + /** @deprecated */ | 'dataSource' | 'dateOfFirstActivity' | 'markets' + + /** @deprecated */ | 'name' | 'netPerformancePercentWithCurrencyEffect' + + /** @deprecated */ | 'sectors' + + /** @deprecated */ | 'symbol' + + /** @deprecated */ | 'url' | 'valueInBaseCurrency' | 'valueInPercentage' diff --git a/libs/ui/src/lib/mocks/holdings.ts b/libs/ui/src/lib/mocks/holdings.ts index 5ab3e89eb..f426593c1 100644 --- a/libs/ui/src/lib/mocks/holdings.ts +++ b/libs/ui/src/lib/mocks/holdings.ts @@ -6,14 +6,35 @@ export const holdings: PortfolioPosition[] = [ allocationInPercentage: 0.042990776363386086, assetClass: 'EQUITY', assetClassLabel: 'Equity', + assetProfile: { + assetClass: 'EQUITY', + assetSubClass: 'STOCK', + countries: [ + { + code: 'US', + continent: 'North America', + name: 'United States', + weight: 1 + } + ], + dataSource: 'YAHOO', + holdings: [], + sectors: [ + { + name: 'Technology', + weight: 1 + } + ], + symbol: 'AAPL' + }, assetSubClass: 'STOCK', assetSubClassLabel: 'Stock', countries: [ { code: 'US', - weight: 1, continent: 'North America', - name: 'United States' + name: 'United States', + weight: 1 } ], currency: 'USD', @@ -49,14 +70,35 @@ export const holdings: PortfolioPosition[] = [ allocationInPercentage: 0.02377401948293552, assetClass: 'EQUITY', assetClassLabel: 'Equity', + assetProfile: { + assetClass: 'EQUITY', + assetSubClass: 'STOCK', + countries: [ + { + code: 'DE', + continent: 'Europe', + name: 'Germany', + weight: 1 + } + ], + dataSource: 'YAHOO', + holdings: [], + sectors: [ + { + name: 'Financial Services', + weight: 1 + } + ], + symbol: 'ALV.DE' + }, assetSubClass: 'STOCK', assetSubClassLabel: 'Stock', countries: [ { code: 'DE', - weight: 1, continent: 'Europe', - name: 'Germany' + name: 'Germany', + weight: 1 } ], currency: 'EUR', @@ -92,14 +134,35 @@ export const holdings: PortfolioPosition[] = [ allocationInPercentage: 0.08038536990007467, assetClass: 'EQUITY', assetClassLabel: 'Equity', + assetProfile: { + assetClass: 'EQUITY', + assetSubClass: 'STOCK', + countries: [ + { + code: 'US', + continent: 'North America', + name: 'United States', + weight: 1 + } + ], + dataSource: 'YAHOO', + holdings: [], + sectors: [ + { + name: 'Consumer Discretionary', + weight: 1 + } + ], + symbol: 'AMZN' + }, assetSubClass: 'STOCK', assetSubClassLabel: 'Stock', countries: [ { code: 'US', - weight: 1, continent: 'North America', - name: 'United States' + name: 'United States', + weight: 1 } ], currency: 'USD', @@ -135,6 +198,15 @@ export const holdings: PortfolioPosition[] = [ allocationInPercentage: 0.19216416482928922, assetClass: 'LIQUIDITY', assetClassLabel: 'Liquidity', + assetProfile: { + assetClass: 'LIQUIDITY', + assetSubClass: 'CASH', + countries: [], + dataSource: 'COINGECKO', + holdings: [], + sectors: [], + symbol: 'bitcoin' + }, assetSubClass: 'CRYPTOCURRENCY', assetSubClassLabel: 'Cryptocurrency', countries: [], @@ -166,14 +238,35 @@ export const holdings: PortfolioPosition[] = [ allocationInPercentage: 0.04307127421937313, assetClass: 'EQUITY', assetClassLabel: 'Equity', + assetProfile: { + assetClass: 'EQUITY', + assetSubClass: 'STOCK', + countries: [ + { + code: 'US', + continent: 'North America', + name: 'United States', + weight: 1 + } + ], + dataSource: 'YAHOO', + holdings: [], + sectors: [ + { + name: 'Technology', + weight: 1 + } + ], + symbol: 'MSFT' + }, assetSubClass: 'STOCK', assetSubClassLabel: 'Stock', countries: [ { code: 'US', - weight: 1, continent: 'North America', - name: 'United States' + name: 'United States', + weight: 1 } ], currency: 'USD', @@ -209,14 +302,35 @@ export const holdings: PortfolioPosition[] = [ allocationInPercentage: 0.18762679306394897, assetClass: 'EQUITY', assetClassLabel: 'Equity', + assetProfile: { + assetClass: 'EQUITY', + assetSubClass: 'STOCK', + countries: [ + { + code: 'US', + continent: 'North America', + name: 'United States', + weight: 1 + } + ], + dataSource: 'YAHOO', + holdings: [], + sectors: [ + { + name: 'Consumer Discretionary', + weight: 1 + } + ], + symbol: 'TSLA' + }, assetSubClass: 'STOCK', assetSubClassLabel: 'Stock', countries: [ { code: 'US', - weight: 1, continent: 'North America', - name: 'United States' + name: 'United States', + weight: 1 } ], currency: 'USD', @@ -252,6 +366,27 @@ export const holdings: PortfolioPosition[] = [ allocationInPercentage: 0.053051250766657634, assetClass: 'EQUITY', assetClassLabel: 'Equity', + assetProfile: { + assetClass: 'EQUITY', + assetSubClass: 'ETF', + countries: [ + { + code: 'US', + continent: 'North America', + name: 'United States', + weight: 1 + } + ], + dataSource: 'YAHOO', + holdings: [], + sectors: [ + { + name: 'Equity', + weight: 1 + } + ], + symbol: 'VTI' + }, assetSubClass: 'ETF', assetSubClassLabel: 'ETF', countries: [ From 9fe38e02f36bd1b2ea8e15e7bd0de7f02629a3dd Mon Sep 17 00:00:00 2001 From: David Requeno <108202767+DavidReque@users.noreply.github.com> Date: Sat, 7 Mar 2026 02:03:31 -0600 Subject: [PATCH 101/224] Feature/enable column sorting in data provider table (#6476) * Enable column sorting * Update changelog --- CHANGELOG.md | 4 ++++ .../admin-settings.component.html | 23 ++++++++++++++++--- .../admin-settings.component.ts | 10 +++++++- 3 files changed, 33 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b2b2eb1ca..9a837052a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## Unreleased +### Added + +- Added support for column sorting to the data providers management of the admin control panel + ### Changed - Included asset profile data in the endpoint `GET api/v1/portfolio/holdings` diff --git a/apps/client/src/app/components/admin-settings/admin-settings.component.html b/apps/client/src/app/components/admin-settings/admin-settings.component.html index 41a9992c9..76af96c4e 100644 --- a/apps/client/src/app/components/admin-settings/admin-settings.component.html +++ b/apps/client/src/app/components/admin-settings/admin-settings.component.html @@ -40,9 +40,21 @@ } - +
    - + -} @else if (benchmarks?.length === 0) { +} @else if (benchmarks()?.length === 0) {
    No data available
    diff --git a/libs/ui/src/lib/benchmark/benchmark.component.ts b/libs/ui/src/lib/benchmark/benchmark.component.ts index adef1f41b..5dbc4648b 100644 --- a/libs/ui/src/lib/benchmark/benchmark.component.ts +++ b/libs/ui/src/lib/benchmark/benchmark.component.ts @@ -16,13 +16,15 @@ import { CUSTOM_ELEMENTS_SCHEMA, ChangeDetectionStrategy, Component, - EventEmitter, - Input, - OnChanges, - OnDestroy, - Output, - ViewChild + DestroyRef, + computed, + effect, + inject, + input, + output, + viewChild } from '@angular/core'; +import { takeUntilDestroyed } from '@angular/core/rxjs-interop'; import { MatButtonModule } from '@angular/material/button'; import { MatDialog } from '@angular/material/dialog'; import { MatMenuModule } from '@angular/material/menu'; @@ -34,7 +36,6 @@ import { addIcons } from 'ionicons'; import { ellipsisHorizontal, trashOutline } from 'ionicons/icons'; import { isNumber } from 'lodash'; import { NgxSkeletonLoaderModule } from 'ngx-skeleton-loader'; -import { Subject, takeUntil } from 'rxjs'; import { translate } from '../i18n'; import { GfTrendIndicatorComponent } from '../trend-indicator/trend-indicator.component'; @@ -61,41 +62,58 @@ import { BenchmarkDetailDialogParams } from './benchmark-detail-dialog/interface styleUrls: ['./benchmark.component.scss'], templateUrl: './benchmark.component.html' }) -export class GfBenchmarkComponent implements OnChanges, OnDestroy { - @Input() benchmarks: Benchmark[]; - @Input() deviceType: string; - @Input() hasPermissionToDeleteItem: boolean; - @Input() locale = getLocale(); - @Input() showSymbol = true; - @Input() user: User; - - @Output() itemDeleted = new EventEmitter(); - - @ViewChild(MatSort) sort: MatSort; - - public dataSource = new MatTableDataSource([]); - public displayedColumns = [ - 'name', - 'date', - 'change', - 'marketCondition', - 'actions' - ]; - public isLoading = true; - public isNumber = isNumber; - public resolveMarketCondition = resolveMarketCondition; - public translate = translate; - - private unsubscribeSubject = new Subject(); - - public constructor( - private dialog: MatDialog, - private notificationService: NotificationService, - private route: ActivatedRoute, - private router: Router - ) { +export class GfBenchmarkComponent { + public readonly benchmarks = input.required(); + public readonly deviceType = input.required(); + public readonly hasPermissionToDeleteItem = input(); + public readonly locale = input(getLocale()); + public readonly showSymbol = input(true); + public readonly user = input(); + + public readonly itemDeleted = output(); + + protected readonly sort = viewChild(MatSort); + + protected readonly dataSource = new MatTableDataSource([]); + protected readonly displayedColumns = computed(() => { + return [ + 'name', + ...(this.user()?.settings?.isExperimentalFeatures + ? ['trend50d', 'trend200d'] + : []), + 'date', + 'change', + 'marketCondition', + 'actions' + ]; + }); + protected isLoading = true; + protected readonly isNumber = isNumber; + protected readonly resolveMarketCondition = resolveMarketCondition; + protected readonly translate = translate; + + private readonly destroyRef = inject(DestroyRef); + private readonly dialog = inject(MatDialog); + private readonly notificationService = inject(NotificationService); + private readonly route = inject(ActivatedRoute); + private readonly router = inject(Router); + + public constructor() { + effect(() => { + const benchmarks = this.benchmarks(); + + if (benchmarks) { + this.dataSource.data = benchmarks; + this.dataSource.sortingDataAccessor = getLowercase; + + this.dataSource.sort = this.sort() ?? null; + + this.isLoading = false; + } + }); + this.route.queryParams - .pipe(takeUntil(this.unsubscribeSubject)) + .pipe(takeUntilDestroyed(this.destroyRef)) .subscribe((params) => { if ( params['benchmarkDetailDialog'] && @@ -112,30 +130,7 @@ export class GfBenchmarkComponent implements OnChanges, OnDestroy { addIcons({ ellipsisHorizontal, trashOutline }); } - public ngOnChanges() { - if (this.benchmarks) { - this.dataSource.data = this.benchmarks; - this.dataSource.sortingDataAccessor = getLowercase; - - this.dataSource.sort = this.sort; - - this.isLoading = false; - } - - if (this.user?.settings?.isExperimentalFeatures) { - this.displayedColumns = [ - 'name', - 'trend50d', - 'trend200d', - 'date', - 'change', - 'marketCondition', - 'actions' - ]; - } - } - - public onDeleteItem({ dataSource, symbol }: AssetProfileIdentifier) { + protected onDeleteItem({ dataSource, symbol }: AssetProfileIdentifier) { this.notificationService.confirm({ confirmFn: () => { this.itemDeleted.emit({ dataSource, symbol }); @@ -145,17 +140,15 @@ export class GfBenchmarkComponent implements OnChanges, OnDestroy { }); } - public onOpenBenchmarkDialog({ dataSource, symbol }: AssetProfileIdentifier) { + protected onOpenBenchmarkDialog({ + dataSource, + symbol + }: AssetProfileIdentifier) { this.router.navigate([], { queryParams: { dataSource, symbol, benchmarkDetailDialog: true } }); } - public ngOnDestroy() { - this.unsubscribeSubject.next(); - this.unsubscribeSubject.complete(); - } - private openBenchmarkDetailDialog({ dataSource, symbol @@ -167,17 +160,17 @@ export class GfBenchmarkComponent implements OnChanges, OnDestroy { data: { dataSource, symbol, - colorScheme: this.user?.settings?.colorScheme, - deviceType: this.deviceType, - locale: this.locale + colorScheme: this.user()?.settings?.colorScheme, + deviceType: this.deviceType(), + locale: this.locale() }, - height: this.deviceType === 'mobile' ? '98vh' : undefined, - width: this.deviceType === 'mobile' ? '100vw' : '50rem' + height: this.deviceType() === 'mobile' ? '98vh' : undefined, + width: this.deviceType() === 'mobile' ? '100vw' : '50rem' }); dialogRef .afterClosed() - .pipe(takeUntil(this.unsubscribeSubject)) + .pipe(takeUntilDestroyed(this.destroyRef)) .subscribe(() => { this.router.navigate(['.'], { relativeTo: this.route }); }); From 9310466c7ab957e4e44b818c8e11db1c22c1806b Mon Sep 17 00:00:00 2001 From: Kenrick Tandrian <60643640+KenTandrian@users.noreply.github.com> Date: Sat, 14 Mar 2026 17:11:23 +0700 Subject: [PATCH 138/224] Task/improve type safety of holdings table component (#6556) * Improve type safety --- .../holdings-table.component.html | 4 ++-- .../holdings-table.component.ts | 21 +++++++++---------- 2 files changed, 12 insertions(+), 13 deletions(-) diff --git a/libs/ui/src/lib/holdings-table/holdings-table.component.html b/libs/ui/src/lib/holdings-table/holdings-table.component.html index 250eff578..3bb387ae4 100644 --- a/libs/ui/src/lib/holdings-table/holdings-table.component.html +++ b/libs/ui/src/lib/holdings-table/holdings-table.component.html @@ -193,7 +193,7 @@
    + Name @@ -102,7 +114,12 @@ - + Asset Profiles diff --git a/apps/client/src/app/components/admin-settings/admin-settings.component.ts b/apps/client/src/app/components/admin-settings/admin-settings.component.ts index 219fd2847..b8cd3409d 100644 --- a/apps/client/src/app/components/admin-settings/admin-settings.component.ts +++ b/apps/client/src/app/components/admin-settings/admin-settings.component.ts @@ -23,17 +23,20 @@ import { ChangeDetectorRef, Component, OnDestroy, - OnInit + OnInit, + ViewChild } from '@angular/core'; import { MatButtonModule } from '@angular/material/button'; import { MatCardModule } from '@angular/material/card'; import { MatMenuModule } from '@angular/material/menu'; import { MatProgressBarModule } from '@angular/material/progress-bar'; +import { MatSort, MatSortModule } from '@angular/material/sort'; import { MatTableDataSource, MatTableModule } from '@angular/material/table'; import { RouterModule } from '@angular/router'; import { IonIcon } from '@ionic/angular/standalone'; import { addIcons } from 'ionicons'; import { ellipsisHorizontal, trashOutline } from 'ionicons/icons'; +import { get } from 'lodash'; import { NgxSkeletonLoaderModule } from 'ngx-skeleton-loader'; import { catchError, filter, of, Subject, takeUntil } from 'rxjs'; @@ -52,6 +55,7 @@ import { catchError, filter, of, Subject, takeUntil } from 'rxjs'; MatCardModule, MatMenuModule, MatProgressBarModule, + MatSortModule, MatTableModule, NgxSkeletonLoaderModule, RouterModule @@ -61,6 +65,8 @@ import { catchError, filter, of, Subject, takeUntil } from 'rxjs'; templateUrl: './admin-settings.component.html' }) export class GfAdminSettingsComponent implements OnDestroy, OnInit { + @ViewChild(MatSort) sort: MatSort; + public dataSource = new MatTableDataSource(); public defaultDateFormat: string; public displayedColumns = [ @@ -166,6 +172,8 @@ export class GfAdminSettingsComponent implements OnDestroy, OnInit { }); this.dataSource = new MatTableDataSource(filteredProviders); + this.dataSource.sort = this.sort; + this.dataSource.sortingDataAccessor = get; const ghostfolioApiKey = settings[ PROPERTY_API_KEY_GHOSTFOLIO From 249cf0cdd9ee4000327b9981650a91511497a75a Mon Sep 17 00:00:00 2001 From: Kenrick Tandrian <60643640+KenTandrian@users.noreply.github.com> Date: Sun, 8 Mar 2026 00:02:42 +0700 Subject: [PATCH 102/224] Bugfix/projected total amount in FIRE calculator (#6490) * Fix projected total amount * Update changelog --- CHANGELOG.md | 4 ++++ .../fire-calculator.component.ts | 23 +++++++++++-------- 2 files changed, 18 insertions(+), 9 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9a837052a..c002057ee 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -19,6 +19,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Reused the value component in the tag management of the admin control panel - Upgraded `jsonpath` from version `1.1.1` to `1.2.1` +### Fixed + +- Fixed an issue in the _FIRE_ calculator to correctly calculate the projected total amount + ## 2.247.0 - 2026-03-04 ### Changed diff --git a/libs/ui/src/lib/fire-calculator/fire-calculator.component.ts b/libs/ui/src/lib/fire-calculator/fire-calculator.component.ts index 8b472fc47..7a62564c6 100644 --- a/libs/ui/src/lib/fire-calculator/fire-calculator.component.ts +++ b/libs/ui/src/lib/fire-calculator/fire-calculator.component.ts @@ -16,8 +16,8 @@ import { Input, OnChanges, OnDestroy, - ViewChild, - output + output, + viewChild } from '@angular/core'; import { takeUntilDestroyed } from '@angular/core/rxjs-interop'; import { @@ -55,7 +55,7 @@ import { startOfMonth, sub } from 'date-fns'; -import { isNil, isNumber } from 'lodash'; +import { isNumber } from 'lodash'; import { NgxSkeletonLoaderModule } from 'ngx-skeleton-loader'; import { debounceTime } from 'rxjs'; @@ -90,8 +90,6 @@ export class GfFireCalculatorComponent implements OnChanges, OnDestroy { @Input() retirementDate: Date; @Input() savingsRate = 0; - @ViewChild('chartCanvas') chartCanvas: ElementRef; - public calculatorForm = this.formBuilder.group({ annualInterestRate: new FormControl(null), paymentPerPeriod: new FormControl(null), @@ -99,23 +97,30 @@ export class GfFireCalculatorComponent implements OnChanges, OnDestroy { projectedTotalAmount: new FormControl(null), retirementDate: new FormControl(null) }); + public chart: Chart<'bar'>; public isLoading = true; public minDate = addDays(new Date(), 1); public periodsToRetire = 0; protected readonly annualInterestRateChanged = output(); + protected readonly calculationCompleted = output(); + protected readonly projectedTotalAmountChanged = output(); protected readonly retirementDateChanged = output(); protected readonly savingsRateChanged = output(); private readonly CONTRIBUTION_PERIOD = 12; + private readonly DEFAULT_RETIREMENT_DATE = startOfMonth( addYears(new Date(), 10) ); + private readonly chartCanvas = + viewChild.required>('chartCanvas'); + public constructor( private changeDetectorRef: ChangeDetectorRef, private fireCalculatorService: FireCalculatorService, @@ -272,7 +277,7 @@ export class GfFireCalculatorComponent implements OnChanges, OnDestroy { const chartData = this.getChartData(); - if (this.chartCanvas) { + if (this.chartCanvas()) { if (this.chart) { this.chart.data.labels = chartData.labels; @@ -282,7 +287,7 @@ export class GfFireCalculatorComponent implements OnChanges, OnDestroy { this.chart.update(); } else { - this.chart = new Chart<'bar'>(this.chartCanvas.nativeElement, { + this.chart = new Chart<'bar'>(this.chartCanvas().nativeElement, { data: chartData, options: { plugins: { @@ -303,7 +308,7 @@ export class GfFireCalculatorComponent implements OnChanges, OnDestroy { }).format(totalAmount)}`; }, label: (context) => { - let label = context.dataset.label || ''; + let label = context.dataset.label ?? ''; if (label) { label += ': '; @@ -473,7 +478,7 @@ export class GfFireCalculatorComponent implements OnChanges, OnDestroy { 'projectedTotalAmount' )?.value; - if (!isNil(projectedTotalAmount)) { + if (projectedTotalAmount) { return projectedTotalAmount; } From 4a832f12ca46482d73892bb3684979f26efa7837 Mon Sep 17 00:00:00 2001 From: Thomas Kaul <4159106+dtslvr@users.noreply.github.com> Date: Sat, 7 Mar 2026 18:19:25 +0100 Subject: [PATCH 103/224] Task/deprecate order endpoints in favor of activities endpoints (#6446) * Deprecate order endpoints in favor of activities endpoints * Update changelog --- CHANGELOG.md | 1 + .../activities.controller.ts} | 55 ++++++++------ .../activities.module.ts} | 12 +-- .../activities.service.ts} | 73 ++++++++++--------- apps/api/src/app/admin/admin.module.ts | 4 +- apps/api/src/app/admin/admin.service.ts | 8 +- apps/api/src/app/app.module.ts | 4 +- apps/api/src/app/endpoints/ai/ai.module.ts | 4 +- .../endpoints/benchmarks/benchmarks.module.ts | 4 +- .../app/endpoints/public/public.controller.ts | 6 +- .../src/app/endpoints/public/public.module.ts | 4 +- apps/api/src/app/export/export.module.ts | 4 +- apps/api/src/app/export/export.service.ts | 6 +- apps/api/src/app/import/import.module.ts | 4 +- apps/api/src/app/import/import.service.ts | 10 +-- .../roai/portfolio-calculator-cash.spec.ts | 17 ++--- .../portfolio/current-rate.service.spec.ts | 2 +- .../src/app/portfolio/current-rate.service.ts | 13 ++-- .../src/app/portfolio/portfolio.controller.ts | 6 +- .../api/src/app/portfolio/portfolio.module.ts | 4 +- .../src/app/portfolio/portfolio.service.ts | 21 ++++-- apps/api/src/app/user/user.module.ts | 4 +- apps/api/src/app/user/user.service.ts | 6 +- .../events/asset-profile-changed.listener.ts | 8 +- apps/api/src/events/events.module.ts | 4 +- .../portfolio-snapshot.module.ts | 4 +- .../portfolio-snapshot.processor.ts | 6 +- .../holding-detail-dialog.component.ts | 2 +- .../activities/activities-page.component.ts | 4 +- libs/ui/src/lib/services/data.service.ts | 40 +++++----- 30 files changed, 180 insertions(+), 160 deletions(-) rename apps/api/src/app/{order/order.controller.ts => activities/activities.controller.ts} (87%) rename apps/api/src/app/{order/order.module.ts => activities/activities.module.ts} (86%) rename apps/api/src/app/{order/order.service.ts => activities/activities.service.ts} (93%) diff --git a/CHANGELOG.md b/CHANGELOG.md index c002057ee..1279ef62f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -17,6 +17,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Included asset profile data in the holdings of the public page - Reused the value component in the platform management of the admin control panel - Reused the value component in the tag management of the admin control panel +- Deprecated the `api/v1/order` endpoints in favor of the `api/v1/activities` endpoints - Upgraded `jsonpath` from version `1.1.1` to `1.2.1` ### Fixed diff --git a/apps/api/src/app/order/order.controller.ts b/apps/api/src/app/activities/activities.controller.ts similarity index 87% rename from apps/api/src/app/order/order.controller.ts rename to apps/api/src/app/activities/activities.controller.ts index c7021809e..da7aed21d 100644 --- a/apps/api/src/app/order/order.controller.ts +++ b/apps/api/src/app/activities/activities.controller.ts @@ -37,20 +37,24 @@ import { } from '@nestjs/common'; import { REQUEST } from '@nestjs/core'; import { AuthGuard } from '@nestjs/passport'; -import { Order as OrderModel, Prisma } from '@prisma/client'; +import { Order, Prisma } from '@prisma/client'; import { parseISO } from 'date-fns'; import { StatusCodes, getReasonPhrase } from 'http-status-codes'; -import { OrderService } from './order.service'; +import { ActivitiesService } from './activities.service'; -@Controller('order') -export class OrderController { +@Controller([ + 'activities', + /** @deprecated */ + 'order' +]) +export class ActivitiesController { public constructor( + private readonly activitiesService: ActivitiesService, private readonly apiService: ApiService, private readonly dataProviderService: DataProviderService, private readonly dataGatheringService: DataGatheringService, private readonly impersonationService: ImpersonationService, - private readonly orderService: OrderService, @Inject(REQUEST) private readonly request: RequestWithUser ) {} @@ -58,7 +62,7 @@ export class OrderController { @HasPermission(permissions.deleteOrder) @UseGuards(AuthGuard('jwt'), HasPermissionGuard) @UseInterceptors(TransformDataSourceInRequestInterceptor) - public async deleteOrders( + public async deleteActivities( @Query('accounts') filterByAccounts?: string, @Query('assetClasses') filterByAssetClasses?: string, @Query('dataSource') filterByDataSource?: string, @@ -73,7 +77,7 @@ export class OrderController { filterByTags }); - return this.orderService.deleteOrders({ + return this.activitiesService.deleteActivities({ filters, userId: this.request.user.id }); @@ -82,20 +86,20 @@ export class OrderController { @Delete(':id') @HasPermission(permissions.deleteOrder) @UseGuards(AuthGuard('jwt'), HasPermissionGuard) - public async deleteOrder(@Param('id') id: string): Promise { - const order = await this.orderService.order({ + public async deleteActivity(@Param('id') id: string): Promise { + const activity = await this.activitiesService.order({ id, userId: this.request.user.id }); - if (!order) { + if (!activity) { throw new HttpException( getReasonPhrase(StatusCodes.FORBIDDEN), StatusCodes.FORBIDDEN ); } - return this.orderService.deleteOrder({ + return this.activitiesService.deleteActivity({ id }); } @@ -105,7 +109,7 @@ export class OrderController { @UseInterceptors(RedactValuesInResponseInterceptor) @UseInterceptors(TransformDataSourceInRequestInterceptor) @UseInterceptors(TransformDataSourceInResponseInterceptor) - public async getAllOrders( + public async getAllActivities( @Headers(HEADER_KEY_IMPERSONATION.toLowerCase()) impersonationId: string, @Query('accounts') filterByAccounts?: string, @Query('assetClasses') filterByAssetClasses?: string, @@ -137,7 +141,7 @@ export class OrderController { await this.impersonationService.validateImpersonationId(impersonationId); const userCurrency = this.request.user.settings.settings.baseCurrency; - const { activities, count } = await this.orderService.getOrders({ + const { activities, count } = await this.activitiesService.getActivities({ endDate, filters, sortColumn, @@ -158,7 +162,7 @@ export class OrderController { @UseGuards(AuthGuard('jwt'), HasPermissionGuard) @UseInterceptors(RedactValuesInResponseInterceptor) @UseInterceptors(TransformDataSourceInResponseInterceptor) - public async getOrderById( + public async getActivityById( @Headers(HEADER_KEY_IMPERSONATION.toLowerCase()) impersonationId: string, @Param('id') id: string ): Promise { @@ -166,7 +170,7 @@ export class OrderController { await this.impersonationService.validateImpersonationId(impersonationId); const userCurrency = this.request.user.settings.settings.baseCurrency; - const { activities } = await this.orderService.getOrders({ + const { activities } = await this.activitiesService.getActivities({ userCurrency, includeDrafts: true, userId: impersonationUserId || this.request.user.id, @@ -191,7 +195,7 @@ export class OrderController { @Post() @UseGuards(AuthGuard('jwt'), HasPermissionGuard) @UseInterceptors(TransformDataSourceInRequestInterceptor) - public async createOrder(@Body() data: CreateOrderDto): Promise { + public async createActivity(@Body() data: CreateOrderDto): Promise { try { await this.dataProviderService.validateActivities({ activitiesDto: [ @@ -227,7 +231,7 @@ export class OrderController { delete data.dataSource; - const order = await this.orderService.createOrder({ + const activity = await this.activitiesService.createActivity({ ...data, date: parseISO(data.date), SymbolProfile: { @@ -252,14 +256,14 @@ export class OrderController { userId: this.request.user.id }); - if (dataSource && !order.isDraft) { + if (dataSource && !activity.isDraft) { // Gather symbol data in the background, if data source is set // (not MANUAL) and not draft this.dataGatheringService.gatherSymbols({ dataGatheringItems: [ { dataSource, - date: order.date, + date: activity.date, symbol: data.symbol } ], @@ -267,19 +271,22 @@ export class OrderController { }); } - return order; + return activity; } @HasPermission(permissions.updateOrder) @Put(':id') @UseGuards(AuthGuard('jwt'), HasPermissionGuard) @UseInterceptors(TransformDataSourceInRequestInterceptor) - public async update(@Param('id') id: string, @Body() data: UpdateOrderDto) { - const originalOrder = await this.orderService.order({ + public async updateActivity( + @Param('id') id: string, + @Body() data: UpdateOrderDto + ) { + const originalActivity = await this.activitiesService.order({ id }); - if (!originalOrder || originalOrder.userId !== this.request.user.id) { + if (!originalActivity || originalActivity.userId !== this.request.user.id) { throw new HttpException( getReasonPhrase(StatusCodes.FORBIDDEN), StatusCodes.FORBIDDEN @@ -302,7 +309,7 @@ export class OrderController { delete data.dataSource; - return this.orderService.updateOrder({ + return this.activitiesService.updateActivity({ data: { ...data, date, diff --git a/apps/api/src/app/order/order.module.ts b/apps/api/src/app/activities/activities.module.ts similarity index 86% rename from apps/api/src/app/order/order.module.ts rename to apps/api/src/app/activities/activities.module.ts index 9bc837aa6..7476ad66a 100644 --- a/apps/api/src/app/order/order.module.ts +++ b/apps/api/src/app/activities/activities.module.ts @@ -15,12 +15,12 @@ import { SymbolProfileModule } from '@ghostfolio/api/services/symbol-profile/sym import { Module } from '@nestjs/common'; -import { OrderController } from './order.controller'; -import { OrderService } from './order.service'; +import { ActivitiesController } from './activities.controller'; +import { ActivitiesService } from './activities.service'; @Module({ - controllers: [OrderController], - exports: [OrderService], + controllers: [ActivitiesController], + exports: [ActivitiesService], imports: [ ApiModule, CacheModule, @@ -35,6 +35,6 @@ import { OrderService } from './order.service'; TransformDataSourceInRequestModule, TransformDataSourceInResponseModule ], - providers: [AccountBalanceService, AccountService, OrderService] + providers: [AccountBalanceService, AccountService, ActivitiesService] }) -export class OrderModule {} +export class ActivitiesModule {} diff --git a/apps/api/src/app/order/order.service.ts b/apps/api/src/app/activities/activities.service.ts similarity index 93% rename from apps/api/src/app/order/order.service.ts rename to apps/api/src/app/activities/activities.service.ts index 9a4f1e46b..89b9468f8 100644 --- a/apps/api/src/app/order/order.service.ts +++ b/apps/api/src/app/activities/activities.service.ts @@ -44,7 +44,7 @@ import { groupBy, uniqBy } from 'lodash'; import { randomUUID } from 'node:crypto'; @Injectable() -export class OrderService { +export class ActivitiesService { public constructor( private readonly accountBalanceService: AccountBalanceService, private readonly accountService: AccountService, @@ -62,7 +62,7 @@ export class OrderService { tags, userId }: { tags: Tag[]; userId: string } & AssetProfileIdentifier) { - const orders = await this.prismaService.order.findMany({ + const activities = await this.prismaService.order.findMany({ where: { userId, SymbolProfile: { @@ -73,7 +73,7 @@ export class OrderService { }); await Promise.all( - orders.map(({ id }) => + activities.map(({ id }) => this.prismaService.order.update({ data: { tags: { @@ -96,7 +96,7 @@ export class OrderService { ); } - public async createOrder( + public async createActivity( data: Prisma.OrderCreateInput & { accountId?: string; assetClass?: AssetClass; @@ -201,7 +201,7 @@ export class OrderService { ? false : isAfter(data.date as Date, endOfToday()); - const order = await this.prismaService.order.create({ + const activity = await this.prismaService.order.create({ data: { ...orderData, account, @@ -235,56 +235,56 @@ export class OrderService { this.eventEmitter.emit( AssetProfileChangedEvent.getName(), new AssetProfileChangedEvent({ - currency: order.SymbolProfile.currency, - dataSource: order.SymbolProfile.dataSource, - symbol: order.SymbolProfile.symbol + currency: activity.SymbolProfile.currency, + dataSource: activity.SymbolProfile.dataSource, + symbol: activity.SymbolProfile.symbol }) ); this.eventEmitter.emit( PortfolioChangedEvent.getName(), new PortfolioChangedEvent({ - userId: order.userId + userId: activity.userId }) ); - return order; + return activity; } - public async deleteOrder( + public async deleteActivity( where: Prisma.OrderWhereUniqueInput ): Promise { - const order = await this.prismaService.order.delete({ + const activity = await this.prismaService.order.delete({ where }); const [symbolProfile] = await this.symbolProfileService.getSymbolProfilesByIds([ - order.symbolProfileId + activity.symbolProfileId ]); if (symbolProfile.activitiesCount === 0) { - await this.symbolProfileService.deleteById(order.symbolProfileId); + await this.symbolProfileService.deleteById(activity.symbolProfileId); } this.eventEmitter.emit( PortfolioChangedEvent.getName(), new PortfolioChangedEvent({ - userId: order.userId + userId: activity.userId }) ); - return order; + return activity; } - public async deleteOrders({ + public async deleteActivities({ filters, userId }: { filters?: Filter[]; userId: string; }): Promise { - const { activities } = await this.getOrders({ + const { activities } = await this.getActivities({ filters, userId, includeDrafts: true, @@ -324,7 +324,7 @@ export class OrderService { } /** - * Generates synthetic orders for cash holdings based on account balance history. + * Generates synthetic activities for cash holdings based on account balance history. * Treat currencies as assets with a fixed unit price of 1.0 (in their own currency) to allow * performance tracking based on exchange rate fluctuations. * @@ -334,7 +334,7 @@ export class OrderService { * @param userId - The ID of the user. * @returns A response containing the list of synthetic cash activities. */ - public async getCashOrders({ + public async getCashActivities({ cashDetails, filters = [], userCurrency, @@ -448,7 +448,10 @@ export class OrderService { }; } - public async getLatestOrder({ dataSource, symbol }: AssetProfileIdentifier) { + public async getLatestActivity({ + dataSource, + symbol + }: AssetProfileIdentifier) { return this.prismaService.order.findFirst({ orderBy: { date: 'desc' @@ -459,7 +462,7 @@ export class OrderService { }); } - public async getOrders({ + public async getActivities({ endDate, filters, includeDrafts = false, @@ -742,17 +745,17 @@ export class OrderService { } /** - * Retrieves all orders required for the portfolio calculator, including both standard asset orders - * and optional synthetic orders representing cash activities. + * Retrieves all activities required for the portfolio calculator, including both standard asset activities + * and optional synthetic activities representing cash activities. */ @LogPerformance - public async getOrdersForPortfolioCalculator({ + public async getActivitiesForPortfolioCalculator({ filters, userCurrency, userId, withCash = false }: { - /** Optional filters to apply to the orders. */ + /** Optional filters to apply to the activities. */ filters?: Filter[]; /** The base currency of the user. */ userCurrency: string; @@ -761,7 +764,7 @@ export class OrderService { /** Whether to include cash activities in the result. */ withCash?: boolean; }) { - const orders = await this.getOrders({ + const activities = await this.getActivities({ filters, userCurrency, userId, @@ -775,18 +778,18 @@ export class OrderService { currency: userCurrency }); - const cashOrders = await this.getCashOrders({ + const cashActivities = await this.getCashActivities({ cashDetails, filters, userCurrency, userId }); - orders.activities.push(...cashOrders.activities); - orders.count += cashOrders.count; + activities.activities.push(...cashActivities.activities); + activities.count += cashActivities.count; } - return orders; + return activities; } public async getStatisticsByCurrency( @@ -817,7 +820,7 @@ export class OrderService { }); } - public async updateOrder({ + public async updateActivity({ data, where }: { @@ -882,7 +885,7 @@ export class OrderService { data: { tags: { set: [] } } }); - const order = await this.prismaService.order.update({ + const activity = await this.prismaService.order.update({ where, data: { ...data, @@ -896,11 +899,11 @@ export class OrderService { this.eventEmitter.emit( PortfolioChangedEvent.getName(), new PortfolioChangedEvent({ - userId: order.userId + userId: activity.userId }) ); - return order; + return activity; } private async orders(params: { diff --git a/apps/api/src/app/admin/admin.module.ts b/apps/api/src/app/admin/admin.module.ts index 598b68f17..960a36629 100644 --- a/apps/api/src/app/admin/admin.module.ts +++ b/apps/api/src/app/admin/admin.module.ts @@ -1,4 +1,4 @@ -import { OrderModule } from '@ghostfolio/api/app/order/order.module'; +import { ActivitiesModule } from '@ghostfolio/api/app/activities/activities.module'; import { TransformDataSourceInRequestModule } from '@ghostfolio/api/interceptors/transform-data-source-in-request/transform-data-source-in-request.module'; import { ApiModule } from '@ghostfolio/api/services/api/api.module'; import { BenchmarkModule } from '@ghostfolio/api/services/benchmark/benchmark.module'; @@ -20,6 +20,7 @@ import { QueueModule } from './queue/queue.module'; @Module({ imports: [ + ActivitiesModule, ApiModule, BenchmarkModule, ConfigurationModule, @@ -28,7 +29,6 @@ import { QueueModule } from './queue/queue.module'; DemoModule, ExchangeRateDataModule, MarketDataModule, - OrderModule, PrismaModule, PropertyModule, QueueModule, diff --git a/apps/api/src/app/admin/admin.service.ts b/apps/api/src/app/admin/admin.service.ts index 1f8745cd1..d2bf6e411 100644 --- a/apps/api/src/app/admin/admin.service.ts +++ b/apps/api/src/app/admin/admin.service.ts @@ -1,4 +1,4 @@ -import { OrderService } from '@ghostfolio/api/app/order/order.service'; +import { ActivitiesService } from '@ghostfolio/api/app/activities/activities.service'; import { environment } from '@ghostfolio/api/environments/environment'; import { BenchmarkService } from '@ghostfolio/api/services/benchmark/benchmark.service'; import { ConfigurationService } from '@ghostfolio/api/services/configuration/configuration.service'; @@ -55,12 +55,12 @@ import { groupBy } from 'lodash'; @Injectable() export class AdminService { public constructor( + private readonly activitiesService: ActivitiesService, private readonly benchmarkService: BenchmarkService, private readonly configurationService: ConfigurationService, private readonly dataProviderService: DataProviderService, private readonly exchangeRateDataService: ExchangeRateDataService, private readonly marketDataService: MarketDataService, - private readonly orderService: OrderService, private readonly prismaService: PrismaService, private readonly propertyService: PropertyService, private readonly symbolProfileService: SymbolProfileService @@ -475,7 +475,7 @@ export class AdminService { if (isCurrencyAssetProfile) { currency = getCurrencyFromSymbol(symbol); ({ activitiesCount, dateOfFirstActivity } = - await this.orderService.getStatisticsByCurrency(currency)); + await this.activitiesService.getStatisticsByCurrency(currency)); } const [[assetProfile], marketData] = await Promise.all([ @@ -798,7 +798,7 @@ export class AdminService { if (isCurrency(getCurrencyFromSymbol(symbol))) { currency = getCurrencyFromSymbol(symbol); ({ activitiesCount, dateOfFirstActivity } = - await this.orderService.getStatisticsByCurrency(currency)); + await this.activitiesService.getStatisticsByCurrency(currency)); } const lastMarketPrice = lastMarketPriceMap.get( diff --git a/apps/api/src/app/app.module.ts b/apps/api/src/app/app.module.ts index 89f52e1ea..4b790d0db 100644 --- a/apps/api/src/app/app.module.ts +++ b/apps/api/src/app/app.module.ts @@ -25,6 +25,7 @@ import { join } from 'node:path'; import { AccessModule } from './access/access.module'; import { AccountModule } from './account/account.module'; +import { ActivitiesModule } from './activities/activities.module'; import { AdminModule } from './admin/admin.module'; import { AppController } from './app.controller'; import { AssetModule } from './asset/asset.module'; @@ -48,7 +49,6 @@ import { HealthModule } from './health/health.module'; import { ImportModule } from './import/import.module'; import { InfoModule } from './info/info.module'; import { LogoModule } from './logo/logo.module'; -import { OrderModule } from './order/order.module'; import { PlatformModule } from './platform/platform.module'; import { PortfolioModule } from './portfolio/portfolio.module'; import { RedisCacheModule } from './redis-cache/redis-cache.module'; @@ -62,6 +62,7 @@ import { UserModule } from './user/user.module'; AdminModule, AccessModule, AccountModule, + ActivitiesModule, AiModule, ApiKeysModule, AssetModule, @@ -94,7 +95,6 @@ import { UserModule } from './user/user.module'; InfoModule, LogoModule, MarketDataModule, - OrderModule, PlatformModule, PlatformsModule, PortfolioModule, diff --git a/apps/api/src/app/endpoints/ai/ai.module.ts b/apps/api/src/app/endpoints/ai/ai.module.ts index 8a441fde7..eab4ecf8b 100644 --- a/apps/api/src/app/endpoints/ai/ai.module.ts +++ b/apps/api/src/app/endpoints/ai/ai.module.ts @@ -1,6 +1,6 @@ import { AccountBalanceService } from '@ghostfolio/api/app/account-balance/account-balance.service'; import { AccountService } from '@ghostfolio/api/app/account/account.service'; -import { OrderModule } from '@ghostfolio/api/app/order/order.module'; +import { ActivitiesModule } from '@ghostfolio/api/app/activities/activities.module'; import { PortfolioCalculatorFactory } from '@ghostfolio/api/app/portfolio/calculator/portfolio-calculator.factory'; import { CurrentRateService } from '@ghostfolio/api/app/portfolio/current-rate.service'; import { PortfolioService } from '@ghostfolio/api/app/portfolio/portfolio.service'; @@ -29,6 +29,7 @@ import { AiService } from './ai.service'; @Module({ controllers: [AiController], imports: [ + ActivitiesModule, ApiModule, BenchmarkModule, ConfigurationModule, @@ -37,7 +38,6 @@ import { AiService } from './ai.service'; I18nModule, ImpersonationModule, MarketDataModule, - OrderModule, PortfolioSnapshotQueueModule, PrismaModule, PropertyModule, diff --git a/apps/api/src/app/endpoints/benchmarks/benchmarks.module.ts b/apps/api/src/app/endpoints/benchmarks/benchmarks.module.ts index 8bdf79035..2bcd6177d 100644 --- a/apps/api/src/app/endpoints/benchmarks/benchmarks.module.ts +++ b/apps/api/src/app/endpoints/benchmarks/benchmarks.module.ts @@ -1,6 +1,6 @@ import { AccountBalanceService } from '@ghostfolio/api/app/account-balance/account-balance.service'; import { AccountService } from '@ghostfolio/api/app/account/account.service'; -import { OrderModule } from '@ghostfolio/api/app/order/order.module'; +import { ActivitiesModule } from '@ghostfolio/api/app/activities/activities.module'; import { PortfolioCalculatorFactory } from '@ghostfolio/api/app/portfolio/calculator/portfolio-calculator.factory'; import { CurrentRateService } from '@ghostfolio/api/app/portfolio/current-rate.service'; import { PortfolioService } from '@ghostfolio/api/app/portfolio/portfolio.service'; @@ -32,6 +32,7 @@ import { BenchmarksService } from './benchmarks.service'; @Module({ controllers: [BenchmarksController], imports: [ + ActivitiesModule, ApiModule, ConfigurationModule, DataProviderModule, @@ -39,7 +40,6 @@ import { BenchmarksService } from './benchmarks.service'; I18nModule, ImpersonationModule, MarketDataModule, - OrderModule, PortfolioSnapshotQueueModule, PrismaModule, PropertyModule, diff --git a/apps/api/src/app/endpoints/public/public.controller.ts b/apps/api/src/app/endpoints/public/public.controller.ts index a1b2b7864..b97640cab 100644 --- a/apps/api/src/app/endpoints/public/public.controller.ts +++ b/apps/api/src/app/endpoints/public/public.controller.ts @@ -1,5 +1,5 @@ import { AccessService } from '@ghostfolio/api/app/access/access.service'; -import { OrderService } from '@ghostfolio/api/app/order/order.service'; +import { ActivitiesService } from '@ghostfolio/api/app/activities/activities.service'; import { PortfolioService } from '@ghostfolio/api/app/portfolio/portfolio.service'; import { UserService } from '@ghostfolio/api/app/user/user.service'; import { RedactValuesInResponseInterceptor } from '@ghostfolio/api/interceptors/redact-values-in-response/redact-values-in-response.interceptor'; @@ -28,9 +28,9 @@ import { StatusCodes, getReasonPhrase } from 'http-status-codes'; export class PublicController { public constructor( private readonly accessService: AccessService, + private readonly activitiesService: ActivitiesService, private readonly configurationService: ConfigurationService, private readonly exchangeRateDataService: ExchangeRateDataService, - private readonly orderService: OrderService, private readonly portfolioService: PortfolioService, @Inject(REQUEST) private readonly request: RequestWithUser, private readonly userService: UserService @@ -81,7 +81,7 @@ export class PublicController { }) ]); - const { activities } = await this.orderService.getOrders({ + const { activities } = await this.activitiesService.getActivities({ sortColumn: 'date', sortDirection: 'desc', take: 10, diff --git a/apps/api/src/app/endpoints/public/public.module.ts b/apps/api/src/app/endpoints/public/public.module.ts index 19e281dde..e8395228f 100644 --- a/apps/api/src/app/endpoints/public/public.module.ts +++ b/apps/api/src/app/endpoints/public/public.module.ts @@ -1,7 +1,7 @@ import { AccessModule } from '@ghostfolio/api/app/access/access.module'; import { AccountBalanceService } from '@ghostfolio/api/app/account-balance/account-balance.service'; import { AccountService } from '@ghostfolio/api/app/account/account.service'; -import { OrderModule } from '@ghostfolio/api/app/order/order.module'; +import { ActivitiesModule } from '@ghostfolio/api/app/activities/activities.module'; import { PortfolioCalculatorFactory } from '@ghostfolio/api/app/portfolio/calculator/portfolio-calculator.factory'; import { CurrentRateService } from '@ghostfolio/api/app/portfolio/current-rate.service'; import { PortfolioService } from '@ghostfolio/api/app/portfolio/portfolio.service'; @@ -27,13 +27,13 @@ import { PublicController } from './public.controller'; controllers: [PublicController], imports: [ AccessModule, + ActivitiesModule, BenchmarkModule, DataProviderModule, ExchangeRateDataModule, I18nModule, ImpersonationModule, MarketDataModule, - OrderModule, PortfolioSnapshotQueueModule, PrismaModule, RedisCacheModule, diff --git a/apps/api/src/app/export/export.module.ts b/apps/api/src/app/export/export.module.ts index 4f40cc417..6158fe043 100644 --- a/apps/api/src/app/export/export.module.ts +++ b/apps/api/src/app/export/export.module.ts @@ -1,5 +1,5 @@ import { AccountModule } from '@ghostfolio/api/app/account/account.module'; -import { OrderModule } from '@ghostfolio/api/app/order/order.module'; +import { ActivitiesModule } from '@ghostfolio/api/app/activities/activities.module'; import { TransformDataSourceInRequestModule } from '@ghostfolio/api/interceptors/transform-data-source-in-request/transform-data-source-in-request.module'; import { ApiModule } from '@ghostfolio/api/services/api/api.module'; import { MarketDataModule } from '@ghostfolio/api/services/market-data/market-data.module'; @@ -14,9 +14,9 @@ import { ExportService } from './export.service'; controllers: [ExportController], imports: [ AccountModule, + ActivitiesModule, ApiModule, MarketDataModule, - OrderModule, TagModule, TransformDataSourceInRequestModule ], diff --git a/apps/api/src/app/export/export.service.ts b/apps/api/src/app/export/export.service.ts index 55f8d7dc9..4f2fb3309 100644 --- a/apps/api/src/app/export/export.service.ts +++ b/apps/api/src/app/export/export.service.ts @@ -1,5 +1,5 @@ import { AccountService } from '@ghostfolio/api/app/account/account.service'; -import { OrderService } from '@ghostfolio/api/app/order/order.service'; +import { ActivitiesService } from '@ghostfolio/api/app/activities/activities.service'; import { environment } from '@ghostfolio/api/environments/environment'; import { MarketDataService } from '@ghostfolio/api/services/market-data/market-data.service'; import { TagService } from '@ghostfolio/api/services/tag/tag.service'; @@ -17,8 +17,8 @@ import { groupBy, uniqBy } from 'lodash'; export class ExportService { public constructor( private readonly accountService: AccountService, + private readonly activitiesService: ActivitiesService, private readonly marketDataService: MarketDataService, - private readonly orderService: OrderService, private readonly tagService: TagService ) {} @@ -38,7 +38,7 @@ export class ExportService { }); const platformsMap: { [platformId: string]: Platform } = {}; - let { activities } = await this.orderService.getOrders({ + let { activities } = await this.activitiesService.getActivities({ filters, userId, includeDrafts: true, diff --git a/apps/api/src/app/import/import.module.ts b/apps/api/src/app/import/import.module.ts index a4a13f941..ca9b5667b 100644 --- a/apps/api/src/app/import/import.module.ts +++ b/apps/api/src/app/import/import.module.ts @@ -1,6 +1,6 @@ import { AccountModule } from '@ghostfolio/api/app/account/account.module'; +import { ActivitiesModule } from '@ghostfolio/api/app/activities/activities.module'; import { CacheModule } from '@ghostfolio/api/app/cache/cache.module'; -import { OrderModule } from '@ghostfolio/api/app/order/order.module'; import { PlatformModule } from '@ghostfolio/api/app/platform/platform.module'; import { PortfolioModule } from '@ghostfolio/api/app/portfolio/portfolio.module'; import { RedisCacheModule } from '@ghostfolio/api/app/redis-cache/redis-cache.module'; @@ -25,6 +25,7 @@ import { ImportService } from './import.service'; controllers: [ImportController], imports: [ AccountModule, + ActivitiesModule, ApiModule, CacheModule, ConfigurationModule, @@ -32,7 +33,6 @@ import { ImportService } from './import.service'; DataProviderModule, ExchangeRateDataModule, MarketDataModule, - OrderModule, PlatformModule, PortfolioModule, PrismaModule, diff --git a/apps/api/src/app/import/import.service.ts b/apps/api/src/app/import/import.service.ts index 497b8a7e9..b82f763a0 100644 --- a/apps/api/src/app/import/import.service.ts +++ b/apps/api/src/app/import/import.service.ts @@ -1,5 +1,5 @@ import { AccountService } from '@ghostfolio/api/app/account/account.service'; -import { OrderService } from '@ghostfolio/api/app/order/order.service'; +import { ActivitiesService } from '@ghostfolio/api/app/activities/activities.service'; import { PlatformService } from '@ghostfolio/api/app/platform/platform.service'; import { PortfolioService } from '@ghostfolio/api/app/portfolio/portfolio.service'; import { ApiService } from '@ghostfolio/api/services/api/api.service'; @@ -44,12 +44,12 @@ import { ImportDataDto } from './import-data.dto'; export class ImportService { public constructor( private readonly accountService: AccountService, + private readonly activitiesService: ActivitiesService, private readonly apiService: ApiService, private readonly dataGatheringService: DataGatheringService, private readonly dataProviderService: DataProviderService, private readonly exchangeRateDataService: ExchangeRateDataService, private readonly marketDataService: MarketDataService, - private readonly orderService: OrderService, private readonly platformService: PlatformService, private readonly portfolioService: PortfolioService, private readonly symbolProfileService: SymbolProfileService, @@ -91,7 +91,7 @@ export class ImportService { userId, withExcludedAccounts: true }), - this.orderService.getOrders({ + this.activitiesService.getActivities({ filters, userCurrency, userId, @@ -548,7 +548,7 @@ export class ImportService { continue; } - order = await this.orderService.createOrder({ + order = await this.activitiesService.createActivity({ comment, currency, date, @@ -645,7 +645,7 @@ export class ImportService { userId: string; }): Promise[]> { const { activities: existingActivities } = - await this.orderService.getOrders({ + await this.activitiesService.getActivities({ userCurrency, userId, includeDrafts: true, diff --git a/apps/api/src/app/portfolio/calculator/roai/portfolio-calculator-cash.spec.ts b/apps/api/src/app/portfolio/calculator/roai/portfolio-calculator-cash.spec.ts index a53ebcf05..217a67c49 100644 --- a/apps/api/src/app/portfolio/calculator/roai/portfolio-calculator-cash.spec.ts +++ b/apps/api/src/app/portfolio/calculator/roai/portfolio-calculator-cash.spec.ts @@ -1,6 +1,6 @@ import { AccountBalanceService } from '@ghostfolio/api/app/account-balance/account-balance.service'; import { AccountService } from '@ghostfolio/api/app/account/account.service'; -import { OrderService } from '@ghostfolio/api/app/order/order.service'; +import { ActivitiesService } from '@ghostfolio/api/app/activities/activities.service'; import { userDummyData } from '@ghostfolio/api/app/portfolio/calculator/portfolio-calculator-test-utils'; import { PortfolioCalculatorFactory } from '@ghostfolio/api/app/portfolio/calculator/portfolio-calculator.factory'; import { CurrentRateService } from '@ghostfolio/api/app/portfolio/current-rate.service'; @@ -62,11 +62,11 @@ jest.mock('@ghostfolio/api/app/redis-cache/redis-cache.service', () => { describe('PortfolioCalculator', () => { let accountBalanceService: AccountBalanceService; let accountService: AccountService; + let activitiesService: ActivitiesService; let configurationService: ConfigurationService; let currentRateService: CurrentRateService; let dataProviderService: DataProviderService; let exchangeRateDataService: ExchangeRateDataService; - let orderService: OrderService; let portfolioCalculatorFactory: PortfolioCalculatorFactory; let portfolioSnapshotService: PortfolioSnapshotService; let redisCacheService: RedisCacheService; @@ -106,13 +106,13 @@ describe('PortfolioCalculator', () => { ); currentRateService = new CurrentRateService( - dataProviderService, null, + dataProviderService, null, null ); - orderService = new OrderService( + activitiesService = new ActivitiesService( accountBalanceService, accountService, null, @@ -183,18 +183,17 @@ describe('PortfolioCalculator', () => { .spyOn(dataProviderService, 'getDataSourceForExchangeRates') .mockReturnValue(DataSource.YAHOO); - jest.spyOn(orderService, 'getOrders').mockResolvedValue({ + jest.spyOn(activitiesService, 'getActivities').mockResolvedValue({ activities: [], count: 0 }); - const { activities } = await orderService.getOrdersForPortfolioCalculator( - { + const { activities } = + await activitiesService.getActivitiesForPortfolioCalculator({ userCurrency: 'CHF', userId: userDummyData.id, withCash: true - } - ); + }); jest.spyOn(currentRateService, 'getValues').mockResolvedValue({ dataProviderInfos: [], diff --git a/apps/api/src/app/portfolio/current-rate.service.spec.ts b/apps/api/src/app/portfolio/current-rate.service.spec.ts index d8b7482e7..5f2358679 100644 --- a/apps/api/src/app/portfolio/current-rate.service.spec.ts +++ b/apps/api/src/app/portfolio/current-rate.service.spec.ts @@ -114,9 +114,9 @@ describe('CurrentRateService', () => { marketDataService = new MarketDataService(null); currentRateService = new CurrentRateService( + null, dataProviderService, marketDataService, - null, null ); }); diff --git a/apps/api/src/app/portfolio/current-rate.service.ts b/apps/api/src/app/portfolio/current-rate.service.ts index 5d39a54bb..b454b01cd 100644 --- a/apps/api/src/app/portfolio/current-rate.service.ts +++ b/apps/api/src/app/portfolio/current-rate.service.ts @@ -1,4 +1,4 @@ -import { OrderService } from '@ghostfolio/api/app/order/order.service'; +import { ActivitiesService } from '@ghostfolio/api/app/activities/activities.service'; import { LogPerformance } from '@ghostfolio/api/interceptors/performance-logging/performance-logging.interceptor'; import { DataProviderService } from '@ghostfolio/api/services/data-provider/data-provider.service'; import { MarketDataService } from '@ghostfolio/api/services/market-data/market-data.service'; @@ -24,9 +24,9 @@ export class CurrentRateService { private static readonly MARKET_DATA_PAGE_SIZE = 50000; public constructor( + private readonly activitiesService: ActivitiesService, private readonly dataProviderService: DataProviderService, private readonly marketDataService: MarketDataService, - private readonly orderService: OrderService, @Inject(REQUEST) private readonly request: RequestWithUser ) {} @@ -129,10 +129,11 @@ export class CurrentRateService { if (!value) { // Fallback to unit price of latest activity - const latestActivity = await this.orderService.getLatestOrder({ - dataSource, - symbol - }); + const latestActivity = + await this.activitiesService.getLatestActivity({ + dataSource, + symbol + }); value = { dataSource, diff --git a/apps/api/src/app/portfolio/portfolio.controller.ts b/apps/api/src/app/portfolio/portfolio.controller.ts index 67b5229c1..80d7f9acc 100644 --- a/apps/api/src/app/portfolio/portfolio.controller.ts +++ b/apps/api/src/app/portfolio/portfolio.controller.ts @@ -1,4 +1,4 @@ -import { OrderService } from '@ghostfolio/api/app/order/order.service'; +import { ActivitiesService } from '@ghostfolio/api/app/activities/activities.service'; import { HasPermission } from '@ghostfolio/api/decorators/has-permission.decorator'; import { HasPermissionGuard } from '@ghostfolio/api/guards/has-permission.guard'; import { @@ -63,10 +63,10 @@ import { UpdateHoldingTagsDto } from './update-holding-tags.dto'; @Controller('portfolio') export class PortfolioController { public constructor( + private readonly activitiesService: ActivitiesService, private readonly apiService: ApiService, private readonly configurationService: ConfigurationService, private readonly impersonationService: ImpersonationService, - private readonly orderService: OrderService, private readonly portfolioService: PortfolioService, @Inject(REQUEST) private readonly request: RequestWithUser ) {} @@ -322,7 +322,7 @@ export class PortfolioController { const { endDate, startDate } = getIntervalFromDateRange(dateRange); - const { activities } = await this.orderService.getOrders({ + const { activities } = await this.activitiesService.getActivities({ endDate, filters, startDate, diff --git a/apps/api/src/app/portfolio/portfolio.module.ts b/apps/api/src/app/portfolio/portfolio.module.ts index 6dd5811a3..65a9b71aa 100644 --- a/apps/api/src/app/portfolio/portfolio.module.ts +++ b/apps/api/src/app/portfolio/portfolio.module.ts @@ -1,7 +1,7 @@ import { AccessModule } from '@ghostfolio/api/app/access/access.module'; import { AccountBalanceService } from '@ghostfolio/api/app/account-balance/account-balance.service'; import { AccountService } from '@ghostfolio/api/app/account/account.service'; -import { OrderModule } from '@ghostfolio/api/app/order/order.module'; +import { ActivitiesModule } from '@ghostfolio/api/app/activities/activities.module'; import { RedisCacheModule } from '@ghostfolio/api/app/redis-cache/redis-cache.module'; import { UserModule } from '@ghostfolio/api/app/user/user.module'; import { PerformanceLoggingModule } from '@ghostfolio/api/interceptors/performance-logging/performance-logging.module'; @@ -34,6 +34,7 @@ import { RulesService } from './rules.service'; exports: [PortfolioService], imports: [ AccessModule, + ActivitiesModule, ApiModule, BenchmarkModule, ConfigurationModule, @@ -43,7 +44,6 @@ import { RulesService } from './rules.service'; I18nModule, ImpersonationModule, MarketDataModule, - OrderModule, PerformanceLoggingModule, PortfolioSnapshotQueueModule, PrismaModule, diff --git a/apps/api/src/app/portfolio/portfolio.service.ts b/apps/api/src/app/portfolio/portfolio.service.ts index 1bfad8395..ed72260ca 100644 --- a/apps/api/src/app/portfolio/portfolio.service.ts +++ b/apps/api/src/app/portfolio/portfolio.service.ts @@ -1,7 +1,7 @@ import { AccountBalanceService } from '@ghostfolio/api/app/account-balance/account-balance.service'; import { AccountService } from '@ghostfolio/api/app/account/account.service'; import { CashDetails } from '@ghostfolio/api/app/account/interfaces/cash-details.interface'; -import { OrderService } from '@ghostfolio/api/app/order/order.service'; +import { ActivitiesService } from '@ghostfolio/api/app/activities/activities.service'; import { UserService } from '@ghostfolio/api/app/user/user.service'; import { getFactor } from '@ghostfolio/api/helper/portfolio.helper'; import { AccountClusterRiskCurrentInvestment } from '@ghostfolio/api/models/rules/account-cluster-risk/current-investment'; @@ -105,13 +105,13 @@ export class PortfolioService { public constructor( private readonly accountBalanceService: AccountBalanceService, private readonly accountService: AccountService, + private readonly activitiesService: ActivitiesService, private readonly benchmarkService: BenchmarkService, private readonly calculatorFactory: PortfolioCalculatorFactory, private readonly dataProviderService: DataProviderService, private readonly exchangeRateDataService: ExchangeRateDataService, private readonly i18nService: I18nService, private readonly impersonationService: ImpersonationService, - private readonly orderService: OrderService, @Inject(REQUEST) private readonly request: RequestWithUser, private readonly rulesService: RulesService, private readonly symbolProfileService: SymbolProfileService, @@ -406,7 +406,7 @@ export class PortfolioService { const { endDate, startDate } = getIntervalFromDateRange(dateRange); const { activities } = - await this.orderService.getOrdersForPortfolioCalculator({ + await this.activitiesService.getActivitiesForPortfolioCalculator({ filters, userCurrency, userId @@ -490,7 +490,7 @@ export class PortfolioService { ); const { activities } = - await this.orderService.getOrdersForPortfolioCalculator({ + await this.activitiesService.getActivitiesForPortfolioCalculator({ filters, userCurrency, userId @@ -779,7 +779,7 @@ export class PortfolioService { const userCurrency = this.getUserCurrency(user); const { activities } = - await this.orderService.getOrdersForPortfolioCalculator({ + await this.activitiesService.getActivitiesForPortfolioCalculator({ userCurrency, userId }); @@ -1009,7 +1009,7 @@ export class PortfolioService { userId, userCurrency }), - this.orderService.getOrdersForPortfolioCalculator({ + this.activitiesService.getActivitiesForPortfolioCalculator({ filters, userCurrency, userId @@ -1370,7 +1370,12 @@ export class PortfolioService { }) { userId = await this.getUserId(impersonationId, userId); - await this.orderService.assignTags({ dataSource, symbol, tags, userId }); + await this.activitiesService.assignTags({ + dataSource, + symbol, + tags, + userId + }); } private getAggregatedMarkets(holdings: Record): { @@ -1872,7 +1877,7 @@ export class PortfolioService { userId = await this.getUserId(impersonationId, userId); const user = await this.userService.user({ id: userId }); - const { activities } = await this.orderService.getOrders({ + const { activities } = await this.activitiesService.getActivities({ userCurrency, userId, withExcludedAccountsAndActivities: true diff --git a/apps/api/src/app/user/user.module.ts b/apps/api/src/app/user/user.module.ts index 7ca68d275..3f4e898fc 100644 --- a/apps/api/src/app/user/user.module.ts +++ b/apps/api/src/app/user/user.module.ts @@ -1,4 +1,4 @@ -import { OrderModule } from '@ghostfolio/api/app/order/order.module'; +import { ActivitiesModule } from '@ghostfolio/api/app/activities/activities.module'; import { SubscriptionModule } from '@ghostfolio/api/app/subscription/subscription.module'; import { RedactValuesInResponseModule } from '@ghostfolio/api/interceptors/redact-values-in-response/redact-values-in-response.module'; import { ConfigurationModule } from '@ghostfolio/api/services/configuration/configuration.module'; @@ -18,6 +18,7 @@ import { UserService } from './user.service'; controllers: [UserController], exports: [UserService], imports: [ + ActivitiesModule, ConfigurationModule, I18nModule, ImpersonationModule, @@ -25,7 +26,6 @@ import { UserService } from './user.service'; secret: process.env.JWT_SECRET_KEY, signOptions: { expiresIn: '30 days' } }), - OrderModule, PrismaModule, PropertyModule, RedactValuesInResponseModule, diff --git a/apps/api/src/app/user/user.service.ts b/apps/api/src/app/user/user.service.ts index 97ab8a59f..5a339c090 100644 --- a/apps/api/src/app/user/user.service.ts +++ b/apps/api/src/app/user/user.service.ts @@ -1,4 +1,4 @@ -import { OrderService } from '@ghostfolio/api/app/order/order.service'; +import { ActivitiesService } from '@ghostfolio/api/app/activities/activities.service'; import { SubscriptionService } from '@ghostfolio/api/app/subscription/subscription.service'; import { environment } from '@ghostfolio/api/environments/environment'; import { PortfolioChangedEvent } from '@ghostfolio/api/events/portfolio-changed.event'; @@ -55,10 +55,10 @@ import { createHmac } from 'node:crypto'; @Injectable() export class UserService { public constructor( + private readonly activitiesService: ActivitiesService, private readonly configurationService: ConfigurationService, private readonly eventEmitter: EventEmitter2, private readonly i18nService: I18nService, - private readonly orderService: OrderService, private readonly prismaService: PrismaService, private readonly propertyService: PropertyService, private readonly subscriptionService: SubscriptionService, @@ -643,7 +643,7 @@ export class UserService { } catch {} try { - await this.orderService.deleteOrders({ + await this.activitiesService.deleteActivities({ userId: where.id }); } catch {} diff --git a/apps/api/src/events/asset-profile-changed.listener.ts b/apps/api/src/events/asset-profile-changed.listener.ts index ad80ee4a5..1ecadec67 100644 --- a/apps/api/src/events/asset-profile-changed.listener.ts +++ b/apps/api/src/events/asset-profile-changed.listener.ts @@ -1,4 +1,4 @@ -import { OrderService } from '@ghostfolio/api/app/order/order.service'; +import { ActivitiesService } from '@ghostfolio/api/app/activities/activities.service'; import { ConfigurationService } from '@ghostfolio/api/services/configuration/configuration.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'; @@ -13,11 +13,11 @@ import { AssetProfileChangedEvent } from './asset-profile-changed.event'; @Injectable() export class AssetProfileChangedListener { public constructor( + private readonly activitiesService: ActivitiesService, private readonly configurationService: ConfigurationService, private readonly dataGatheringService: DataGatheringService, private readonly dataProviderService: DataProviderService, - private readonly exchangeRateDataService: ExchangeRateDataService, - private readonly orderService: OrderService + private readonly exchangeRateDataService: ExchangeRateDataService ) {} @OnEvent(AssetProfileChangedEvent.getName()) @@ -48,7 +48,7 @@ export class AssetProfileChangedListener { } const { dateOfFirstActivity } = - await this.orderService.getStatisticsByCurrency(event.data.currency); + await this.activitiesService.getStatisticsByCurrency(event.data.currency); if (dateOfFirstActivity) { await this.dataGatheringService.gatherSymbol({ diff --git a/apps/api/src/events/events.module.ts b/apps/api/src/events/events.module.ts index ece67ebe0..772766945 100644 --- a/apps/api/src/events/events.module.ts +++ b/apps/api/src/events/events.module.ts @@ -1,4 +1,4 @@ -import { OrderModule } from '@ghostfolio/api/app/order/order.module'; +import { ActivitiesModule } from '@ghostfolio/api/app/activities/activities.module'; import { RedisCacheModule } from '@ghostfolio/api/app/redis-cache/redis-cache.module'; import { ConfigurationModule } from '@ghostfolio/api/services/configuration/configuration.module'; import { DataProviderModule } from '@ghostfolio/api/services/data-provider/data-provider.module'; @@ -12,11 +12,11 @@ import { PortfolioChangedListener } from './portfolio-changed.listener'; @Module({ imports: [ + ActivitiesModule, ConfigurationModule, DataGatheringModule, DataProviderModule, ExchangeRateDataModule, - OrderModule, RedisCacheModule ], providers: [AssetProfileChangedListener, PortfolioChangedListener] diff --git a/apps/api/src/services/queues/portfolio-snapshot/portfolio-snapshot.module.ts b/apps/api/src/services/queues/portfolio-snapshot/portfolio-snapshot.module.ts index 958636334..553765768 100644 --- a/apps/api/src/services/queues/portfolio-snapshot/portfolio-snapshot.module.ts +++ b/apps/api/src/services/queues/portfolio-snapshot/portfolio-snapshot.module.ts @@ -1,5 +1,5 @@ import { AccountBalanceModule } from '@ghostfolio/api/app/account-balance/account-balance.module'; -import { OrderModule } from '@ghostfolio/api/app/order/order.module'; +import { ActivitiesModule } from '@ghostfolio/api/app/activities/activities.module'; import { PortfolioCalculatorFactory } from '@ghostfolio/api/app/portfolio/calculator/portfolio-calculator.factory'; import { CurrentRateService } from '@ghostfolio/api/app/portfolio/current-rate.service'; import { RedisCacheModule } from '@ghostfolio/api/app/redis-cache/redis-cache.module'; @@ -22,6 +22,7 @@ import { PortfolioSnapshotProcessor } from './portfolio-snapshot.processor'; exports: [BullModule, PortfolioSnapshotService], imports: [ AccountBalanceModule, + ActivitiesModule, BullModule.registerQueue({ name: PORTFOLIO_SNAPSHOT_COMPUTATION_QUEUE, settings: { @@ -36,7 +37,6 @@ import { PortfolioSnapshotProcessor } from './portfolio-snapshot.processor'; DataProviderModule, ExchangeRateDataModule, MarketDataModule, - OrderModule, RedisCacheModule ], providers: [ diff --git a/apps/api/src/services/queues/portfolio-snapshot/portfolio-snapshot.processor.ts b/apps/api/src/services/queues/portfolio-snapshot/portfolio-snapshot.processor.ts index 58a0a8f8a..f3aa6e77e 100644 --- a/apps/api/src/services/queues/portfolio-snapshot/portfolio-snapshot.processor.ts +++ b/apps/api/src/services/queues/portfolio-snapshot/portfolio-snapshot.processor.ts @@ -1,5 +1,5 @@ import { AccountBalanceService } from '@ghostfolio/api/app/account-balance/account-balance.service'; -import { OrderService } from '@ghostfolio/api/app/order/order.service'; +import { ActivitiesService } from '@ghostfolio/api/app/activities/activities.service'; import { PortfolioCalculatorFactory } from '@ghostfolio/api/app/portfolio/calculator/portfolio-calculator.factory'; import { PortfolioSnapshotValue } from '@ghostfolio/api/app/portfolio/interfaces/snapshot-value.interface'; import { RedisCacheService } from '@ghostfolio/api/app/redis-cache/redis-cache.service'; @@ -23,9 +23,9 @@ import { PortfolioSnapshotQueueJob } from './interfaces/portfolio-snapshot-queue export class PortfolioSnapshotProcessor { public constructor( private readonly accountBalanceService: AccountBalanceService, + private readonly activitiesService: ActivitiesService, private readonly calculatorFactory: PortfolioCalculatorFactory, private readonly configurationService: ConfigurationService, - private readonly orderService: OrderService, private readonly redisCacheService: RedisCacheService ) {} @@ -47,7 +47,7 @@ export class PortfolioSnapshotProcessor { ); const { activities } = - await this.orderService.getOrdersForPortfolioCalculator({ + await this.activitiesService.getActivitiesForPortfolioCalculator({ filters: job.data.filters, userCurrency: job.data.userCurrency, userId: job.data.userId, 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 427386796..4d89cfbe1 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 @@ -581,7 +581,7 @@ export class GfHoldingDetailDialogComponent implements OnDestroy, OnInit { }; this.dataService - .postOrder(activity) + .postActivity(activity) .pipe(takeUntil(this.unsubscribeSubject)) .subscribe(() => { this.router.navigate( diff --git a/apps/client/src/app/pages/portfolio/activities/activities-page.component.ts b/apps/client/src/app/pages/portfolio/activities/activities-page.component.ts index cf7a41215..ca3f5b30d 100644 --- a/apps/client/src/app/pages/portfolio/activities/activities-page.component.ts +++ b/apps/client/src/app/pages/portfolio/activities/activities-page.component.ts @@ -334,7 +334,7 @@ export class GfActivitiesPageComponent implements OnDestroy, OnInit { .subscribe((activity: UpdateOrderDto) => { if (activity) { this.dataService - .putOrder(activity) + .putActivity(activity) .pipe(takeUntil(this.unsubscribeSubject)) .subscribe({ next: () => { @@ -385,7 +385,7 @@ export class GfActivitiesPageComponent implements OnDestroy, OnInit { .pipe(takeUntil(this.unsubscribeSubject)) .subscribe((transaction: CreateOrderDto | null) => { if (transaction) { - this.dataService.postOrder(transaction).subscribe({ + this.dataService.postActivity(transaction).subscribe({ next: () => { this.userService .get(true) diff --git a/libs/ui/src/lib/services/data.service.ts b/libs/ui/src/lib/services/data.service.ts index 37443cd20..62e7b6b4a 100644 --- a/libs/ui/src/lib/services/data.service.ts +++ b/libs/ui/src/lib/services/data.service.ts @@ -241,7 +241,7 @@ export class DataService { params = params.append('take', take); } - return this.http.get('/api/v1/order', { params }).pipe( + return this.http.get('/api/v1/activities', { params }).pipe( map(({ activities, count }) => { for (const activity of activities) { activity.createdAt = parseISO(activity.createdAt); @@ -253,14 +253,18 @@ export class DataService { } public fetchActivity(aActivityId: string) { - return this.http.get(`/api/v1/order/${aActivityId}`).pipe( - map((activity) => { - activity.createdAt = parseISO(activity.createdAt as unknown as string); - activity.date = parseISO(activity.date as unknown as string); + return this.http + .get(`/api/v1/activities/${aActivityId}`) + .pipe( + map((activity) => { + activity.createdAt = parseISO( + activity.createdAt as unknown as string + ); + activity.date = parseISO(activity.date as unknown as string); - return activity; - }) - ); + return activity; + }) + ); } public fetchDividends({ @@ -317,11 +321,11 @@ export class DataService { public deleteActivities({ filters }) { const params = this.buildFiltersAsQueryParams({ filters }); - return this.http.delete('/api/v1/order', { params }); + return this.http.delete('/api/v1/activities', { params }); } public deleteActivity(aId: string) { - return this.http.delete(`/api/v1/order/${aId}`); + return this.http.delete(`/api/v1/activities/${aId}`); } public deleteBenchmark({ dataSource, symbol }: AssetProfileIdentifier) { @@ -761,6 +765,10 @@ export class DataService { ); } + public postActivity(aOrder: CreateOrderDto) { + return this.http.post('/api/v1/activities', aOrder); + } + public postApiKey() { return this.http.post('/api/v1/api-keys', {}); } @@ -783,10 +791,6 @@ export class DataService { return this.http.post(url, marketData); } - public postOrder(aOrder: CreateOrderDto) { - return this.http.post('/api/v1/order', aOrder); - } - public postTag(aTag: CreateTagDto) { return this.http.post(`/api/v1/tags`, aTag); } @@ -807,6 +811,10 @@ export class DataService { return this.http.put(`/api/v1/account/${aAccount.id}`, aAccount); } + public putActivity(aOrder: UpdateOrderDto) { + return this.http.put(`/api/v1/activities/${aOrder.id}`, aOrder); + } + public putAdminSetting(key: string, aData: UpdatePropertyDto) { return this.http.put(`/api/v1/admin/settings/${key}`, aData); } @@ -822,10 +830,6 @@ export class DataService { ); } - public putOrder(aOrder: UpdateOrderDto) { - return this.http.put(`/api/v1/order/${aOrder.id}`, aOrder); - } - public putTag(aTag: UpdateTagDto) { return this.http.put(`/api/v1/tags/${aTag.id}`, aTag); } From 1057f4308485803eb44bf29b4218d596153f7c5b Mon Sep 17 00:00:00 2001 From: Thomas Kaul <4159106+dtslvr@users.noreply.github.com> Date: Sat, 7 Mar 2026 18:22:55 +0100 Subject: [PATCH 104/224] Release 2.248.0 (#6493) --- CHANGELOG.md | 2 +- package-lock.json | 4 ++-- package.json | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1279ef62f..4d8cdd873 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,7 +5,7 @@ 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 +## 2.248.0 - 2026-03-07 ### Added diff --git a/package-lock.json b/package-lock.json index 0ea9bbdce..ed34faf03 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "ghostfolio", - "version": "2.247.0", + "version": "2.248.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "ghostfolio", - "version": "2.247.0", + "version": "2.248.0", "hasInstallScript": true, "license": "AGPL-3.0", "dependencies": { diff --git a/package.json b/package.json index 47c9e9ade..b501bf7a4 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "ghostfolio", - "version": "2.247.0", + "version": "2.248.0", "homepage": "https://ghostfol.io", "license": "AGPL-3.0", "repository": "https://github.com/ghostfolio/ghostfolio", From 7d8f0defb2ab47e2f2b1c30f6ea1a78241e8b705 Mon Sep 17 00:00:00 2001 From: Thomas Kaul <4159106+dtslvr@users.noreply.github.com> Date: Sun, 8 Mar 2026 07:05:07 +0100 Subject: [PATCH 105/224] Bugfix/improve types in data service (#6492) * Improve types --- libs/ui/src/lib/services/data.service.ts | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/libs/ui/src/lib/services/data.service.ts b/libs/ui/src/lib/services/data.service.ts index 62e7b6b4a..169de067c 100644 --- a/libs/ui/src/lib/services/data.service.ts +++ b/libs/ui/src/lib/services/data.service.ts @@ -69,10 +69,11 @@ import { Injectable } from '@angular/core'; import { SortDirection } from '@angular/material/sort'; import { utc } from '@date-fns/utc'; import { + Account, AccountBalance, DataSource, MarketData, - Order as OrderModel, + Order, Tag } from '@prisma/client'; import { format, parseISO } from 'date-fns'; @@ -751,11 +752,11 @@ export class DataService { } public postAccess(aAccess: CreateAccessDto) { - return this.http.post('/api/v1/access', aAccess); + return this.http.post('/api/v1/access', aAccess); } public postAccount(aAccount: CreateAccountDto) { - return this.http.post('/api/v1/account', aAccount); + return this.http.post('/api/v1/account', aAccount); } public postAccountBalance(aAccountBalance: CreateAccountBalanceDto) { @@ -766,7 +767,7 @@ export class DataService { } public postActivity(aOrder: CreateOrderDto) { - return this.http.post('/api/v1/activities', aOrder); + return this.http.post('/api/v1/activities', aOrder); } public postApiKey() { From 7ac32ee6f3637c3397f4b50b7e147746bb3b8252 Mon Sep 17 00:00:00 2001 From: Thomas Kaul <4159106+dtslvr@users.noreply.github.com> Date: Sun, 8 Mar 2026 13:51:59 +0100 Subject: [PATCH 106/224] Task/add asset profile to portfolio position interface (part 2) (#6500) * Add currency to asset profile --- apps/api/src/app/portfolio/portfolio.service.ts | 2 ++ .../src/lib/interfaces/portfolio-position.interface.ts | 2 ++ libs/ui/src/lib/mocks/holdings.ts | 7 +++++++ 3 files changed, 11 insertions(+) diff --git a/apps/api/src/app/portfolio/portfolio.service.ts b/apps/api/src/app/portfolio/portfolio.service.ts index ed72260ca..167339487 100644 --- a/apps/api/src/app/portfolio/portfolio.service.ts +++ b/apps/api/src/app/portfolio/portfolio.service.ts @@ -628,6 +628,7 @@ export class PortfolioService { assetSubClass: assetProfile.assetSubClass, countries: assetProfile.countries, dataSource: assetProfile.dataSource, + currency: assetProfile.currency, holdings: assetProfile.holdings.map( ({ allocationInPercentage, name }) => { return { @@ -1699,6 +1700,7 @@ export class PortfolioService { assetClass: AssetClass.LIQUIDITY, assetSubClass: AssetSubClass.CASH, assetProfile: { + currency, assetClass: AssetClass.LIQUIDITY, assetSubClass: AssetSubClass.CASH, countries: [], diff --git a/libs/common/src/lib/interfaces/portfolio-position.interface.ts b/libs/common/src/lib/interfaces/portfolio-position.interface.ts index 742e63d7a..c4ef2e3dc 100644 --- a/libs/common/src/lib/interfaces/portfolio-position.interface.ts +++ b/libs/common/src/lib/interfaces/portfolio-position.interface.ts @@ -22,6 +22,7 @@ export interface PortfolioPosition { | 'assetClass' | 'assetSubClass' | 'countries' + | 'currency' | 'dataSource' | 'holdings' | 'name' @@ -42,6 +43,7 @@ export interface PortfolioPosition { /** @deprecated */ countries: Country[]; + /** @deprecated */ currency: string; /** @deprecated */ diff --git a/libs/ui/src/lib/mocks/holdings.ts b/libs/ui/src/lib/mocks/holdings.ts index f426593c1..b32eb527a 100644 --- a/libs/ui/src/lib/mocks/holdings.ts +++ b/libs/ui/src/lib/mocks/holdings.ts @@ -17,6 +17,7 @@ export const holdings: PortfolioPosition[] = [ weight: 1 } ], + currency: 'USD', dataSource: 'YAHOO', holdings: [], sectors: [ @@ -81,6 +82,7 @@ export const holdings: PortfolioPosition[] = [ weight: 1 } ], + currency: 'EUR', dataSource: 'YAHOO', holdings: [], sectors: [ @@ -145,6 +147,7 @@ export const holdings: PortfolioPosition[] = [ weight: 1 } ], + currency: 'USD', dataSource: 'YAHOO', holdings: [], sectors: [ @@ -202,6 +205,7 @@ export const holdings: PortfolioPosition[] = [ assetClass: 'LIQUIDITY', assetSubClass: 'CASH', countries: [], + currency: 'USD', dataSource: 'COINGECKO', holdings: [], sectors: [], @@ -249,6 +253,7 @@ export const holdings: PortfolioPosition[] = [ weight: 1 } ], + currency: 'USD', dataSource: 'YAHOO', holdings: [], sectors: [ @@ -313,6 +318,7 @@ export const holdings: PortfolioPosition[] = [ weight: 1 } ], + currency: 'USD', dataSource: 'YAHOO', holdings: [], sectors: [ @@ -377,6 +383,7 @@ export const holdings: PortfolioPosition[] = [ weight: 1 } ], + currency: 'USD', dataSource: 'YAHOO', holdings: [], sectors: [ From 07b165f79a0eb625071bc5c78f7b7016589eff7c Mon Sep 17 00:00:00 2001 From: Thomas Kaul <4159106+dtslvr@users.noreply.github.com> Date: Sun, 8 Mar 2026 16:02:48 +0100 Subject: [PATCH 107/224] Task/add asset profile to portfolio position interface (part 3) (#6502) * Reorder --- apps/api/src/app/portfolio/portfolio.service.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/api/src/app/portfolio/portfolio.service.ts b/apps/api/src/app/portfolio/portfolio.service.ts index 167339487..5dab27939 100644 --- a/apps/api/src/app/portfolio/portfolio.service.ts +++ b/apps/api/src/app/portfolio/portfolio.service.ts @@ -627,8 +627,8 @@ export class PortfolioService { assetClass: assetProfile.assetClass, assetSubClass: assetProfile.assetSubClass, countries: assetProfile.countries, - dataSource: assetProfile.dataSource, currency: assetProfile.currency, + dataSource: assetProfile.dataSource, holdings: assetProfile.holdings.map( ({ allocationInPercentage, name }) => { return { From 2860ebe1cb96f29ea73a07acfd96b33d5bd0fa3a Mon Sep 17 00:00:00 2001 From: Erwin-N <111194281+Erwin-N@users.noreply.github.com> Date: Mon, 9 Mar 2026 12:00:13 +0100 Subject: [PATCH 108/224] Task/improve language localization for NL 20260903 (#6506) * Improve language localization * Update changelog --- CHANGELOG.md | 6 ++++++ apps/client/src/locales/messages.nl.xlf | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4d8cdd873..457f98884 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 Dutch (`nl`) + ## 2.248.0 - 2026-03-07 ### Added diff --git a/apps/client/src/locales/messages.nl.xlf b/apps/client/src/locales/messages.nl.xlf index 158ff4fb1..2cf570721 100644 --- a/apps/client/src/locales/messages.nl.xlf +++ b/apps/client/src/locales/messages.nl.xlf @@ -3823,7 +3823,7 @@ By - Door + Tegen apps/client/src/app/pages/portfolio/fire/fire-page.html 139 From e5a771671f8f45fcf99b9b0cc1c25cd0223489c1 Mon Sep 17 00:00:00 2001 From: Thomas Kaul <4159106+dtslvr@users.noreply.github.com> Date: Mon, 9 Mar 2026 20:42:23 +0100 Subject: [PATCH 109/224] Task/rename order permissions to activity (#6494) * Rename order permissions to activity --- .../app/activities/activities.controller.ts | 8 ++++---- apps/api/src/app/import/import.controller.ts | 2 +- .../src/app/portfolio/portfolio.controller.ts | 2 +- apps/client/src/app/app.component.ts | 12 +++++++++--- .../holding-detail-dialog.html | 2 +- .../interfaces/interfaces.ts | 2 +- .../home-holdings/home-holdings.component.ts | 2 +- .../home-overview/home-overview.component.ts | 2 +- .../pages/accounts/accounts-page.component.ts | 2 +- .../activities/activities-page.component.ts | 4 ++-- .../allocations/allocations-page.component.ts | 2 +- libs/common/src/lib/permissions.ts | 18 +++++++++--------- 12 files changed, 32 insertions(+), 26 deletions(-) diff --git a/apps/api/src/app/activities/activities.controller.ts b/apps/api/src/app/activities/activities.controller.ts index da7aed21d..49c8885a1 100644 --- a/apps/api/src/app/activities/activities.controller.ts +++ b/apps/api/src/app/activities/activities.controller.ts @@ -59,7 +59,7 @@ export class ActivitiesController { ) {} @Delete() - @HasPermission(permissions.deleteOrder) + @HasPermission(permissions.deleteActivity) @UseGuards(AuthGuard('jwt'), HasPermissionGuard) @UseInterceptors(TransformDataSourceInRequestInterceptor) public async deleteActivities( @@ -84,7 +84,7 @@ export class ActivitiesController { } @Delete(':id') - @HasPermission(permissions.deleteOrder) + @HasPermission(permissions.deleteActivity) @UseGuards(AuthGuard('jwt'), HasPermissionGuard) public async deleteActivity(@Param('id') id: string): Promise { const activity = await this.activitiesService.order({ @@ -191,7 +191,7 @@ export class ActivitiesController { return activity; } - @HasPermission(permissions.createOrder) + @HasPermission(permissions.createActivity) @Post() @UseGuards(AuthGuard('jwt'), HasPermissionGuard) @UseInterceptors(TransformDataSourceInRequestInterceptor) @@ -274,7 +274,7 @@ export class ActivitiesController { return activity; } - @HasPermission(permissions.updateOrder) + @HasPermission(permissions.updateActivity) @Put(':id') @UseGuards(AuthGuard('jwt'), HasPermissionGuard) @UseInterceptors(TransformDataSourceInRequestInterceptor) diff --git a/apps/api/src/app/import/import.controller.ts b/apps/api/src/app/import/import.controller.ts index 81481fd65..d5724bef2 100644 --- a/apps/api/src/app/import/import.controller.ts +++ b/apps/api/src/app/import/import.controller.ts @@ -38,7 +38,7 @@ export class ImportController { @Post() @UseGuards(AuthGuard('jwt'), HasPermissionGuard) - @HasPermission(permissions.createOrder) + @HasPermission(permissions.createActivity) @UseInterceptors(TransformDataSourceInRequestInterceptor) @UseInterceptors(TransformDataSourceInResponseInterceptor) public async import( diff --git a/apps/api/src/app/portfolio/portfolio.controller.ts b/apps/api/src/app/portfolio/portfolio.controller.ts index 80d7f9acc..73d4320d6 100644 --- a/apps/api/src/app/portfolio/portfolio.controller.ts +++ b/apps/api/src/app/portfolio/portfolio.controller.ts @@ -639,7 +639,7 @@ export class PortfolioController { return report; } - @HasPermission(permissions.updateOrder) + @HasPermission(permissions.updateActivity) @Put('holding/:dataSource/:symbol/tags') @UseInterceptors(TransformDataSourceInRequestInterceptor) @UseGuards(AuthGuard('jwt'), HasPermissionGuard) diff --git a/apps/client/src/app/app.component.ts b/apps/client/src/app/app.component.ts index a4af01124..3daca607a 100644 --- a/apps/client/src/app/app.component.ts +++ b/apps/client/src/app/app.component.ts @@ -296,15 +296,21 @@ export class GfAppComponent implements OnDestroy, OnInit { ), hasPermissionToCreateActivity: !this.hasImpersonationId && - hasPermission(this.user?.permissions, permissions.createOrder) && + hasPermission( + this.user?.permissions, + permissions.createActivity + ) && !this.user?.settings?.isRestrictedView, hasPermissionToReportDataGlitch: hasPermission( this.user?.permissions, permissions.reportDataGlitch ), - hasPermissionToUpdateOrder: + hasPermissionToUpdateActivity: !this.hasImpersonationId && - hasPermission(this.user?.permissions, permissions.updateOrder) && + hasPermission( + this.user?.permissions, + permissions.updateActivity + ) && !this.user?.settings?.isRestrictedView, locale: this.user?.settings?.locale }, diff --git a/apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html b/apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html index 86f4676f3..15415e413 100644 --- a/apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html +++ b/apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html @@ -414,7 +414,7 @@ diff --git a/apps/client/src/app/components/holding-detail-dialog/interfaces/interfaces.ts b/apps/client/src/app/components/holding-detail-dialog/interfaces/interfaces.ts index aab854384..527b13636 100644 --- a/apps/client/src/app/components/holding-detail-dialog/interfaces/interfaces.ts +++ b/apps/client/src/app/components/holding-detail-dialog/interfaces/interfaces.ts @@ -11,7 +11,7 @@ export interface HoldingDetailDialogParams { hasPermissionToAccessAdminControl: boolean; hasPermissionToCreateActivity: boolean; hasPermissionToReportDataGlitch: boolean; - hasPermissionToUpdateOrder: boolean; + hasPermissionToUpdateActivity: boolean; locale: string; symbol: string; } diff --git a/apps/client/src/app/components/home-holdings/home-holdings.component.ts b/apps/client/src/app/components/home-holdings/home-holdings.component.ts index dc444977d..df5e43087 100644 --- a/apps/client/src/app/components/home-holdings/home-holdings.component.ts +++ b/apps/client/src/app/components/home-holdings/home-holdings.component.ts @@ -107,7 +107,7 @@ export class GfHomeHoldingsComponent implements OnDestroy, OnInit { this.hasPermissionToCreateActivity = hasPermission( this.user.permissions, - permissions.createOrder + permissions.createActivity ); this.initialize(); diff --git a/apps/client/src/app/components/home-overview/home-overview.component.ts b/apps/client/src/app/components/home-overview/home-overview.component.ts index 0d5020904..cb1df1a74 100644 --- a/apps/client/src/app/components/home-overview/home-overview.component.ts +++ b/apps/client/src/app/components/home-overview/home-overview.component.ts @@ -80,7 +80,7 @@ export class GfHomeOverviewComponent implements OnDestroy, OnInit { this.hasPermissionToCreateActivity = hasPermission( this.user.permissions, - permissions.createOrder + permissions.createActivity ); this.update(); diff --git a/apps/client/src/app/pages/accounts/accounts-page.component.ts b/apps/client/src/app/pages/accounts/accounts-page.component.ts index f7e6541b5..a0eef4eba 100644 --- a/apps/client/src/app/pages/accounts/accounts-page.component.ts +++ b/apps/client/src/app/pages/accounts/accounts-page.component.ts @@ -245,7 +245,7 @@ export class GfAccountsPageComponent implements OnDestroy, OnInit { hasImpersonationId: this.hasImpersonationId, hasPermissionToCreateActivity: !this.hasImpersonationId && - hasPermission(this.user?.permissions, permissions.createOrder) && + hasPermission(this.user?.permissions, permissions.createActivity) && !this.user?.settings?.isRestrictedView }, height: this.deviceType === 'mobile' ? '98vh' : '80vh', diff --git a/apps/client/src/app/pages/portfolio/activities/activities-page.component.ts b/apps/client/src/app/pages/portfolio/activities/activities-page.component.ts index ca3f5b30d..dd78a0221 100644 --- a/apps/client/src/app/pages/portfolio/activities/activities-page.component.ts +++ b/apps/client/src/app/pages/portfolio/activities/activities-page.component.ts @@ -407,9 +407,9 @@ export class GfActivitiesPageComponent implements OnDestroy, OnInit { this.hasPermissionToCreateActivity = !this.hasImpersonationId && - hasPermission(this.user.permissions, permissions.createOrder); + hasPermission(this.user.permissions, permissions.createActivity); this.hasPermissionToDeleteActivity = !this.hasImpersonationId && - hasPermission(this.user.permissions, permissions.deleteOrder); + hasPermission(this.user.permissions, permissions.deleteActivity); } } 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 a98adc438..5226c3c12 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 @@ -567,7 +567,7 @@ export class GfAllocationsPageComponent implements OnInit { hasImpersonationId: this.hasImpersonationId, hasPermissionToCreateActivity: !this.hasImpersonationId && - hasPermission(this.user?.permissions, permissions.createOrder) && + hasPermission(this.user?.permissions, permissions.createActivity) && !this.user?.settings?.isRestrictedView }, height: this.deviceType === 'mobile' ? '98vh' : '80vh', diff --git a/libs/common/src/lib/permissions.ts b/libs/common/src/lib/permissions.ts index cb4eb175b..62ae59fbe 100644 --- a/libs/common/src/lib/permissions.ts +++ b/libs/common/src/lib/permissions.ts @@ -9,10 +9,10 @@ export const permissions = { createAccess: 'createAccess', createAccount: 'createAccount', createAccountBalance: 'createAccountBalance', + createActivity: 'createActivity', createApiKey: 'createApiKey', createMarketData: 'createMarketData', createMarketDataOfOwnAssetProfile: 'createMarketDataOfOwnAssetProfile', - createOrder: 'createOrder', createOwnTag: 'createOwnTag', createPlatform: 'createPlatform', createTag: 'createTag', @@ -21,8 +21,8 @@ export const permissions = { deleteAccess: 'deleteAccess', deleteAccount: 'deleteAccount', deleteAccountBalance: 'deleteAccountBalance', + deleteActivity: 'deleteActivity', deleteAuthDevice: 'deleteAuthDevice', - deleteOrder: 'deleteOrder', deleteOwnUser: 'deleteOwnUser', deletePlatform: 'deletePlatform', deleteTag: 'deleteTag', @@ -53,10 +53,10 @@ export const permissions = { toggleReadOnlyMode: 'toggleReadOnlyMode', updateAccount: 'updateAccount', updateAccess: 'updateAccess', + updateActivity: 'updateActivity', updateAuthDevice: 'updateAuthDevice', updateMarketData: 'updateMarketData', updateMarketDataOfOwnAssetProfile: 'updateMarketDataOfOwnAssetProfile', - updateOrder: 'updateOrder', updateOwnAccessToken: 'updateOwnAccessToken', updatePlatform: 'updatePlatform', updateTag: 'updateTag', @@ -74,19 +74,19 @@ export function getPermissions(aRole: Role): string[] { permissions.createAccess, permissions.createAccount, permissions.createAccountBalance, + permissions.createActivity, permissions.createWatchlistItem, permissions.deleteAccountBalance, permissions.deleteWatchlistItem, permissions.createMarketData, permissions.createMarketDataOfOwnAssetProfile, - permissions.createOrder, permissions.createOwnTag, permissions.createPlatform, permissions.createTag, permissions.deleteAccess, permissions.deleteAccount, + permissions.deleteActivity, permissions.deleteAuthDevice, - permissions.deleteOrder, permissions.deletePlatform, permissions.deleteTag, permissions.deleteUser, @@ -99,10 +99,10 @@ export function getPermissions(aRole: Role): string[] { permissions.readWatchlist, permissions.updateAccount, permissions.updateAccess, + permissions.updateActivity, permissions.updateAuthDevice, permissions.updateMarketData, permissions.updateMarketDataOfOwnAssetProfile, - permissions.updateOrder, permissions.updatePlatform, permissions.updateTag, permissions.updateUserSettings, @@ -125,15 +125,15 @@ export function getPermissions(aRole: Role): string[] { permissions.createAccess, permissions.createAccount, permissions.createAccountBalance, + permissions.createActivity, permissions.createMarketDataOfOwnAssetProfile, - permissions.createOrder, permissions.createOwnTag, permissions.createWatchlistItem, permissions.deleteAccess, permissions.deleteAccount, permissions.deleteAccountBalance, + permissions.deleteActivity, permissions.deleteAuthDevice, - permissions.deleteOrder, permissions.deleteWatchlistItem, permissions.readAiPrompt, permissions.readMarketDataOfOwnAssetProfile, @@ -141,9 +141,9 @@ export function getPermissions(aRole: Role): string[] { permissions.readWatchlist, permissions.updateAccount, permissions.updateAccess, + permissions.updateActivity, permissions.updateAuthDevice, permissions.updateMarketDataOfOwnAssetProfile, - permissions.updateOrder, permissions.updateUserSettings, permissions.updateViewMode ]; From 80057ccc73f2f111e74b798daa5a376ea675f266 Mon Sep 17 00:00:00 2001 From: Thomas Kaul <4159106+dtslvr@users.noreply.github.com> Date: Tue, 10 Mar 2026 17:34:46 +0100 Subject: [PATCH 110/224] Bugfix/redis health check race condition (#6504) * Fix false Redis health check failures caused by race condition * Update changelog --- CHANGELOG.md | 4 ++++ apps/api/src/app/redis-cache/redis-cache.service.ts | 11 +++++++---- 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 457f98884..b0bbc8bcf 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 Dutch (`nl`) +### Fixed + +- Fixed false _Redis_ health check failures by using unique keys and increasing the timeout to 5s + ## 2.248.0 - 2026-03-07 ### Added diff --git a/apps/api/src/app/redis-cache/redis-cache.service.ts b/apps/api/src/app/redis-cache/redis-cache.service.ts index 1ea0a6137..619d23fc5 100644 --- a/apps/api/src/app/redis-cache/redis-cache.service.ts +++ b/apps/api/src/app/redis-cache/redis-cache.service.ts @@ -6,7 +6,7 @@ import { CACHE_MANAGER, Cache } from '@nestjs/cache-manager'; import { Inject, Injectable, Logger } from '@nestjs/common'; import Keyv from 'keyv'; import ms from 'ms'; -import { createHash } from 'node:crypto'; +import { createHash, randomUUID } from 'node:crypto'; @Injectable() export class RedisCacheService { @@ -75,13 +75,16 @@ export class RedisCacheService { } public async isHealthy() { - const testKey = '__health_check__'; + const HEALTH_CHECK_TIMEOUT = ms('5 seconds'); + + const testKey = `__health_check__${randomUUID().replace(/-/g, '')}`; const testValue = Date.now().toString(); try { await Promise.race([ (async () => { - await this.set(testKey, testValue, ms('1 second')); + await this.set(testKey, testValue, HEALTH_CHECK_TIMEOUT); + const result = await this.get(testKey); if (result !== testValue) { @@ -91,7 +94,7 @@ export class RedisCacheService { new Promise((_, reject) => setTimeout( () => reject(new Error('Redis health check failed: timeout')), - ms('2 seconds') + HEALTH_CHECK_TIMEOUT ) ) ]); From 49d685c8ad52278aa73c979cbb2e13fefea98a51 Mon Sep 17 00:00:00 2001 From: Thomas Kaul <4159106+dtslvr@users.noreply.github.com> Date: Tue, 10 Mar 2026 17:35:54 +0100 Subject: [PATCH 111/224] Task/improve Storybook stories of value component (#6496) * Fix label and support size * Update changelog --- CHANGELOG.md | 1 + libs/ui/src/lib/value/value.component.stories.ts | 10 +++++++++- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b0bbc8bcf..e2dd0d4c8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Changed +- Improved the _Storybook_ stories of the value component - Improved the language localization for Dutch (`nl`) ### Fixed diff --git a/libs/ui/src/lib/value/value.component.stories.ts b/libs/ui/src/lib/value/value.component.stories.ts index a1f9d06a0..eeebe9399 100644 --- a/libs/ui/src/lib/value/value.component.stories.ts +++ b/libs/ui/src/lib/value/value.component.stories.ts @@ -16,6 +16,10 @@ export default { deviceType: { control: 'select', options: ['desktop', 'mobile'] + }, + size: { + control: 'select', + options: ['small', 'medium', 'large'] } } } as Meta; @@ -51,7 +55,11 @@ export const Label: Story = { args: { locale: 'en-US', value: 7.25 - } + }, + render: (args) => ({ + props: args, + template: `Label` + }) }; export const PerformancePositive: Story = { From b16314a625e3eb30bfe95bc03d6091fb2b6f96a4 Mon Sep 17 00:00:00 2001 From: Thomas Kaul <4159106+dtslvr@users.noreply.github.com> Date: Tue, 10 Mar 2026 17:36:57 +0100 Subject: [PATCH 112/224] Task/upgrade class-validator to version 0.15.1 (#6489) * Upgrade class-validator to version 0.15.1 * Update changelog --- CHANGELOG.md | 1 + package-lock.json | 10 +++++----- package.json | 2 +- 3 files changed, 7 insertions(+), 6 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e2dd0d4c8..3b49eaaaa 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Improved the _Storybook_ stories of the value component - Improved the language localization for Dutch (`nl`) +- Upgraded `class-validator` from version `0.14.3` to `0.15.1` ### Fixed diff --git a/package-lock.json b/package-lock.json index ed34faf03..1654d1acd 100644 --- a/package-lock.json +++ b/package-lock.json @@ -53,7 +53,7 @@ "chartjs-plugin-datalabels": "2.2.0", "cheerio": "1.2.0", "class-transformer": "0.5.1", - "class-validator": "0.14.3", + "class-validator": "0.15.1", "color": "5.0.3", "countries-and-timezones": "3.8.0", "countries-list": "3.2.2", @@ -16400,14 +16400,14 @@ "license": "MIT" }, "node_modules/class-validator": { - "version": "0.14.3", - "resolved": "https://registry.npmjs.org/class-validator/-/class-validator-0.14.3.tgz", - "integrity": "sha512-rXXekcjofVN1LTOSw+u4u9WXVEUvNBVjORW154q/IdmYWy1nMbOU9aNtZB0t8m+FJQ9q91jlr2f9CwwUFdFMRA==", + "version": "0.15.1", + "resolved": "https://registry.npmjs.org/class-validator/-/class-validator-0.15.1.tgz", + "integrity": "sha512-LqoS80HBBSCVhz/3KloUly0ovokxpdOLR++Al3J3+dHXWt9sTKlKd4eYtoxhxyUjoe5+UcIM+5k9MIxyBWnRTw==", "license": "MIT", "dependencies": { "@types/validator": "^13.15.3", "libphonenumber-js": "^1.11.1", - "validator": "^13.15.20" + "validator": "^13.15.22" } }, "node_modules/clean-css": { diff --git a/package.json b/package.json index b501bf7a4..9fe3ef3c2 100644 --- a/package.json +++ b/package.json @@ -98,7 +98,7 @@ "chartjs-plugin-datalabels": "2.2.0", "cheerio": "1.2.0", "class-transformer": "0.5.1", - "class-validator": "0.14.3", + "class-validator": "0.15.1", "color": "5.0.3", "countries-and-timezones": "3.8.0", "countries-list": "3.2.2", From dd895e3112c49dc30e7c25587637a73fee22b8a7 Mon Sep 17 00:00:00 2001 From: Thomas Kaul <4159106+dtslvr@users.noreply.github.com> Date: Tue, 10 Mar 2026 17:37:35 +0100 Subject: [PATCH 113/224] Task/improve localization of resources overview component (#6509) * Improve localization --- .../resources/overview/resources-overview.component.html | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/apps/client/src/app/pages/resources/overview/resources-overview.component.html b/apps/client/src/app/pages/resources/overview/resources-overview.component.html index 3a6f18d40..86a334c79 100644 --- a/apps/client/src/app/pages/resources/overview/resources-overview.component.html +++ b/apps/client/src/app/pages/resources/overview/resources-overview.component.html @@ -7,7 +7,9 @@

    {{ item.title }}

    {{ item.description }}

    - Explore {{ item.title }} → + Explore {{ item.title }}
    } From 41f0dfda652420a43c08bacfed224de0e2bf3373 Mon Sep 17 00:00:00 2001 From: Thomas Kaul <4159106+dtslvr@users.noreply.github.com> Date: Tue, 10 Mar 2026 17:40:10 +0100 Subject: [PATCH 114/224] Task/debounce portfolio and asset profile change listeners (#6505) * Debounce portfolio and asset profile change event listeners * Update changelog --- CHANGELOG.md | 4 ++ .../src/events/asset-profile-changed.event.ts | 12 ++++ .../events/asset-profile-changed.listener.ts | 59 ++++++++++++++++--- .../src/events/portfolio-changed.listener.ts | 30 ++++++++-- 4 files changed, 94 insertions(+), 11 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3b49eaaaa..89c34edde 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## Unreleased +### Added + +- Added a debounce to the `PortfolioChangedListener` and `AssetProfileChangedListener` to minimize redundant _Redis_ and database operations + ### Changed - Improved the _Storybook_ stories of the value component diff --git a/apps/api/src/events/asset-profile-changed.event.ts b/apps/api/src/events/asset-profile-changed.event.ts index 46a8c5db4..c08fe59f1 100644 --- a/apps/api/src/events/asset-profile-changed.event.ts +++ b/apps/api/src/events/asset-profile-changed.event.ts @@ -8,4 +8,16 @@ export class AssetProfileChangedEvent { public static getName(): string { return 'assetProfile.changed'; } + + public getCurrency() { + return this.data.currency; + } + + public getDataSource() { + return this.data.dataSource; + } + + public getSymbol() { + return this.data.symbol; + } } diff --git a/apps/api/src/events/asset-profile-changed.listener.ts b/apps/api/src/events/asset-profile-changed.listener.ts index 1ecadec67..cc70edad6 100644 --- a/apps/api/src/events/asset-profile-changed.listener.ts +++ b/apps/api/src/events/asset-profile-changed.listener.ts @@ -4,14 +4,21 @@ import { DataProviderService } from '@ghostfolio/api/services/data-provider/data import { ExchangeRateDataService } from '@ghostfolio/api/services/exchange-rate-data/exchange-rate-data.service'; import { DataGatheringService } from '@ghostfolio/api/services/queues/data-gathering/data-gathering.service'; import { DEFAULT_CURRENCY } from '@ghostfolio/common/config'; +import { getAssetProfileIdentifier } from '@ghostfolio/common/helper'; import { Injectable, Logger } from '@nestjs/common'; import { OnEvent } from '@nestjs/event-emitter'; +import { DataSource } from '@prisma/client'; +import ms from 'ms'; import { AssetProfileChangedEvent } from './asset-profile-changed.event'; @Injectable() export class AssetProfileChangedListener { + private static readonly DEBOUNCE_DELAY = ms('5 seconds'); + + private debounceTimers = new Map(); + public constructor( private readonly activitiesService: ActivitiesService, private readonly configurationService: ConfigurationService, @@ -21,9 +28,47 @@ export class AssetProfileChangedListener { ) {} @OnEvent(AssetProfileChangedEvent.getName()) - public async handleAssetProfileChanged(event: AssetProfileChangedEvent) { + public handleAssetProfileChanged(event: AssetProfileChangedEvent) { + const currency = event.getCurrency(); + const dataSource = event.getDataSource(); + const symbol = event.getSymbol(); + + const key = getAssetProfileIdentifier({ + dataSource, + symbol + }); + + const existingTimer = this.debounceTimers.get(key); + + if (existingTimer) { + clearTimeout(existingTimer); + } + + this.debounceTimers.set( + key, + setTimeout(() => { + this.debounceTimers.delete(key); + + void this.processAssetProfileChanged({ + currency, + dataSource, + symbol + }); + }, AssetProfileChangedListener.DEBOUNCE_DELAY) + ); + } + + private async processAssetProfileChanged({ + currency, + dataSource, + symbol + }: { + currency: string; + dataSource: DataSource; + symbol: string; + }) { Logger.log( - `Asset profile of ${event.data.symbol} (${event.data.dataSource}) has changed`, + `Asset profile of ${symbol} (${dataSource}) has changed`, 'AssetProfileChangedListener' ); @@ -31,16 +76,16 @@ export class AssetProfileChangedListener { this.configurationService.get( 'ENABLE_FEATURE_GATHER_NEW_EXCHANGE_RATES' ) === false || - event.data.currency === DEFAULT_CURRENCY + currency === DEFAULT_CURRENCY ) { return; } const existingCurrencies = this.exchangeRateDataService.getCurrencies(); - if (!existingCurrencies.includes(event.data.currency)) { + if (!existingCurrencies.includes(currency)) { Logger.log( - `New currency ${event.data.currency} has been detected`, + `New currency ${currency} has been detected`, 'AssetProfileChangedListener' ); @@ -48,13 +93,13 @@ export class AssetProfileChangedListener { } const { dateOfFirstActivity } = - await this.activitiesService.getStatisticsByCurrency(event.data.currency); + await this.activitiesService.getStatisticsByCurrency(currency); if (dateOfFirstActivity) { await this.dataGatheringService.gatherSymbol({ dataSource: this.dataProviderService.getDataSourceForExchangeRates(), date: dateOfFirstActivity, - symbol: `${DEFAULT_CURRENCY}${event.data.currency}` + symbol: `${DEFAULT_CURRENCY}${currency}` }); } } diff --git a/apps/api/src/events/portfolio-changed.listener.ts b/apps/api/src/events/portfolio-changed.listener.ts index d12b9558d..f8e2a9229 100644 --- a/apps/api/src/events/portfolio-changed.listener.ts +++ b/apps/api/src/events/portfolio-changed.listener.ts @@ -2,22 +2,44 @@ import { RedisCacheService } from '@ghostfolio/api/app/redis-cache/redis-cache.s import { Injectable, Logger } from '@nestjs/common'; import { OnEvent } from '@nestjs/event-emitter'; +import ms from 'ms'; import { PortfolioChangedEvent } from './portfolio-changed.event'; @Injectable() export class PortfolioChangedListener { + private static readonly DEBOUNCE_DELAY = ms('5 seconds'); + + private debounceTimers = new Map(); + public constructor(private readonly redisCacheService: RedisCacheService) {} @OnEvent(PortfolioChangedEvent.getName()) handlePortfolioChangedEvent(event: PortfolioChangedEvent) { + const userId = event.getUserId(); + + const existingTimer = this.debounceTimers.get(userId); + + if (existingTimer) { + clearTimeout(existingTimer); + } + + this.debounceTimers.set( + userId, + setTimeout(() => { + this.debounceTimers.delete(userId); + + void this.processPortfolioChanged({ userId }); + }, PortfolioChangedListener.DEBOUNCE_DELAY) + ); + } + + private async processPortfolioChanged({ userId }: { userId: string }) { Logger.log( - `Portfolio of user '${event.getUserId()}' has changed`, + `Portfolio of user '${userId}' has changed`, 'PortfolioChangedListener' ); - this.redisCacheService.removePortfolioSnapshotsByUserId({ - userId: event.getUserId() - }); + await this.redisCacheService.removePortfolioSnapshotsByUserId({ userId }); } } From fa4260d6fc74cdd49c4dd248e7d97a01232e076c Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue, 10 Mar 2026 17:42:37 +0100 Subject: [PATCH 115/224] Task/update locales (#6410) --- apps/client/src/locales/messages.ca.xlf | 160 ++++++++++++----------- apps/client/src/locales/messages.de.xlf | 160 ++++++++++++----------- apps/client/src/locales/messages.es.xlf | 160 ++++++++++++----------- apps/client/src/locales/messages.fr.xlf | 160 ++++++++++++----------- apps/client/src/locales/messages.it.xlf | 160 ++++++++++++----------- apps/client/src/locales/messages.ko.xlf | 160 ++++++++++++----------- apps/client/src/locales/messages.nl.xlf | 166 +++++++++++++----------- apps/client/src/locales/messages.pl.xlf | 160 ++++++++++++----------- apps/client/src/locales/messages.pt.xlf | 160 ++++++++++++----------- apps/client/src/locales/messages.tr.xlf | 160 ++++++++++++----------- apps/client/src/locales/messages.uk.xlf | 160 ++++++++++++----------- apps/client/src/locales/messages.xlf | 159 ++++++++++++----------- apps/client/src/locales/messages.zh.xlf | 160 ++++++++++++----------- 13 files changed, 1094 insertions(+), 991 deletions(-) diff --git a/apps/client/src/locales/messages.ca.xlf b/apps/client/src/locales/messages.ca.xlf index d878a63bf..cf0ede34d 100644 --- a/apps/client/src/locales/messages.ca.xlf +++ b/apps/client/src/locales/messages.ca.xlf @@ -427,7 +427,7 @@
    apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 309 + 310 apps/client/src/app/components/admin-platform/admin-platform.component.html @@ -439,7 +439,7 @@ apps/client/src/app/components/admin-settings/admin-settings.component.html - 46 + 58 apps/client/src/app/components/admin-tag/admin-tag.component.html @@ -499,7 +499,7 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 316 + 317 apps/client/src/app/components/admin-market-data/create-asset-profile-dialog/create-asset-profile-dialog.html @@ -587,11 +587,11 @@ apps/client/src/app/components/admin-platform/admin-platform.component.html - 74 + 78 apps/client/src/app/components/admin-tag/admin-tag.component.html - 67 + 71 libs/ui/src/lib/accounts-table/accounts-table.component.html @@ -619,11 +619,11 @@ apps/client/src/app/components/admin-platform/admin-platform.component.html - 85 + 89 apps/client/src/app/components/admin-tag/admin-tag.component.html - 78 + 82 apps/client/src/app/components/user-detail-dialog/user-detail-dialog.html @@ -691,7 +691,7 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 448 + 451
    @@ -759,7 +759,7 @@ apps/client/src/app/components/admin-settings/admin-settings.component.html - 92 + 104 @@ -1011,7 +1011,7 @@ El preu de mercat actual és apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 706 + 722 @@ -1079,7 +1079,7 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 396 + 399 apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html @@ -1099,7 +1099,7 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 407 + 410 apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html @@ -1111,7 +1111,7 @@ Mapatge de Símbols apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 384 + 387 @@ -1127,7 +1127,7 @@ Configuració del Proveïdor de Dades apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 471 + 474 @@ -1135,7 +1135,7 @@ Prova apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 568 + 571 @@ -1143,11 +1143,11 @@ Url apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 419 + 422 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 550 + 553 apps/client/src/app/components/admin-platform/admin-platform.component.html @@ -1163,7 +1163,7 @@ Asset profile has been saved apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 578 + 594 @@ -1171,7 +1171,7 @@ Notes apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 432 + 435 apps/client/src/app/pages/accounts/create-or-update-account-dialog/create-or-update-account-dialog.html @@ -1319,7 +1319,7 @@ Recollida de Dades apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 587 + 594 apps/client/src/app/components/admin-overview/admin-overview.html @@ -1391,7 +1391,15 @@ Està segur que vol eliminar aquesta plataforma? apps/client/src/app/components/admin-platform/admin-platform.component.ts - 106 + 112 + + + + Explore + Explore + + apps/client/src/app/pages/resources/overview/resources-overview.component.html + 11 @@ -1415,7 +1423,7 @@ Current year apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 199 + 204 @@ -1431,7 +1439,7 @@ Plataformes apps/client/src/app/components/admin-settings/admin-settings.component.html - 195 + 212 @@ -1439,7 +1447,7 @@ Etiquetes apps/client/src/app/components/admin-settings/admin-settings.component.html - 201 + 218 libs/ui/src/lib/tags-selector/tags-selector.component.html @@ -1463,7 +1471,7 @@ Està segur que vol eliminar aquesta etiqueta? apps/client/src/app/components/admin-tag/admin-tag.component.ts - 103 + 109 @@ -1555,11 +1563,11 @@ Could not validate form apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 554 + 570 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 557 + 573 @@ -1607,7 +1615,7 @@ Punt de Referència apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 376 + 379 apps/client/src/app/components/benchmark-comparator/benchmark-comparator.component.ts @@ -1943,7 +1951,7 @@ Current week apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 191 + 196 @@ -2351,7 +2359,7 @@ YTD apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 199 + 204 libs/ui/src/lib/assistant/assistant.component.ts @@ -2363,7 +2371,7 @@ 1 any apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 203 + 208 libs/ui/src/lib/assistant/assistant.component.ts @@ -2375,7 +2383,7 @@ 5 anys apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 207 + 212 libs/ui/src/lib/assistant/assistant.component.ts @@ -2395,7 +2403,7 @@ Màx apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 211 + 216 libs/ui/src/lib/assistant/assistant.component.ts @@ -2567,7 +2575,7 @@ Include in apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 374 + 377 @@ -2623,7 +2631,7 @@ Localització apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 509 + 512 apps/client/src/app/components/user-account-settings/user-account-settings.html @@ -3223,11 +3231,11 @@ Could not parse scraper configuration apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 509 + 525 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 512 + 528 @@ -3271,7 +3279,7 @@ General apps/client/src/app/pages/faq/faq-page.component.ts - 49 + 41 @@ -3279,7 +3287,7 @@ Núvol apps/client/src/app/pages/faq/faq-page.component.ts - 54 + 46 libs/common/src/lib/routes/routes.ts @@ -3291,7 +3299,7 @@ Autoallotjament apps/client/src/app/pages/faq/faq-page.component.ts - 60 + 52 libs/common/src/lib/routes/routes.ts @@ -3492,7 +3500,7 @@ Mercats apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 378 + 381 apps/client/src/app/components/footer/footer.component.html @@ -4852,11 +4860,11 @@ Could not save asset profile apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 588 + 604 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 591 + 607 @@ -5433,7 +5441,7 @@ WTD apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 191 + 196 libs/ui/src/lib/assistant/assistant.component.ts @@ -5453,7 +5461,7 @@ MTD apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 195 + 200 libs/ui/src/lib/assistant/assistant.component.ts @@ -5473,7 +5481,7 @@ any apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 203 + 208 apps/client/src/app/pages/resources/personal-finance-tools/product-page.html @@ -5493,7 +5501,7 @@ anys apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 207 + 212 libs/ui/src/lib/assistant/assistant.component.ts @@ -5505,7 +5513,7 @@ Perfils d’actius apps/client/src/app/components/admin-settings/admin-settings.component.html - 106 + 123 libs/ui/src/lib/assistant/assistant.html @@ -5645,7 +5653,7 @@ Dipòsit libs/ui/src/lib/fire-calculator/fire-calculator.component.ts - 385 + 390 @@ -5661,7 +5669,7 @@ libs/ui/src/lib/fire-calculator/fire-calculator.component.ts - 395 + 400 libs/ui/src/lib/i18n.ts @@ -5673,7 +5681,7 @@ Estalvi libs/ui/src/lib/fire-calculator/fire-calculator.component.ts - 405 + 410 @@ -5745,7 +5753,7 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 326 + 327 apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html @@ -5777,7 +5785,7 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 342 + 343 apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html @@ -6293,7 +6301,7 @@ Vàlid fins a apps/client/src/app/components/admin-settings/admin-settings.component.html - 74 + 86 libs/ui/src/lib/membership-card/membership-card.component.html @@ -6673,7 +6681,7 @@ Error apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 697 + 713 @@ -6725,7 +6733,7 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 592 + 599 apps/client/src/app/components/admin-market-data/create-asset-profile-dialog/create-asset-profile-dialog.html @@ -6777,7 +6785,7 @@ Close apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 594 + 601 apps/client/src/app/components/admin-market-data/create-asset-profile-dialog/create-asset-profile-dialog.html @@ -7081,7 +7089,7 @@ Set API key apps/client/src/app/components/admin-settings/admin-settings.component.html - 171 + 188 @@ -7187,7 +7195,7 @@ of apps/client/src/app/components/admin-settings/admin-settings.component.html - 135 + 152 @@ -7195,7 +7203,7 @@ daily requests apps/client/src/app/components/admin-settings/admin-settings.component.html - 137 + 154 @@ -7203,7 +7211,7 @@ Remove API key apps/client/src/app/components/admin-settings/admin-settings.component.html - 161 + 178 @@ -7211,7 +7219,7 @@ Do you really want to delete the API key? apps/client/src/app/components/admin-settings/admin-settings.component.ts - 127 + 133 @@ -7303,7 +7311,7 @@ Save apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 603 + 610 apps/client/src/app/components/admin-market-data/create-asset-profile-dialog/create-asset-profile-dialog.html @@ -7379,7 +7387,7 @@ Please enter your Ghostfolio API key. apps/client/src/app/components/admin-settings/admin-settings.component.ts - 146 + 152 @@ -7411,7 +7419,7 @@ Lazy apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 225 + 230 @@ -7419,7 +7427,7 @@ Instant apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 229 + 234 @@ -7427,7 +7435,7 @@ Default Market Price apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 481 + 484 @@ -7435,7 +7443,7 @@ Mode apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 518 + 521 @@ -7443,7 +7451,7 @@ Selector apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 534 + 537 @@ -7451,7 +7459,7 @@ HTTP Request Headers apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 494 + 497 @@ -7459,7 +7467,7 @@ end of day apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 225 + 230 @@ -7467,7 +7475,7 @@ real-time apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 229 + 234 @@ -7708,7 +7716,7 @@ () is already in use. apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 633 + 649 @@ -7716,7 +7724,7 @@ An error occurred while updating to (). apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 641 + 657 @@ -8067,7 +8075,7 @@ Current month apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 195 + 200 @@ -8075,7 +8083,7 @@ new apps/client/src/app/components/admin-settings/admin-settings.component.html - 67 + 79 apps/client/src/app/pages/admin/admin-page.component.ts diff --git a/apps/client/src/locales/messages.de.xlf b/apps/client/src/locales/messages.de.xlf index 54c3f7de8..74365a176 100644 --- a/apps/client/src/locales/messages.de.xlf +++ b/apps/client/src/locales/messages.de.xlf @@ -106,7 +106,7 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 309 + 310 apps/client/src/app/components/admin-platform/admin-platform.component.html @@ -118,7 +118,7 @@ apps/client/src/app/components/admin-settings/admin-settings.component.html - 46 + 58 apps/client/src/app/components/admin-tag/admin-tag.component.html @@ -234,11 +234,11 @@ apps/client/src/app/components/admin-platform/admin-platform.component.html - 74 + 78 apps/client/src/app/components/admin-tag/admin-tag.component.html - 67 + 71 libs/ui/src/lib/accounts-table/accounts-table.component.html @@ -266,11 +266,11 @@ apps/client/src/app/components/admin-platform/admin-platform.component.html - 85 + 89 apps/client/src/app/components/admin-tag/admin-tag.component.html - 78 + 82 apps/client/src/app/components/user-detail-dialog/user-detail-dialog.html @@ -366,7 +366,7 @@ apps/client/src/app/components/admin-settings/admin-settings.component.html - 92 + 104 @@ -382,7 +382,7 @@ Anlageprofile apps/client/src/app/components/admin-settings/admin-settings.component.html - 106 + 123 libs/ui/src/lib/assistant/assistant.html @@ -398,7 +398,7 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 448 + 451 @@ -986,7 +986,7 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 396 + 399 apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html @@ -1006,7 +1006,7 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 407 + 410 apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html @@ -1018,7 +1018,7 @@ Tags apps/client/src/app/components/admin-settings/admin-settings.component.html - 201 + 218 libs/ui/src/lib/tags-selector/tags-selector.component.html @@ -1082,7 +1082,7 @@ YTD apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 199 + 204 libs/ui/src/lib/assistant/assistant.component.ts @@ -1094,7 +1094,7 @@ 1J apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 203 + 208 libs/ui/src/lib/assistant/assistant.component.ts @@ -1106,7 +1106,7 @@ 5J apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 207 + 212 libs/ui/src/lib/assistant/assistant.component.ts @@ -1126,7 +1126,7 @@ Max apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 211 + 216 libs/ui/src/lib/assistant/assistant.component.ts @@ -1298,7 +1298,7 @@ Lokalität apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 509 + 512 apps/client/src/app/components/user-account-settings/user-account-settings.html @@ -1438,7 +1438,7 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 316 + 317 apps/client/src/app/components/admin-market-data/create-asset-profile-dialog/create-asset-profile-dialog.html @@ -1714,7 +1714,7 @@ Märkte apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 378 + 381 apps/client/src/app/components/footer/footer.component.html @@ -1934,7 +1934,7 @@ Aktuelle Woche apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 191 + 196 @@ -2018,7 +2018,7 @@ Kommentar apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 432 + 435 apps/client/src/app/pages/accounts/create-or-update-account-dialog/create-or-update-account-dialog.html @@ -2546,7 +2546,7 @@ Einlage libs/ui/src/lib/fire-calculator/fire-calculator.component.ts - 385 + 390 @@ -2562,7 +2562,7 @@ libs/ui/src/lib/fire-calculator/fire-calculator.component.ts - 395 + 400 libs/ui/src/lib/i18n.ts @@ -2574,7 +2574,7 @@ Ersparnisse libs/ui/src/lib/fire-calculator/fire-calculator.component.ts - 405 + 410 @@ -2666,11 +2666,11 @@ Das Formular konnte nicht validiert werden apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 554 + 570 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 557 + 573 @@ -2686,7 +2686,7 @@ Benchmark apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 376 + 379 apps/client/src/app/components/benchmark-comparator/benchmark-comparator.component.ts @@ -2802,7 +2802,7 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 326 + 327 apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html @@ -3126,7 +3126,7 @@ Symbol Zuordnung apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 384 + 387 @@ -3190,7 +3190,7 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 342 + 343 apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html @@ -3318,7 +3318,7 @@ Gültig bis apps/client/src/app/components/admin-settings/admin-settings.component.html - 74 + 86 libs/ui/src/lib/membership-card/membership-card.component.html @@ -3638,11 +3638,11 @@ Das Anlageprofil konnte nicht gespeichert werden apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 588 + 604 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 591 + 607 @@ -3845,6 +3845,14 @@ 306 + + Explore + Explore + + apps/client/src/app/pages/resources/overview/resources-overview.component.html + 11 + + By Bis @@ -3866,7 +3874,7 @@ Aktuelles Jahr apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 199 + 204 @@ -3882,11 +3890,11 @@ Url apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 419 + 422 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 550 + 553 apps/client/src/app/components/admin-platform/admin-platform.component.html @@ -3902,7 +3910,7 @@ Das Anlageprofil wurde gespeichert apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 578 + 594 @@ -3910,7 +3918,7 @@ Möchtest du diese Plattform wirklich löschen? apps/client/src/app/components/admin-platform/admin-platform.component.ts - 106 + 112 @@ -3918,7 +3926,7 @@ Plattformen apps/client/src/app/components/admin-settings/admin-settings.component.html - 195 + 212 @@ -4262,7 +4270,7 @@ Scraper Konfiguration apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 471 + 474 @@ -4802,11 +4810,11 @@ Die Scraper Konfiguration konnte nicht geparsed werden apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 509 + 525 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 512 + 528 @@ -5500,7 +5508,7 @@ Möchtest du diesen Tag wirklich löschen? apps/client/src/app/components/admin-tag/admin-tag.component.ts - 103 + 109 @@ -5792,7 +5800,7 @@ Der aktuelle Marktpreis ist apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 706 + 722 @@ -5800,7 +5808,7 @@ Test apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 568 + 571 @@ -5960,7 +5968,7 @@ WTD apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 191 + 196 libs/ui/src/lib/assistant/assistant.component.ts @@ -5980,7 +5988,7 @@ MTD apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 195 + 200 libs/ui/src/lib/assistant/assistant.component.ts @@ -6028,7 +6036,7 @@ Jahr apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 203 + 208 apps/client/src/app/pages/resources/personal-finance-tools/product-page.html @@ -6048,7 +6056,7 @@ Jahre apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 207 + 212 libs/ui/src/lib/assistant/assistant.component.ts @@ -6068,7 +6076,7 @@ Finanzmarktdaten synchronisieren apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 587 + 594 apps/client/src/app/components/admin-overview/admin-overview.html @@ -6080,7 +6088,7 @@ Allgemein apps/client/src/app/pages/faq/faq-page.component.ts - 49 + 41 @@ -6088,7 +6096,7 @@ Cloud apps/client/src/app/pages/faq/faq-page.component.ts - 54 + 46 libs/common/src/lib/routes/routes.ts @@ -6100,7 +6108,7 @@ Self-Hosting apps/client/src/app/pages/faq/faq-page.component.ts - 60 + 52 libs/common/src/lib/routes/routes.ts @@ -6293,7 +6301,7 @@ Berücksichtigen in apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 374 + 377 @@ -6697,7 +6705,7 @@ Fehler apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 697 + 713 @@ -6749,7 +6757,7 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 592 + 599 apps/client/src/app/components/admin-market-data/create-asset-profile-dialog/create-asset-profile-dialog.html @@ -6801,7 +6809,7 @@ Schliessen apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 594 + 601 apps/client/src/app/components/admin-market-data/create-asset-profile-dialog/create-asset-profile-dialog.html @@ -7105,7 +7113,7 @@ API-Schlüssel setzen apps/client/src/app/components/admin-settings/admin-settings.component.html - 171 + 188 @@ -7211,7 +7219,7 @@ von apps/client/src/app/components/admin-settings/admin-settings.component.html - 135 + 152 @@ -7219,7 +7227,7 @@ täglichen Anfragen apps/client/src/app/components/admin-settings/admin-settings.component.html - 137 + 154 @@ -7227,7 +7235,7 @@ API-Schlüssel löschen apps/client/src/app/components/admin-settings/admin-settings.component.html - 161 + 178 @@ -7235,7 +7243,7 @@ Möchtest du den API-Schlüssel wirklich löschen? apps/client/src/app/components/admin-settings/admin-settings.component.ts - 127 + 133 @@ -7327,7 +7335,7 @@ Speichern apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 603 + 610 apps/client/src/app/components/admin-market-data/create-asset-profile-dialog/create-asset-profile-dialog.html @@ -7403,7 +7411,7 @@ Bitte gebe deinen Ghostfolio API-Schlüssel ein. apps/client/src/app/components/admin-settings/admin-settings.component.ts - 146 + 152 @@ -7435,7 +7443,7 @@ Verzögert apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 225 + 230 @@ -7443,7 +7451,7 @@ Sofort apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 229 + 234 @@ -7451,7 +7459,7 @@ Standardmarktpreis apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 481 + 484 @@ -7459,7 +7467,7 @@ Modus apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 518 + 521 @@ -7467,7 +7475,7 @@ Selektor apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 534 + 537 @@ -7475,7 +7483,7 @@ HTTP Request-Headers apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 494 + 497 @@ -7483,7 +7491,7 @@ Tagesende apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 225 + 230 @@ -7491,7 +7499,7 @@ in Echtzeit apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 229 + 234 @@ -7732,7 +7740,7 @@ () wird bereits verwendet. apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 633 + 649 @@ -7740,7 +7748,7 @@ Bei der Änderung zu () ist ein Fehler aufgetreten. apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 641 + 657 @@ -8067,7 +8075,7 @@ Aktueller Monat apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 195 + 200 @@ -8075,7 +8083,7 @@ neu apps/client/src/app/components/admin-settings/admin-settings.component.html - 67 + 79 apps/client/src/app/pages/admin/admin-page.component.ts diff --git a/apps/client/src/locales/messages.es.xlf b/apps/client/src/locales/messages.es.xlf index ba5a38d67..a904cbae8 100644 --- a/apps/client/src/locales/messages.es.xlf +++ b/apps/client/src/locales/messages.es.xlf @@ -107,7 +107,7 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 309 + 310 apps/client/src/app/components/admin-platform/admin-platform.component.html @@ -119,7 +119,7 @@ apps/client/src/app/components/admin-settings/admin-settings.component.html - 46 + 58 apps/client/src/app/components/admin-tag/admin-tag.component.html @@ -235,11 +235,11 @@ apps/client/src/app/components/admin-platform/admin-platform.component.html - 74 + 78 apps/client/src/app/components/admin-tag/admin-tag.component.html - 67 + 71 libs/ui/src/lib/accounts-table/accounts-table.component.html @@ -267,11 +267,11 @@ apps/client/src/app/components/admin-platform/admin-platform.component.html - 85 + 89 apps/client/src/app/components/admin-tag/admin-tag.component.html - 78 + 82 apps/client/src/app/components/user-detail-dialog/user-detail-dialog.html @@ -367,7 +367,7 @@ apps/client/src/app/components/admin-settings/admin-settings.component.html - 92 + 104 @@ -383,7 +383,7 @@ Perfiles de activos. apps/client/src/app/components/admin-settings/admin-settings.component.html - 106 + 123 libs/ui/src/lib/assistant/assistant.html @@ -399,7 +399,7 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 448 + 451 @@ -971,7 +971,7 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 396 + 399 apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html @@ -991,7 +991,7 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 407 + 410 apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html @@ -1003,7 +1003,7 @@ Etiquetas apps/client/src/app/components/admin-settings/admin-settings.component.html - 201 + 218 libs/ui/src/lib/tags-selector/tags-selector.component.html @@ -1067,7 +1067,7 @@ Desde principio de año apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 199 + 204 libs/ui/src/lib/assistant/assistant.component.ts @@ -1079,7 +1079,7 @@ 1 año apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 203 + 208 libs/ui/src/lib/assistant/assistant.component.ts @@ -1091,7 +1091,7 @@ 5 años apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 207 + 212 libs/ui/src/lib/assistant/assistant.component.ts @@ -1111,7 +1111,7 @@ Máximo apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 211 + 216 libs/ui/src/lib/assistant/assistant.component.ts @@ -1283,7 +1283,7 @@ Ubicación apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 509 + 512 apps/client/src/app/components/user-account-settings/user-account-settings.html @@ -1423,7 +1423,7 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 316 + 317 apps/client/src/app/components/admin-market-data/create-asset-profile-dialog/create-asset-profile-dialog.html @@ -1699,7 +1699,7 @@ Mercados apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 378 + 381 apps/client/src/app/components/footer/footer.component.html @@ -1919,7 +1919,7 @@ Semana actual apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 191 + 196 @@ -2003,7 +2003,7 @@ Nota apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 432 + 435 apps/client/src/app/pages/accounts/create-or-update-account-dialog/create-or-update-account-dialog.html @@ -2515,7 +2515,7 @@ Ahorros libs/ui/src/lib/fire-calculator/fire-calculator.component.ts - 405 + 410 @@ -2531,7 +2531,7 @@ libs/ui/src/lib/fire-calculator/fire-calculator.component.ts - 395 + 400 libs/ui/src/lib/i18n.ts @@ -2551,7 +2551,7 @@ Depósito libs/ui/src/lib/fire-calculator/fire-calculator.component.ts - 385 + 390 @@ -2651,7 +2651,7 @@ Benchmark apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 376 + 379 apps/client/src/app/components/benchmark-comparator/benchmark-comparator.component.ts @@ -2663,11 +2663,11 @@ No se pudo validar el formulario apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 554 + 570 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 557 + 573 @@ -2787,7 +2787,7 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 326 + 327 apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html @@ -3111,7 +3111,7 @@ Mapeo de símbolos apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 384 + 387 @@ -3175,7 +3175,7 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 342 + 343 apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html @@ -3303,7 +3303,7 @@ Válido hasta apps/client/src/app/components/admin-settings/admin-settings.component.html - 74 + 86 libs/ui/src/lib/membership-card/membership-card.component.html @@ -3623,11 +3623,11 @@ No se pudo guardar el perfil del activo apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 588 + 604 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 591 + 607 @@ -3822,6 +3822,14 @@ 306 + + Explore + Explore + + apps/client/src/app/pages/resources/overview/resources-overview.component.html + 11 + + By Por @@ -3843,7 +3851,7 @@ Año actual apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 199 + 204 @@ -3859,11 +3867,11 @@ ¿La URL? apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 419 + 422 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 550 + 553 apps/client/src/app/components/admin-platform/admin-platform.component.html @@ -3879,7 +3887,7 @@ El perfil del activo ha sido guardado apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 578 + 594 @@ -3887,7 +3895,7 @@ ¿Realmente deseas eliminar esta plataforma? apps/client/src/app/components/admin-platform/admin-platform.component.ts - 106 + 112 @@ -3895,7 +3903,7 @@ Plataformas apps/client/src/app/components/admin-settings/admin-settings.component.html - 195 + 212 @@ -4239,7 +4247,7 @@ Configuración del scraper apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 471 + 474 @@ -4779,11 +4787,11 @@ No se pudo analizar la configuración del scraper apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 509 + 525 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 512 + 528 @@ -5477,7 +5485,7 @@ ¿Realmente deseas eliminar esta etiqueta? apps/client/src/app/components/admin-tag/admin-tag.component.ts - 103 + 109 @@ -5769,7 +5777,7 @@ El precio actual de mercado es apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 706 + 722 @@ -5777,7 +5785,7 @@ Prueba apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 568 + 571 @@ -5937,7 +5945,7 @@ WTD apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 191 + 196 libs/ui/src/lib/assistant/assistant.component.ts @@ -5957,7 +5965,7 @@ MTD apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 195 + 200 libs/ui/src/lib/assistant/assistant.component.ts @@ -6005,7 +6013,7 @@ año apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 203 + 208 apps/client/src/app/pages/resources/personal-finance-tools/product-page.html @@ -6025,7 +6033,7 @@ años apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 207 + 212 libs/ui/src/lib/assistant/assistant.component.ts @@ -6045,7 +6053,7 @@ Recopilación de datos apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 587 + 594 apps/client/src/app/components/admin-overview/admin-overview.html @@ -6057,7 +6065,7 @@ General apps/client/src/app/pages/faq/faq-page.component.ts - 49 + 41 @@ -6065,7 +6073,7 @@ Nube apps/client/src/app/pages/faq/faq-page.component.ts - 54 + 46 libs/common/src/lib/routes/routes.ts @@ -6077,7 +6085,7 @@ Autoalojamiento apps/client/src/app/pages/faq/faq-page.component.ts - 60 + 52 libs/common/src/lib/routes/routes.ts @@ -6270,7 +6278,7 @@ Incluir en apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 374 + 377 @@ -6674,7 +6682,7 @@ Error apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 697 + 713 @@ -6726,7 +6734,7 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 592 + 599 apps/client/src/app/components/admin-market-data/create-asset-profile-dialog/create-asset-profile-dialog.html @@ -6778,7 +6786,7 @@ Cerrar apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 594 + 601 apps/client/src/app/components/admin-market-data/create-asset-profile-dialog/create-asset-profile-dialog.html @@ -7082,7 +7090,7 @@ Configurar clave API apps/client/src/app/components/admin-settings/admin-settings.component.html - 171 + 188 @@ -7188,7 +7196,7 @@ de apps/client/src/app/components/admin-settings/admin-settings.component.html - 135 + 152 @@ -7196,7 +7204,7 @@ solicitudes diarias apps/client/src/app/components/admin-settings/admin-settings.component.html - 137 + 154 @@ -7204,7 +7212,7 @@ Eliminar clave API apps/client/src/app/components/admin-settings/admin-settings.component.html - 161 + 178 @@ -7212,7 +7220,7 @@ ¿Realmente deseas eliminar la clave API? apps/client/src/app/components/admin-settings/admin-settings.component.ts - 127 + 133 @@ -7304,7 +7312,7 @@ Ahorrar apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 603 + 610 apps/client/src/app/components/admin-market-data/create-asset-profile-dialog/create-asset-profile-dialog.html @@ -7380,7 +7388,7 @@ Por favor, ingresa tu clave API de Ghostfolio. apps/client/src/app/components/admin-settings/admin-settings.component.ts - 146 + 152 @@ -7412,7 +7420,7 @@ Perezoso apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 225 + 230 @@ -7420,7 +7428,7 @@ Instantáneo apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 229 + 234 @@ -7428,7 +7436,7 @@ Precio de mercado por defecto apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 481 + 484 @@ -7436,7 +7444,7 @@ Modo apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 518 + 521 @@ -7444,7 +7452,7 @@ Selector apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 534 + 537 @@ -7452,7 +7460,7 @@ Encabezados de solicitud HTTP apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 494 + 497 @@ -7460,7 +7468,7 @@ final del día apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 225 + 230 @@ -7468,7 +7476,7 @@ en tiempo real apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 229 + 234 @@ -7709,7 +7717,7 @@ () ya está en uso. apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 633 + 649 @@ -7717,7 +7725,7 @@ Ocurrió un error al actualizar a (). apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 641 + 657 @@ -8068,7 +8076,7 @@ Mes actual apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 195 + 200 @@ -8076,7 +8084,7 @@ nuevo apps/client/src/app/components/admin-settings/admin-settings.component.html - 67 + 79 apps/client/src/app/pages/admin/admin-page.component.ts diff --git a/apps/client/src/locales/messages.fr.xlf b/apps/client/src/locales/messages.fr.xlf index f343cb2ad..f01a3a505 100644 --- a/apps/client/src/locales/messages.fr.xlf +++ b/apps/client/src/locales/messages.fr.xlf @@ -114,7 +114,7 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 309 + 310 apps/client/src/app/components/admin-platform/admin-platform.component.html @@ -126,7 +126,7 @@ apps/client/src/app/components/admin-settings/admin-settings.component.html - 46 + 58 apps/client/src/app/components/admin-tag/admin-tag.component.html @@ -186,7 +186,7 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 316 + 317 apps/client/src/app/components/admin-market-data/create-asset-profile-dialog/create-asset-profile-dialog.html @@ -290,11 +290,11 @@ apps/client/src/app/components/admin-platform/admin-platform.component.html - 74 + 78 apps/client/src/app/components/admin-tag/admin-tag.component.html - 67 + 71 libs/ui/src/lib/accounts-table/accounts-table.component.html @@ -322,11 +322,11 @@ apps/client/src/app/components/admin-platform/admin-platform.component.html - 85 + 89 apps/client/src/app/components/admin-tag/admin-tag.component.html - 78 + 82 apps/client/src/app/components/user-detail-dialog/user-detail-dialog.html @@ -414,7 +414,7 @@ apps/client/src/app/components/admin-settings/admin-settings.component.html - 92 + 104 @@ -438,7 +438,7 @@ Profils d’Actifs apps/client/src/app/components/admin-settings/admin-settings.component.html - 106 + 123 libs/ui/src/lib/assistant/assistant.html @@ -454,7 +454,7 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 448 + 451 @@ -650,7 +650,7 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 396 + 399 apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html @@ -670,7 +670,7 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 407 + 410 apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html @@ -682,7 +682,7 @@ Équivalence de Symboles apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 384 + 387 @@ -690,7 +690,7 @@ Note apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 432 + 435 apps/client/src/app/pages/accounts/create-or-update-account-dialog/create-or-update-account-dialog.html @@ -762,7 +762,7 @@ Étiquettes apps/client/src/app/components/admin-settings/admin-settings.component.html - 201 + 218 libs/ui/src/lib/tags-selector/tags-selector.component.html @@ -898,11 +898,11 @@ Could not validate form apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 554 + 570 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 557 + 573 @@ -942,7 +942,7 @@ Référence apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 376 + 379 apps/client/src/app/components/benchmark-comparator/benchmark-comparator.component.ts @@ -1314,7 +1314,7 @@ CDA apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 199 + 204 libs/ui/src/lib/assistant/assistant.component.ts @@ -1326,7 +1326,7 @@ 1A apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 203 + 208 libs/ui/src/lib/assistant/assistant.component.ts @@ -1338,7 +1338,7 @@ 5A apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 207 + 212 libs/ui/src/lib/assistant/assistant.component.ts @@ -1358,7 +1358,7 @@ Max apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 211 + 216 libs/ui/src/lib/assistant/assistant.component.ts @@ -1586,7 +1586,7 @@ Paramètres régionaux apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 509 + 512 apps/client/src/app/components/user-account-settings/user-account-settings.html @@ -1994,7 +1994,7 @@ Marchés apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 378 + 381 apps/client/src/app/components/footer/footer.component.html @@ -2098,7 +2098,7 @@ Current week apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 191 + 196 @@ -2438,7 +2438,7 @@ Dépôt libs/ui/src/lib/fire-calculator/fire-calculator.component.ts - 385 + 390 @@ -2858,7 +2858,7 @@ libs/ui/src/lib/fire-calculator/fire-calculator.component.ts - 395 + 400 libs/ui/src/lib/i18n.ts @@ -2870,7 +2870,7 @@ Épargne libs/ui/src/lib/fire-calculator/fire-calculator.component.ts - 405 + 410 @@ -2934,7 +2934,7 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 326 + 327 apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html @@ -2966,7 +2966,7 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 342 + 343 apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html @@ -3302,7 +3302,7 @@ Valide jusqu’au apps/client/src/app/components/admin-settings/admin-settings.component.html - 74 + 86 libs/ui/src/lib/membership-card/membership-card.component.html @@ -3622,11 +3622,11 @@ Could not save asset profile apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 588 + 604 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 591 + 607 @@ -3821,6 +3821,14 @@ 306 + + Explore + Explore + + apps/client/src/app/pages/resources/overview/resources-overview.component.html + 11 + + By By @@ -3842,7 +3850,7 @@ Current year apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 199 + 204 @@ -3858,11 +3866,11 @@ Lien apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 419 + 422 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 550 + 553 apps/client/src/app/components/admin-platform/admin-platform.component.html @@ -3878,7 +3886,7 @@ Asset profile has been saved apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 578 + 594 @@ -3886,7 +3894,7 @@ Voulez-vous vraiment supprimer cette plateforme ? apps/client/src/app/components/admin-platform/admin-platform.component.ts - 106 + 112 @@ -3894,7 +3902,7 @@ Platformes apps/client/src/app/components/admin-settings/admin-settings.component.html - 195 + 212 @@ -4238,7 +4246,7 @@ Configuration du Scraper apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 471 + 474 @@ -4778,11 +4786,11 @@ Could not parse scraper configuration apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 509 + 525 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 512 + 528 @@ -5476,7 +5484,7 @@ Confirmez la suppression de ce tag ? apps/client/src/app/components/admin-tag/admin-tag.component.ts - 103 + 109 @@ -5768,7 +5776,7 @@ Le prix actuel du marché est apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 706 + 722 @@ -5776,7 +5784,7 @@ Test apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 568 + 571 @@ -5936,7 +5944,7 @@ WTD apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 191 + 196 libs/ui/src/lib/assistant/assistant.component.ts @@ -5956,7 +5964,7 @@ MTD apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 195 + 200 libs/ui/src/lib/assistant/assistant.component.ts @@ -6004,7 +6012,7 @@ année apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 203 + 208 apps/client/src/app/pages/resources/personal-finance-tools/product-page.html @@ -6024,7 +6032,7 @@ années apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 207 + 212 libs/ui/src/lib/assistant/assistant.component.ts @@ -6044,7 +6052,7 @@ Collecter les données apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 587 + 594 apps/client/src/app/components/admin-overview/admin-overview.html @@ -6056,7 +6064,7 @@ Général apps/client/src/app/pages/faq/faq-page.component.ts - 49 + 41 @@ -6064,7 +6072,7 @@ Cloud apps/client/src/app/pages/faq/faq-page.component.ts - 54 + 46 libs/common/src/lib/routes/routes.ts @@ -6076,7 +6084,7 @@ Self-Hosting apps/client/src/app/pages/faq/faq-page.component.ts - 60 + 52 libs/common/src/lib/routes/routes.ts @@ -6269,7 +6277,7 @@ Include in apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 374 + 377 @@ -6673,7 +6681,7 @@ Erreur apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 697 + 713 @@ -6725,7 +6733,7 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 592 + 599 apps/client/src/app/components/admin-market-data/create-asset-profile-dialog/create-asset-profile-dialog.html @@ -6777,7 +6785,7 @@ Fermer apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 594 + 601 apps/client/src/app/components/admin-market-data/create-asset-profile-dialog/create-asset-profile-dialog.html @@ -7081,7 +7089,7 @@ Définir clé API apps/client/src/app/components/admin-settings/admin-settings.component.html - 171 + 188 @@ -7187,7 +7195,7 @@ sur apps/client/src/app/components/admin-settings/admin-settings.component.html - 135 + 152 @@ -7195,7 +7203,7 @@ requêtes journalières apps/client/src/app/components/admin-settings/admin-settings.component.html - 137 + 154 @@ -7203,7 +7211,7 @@ Retirer la clé API apps/client/src/app/components/admin-settings/admin-settings.component.html - 161 + 178 @@ -7211,7 +7219,7 @@ Voulez-vous vraiment supprimer la clé API? apps/client/src/app/components/admin-settings/admin-settings.component.ts - 127 + 133 @@ -7303,7 +7311,7 @@ Sauvegarder apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 603 + 610 apps/client/src/app/components/admin-market-data/create-asset-profile-dialog/create-asset-profile-dialog.html @@ -7379,7 +7387,7 @@ Veuillez saisir votre clé API Ghostfolio. apps/client/src/app/components/admin-settings/admin-settings.component.ts - 146 + 152 @@ -7411,7 +7419,7 @@ Paresseux apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 225 + 230 @@ -7419,7 +7427,7 @@ Instantané apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 229 + 234 @@ -7427,7 +7435,7 @@ Prix du marché par défaut apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 481 + 484 @@ -7435,7 +7443,7 @@ Mode apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 518 + 521 @@ -7443,7 +7451,7 @@ Selecteur apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 534 + 537 @@ -7451,7 +7459,7 @@ En-têtes de requête HTTP apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 494 + 497 @@ -7459,7 +7467,7 @@ fin de journée apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 225 + 230 @@ -7467,7 +7475,7 @@ temps réel apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 229 + 234 @@ -7708,7 +7716,7 @@ () est déjà utilisé. apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 633 + 649 @@ -7716,7 +7724,7 @@ Une erreur s’est produite lors de la mise à jour vers (). apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 641 + 657 @@ -8067,7 +8075,7 @@ Current month apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 195 + 200 @@ -8075,7 +8083,7 @@ new apps/client/src/app/components/admin-settings/admin-settings.component.html - 67 + 79 apps/client/src/app/pages/admin/admin-page.component.ts diff --git a/apps/client/src/locales/messages.it.xlf b/apps/client/src/locales/messages.it.xlf index 20bfd1b33..5f06af0b4 100644 --- a/apps/client/src/locales/messages.it.xlf +++ b/apps/client/src/locales/messages.it.xlf @@ -107,7 +107,7 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 309 + 310 apps/client/src/app/components/admin-platform/admin-platform.component.html @@ -119,7 +119,7 @@ apps/client/src/app/components/admin-settings/admin-settings.component.html - 46 + 58 apps/client/src/app/components/admin-tag/admin-tag.component.html @@ -235,11 +235,11 @@ apps/client/src/app/components/admin-platform/admin-platform.component.html - 74 + 78 apps/client/src/app/components/admin-tag/admin-tag.component.html - 67 + 71 libs/ui/src/lib/accounts-table/accounts-table.component.html @@ -267,11 +267,11 @@ apps/client/src/app/components/admin-platform/admin-platform.component.html - 85 + 89 apps/client/src/app/components/admin-tag/admin-tag.component.html - 78 + 82 apps/client/src/app/components/user-detail-dialog/user-detail-dialog.html @@ -367,7 +367,7 @@ apps/client/src/app/components/admin-settings/admin-settings.component.html - 92 + 104 @@ -383,7 +383,7 @@ Profilo dell’asset apps/client/src/app/components/admin-settings/admin-settings.component.html - 106 + 123 libs/ui/src/lib/assistant/assistant.html @@ -399,7 +399,7 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 448 + 451 @@ -971,7 +971,7 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 396 + 399 apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html @@ -991,7 +991,7 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 407 + 410 apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html @@ -1003,7 +1003,7 @@ Tag apps/client/src/app/components/admin-settings/admin-settings.component.html - 201 + 218 libs/ui/src/lib/tags-selector/tags-selector.component.html @@ -1067,7 +1067,7 @@ anno corrente apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 199 + 204 libs/ui/src/lib/assistant/assistant.component.ts @@ -1079,7 +1079,7 @@ 1 anno apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 203 + 208 libs/ui/src/lib/assistant/assistant.component.ts @@ -1091,7 +1091,7 @@ 5 anni apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 207 + 212 libs/ui/src/lib/assistant/assistant.component.ts @@ -1111,7 +1111,7 @@ Massimo apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 211 + 216 libs/ui/src/lib/assistant/assistant.component.ts @@ -1283,7 +1283,7 @@ Locale apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 509 + 512 apps/client/src/app/components/user-account-settings/user-account-settings.html @@ -1423,7 +1423,7 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 316 + 317 apps/client/src/app/components/admin-market-data/create-asset-profile-dialog/create-asset-profile-dialog.html @@ -1699,7 +1699,7 @@ Mercati apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 378 + 381 apps/client/src/app/components/footer/footer.component.html @@ -1919,7 +1919,7 @@ Current week apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 191 + 196 @@ -2003,7 +2003,7 @@ Nota apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 432 + 435 apps/client/src/app/pages/accounts/create-or-update-account-dialog/create-or-update-account-dialog.html @@ -2515,7 +2515,7 @@ Risparmio libs/ui/src/lib/fire-calculator/fire-calculator.component.ts - 405 + 410 @@ -2531,7 +2531,7 @@ libs/ui/src/lib/fire-calculator/fire-calculator.component.ts - 395 + 400 libs/ui/src/lib/i18n.ts @@ -2551,7 +2551,7 @@ Deposito libs/ui/src/lib/fire-calculator/fire-calculator.component.ts - 385 + 390 @@ -2651,7 +2651,7 @@ Benchmark apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 376 + 379 apps/client/src/app/components/benchmark-comparator/benchmark-comparator.component.ts @@ -2663,11 +2663,11 @@ Could not validate form apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 554 + 570 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 557 + 573 @@ -2787,7 +2787,7 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 326 + 327 apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html @@ -3111,7 +3111,7 @@ Mappatura dei simboli apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 384 + 387 @@ -3175,7 +3175,7 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 342 + 343 apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html @@ -3303,7 +3303,7 @@ Valido fino a apps/client/src/app/components/admin-settings/admin-settings.component.html - 74 + 86 libs/ui/src/lib/membership-card/membership-card.component.html @@ -3623,11 +3623,11 @@ Could not save asset profile apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 588 + 604 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 591 + 607 @@ -3822,6 +3822,14 @@ 306 + + Explore + Explore + + apps/client/src/app/pages/resources/overview/resources-overview.component.html + 11 + + By By @@ -3843,7 +3851,7 @@ Current year apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 199 + 204 @@ -3859,11 +3867,11 @@ Url apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 419 + 422 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 550 + 553 apps/client/src/app/components/admin-platform/admin-platform.component.html @@ -3879,7 +3887,7 @@ Asset profile has been saved apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 578 + 594 @@ -3887,7 +3895,7 @@ Vuoi davvero eliminare questa piattaforma? apps/client/src/app/components/admin-platform/admin-platform.component.ts - 106 + 112 @@ -3895,7 +3903,7 @@ Piattaforme apps/client/src/app/components/admin-settings/admin-settings.component.html - 195 + 212 @@ -4239,7 +4247,7 @@ Configurazione dello scraper apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 471 + 474 @@ -4779,11 +4787,11 @@ Could not parse scraper configuration apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 509 + 525 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 512 + 528 @@ -5477,7 +5485,7 @@ Sei sicuro di voler eliminare questo tag? apps/client/src/app/components/admin-tag/admin-tag.component.ts - 103 + 109 @@ -5769,7 +5777,7 @@ L’attuale prezzo di mercato è apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 706 + 722 @@ -5777,7 +5785,7 @@ Prova apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 568 + 571 @@ -5937,7 +5945,7 @@ Settimana corrente apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 191 + 196 libs/ui/src/lib/assistant/assistant.component.ts @@ -5957,7 +5965,7 @@ Mese corrente apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 195 + 200 libs/ui/src/lib/assistant/assistant.component.ts @@ -6005,7 +6013,7 @@ anno apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 203 + 208 apps/client/src/app/pages/resources/personal-finance-tools/product-page.html @@ -6025,7 +6033,7 @@ anni apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 207 + 212 libs/ui/src/lib/assistant/assistant.component.ts @@ -6045,7 +6053,7 @@ Raccolta Dati apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 587 + 594 apps/client/src/app/components/admin-overview/admin-overview.html @@ -6057,7 +6065,7 @@ Generale apps/client/src/app/pages/faq/faq-page.component.ts - 49 + 41 @@ -6065,7 +6073,7 @@ Cloud apps/client/src/app/pages/faq/faq-page.component.ts - 54 + 46 libs/common/src/lib/routes/routes.ts @@ -6077,7 +6085,7 @@ Self-Hosting apps/client/src/app/pages/faq/faq-page.component.ts - 60 + 52 libs/common/src/lib/routes/routes.ts @@ -6270,7 +6278,7 @@ Include in apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 374 + 377 @@ -6674,7 +6682,7 @@ Errore apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 697 + 713 @@ -6726,7 +6734,7 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 592 + 599 apps/client/src/app/components/admin-market-data/create-asset-profile-dialog/create-asset-profile-dialog.html @@ -6778,7 +6786,7 @@ Chiudi apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 594 + 601 apps/client/src/app/components/admin-market-data/create-asset-profile-dialog/create-asset-profile-dialog.html @@ -7082,7 +7090,7 @@ Imposta API Key apps/client/src/app/components/admin-settings/admin-settings.component.html - 171 + 188 @@ -7188,7 +7196,7 @@ di apps/client/src/app/components/admin-settings/admin-settings.component.html - 135 + 152 @@ -7196,7 +7204,7 @@ richieste giornaliere apps/client/src/app/components/admin-settings/admin-settings.component.html - 137 + 154 @@ -7204,7 +7212,7 @@ Rimuovi API key apps/client/src/app/components/admin-settings/admin-settings.component.html - 161 + 178 @@ -7212,7 +7220,7 @@ Vuoi davvero eliminare l’API key? apps/client/src/app/components/admin-settings/admin-settings.component.ts - 127 + 133 @@ -7304,7 +7312,7 @@ Salva apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 603 + 610 apps/client/src/app/components/admin-market-data/create-asset-profile-dialog/create-asset-profile-dialog.html @@ -7380,7 +7388,7 @@ Inserisci la tua API key di Ghostfolio. apps/client/src/app/components/admin-settings/admin-settings.component.ts - 146 + 152 @@ -7412,7 +7420,7 @@ Pigro apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 225 + 230 @@ -7420,7 +7428,7 @@ Istantaneo apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 229 + 234 @@ -7428,7 +7436,7 @@ Prezzo di mercato predefinito apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 481 + 484 @@ -7436,7 +7444,7 @@ Modalità apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 518 + 521 @@ -7444,7 +7452,7 @@ Selettore apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 534 + 537 @@ -7452,7 +7460,7 @@ Intestazioni della richiesta HTTP apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 494 + 497 @@ -7460,7 +7468,7 @@ fine giornata apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 225 + 230 @@ -7468,7 +7476,7 @@ in tempo reale apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 229 + 234 @@ -7709,7 +7717,7 @@ () e gia in uso. apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 633 + 649 @@ -7717,7 +7725,7 @@ Si è verificato un errore durante l’aggiornamento di (). apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 641 + 657 @@ -8068,7 +8076,7 @@ Current month apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 195 + 200 @@ -8076,7 +8084,7 @@ nuovo apps/client/src/app/components/admin-settings/admin-settings.component.html - 67 + 79 apps/client/src/app/pages/admin/admin-page.component.ts diff --git a/apps/client/src/locales/messages.ko.xlf b/apps/client/src/locales/messages.ko.xlf index 9b7c4192e..bb361b515 100644 --- a/apps/client/src/locales/messages.ko.xlf +++ b/apps/client/src/locales/messages.ko.xlf @@ -360,7 +360,7 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 309 + 310 apps/client/src/app/components/admin-platform/admin-platform.component.html @@ -372,7 +372,7 @@ apps/client/src/app/components/admin-settings/admin-settings.component.html - 46 + 58 apps/client/src/app/components/admin-tag/admin-tag.component.html @@ -432,7 +432,7 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 316 + 317 apps/client/src/app/components/admin-market-data/create-asset-profile-dialog/create-asset-profile-dialog.html @@ -520,11 +520,11 @@ apps/client/src/app/components/admin-platform/admin-platform.component.html - 74 + 78 apps/client/src/app/components/admin-tag/admin-tag.component.html - 67 + 71 libs/ui/src/lib/accounts-table/accounts-table.component.html @@ -552,11 +552,11 @@ apps/client/src/app/components/admin-platform/admin-platform.component.html - 85 + 89 apps/client/src/app/components/admin-tag/admin-tag.component.html - 78 + 82 apps/client/src/app/components/user-detail-dialog/user-detail-dialog.html @@ -604,7 +604,7 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 448 + 451 @@ -664,7 +664,7 @@ apps/client/src/app/components/admin-settings/admin-settings.component.html - 92 + 104 @@ -960,7 +960,7 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 396 + 399 apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html @@ -980,7 +980,7 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 407 + 410 apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html @@ -992,7 +992,7 @@ 심볼 매핑 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 384 + 387 @@ -1008,7 +1008,7 @@ 스크래퍼 설정 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 471 + 474 @@ -1016,7 +1016,7 @@ 메모 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 432 + 435 apps/client/src/app/pages/accounts/create-or-update-account-dialog/create-or-update-account-dialog.html @@ -1224,11 +1224,11 @@ 링크 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 419 + 422 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 550 + 553 apps/client/src/app/components/admin-platform/admin-platform.component.html @@ -1244,7 +1244,7 @@ Asset profile has been saved apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 578 + 594 @@ -1252,7 +1252,15 @@ 정말로 이 플랫폼을 삭제하시겠습니까? apps/client/src/app/components/admin-platform/admin-platform.component.ts - 106 + 112 + + + + Explore + Explore + + apps/client/src/app/pages/resources/overview/resources-overview.component.html + 11 @@ -1276,7 +1284,7 @@ 올해 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 199 + 204 @@ -1292,7 +1300,7 @@ 플랫폼 apps/client/src/app/components/admin-settings/admin-settings.component.html - 195 + 212 @@ -1300,7 +1308,7 @@ 태그 apps/client/src/app/components/admin-settings/admin-settings.component.html - 201 + 218 libs/ui/src/lib/tags-selector/tags-selector.component.html @@ -1324,7 +1332,7 @@ 이 태그를 정말로 삭제하시겠습니까? apps/client/src/app/components/admin-tag/admin-tag.component.ts - 103 + 109 @@ -1416,11 +1424,11 @@ Could not validate form apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 554 + 570 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 557 + 573 @@ -1468,7 +1476,7 @@ 기준 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 376 + 379 apps/client/src/app/components/benchmark-comparator/benchmark-comparator.component.ts @@ -1672,7 +1680,7 @@ 이번주 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 191 + 196 @@ -2140,7 +2148,7 @@ 연초 대비 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 199 + 204 libs/ui/src/lib/assistant/assistant.component.ts @@ -2152,7 +2160,7 @@ 1년 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 203 + 208 libs/ui/src/lib/assistant/assistant.component.ts @@ -2164,7 +2172,7 @@ 5년 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 207 + 212 libs/ui/src/lib/assistant/assistant.component.ts @@ -2184,7 +2192,7 @@ 맥스 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 211 + 216 libs/ui/src/lib/assistant/assistant.component.ts @@ -2340,7 +2348,7 @@ 장소 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 509 + 512 apps/client/src/app/components/user-account-settings/user-account-settings.html @@ -2916,11 +2924,11 @@ Could not parse scraper configuration apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 509 + 525 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 512 + 528 @@ -3160,7 +3168,7 @@ 시장 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 378 + 381 apps/client/src/app/components/footer/footer.component.html @@ -4160,7 +4168,7 @@ 보증금 libs/ui/src/lib/fire-calculator/fire-calculator.component.ts - 385 + 390 @@ -4456,11 +4464,11 @@ Could not save asset profile apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 588 + 604 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 591 + 607 @@ -5005,7 +5013,7 @@ 자산 프로필 apps/client/src/app/components/admin-settings/admin-settings.component.html - 106 + 123 libs/ui/src/lib/assistant/assistant.html @@ -5121,7 +5129,7 @@ libs/ui/src/lib/fire-calculator/fire-calculator.component.ts - 395 + 400 libs/ui/src/lib/i18n.ts @@ -5133,7 +5141,7 @@ 저금 libs/ui/src/lib/fire-calculator/fire-calculator.component.ts - 405 + 410 @@ -5205,7 +5213,7 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 326 + 327 apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html @@ -5237,7 +5245,7 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 342 + 343 apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html @@ -5737,7 +5745,7 @@ 유효기간 apps/client/src/app/components/admin-settings/admin-settings.component.html - 74 + 86 libs/ui/src/lib/membership-card/membership-card.component.html @@ -5801,7 +5809,7 @@ 현재 시장가격은 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 706 + 722 @@ -5809,7 +5817,7 @@ 시험 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 568 + 571 @@ -5977,7 +5985,7 @@ MTD apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 195 + 200 libs/ui/src/lib/assistant/assistant.component.ts @@ -5989,7 +5997,7 @@ WTD apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 191 + 196 libs/ui/src/lib/assistant/assistant.component.ts @@ -6029,7 +6037,7 @@ 년도 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 203 + 208 apps/client/src/app/pages/resources/personal-finance-tools/product-page.html @@ -6049,7 +6057,7 @@ 연령 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 207 + 212 libs/ui/src/lib/assistant/assistant.component.ts @@ -6082,7 +6090,7 @@ 셀프 호스팅 apps/client/src/app/pages/faq/faq-page.component.ts - 60 + 52 libs/common/src/lib/routes/routes.ts @@ -6094,7 +6102,7 @@ 데이터 수집 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 587 + 594 apps/client/src/app/components/admin-overview/admin-overview.html @@ -6106,7 +6114,7 @@ 일반적인 apps/client/src/app/pages/faq/faq-page.component.ts - 49 + 41 @@ -6114,7 +6122,7 @@ 구름 apps/client/src/app/pages/faq/faq-page.component.ts - 54 + 46 libs/common/src/lib/routes/routes.ts @@ -6294,7 +6302,7 @@ 포함 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 374 + 377 @@ -6698,7 +6706,7 @@ 오류 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 697 + 713 @@ -6710,7 +6718,7 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 592 + 599 apps/client/src/app/components/admin-market-data/create-asset-profile-dialog/create-asset-profile-dialog.html @@ -6794,7 +6802,7 @@ 닫다 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 594 + 601 apps/client/src/app/components/admin-market-data/create-asset-profile-dialog/create-asset-profile-dialog.html @@ -7106,7 +7114,7 @@ API 키 설정 apps/client/src/app/components/admin-settings/admin-settings.component.html - 171 + 188 @@ -7220,7 +7228,7 @@ ~의 apps/client/src/app/components/admin-settings/admin-settings.component.html - 135 + 152 @@ -7228,7 +7236,7 @@ API 키를 정말로 삭제하시겠습니까? apps/client/src/app/components/admin-settings/admin-settings.component.ts - 127 + 133 @@ -7236,7 +7244,7 @@ API 키 제거 apps/client/src/app/components/admin-settings/admin-settings.component.html - 161 + 178 @@ -7244,7 +7252,7 @@ 일일 요청 apps/client/src/app/components/admin-settings/admin-settings.component.html - 137 + 154 @@ -7328,7 +7336,7 @@ 구하다 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 603 + 610 apps/client/src/app/components/admin-market-data/create-asset-profile-dialog/create-asset-profile-dialog.html @@ -7404,7 +7412,7 @@ Ghostfolio API 키를 입력하세요. apps/client/src/app/components/admin-settings/admin-settings.component.ts - 146 + 152 @@ -7436,7 +7444,7 @@ 방법 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 518 + 521 @@ -7444,7 +7452,7 @@ 기본 시장 가격 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 481 + 484 @@ -7452,7 +7460,7 @@ 선택자 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 534 + 537 @@ -7460,7 +7468,7 @@ 즉각적인 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 229 + 234 @@ -7468,7 +7476,7 @@ 게으른 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 225 + 230 @@ -7476,7 +7484,7 @@ HTTP 요청 헤더 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 494 + 497 @@ -7484,7 +7492,7 @@ 실시간 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 229 + 234 @@ -7492,7 +7500,7 @@ 하루의 끝 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 225 + 230 @@ -7733,7 +7741,7 @@ ()은(는) 이미 사용 중입니다. apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 633 + 649 @@ -7741,7 +7749,7 @@ ()로 업데이트하는 동안 오류가 발생했습니다. apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 641 + 657 @@ -8068,7 +8076,7 @@ 이번 달 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 195 + 200 @@ -8076,7 +8084,7 @@ 새로운 apps/client/src/app/components/admin-settings/admin-settings.component.html - 67 + 79 apps/client/src/app/pages/admin/admin-page.component.ts diff --git a/apps/client/src/locales/messages.nl.xlf b/apps/client/src/locales/messages.nl.xlf index 2cf570721..fbd87961c 100644 --- a/apps/client/src/locales/messages.nl.xlf +++ b/apps/client/src/locales/messages.nl.xlf @@ -106,7 +106,7 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 309 + 310 apps/client/src/app/components/admin-platform/admin-platform.component.html @@ -118,7 +118,7 @@ apps/client/src/app/components/admin-settings/admin-settings.component.html - 46 + 58 apps/client/src/app/components/admin-tag/admin-tag.component.html @@ -234,11 +234,11 @@ apps/client/src/app/components/admin-platform/admin-platform.component.html - 74 + 78 apps/client/src/app/components/admin-tag/admin-tag.component.html - 67 + 71 libs/ui/src/lib/accounts-table/accounts-table.component.html @@ -266,11 +266,11 @@ apps/client/src/app/components/admin-platform/admin-platform.component.html - 85 + 89 apps/client/src/app/components/admin-tag/admin-tag.component.html - 78 + 82 apps/client/src/app/components/user-detail-dialog/user-detail-dialog.html @@ -366,7 +366,7 @@ apps/client/src/app/components/admin-settings/admin-settings.component.html - 92 + 104 @@ -382,7 +382,7 @@ Activa Profiel apps/client/src/app/components/admin-settings/admin-settings.component.html - 106 + 123 libs/ui/src/lib/assistant/assistant.html @@ -398,7 +398,7 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 448 + 451 @@ -970,7 +970,7 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 396 + 399 apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html @@ -990,7 +990,7 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 407 + 410 apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html @@ -1002,7 +1002,7 @@ Tags apps/client/src/app/components/admin-settings/admin-settings.component.html - 201 + 218 libs/ui/src/lib/tags-selector/tags-selector.component.html @@ -1066,7 +1066,7 @@ YTD apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 199 + 204 libs/ui/src/lib/assistant/assistant.component.ts @@ -1078,7 +1078,7 @@ 1J apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 203 + 208 libs/ui/src/lib/assistant/assistant.component.ts @@ -1090,7 +1090,7 @@ 5J apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 207 + 212 libs/ui/src/lib/assistant/assistant.component.ts @@ -1110,7 +1110,7 @@ Max apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 211 + 216 libs/ui/src/lib/assistant/assistant.component.ts @@ -1282,7 +1282,7 @@ Locatie apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 509 + 512 apps/client/src/app/components/user-account-settings/user-account-settings.html @@ -1422,7 +1422,7 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 316 + 317 apps/client/src/app/components/admin-market-data/create-asset-profile-dialog/create-asset-profile-dialog.html @@ -1698,7 +1698,7 @@ Markten apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 378 + 381 apps/client/src/app/components/footer/footer.component.html @@ -1918,7 +1918,7 @@ Huidige week apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 191 + 196 @@ -2002,7 +2002,7 @@ Opmerking apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 432 + 435 apps/client/src/app/pages/accounts/create-or-update-account-dialog/create-or-update-account-dialog.html @@ -2514,7 +2514,7 @@ Besparingen libs/ui/src/lib/fire-calculator/fire-calculator.component.ts - 405 + 410 @@ -2530,7 +2530,7 @@ libs/ui/src/lib/fire-calculator/fire-calculator.component.ts - 395 + 400 libs/ui/src/lib/i18n.ts @@ -2550,7 +2550,7 @@ Storting libs/ui/src/lib/fire-calculator/fire-calculator.component.ts - 385 + 390 @@ -2650,7 +2650,7 @@ Benchmark apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 376 + 379 apps/client/src/app/components/benchmark-comparator/benchmark-comparator.component.ts @@ -2662,11 +2662,11 @@ Het formulier kon niet worden gevalideerd. apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 554 + 570 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 557 + 573 @@ -2786,7 +2786,7 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 326 + 327 apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html @@ -3110,7 +3110,7 @@ Symbool toewijzen apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 384 + 387 @@ -3174,7 +3174,7 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 342 + 343 apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html @@ -3302,7 +3302,7 @@ Geldig tot apps/client/src/app/components/admin-settings/admin-settings.component.html - 74 + 86 libs/ui/src/lib/membership-card/membership-card.component.html @@ -3622,11 +3622,11 @@ Kon het assetprofiel niet opslaan apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 588 + 604 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 591 + 607 @@ -3821,6 +3821,14 @@ 306 + + Explore + Explore + + apps/client/src/app/pages/resources/overview/resources-overview.component.html + 11 + + By Tegen @@ -3842,7 +3850,7 @@ Huidig jaar apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 199 + 204 @@ -3858,11 +3866,11 @@ Url apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 419 + 422 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 550 + 553 apps/client/src/app/components/admin-platform/admin-platform.component.html @@ -3878,7 +3886,7 @@ Het activaprofiel is opgeslagen. apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 578 + 594 @@ -3886,7 +3894,7 @@ Wil je dit platform echt verwijderen? apps/client/src/app/components/admin-platform/admin-platform.component.ts - 106 + 112 @@ -3894,7 +3902,7 @@ Platforms apps/client/src/app/components/admin-settings/admin-settings.component.html - 195 + 212 @@ -4238,7 +4246,7 @@ Scraper instellingen apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 471 + 474 @@ -4778,11 +4786,11 @@ De scraperconfiguratie kon niet worden geparseerd apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 509 + 525 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 512 + 528 @@ -5476,7 +5484,7 @@ Weet u zetker dat u dit label wilt verwijderen? apps/client/src/app/components/admin-tag/admin-tag.component.ts - 103 + 109 @@ -5768,7 +5776,7 @@ De huidige markt waarde is apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 706 + 722 @@ -5776,7 +5784,7 @@ Test apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 568 + 571 @@ -5821,7 +5829,7 @@ Argentina - Argentinië + Argentinië libs/ui/src/lib/i18n.ts 78 @@ -5936,7 +5944,7 @@ Week tot nu toe apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 191 + 196 libs/ui/src/lib/assistant/assistant.component.ts @@ -5956,7 +5964,7 @@ MTD apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 195 + 200 libs/ui/src/lib/assistant/assistant.component.ts @@ -6004,7 +6012,7 @@ jaar apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 203 + 208 apps/client/src/app/pages/resources/personal-finance-tools/product-page.html @@ -6024,7 +6032,7 @@ jaren apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 207 + 212 libs/ui/src/lib/assistant/assistant.component.ts @@ -6044,7 +6052,7 @@ Data Verzamelen apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 587 + 594 apps/client/src/app/components/admin-overview/admin-overview.html @@ -6056,7 +6064,7 @@ Algemeen apps/client/src/app/pages/faq/faq-page.component.ts - 49 + 41 @@ -6064,7 +6072,7 @@ Cloud apps/client/src/app/pages/faq/faq-page.component.ts - 54 + 46 libs/common/src/lib/routes/routes.ts @@ -6076,7 +6084,7 @@ Zelf Hosten apps/client/src/app/pages/faq/faq-page.component.ts - 60 + 52 libs/common/src/lib/routes/routes.ts @@ -6269,7 +6277,7 @@ Opnemen in apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 374 + 377 @@ -6673,7 +6681,7 @@ Fout apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 697 + 713 @@ -6702,7 +6710,7 @@ , based on your total assets of - opnemen, dit is gebaseerd op uw totale vermogen van + opnemen, dit is gebaseerd op uw totale vermogen van apps/client/src/app/pages/portfolio/fire/fire-page.html 96 @@ -6725,7 +6733,7 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 592 + 599 apps/client/src/app/components/admin-market-data/create-asset-profile-dialog/create-asset-profile-dialog.html @@ -6777,7 +6785,7 @@ Sluiten apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 594 + 601 apps/client/src/app/components/admin-market-data/create-asset-profile-dialog/create-asset-profile-dialog.html @@ -7054,7 +7062,7 @@ Ghostfolio is a lightweight wealth management application for individuals to keep track of stocks, ETFs or cryptocurrencies and make solid, data-driven investment decisions. - Ghostfolio is een gebruiksvriendelijke applicatie voor vermogensbeheer waarmee particulieren hun aandelen, ETF's of cryptovaluta kunnen volgen en weloverwogen, datagestuurde beleggingsbeslissingen kunnen nemen. + Ghostfolio is een gebruiksvriendelijke applicatie voor vermogensbeheer waarmee particulieren hun aandelen, ETF's of cryptovaluta kunnen volgen en weloverwogen, datagestuurde beleggingsbeslissingen kunnen nemen. apps/client/src/app/pages/about/overview/about-overview-page.html 10 @@ -7081,7 +7089,7 @@ API-sleutel instellen apps/client/src/app/components/admin-settings/admin-settings.component.html - 171 + 188 @@ -7187,7 +7195,7 @@ van apps/client/src/app/components/admin-settings/admin-settings.component.html - 135 + 152 @@ -7195,7 +7203,7 @@ dagelijkse verzoeken apps/client/src/app/components/admin-settings/admin-settings.component.html - 137 + 154 @@ -7203,7 +7211,7 @@ Verwijder API-sleutel apps/client/src/app/components/admin-settings/admin-settings.component.html - 161 + 178 @@ -7211,7 +7219,7 @@ Wilt u de API-sleutel echt verwijderen? apps/client/src/app/components/admin-settings/admin-settings.component.ts - 127 + 133 @@ -7303,7 +7311,7 @@ Opslaan apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 603 + 610 apps/client/src/app/components/admin-market-data/create-asset-profile-dialog/create-asset-profile-dialog.html @@ -7379,7 +7387,7 @@ Voer uw Ghostfolio API-sleutel in. apps/client/src/app/components/admin-settings/admin-settings.component.ts - 146 + 152 @@ -7411,7 +7419,7 @@ Lui apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 225 + 230 @@ -7419,7 +7427,7 @@ Direct apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 229 + 234 @@ -7427,7 +7435,7 @@ Standaard Marktprijs apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 481 + 484 @@ -7435,7 +7443,7 @@ Modus apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 518 + 521 @@ -7443,7 +7451,7 @@ Kiezer apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 534 + 537 @@ -7451,7 +7459,7 @@ HTTP Verzoek Headers apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 494 + 497 @@ -7459,7 +7467,7 @@ eind van de dag apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 225 + 230 @@ -7467,7 +7475,7 @@ real-time apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 229 + 234 @@ -7708,7 +7716,7 @@ () is al in gebruik. apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 633 + 649 @@ -7716,7 +7724,7 @@ Er is een fout opgetreden tijdens het updaten naar (). apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 641 + 657 @@ -8067,7 +8075,7 @@ Huidige maand apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 195 + 200 @@ -8075,7 +8083,7 @@ nieuw apps/client/src/app/components/admin-settings/admin-settings.component.html - 67 + 79 apps/client/src/app/pages/admin/admin-page.component.ts diff --git a/apps/client/src/locales/messages.pl.xlf b/apps/client/src/locales/messages.pl.xlf index bc8b948cd..5de2ed8f4 100644 --- a/apps/client/src/locales/messages.pl.xlf +++ b/apps/client/src/locales/messages.pl.xlf @@ -351,7 +351,7 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 309 + 310 apps/client/src/app/components/admin-platform/admin-platform.component.html @@ -363,7 +363,7 @@ apps/client/src/app/components/admin-settings/admin-settings.component.html - 46 + 58 apps/client/src/app/components/admin-tag/admin-tag.component.html @@ -423,7 +423,7 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 316 + 317 apps/client/src/app/components/admin-market-data/create-asset-profile-dialog/create-asset-profile-dialog.html @@ -511,11 +511,11 @@ apps/client/src/app/components/admin-platform/admin-platform.component.html - 74 + 78 apps/client/src/app/components/admin-tag/admin-tag.component.html - 67 + 71 libs/ui/src/lib/accounts-table/accounts-table.component.html @@ -543,11 +543,11 @@ apps/client/src/app/components/admin-platform/admin-platform.component.html - 85 + 89 apps/client/src/app/components/admin-tag/admin-tag.component.html - 78 + 82 apps/client/src/app/components/user-detail-dialog/user-detail-dialog.html @@ -595,7 +595,7 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 448 + 451 @@ -655,7 +655,7 @@ apps/client/src/app/components/admin-settings/admin-settings.component.html - 92 + 104 @@ -927,7 +927,7 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 396 + 399 apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html @@ -947,7 +947,7 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 407 + 410 apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html @@ -959,7 +959,7 @@ Mapowanie Symboli apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 384 + 387 @@ -975,7 +975,7 @@ Konfiguracja Scrapera apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 471 + 474 @@ -983,7 +983,7 @@ Notatka apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 432 + 435 apps/client/src/app/pages/accounts/create-or-update-account-dialog/create-or-update-account-dialog.html @@ -1191,11 +1191,11 @@ Url apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 419 + 422 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 550 + 553 apps/client/src/app/components/admin-platform/admin-platform.component.html @@ -1211,7 +1211,7 @@ Asset profile has been saved apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 578 + 594 @@ -1219,7 +1219,15 @@ Czy naprawdę chcesz usunąć tę platformę? apps/client/src/app/components/admin-platform/admin-platform.component.ts - 106 + 112 + + + + Explore + Explore + + apps/client/src/app/pages/resources/overview/resources-overview.component.html + 11 @@ -1243,7 +1251,7 @@ Current year apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 199 + 204 @@ -1259,7 +1267,7 @@ Platformy apps/client/src/app/components/admin-settings/admin-settings.component.html - 195 + 212 @@ -1267,7 +1275,7 @@ Tagi apps/client/src/app/components/admin-settings/admin-settings.component.html - 201 + 218 libs/ui/src/lib/tags-selector/tags-selector.component.html @@ -1291,7 +1299,7 @@ Czy naprawdę chcesz usunąć ten tag? apps/client/src/app/components/admin-tag/admin-tag.component.ts - 103 + 109 @@ -1383,11 +1391,11 @@ Could not validate form apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 554 + 570 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 557 + 573 @@ -1435,7 +1443,7 @@ Poziom Odniesienia (Benchmark) apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 376 + 379 apps/client/src/app/components/benchmark-comparator/benchmark-comparator.component.ts @@ -1639,7 +1647,7 @@ Current week apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 191 + 196 @@ -2107,7 +2115,7 @@ Liczony od początku roku (year-to-date) apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 199 + 204 libs/ui/src/lib/assistant/assistant.component.ts @@ -2119,7 +2127,7 @@ 1 rok apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 203 + 208 libs/ui/src/lib/assistant/assistant.component.ts @@ -2131,7 +2139,7 @@ 5 lat apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 207 + 212 libs/ui/src/lib/assistant/assistant.component.ts @@ -2151,7 +2159,7 @@ Maksimum apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 211 + 216 libs/ui/src/lib/assistant/assistant.component.ts @@ -2307,7 +2315,7 @@ Ustawienia Regionalne apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 509 + 512 apps/client/src/app/components/user-account-settings/user-account-settings.html @@ -2883,11 +2891,11 @@ Could not parse scraper configuration apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 509 + 525 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 512 + 528 @@ -3127,7 +3135,7 @@ Rynki apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 378 + 381 apps/client/src/app/components/footer/footer.component.html @@ -4127,7 +4135,7 @@ Depozyt libs/ui/src/lib/fire-calculator/fire-calculator.component.ts - 385 + 390 @@ -4423,11 +4431,11 @@ Could not save asset profile apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 588 + 604 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 591 + 607 @@ -4952,7 +4960,7 @@ Profile aktywów apps/client/src/app/components/admin-settings/admin-settings.component.html - 106 + 123 libs/ui/src/lib/assistant/assistant.html @@ -5052,7 +5060,7 @@ libs/ui/src/lib/fire-calculator/fire-calculator.component.ts - 395 + 400 libs/ui/src/lib/i18n.ts @@ -5064,7 +5072,7 @@ Oszczędności libs/ui/src/lib/fire-calculator/fire-calculator.component.ts - 405 + 410 @@ -5136,7 +5144,7 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 326 + 327 apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html @@ -5168,7 +5176,7 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 342 + 343 apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html @@ -5668,7 +5676,7 @@ Ważność do apps/client/src/app/components/admin-settings/admin-settings.component.html - 74 + 86 libs/ui/src/lib/membership-card/membership-card.component.html @@ -5768,7 +5776,7 @@ Obecna cena rynkowa wynosi apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 706 + 722 @@ -5776,7 +5784,7 @@ Test apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 568 + 571 @@ -5936,7 +5944,7 @@ WTD apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 191 + 196 libs/ui/src/lib/assistant/assistant.component.ts @@ -5956,7 +5964,7 @@ MTD apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 195 + 200 libs/ui/src/lib/assistant/assistant.component.ts @@ -6004,7 +6012,7 @@ rok apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 203 + 208 apps/client/src/app/pages/resources/personal-finance-tools/product-page.html @@ -6024,7 +6032,7 @@ lata apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 207 + 212 libs/ui/src/lib/assistant/assistant.component.ts @@ -6044,7 +6052,7 @@ Gromadzenie Danych apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 587 + 594 apps/client/src/app/components/admin-overview/admin-overview.html @@ -6056,7 +6064,7 @@ Informacje Ogólne apps/client/src/app/pages/faq/faq-page.component.ts - 49 + 41 @@ -6064,7 +6072,7 @@ Rozwiązanie w Chmurze apps/client/src/app/pages/faq/faq-page.component.ts - 54 + 46 libs/common/src/lib/routes/routes.ts @@ -6076,7 +6084,7 @@ Własny Hosting apps/client/src/app/pages/faq/faq-page.component.ts - 60 + 52 libs/common/src/lib/routes/routes.ts @@ -6269,7 +6277,7 @@ Include in apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 374 + 377 @@ -6673,7 +6681,7 @@ Błąd apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 697 + 713 @@ -6725,7 +6733,7 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 592 + 599 apps/client/src/app/components/admin-market-data/create-asset-profile-dialog/create-asset-profile-dialog.html @@ -6777,7 +6785,7 @@ Zamknij apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 594 + 601 apps/client/src/app/components/admin-market-data/create-asset-profile-dialog/create-asset-profile-dialog.html @@ -7081,7 +7089,7 @@ Skonfiguruj klucz API apps/client/src/app/components/admin-settings/admin-settings.component.html - 171 + 188 @@ -7187,7 +7195,7 @@ z apps/client/src/app/components/admin-settings/admin-settings.component.html - 135 + 152 @@ -7195,7 +7203,7 @@ codzienne żądania apps/client/src/app/components/admin-settings/admin-settings.component.html - 137 + 154 @@ -7203,7 +7211,7 @@ Usuń klucz API apps/client/src/app/components/admin-settings/admin-settings.component.html - 161 + 178 @@ -7211,7 +7219,7 @@ Czy na pewno chcesz usunąć klucz API?? apps/client/src/app/components/admin-settings/admin-settings.component.ts - 127 + 133 @@ -7303,7 +7311,7 @@ Zapisz apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 603 + 610 apps/client/src/app/components/admin-market-data/create-asset-profile-dialog/create-asset-profile-dialog.html @@ -7379,7 +7387,7 @@ Wprowadź swój klucz API Ghostfolio. apps/client/src/app/components/admin-settings/admin-settings.component.ts - 146 + 152 @@ -7411,7 +7419,7 @@ Leniwy apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 225 + 230 @@ -7419,7 +7427,7 @@ Natychmiastowy apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 229 + 234 @@ -7427,7 +7435,7 @@ Domyślna cena rynkowa apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 481 + 484 @@ -7435,7 +7443,7 @@ Tryb apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 518 + 521 @@ -7443,7 +7451,7 @@ Selektor apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 534 + 537 @@ -7451,7 +7459,7 @@ Nagłówki żądań HTTP apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 494 + 497 @@ -7459,7 +7467,7 @@ koniec dnia apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 225 + 230 @@ -7467,7 +7475,7 @@ w czasie rzeczywistym apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 229 + 234 @@ -7708,7 +7716,7 @@ () jest już w użyciu. apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 633 + 649 @@ -7716,7 +7724,7 @@ Wystąpił błąd podczas aktualizacji do (). apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 641 + 657 @@ -8067,7 +8075,7 @@ Current month apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 195 + 200 @@ -8075,7 +8083,7 @@ nowy apps/client/src/app/components/admin-settings/admin-settings.component.html - 67 + 79 apps/client/src/app/pages/admin/admin-page.component.ts diff --git a/apps/client/src/locales/messages.pt.xlf b/apps/client/src/locales/messages.pt.xlf index e49f13b96..72c1e6a3e 100644 --- a/apps/client/src/locales/messages.pt.xlf +++ b/apps/client/src/locales/messages.pt.xlf @@ -114,7 +114,7 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 309 + 310 apps/client/src/app/components/admin-platform/admin-platform.component.html @@ -126,7 +126,7 @@ apps/client/src/app/components/admin-settings/admin-settings.component.html - 46 + 58 apps/client/src/app/components/admin-tag/admin-tag.component.html @@ -186,7 +186,7 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 316 + 317 apps/client/src/app/components/admin-market-data/create-asset-profile-dialog/create-asset-profile-dialog.html @@ -290,11 +290,11 @@ apps/client/src/app/components/admin-platform/admin-platform.component.html - 74 + 78 apps/client/src/app/components/admin-tag/admin-tag.component.html - 67 + 71 libs/ui/src/lib/accounts-table/accounts-table.component.html @@ -322,11 +322,11 @@ apps/client/src/app/components/admin-platform/admin-platform.component.html - 85 + 89 apps/client/src/app/components/admin-tag/admin-tag.component.html - 78 + 82 apps/client/src/app/components/user-detail-dialog/user-detail-dialog.html @@ -414,7 +414,7 @@ apps/client/src/app/components/admin-settings/admin-settings.component.html - 92 + 104 @@ -438,7 +438,7 @@ Perfil de Ativos apps/client/src/app/components/admin-settings/admin-settings.component.html - 106 + 123 libs/ui/src/lib/assistant/assistant.html @@ -454,7 +454,7 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 448 + 451 @@ -766,11 +766,11 @@ Could not validate form apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 554 + 570 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 557 + 573 @@ -810,7 +810,7 @@ Referência apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 376 + 379 apps/client/src/app/components/benchmark-comparator/benchmark-comparator.component.ts @@ -942,7 +942,7 @@ Depósito libs/ui/src/lib/fire-calculator/fire-calculator.component.ts - 385 + 390 @@ -1214,7 +1214,7 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 396 + 399 apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html @@ -1234,7 +1234,7 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 407 + 410 apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html @@ -1246,7 +1246,7 @@ Marcadores apps/client/src/app/components/admin-settings/admin-settings.component.html - 201 + 218 libs/ui/src/lib/tags-selector/tags-selector.component.html @@ -1310,7 +1310,7 @@ AATD apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 199 + 204 libs/ui/src/lib/assistant/assistant.component.ts @@ -1322,7 +1322,7 @@ 1A apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 203 + 208 libs/ui/src/lib/assistant/assistant.component.ts @@ -1334,7 +1334,7 @@ 5A apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 207 + 212 libs/ui/src/lib/assistant/assistant.component.ts @@ -1354,7 +1354,7 @@ Máx apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 211 + 216 libs/ui/src/lib/assistant/assistant.component.ts @@ -1590,7 +1590,7 @@ Localidade apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 509 + 512 apps/client/src/app/components/user-account-settings/user-account-settings.html @@ -1974,7 +1974,7 @@ Mercados apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 378 + 381 apps/client/src/app/components/footer/footer.component.html @@ -2078,7 +2078,7 @@ Current week apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 191 + 196 @@ -2142,7 +2142,7 @@ Nota apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 432 + 435 apps/client/src/app/pages/accounts/create-or-update-account-dialog/create-or-update-account-dialog.html @@ -2758,7 +2758,7 @@ libs/ui/src/lib/fire-calculator/fire-calculator.component.ts - 395 + 400 libs/ui/src/lib/i18n.ts @@ -2770,7 +2770,7 @@ Poupanças libs/ui/src/lib/fire-calculator/fire-calculator.component.ts - 405 + 410 @@ -2806,7 +2806,7 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 326 + 327 apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html @@ -3118,7 +3118,7 @@ Mapeamento de Símbolo apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 384 + 387 @@ -3238,7 +3238,7 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 342 + 343 apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html @@ -3302,7 +3302,7 @@ Válido até apps/client/src/app/components/admin-settings/admin-settings.component.html - 74 + 86 libs/ui/src/lib/membership-card/membership-card.component.html @@ -3622,11 +3622,11 @@ Could not save asset profile apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 588 + 604 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 591 + 607 @@ -3821,6 +3821,14 @@ 306 + + Explore + Explore + + apps/client/src/app/pages/resources/overview/resources-overview.component.html + 11 + + By By @@ -3842,7 +3850,7 @@ Current year apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 199 + 204 @@ -3858,11 +3866,11 @@ Url apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 419 + 422 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 550 + 553 apps/client/src/app/components/admin-platform/admin-platform.component.html @@ -3878,7 +3886,7 @@ Asset profile has been saved apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 578 + 594 @@ -3886,7 +3894,7 @@ Deseja mesmo eliminar esta plataforma? apps/client/src/app/components/admin-platform/admin-platform.component.ts - 106 + 112 @@ -3894,7 +3902,7 @@ Plataformas apps/client/src/app/components/admin-settings/admin-settings.component.html - 195 + 212 @@ -4238,7 +4246,7 @@ Configuração do raspador apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 471 + 474 @@ -4778,11 +4786,11 @@ Could not parse scraper configuration apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 509 + 525 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 512 + 528 @@ -5476,7 +5484,7 @@ Você realmente deseja excluir esta tag? apps/client/src/app/components/admin-tag/admin-tag.component.ts - 103 + 109 @@ -5768,7 +5776,7 @@ O preço de mercado atual é apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 706 + 722 @@ -5776,7 +5784,7 @@ Teste apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 568 + 571 @@ -5936,7 +5944,7 @@ WTD apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 191 + 196 libs/ui/src/lib/assistant/assistant.component.ts @@ -5956,7 +5964,7 @@ MTD apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 195 + 200 libs/ui/src/lib/assistant/assistant.component.ts @@ -6004,7 +6012,7 @@ ano apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 203 + 208 apps/client/src/app/pages/resources/personal-finance-tools/product-page.html @@ -6024,7 +6032,7 @@ anos apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 207 + 212 libs/ui/src/lib/assistant/assistant.component.ts @@ -6044,7 +6052,7 @@ Coleta de dados apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 587 + 594 apps/client/src/app/components/admin-overview/admin-overview.html @@ -6056,7 +6064,7 @@ geral apps/client/src/app/pages/faq/faq-page.component.ts - 49 + 41 @@ -6064,7 +6072,7 @@ Nuvem apps/client/src/app/pages/faq/faq-page.component.ts - 54 + 46 libs/common/src/lib/routes/routes.ts @@ -6076,7 +6084,7 @@ Auto-hospedagem apps/client/src/app/pages/faq/faq-page.component.ts - 60 + 52 libs/common/src/lib/routes/routes.ts @@ -6269,7 +6277,7 @@ Include in apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 374 + 377 @@ -6673,7 +6681,7 @@ Erro apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 697 + 713 @@ -6725,7 +6733,7 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 592 + 599 apps/client/src/app/components/admin-market-data/create-asset-profile-dialog/create-asset-profile-dialog.html @@ -6777,7 +6785,7 @@ Fechar apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 594 + 601 apps/client/src/app/components/admin-market-data/create-asset-profile-dialog/create-asset-profile-dialog.html @@ -7081,7 +7089,7 @@ Definir chave de API apps/client/src/app/components/admin-settings/admin-settings.component.html - 171 + 188 @@ -7187,7 +7195,7 @@ de apps/client/src/app/components/admin-settings/admin-settings.component.html - 135 + 152 @@ -7195,7 +7203,7 @@ solicitações diárias apps/client/src/app/components/admin-settings/admin-settings.component.html - 137 + 154 @@ -7203,7 +7211,7 @@ Remover chave de API apps/client/src/app/components/admin-settings/admin-settings.component.html - 161 + 178 @@ -7211,7 +7219,7 @@ Você realmente deseja excluir a chave de API? apps/client/src/app/components/admin-settings/admin-settings.component.ts - 127 + 133 @@ -7303,7 +7311,7 @@ Guardar apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 603 + 610 apps/client/src/app/components/admin-market-data/create-asset-profile-dialog/create-asset-profile-dialog.html @@ -7379,7 +7387,7 @@ Please enter your Ghostfolio API key. apps/client/src/app/components/admin-settings/admin-settings.component.ts - 146 + 152 @@ -7411,7 +7419,7 @@ Lazy apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 225 + 230 @@ -7419,7 +7427,7 @@ Instant apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 229 + 234 @@ -7427,7 +7435,7 @@ Preço de mercado padrão apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 481 + 484 @@ -7435,7 +7443,7 @@ Mode apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 518 + 521 @@ -7443,7 +7451,7 @@ Selector apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 534 + 537 @@ -7451,7 +7459,7 @@ HTTP Request Headers apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 494 + 497 @@ -7459,7 +7467,7 @@ end of day apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 225 + 230 @@ -7467,7 +7475,7 @@ real-time apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 229 + 234 @@ -7708,7 +7716,7 @@ () is already in use. apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 633 + 649 @@ -7716,7 +7724,7 @@ An error occurred while updating to (). apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 641 + 657 @@ -8067,7 +8075,7 @@ Current month apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 195 + 200 @@ -8075,7 +8083,7 @@ new apps/client/src/app/components/admin-settings/admin-settings.component.html - 67 + 79 apps/client/src/app/pages/admin/admin-page.component.ts diff --git a/apps/client/src/locales/messages.tr.xlf b/apps/client/src/locales/messages.tr.xlf index abe33aa80..7f51580d7 100644 --- a/apps/client/src/locales/messages.tr.xlf +++ b/apps/client/src/locales/messages.tr.xlf @@ -311,7 +311,7 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 309 + 310 apps/client/src/app/components/admin-platform/admin-platform.component.html @@ -323,7 +323,7 @@ apps/client/src/app/components/admin-settings/admin-settings.component.html - 46 + 58 apps/client/src/app/components/admin-tag/admin-tag.component.html @@ -383,7 +383,7 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 316 + 317 apps/client/src/app/components/admin-market-data/create-asset-profile-dialog/create-asset-profile-dialog.html @@ -471,11 +471,11 @@ apps/client/src/app/components/admin-platform/admin-platform.component.html - 74 + 78 apps/client/src/app/components/admin-tag/admin-tag.component.html - 67 + 71 libs/ui/src/lib/accounts-table/accounts-table.component.html @@ -503,11 +503,11 @@ apps/client/src/app/components/admin-platform/admin-platform.component.html - 85 + 89 apps/client/src/app/components/admin-tag/admin-tag.component.html - 78 + 82 apps/client/src/app/components/user-detail-dialog/user-detail-dialog.html @@ -595,7 +595,7 @@ apps/client/src/app/components/admin-settings/admin-settings.component.html - 92 + 104 @@ -619,7 +619,7 @@ Varlık Profili apps/client/src/app/components/admin-settings/admin-settings.component.html - 106 + 123 libs/ui/src/lib/assistant/assistant.html @@ -635,7 +635,7 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 448 + 451 @@ -859,7 +859,7 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 396 + 399 apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html @@ -879,7 +879,7 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 407 + 410 apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html @@ -891,7 +891,7 @@ Sembol Eşleştirme apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 384 + 387 @@ -907,7 +907,7 @@ Veri Toplayıcı Yapılandırması apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 471 + 474 @@ -915,7 +915,7 @@ Not apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 432 + 435 apps/client/src/app/pages/accounts/create-or-update-account-dialog/create-or-update-account-dialog.html @@ -1015,7 +1015,7 @@ Etiketler apps/client/src/app/components/admin-settings/admin-settings.component.html - 201 + 218 libs/ui/src/lib/tags-selector/tags-selector.component.html @@ -1107,11 +1107,11 @@ Url apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 419 + 422 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 550 + 553 apps/client/src/app/components/admin-platform/admin-platform.component.html @@ -1127,7 +1127,7 @@ Asset profile has been saved apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 578 + 594 @@ -1135,7 +1135,15 @@ Bu platformu silmeyi gerçekten istiyor musunuz? apps/client/src/app/components/admin-platform/admin-platform.component.ts - 106 + 112 + + + + Explore + Explore + + apps/client/src/app/pages/resources/overview/resources-overview.component.html + 11 @@ -1159,7 +1167,7 @@ Current year apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 199 + 204 @@ -1175,7 +1183,7 @@ Platformlar apps/client/src/app/components/admin-settings/admin-settings.component.html - 195 + 212 @@ -1251,11 +1259,11 @@ Could not validate form apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 554 + 570 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 557 + 573 @@ -1303,7 +1311,7 @@ Karşılaştırma Ölçütü apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 376 + 379 apps/client/src/app/components/benchmark-comparator/benchmark-comparator.component.ts @@ -1507,7 +1515,7 @@ Current week apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 191 + 196 @@ -1975,7 +1983,7 @@ YTD apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 199 + 204 libs/ui/src/lib/assistant/assistant.component.ts @@ -1987,7 +1995,7 @@ 1Y apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 203 + 208 libs/ui/src/lib/assistant/assistant.component.ts @@ -1999,7 +2007,7 @@ 5Y apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 207 + 212 libs/ui/src/lib/assistant/assistant.component.ts @@ -2019,7 +2027,7 @@ Maks. apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 211 + 216 libs/ui/src/lib/assistant/assistant.component.ts @@ -2447,11 +2455,11 @@ Could not parse scraper configuration apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 509 + 525 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 512 + 528 @@ -2703,7 +2711,7 @@ Piyasalar apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 378 + 381 apps/client/src/app/components/footer/footer.component.html @@ -3611,7 +3619,7 @@ Para Yatırma libs/ui/src/lib/fire-calculator/fire-calculator.component.ts - 385 + 390 @@ -3907,11 +3915,11 @@ Could not save asset profile apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 588 + 604 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 591 + 607 @@ -4392,7 +4400,7 @@ Geçerli tarih apps/client/src/app/components/admin-settings/admin-settings.component.html - 74 + 86 libs/ui/src/lib/membership-card/membership-card.component.html @@ -4472,7 +4480,7 @@ Yerel Ayarlar apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 509 + 512 apps/client/src/app/components/user-account-settings/user-account-settings.html @@ -4748,7 +4756,7 @@ libs/ui/src/lib/fire-calculator/fire-calculator.component.ts - 395 + 400 libs/ui/src/lib/i18n.ts @@ -4760,7 +4768,7 @@ Tasarruflar libs/ui/src/lib/fire-calculator/fire-calculator.component.ts - 405 + 410 @@ -4832,7 +4840,7 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 326 + 327 apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html @@ -4864,7 +4872,7 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 342 + 343 apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html @@ -5476,7 +5484,7 @@ Bu etiketi silmeyi gerçekten istiyor musunuz? apps/client/src/app/components/admin-tag/admin-tag.component.ts - 103 + 109 @@ -5768,7 +5776,7 @@ Şu anki piyasa fiyatı apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 706 + 722 @@ -5776,7 +5784,7 @@ Test apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 568 + 571 @@ -5936,7 +5944,7 @@ WTD apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 191 + 196 libs/ui/src/lib/assistant/assistant.component.ts @@ -5956,7 +5964,7 @@ MTD apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 195 + 200 libs/ui/src/lib/assistant/assistant.component.ts @@ -6004,7 +6012,7 @@ Yıl apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 203 + 208 apps/client/src/app/pages/resources/personal-finance-tools/product-page.html @@ -6024,7 +6032,7 @@ Yıllar apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 207 + 212 libs/ui/src/lib/assistant/assistant.component.ts @@ -6044,7 +6052,7 @@ Veri Toplama apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 587 + 594 apps/client/src/app/components/admin-overview/admin-overview.html @@ -6056,7 +6064,7 @@ Genel apps/client/src/app/pages/faq/faq-page.component.ts - 49 + 41 @@ -6064,7 +6072,7 @@ Bulut apps/client/src/app/pages/faq/faq-page.component.ts - 54 + 46 libs/common/src/lib/routes/routes.ts @@ -6076,7 +6084,7 @@ Kendini Barındırma apps/client/src/app/pages/faq/faq-page.component.ts - 60 + 52 libs/common/src/lib/routes/routes.ts @@ -6269,7 +6277,7 @@ Include in apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 374 + 377 @@ -6673,7 +6681,7 @@ Hata apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 697 + 713 @@ -6725,7 +6733,7 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 592 + 599 apps/client/src/app/components/admin-market-data/create-asset-profile-dialog/create-asset-profile-dialog.html @@ -6777,7 +6785,7 @@ Kapat apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 594 + 601 apps/client/src/app/components/admin-market-data/create-asset-profile-dialog/create-asset-profile-dialog.html @@ -7081,7 +7089,7 @@ API anahtarını ayarla apps/client/src/app/components/admin-settings/admin-settings.component.html - 171 + 188 @@ -7187,7 +7195,7 @@ ın apps/client/src/app/components/admin-settings/admin-settings.component.html - 135 + 152 @@ -7195,7 +7203,7 @@ günlük istekler apps/client/src/app/components/admin-settings/admin-settings.component.html - 137 + 154 @@ -7203,7 +7211,7 @@ API anahtarını kaldır apps/client/src/app/components/admin-settings/admin-settings.component.html - 161 + 178 @@ -7211,7 +7219,7 @@ API anahtarını silmek istediğinize emin misiniz? apps/client/src/app/components/admin-settings/admin-settings.component.ts - 127 + 133 @@ -7303,7 +7311,7 @@ Kaydet apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 603 + 610 apps/client/src/app/components/admin-market-data/create-asset-profile-dialog/create-asset-profile-dialog.html @@ -7379,7 +7387,7 @@ Lütfen Ghostfolio API anahtarınızı girin. apps/client/src/app/components/admin-settings/admin-settings.component.ts - 146 + 152 @@ -7411,7 +7419,7 @@ Tembel apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 225 + 230 @@ -7419,7 +7427,7 @@ Anında apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 229 + 234 @@ -7427,7 +7435,7 @@ Varsayılan Piyasa Fiyatı apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 481 + 484 @@ -7435,7 +7443,7 @@ Mod apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 518 + 521 @@ -7443,7 +7451,7 @@ Seçici apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 534 + 537 @@ -7451,7 +7459,7 @@ HTTP İstek Başlıkları apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 494 + 497 @@ -7459,7 +7467,7 @@ gün sonu apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 225 + 230 @@ -7467,7 +7475,7 @@ gerçek zamanlı apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 229 + 234 @@ -7708,7 +7716,7 @@ () is already in use. apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 633 + 649 @@ -7716,7 +7724,7 @@ Güncelleştirilirken bir hata oluştu (). apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 641 + 657 @@ -8067,7 +8075,7 @@ Current month apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 195 + 200 @@ -8075,7 +8083,7 @@ yeni apps/client/src/app/components/admin-settings/admin-settings.component.html - 67 + 79 apps/client/src/app/pages/admin/admin-page.component.ts diff --git a/apps/client/src/locales/messages.uk.xlf b/apps/client/src/locales/messages.uk.xlf index 95ad50c7c..54bf5a08b 100644 --- a/apps/client/src/locales/messages.uk.xlf +++ b/apps/client/src/locales/messages.uk.xlf @@ -443,7 +443,7 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 309 + 310 apps/client/src/app/components/admin-platform/admin-platform.component.html @@ -455,7 +455,7 @@ apps/client/src/app/components/admin-settings/admin-settings.component.html - 46 + 58 apps/client/src/app/components/admin-tag/admin-tag.component.html @@ -515,7 +515,7 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 316 + 317 apps/client/src/app/components/admin-market-data/create-asset-profile-dialog/create-asset-profile-dialog.html @@ -603,11 +603,11 @@ apps/client/src/app/components/admin-platform/admin-platform.component.html - 74 + 78 apps/client/src/app/components/admin-tag/admin-tag.component.html - 67 + 71 libs/ui/src/lib/accounts-table/accounts-table.component.html @@ -635,11 +635,11 @@ apps/client/src/app/components/admin-platform/admin-platform.component.html - 85 + 89 apps/client/src/app/components/admin-tag/admin-tag.component.html - 78 + 82 apps/client/src/app/components/user-detail-dialog/user-detail-dialog.html @@ -707,7 +707,7 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 448 + 451 @@ -783,7 +783,7 @@ apps/client/src/app/components/admin-settings/admin-settings.component.html - 92 + 104 @@ -999,7 +999,7 @@ Помилка apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 697 + 713 @@ -1007,7 +1007,7 @@ Поточна ринкова ціна apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 706 + 722 @@ -1059,7 +1059,7 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 396 + 399 apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html @@ -1079,7 +1079,7 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 407 + 410 apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html @@ -1091,7 +1091,7 @@ Зіставлення символів apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 384 + 387 @@ -1107,7 +1107,7 @@ Конфігурація скребка apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 471 + 474 @@ -1115,7 +1115,7 @@ Тест apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 568 + 571 @@ -1123,11 +1123,11 @@ URL apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 419 + 422 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 550 + 553 apps/client/src/app/components/admin-platform/admin-platform.component.html @@ -1143,7 +1143,7 @@ Asset profile has been saved apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 578 + 594 @@ -1151,7 +1151,7 @@ Примітка apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 432 + 435 apps/client/src/app/pages/accounts/create-or-update-account-dialog/create-or-update-account-dialog.html @@ -1307,7 +1307,7 @@ Збір даних apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 587 + 594 apps/client/src/app/components/admin-overview/admin-overview.html @@ -1379,7 +1379,15 @@ Ви дійсно хочете видалити цю платформу? apps/client/src/app/components/admin-platform/admin-platform.component.ts - 106 + 112 + + + + Explore + Explore + + apps/client/src/app/pages/resources/overview/resources-overview.component.html + 11 @@ -1403,7 +1411,7 @@ Current year apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 199 + 204 @@ -1427,7 +1435,7 @@ Дійсне до apps/client/src/app/components/admin-settings/admin-settings.component.html - 74 + 86 libs/ui/src/lib/membership-card/membership-card.component.html @@ -1439,7 +1447,7 @@ з apps/client/src/app/components/admin-settings/admin-settings.component.html - 135 + 152 @@ -1447,7 +1455,7 @@ щоденних запитів apps/client/src/app/components/admin-settings/admin-settings.component.html - 137 + 154 @@ -1455,7 +1463,7 @@ Вилучити ключ API apps/client/src/app/components/admin-settings/admin-settings.component.html - 161 + 178 @@ -1463,7 +1471,7 @@ Встановити ключ API apps/client/src/app/components/admin-settings/admin-settings.component.html - 171 + 188 @@ -1471,7 +1479,7 @@ Платформи apps/client/src/app/components/admin-settings/admin-settings.component.html - 195 + 212 @@ -1479,7 +1487,7 @@ Теги apps/client/src/app/components/admin-settings/admin-settings.component.html - 201 + 218 libs/ui/src/lib/tags-selector/tags-selector.component.html @@ -1495,7 +1503,7 @@ Ви дійсно хочете видалити ключ API? apps/client/src/app/components/admin-settings/admin-settings.component.ts - 127 + 133 @@ -1503,7 +1511,7 @@ Будь ласка, введіть ваш ключ API Ghostfolio. apps/client/src/app/components/admin-settings/admin-settings.component.ts - 146 + 152 @@ -1587,7 +1595,7 @@ Ви дійсно хочете видалити цей тег? apps/client/src/app/components/admin-tag/admin-tag.component.ts - 103 + 109 @@ -1667,11 +1675,11 @@ Could not validate form apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 554 + 570 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 557 + 573 @@ -1719,7 +1727,7 @@ Порівняльний показник apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 376 + 379 apps/client/src/app/components/benchmark-comparator/benchmark-comparator.component.ts @@ -2079,7 +2087,7 @@ Current week apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 191 + 196 @@ -2283,7 +2291,7 @@ Зберегти apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 603 + 610 apps/client/src/app/components/admin-market-data/create-asset-profile-dialog/create-asset-profile-dialog.html @@ -2563,7 +2571,7 @@ З початку року apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 199 + 204 libs/ui/src/lib/assistant/assistant.component.ts @@ -2575,7 +2583,7 @@ 1 рік apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 203 + 208 libs/ui/src/lib/assistant/assistant.component.ts @@ -2587,7 +2595,7 @@ 5 років apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 207 + 212 libs/ui/src/lib/assistant/assistant.component.ts @@ -2607,7 +2615,7 @@ Максимум apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 211 + 216 libs/ui/src/lib/assistant/assistant.component.ts @@ -2855,7 +2863,7 @@ Include in apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 374 + 377 @@ -2911,7 +2919,7 @@ Локалізація apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 509 + 512 apps/client/src/app/components/user-account-settings/user-account-settings.html @@ -3503,11 +3511,11 @@ Could not parse scraper configuration apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 509 + 525 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 512 + 528 @@ -3551,7 +3559,7 @@ Загальні apps/client/src/app/pages/faq/faq-page.component.ts - 49 + 41 @@ -3559,7 +3567,7 @@ Хмара apps/client/src/app/pages/faq/faq-page.component.ts - 54 + 46 libs/common/src/lib/routes/routes.ts @@ -3571,7 +3579,7 @@ Самохостинг apps/client/src/app/pages/faq/faq-page.component.ts - 60 + 52 libs/common/src/lib/routes/routes.ts @@ -3772,7 +3780,7 @@ Ринки apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 378 + 381 apps/client/src/app/components/footer/footer.component.html @@ -5208,11 +5216,11 @@ Could not save asset profile apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 588 + 604 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 591 + 607 @@ -6163,7 +6171,7 @@ WTD apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 191 + 196 libs/ui/src/lib/assistant/assistant.component.ts @@ -6183,7 +6191,7 @@ MTD apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 195 + 200 libs/ui/src/lib/assistant/assistant.component.ts @@ -6203,7 +6211,7 @@ рік apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 203 + 208 apps/client/src/app/pages/resources/personal-finance-tools/product-page.html @@ -6223,7 +6231,7 @@ роки apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 207 + 212 libs/ui/src/lib/assistant/assistant.component.ts @@ -6235,7 +6243,7 @@ Профілі активів apps/client/src/app/components/admin-settings/admin-settings.component.html - 106 + 123 libs/ui/src/lib/assistant/assistant.html @@ -6375,7 +6383,7 @@ Депозит libs/ui/src/lib/fire-calculator/fire-calculator.component.ts - 385 + 390 @@ -6391,7 +6399,7 @@ libs/ui/src/lib/fire-calculator/fire-calculator.component.ts - 395 + 400 libs/ui/src/lib/i18n.ts @@ -6403,7 +6411,7 @@ Заощадження libs/ui/src/lib/fire-calculator/fire-calculator.component.ts - 405 + 410 @@ -6491,7 +6499,7 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 326 + 327 apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html @@ -6523,7 +6531,7 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 342 + 343 apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html @@ -6555,7 +6563,7 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 592 + 599 apps/client/src/app/components/admin-market-data/create-asset-profile-dialog/create-asset-profile-dialog.html @@ -6615,7 +6623,7 @@ Закрити apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 594 + 601 apps/client/src/app/components/admin-market-data/create-asset-profile-dialog/create-asset-profile-dialog.html @@ -7411,7 +7419,7 @@ Lazy apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 225 + 230 @@ -7419,7 +7427,7 @@ Instant apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 229 + 234 @@ -7427,7 +7435,7 @@ Default Market Price apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 481 + 484 @@ -7435,7 +7443,7 @@ Mode apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 518 + 521 @@ -7443,7 +7451,7 @@ Selector apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 534 + 537 @@ -7451,7 +7459,7 @@ HTTP Request Headers apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 494 + 497 @@ -7459,7 +7467,7 @@ end of day apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 225 + 230 @@ -7467,7 +7475,7 @@ real-time apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 229 + 234 @@ -7708,7 +7716,7 @@ () is already in use. apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 633 + 649 @@ -7716,7 +7724,7 @@ An error occurred while updating to (). apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 641 + 657 @@ -8067,7 +8075,7 @@ Current month apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 195 + 200 @@ -8075,7 +8083,7 @@ new apps/client/src/app/components/admin-settings/admin-settings.component.html - 67 + 79 apps/client/src/app/pages/admin/admin-page.component.ts diff --git a/apps/client/src/locales/messages.xlf b/apps/client/src/locales/messages.xlf index b6a54edfe..7db54e0c4 100644 --- a/apps/client/src/locales/messages.xlf +++ b/apps/client/src/locales/messages.xlf @@ -334,7 +334,7 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 309 + 310 apps/client/src/app/components/admin-platform/admin-platform.component.html @@ -346,7 +346,7 @@ apps/client/src/app/components/admin-settings/admin-settings.component.html - 46 + 58 apps/client/src/app/components/admin-tag/admin-tag.component.html @@ -404,7 +404,7 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 316 + 317 apps/client/src/app/components/admin-market-data/create-asset-profile-dialog/create-asset-profile-dialog.html @@ -490,11 +490,11 @@ apps/client/src/app/components/admin-platform/admin-platform.component.html - 74 + 78 apps/client/src/app/components/admin-tag/admin-tag.component.html - 67 + 71 libs/ui/src/lib/accounts-table/accounts-table.component.html @@ -521,11 +521,11 @@ apps/client/src/app/components/admin-platform/admin-platform.component.html - 85 + 89 apps/client/src/app/components/admin-tag/admin-tag.component.html - 78 + 82 apps/client/src/app/components/user-detail-dialog/user-detail-dialog.html @@ -570,7 +570,7 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 448 + 451 @@ -625,7 +625,7 @@ apps/client/src/app/components/admin-settings/admin-settings.component.html - 92 + 104 @@ -893,7 +893,7 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 396 + 399 apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html @@ -912,7 +912,7 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 407 + 410 apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html @@ -923,7 +923,7 @@ Symbol Mapping apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 384 + 387 @@ -937,14 +937,14 @@ Scraper Configuration apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 471 + 474 Note apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 432 + 435 apps/client/src/app/pages/accounts/create-or-update-account-dialog/create-or-update-account-dialog.html @@ -1129,11 +1129,11 @@ Url apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 419 + 422 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 550 + 553 apps/client/src/app/components/admin-platform/admin-platform.component.html @@ -1148,14 +1148,21 @@ Asset profile has been saved apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 578 + 594 Do you really want to delete this platform? apps/client/src/app/components/admin-platform/admin-platform.component.ts - 106 + 112 + + + + Explore + + apps/client/src/app/pages/resources/overview/resources-overview.component.html + 11 @@ -1176,7 +1183,7 @@ Current year apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 199 + 204 @@ -1190,14 +1197,14 @@ Platforms apps/client/src/app/components/admin-settings/admin-settings.component.html - 195 + 212 Tags apps/client/src/app/components/admin-settings/admin-settings.component.html - 201 + 218 libs/ui/src/lib/tags-selector/tags-selector.component.html @@ -1219,7 +1226,7 @@ Do you really want to delete this tag? apps/client/src/app/components/admin-tag/admin-tag.component.ts - 103 + 109 @@ -1301,11 +1308,11 @@ Could not validate form apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 554 + 570 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 557 + 573 @@ -1349,7 +1356,7 @@ Benchmark apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 376 + 379 apps/client/src/app/components/benchmark-comparator/benchmark-comparator.component.ts @@ -1534,7 +1541,7 @@ Current week apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 191 + 196 @@ -1965,7 +1972,7 @@ YTD apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 199 + 204 libs/ui/src/lib/assistant/assistant.component.ts @@ -1976,7 +1983,7 @@ 1Y apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 203 + 208 libs/ui/src/lib/assistant/assistant.component.ts @@ -1987,7 +1994,7 @@ 5Y apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 207 + 212 libs/ui/src/lib/assistant/assistant.component.ts @@ -2005,7 +2012,7 @@ Max apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 211 + 216 libs/ui/src/lib/assistant/assistant.component.ts @@ -2144,7 +2151,7 @@ Locale apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 509 + 512 apps/client/src/app/components/user-account-settings/user-account-settings.html @@ -2680,11 +2687,11 @@ Could not parse scraper configuration apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 509 + 525 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 512 + 528 @@ -2903,7 +2910,7 @@ Markets apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 378 + 381 apps/client/src/app/components/footer/footer.component.html @@ -3808,7 +3815,7 @@ Deposit libs/ui/src/lib/fire-calculator/fire-calculator.component.ts - 385 + 390 @@ -4074,11 +4081,11 @@ Could not save asset profile apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 588 + 604 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 591 + 607 @@ -4570,7 +4577,7 @@ Asset Profiles apps/client/src/app/components/admin-settings/admin-settings.component.html - 106 + 123 libs/ui/src/lib/assistant/assistant.html @@ -4673,7 +4680,7 @@ libs/ui/src/lib/fire-calculator/fire-calculator.component.ts - 395 + 400 libs/ui/src/lib/i18n.ts @@ -4684,7 +4691,7 @@ Savings libs/ui/src/lib/fire-calculator/fire-calculator.component.ts - 405 + 410 @@ -4751,7 +4758,7 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 326 + 327 apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html @@ -4782,7 +4789,7 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 342 + 343 apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html @@ -5222,7 +5229,7 @@ Valid until apps/client/src/app/components/admin-settings/admin-settings.component.html - 74 + 86 libs/ui/src/lib/membership-card/membership-card.component.html @@ -5281,14 +5288,14 @@ The current market price is apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 706 + 722 Test apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 568 + 571 @@ -5438,7 +5445,7 @@ MTD apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 195 + 200 libs/ui/src/lib/assistant/assistant.component.ts @@ -5449,7 +5456,7 @@ WTD apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 191 + 196 libs/ui/src/lib/assistant/assistant.component.ts @@ -5485,7 +5492,7 @@ year apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 203 + 208 apps/client/src/app/pages/resources/personal-finance-tools/product-page.html @@ -5504,7 +5511,7 @@ years apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 207 + 212 libs/ui/src/lib/assistant/assistant.component.ts @@ -5534,7 +5541,7 @@ Self-Hosting apps/client/src/app/pages/faq/faq-page.component.ts - 60 + 52 libs/common/src/lib/routes/routes.ts @@ -5545,7 +5552,7 @@ Data Gathering apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 587 + 594 apps/client/src/app/components/admin-overview/admin-overview.html @@ -5556,14 +5563,14 @@ General apps/client/src/app/pages/faq/faq-page.component.ts - 49 + 41 Cloud apps/client/src/app/pages/faq/faq-page.component.ts - 54 + 46 libs/common/src/lib/routes/routes.ts @@ -5721,7 +5728,7 @@ Include in apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 374 + 377 @@ -6082,7 +6089,7 @@ Error apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 697 + 713 @@ -6093,7 +6100,7 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 592 + 599 apps/client/src/app/components/admin-market-data/create-asset-profile-dialog/create-asset-profile-dialog.html @@ -6172,7 +6179,7 @@ Close apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 594 + 601 apps/client/src/app/components/admin-market-data/create-asset-profile-dialog/create-asset-profile-dialog.html @@ -6454,7 +6461,7 @@ Set API key apps/client/src/app/components/admin-settings/admin-settings.component.html - 171 + 188 @@ -6557,28 +6564,28 @@ of apps/client/src/app/components/admin-settings/admin-settings.component.html - 135 + 152 Do you really want to delete the API key? apps/client/src/app/components/admin-settings/admin-settings.component.ts - 127 + 133 Remove API key apps/client/src/app/components/admin-settings/admin-settings.component.html - 161 + 178 daily requests apps/client/src/app/components/admin-settings/admin-settings.component.html - 137 + 154 @@ -6652,7 +6659,7 @@ Save apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 603 + 610 apps/client/src/app/components/admin-market-data/create-asset-profile-dialog/create-asset-profile-dialog.html @@ -6724,7 +6731,7 @@ Please enter your Ghostfolio API key. apps/client/src/app/components/admin-settings/admin-settings.component.ts - 146 + 152 @@ -6752,56 +6759,56 @@ Mode apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 518 + 521 Default Market Price apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 481 + 484 Selector apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 534 + 537 Instant apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 229 + 234 Lazy apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 225 + 230 HTTP Request Headers apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 494 + 497 real-time apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 229 + 234 end of day apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 225 + 230 @@ -7016,14 +7023,14 @@ () is already in use. apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 633 + 649 An error occurred while updating to (). apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 641 + 657 @@ -7315,14 +7322,14 @@ Current month apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 195 + 200 new apps/client/src/app/components/admin-settings/admin-settings.component.html - 67 + 79 apps/client/src/app/pages/admin/admin-page.component.ts diff --git a/apps/client/src/locales/messages.zh.xlf b/apps/client/src/locales/messages.zh.xlf index ac81eebc7..be465e9df 100644 --- a/apps/client/src/locales/messages.zh.xlf +++ b/apps/client/src/locales/messages.zh.xlf @@ -360,7 +360,7 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 309 + 310 apps/client/src/app/components/admin-platform/admin-platform.component.html @@ -372,7 +372,7 @@ apps/client/src/app/components/admin-settings/admin-settings.component.html - 46 + 58 apps/client/src/app/components/admin-tag/admin-tag.component.html @@ -432,7 +432,7 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 316 + 317 apps/client/src/app/components/admin-market-data/create-asset-profile-dialog/create-asset-profile-dialog.html @@ -520,11 +520,11 @@ apps/client/src/app/components/admin-platform/admin-platform.component.html - 74 + 78 apps/client/src/app/components/admin-tag/admin-tag.component.html - 67 + 71 libs/ui/src/lib/accounts-table/accounts-table.component.html @@ -552,11 +552,11 @@ apps/client/src/app/components/admin-platform/admin-platform.component.html - 85 + 89 apps/client/src/app/components/admin-tag/admin-tag.component.html - 78 + 82 apps/client/src/app/components/user-detail-dialog/user-detail-dialog.html @@ -604,7 +604,7 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 448 + 451 @@ -664,7 +664,7 @@ apps/client/src/app/components/admin-settings/admin-settings.component.html - 92 + 104 @@ -936,7 +936,7 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 396 + 399 apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html @@ -956,7 +956,7 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 407 + 410 apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html @@ -968,7 +968,7 @@ 代码映射 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 384 + 387 @@ -984,7 +984,7 @@ 刮削配置 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 471 + 474 @@ -992,7 +992,7 @@ 笔记 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 432 + 435 apps/client/src/app/pages/accounts/create-or-update-account-dialog/create-or-update-account-dialog.html @@ -1200,11 +1200,11 @@ 网址 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 419 + 422 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 550 + 553 apps/client/src/app/components/admin-platform/admin-platform.component.html @@ -1220,7 +1220,7 @@ 资产概况已保存 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 578 + 594 @@ -1228,7 +1228,15 @@ 您真的要删除这个平台吗? apps/client/src/app/components/admin-platform/admin-platform.component.ts - 106 + 112 + + + + Explore + Explore + + apps/client/src/app/pages/resources/overview/resources-overview.component.html + 11 @@ -1252,7 +1260,7 @@ 当前年份 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 199 + 204 @@ -1268,7 +1276,7 @@ 平台 apps/client/src/app/components/admin-settings/admin-settings.component.html - 195 + 212 @@ -1276,7 +1284,7 @@ 标签 apps/client/src/app/components/admin-settings/admin-settings.component.html - 201 + 218 libs/ui/src/lib/tags-selector/tags-selector.component.html @@ -1300,7 +1308,7 @@ 您真的要删除此标签吗? apps/client/src/app/components/admin-tag/admin-tag.component.ts - 103 + 109 @@ -1392,11 +1400,11 @@ 无法验证表单 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 554 + 570 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 557 + 573 @@ -1444,7 +1452,7 @@ 基准 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 376 + 379 apps/client/src/app/components/benchmark-comparator/benchmark-comparator.component.ts @@ -1648,7 +1656,7 @@ 当前周 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 191 + 196 @@ -2116,7 +2124,7 @@ 年初至今 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 199 + 204 libs/ui/src/lib/assistant/assistant.component.ts @@ -2128,7 +2136,7 @@ 1年 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 203 + 208 libs/ui/src/lib/assistant/assistant.component.ts @@ -2140,7 +2148,7 @@ 5年 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 207 + 212 libs/ui/src/lib/assistant/assistant.component.ts @@ -2160,7 +2168,7 @@ 最大限度 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 211 + 216 libs/ui/src/lib/assistant/assistant.component.ts @@ -2316,7 +2324,7 @@ 语言环境 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 509 + 512 apps/client/src/app/components/user-account-settings/user-account-settings.html @@ -2892,11 +2900,11 @@ 无法解析抓取器配置 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 509 + 525 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 512 + 528 @@ -3136,7 +3144,7 @@ 市场 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 378 + 381 apps/client/src/app/components/footer/footer.component.html @@ -4144,7 +4152,7 @@ 存款 libs/ui/src/lib/fire-calculator/fire-calculator.component.ts - 385 + 390 @@ -4440,11 +4448,11 @@ 无法保存资产概况 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 588 + 604 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 591 + 607 @@ -4989,7 +4997,7 @@ 资产概况 apps/client/src/app/components/admin-settings/admin-settings.component.html - 106 + 123 libs/ui/src/lib/assistant/assistant.html @@ -5105,7 +5113,7 @@ libs/ui/src/lib/fire-calculator/fire-calculator.component.ts - 395 + 400 libs/ui/src/lib/i18n.ts @@ -5117,7 +5125,7 @@ 储蓄 libs/ui/src/lib/fire-calculator/fire-calculator.component.ts - 405 + 410 @@ -5189,7 +5197,7 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 326 + 327 apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html @@ -5221,7 +5229,7 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 342 + 343 apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html @@ -5713,7 +5721,7 @@ 有效期至 apps/client/src/app/components/admin-settings/admin-settings.component.html - 74 + 86 libs/ui/src/lib/membership-card/membership-card.component.html @@ -5777,7 +5785,7 @@ 当前市场价格为 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 706 + 722 @@ -5785,7 +5793,7 @@ 测试 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 568 + 571 @@ -5953,7 +5961,7 @@ 本月至今 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 195 + 200 libs/ui/src/lib/assistant/assistant.component.ts @@ -5965,7 +5973,7 @@ 本周至今 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 191 + 196 libs/ui/src/lib/assistant/assistant.component.ts @@ -6005,7 +6013,7 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 203 + 208 apps/client/src/app/pages/resources/personal-finance-tools/product-page.html @@ -6025,7 +6033,7 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 207 + 212 libs/ui/src/lib/assistant/assistant.component.ts @@ -6058,7 +6066,7 @@ 自托管 apps/client/src/app/pages/faq/faq-page.component.ts - 60 + 52 libs/common/src/lib/routes/routes.ts @@ -6070,7 +6078,7 @@ 数据收集 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 587 + 594 apps/client/src/app/components/admin-overview/admin-overview.html @@ -6082,7 +6090,7 @@ 一般的 apps/client/src/app/pages/faq/faq-page.component.ts - 49 + 41 @@ -6090,7 +6098,7 @@ apps/client/src/app/pages/faq/faq-page.component.ts - 54 + 46 libs/common/src/lib/routes/routes.ts @@ -6270,7 +6278,7 @@ 包含在 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 374 + 377 @@ -6674,7 +6682,7 @@ 错误 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 697 + 713 @@ -6726,7 +6734,7 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 592 + 599 apps/client/src/app/components/admin-market-data/create-asset-profile-dialog/create-asset-profile-dialog.html @@ -6778,7 +6786,7 @@ 关闭 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 594 + 601 apps/client/src/app/components/admin-market-data/create-asset-profile-dialog/create-asset-profile-dialog.html @@ -7082,7 +7090,7 @@ 设置 API 密钥 apps/client/src/app/components/admin-settings/admin-settings.component.html - 171 + 188 @@ -7188,7 +7196,7 @@ apps/client/src/app/components/admin-settings/admin-settings.component.html - 135 + 152 @@ -7196,7 +7204,7 @@ 每日请求 apps/client/src/app/components/admin-settings/admin-settings.component.html - 137 + 154 @@ -7204,7 +7212,7 @@ 移除 API 密钥 apps/client/src/app/components/admin-settings/admin-settings.component.html - 161 + 178 @@ -7212,7 +7220,7 @@ 您确定要删除此 API 密钥吗? apps/client/src/app/components/admin-settings/admin-settings.component.ts - 127 + 133 @@ -7304,7 +7312,7 @@ 保存 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 603 + 610 apps/client/src/app/components/admin-market-data/create-asset-profile-dialog/create-asset-profile-dialog.html @@ -7380,7 +7388,7 @@ 请输入您的 Ghostfolio API 密钥。 apps/client/src/app/components/admin-settings/admin-settings.component.ts - 146 + 152 @@ -7412,7 +7420,7 @@ 延迟 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 225 + 230 @@ -7420,7 +7428,7 @@ 即时 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 229 + 234 @@ -7428,7 +7436,7 @@ 默认市场价格 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 481 + 484 @@ -7436,7 +7444,7 @@ 模式 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 518 + 521 @@ -7444,7 +7452,7 @@ 选择器 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 534 + 537 @@ -7452,7 +7460,7 @@ HTTP 请求标头 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 494 + 497 @@ -7460,7 +7468,7 @@ 收盘 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 225 + 230 @@ -7468,7 +7476,7 @@ 实时 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 229 + 234 @@ -7709,7 +7717,7 @@ () 已在使用中。 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 633 + 649 @@ -7717,7 +7725,7 @@ 在更新到 () 时发生错误。 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 641 + 657 @@ -8068,7 +8076,7 @@ 当前月份 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 195 + 200 @@ -8076,7 +8084,7 @@ 新增 apps/client/src/app/components/admin-settings/admin-settings.component.html - 67 + 79 apps/client/src/app/pages/admin/admin-page.component.ts From d39172f0ebd9763c0d014db79d5b54fac0c9a1c6 Mon Sep 17 00:00:00 2001 From: Thomas Kaul <4159106+dtslvr@users.noreply.github.com> Date: Tue, 10 Mar 2026 19:34:25 +0100 Subject: [PATCH 116/224] Task/improve language localization for DE (20260310) (#6511) * Update translation * Update changelog --- CHANGELOG.md | 1 + apps/client/src/locales/messages.de.xlf | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 89c34edde..aeadceb93 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 - Improved the _Storybook_ stories of the value component - Improved the language localization for Dutch (`nl`) +- Improved the language localization for German (`de`) - Upgraded `class-validator` from version `0.14.3` to `0.15.1` ### Fixed diff --git a/apps/client/src/locales/messages.de.xlf b/apps/client/src/locales/messages.de.xlf index 74365a176..cad4fcc92 100644 --- a/apps/client/src/locales/messages.de.xlf +++ b/apps/client/src/locales/messages.de.xlf @@ -3847,7 +3847,7 @@ Explore - Explore + Entdecke apps/client/src/app/pages/resources/overview/resources-overview.component.html 11 From efa93a3b988e93a62cb8d0acd36522f901f17f33 Mon Sep 17 00:00:00 2001 From: Thomas Kaul <4159106+dtslvr@users.noreply.github.com> Date: Tue, 10 Mar 2026 20:23:03 +0100 Subject: [PATCH 117/224] Feature/setup Bull Dashboard (#6501) * Initial setup * Update changelog --- CHANGELOG.md | 1 + apps/api/src/app/app.module.ts | 34 +++++- apps/api/src/app/user/user.service.ts | 10 +- apps/api/src/main.ts | 6 + .../middlewares/bull-board-auth.middleware.ts | 28 +++++ .../configuration/configuration.service.ts | 2 + .../interfaces/environment.interface.ts | 2 + .../data-gathering/data-gathering.module.ts | 14 +++ .../portfolio-snapshot.module.ts | 14 +++ apps/client/proxy.conf.json | 4 + .../admin-jobs/admin-jobs.component.ts | 51 ++++++--- .../app/components/admin-jobs/admin-jobs.html | 9 ++ libs/common/src/lib/config.ts | 8 ++ libs/common/src/lib/permissions.ts | 1 + package-lock.json | 103 +++++++++++++++--- package.json | 5 + 16 files changed, 259 insertions(+), 33 deletions(-) create mode 100644 apps/api/src/middlewares/bull-board-auth.middleware.ts diff --git a/CHANGELOG.md b/CHANGELOG.md index aeadceb93..a01c57e86 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Added +- Integrated _Bull Dashboard_ for a detailed jobs queue view in the admin control panel (experimental) - Added a debounce to the `PortfolioChangedListener` and `AssetProfileChangedListener` to minimize redundant _Redis_ and database operations ### Changed diff --git a/apps/api/src/app/app.module.ts b/apps/api/src/app/app.module.ts index 4b790d0db..8ebe05928 100644 --- a/apps/api/src/app/app.module.ts +++ b/apps/api/src/app/app.module.ts @@ -1,4 +1,5 @@ import { EventsModule } from '@ghostfolio/api/events/events.module'; +import { BullBoardAuthMiddleware } from '@ghostfolio/api/middlewares/bull-board-auth.middleware'; import { HtmlTemplateMiddleware } from '@ghostfolio/api/middlewares/html-template.middleware'; import { ConfigurationModule } from '@ghostfolio/api/services/configuration/configuration.module'; import { CronModule } from '@ghostfolio/api/services/cron/cron.module'; @@ -10,10 +11,13 @@ import { PropertyModule } from '@ghostfolio/api/services/property/property.modul import { DataGatheringModule } from '@ghostfolio/api/services/queues/data-gathering/data-gathering.module'; import { PortfolioSnapshotQueueModule } from '@ghostfolio/api/services/queues/portfolio-snapshot/portfolio-snapshot.module'; import { + BULL_BOARD_ROUTE, DEFAULT_LANGUAGE_CODE, SUPPORTED_LANGUAGE_CODES } from '@ghostfolio/common/config'; +import { ExpressAdapter } from '@bull-board/express'; +import { BullBoardModule } from '@bull-board/nestjs'; import { BullModule } from '@nestjs/bull'; import { MiddlewareConsumer, Module, NestModule } from '@nestjs/common'; import { ConfigModule } from '@nestjs/config'; @@ -70,6 +74,29 @@ import { UserModule } from './user/user.module'; AuthDeviceModule, AuthModule, BenchmarksModule, + ...(process.env.ENABLE_FEATURE_BULL_BOARD === 'true' + ? [ + BullBoardModule.forRoot({ + adapter: ExpressAdapter, + boardOptions: { + uiConfig: { + boardLogo: { + height: 0, + path: '', + width: 0 + }, + boardTitle: 'Job Queues', + favIcon: { + alternative: '/assets/favicon-32x32.png', + default: '/assets/favicon-32x32.png' + } + } + }, + middleware: BullBoardAuthMiddleware, + route: BULL_BOARD_ROUTE + }) + ] + : []), BullModule.forRoot({ redis: { db: parseInt(process.env.REDIS_DB ?? '0', 10), @@ -105,7 +132,12 @@ import { UserModule } from './user/user.module'; RedisCacheModule, ScheduleModule.forRoot(), ServeStaticModule.forRoot({ - exclude: ['/.well-known/*wildcard', '/api/*wildcard', '/sitemap.xml'], + exclude: [ + `${BULL_BOARD_ROUTE}/*wildcard`, + '/.well-known/*wildcard', + '/api/*wildcard', + '/sitemap.xml' + ], rootPath: join(__dirname, '..', 'client'), serveStaticOptions: { setHeaders: (res) => { diff --git a/apps/api/src/app/user/user.service.ts b/apps/api/src/app/user/user.service.ts index 5a339c090..370f5d422 100644 --- a/apps/api/src/app/user/user.service.ts +++ b/apps/api/src/app/user/user.service.ts @@ -530,8 +530,14 @@ export class UserService { } } - if (!environment.production && hasRole(user, Role.ADMIN)) { - currentPermissions.push(permissions.impersonateAllUsers); + if (hasRole(user, Role.ADMIN)) { + if (this.configurationService.get('ENABLE_FEATURE_BULL_BOARD')) { + currentPermissions.push(permissions.accessAdminControlBullBoard); + } + + if (!environment.production) { + currentPermissions.push(permissions.impersonateAllUsers); + } } user.accounts = user.accounts.sort((a, b) => { diff --git a/apps/api/src/main.ts b/apps/api/src/main.ts index a8de3dc5e..f08a09a83 100644 --- a/apps/api/src/main.ts +++ b/apps/api/src/main.ts @@ -1,4 +1,5 @@ import { + BULL_BOARD_ROUTE, DEFAULT_HOST, DEFAULT_PORT, STORYBOOK_PATH, @@ -14,6 +15,7 @@ import { import { ConfigService } from '@nestjs/config'; import { NestFactory } from '@nestjs/core'; import type { NestExpressApplication } from '@nestjs/platform-express'; +import cookieParser from 'cookie-parser'; import { NextFunction, Request, Response } from 'express'; import helmet from 'helmet'; @@ -46,6 +48,7 @@ async function bootstrap() { }); app.setGlobalPrefix('api', { exclude: [ + `${BULL_BOARD_ROUTE.substring(1)}{/*wildcard}`, 'sitemap.xml', ...SUPPORTED_LANGUAGE_CODES.map((languageCode) => { // Exclude language-specific routes with an optional wildcard @@ -53,6 +56,7 @@ async function bootstrap() { }) ] }); + app.useGlobalPipes( new ValidationPipe({ forbidNonWhitelisted: true, @@ -64,6 +68,8 @@ async function bootstrap() { // Support 10mb csv/json files for importing activities app.useBodyParser('json', { limit: '10mb' }); + app.use(cookieParser()); + if (configService.get('ENABLE_FEATURE_SUBSCRIPTION') === 'true') { app.use((req: Request, res: Response, next: NextFunction) => { if (req.path.startsWith(STORYBOOK_PATH)) { diff --git a/apps/api/src/middlewares/bull-board-auth.middleware.ts b/apps/api/src/middlewares/bull-board-auth.middleware.ts new file mode 100644 index 000000000..432deb974 --- /dev/null +++ b/apps/api/src/middlewares/bull-board-auth.middleware.ts @@ -0,0 +1,28 @@ +import { BULL_BOARD_COOKIE_NAME } from '@ghostfolio/common/config'; +import { hasPermission, permissions } from '@ghostfolio/common/permissions'; + +import { ForbiddenException, Injectable, NestMiddleware } from '@nestjs/common'; +import { NextFunction, Request, Response } from 'express'; +import passport from 'passport'; + +@Injectable() +export class BullBoardAuthMiddleware implements NestMiddleware { + public use(req: Request, res: Response, next: NextFunction) { + const token = req.cookies?.[BULL_BOARD_COOKIE_NAME]; + + if (token) { + req.headers.authorization = `Bearer ${token}`; + } + + passport.authenticate('jwt', { session: false }, (error, user) => { + if ( + error || + !hasPermission(user?.permissions, permissions.accessAdminControl) + ) { + next(new ForbiddenException()); + } else { + next(); + } + })(req, res, next); + } +} diff --git a/apps/api/src/services/configuration/configuration.service.ts b/apps/api/src/services/configuration/configuration.service.ts index 5f9d1055d..ad8e84a99 100644 --- a/apps/api/src/services/configuration/configuration.service.ts +++ b/apps/api/src/services/configuration/configuration.service.ts @@ -30,6 +30,7 @@ export class ConfigurationService { API_KEY_FINANCIAL_MODELING_PREP: str({ default: '' }), API_KEY_OPEN_FIGI: str({ default: '' }), API_KEY_RAPID_API: str({ default: '' }), + BULL_BOARD_IS_READ_ONLY: bool({ default: true }), CACHE_QUOTES_TTL: num({ default: ms('1 minute') }), CACHE_TTL: num({ default: CACHE_TTL_NO_CACHE }), DATA_SOURCE_EXCHANGE_RATES: str({ default: DataSource.YAHOO }), @@ -43,6 +44,7 @@ export class ConfigurationService { ENABLE_FEATURE_AUTH_GOOGLE: bool({ default: false }), ENABLE_FEATURE_AUTH_OIDC: bool({ default: false }), ENABLE_FEATURE_AUTH_TOKEN: bool({ default: true }), + ENABLE_FEATURE_BULL_BOARD: bool({ default: false }), ENABLE_FEATURE_FEAR_AND_GREED_INDEX: bool({ default: false }), ENABLE_FEATURE_GATHER_NEW_EXCHANGE_RATES: bool({ default: true }), ENABLE_FEATURE_READ_ONLY_MODE: bool({ default: false }), diff --git a/apps/api/src/services/interfaces/environment.interface.ts b/apps/api/src/services/interfaces/environment.interface.ts index 57c58898e..9664ae144 100644 --- a/apps/api/src/services/interfaces/environment.interface.ts +++ b/apps/api/src/services/interfaces/environment.interface.ts @@ -10,6 +10,7 @@ export interface Environment extends CleanedEnvAccessors { API_KEY_FINANCIAL_MODELING_PREP: string; API_KEY_OPEN_FIGI: string; API_KEY_RAPID_API: string; + BULL_BOARD_IS_READ_ONLY: boolean; CACHE_QUOTES_TTL: number; CACHE_TTL: number; DATA_SOURCE_EXCHANGE_RATES: string; @@ -19,6 +20,7 @@ export interface Environment extends CleanedEnvAccessors { ENABLE_FEATURE_AUTH_GOOGLE: boolean; ENABLE_FEATURE_AUTH_OIDC: boolean; ENABLE_FEATURE_AUTH_TOKEN: boolean; + ENABLE_FEATURE_BULL_BOARD: boolean; ENABLE_FEATURE_FEAR_AND_GREED_INDEX: boolean; ENABLE_FEATURE_GATHER_NEW_EXCHANGE_RATES: boolean; ENABLE_FEATURE_READ_ONLY_MODE: boolean; diff --git a/apps/api/src/services/queues/data-gathering/data-gathering.module.ts b/apps/api/src/services/queues/data-gathering/data-gathering.module.ts index b51823476..f251c8d0c 100644 --- a/apps/api/src/services/queues/data-gathering/data-gathering.module.ts +++ b/apps/api/src/services/queues/data-gathering/data-gathering.module.ts @@ -9,6 +9,8 @@ import { DataGatheringService } from '@ghostfolio/api/services/queues/data-gathe import { SymbolProfileModule } from '@ghostfolio/api/services/symbol-profile/symbol-profile.module'; import { DATA_GATHERING_QUEUE } from '@ghostfolio/common/config'; +import { BullAdapter } from '@bull-board/api/bullAdapter'; +import { BullBoardModule } from '@bull-board/nestjs'; import { BullModule } from '@nestjs/bull'; import { Module } from '@nestjs/common'; import ms from 'ms'; @@ -17,6 +19,18 @@ import { DataGatheringProcessor } from './data-gathering.processor'; @Module({ imports: [ + ...(process.env.ENABLE_FEATURE_BULL_BOARD === 'true' + ? [ + BullBoardModule.forFeature({ + adapter: BullAdapter, + name: DATA_GATHERING_QUEUE, + options: { + displayName: 'Data Gathering', + readOnlyMode: process.env.BULL_BOARD_IS_READ_ONLY !== 'false' + } + }) + ] + : []), BullModule.registerQueue({ limiter: { duration: ms('4 seconds'), diff --git a/apps/api/src/services/queues/portfolio-snapshot/portfolio-snapshot.module.ts b/apps/api/src/services/queues/portfolio-snapshot/portfolio-snapshot.module.ts index 553765768..1260f1cf0 100644 --- a/apps/api/src/services/queues/portfolio-snapshot/portfolio-snapshot.module.ts +++ b/apps/api/src/services/queues/portfolio-snapshot/portfolio-snapshot.module.ts @@ -13,6 +13,8 @@ import { PORTFOLIO_SNAPSHOT_COMPUTATION_QUEUE } from '@ghostfolio/common/config'; +import { BullAdapter } from '@bull-board/api/bullAdapter'; +import { BullBoardModule } from '@bull-board/nestjs'; import { BullModule } from '@nestjs/bull'; import { Module } from '@nestjs/common'; @@ -23,6 +25,18 @@ import { PortfolioSnapshotProcessor } from './portfolio-snapshot.processor'; imports: [ AccountBalanceModule, ActivitiesModule, + ...(process.env.ENABLE_FEATURE_BULL_BOARD === 'true' + ? [ + BullBoardModule.forFeature({ + adapter: BullAdapter, + name: PORTFOLIO_SNAPSHOT_COMPUTATION_QUEUE, + options: { + displayName: 'Portfolio Snapshot Computation', + readOnlyMode: process.env.BULL_BOARD_IS_READ_ONLY !== 'false' + } + }) + ] + : []), BullModule.registerQueue({ name: PORTFOLIO_SNAPSHOT_COMPUTATION_QUEUE, settings: { diff --git a/apps/client/proxy.conf.json b/apps/client/proxy.conf.json index a31371d9f..825965b92 100644 --- a/apps/client/proxy.conf.json +++ b/apps/client/proxy.conf.json @@ -1,4 +1,8 @@ { + "/admin/queues": { + "target": "http://0.0.0.0:3333", + "secure": false + }, "/api": { "target": "http://0.0.0.0:3333", "secure": false diff --git a/apps/client/src/app/components/admin-jobs/admin-jobs.component.ts b/apps/client/src/app/components/admin-jobs/admin-jobs.component.ts index de70a7b6e..1537db2a0 100644 --- a/apps/client/src/app/components/admin-jobs/admin-jobs.component.ts +++ b/apps/client/src/app/components/admin-jobs/admin-jobs.component.ts @@ -1,5 +1,8 @@ +import { TokenStorageService } from '@ghostfolio/client/services/token-storage.service'; import { UserService } from '@ghostfolio/client/services/user/user.service'; import { + BULL_BOARD_COOKIE_NAME, + BULL_BOARD_ROUTE, DATA_GATHERING_QUEUE_PRIORITY_HIGH, DATA_GATHERING_QUEUE_PRIORITY_LOW, DATA_GATHERING_QUEUE_PRIORITY_MEDIUM, @@ -7,6 +10,7 @@ import { } from '@ghostfolio/common/config'; import { getDateWithTimeFormatString } from '@ghostfolio/common/helper'; import { AdminJobs, User } from '@ghostfolio/common/interfaces'; +import { hasPermission, permissions } from '@ghostfolio/common/permissions'; import { NotificationService } from '@ghostfolio/ui/notifications'; import { AdminService } from '@ghostfolio/ui/services'; @@ -15,10 +19,11 @@ import { ChangeDetectionStrategy, ChangeDetectorRef, Component, - OnDestroy, + DestroyRef, OnInit, ViewChild } from '@angular/core'; +import { takeUntilDestroyed } from '@angular/core/rxjs-interop'; import { FormBuilder, FormGroup, @@ -41,6 +46,7 @@ import { chevronUpCircleOutline, ellipsisHorizontal, ellipsisVertical, + openOutline, pauseOutline, playOutline, removeCircleOutline, @@ -48,8 +54,6 @@ import { } from 'ionicons/icons'; import { get } from 'lodash'; import { NgxSkeletonLoaderModule } from 'ngx-skeleton-loader'; -import { Subject } from 'rxjs'; -import { takeUntil } from 'rxjs/operators'; @Component({ changeDetection: ChangeDetectionStrategy.OnPush, @@ -69,7 +73,7 @@ import { takeUntil } from 'rxjs/operators'; styleUrls: ['./admin-jobs.scss'], templateUrl: './admin-jobs.html' }) -export class GfAdminJobsComponent implements OnDestroy, OnInit { +export class GfAdminJobsComponent implements OnInit { @ViewChild(MatSort) sort: MatSort; public DATA_GATHERING_QUEUE_PRIORITY_LOW = DATA_GATHERING_QUEUE_PRIORITY_LOW; @@ -81,6 +85,7 @@ export class GfAdminJobsComponent implements OnDestroy, OnInit { public dataSource = new MatTableDataSource(); public defaultDateTimeFormat: string; public filterForm: FormGroup; + public displayedColumns = [ 'index', 'type', @@ -93,21 +98,24 @@ export class GfAdminJobsComponent implements OnDestroy, OnInit { 'status', 'actions' ]; + + public hasPermissionToAccessBullBoard = false; public isLoading = false; public statusFilterOptions = QUEUE_JOB_STATUS_LIST; - public user: User; - private unsubscribeSubject = new Subject(); + private user: User; public constructor( private adminService: AdminService, private changeDetectorRef: ChangeDetectorRef, + private destroyRef: DestroyRef, private formBuilder: FormBuilder, private notificationService: NotificationService, + private tokenStorageService: TokenStorageService, private userService: UserService ) { this.userService.stateChanged - .pipe(takeUntil(this.unsubscribeSubject)) + .pipe(takeUntilDestroyed(this.destroyRef)) .subscribe((state) => { if (state?.user) { this.user = state.user; @@ -115,6 +123,11 @@ export class GfAdminJobsComponent implements OnDestroy, OnInit { this.defaultDateTimeFormat = getDateWithTimeFormatString( this.user.settings.locale ); + + this.hasPermissionToAccessBullBoard = hasPermission( + this.user.permissions, + permissions.accessAdminControlBullBoard + ); } }); @@ -126,6 +139,7 @@ export class GfAdminJobsComponent implements OnDestroy, OnInit { chevronUpCircleOutline, ellipsisHorizontal, ellipsisVertical, + openOutline, pauseOutline, playOutline, removeCircleOutline, @@ -139,7 +153,7 @@ export class GfAdminJobsComponent implements OnDestroy, OnInit { }); this.filterForm.valueChanges - .pipe(takeUntil(this.unsubscribeSubject)) + .pipe(takeUntilDestroyed(this.destroyRef)) .subscribe(() => { const currentFilter = this.filterForm.get('status').value; this.fetchJobs(currentFilter ? [currentFilter] : undefined); @@ -151,7 +165,7 @@ export class GfAdminJobsComponent implements OnDestroy, OnInit { public onDeleteJob(aId: string) { this.adminService .deleteJob(aId) - .pipe(takeUntil(this.unsubscribeSubject)) + .pipe(takeUntilDestroyed(this.destroyRef)) .subscribe(() => { this.fetchJobs(); }); @@ -162,7 +176,7 @@ export class GfAdminJobsComponent implements OnDestroy, OnInit { this.adminService .deleteJobs({ status: currentFilter ? [currentFilter] : undefined }) - .pipe(takeUntil(this.unsubscribeSubject)) + .pipe(takeUntilDestroyed(this.destroyRef)) .subscribe(() => { this.fetchJobs(currentFilter ? [currentFilter] : undefined); }); @@ -171,12 +185,20 @@ export class GfAdminJobsComponent implements OnDestroy, OnInit { public onExecuteJob(aId: string) { this.adminService .executeJob(aId) - .pipe(takeUntil(this.unsubscribeSubject)) + .pipe(takeUntilDestroyed(this.destroyRef)) .subscribe(() => { this.fetchJobs(); }); } + public onOpenBullBoard() { + const token = this.tokenStorageService.getToken(); + + document.cookie = `${BULL_BOARD_COOKIE_NAME}=${token}; path=${BULL_BOARD_ROUTE}; SameSite=Strict`; + + window.open(BULL_BOARD_ROUTE, '_blank'); + } + public onViewData(aData: AdminJobs['jobs'][0]['data']) { this.notificationService.alert({ title: JSON.stringify(aData, null, ' ') @@ -189,17 +211,12 @@ export class GfAdminJobsComponent implements OnDestroy, OnInit { }); } - public ngOnDestroy() { - this.unsubscribeSubject.next(); - this.unsubscribeSubject.complete(); - } - private fetchJobs(aStatus?: JobStatus[]) { this.isLoading = true; this.adminService .fetchJobs({ status: aStatus }) - .pipe(takeUntil(this.unsubscribeSubject)) + .pipe(takeUntilDestroyed(this.destroyRef)) .subscribe(({ jobs }) => { this.dataSource = new MatTableDataSource(jobs); this.dataSource.sort = this.sort; diff --git a/apps/client/src/app/components/admin-jobs/admin-jobs.html b/apps/client/src/app/components/admin-jobs/admin-jobs.html index a82294001..cff80498c 100644 --- a/apps/client/src/app/components/admin-jobs/admin-jobs.html +++ b/apps/client/src/app/components/admin-jobs/admin-jobs.html @@ -1,6 +1,15 @@
    + @if (hasPermissionToAccessBullBoard) { +
    + +
    + } +
    diff --git a/libs/common/src/lib/config.ts b/libs/common/src/lib/config.ts index 5da0e0122..08fa2f030 100644 --- a/libs/common/src/lib/config.ts +++ b/libs/common/src/lib/config.ts @@ -51,6 +51,14 @@ export const ASSET_CLASS_MAPPING = new Map([ [AssetClass.REAL_ESTATE, []] ]); +export const BULL_BOARD_COOKIE_NAME = 'bull_board_token'; + +/** + * WARNING: This route is mirrored in `apps/client/proxy.conf.json`. + * If you update this value, you must also update the proxy configuration. + */ +export const BULL_BOARD_ROUTE = '/admin/queues'; + export const CACHE_TTL_NO_CACHE = 1; export const CACHE_TTL_INFINITE = 0; diff --git a/libs/common/src/lib/permissions.ts b/libs/common/src/lib/permissions.ts index 62ae59fbe..a70e61bac 100644 --- a/libs/common/src/lib/permissions.ts +++ b/libs/common/src/lib/permissions.ts @@ -4,6 +4,7 @@ import { Role } from '@prisma/client'; export const permissions = { accessAdminControl: 'accessAdminControl', + accessAdminControlBullBoard: 'accessAdminControlBullBoard', accessAssistant: 'accessAssistant', accessHoldingsChart: 'accessHoldingsChart', createAccess: 'createAccess', diff --git a/package-lock.json b/package-lock.json index 1654d1acd..289fa0ecb 100644 --- a/package-lock.json +++ b/package-lock.json @@ -21,6 +21,9 @@ "@angular/platform-browser-dynamic": "21.1.1", "@angular/router": "21.1.1", "@angular/service-worker": "21.1.1", + "@bull-board/api": "6.20.3", + "@bull-board/express": "6.20.3", + "@bull-board/nestjs": "6.20.3", "@codewithdan/observable-store": "2.2.15", "@date-fns/utc": "2.1.1", "@internationalized/number": "3.6.5", @@ -55,6 +58,7 @@ "class-transformer": "0.5.1", "class-validator": "0.15.1", "color": "5.0.3", + "cookie-parser": "1.4.7", "countries-and-timezones": "3.8.0", "countries-list": "3.2.2", "countup.js": "2.9.0", @@ -123,6 +127,7 @@ "@storybook/angular": "10.1.10", "@trivago/prettier-plugin-sort-imports": "5.2.2", "@types/big.js": "6.2.2", + "@types/cookie-parser": "1.4.10", "@types/fast-redact": "3.0.4", "@types/google-spreadsheet": "3.1.5", "@types/jest": "30.0.0", @@ -3641,6 +3646,53 @@ "devOptional": true, "license": "(Apache-2.0 AND BSD-3-Clause)" }, + "node_modules/@bull-board/api": { + "version": "6.20.3", + "resolved": "https://registry.npmjs.org/@bull-board/api/-/api-6.20.3.tgz", + "integrity": "sha512-cDrsJJsmF4DbbY8/5oHxO4qFtyFjxexsWQKHowsud/8H4mtZN7MZg4fCmNzfaxc9Ov7V6r9Y9F5G2Mq6t7ZEJg==", + "license": "MIT", + "dependencies": { + "redis-info": "^3.1.0" + }, + "peerDependencies": { + "@bull-board/ui": "6.20.3" + } + }, + "node_modules/@bull-board/express": { + "version": "6.20.3", + "resolved": "https://registry.npmjs.org/@bull-board/express/-/express-6.20.3.tgz", + "integrity": "sha512-S6BGeSf/PLwjx5W1IrKxoV8G6iiMmLqT/pldZ6BiC1IDldedisTtAdL1z117swXPv1H7/3hy0vr03dUr8bUCPg==", + "license": "MIT", + "dependencies": { + "@bull-board/api": "6.20.3", + "@bull-board/ui": "6.20.3", + "ejs": "^3.1.10", + "express": "^5.2.1" + } + }, + "node_modules/@bull-board/nestjs": { + "version": "6.20.3", + "resolved": "https://registry.npmjs.org/@bull-board/nestjs/-/nestjs-6.20.3.tgz", + "integrity": "sha512-VFi96Z2M8k3G26H1ivzQnpjKszxh90vrUm78VtMZH/sh8wjm88mJFDXcOgFutOaddx7cc9VNXlKsTTcu6okPFQ==", + "license": "MIT", + "peerDependencies": { + "@bull-board/api": "^6.20.3", + "@nestjs/bull-shared": "^10.0.0 || ^11.0.0", + "@nestjs/common": "^9.0.0 || ^10.0.0 || ^11.0.0", + "@nestjs/core": "^9.0.0 || ^10.0.0 || ^11.0.0", + "reflect-metadata": "^0.1.13 || ^0.2.0", + "rxjs": "^7.8.1" + } + }, + "node_modules/@bull-board/ui": { + "version": "6.20.3", + "resolved": "https://registry.npmjs.org/@bull-board/ui/-/ui-6.20.3.tgz", + "integrity": "sha512-oANyYoW0X+xd0j/09DRyh3u7Q3wqBtXiLEWyZUJIi/Bjp/hINwiw20RwWuRcaFkqkFylEJL9l+pjmeSA9X5L2A==", + "license": "MIT", + "dependencies": { + "@bull-board/api": "6.20.3" + } + }, "node_modules/@chevrotain/cst-dts-gen": { "version": "11.0.3", "resolved": "https://registry.npmjs.org/@chevrotain/cst-dts-gen/-/cst-dts-gen-11.0.3.tgz", @@ -12688,6 +12740,16 @@ "@types/node": "*" } }, + "node_modules/@types/cookie-parser": { + "version": "1.4.10", + "resolved": "https://registry.npmjs.org/@types/cookie-parser/-/cookie-parser-1.4.10.tgz", + "integrity": "sha512-B4xqkqfZ8Wek+rCOeRxsjMS9OgvzebEzzLYw7NHYuvzb7IdxOkI0ZHGgeEBX4PUM7QGVvNSK60T3OvWj3YfBRg==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "@types/express": "*" + } + }, "node_modules/@types/d3": { "version": "7.4.3", "resolved": "https://registry.npmjs.org/@types/d3/-/d3-7.4.3.tgz", @@ -14979,7 +15041,6 @@ "version": "3.2.6", "resolved": "https://registry.npmjs.org/async/-/async-3.2.6.tgz", "integrity": "sha512-htCUDlxyyCLMgaM3xXg0C0LW2xqfuQ6p05pCEIsXuyQ+a1koYKTuBMzRNwmybfLgvJDMd0r1LTn4+E0Ti6C2AA==", - "dev": true, "license": "MIT" }, "node_modules/async-function": { @@ -15373,7 +15434,6 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", - "dev": true, "license": "MIT" }, "node_modules/base64-js": { @@ -15627,7 +15687,6 @@ "version": "1.1.12", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", - "dev": true, "license": "MIT", "dependencies": { "balanced-match": "^1.0.0", @@ -16852,7 +16911,6 @@ "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", - "dev": true, "license": "MIT" }, "node_modules/confbox": { @@ -16924,6 +16982,25 @@ "node": ">= 0.6" } }, + "node_modules/cookie-parser": { + "version": "1.4.7", + "resolved": "https://registry.npmjs.org/cookie-parser/-/cookie-parser-1.4.7.tgz", + "integrity": "sha512-nGUvgXnotP3BsjiLX2ypbQnWoGUPIIfHQNZkkC668ntrzGWEZVW70HDEB1qnNGMicPje6EttlIgzo51YSwNQGw==", + "license": "MIT", + "dependencies": { + "cookie": "0.7.2", + "cookie-signature": "1.0.6" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/cookie-parser/node_modules/cookie-signature": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", + "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==", + "license": "MIT" + }, "node_modules/cookie-signature": { "version": "1.2.2", "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.2.2.tgz", @@ -18812,7 +18889,6 @@ "version": "3.1.10", "resolved": "https://registry.npmjs.org/ejs/-/ejs-3.1.10.tgz", "integrity": "sha512-UeJmFfOrAQS8OJWPZ4qtgHyWExa088/MtK5UEyoJGFH67cDEXkZSviOiKRCZ4Xij0zxI3JECgYs3oKx+AizQBA==", - "dev": true, "license": "Apache-2.0", "dependencies": { "jake": "^10.8.5" @@ -20253,7 +20329,6 @@ "version": "1.0.4", "resolved": "https://registry.npmjs.org/filelist/-/filelist-1.0.4.tgz", "integrity": "sha512-w1cEuf3S+DrLCQL7ET6kz+gmlJdbq9J7yXCSjK/OZCPA+qEN1WyF4ZAf0YYJa4/shHJra2t/d/r8SV4Ji+x+8Q==", - "dev": true, "license": "Apache-2.0", "dependencies": { "minimatch": "^5.0.1" @@ -20263,7 +20338,6 @@ "version": "2.0.2", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz", "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==", - "dev": true, "license": "MIT", "dependencies": { "balanced-match": "^1.0.0" @@ -20273,7 +20347,6 @@ "version": "5.1.6", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz", "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==", - "dev": true, "license": "ISC", "dependencies": { "brace-expansion": "^2.0.1" @@ -21485,7 +21558,6 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "devOptional": true, "license": "MIT", "engines": { "node": ">=8" @@ -23125,7 +23197,6 @@ "version": "10.9.2", "resolved": "https://registry.npmjs.org/jake/-/jake-10.9.2.tgz", "integrity": "sha512-2P4SQ0HrLQ+fw6llpLnOaGAvN2Zu6778SJMrCUwns4fOoG9ayrTiZk3VV8sCPkVZF8ab0zksVpS8FDY5pRCNBA==", - "dev": true, "license": "Apache-2.0", "dependencies": { "async": "^3.2.3", @@ -23144,7 +23215,6 @@ "version": "4.1.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, "license": "MIT", "dependencies": { "ansi-styles": "^4.1.0", @@ -25916,7 +25986,6 @@ "version": "3.1.2", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dev": true, "license": "ISC", "dependencies": { "brace-expansion": "^1.1.7" @@ -29532,6 +29601,15 @@ "node": ">=4" } }, + "node_modules/redis-info": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/redis-info/-/redis-info-3.1.0.tgz", + "integrity": "sha512-ER4L9Sh/vm63DkIE0bkSjxluQlioBiBgf5w1UuldaW/3vPcecdljVDisZhmnCMvsxHNiARTTDDHGg9cGwTfrKg==", + "license": "MIT", + "dependencies": { + "lodash": "^4.17.11" + } + }, "node_modules/redis-parser": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/redis-parser/-/redis-parser-3.0.0.tgz", @@ -32233,7 +32311,6 @@ "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, "license": "MIT", "dependencies": { "has-flag": "^4.0.0" diff --git a/package.json b/package.json index 9fe3ef3c2..33ed6ce65 100644 --- a/package.json +++ b/package.json @@ -66,6 +66,9 @@ "@angular/platform-browser-dynamic": "21.1.1", "@angular/router": "21.1.1", "@angular/service-worker": "21.1.1", + "@bull-board/api": "6.20.3", + "@bull-board/express": "6.20.3", + "@bull-board/nestjs": "6.20.3", "@codewithdan/observable-store": "2.2.15", "@date-fns/utc": "2.1.1", "@internationalized/number": "3.6.5", @@ -100,6 +103,7 @@ "class-transformer": "0.5.1", "class-validator": "0.15.1", "color": "5.0.3", + "cookie-parser": "1.4.7", "countries-and-timezones": "3.8.0", "countries-list": "3.2.2", "countup.js": "2.9.0", @@ -168,6 +172,7 @@ "@storybook/angular": "10.1.10", "@trivago/prettier-plugin-sort-imports": "5.2.2", "@types/big.js": "6.2.2", + "@types/cookie-parser": "1.4.10", "@types/fast-redact": "3.0.4", "@types/google-spreadsheet": "3.1.5", "@types/jest": "30.0.0", From d7a56c5cbc33e68f699255974e5c8097282e2b1c Mon Sep 17 00:00:00 2001 From: Thomas Kaul <4159106+dtslvr@users.noreply.github.com> Date: Tue, 10 Mar 2026 20:24:56 +0100 Subject: [PATCH 118/224] Release 2.249.0 (#6512) --- CHANGELOG.md | 2 +- package-lock.json | 4 ++-- package.json | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a01c57e86..98bcdb20f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,7 +5,7 @@ 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 +## 2.249.0 - 2026-03-10 ### Added diff --git a/package-lock.json b/package-lock.json index 289fa0ecb..e4cf3382c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "ghostfolio", - "version": "2.248.0", + "version": "2.249.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "ghostfolio", - "version": "2.248.0", + "version": "2.249.0", "hasInstallScript": true, "license": "AGPL-3.0", "dependencies": { diff --git a/package.json b/package.json index 33ed6ce65..03f4a527d 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "ghostfolio", - "version": "2.248.0", + "version": "2.249.0", "homepage": "https://ghostfol.io", "license": "AGPL-3.0", "repository": "https://github.com/ghostfolio/ghostfolio", From 8bca0f58303904f427f022d57fd787ad92603769 Mon Sep 17 00:00:00 2001 From: Kenrick Tandrian <60643640+KenTandrian@users.noreply.github.com> Date: Thu, 12 Mar 2026 01:47:24 +0700 Subject: [PATCH 119/224] Task/improve type safety in portfolio proportion chart component (#6491) * Improve type safety in portfolio proportion chart component --- .../portfolio-proportion-chart.component.ts | 94 ++++++++++--------- 1 file changed, 48 insertions(+), 46 deletions(-) diff --git a/libs/ui/src/lib/portfolio-proportion-chart/portfolio-proportion-chart.component.ts b/libs/ui/src/lib/portfolio-proportion-chart/portfolio-proportion-chart.component.ts index 7d0203e9c..2f5d9e4f7 100644 --- a/libs/ui/src/lib/portfolio-proportion-chart/portfolio-proportion-chart.component.ts +++ b/libs/ui/src/lib/portfolio-proportion-chart/portfolio-proportion-chart.component.ts @@ -13,12 +13,11 @@ import { ChangeDetectionStrategy, Component, ElementRef, - EventEmitter, Input, OnChanges, OnDestroy, - Output, - ViewChild + output, + viewChild } from '@angular/core'; import { DataSource } from '@prisma/client'; import { Big } from 'big.js'; @@ -81,15 +80,16 @@ export class GfPortfolioProportionChartComponent @Input() maxItems?: number; @Input() showLabels = false; - @Output() proportionChartClicked = new EventEmitter(); - - @ViewChild('chartCanvas') chartCanvas: ElementRef; - public chart: Chart<'doughnut'>; public isLoading = true; + protected readonly proportionChartClicked = output(); + private readonly OTHER_KEY = 'OTHER'; + private readonly chartCanvas = + viewChild.required>('chartCanvas'); + private colorMap: { [symbol: string]: string; } = {}; @@ -130,45 +130,45 @@ export class GfPortfolioProportionChartComponent }; if (this.keys.length > 0) { + const primaryKey = this.keys[0]; + const secondaryKey = this.keys[1]; + Object.keys(this.data).forEach((symbol) => { - if (this.data[symbol][this.keys[0]]?.toUpperCase()) { - if (chartData[this.data[symbol][this.keys[0]].toUpperCase()]) { - chartData[this.data[symbol][this.keys[0]].toUpperCase()].value = - chartData[ - this.data[symbol][this.keys[0]].toUpperCase() - ].value.plus(this.data[symbol].value || 0); - - if ( - chartData[this.data[symbol][this.keys[0]].toUpperCase()] - .subCategory[this.data[symbol][this.keys[1]]] - ) { - chartData[ - this.data[symbol][this.keys[0]].toUpperCase() - ].subCategory[this.data[symbol][this.keys[1]]].value = chartData[ - this.data[symbol][this.keys[0]].toUpperCase() - ].subCategory[this.data[symbol][this.keys[1]]].value.plus( - this.data[symbol].value || 0 - ); + const asset = this.data[symbol]; + const assetValue = asset.value || 0; + const primaryKeyValue = (asset[primaryKey] as string)?.toUpperCase(); + const secondaryKeyValue = asset[secondaryKey] as string; + + if (primaryKeyValue) { + if (chartData[primaryKeyValue]) { + chartData[primaryKeyValue].value = + chartData[primaryKeyValue].value.plus(assetValue); + + const targetSubCategory = + chartData[primaryKeyValue].subCategory?.[secondaryKeyValue]; + if (targetSubCategory) { + targetSubCategory.value = + targetSubCategory.value.plus(assetValue); } else { - chartData[ - this.data[symbol][this.keys[0]].toUpperCase() - ].subCategory[this.data[symbol][this.keys[1]] ?? UNKNOWN_KEY] = { - value: new Big(this.data[symbol].value || 0) - }; + if (chartData[primaryKeyValue].subCategory) { + chartData[primaryKeyValue].subCategory[ + secondaryKeyValue ?? UNKNOWN_KEY + ] = { + value: new Big(assetValue) + }; + } } } else { - chartData[this.data[symbol][this.keys[0]].toUpperCase()] = { - name: this.data[symbol][this.keys[0]], + chartData[primaryKeyValue] = { + name: asset[primaryKey] as string, subCategory: {}, - value: new Big(this.data[symbol].value || 0) + value: new Big(assetValue) }; - if (this.data[symbol][this.keys[1]]) { - chartData[ - this.data[symbol][this.keys[0]].toUpperCase() - ].subCategory = { - [this.data[symbol][this.keys[1]]]: { - value: new Big(this.data[symbol].value || 0) + if (secondaryKeyValue) { + chartData[primaryKeyValue].subCategory = { + [secondaryKeyValue]: { + value: new Big(assetValue) } }; } @@ -181,10 +181,10 @@ export class GfPortfolioProportionChartComponent } else { chartData[UNKNOWN_KEY] = { name: this.data[symbol].name, - subCategory: this.keys[1] - ? { [this.keys[1]]: { value: new Big(0) } } + subCategory: secondaryKey + ? { [secondaryKey]: { value: new Big(0) } } : undefined, - value: new Big(this.data[symbol].value || 0) + value: new Big(assetValue) }; } } @@ -278,13 +278,15 @@ export class GfPortfolioProportionChartComponent Object.keys(item.subCategory ?? {}).forEach((subCategory) => { if (item.name === UNKNOWN_KEY) { - backgroundColorSubCategory.push(item.color); + backgroundColorSubCategory.push(item.color ?? ''); } else { backgroundColorSubCategory.push( Color(item.color).lighten(lightnessRatio).hex() ); } - dataSubCategory.push(item.subCategory[subCategory].value.toNumber()); + dataSubCategory.push( + item.subCategory?.[subCategory].value.toNumber() ?? 0 + ); labelSubCategory.push(subCategory); lightnessRatio += 0.1; @@ -334,7 +336,7 @@ export class GfPortfolioProportionChartComponent labels }; - if (this.chartCanvas) { + if (this.chartCanvas()) { if (this.chart) { this.chart.data = data; this.chart.options.plugins ??= {}; @@ -343,7 +345,7 @@ export class GfPortfolioProportionChartComponent this.chart.update(); } else { - this.chart = new Chart<'doughnut'>(this.chartCanvas.nativeElement, { + this.chart = new Chart<'doughnut'>(this.chartCanvas().nativeElement, { data, options: { animation: false, From 8f68bd98c25fcec978d958b3bcba836bc12fec1d Mon Sep 17 00:00:00 2001 From: Erwin-N <111194281+Erwin-N@users.noreply.github.com> Date: Wed, 11 Mar 2026 20:01:25 +0100 Subject: [PATCH 120/224] Task/upgrade svgmap to version 2.19.2 (#6503) * Upgrade svgmap to version 2.19.2 * Update changelog --- CHANGELOG.md | 6 ++++++ apps/client/src/styles.scss | 2 +- package-lock.json | 8 ++++---- package.json | 2 +- 4 files changed, 12 insertions(+), 6 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 98bcdb20f..103a09fbb 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 + +- Upgraded `svgmap` from version `2.14.0` to `2.19.2` + ## 2.249.0 - 2026-03-10 ### Added diff --git a/apps/client/src/styles.scss b/apps/client/src/styles.scss index b7a031bfa..142d2ea53 100644 --- a/apps/client/src/styles.scss +++ b/apps/client/src/styles.scss @@ -2,7 +2,7 @@ @import './styles/table'; @import './styles/variables'; -@import 'svgmap/dist/svgMap'; +@import 'svgmap/style.min'; :root { --dark-background: rgb(25, 25, 25); diff --git a/package-lock.json b/package-lock.json index e4cf3382c..9ae63af6e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -90,7 +90,7 @@ "reflect-metadata": "0.2.2", "rxjs": "7.8.1", "stripe": "20.3.0", - "svgmap": "2.14.0", + "svgmap": "2.19.2", "tablemark": "4.1.0", "twitter-api-v2": "1.29.0", "yahoo-finance2": "3.13.2", @@ -32339,9 +32339,9 @@ "license": "BSD-2-Clause" }, "node_modules/svgmap": { - "version": "2.14.0", - "resolved": "https://registry.npmjs.org/svgmap/-/svgmap-2.14.0.tgz", - "integrity": "sha512-+Vklx4DO1uv1SFq6wnJWl/dRjX4uRT9CcsIHuADxAcZ+h5X1OSyDVbNdIu837fx5TtYYuaGRhWuFCXIioN/1ww==", + "version": "2.19.2", + "resolved": "https://registry.npmjs.org/svgmap/-/svgmap-2.19.2.tgz", + "integrity": "sha512-mRqRcQiwwSTh9kTOPhjTmd3ywxA9aTfybBHGAoyuGn9CI9PnAQsuZ7H/2/VEIvgJhi1xM5IGBfk8i4/Ke4iTCQ==", "license": "MIT", "dependencies": { "svg-pan-zoom": "^3.6.2" diff --git a/package.json b/package.json index 03f4a527d..fd62729b9 100644 --- a/package.json +++ b/package.json @@ -135,7 +135,7 @@ "reflect-metadata": "0.2.2", "rxjs": "7.8.1", "stripe": "20.3.0", - "svgmap": "2.14.0", + "svgmap": "2.19.2", "tablemark": "4.1.0", "twitter-api-v2": "1.29.0", "yahoo-finance2": "3.13.2", From 4dabd8ae68adcffeae4c142ef62439f77d822868 Mon Sep 17 00:00:00 2001 From: Kenrick Tandrian <60643640+KenTandrian@users.noreply.github.com> Date: Thu, 12 Mar 2026 02:07:32 +0700 Subject: [PATCH 121/224] Task/improve type safety in symbol autocomplete (#6498) * Improve type safety in symbol autocomplete --- .../lib/interfaces/lookup-item.interface.ts | 2 +- .../symbol-autocomplete.component.ts | 61 +++++++++---------- 2 files changed, 29 insertions(+), 34 deletions(-) diff --git a/libs/common/src/lib/interfaces/lookup-item.interface.ts b/libs/common/src/lib/interfaces/lookup-item.interface.ts index fa91ed690..6cedeca09 100644 --- a/libs/common/src/lib/interfaces/lookup-item.interface.ts +++ b/libs/common/src/lib/interfaces/lookup-item.interface.ts @@ -7,7 +7,7 @@ export interface LookupItem { assetSubClass: AssetSubClass; currency: string; dataProviderInfo: DataProviderInfo; - dataSource: DataSource; + dataSource: DataSource | null; name: string; symbol: string; } diff --git a/libs/ui/src/lib/symbol-autocomplete/symbol-autocomplete.component.ts b/libs/ui/src/lib/symbol-autocomplete/symbol-autocomplete.component.ts index c74e8a077..4b1898b8a 100644 --- a/libs/ui/src/lib/symbol-autocomplete/symbol-autocomplete.component.ts +++ b/libs/ui/src/lib/symbol-autocomplete/symbol-autocomplete.component.ts @@ -8,15 +8,17 @@ import { ChangeDetectionStrategy, ChangeDetectorRef, Component, + DestroyRef, DoCheck, ElementRef, Input, OnChanges, - OnDestroy, OnInit, SimpleChanges, - ViewChild + inject, + viewChild } from '@angular/core'; +import { takeUntilDestroyed } from '@angular/core/rxjs-interop'; import { FormControl, FormsModule, @@ -35,13 +37,12 @@ import { import { MatInput, MatInputModule } from '@angular/material/input'; import { MatProgressSpinnerModule } from '@angular/material/progress-spinner'; import { isString } from 'lodash'; -import { Subject, tap } from 'rxjs'; +import { tap } from 'rxjs'; import { debounceTime, distinctUntilChanged, filter, - switchMap, - takeUntil + switchMap } from 'rxjs/operators'; import { translate } from '../i18n'; @@ -77,21 +78,21 @@ import { AbstractMatFormField } from '../shared/abstract-mat-form-field'; }) export class GfSymbolAutocompleteComponent extends AbstractMatFormField - implements DoCheck, OnChanges, OnDestroy, OnInit + implements DoCheck, OnChanges, OnInit { @Input() public defaultLookupItems: LookupItem[] = []; @Input() public isLoading = false; - @ViewChild('symbolAutocomplete') public symbolAutocomplete: MatAutocomplete; - @Input() private includeIndices = false; - @ViewChild(MatInput) private input: MatInput; - - public control = new FormControl(); + public readonly control = new FormControl(); public lookupItems: (LookupItem & { assetSubClassString: string })[] = []; - private unsubscribeSubject = new Subject(); + protected readonly symbolAutocomplete = + viewChild.required('symbolAutocomplete'); + + private readonly destroyRef = inject(DestroyRef); + private readonly input = viewChild.required(MatInput); public constructor( public readonly _elementRef: ElementRef, @@ -105,13 +106,22 @@ export class GfSymbolAutocompleteComponent this.controlType = 'symbol-autocomplete'; } + public get empty() { + return this.input().empty; + } + + public set value(value: LookupItem) { + this.control.setValue(value); + super.value = value; + } + public ngOnInit() { if (this.disabled) { this.control.disable(); } this.control.valueChanges - .pipe(takeUntil(this.unsubscribeSubject)) + .pipe(takeUntilDestroyed(this.destroyRef)) .subscribe(() => { if (super.value) { super.value.dataSource = null; @@ -136,7 +146,7 @@ export class GfSymbolAutocompleteComponent }), debounceTime(400), distinctUntilChanged(), - takeUntil(this.unsubscribeSubject), + takeUntilDestroyed(this.destroyRef), switchMap((query: string) => { return this.dataService.fetchSymbols({ query, @@ -168,12 +178,8 @@ export class GfSymbolAutocompleteComponent return aLookupItem?.symbol ?? ''; } - public get empty() { - return this.input?.empty; - } - public focus() { - this.input.focus(); + this.input().focus(); } public isValueInOptions(value: string) { @@ -185,7 +191,7 @@ export class GfSymbolAutocompleteComponent public ngDoCheck() { if (this.ngControl) { this.validateRequired(); - this.errorState = this.ngControl.invalid && this.ngControl.touched; + this.errorState = !!(this.ngControl.invalid && this.ngControl.touched); this.stateChanges.next(); } } @@ -197,18 +203,6 @@ export class GfSymbolAutocompleteComponent } as LookupItem; } - public set value(value: LookupItem) { - this.control.setValue(value); - super.value = value; - } - - public ngOnDestroy() { - super.ngOnDestroy(); - - this.unsubscribeSubject.next(); - this.unsubscribeSubject.complete(); - } - private showDefaultOptions() { this.lookupItems = this.defaultLookupItems.map((lookupItem) => { return { @@ -224,8 +218,9 @@ export class GfSymbolAutocompleteComponent const requiredCheck = super.required ? !super.value?.dataSource || !super.value?.symbol : false; + if (requiredCheck) { - this.ngControl.control.setErrors({ invalidData: true }); + this.ngControl.control?.setErrors({ invalidData: true }); } } } From bac3e2ebf36aedad595845bc204e518fe8821ef1 Mon Sep 17 00:00:00 2001 From: Erwin-N <111194281+Erwin-N@users.noreply.github.com> Date: Thu, 12 Mar 2026 17:25:22 +0100 Subject: [PATCH 122/224] Task/eliminate OnDestroy lifecycle hook from FIRE page (#6521) * Eliminate OnDestroy lifecycle hook --- .../portfolio/fire/fire-page.component.ts | 48 +++++++++---------- 1 file changed, 23 insertions(+), 25 deletions(-) diff --git a/apps/client/src/app/pages/portfolio/fire/fire-page.component.ts b/apps/client/src/app/pages/portfolio/fire/fire-page.component.ts index 27db6c76e..2f7568982 100644 --- a/apps/client/src/app/pages/portfolio/fire/fire-page.component.ts +++ b/apps/client/src/app/pages/portfolio/fire/fire-page.component.ts @@ -12,14 +12,18 @@ import { DataService } from '@ghostfolio/ui/services'; import { GfValueComponent } from '@ghostfolio/ui/value'; import { CommonModule, NgStyle } from '@angular/common'; -import { ChangeDetectorRef, Component, OnDestroy, OnInit } from '@angular/core'; +import { + ChangeDetectorRef, + Component, + DestroyRef, + OnInit +} from '@angular/core'; +import { takeUntilDestroyed } from '@angular/core/rxjs-interop'; import { FormsModule, ReactiveFormsModule } from '@angular/forms'; import { FormControl } from '@angular/forms'; import { Big } from 'big.js'; import { DeviceDetectorService } from 'ngx-device-detector'; import { NgxSkeletonLoaderModule } from 'ngx-skeleton-loader'; -import { Subject } from 'rxjs'; -import { takeUntil } from 'rxjs/operators'; @Component({ imports: [ @@ -36,7 +40,7 @@ import { takeUntil } from 'rxjs/operators'; styleUrls: ['./fire-page.scss'], templateUrl: './fire-page.html' }) -export class GfFirePageComponent implements OnDestroy, OnInit { +export class GfFirePageComponent implements OnInit { public deviceType: string; public fireWealth: FireWealth; public hasImpersonationId: boolean; @@ -52,11 +56,10 @@ export class GfFirePageComponent implements OnDestroy, OnInit { public withdrawalRatePerYear: Big; public withdrawalRatePerYearProjected: Big; - private unsubscribeSubject = new Subject(); - public constructor( private changeDetectorRef: ChangeDetectorRef, private dataService: DataService, + private destroyRef: DestroyRef, private deviceService: DeviceDetectorService, private impersonationStorageService: ImpersonationStorageService, private userService: UserService @@ -68,7 +71,7 @@ export class GfFirePageComponent implements OnDestroy, OnInit { this.dataService .fetchPortfolioDetails() - .pipe(takeUntil(this.unsubscribeSubject)) + .pipe(takeUntilDestroyed(this.destroyRef)) .subscribe(({ summary }) => { this.fireWealth = { today: { @@ -92,19 +95,19 @@ export class GfFirePageComponent implements OnDestroy, OnInit { this.impersonationStorageService .onChangeHasImpersonation() - .pipe(takeUntil(this.unsubscribeSubject)) + .pipe(takeUntilDestroyed(this.destroyRef)) .subscribe((impersonationId) => { this.hasImpersonationId = !!impersonationId; }); this.safeWithdrawalRateControl.valueChanges - .pipe(takeUntil(this.unsubscribeSubject)) + .pipe(takeUntilDestroyed(this.destroyRef)) .subscribe((value) => { this.onSafeWithdrawalRateChange(Number(value)); }); this.userService.stateChanged - .pipe(takeUntil(this.unsubscribeSubject)) + .pipe(takeUntilDestroyed(this.destroyRef)) .subscribe((state) => { if (state?.user) { this.user = state.user; @@ -132,11 +135,11 @@ export class GfFirePageComponent implements OnDestroy, OnInit { public onAnnualInterestRateChange(annualInterestRate: number) { this.dataService .putUserSetting({ annualInterestRate }) - .pipe(takeUntil(this.unsubscribeSubject)) + .pipe(takeUntilDestroyed(this.destroyRef)) .subscribe(() => { this.userService .get(true) - .pipe(takeUntil(this.unsubscribeSubject)) + .pipe(takeUntilDestroyed(this.destroyRef)) .subscribe((user) => { this.user = user; @@ -163,11 +166,11 @@ export class GfFirePageComponent implements OnDestroy, OnInit { retirementDate: retirementDate.toISOString(), projectedTotalAmount: null }) - .pipe(takeUntil(this.unsubscribeSubject)) + .pipe(takeUntilDestroyed(this.destroyRef)) .subscribe(() => { this.userService .get(true) - .pipe(takeUntil(this.unsubscribeSubject)) + .pipe(takeUntilDestroyed(this.destroyRef)) .subscribe((user) => { this.user = user; @@ -179,11 +182,11 @@ export class GfFirePageComponent implements OnDestroy, OnInit { public onSafeWithdrawalRateChange(safeWithdrawalRate: number) { this.dataService .putUserSetting({ safeWithdrawalRate }) - .pipe(takeUntil(this.unsubscribeSubject)) + .pipe(takeUntilDestroyed(this.destroyRef)) .subscribe(() => { this.userService .get(true) - .pipe(takeUntil(this.unsubscribeSubject)) + .pipe(takeUntilDestroyed(this.destroyRef)) .subscribe((user) => { this.user = user; @@ -198,11 +201,11 @@ export class GfFirePageComponent implements OnDestroy, OnInit { public onSavingsRateChange(savingsRate: number) { this.dataService .putUserSetting({ savingsRate }) - .pipe(takeUntil(this.unsubscribeSubject)) + .pipe(takeUntilDestroyed(this.destroyRef)) .subscribe(() => { this.userService .get(true) - .pipe(takeUntil(this.unsubscribeSubject)) + .pipe(takeUntilDestroyed(this.destroyRef)) .subscribe((user) => { this.user = user; @@ -217,11 +220,11 @@ export class GfFirePageComponent implements OnDestroy, OnInit { projectedTotalAmount, retirementDate: null }) - .pipe(takeUntil(this.unsubscribeSubject)) + .pipe(takeUntilDestroyed(this.destroyRef)) .subscribe(() => { this.userService .get(true) - .pipe(takeUntil(this.unsubscribeSubject)) + .pipe(takeUntilDestroyed(this.destroyRef)) .subscribe((user) => { this.user = user; @@ -230,11 +233,6 @@ export class GfFirePageComponent implements OnDestroy, OnInit { }); } - public ngOnDestroy() { - this.unsubscribeSubject.next(); - this.unsubscribeSubject.complete(); - } - private calculateWithdrawalRates() { if (this.fireWealth && this.user?.settings?.safeWithdrawalRate) { this.withdrawalRatePerYear = new Big( From 55d717ca9397b5e5d3ee5c360b550eedd3dcd5ad Mon Sep 17 00:00:00 2001 From: Erwin-N <111194281+Erwin-N@users.noreply.github.com> Date: Thu, 12 Mar 2026 20:03:37 +0100 Subject: [PATCH 123/224] Task/eliminate OnDestroy lifecycle hook from X-ray page (#6522) * Eliminate OnDestroy lifecycle hook --- .../portfolio/x-ray/x-ray-page.component.ts | 22 +++++++------------ 1 file changed, 8 insertions(+), 14 deletions(-) diff --git a/apps/client/src/app/pages/portfolio/x-ray/x-ray-page.component.ts b/apps/client/src/app/pages/portfolio/x-ray/x-ray-page.component.ts index 70b748b10..e97fd4876 100644 --- a/apps/client/src/app/pages/portfolio/x-ray/x-ray-page.component.ts +++ b/apps/client/src/app/pages/portfolio/x-ray/x-ray-page.component.ts @@ -12,7 +12,8 @@ import { GfPremiumIndicatorComponent } from '@ghostfolio/ui/premium-indicator'; import { DataService } from '@ghostfolio/ui/services'; import { NgClass } from '@angular/common'; -import { ChangeDetectorRef, Component } from '@angular/core'; +import { ChangeDetectorRef, Component, DestroyRef } from '@angular/core'; +import { takeUntilDestroyed } from '@angular/core/rxjs-interop'; import { IonIcon } from '@ionic/angular/standalone'; import { addIcons } from 'ionicons'; import { @@ -21,7 +22,6 @@ import { warningOutline } from 'ionicons/icons'; import { NgxSkeletonLoaderModule } from 'ngx-skeleton-loader'; -import { Subject, takeUntil } from 'rxjs'; @Component({ imports: [ @@ -48,11 +48,10 @@ export class GfXRayPageComponent { public statistics: PortfolioReportResponse['xRay']['statistics']; public user: User; - private unsubscribeSubject = new Subject(); - public constructor( private changeDetectorRef: ChangeDetectorRef, private dataService: DataService, + private destroyRef: DestroyRef, private impersonationStorageService: ImpersonationStorageService, private userService: UserService ) { @@ -62,13 +61,13 @@ export class GfXRayPageComponent { public ngOnInit() { this.impersonationStorageService .onChangeHasImpersonation() - .pipe(takeUntil(this.unsubscribeSubject)) + .pipe(takeUntilDestroyed(this.destroyRef)) .subscribe((impersonationId) => { this.hasImpersonationId = !!impersonationId; }); this.userService.stateChanged - .pipe(takeUntil(this.unsubscribeSubject)) + .pipe(takeUntilDestroyed(this.destroyRef)) .subscribe((state) => { if (state?.user) { this.user = state.user; @@ -91,28 +90,23 @@ export class GfXRayPageComponent { public onRulesUpdated(event: UpdateUserSettingDto) { this.dataService .putUserSetting(event) - .pipe(takeUntil(this.unsubscribeSubject)) + .pipe(takeUntilDestroyed(this.destroyRef)) .subscribe(() => { this.userService .get(true) - .pipe(takeUntil(this.unsubscribeSubject)) + .pipe(takeUntilDestroyed(this.destroyRef)) .subscribe(); this.initializePortfolioReport(); }); } - public ngOnDestroy() { - this.unsubscribeSubject.next(); - this.unsubscribeSubject.complete(); - } - private initializePortfolioReport() { this.isLoading = true; this.dataService .fetchPortfolioReport() - .pipe(takeUntil(this.unsubscribeSubject)) + .pipe(takeUntilDestroyed(this.destroyRef)) .subscribe(({ xRay: { categories, statistics } }) => { this.categories = categories; this.inactiveRules = this.mergeInactiveRules(categories); From cfa974385adaadd5c0b94ebde95bce341519d02e Mon Sep 17 00:00:00 2001 From: Erwin-N <111194281+Erwin-N@users.noreply.github.com> Date: Fri, 13 Mar 2026 12:08:54 +0100 Subject: [PATCH 124/224] Task/eliminate OnDestroy lifecycle hook from accounts page (#6527) * Eliminate OnDestroy lifecycle hook --- .../pages/accounts/accounts-page.component.ts | 52 +++++++++---------- 1 file changed, 26 insertions(+), 26 deletions(-) diff --git a/apps/client/src/app/pages/accounts/accounts-page.component.ts b/apps/client/src/app/pages/accounts/accounts-page.component.ts index a0eef4eba..fdc78a8c4 100644 --- a/apps/client/src/app/pages/accounts/accounts-page.component.ts +++ b/apps/client/src/app/pages/accounts/accounts-page.component.ts @@ -13,7 +13,13 @@ import { GfAccountsTableComponent } from '@ghostfolio/ui/accounts-table'; import { NotificationService } from '@ghostfolio/ui/notifications'; import { DataService } from '@ghostfolio/ui/services'; -import { ChangeDetectorRef, Component, OnDestroy, OnInit } from '@angular/core'; +import { + ChangeDetectorRef, + Component, + DestroyRef, + OnInit +} from '@angular/core'; +import { takeUntilDestroyed } from '@angular/core/rxjs-interop'; import { MatButtonModule } from '@angular/material/button'; import { MatDialog } from '@angular/material/dialog'; import { ActivatedRoute, Router, RouterModule } from '@angular/router'; @@ -21,8 +27,8 @@ import { Account as AccountModel } from '@prisma/client'; import { addIcons } from 'ionicons'; import { addOutline } from 'ionicons/icons'; import { DeviceDetectorService } from 'ngx-device-detector'; -import { EMPTY, Subject, Subscription } from 'rxjs'; -import { catchError, takeUntil } from 'rxjs/operators'; +import { EMPTY, Subscription } from 'rxjs'; +import { catchError } from 'rxjs/operators'; import { GfCreateOrUpdateAccountDialogComponent } from './create-or-update-account-dialog/create-or-update-account-dialog.component'; import { CreateOrUpdateAccountDialogParams } from './create-or-update-account-dialog/interfaces/interfaces'; @@ -36,7 +42,7 @@ import { GfTransferBalanceDialogComponent } from './transfer-balance/transfer-ba styleUrls: ['./accounts-page.scss'], templateUrl: './accounts-page.html' }) -export class GfAccountsPageComponent implements OnDestroy, OnInit { +export class GfAccountsPageComponent implements OnInit { public accounts: AccountModel[]; public activitiesCount = 0; public deviceType: string; @@ -48,11 +54,10 @@ export class GfAccountsPageComponent implements OnDestroy, OnInit { public totalValueInBaseCurrency = 0; public user: User; - private unsubscribeSubject = new Subject(); - public constructor( private changeDetectorRef: ChangeDetectorRef, private dataService: DataService, + private destroyRef: DestroyRef, private deviceService: DeviceDetectorService, private dialog: MatDialog, private impersonationStorageService: ImpersonationStorageService, @@ -62,7 +67,7 @@ export class GfAccountsPageComponent implements OnDestroy, OnInit { private userService: UserService ) { this.route.queryParams - .pipe(takeUntil(this.unsubscribeSubject)) + .pipe(takeUntilDestroyed(this.destroyRef)) .subscribe((params) => { if (params['accountId'] && params['accountDetailDialog']) { this.openAccountDetailDialog(params['accountId']); @@ -94,13 +99,13 @@ export class GfAccountsPageComponent implements OnDestroy, OnInit { this.impersonationStorageService .onChangeHasImpersonation() - .pipe(takeUntil(this.unsubscribeSubject)) + .pipe(takeUntilDestroyed(this.destroyRef)) .subscribe((impersonationId) => { this.hasImpersonationId = !!impersonationId; }); this.userService.stateChanged - .pipe(takeUntil(this.unsubscribeSubject)) + .pipe(takeUntilDestroyed(this.destroyRef)) .subscribe((state) => { if (state?.user) { this.user = state.user; @@ -124,7 +129,7 @@ export class GfAccountsPageComponent implements OnDestroy, OnInit { public fetchAccounts() { this.dataService .fetchAccounts() - .pipe(takeUntil(this.unsubscribeSubject)) + .pipe(takeUntilDestroyed(this.destroyRef)) .subscribe( ({ accounts, @@ -151,11 +156,11 @@ export class GfAccountsPageComponent implements OnDestroy, OnInit { this.dataService .deleteAccount(aId) - .pipe(takeUntil(this.unsubscribeSubject)) + .pipe(takeUntilDestroyed(this.destroyRef)) .subscribe(() => { this.userService .get(true) - .pipe(takeUntil(this.unsubscribeSubject)) + .pipe(takeUntilDestroyed(this.destroyRef)) .subscribe(); this.fetchAccounts(); @@ -204,18 +209,18 @@ export class GfAccountsPageComponent implements OnDestroy, OnInit { dialogRef .afterClosed() - .pipe(takeUntil(this.unsubscribeSubject)) + .pipe(takeUntilDestroyed(this.destroyRef)) .subscribe((account: UpdateAccountDto | null) => { if (account) { this.reset(); this.dataService .putAccount(account) - .pipe(takeUntil(this.unsubscribeSubject)) + .pipe(takeUntilDestroyed(this.destroyRef)) .subscribe(() => { this.userService .get(true) - .pipe(takeUntil(this.unsubscribeSubject)) + .pipe(takeUntilDestroyed(this.destroyRef)) .subscribe(); this.fetchAccounts(); @@ -228,11 +233,6 @@ export class GfAccountsPageComponent implements OnDestroy, OnInit { }); } - public ngOnDestroy() { - this.unsubscribeSubject.next(); - this.unsubscribeSubject.complete(); - } - private openAccountDetailDialog(aAccountId: string) { const dialogRef = this.dialog.open< GfAccountDetailDialogComponent, @@ -254,7 +254,7 @@ export class GfAccountsPageComponent implements OnDestroy, OnInit { dialogRef .afterClosed() - .pipe(takeUntil(this.unsubscribeSubject)) + .pipe(takeUntilDestroyed(this.destroyRef)) .subscribe(() => { this.fetchAccounts(); @@ -284,18 +284,18 @@ export class GfAccountsPageComponent implements OnDestroy, OnInit { dialogRef .afterClosed() - .pipe(takeUntil(this.unsubscribeSubject)) + .pipe(takeUntilDestroyed(this.destroyRef)) .subscribe((account: CreateAccountDto | null) => { if (account) { this.reset(); this.dataService .postAccount(account) - .pipe(takeUntil(this.unsubscribeSubject)) + .pipe(takeUntilDestroyed(this.destroyRef)) .subscribe(() => { this.userService .get(true) - .pipe(takeUntil(this.unsubscribeSubject)) + .pipe(takeUntilDestroyed(this.destroyRef)) .subscribe(); this.fetchAccounts(); @@ -321,7 +321,7 @@ export class GfAccountsPageComponent implements OnDestroy, OnInit { dialogRef .afterClosed() - .pipe(takeUntil(this.unsubscribeSubject)) + .pipe(takeUntilDestroyed(this.destroyRef)) .subscribe((data: any) => { if (data) { this.reset(); @@ -343,7 +343,7 @@ export class GfAccountsPageComponent implements OnDestroy, OnInit { return EMPTY; }), - takeUntil(this.unsubscribeSubject) + takeUntilDestroyed(this.destroyRef) ) .subscribe(() => { this.fetchAccounts(); From e127c1af2b74b79005cb351d53b2a16992ab80b4 Mon Sep 17 00:00:00 2001 From: Erwin-N <111194281+Erwin-N@users.noreply.github.com> Date: Fri, 13 Mar 2026 20:14:13 +0100 Subject: [PATCH 125/224] Task/eliminate OnDestroy lifecycle hook from about page (#6529) * Eliminate OnDestroy lifecycle hook --- .../src/app/pages/about/about-page.component.ts | 17 +++++------------ 1 file changed, 5 insertions(+), 12 deletions(-) diff --git a/apps/client/src/app/pages/about/about-page.component.ts b/apps/client/src/app/pages/about/about-page.component.ts index 5ddb6b2e0..1e749d1cd 100644 --- a/apps/client/src/app/pages/about/about-page.component.ts +++ b/apps/client/src/app/pages/about/about-page.component.ts @@ -8,9 +8,10 @@ import { ChangeDetectorRef, Component, CUSTOM_ELEMENTS_SCHEMA, - OnDestroy, + DestroyRef, OnInit } from '@angular/core'; +import { takeUntilDestroyed } from '@angular/core/rxjs-interop'; import { MatTabsModule } from '@angular/material/tabs'; import { RouterModule } from '@angular/router'; import { IonIcon } from '@ionic/angular/standalone'; @@ -24,8 +25,6 @@ import { sparklesOutline } from 'ionicons/icons'; import { DeviceDetectorService } from 'ngx-device-detector'; -import { Subject } from 'rxjs'; -import { takeUntil } from 'rxjs/operators'; @Component({ host: { class: 'page has-tabs' }, @@ -35,17 +34,16 @@ import { takeUntil } from 'rxjs/operators'; styleUrls: ['./about-page.scss'], templateUrl: './about-page.html' }) -export class AboutPageComponent implements OnDestroy, OnInit { +export class AboutPageComponent implements OnInit { public deviceType: string; public hasPermissionForSubscription: boolean; public tabs: TabConfiguration[] = []; public user: User; - private unsubscribeSubject = new Subject(); - public constructor( private changeDetectorRef: ChangeDetectorRef, private dataService: DataService, + private destroyRef: DestroyRef, private deviceService: DeviceDetectorService, private userService: UserService ) { @@ -57,7 +55,7 @@ export class AboutPageComponent implements OnDestroy, OnInit { ); this.userService.stateChanged - .pipe(takeUntil(this.unsubscribeSubject)) + .pipe(takeUntilDestroyed(this.destroyRef)) .subscribe((state) => { this.tabs = [ { @@ -118,9 +116,4 @@ export class AboutPageComponent implements OnDestroy, OnInit { public ngOnInit() { this.deviceType = this.deviceService.getDeviceInfo().deviceType; } - - public ngOnDestroy() { - this.unsubscribeSubject.next(); - this.unsubscribeSubject.complete(); - } } From 88307cca2863ac905f45d3d9de3cd5ab50101159 Mon Sep 17 00:00:00 2001 From: Erwin-N <111194281+Erwin-N@users.noreply.github.com> Date: Fri, 13 Mar 2026 20:19:56 +0100 Subject: [PATCH 126/224] Task/eliminate OnDestroy lifecycle hook from portfolio analysis page (#6524) * Eliminate OnDestroy lifecycle hook --- .../analysis/analysis-page.component.ts | 37 ++++++++----------- 1 file changed, 15 insertions(+), 22 deletions(-) diff --git a/apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts b/apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts index 5cd24777c..47845ea6f 100644 --- a/apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts +++ b/apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts @@ -24,10 +24,11 @@ import { Clipboard } from '@angular/cdk/clipboard'; import { ChangeDetectorRef, Component, - OnDestroy, + DestroyRef, OnInit, ViewChild } from '@angular/core'; +import { takeUntilDestroyed } from '@angular/core/rxjs-interop'; import { MatButtonModule } from '@angular/material/button'; import { MatCardModule } from '@angular/material/card'; import { MatMenuModule, MatMenuTrigger } from '@angular/material/menu'; @@ -42,8 +43,6 @@ import { isNumber, sortBy } from 'lodash'; import ms from 'ms'; import { DeviceDetectorService } from 'ngx-device-detector'; import { NgxSkeletonLoaderModule } from 'ngx-skeleton-loader'; -import { Subject } from 'rxjs'; -import { takeUntil } from 'rxjs/operators'; @Component({ imports: [ @@ -64,7 +63,7 @@ import { takeUntil } from 'rxjs/operators'; styleUrls: ['./analysis-page.scss'], templateUrl: './analysis-page.html' }) -export class GfAnalysisPageComponent implements OnDestroy, OnInit { +export class GfAnalysisPageComponent implements OnInit { @ViewChild(MatMenuTrigger) actionsMenuButton!: MatMenuTrigger; public benchmark: Partial; @@ -102,12 +101,11 @@ export class GfAnalysisPageComponent implements OnDestroy, OnInit { public unitLongestStreak: string; public user: User; - private unsubscribeSubject = new Subject(); - public constructor( private changeDetectorRef: ChangeDetectorRef, private clipboard: Clipboard, private dataService: DataService, + private destroyRef: DestroyRef, private deviceService: DeviceDetectorService, private impersonationStorageService: ImpersonationStorageService, private snackBar: MatSnackBar, @@ -135,13 +133,13 @@ export class GfAnalysisPageComponent implements OnDestroy, OnInit { this.impersonationStorageService .onChangeHasImpersonation() - .pipe(takeUntil(this.unsubscribeSubject)) + .pipe(takeUntilDestroyed(this.destroyRef)) .subscribe((impersonationId) => { this.hasImpersonationId = !!impersonationId; }); this.userService.stateChanged - .pipe(takeUntil(this.unsubscribeSubject)) + .pipe(takeUntilDestroyed(this.destroyRef)) .subscribe((state) => { if (state?.user) { this.user = state.user; @@ -163,11 +161,11 @@ export class GfAnalysisPageComponent implements OnDestroy, OnInit { public onChangeBenchmark(symbolProfileId: string) { this.dataService .putUserSetting({ benchmark: symbolProfileId }) - .pipe(takeUntil(this.unsubscribeSubject)) + .pipe(takeUntilDestroyed(this.destroyRef)) .subscribe(() => { this.userService .get(true) - .pipe(takeUntil(this.unsubscribeSubject)) + .pipe(takeUntilDestroyed(this.destroyRef)) .subscribe((user) => { this.user = user; @@ -193,7 +191,7 @@ export class GfAnalysisPageComponent implements OnDestroy, OnInit { mode, filters: this.userService.getFilters() }) - .pipe(takeUntil(this.unsubscribeSubject)) + .pipe(takeUntilDestroyed(this.destroyRef)) .subscribe(({ prompt }) => { this.clipboard.copy(prompt); @@ -207,7 +205,7 @@ export class GfAnalysisPageComponent implements OnDestroy, OnInit { snackBarRef .onAction() - .pipe(takeUntil(this.unsubscribeSubject)) + .pipe(takeUntilDestroyed(this.destroyRef)) .subscribe(() => { window.open('https://duck.ai', '_blank'); }); @@ -222,11 +220,6 @@ export class GfAnalysisPageComponent implements OnDestroy, OnInit { }); } - public ngOnDestroy() { - this.unsubscribeSubject.next(); - this.unsubscribeSubject.complete(); - } - private fetchDividendsAndInvestments() { this.isLoadingDividendTimelineChart = true; this.isLoadingInvestmentTimelineChart = true; @@ -237,7 +230,7 @@ export class GfAnalysisPageComponent implements OnDestroy, OnInit { groupBy: this.mode, range: this.user?.settings?.dateRange }) - .pipe(takeUntil(this.unsubscribeSubject)) + .pipe(takeUntilDestroyed(this.destroyRef)) .subscribe(({ dividends }) => { this.dividendsByGroup = dividends; @@ -252,7 +245,7 @@ export class GfAnalysisPageComponent implements OnDestroy, OnInit { groupBy: this.mode, range: this.user?.settings?.dateRange }) - .pipe(takeUntil(this.unsubscribeSubject)) + .pipe(takeUntilDestroyed(this.destroyRef)) .subscribe(({ investments, streaks }) => { this.investmentsByGroup = investments; this.streaks = streaks; @@ -287,7 +280,7 @@ export class GfAnalysisPageComponent implements OnDestroy, OnInit { filters: this.userService.getFilters(), range: this.user?.settings?.dateRange }) - .pipe(takeUntil(this.unsubscribeSubject)) + .pipe(takeUntilDestroyed(this.destroyRef)) .subscribe(({ chart, firstOrderDate, performance }) => { this.firstOrderDate = firstOrderDate ?? new Date(); @@ -346,7 +339,7 @@ export class GfAnalysisPageComponent implements OnDestroy, OnInit { filters: this.userService.getFilters(), range: this.user?.settings?.dateRange }) - .pipe(takeUntil(this.unsubscribeSubject)) + .pipe(takeUntilDestroyed(this.destroyRef)) .subscribe(({ holdings }) => { const holdingsSorted = sortBy( holdings.filter(({ netPerformancePercentWithCurrencyEffect }) => { @@ -397,7 +390,7 @@ export class GfAnalysisPageComponent implements OnDestroy, OnInit { range: this.user?.settings?.dateRange, startDate: this.firstOrderDate }) - .pipe(takeUntil(this.unsubscribeSubject)) + .pipe(takeUntilDestroyed(this.destroyRef)) .subscribe(({ marketData }) => { this.benchmarkDataItems = marketData.map(({ date, value }) => { return { From 269b981e8625d5196b0a83f2565f7ce88f3f3548 Mon Sep 17 00:00:00 2001 From: Thomas Kaul <4159106+dtslvr@users.noreply.github.com> Date: Fri, 13 Mar 2026 20:28:49 +0100 Subject: [PATCH 127/224] Task/implement OnModuleInit in I18nService (#6448) * Implement onModuleInit --- apps/api/src/services/i18n/i18n.service.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/apps/api/src/services/i18n/i18n.service.ts b/apps/api/src/services/i18n/i18n.service.ts index cf340d7c6..1cdb811a9 100644 --- a/apps/api/src/services/i18n/i18n.service.ts +++ b/apps/api/src/services/i18n/i18n.service.ts @@ -1,16 +1,16 @@ import { DEFAULT_LANGUAGE_CODE } from '@ghostfolio/common/config'; -import { Injectable, Logger } from '@nestjs/common'; +import { Injectable, Logger, OnModuleInit } from '@nestjs/common'; import * as cheerio from 'cheerio'; import { readFileSync, readdirSync } from 'node:fs'; import { join } from 'node:path'; @Injectable() -export class I18nService { +export class I18nService implements OnModuleInit { private localesPath = join(__dirname, 'assets', 'locales'); private translations: { [locale: string]: cheerio.CheerioAPI } = {}; - public constructor() { + public onModuleInit() { this.loadFiles(); } From 860ae50ad948083fe62d2601ba7d1b6563be076f Mon Sep 17 00:00:00 2001 From: Erwin <111194281+Erwin-N@users.noreply.github.com> Date: Sat, 14 Mar 2026 09:02:30 +0100 Subject: [PATCH 128/224] Task/eliminate OnDestroy lifecycle hook from home holdings component (#6547) * Eliminate OnDestroy lifecycle hook --- .../home-holdings/home-holdings.component.ts | 27 +++++++------------ 1 file changed, 10 insertions(+), 17 deletions(-) diff --git a/apps/client/src/app/components/home-holdings/home-holdings.component.ts b/apps/client/src/app/components/home-holdings/home-holdings.component.ts index df5e43087..19a48ccd8 100644 --- a/apps/client/src/app/components/home-holdings/home-holdings.component.ts +++ b/apps/client/src/app/components/home-holdings/home-holdings.component.ts @@ -19,9 +19,10 @@ import { ChangeDetectorRef, Component, CUSTOM_ELEMENTS_SCHEMA, - OnDestroy, + DestroyRef, OnInit } from '@angular/core'; +import { takeUntilDestroyed } from '@angular/core/rxjs-interop'; import { FormControl, FormsModule, ReactiveFormsModule } from '@angular/forms'; import { MatButtonModule } from '@angular/material/button'; import { MatButtonToggleModule } from '@angular/material/button-toggle'; @@ -30,8 +31,6 @@ import { IonIcon } from '@ionic/angular/standalone'; import { addIcons } from 'ionicons'; import { gridOutline, reorderFourOutline } from 'ionicons/icons'; import { DeviceDetectorService } from 'ngx-device-detector'; -import { Subject } from 'rxjs'; -import { takeUntil } from 'rxjs/operators'; @Component({ imports: [ @@ -51,7 +50,7 @@ import { takeUntil } from 'rxjs/operators'; styleUrls: ['./home-holdings.scss'], templateUrl: './home-holdings.html' }) -export class GfHomeHoldingsComponent implements OnDestroy, OnInit { +export class GfHomeHoldingsComponent implements OnInit { public static DEFAULT_HOLDINGS_VIEW_MODE: HoldingsViewMode = 'TABLE'; public deviceType: string; @@ -71,11 +70,10 @@ export class GfHomeHoldingsComponent implements OnDestroy, OnInit { GfHomeHoldingsComponent.DEFAULT_HOLDINGS_VIEW_MODE ); - private unsubscribeSubject = new Subject(); - public constructor( private changeDetectorRef: ChangeDetectorRef, private dataService: DataService, + private destroyRef: DestroyRef, private deviceService: DeviceDetectorService, private impersonationStorageService: ImpersonationStorageService, private router: Router, @@ -89,13 +87,13 @@ export class GfHomeHoldingsComponent implements OnDestroy, OnInit { this.impersonationStorageService .onChangeHasImpersonation() - .pipe(takeUntil(this.unsubscribeSubject)) + .pipe(takeUntilDestroyed(this.destroyRef)) .subscribe((impersonationId) => { this.hasImpersonationId = !!impersonationId; }); this.userService.stateChanged - .pipe(takeUntil(this.unsubscribeSubject)) + .pipe(takeUntilDestroyed(this.destroyRef)) .subscribe((state) => { if (state?.user) { this.user = state.user; @@ -117,15 +115,15 @@ export class GfHomeHoldingsComponent implements OnDestroy, OnInit { }); this.viewModeFormControl.valueChanges - .pipe(takeUntil(this.unsubscribeSubject)) + .pipe(takeUntilDestroyed(this.destroyRef)) .subscribe((holdingsViewMode) => { this.dataService .putUserSetting({ holdingsViewMode }) - .pipe(takeUntil(this.unsubscribeSubject)) + .pipe(takeUntilDestroyed(this.destroyRef)) .subscribe(() => { this.userService .get(true) - .pipe(takeUntil(this.unsubscribeSubject)) + .pipe(takeUntilDestroyed(this.destroyRef)) .subscribe((user) => { this.user = user; @@ -149,11 +147,6 @@ export class GfHomeHoldingsComponent implements OnDestroy, OnInit { } } - public ngOnDestroy() { - this.unsubscribeSubject.next(); - this.unsubscribeSubject.complete(); - } - private fetchHoldings() { const filters = this.userService.getFilters(); @@ -193,7 +186,7 @@ export class GfHomeHoldingsComponent implements OnDestroy, OnInit { this.holdings = undefined; this.fetchHoldings() - .pipe(takeUntil(this.unsubscribeSubject)) + .pipe(takeUntilDestroyed(this.destroyRef)) .subscribe(({ holdings }) => { this.holdings = holdings; From cdd508dfe699222baa5458db86d44c6817eb2fbc Mon Sep 17 00:00:00 2001 From: Erwin <111194281+Erwin-N@users.noreply.github.com> Date: Sat, 14 Mar 2026 09:04:24 +0100 Subject: [PATCH 129/224] Task/eliminate OnDestroy lifecycle hook from home market component (#6548) * Eliminate OnDestroy lifecycle hook --- .../home-market/home-market.component.ts | 21 +++++++------------ 1 file changed, 7 insertions(+), 14 deletions(-) diff --git a/apps/client/src/app/components/home-market/home-market.component.ts b/apps/client/src/app/components/home-market/home-market.component.ts index 841c0818a..2ddb89408 100644 --- a/apps/client/src/app/components/home-market/home-market.component.ts +++ b/apps/client/src/app/components/home-market/home-market.component.ts @@ -17,12 +17,11 @@ import { ChangeDetectorRef, Component, CUSTOM_ELEMENTS_SCHEMA, - OnDestroy, + DestroyRef, OnInit } from '@angular/core'; +import { takeUntilDestroyed } from '@angular/core/rxjs-interop'; import { DeviceDetectorService } from 'ngx-device-detector'; -import { Subject } from 'rxjs'; -import { takeUntil } from 'rxjs/operators'; @Component({ imports: [ @@ -35,7 +34,7 @@ import { takeUntil } from 'rxjs/operators'; styleUrls: ['./home-market.scss'], templateUrl: './home-market.html' }) -export class GfHomeMarketComponent implements OnDestroy, OnInit { +export class GfHomeMarketComponent implements OnInit { public benchmarks: Benchmark[]; public deviceType: string; public fearAndGreedIndex: number; @@ -47,11 +46,10 @@ export class GfHomeMarketComponent implements OnDestroy, OnInit { public readonly numberOfDays = 365; public user: User; - private unsubscribeSubject = new Subject(); - public constructor( private changeDetectorRef: ChangeDetectorRef, private dataService: DataService, + private destroyRef: DestroyRef, private deviceService: DeviceDetectorService, private userService: UserService ) { @@ -59,7 +57,7 @@ export class GfHomeMarketComponent implements OnDestroy, OnInit { this.info = this.dataService.fetchInfo(); this.userService.stateChanged - .pipe(takeUntil(this.unsubscribeSubject)) + .pipe(takeUntilDestroyed(this.destroyRef)) .subscribe((state) => { if (state?.user) { this.user = state.user; @@ -82,7 +80,7 @@ export class GfHomeMarketComponent implements OnDestroy, OnInit { includeHistoricalData: this.numberOfDays, symbol: ghostfolioFearAndGreedIndexSymbol }) - .pipe(takeUntil(this.unsubscribeSubject)) + .pipe(takeUntilDestroyed(this.destroyRef)) .subscribe(({ historicalData, marketPrice }) => { this.fearAndGreedIndex = marketPrice; this.historicalDataItems = [ @@ -99,16 +97,11 @@ export class GfHomeMarketComponent implements OnDestroy, OnInit { this.dataService .fetchBenchmarks() - .pipe(takeUntil(this.unsubscribeSubject)) + .pipe(takeUntilDestroyed(this.destroyRef)) .subscribe(({ benchmarks }) => { this.benchmarks = benchmarks; this.changeDetectorRef.markForCheck(); }); } - - public ngOnDestroy() { - this.unsubscribeSubject.next(); - this.unsubscribeSubject.complete(); - } } From 9f9008c89a37aeb94517a142eb3cdd420aeae316 Mon Sep 17 00:00:00 2001 From: Erwin <111194281+Erwin-N@users.noreply.github.com> Date: Sat, 14 Mar 2026 09:06:10 +0100 Subject: [PATCH 130/224] Task/eliminate OnDestroy lifecycle hook from home overview component (#6549) * Eliminate OnDestroy lifecycle hook --- .../home-overview/home-overview.component.ts | 23 +++++++------------ 1 file changed, 8 insertions(+), 15 deletions(-) diff --git a/apps/client/src/app/components/home-overview/home-overview.component.ts b/apps/client/src/app/components/home-overview/home-overview.component.ts index cb1df1a74..58284d27d 100644 --- a/apps/client/src/app/components/home-overview/home-overview.component.ts +++ b/apps/client/src/app/components/home-overview/home-overview.component.ts @@ -19,14 +19,13 @@ import { ChangeDetectorRef, Component, CUSTOM_ELEMENTS_SCHEMA, - OnDestroy, + DestroyRef, OnInit } from '@angular/core'; +import { takeUntilDestroyed } from '@angular/core/rxjs-interop'; import { MatButtonModule } from '@angular/material/button'; import { RouterModule } from '@angular/router'; import { DeviceDetectorService } from 'ngx-device-detector'; -import { Subject } from 'rxjs'; -import { takeUntil } from 'rxjs/operators'; @Component({ imports: [ @@ -41,7 +40,7 @@ import { takeUntil } from 'rxjs/operators'; styleUrls: ['./home-overview.scss'], templateUrl: './home-overview.html' }) -export class GfHomeOverviewComponent implements OnDestroy, OnInit { +export class GfHomeOverviewComponent implements OnInit { public deviceType: string; public errors: AssetProfileIdentifier[]; public hasError: boolean; @@ -62,18 +61,17 @@ export class GfHomeOverviewComponent implements OnDestroy, OnInit { public unit: string; public user: User; - private unsubscribeSubject = new Subject(); - public constructor( private changeDetectorRef: ChangeDetectorRef, private dataService: DataService, + private destroyRef: DestroyRef, private deviceService: DeviceDetectorService, private impersonationStorageService: ImpersonationStorageService, private layoutService: LayoutService, private userService: UserService ) { this.userService.stateChanged - .pipe(takeUntil(this.unsubscribeSubject)) + .pipe(takeUntilDestroyed(this.destroyRef)) .subscribe((state) => { if (state?.user) { this.user = state.user; @@ -99,7 +97,7 @@ export class GfHomeOverviewComponent implements OnDestroy, OnInit { this.impersonationStorageService .onChangeHasImpersonation() - .pipe(takeUntil(this.unsubscribeSubject)) + .pipe(takeUntilDestroyed(this.destroyRef)) .subscribe((impersonationId) => { this.hasImpersonationId = !!impersonationId; @@ -107,17 +105,12 @@ export class GfHomeOverviewComponent implements OnDestroy, OnInit { }); this.layoutService.shouldReloadContent$ - .pipe(takeUntil(this.unsubscribeSubject)) + .pipe(takeUntilDestroyed(this.destroyRef)) .subscribe(() => { this.update(); }); } - public ngOnDestroy() { - this.unsubscribeSubject.next(); - this.unsubscribeSubject.complete(); - } - private update() { this.historicalDataItems = null; this.isLoadingPerformance = true; @@ -126,7 +119,7 @@ export class GfHomeOverviewComponent implements OnDestroy, OnInit { .fetchPortfolioPerformance({ range: this.user?.settings?.dateRange }) - .pipe(takeUntil(this.unsubscribeSubject)) + .pipe(takeUntilDestroyed(this.destroyRef)) .subscribe(({ chart, errors, performance }) => { this.errors = errors; this.performance = performance; From 6a714687b54e4e5aa89f7f084ae7c531f61c3c43 Mon Sep 17 00:00:00 2001 From: Erwin <111194281+Erwin-N@users.noreply.github.com> Date: Sat, 14 Mar 2026 09:07:53 +0100 Subject: [PATCH 131/224] Task/eliminate OnDestroy lifecycle hook from home summary component (#6550) * Eliminate OnDestroy lifecycle hook --- .../home-summary/home-summary.component.ts | 25 +++++++------------ 1 file changed, 9 insertions(+), 16 deletions(-) diff --git a/apps/client/src/app/components/home-summary/home-summary.component.ts b/apps/client/src/app/components/home-summary/home-summary.component.ts index 454d05689..719cfbd29 100644 --- a/apps/client/src/app/components/home-summary/home-summary.component.ts +++ b/apps/client/src/app/components/home-summary/home-summary.component.ts @@ -13,14 +13,13 @@ import { ChangeDetectorRef, Component, CUSTOM_ELEMENTS_SCHEMA, - OnDestroy, + DestroyRef, OnInit } from '@angular/core'; +import { takeUntilDestroyed } from '@angular/core/rxjs-interop'; import { MatCardModule } from '@angular/material/card'; import { MatSnackBarRef, TextOnlySnackBar } from '@angular/material/snack-bar'; import { DeviceDetectorService } from 'ngx-device-detector'; -import { Subject } from 'rxjs'; -import { takeUntil } from 'rxjs/operators'; @Component({ imports: [GfPortfolioSummaryComponent, MatCardModule], @@ -29,7 +28,7 @@ import { takeUntil } from 'rxjs/operators'; styleUrls: ['./home-summary.scss'], templateUrl: './home-summary.html' }) -export class GfHomeSummaryComponent implements OnDestroy, OnInit { +export class GfHomeSummaryComponent implements OnInit { public deviceType: string; public hasImpersonationId: boolean; public hasPermissionForSubscription: boolean; @@ -40,11 +39,10 @@ export class GfHomeSummaryComponent implements OnDestroy, OnInit { public summary: PortfolioSummary; public user: User; - private unsubscribeSubject = new Subject(); - public constructor( private changeDetectorRef: ChangeDetectorRef, private dataService: DataService, + private destroyRef: DestroyRef, private deviceService: DeviceDetectorService, private impersonationStorageService: ImpersonationStorageService, private userService: UserService @@ -57,7 +55,7 @@ export class GfHomeSummaryComponent implements OnDestroy, OnInit { ); this.userService.stateChanged - .pipe(takeUntil(this.unsubscribeSubject)) + .pipe(takeUntilDestroyed(this.destroyRef)) .subscribe((state) => { if (state?.user) { this.user = state.user; @@ -77,7 +75,7 @@ export class GfHomeSummaryComponent implements OnDestroy, OnInit { this.impersonationStorageService .onChangeHasImpersonation() - .pipe(takeUntil(this.unsubscribeSubject)) + .pipe(takeUntilDestroyed(this.destroyRef)) .subscribe((impersonationId) => { this.hasImpersonationId = !!impersonationId; }); @@ -86,11 +84,11 @@ export class GfHomeSummaryComponent implements OnDestroy, OnInit { public onChangeEmergencyFund(emergencyFund: number) { this.dataService .putUserSetting({ emergencyFund }) - .pipe(takeUntil(this.unsubscribeSubject)) + .pipe(takeUntilDestroyed(this.destroyRef)) .subscribe(() => { this.userService .get(true) - .pipe(takeUntil(this.unsubscribeSubject)) + .pipe(takeUntilDestroyed(this.destroyRef)) .subscribe((user) => { this.user = user; @@ -99,17 +97,12 @@ export class GfHomeSummaryComponent implements OnDestroy, OnInit { }); } - public ngOnDestroy() { - this.unsubscribeSubject.next(); - this.unsubscribeSubject.complete(); - } - private update() { this.isLoading = true; this.dataService .fetchPortfolioDetails() - .pipe(takeUntil(this.unsubscribeSubject)) + .pipe(takeUntilDestroyed(this.destroyRef)) .subscribe(({ summary }) => { this.summary = summary; this.isLoading = false; From 573fbb9a4031f51b3613d02188374a7171b9ca4e Mon Sep 17 00:00:00 2001 From: Kenrick Tandrian <60643640+KenTandrian@users.noreply.github.com> Date: Sat, 14 Mar 2026 15:16:46 +0700 Subject: [PATCH 132/224] Task/improve type safety of toggle component (#6533) * Improve type safety --- libs/ui/src/lib/toggle/toggle.component.html | 7 +++-- libs/ui/src/lib/toggle/toggle.component.ts | 32 +++++++++++--------- 2 files changed, 22 insertions(+), 17 deletions(-) diff --git a/libs/ui/src/lib/toggle/toggle.component.html b/libs/ui/src/lib/toggle/toggle.component.html index ac2256daa..d6271ef58 100644 --- a/libs/ui/src/lib/toggle/toggle.component.html +++ b/libs/ui/src/lib/toggle/toggle.component.html @@ -3,13 +3,14 @@ [formControl]="optionFormControl" (change)="onValueChange()" > - @for (option of options; track option) { + @for (option of options(); track option) { {{ option.label }}(); + public readonly isLoading = input(false); + public readonly options = input([]); - @Output() valueChange = new EventEmitter>(); + protected readonly optionFormControl = new FormControl(null); + protected readonly valueChange = output>(); - public optionFormControl = new FormControl(undefined); - - public ngOnChanges() { - this.optionFormControl.setValue(this.defaultValue); + public constructor() { + effect(() => { + this.optionFormControl.setValue(this.defaultValue()); + }); } public onValueChange() { - this.valueChange.emit({ value: this.optionFormControl.value }); + const value = this.optionFormControl.value; + + if (value !== null) { + this.valueChange.emit({ value }); + } } } From 439af5f21d9cc69eaa83e0b8a815f683314b77c1 Mon Sep 17 00:00:00 2001 From: Thomas Kaul <4159106+dtslvr@users.noreply.github.com> Date: Sat, 14 Mar 2026 09:26:47 +0100 Subject: [PATCH 133/224] Task/consolidate sign-out logic (#6526) * Consolidate sign-out logic * Update changelog --- CHANGELOG.md | 1 + apps/client/src/app/app.component.ts | 7 ++-- .../admin-users/admin-users.component.ts | 5 +-- .../user-account-access.component.ts | 5 +-- .../user-account-settings.component.ts | 5 +-- apps/client/src/app/core/auth.guard.ts | 2 +- .../src/app/core/http-response.interceptor.ts | 6 ++-- .../pages/register/register-page.component.ts | 6 ++-- .../src/app/services/token-storage.service.ts | 26 +------------- .../src/app/services/user/user.service.ts | 36 +++++++++++++++++-- 10 files changed, 49 insertions(+), 50 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 103a09fbb..03fbc962c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Changed +- Consolidated the sign-out logic within the user service to unify cookie, state and token clearance - Upgraded `svgmap` from version `2.14.0` to `2.19.2` ## 2.249.0 - 2026-03-10 diff --git a/apps/client/src/app/app.component.ts b/apps/client/src/app/app.component.ts index 3daca607a..0e7d50a54 100644 --- a/apps/client/src/app/app.component.ts +++ b/apps/client/src/app/app.component.ts @@ -38,7 +38,6 @@ import { GfHeaderComponent } from './components/header/header.component'; import { GfHoldingDetailDialogComponent } from './components/holding-detail-dialog/holding-detail-dialog.component'; import { HoldingDetailDialogParams } from './components/holding-detail-dialog/interfaces/interfaces'; import { ImpersonationStorageService } from './services/impersonation-storage.service'; -import { TokenStorageService } from './services/token-storage.service'; import { UserService } from './services/user/user.service'; @Component({ @@ -82,7 +81,6 @@ export class GfAppComponent implements OnDestroy, OnInit { private route: ActivatedRoute, private router: Router, private title: Title, - private tokenStorageService: TokenStorageService, private userService: UserService ) { this.initializeTheme(); @@ -236,12 +234,11 @@ export class GfAppComponent implements OnDestroy, OnInit { } public onCreateAccount() { - this.tokenStorageService.signOut(); + this.userService.signOut(); } public onSignOut() { - this.tokenStorageService.signOut(); - this.userService.remove(); + this.userService.signOut(); document.location.href = `/${document.documentElement.lang}`; } diff --git a/apps/client/src/app/components/admin-users/admin-users.component.ts b/apps/client/src/app/components/admin-users/admin-users.component.ts index d479f2037..7916acffd 100644 --- a/apps/client/src/app/components/admin-users/admin-users.component.ts +++ b/apps/client/src/app/components/admin-users/admin-users.component.ts @@ -1,7 +1,6 @@ import { UserDetailDialogParams } from '@ghostfolio/client/components/user-detail-dialog/interfaces/interfaces'; import { GfUserDetailDialogComponent } from '@ghostfolio/client/components/user-detail-dialog/user-detail-dialog.component'; import { ImpersonationStorageService } from '@ghostfolio/client/services/impersonation-storage.service'; -import { TokenStorageService } from '@ghostfolio/client/services/token-storage.service'; import { UserService } from '@ghostfolio/client/services/user/user.service'; import { DEFAULT_PAGE_SIZE } from '@ghostfolio/common/config'; import { ConfirmationDialogType } from '@ghostfolio/common/enums'; @@ -106,7 +105,6 @@ export class GfAdminUsersComponent implements OnDestroy, OnInit { private notificationService: NotificationService, private route: ActivatedRoute, private router: Router, - private tokenStorageService: TokenStorageService, private userService: UserService ) { this.deviceType = this.deviceService.getDeviceInfo().deviceType; @@ -229,8 +227,7 @@ export class GfAdminUsersComponent implements OnDestroy, OnInit { this.notificationService.alert({ discardFn: () => { if (aUserId === this.user.id) { - this.tokenStorageService.signOut(); - this.userService.remove(); + this.userService.signOut(); document.location.href = `/${document.documentElement.lang}`; } diff --git a/apps/client/src/app/components/user-account-access/user-account-access.component.ts b/apps/client/src/app/components/user-account-access/user-account-access.component.ts index ef78cccff..4f744a087 100644 --- a/apps/client/src/app/components/user-account-access/user-account-access.component.ts +++ b/apps/client/src/app/components/user-account-access/user-account-access.component.ts @@ -1,5 +1,4 @@ import { GfAccessTableComponent } from '@ghostfolio/client/components/access-table/access-table.component'; -import { TokenStorageService } from '@ghostfolio/client/services/token-storage.service'; import { UserService } from '@ghostfolio/client/services/user/user.service'; import { CreateAccessDto } from '@ghostfolio/common/dtos'; import { ConfirmationDialogType } from '@ghostfolio/common/enums'; @@ -76,7 +75,6 @@ export class GfUserAccountAccessComponent implements OnDestroy, OnInit { private notificationService: NotificationService, private route: ActivatedRoute, private router: Router, - private tokenStorageService: TokenStorageService, private userService: UserService ) { const { globalPermissions } = this.dataService.fetchInfo(); @@ -161,8 +159,7 @@ export class GfUserAccountAccessComponent implements OnDestroy, OnInit { .subscribe(({ accessToken }) => { this.notificationService.alert({ discardFn: () => { - this.tokenStorageService.signOut(); - this.userService.remove(); + this.userService.signOut(); document.location.href = `/${document.documentElement.lang}`; }, diff --git a/apps/client/src/app/components/user-account-settings/user-account-settings.component.ts b/apps/client/src/app/components/user-account-settings/user-account-settings.component.ts index 44be30b9a..0cf18df36 100644 --- a/apps/client/src/app/components/user-account-settings/user-account-settings.component.ts +++ b/apps/client/src/app/components/user-account-settings/user-account-settings.component.ts @@ -3,7 +3,6 @@ import { KEY_TOKEN, SettingsStorageService } from '@ghostfolio/client/services/settings-storage.service'; -import { TokenStorageService } from '@ghostfolio/client/services/token-storage.service'; import { UserService } from '@ghostfolio/client/services/user/user.service'; import { WebAuthnService } from '@ghostfolio/client/services/web-authn.service'; import { ConfirmationDialogType } from '@ghostfolio/common/enums'; @@ -108,7 +107,6 @@ export class GfUserAccountSettingsComponent implements OnDestroy, OnInit { private notificationService: NotificationService, private settingsStorageService: SettingsStorageService, private snackBar: MatSnackBar, - private tokenStorageService: TokenStorageService, private userService: UserService, public webAuthnService: WebAuthnService ) { @@ -198,8 +196,7 @@ export class GfUserAccountSettingsComponent implements OnDestroy, OnInit { takeUntil(this.unsubscribeSubject) ) .subscribe(() => { - this.tokenStorageService.signOut(); - this.userService.remove(); + this.userService.signOut(); document.location.href = `/${document.documentElement.lang}`; }); diff --git a/apps/client/src/app/core/auth.guard.ts b/apps/client/src/app/core/auth.guard.ts index 123a6169a..3292f0ff7 100644 --- a/apps/client/src/app/core/auth.guard.ts +++ b/apps/client/src/app/core/auth.guard.ts @@ -68,7 +68,7 @@ export class AuthGuard { this.dataService .putUserSetting({ language: document.documentElement.lang }) .subscribe(() => { - this.userService.remove(); + this.userService.reset(); setTimeout(() => { window.location.reload(); diff --git a/apps/client/src/app/core/http-response.interceptor.ts b/apps/client/src/app/core/http-response.interceptor.ts index ab99b440f..315e9d64e 100644 --- a/apps/client/src/app/core/http-response.interceptor.ts +++ b/apps/client/src/app/core/http-response.interceptor.ts @@ -1,4 +1,4 @@ -import { TokenStorageService } from '@ghostfolio/client/services/token-storage.service'; +import { UserService } from '@ghostfolio/client/services/user/user.service'; import { WebAuthnService } from '@ghostfolio/client/services/web-authn.service'; import { InfoItem } from '@ghostfolio/common/interfaces'; import { internalRoutes, publicRoutes } from '@ghostfolio/common/routes/routes'; @@ -32,8 +32,8 @@ export class HttpResponseInterceptor implements HttpInterceptor { public constructor( private dataService: DataService, private router: Router, - private tokenStorageService: TokenStorageService, private snackBar: MatSnackBar, + private userService: UserService, private webAuthnService: WebAuthnService ) { this.info = this.dataService.fetchInfo(); @@ -115,7 +115,7 @@ export class HttpResponseInterceptor implements HttpInterceptor { if (this.webAuthnService.isEnabled()) { this.router.navigate(internalRoutes.webauthn.routerLink); } else { - this.tokenStorageService.signOut(); + this.userService.signOut(); } } } diff --git a/apps/client/src/app/pages/register/register-page.component.ts b/apps/client/src/app/pages/register/register-page.component.ts index 3678f0249..db199143f 100644 --- a/apps/client/src/app/pages/register/register-page.component.ts +++ b/apps/client/src/app/pages/register/register-page.component.ts @@ -1,4 +1,5 @@ import { TokenStorageService } from '@ghostfolio/client/services/token-storage.service'; +import { UserService } from '@ghostfolio/client/services/user/user.service'; import { InfoItem, LineChartItem } from '@ghostfolio/common/interfaces'; import { hasPermission, permissions } from '@ghostfolio/common/permissions'; import { GfLogoComponent } from '@ghostfolio/ui/logo'; @@ -42,11 +43,12 @@ export class GfRegisterPageComponent implements OnInit { private deviceService: DeviceDetectorService, private dialog: MatDialog, private router: Router, - private tokenStorageService: TokenStorageService + private tokenStorageService: TokenStorageService, + private userService: UserService ) { this.info = this.dataService.fetchInfo(); - this.tokenStorageService.signOut(); + this.userService.signOut(); } public ngOnInit() { diff --git a/apps/client/src/app/services/token-storage.service.ts b/apps/client/src/app/services/token-storage.service.ts index 5b9a29a08..f54aab828 100644 --- a/apps/client/src/app/services/token-storage.service.ts +++ b/apps/client/src/app/services/token-storage.service.ts @@ -1,19 +1,11 @@ -import { WebAuthnService } from '@ghostfolio/client/services/web-authn.service'; - import { Injectable } from '@angular/core'; import { KEY_TOKEN } from './settings-storage.service'; -import { UserService } from './user/user.service'; @Injectable({ providedIn: 'root' }) export class TokenStorageService { - public constructor( - private userService: UserService, - private webAuthnService: WebAuthnService - ) {} - public getToken(): string { return ( window.sessionStorage.getItem(KEY_TOKEN) || @@ -25,23 +17,7 @@ export class TokenStorageService { if (staySignedIn) { window.localStorage.setItem(KEY_TOKEN, token); } - window.sessionStorage.setItem(KEY_TOKEN, token); - } - - public signOut() { - const utmSource = window.localStorage.getItem('utm_source'); - if (this.webAuthnService.isEnabled()) { - this.webAuthnService.deregister().subscribe(); - } - - window.localStorage.clear(); - window.sessionStorage.clear(); - - this.userService.remove(); - - if (utmSource) { - window.localStorage.setItem('utm_source', utmSource); - } + window.sessionStorage.setItem(KEY_TOKEN, token); } } diff --git a/apps/client/src/app/services/user/user.service.ts b/apps/client/src/app/services/user/user.service.ts index bd9d7d04c..44b63e056 100644 --- a/apps/client/src/app/services/user/user.service.ts +++ b/apps/client/src/app/services/user/user.service.ts @@ -1,3 +1,4 @@ +import { WebAuthnService } from '@ghostfolio/client/services/web-authn.service'; import { Filter, User } from '@ghostfolio/common/interfaces'; import { hasPermission, permissions } from '@ghostfolio/common/permissions'; @@ -26,7 +27,8 @@ export class UserService extends ObservableStore { public constructor( private deviceService: DeviceDetectorService, private dialog: MatDialog, - private http: HttpClient + private http: HttpClient, + private webAuthnService: WebAuthnService ) { super({ trackStateHistory: true }); @@ -93,10 +95,40 @@ export class UserService extends ObservableStore { return this.getFilters().length > 0; } - public remove() { + public reset() { this.setState({ user: null }, UserStoreActions.RemoveUser); } + public signOut() { + const utmSource = window.localStorage.getItem('utm_source'); + + if (this.webAuthnService.isEnabled()) { + this.webAuthnService.deregister().subscribe(); + } + + window.localStorage.clear(); + window.sessionStorage.clear(); + + void this.clearAllCookies(); + + this.reset(); + + if (utmSource) { + window.localStorage.setItem('utm_source', utmSource); + } + } + + private async clearAllCookies() { + if (!('cookieStore' in window)) { + console.warn('Cookie Store API not available in this browser'); + return; + } + + const cookies = await cookieStore.getAll(); + + await Promise.all(cookies.map(({ name }) => cookieStore.delete(name))); + } + private fetchUser(): Observable { return this.http.get('/api/v1/user').pipe( map((user) => { From cf57c156fc5af42379933d2a56d09a3ea45be33d Mon Sep 17 00:00:00 2001 From: Thomas Kaul <4159106+dtslvr@users.noreply.github.com> Date: Sat, 14 Mar 2026 09:28:28 +0100 Subject: [PATCH 134/224] Task/refactor open Bull Board in admin jobs component (#6525) * Refactoring --- .../src/app/components/admin-jobs/admin-jobs.component.ts | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/apps/client/src/app/components/admin-jobs/admin-jobs.component.ts b/apps/client/src/app/components/admin-jobs/admin-jobs.component.ts index 1537db2a0..b9f4d590d 100644 --- a/apps/client/src/app/components/admin-jobs/admin-jobs.component.ts +++ b/apps/client/src/app/components/admin-jobs/admin-jobs.component.ts @@ -194,7 +194,11 @@ export class GfAdminJobsComponent implements OnInit { public onOpenBullBoard() { const token = this.tokenStorageService.getToken(); - document.cookie = `${BULL_BOARD_COOKIE_NAME}=${token}; path=${BULL_BOARD_ROUTE}; SameSite=Strict`; + document.cookie = [ + `${BULL_BOARD_COOKIE_NAME}=${encodeURIComponent(token)}`, + 'path=/', + 'SameSite=Strict' + ].join('; '); window.open(BULL_BOARD_ROUTE, '_blank'); } From a3b1b922d279b581a29e95432befa840337ede26 Mon Sep 17 00:00:00 2001 From: Thomas Kaul <4159106+dtslvr@users.noreply.github.com> Date: Sat, 14 Mar 2026 09:30:20 +0100 Subject: [PATCH 135/224] Task/implement OnModuleInit interface in AssetsController (#6451) * Implement OnModuleInit interface --- apps/api/src/app/endpoints/assets/assets.controller.ts | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/apps/api/src/app/endpoints/assets/assets.controller.ts b/apps/api/src/app/endpoints/assets/assets.controller.ts index a314b3f19..397686d8c 100644 --- a/apps/api/src/app/endpoints/assets/assets.controller.ts +++ b/apps/api/src/app/endpoints/assets/assets.controller.ts @@ -4,6 +4,7 @@ import { interpolate } from '@ghostfolio/common/helper'; import { Controller, Get, + OnModuleInit, Param, Res, Version, @@ -14,12 +15,14 @@ import { readFileSync } from 'node:fs'; import { join } from 'node:path'; @Controller('assets') -export class AssetsController { +export class AssetsController implements OnModuleInit { private webManifest = ''; public constructor( public readonly configurationService: ConfigurationService - ) { + ) {} + + public onModuleInit() { try { this.webManifest = readFileSync( join(__dirname, 'assets', 'site.webmanifest'), From 06492b6012214dbca2c550e2db162a9bce5851a8 Mon Sep 17 00:00:00 2001 From: Akd11111 <70412728+Akd11111@users.noreply.github.com> Date: Sat, 14 Mar 2026 10:11:28 +0100 Subject: [PATCH 136/224] Task/improve language localization for PL (20260312) (#6523) * Improve language localization for PL * Update changelog --- CHANGELOG.md | 1 + apps/client/src/locales/messages.pl.xlf | 64 ++++++++++++------------- 2 files changed, 33 insertions(+), 32 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 03fbc962c..13f014146 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Changed - Consolidated the sign-out logic within the user service to unify cookie, state and token clearance +- Improved the language localization for Polish (`pl`) - Upgraded `svgmap` from version `2.14.0` to `2.19.2` ## 2.249.0 - 2026-03-10 diff --git a/apps/client/src/locales/messages.pl.xlf b/apps/client/src/locales/messages.pl.xlf index 5de2ed8f4..e2083ccf7 100644 --- a/apps/client/src/locales/messages.pl.xlf +++ b/apps/client/src/locales/messages.pl.xlf @@ -660,7 +660,7 @@ and is driven by the efforts of its contributors - and is driven by the efforts of its contributors + i jest rozwijany dzięki pracy jego współtwórców apps/client/src/app/pages/about/overview/about-overview-page.html 49 @@ -1580,7 +1580,7 @@ The source code is fully available as open source software (OSS) under the AGPL-3.0 license - The source code is fully available as open source software (OSS) under the AGPL-3.0 license + Kod źródłowy jest w pełni dostępny jako oprogramowanie open source (OSS) na licencji AGPL-3.0 license apps/client/src/app/pages/about/overview/about-overview-page.html 16 @@ -2148,7 +2148,7 @@ Performance with currency effect - Performance with currency effect + Wynik z efektem walutowym apps/client/src/app/pages/portfolio/analysis/analysis-page.html 135 @@ -2376,7 +2376,7 @@ this is projected to increase to - this is projected to increase to + prognozuje się wzrost tej kwoty do apps/client/src/app/pages/portfolio/fire/fire-page.html 147 @@ -3564,7 +3564,7 @@ and a safe withdrawal rate (SWR) of - and a safe withdrawal rate (SWR) of + oraz bezpiecznej stopy wypłaty (SWR) na poziomie apps/client/src/app/pages/portfolio/fire/fire-page.html 108 @@ -4124,7 +4124,7 @@ annual interest rate - annual interest rate + rocznej stopy zwrotu apps/client/src/app/pages/portfolio/fire/fire-page.html 185 @@ -4464,7 +4464,7 @@ Sustainable retirement income - Sustainable retirement income + Zrównoważony dochód na emeryturze apps/client/src/app/pages/portfolio/fire/fire-page.html 41 @@ -4597,7 +4597,7 @@ per month - per month + miesięcznie apps/client/src/app/pages/portfolio/fire/fire-page.html 94 @@ -5397,7 +5397,7 @@ View Details - View Details + Zobacz szczegóły apps/client/src/app/components/admin-users/admin-users.html 225 @@ -5425,7 +5425,7 @@ Buy - Zakup + Kupno apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html 31 @@ -5469,7 +5469,7 @@ Sell - Sprzedaj + Sprzedaż apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html 44 @@ -5625,7 +5625,7 @@ If you retire today, you would be able to withdraw - If you retire today, you would be able to withdraw + Gdybyś przeszedł na emeryturę dziś, mógłbyś wypłacać apps/client/src/app/pages/portfolio/fire/fire-page.html 68 @@ -6710,7 +6710,7 @@ , based on your total assets of - , based on your total assets of + , na podstawie całkowitej wartości aktywów wynoszącej apps/client/src/app/pages/portfolio/fire/fire-page.html 96 @@ -6974,7 +6974,7 @@ , assuming a - , assuming a + , przyjmując apps/client/src/app/pages/portfolio/fire/fire-page.html 174 @@ -7062,7 +7062,7 @@ Ghostfolio is a lightweight wealth management application for individuals to keep track of stocks, ETFs or cryptocurrencies and make solid, data-driven investment decisions. - Ghostfolio is a lightweight wealth management application for individuals to keep track of stocks, ETFs or cryptocurrencies and make solid, data-driven investment decisions. + Ghostfolio to aplikacja do zarządzania majątkiem, przeznaczona dla osób prywatnych do śledzenia akcji, ETF‑ów i kryptowalut oraz podejmowania solidnych, opartych na danych decyzji inwestycyjnych. apps/client/src/app/pages/about/overview/about-overview-page.html 10 @@ -7392,7 +7392,7 @@ Change with currency effect - Change with currency effect + Zmiana z efektem walutowym apps/client/src/app/pages/portfolio/analysis/analysis-page.html 116 @@ -7532,7 +7532,7 @@ The project has been initiated by - The project has been initiated by + Projekt został zainicjowany przez apps/client/src/app/pages/about/overview/about-overview-page.html 40 @@ -7556,7 +7556,7 @@ Total amount - Total amount + Wartość portfela apps/client/src/app/pages/portfolio/analysis/analysis-page.html 95 @@ -7898,7 +7898,7 @@ Fee Ratio - Fee Ratio + Wskaźnik opłat apps/client/src/app/pages/i18n/i18n-page.html 152 @@ -8333,7 +8333,7 @@ Account Cluster Risks - Account Cluster Risks + Ryzyka skupienia w obrębie rachunków apps/client/src/app/pages/i18n/i18n-page.html 14 @@ -8341,7 +8341,7 @@ Asset Class Cluster Risks - Asset Class Cluster Risks + Ryzyka skupienia w obrębie klas aktywów apps/client/src/app/pages/i18n/i18n-page.html 39 @@ -8349,7 +8349,7 @@ Currency Cluster Risks - Currency Cluster Risks + Ryzyka koncentracji walutowej apps/client/src/app/pages/i18n/i18n-page.html 83 @@ -8357,7 +8357,7 @@ Economic Market Cluster Risks - Economic Market Cluster Risks + Ryzyka skupienia w obrębie segmentów rynku gospodarczego apps/client/src/app/pages/i18n/i18n-page.html 106 @@ -8373,7 +8373,7 @@ Fees - Fees + Opłaty apps/client/src/app/pages/i18n/i18n-page.html 161 @@ -8381,7 +8381,7 @@ Liquidity - Liquidity + Płynność apps/client/src/app/pages/i18n/i18n-page.html 70 @@ -8389,7 +8389,7 @@ Buying Power - Buying Power + Siła nabywcza apps/client/src/app/pages/i18n/i18n-page.html 71 @@ -8413,7 +8413,7 @@ Your buying power exceeds ${thresholdMin} ${baseCurrency} - Your buying power exceeds ${thresholdMin} ${baseCurrency} + Twoja siła nabywcza przekracza ${thresholdMin} ${baseCurrency} apps/client/src/app/pages/i18n/i18n-page.html 80 @@ -8421,7 +8421,7 @@ Regional Market Cluster Risks - Regional Market Cluster Risks + Ryzyka skupienia w obrębie regionów rynkowych apps/client/src/app/pages/i18n/i18n-page.html 163 @@ -8437,7 +8437,7 @@ Developed Markets - Developed Markets + Rynki rozwinięte apps/client/src/app/pages/i18n/i18n-page.html 109 @@ -8469,7 +8469,7 @@ Emerging Markets - Emerging Markets + Rynki wschodzące apps/client/src/app/pages/i18n/i18n-page.html 127 @@ -8581,7 +8581,7 @@ Europe - Europe + Europa apps/client/src/app/pages/i18n/i18n-page.html 195 @@ -8613,7 +8613,7 @@ Japan - Japan + Japonia apps/client/src/app/pages/i18n/i18n-page.html 209 From 27c50bf5096c5d561af4e35d97d6f55ad1e81ad9 Mon Sep 17 00:00:00 2001 From: Kenrick Tandrian <60643640+KenTandrian@users.noreply.github.com> Date: Sat, 14 Mar 2026 17:06:46 +0700 Subject: [PATCH 137/224] Task/improve type safety of benchmark component (#6555) * Improve type safety --- .../interfaces/interfaces.ts | 2 +- .../lib/benchmark/benchmark.component.html | 16 +- .../src/lib/benchmark/benchmark.component.ts | 147 +++++++++--------- 3 files changed, 79 insertions(+), 86 deletions(-) diff --git a/libs/ui/src/lib/benchmark/benchmark-detail-dialog/interfaces/interfaces.ts b/libs/ui/src/lib/benchmark/benchmark-detail-dialog/interfaces/interfaces.ts index 291f4c973..b01403284 100644 --- a/libs/ui/src/lib/benchmark/benchmark-detail-dialog/interfaces/interfaces.ts +++ b/libs/ui/src/lib/benchmark/benchmark-detail-dialog/interfaces/interfaces.ts @@ -3,7 +3,7 @@ import { ColorScheme } from '@ghostfolio/common/types'; import { DataSource } from '@prisma/client'; export interface BenchmarkDetailDialogParams { - colorScheme: ColorScheme; + colorScheme?: ColorScheme; dataSource: DataSource; deviceType: string; locale: string; diff --git a/libs/ui/src/lib/benchmark/benchmark.component.html b/libs/ui/src/lib/benchmark/benchmark.component.html index ab6db8887..8820f2ec1 100644 --- a/libs/ui/src/lib/benchmark/benchmark.component.html +++ b/libs/ui/src/lib/benchmark/benchmark.component.html @@ -15,7 +15,7 @@
    {{ element?.name }}
    - @if (showSymbol) { + @if (showSymbol()) {
    {{ element?.symbol }}
    @@ -98,7 +98,7 @@ @if (element?.performances?.allTimeHigh?.date) { } @@ -123,7 +123,7 @@
    - @if (hasPermissionToDeleteItem) { + @if (hasPermissionToDeleteItem()) {
    - + @if (isLoading()) { } -@if (dataSource.data.length > pageSize && !isLoading()) { +@if (dataSource.data.length > pageSize() && !isLoading()) {
    + } + + @if (value || value === 0 || value === null) {
    } + @if (!hasLabel) { + + }
    } @@ -88,6 +110,9 @@ @if (size === 'large') {
    + @if (hasLabel) { + + } @if (subLabel) { {{ subLabel }} } @@ -95,6 +120,9 @@ } @else { + @if (hasLabel) { + + } }
    diff --git a/libs/ui/src/lib/value/value.component.stories.ts b/libs/ui/src/lib/value/value.component.stories.ts index eeebe9399..214331efc 100644 --- a/libs/ui/src/lib/value/value.component.stories.ts +++ b/libs/ui/src/lib/value/value.component.stories.ts @@ -1,3 +1,4 @@ +import '@angular/localize/init'; import { moduleMetadata } from '@storybook/angular'; import type { Meta, StoryObj } from '@storybook/angular'; import { NgxSkeletonLoaderModule } from 'ngx-skeleton-loader'; @@ -17,6 +18,9 @@ export default { control: 'select', options: ['desktop', 'mobile'] }, + enableCopyToClipboardButton: { + control: 'boolean' + }, size: { control: 'select', options: ['small', 'medium', 'large'] @@ -58,7 +62,7 @@ export const Label: Story = { }, render: (args) => ({ props: args, - template: `Label` + template: `Label` }) }; diff --git a/libs/ui/src/lib/value/value.component.ts b/libs/ui/src/lib/value/value.component.ts index 795e16491..9c3330466 100644 --- a/libs/ui/src/lib/value/value.component.ts +++ b/libs/ui/src/lib/value/value.component.ts @@ -1,30 +1,41 @@ import { getLocale } from '@ghostfolio/common/helper'; +import { Clipboard } from '@angular/cdk/clipboard'; import { CommonModule } from '@angular/common'; import { - CUSTOM_ELEMENTS_SCHEMA, + AfterViewInit, ChangeDetectionStrategy, + ChangeDetectorRef, Component, + computed, + CUSTOM_ELEMENTS_SCHEMA, + ElementRef, + input, Input, OnChanges, - computed, - input + ViewChild } from '@angular/core'; +import { MatButtonModule } from '@angular/material/button'; +import { MatSnackBar } from '@angular/material/snack-bar'; import { IonIcon } from '@ionic/angular/standalone'; +import { addIcons } from 'ionicons'; +import { copyOutline } from 'ionicons/icons'; import { isNumber } from 'lodash'; +import ms from 'ms'; import { NgxSkeletonLoaderModule } from 'ngx-skeleton-loader'; @Component({ changeDetection: ChangeDetectionStrategy.OnPush, - imports: [CommonModule, IonIcon, NgxSkeletonLoaderModule], + imports: [CommonModule, IonIcon, MatButtonModule, NgxSkeletonLoaderModule], schemas: [CUSTOM_ELEMENTS_SCHEMA], selector: 'gf-value', styleUrls: ['./value.component.scss'], templateUrl: './value.component.html' }) -export class GfValueComponent implements OnChanges { +export class GfValueComponent implements AfterViewInit, OnChanges { @Input() colorizeSign = false; @Input() deviceType: string; + @Input() enableCopyToClipboardButton = false; @Input() icon = ''; @Input() isAbsolute = false; @Input() isCurrency = false; @@ -37,12 +48,26 @@ export class GfValueComponent implements OnChanges { @Input() unit = ''; @Input() value: number | string = ''; + @ViewChild('labelContent', { static: false }) + labelContent!: ElementRef; + public absoluteValue = 0; public formattedValue = ''; + public hasLabel = false; public isNumber = false; public isString = false; public useAbsoluteValue = false; + public constructor( + private changeDetectorRef: ChangeDetectorRef, + private clipboard: Clipboard, + private snackBar: MatSnackBar + ) { + addIcons({ + copyOutline + }); + } + public readonly precision = input(); private readonly formatOptions = computed(() => { @@ -59,6 +84,17 @@ export class GfValueComponent implements OnChanges { return precision !== undefined && precision >= 0; } + public ngAfterViewInit() { + if (this.labelContent) { + const element = this.labelContent.nativeElement; + + this.hasLabel = + element.children.length > 0 || element.textContent.trim().length > 0; + + this.changeDetectorRef.markForCheck(); + } + } + public ngOnChanges() { this.initializeVariables(); @@ -137,6 +173,18 @@ export class GfValueComponent implements OnChanges { } } + public onCopyValueToClipboard() { + this.clipboard.copy(String(this.value)); + + this.snackBar.open( + '✅ ' + $localize`${this.value} has been copied to the clipboard`, + undefined, + { + duration: ms('3 seconds') + } + ); + } + private initializeVariables() { this.absoluteValue = 0; this.formattedValue = ''; From d98dc15c34bb41ec336e1f9b2bbd59070b8b3718 Mon Sep 17 00:00:00 2001 From: Thomas Kaul <4159106+dtslvr@users.noreply.github.com> Date: Tue, 31 Mar 2026 17:41:49 +0200 Subject: [PATCH 187/224] Feature/add copy-to-clipboard buttons to holding detail dialog (#6640) * Add copy to clipboard buttons for symbol and ISIN * Update changelog --- CHANGELOG.md | 2 ++ .../holding-detail-dialog/holding-detail-dialog.html | 6 ++++++ 2 files changed, 8 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6721e3022..274851846 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Added - Added support for a copy-to-clipboard functionality in the value component +- Extended the holding detail dialog by adding a copy-to-clipboard button for the ISIN number (experimental) +- Extended the holding detail dialog by adding a copy-to-clipboard button for the symbol (experimental) ### Changed diff --git a/apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html b/apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html index 15415e413..b8cb8dda2 100644 --- a/apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html +++ b/apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html @@ -310,6 +310,9 @@ Symbol ISIN Date: Tue, 31 Mar 2026 17:48:14 +0200 Subject: [PATCH 188/224] Task/update locales (#6513) * Update locales --- apps/client/src/locales/messages.ca.xlf | 218 ++++++++++++----------- apps/client/src/locales/messages.de.xlf | 218 ++++++++++++----------- apps/client/src/locales/messages.es.xlf | 220 ++++++++++++----------- apps/client/src/locales/messages.fr.xlf | 218 ++++++++++++----------- apps/client/src/locales/messages.it.xlf | 218 ++++++++++++----------- apps/client/src/locales/messages.ko.xlf | 218 ++++++++++++----------- apps/client/src/locales/messages.nl.xlf | 218 ++++++++++++----------- apps/client/src/locales/messages.pl.xlf | 224 +++++++++++++----------- apps/client/src/locales/messages.pt.xlf | 218 ++++++++++++----------- apps/client/src/locales/messages.tr.xlf | 218 ++++++++++++----------- apps/client/src/locales/messages.uk.xlf | 218 ++++++++++++----------- apps/client/src/locales/messages.xlf | 217 ++++++++++++----------- apps/client/src/locales/messages.zh.xlf | 218 ++++++++++++----------- 13 files changed, 1524 insertions(+), 1317 deletions(-) diff --git a/apps/client/src/locales/messages.ca.xlf b/apps/client/src/locales/messages.ca.xlf index cf0ede34d..566d91cc7 100644 --- a/apps/client/src/locales/messages.ca.xlf +++ b/apps/client/src/locales/messages.ca.xlf @@ -38,7 +38,7 @@ apps/client/src/app/components/header/header.component.ts - 297 + 298 apps/client/src/app/components/login-with-access-token-dialog/login-with-access-token-dialog.html @@ -659,7 +659,7 @@ Tipus apps/client/src/app/components/admin-jobs/admin-jobs.html - 48 + 57 apps/client/src/app/components/user-account-access/create-or-update-access-dialog/create-or-update-access-dialog.html @@ -679,7 +679,7 @@ Perfil d’Actiu apps/client/src/app/components/admin-jobs/admin-jobs.html - 52 + 61 @@ -687,7 +687,7 @@ Dades Històriques de Mercat apps/client/src/app/components/admin-jobs/admin-jobs.html - 54 + 63 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html @@ -699,7 +699,7 @@ Origen de les Dades apps/client/src/app/components/admin-jobs/admin-jobs.html - 82 + 91 apps/client/src/app/components/admin-market-data/admin-market-data.html @@ -723,7 +723,7 @@ Prioritat apps/client/src/app/components/admin-jobs/admin-jobs.html - 96 + 105 @@ -731,7 +731,7 @@ Intents apps/client/src/app/components/admin-jobs/admin-jobs.html - 120 + 129 @@ -739,7 +739,7 @@ Creat apps/client/src/app/components/admin-jobs/admin-jobs.html - 134 + 143 @@ -747,7 +747,7 @@ Finalitzat apps/client/src/app/components/admin-jobs/admin-jobs.html - 143 + 152 @@ -755,7 +755,7 @@ Estat apps/client/src/app/components/admin-jobs/admin-jobs.html - 152 + 161 apps/client/src/app/components/admin-settings/admin-settings.component.html @@ -775,7 +775,7 @@ Aturar Processos apps/client/src/app/components/admin-jobs/admin-jobs.html - 193 + 202 @@ -783,7 +783,7 @@ Veure les Dades apps/client/src/app/components/admin-jobs/admin-jobs.html - 208 + 217 @@ -791,7 +791,7 @@ Veure Stacktrace apps/client/src/app/components/admin-jobs/admin-jobs.html - 216 + 225 @@ -799,7 +799,7 @@ Executar Procés apps/client/src/app/components/admin-jobs/admin-jobs.html - 220 + 229 @@ -807,7 +807,7 @@ Suprimir Procés apps/client/src/app/components/admin-jobs/admin-jobs.html - 224 + 233 @@ -859,7 +859,7 @@ Punts de referència apps/client/src/app/components/admin-market-data/admin-market-data.component.ts - 126 + 125 @@ -867,7 +867,7 @@ Divises apps/client/src/app/components/admin-market-data/admin-market-data.component.ts - 131 + 130 apps/client/src/app/pages/public/public-page.html @@ -879,7 +879,7 @@ ETFs sense País apps/client/src/app/components/admin-market-data/admin-market-data.component.ts - 136 + 135 @@ -887,7 +887,7 @@ ETFs sense Sector apps/client/src/app/components/admin-market-data/admin-market-data.component.ts - 141 + 140 @@ -895,7 +895,7 @@ Filtra per... apps/client/src/app/components/admin-market-data/admin-market-data.component.ts - 390 + 383 @@ -1231,7 +1231,7 @@ Està segur qeu vol eliminar aquest cupó? apps/client/src/app/components/admin-overview/admin-overview.component.ts - 193 + 196 @@ -1239,7 +1239,7 @@ Està segur que vol eliminar aquest missatge del sistema? apps/client/src/app/components/admin-overview/admin-overview.component.ts - 206 + 209 @@ -1247,7 +1247,7 @@ Està segur que vol depurar el cache? apps/client/src/app/components/admin-overview/admin-overview.component.ts - 230 + 233 @@ -1255,7 +1255,7 @@ Si us plau, afegeixi el seu missatge del sistema: apps/client/src/app/components/admin-overview/admin-overview.component.ts - 250 + 253 @@ -1391,7 +1391,7 @@ Està segur que vol eliminar aquesta plataforma? apps/client/src/app/components/admin-platform/admin-platform.component.ts - 112 + 111 @@ -1423,7 +1423,7 @@ Current year apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 204 + 205 @@ -1471,7 +1471,7 @@ Està segur que vol eliminar aquesta etiqueta? apps/client/src/app/components/admin-tag/admin-tag.component.ts - 109 + 108 @@ -1495,7 +1495,7 @@ Està segur que vol eliminar aquest usuari? apps/client/src/app/components/admin-users/admin-users.component.ts - 218 + 215 @@ -1691,15 +1691,15 @@ Oooh! El testimoni de seguretat és incorrecte. apps/client/src/app/components/header/header.component.ts - 312 + 313 apps/client/src/app/components/user-account-access/user-account-access.component.ts - 154 + 152 apps/client/src/app/components/user-account-settings/user-account-settings.component.ts - 193 + 191 @@ -1779,7 +1779,7 @@ Informar d’un Problema amb les Dades apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html - 450 + 456 @@ -1787,7 +1787,7 @@ en Actiiu apps/client/src/app/components/home-holdings/home-holdings.component.ts - 64 + 63 @@ -1795,7 +1795,7 @@ Finalitzat apps/client/src/app/components/home-holdings/home-holdings.component.ts - 65 + 64 @@ -1819,7 +1819,7 @@ Gestionar Activitats apps/client/src/app/components/home-holdings/home-holdings.html - 65 + 64 @@ -1827,11 +1827,11 @@ Por apps/client/src/app/components/home-market/home-market.component.ts - 42 + 41 apps/client/src/app/components/markets/markets.component.ts - 47 + 46 libs/ui/src/lib/i18n.ts @@ -1843,11 +1843,11 @@ Cobdícia apps/client/src/app/components/home-market/home-market.component.ts - 43 + 42 apps/client/src/app/components/markets/markets.component.ts - 48 + 47 libs/ui/src/lib/i18n.ts @@ -1951,7 +1951,7 @@ Current week apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 196 + 197 @@ -2359,7 +2359,7 @@ YTD apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 204 + 205 libs/ui/src/lib/assistant/assistant.component.ts @@ -2371,7 +2371,7 @@ 1 any apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 208 + 209 libs/ui/src/lib/assistant/assistant.component.ts @@ -2383,7 +2383,7 @@ 5 anys apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 212 + 213 libs/ui/src/lib/assistant/assistant.component.ts @@ -2403,7 +2403,7 @@ Màx apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 216 + 217 libs/ui/src/lib/assistant/assistant.component.ts @@ -2547,7 +2547,7 @@ Automàtic apps/client/src/app/components/user-account-settings/user-account-settings.component.ts - 70 + 69 apps/client/src/app/components/user-account-settings/user-account-settings.html @@ -2559,7 +2559,7 @@ De debò vols tancar el teu compte de Ghostfolio? apps/client/src/app/components/user-account-settings/user-account-settings.component.ts - 208 + 205 @@ -2567,7 +2567,7 @@ De debò vols eliminar aquest mètode d’inici de sessió? apps/client/src/app/components/user-account-settings/user-account-settings.component.ts - 282 + 279 @@ -2583,7 +2583,7 @@ Ups! Hi ha hagut un error en configurar l’autenticació biomètrica. apps/client/src/app/components/user-account-settings/user-account-settings.component.ts - 336 + 333 @@ -2775,7 +2775,7 @@ apps/client/src/app/pages/portfolio/activities/import-activities-dialog/import-activities-dialog.component.ts - 195 + 194 @@ -2795,7 +2795,7 @@ apps/client/src/app/pages/portfolio/activities/import-activities-dialog/import-activities-dialog.component.ts - 193 + 192 @@ -2811,7 +2811,7 @@ apps/client/src/app/pages/portfolio/activities/import-activities-dialog/import-activities-dialog.component.ts - 196 + 195 @@ -2947,7 +2947,7 @@ apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html - 375 + 381 apps/client/src/app/components/user-detail-dialog/user-detail-dialog.html @@ -3051,7 +3051,7 @@ Dades de mercat apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html - 397 + 403 libs/common/src/lib/routes/routes.ts @@ -3085,6 +3085,10 @@ Overview Visió general + + apps/client/src/app/components/admin-jobs/admin-jobs.html + 7 + apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html 114 @@ -3972,7 +3976,7 @@ Job ID apps/client/src/app/components/admin-jobs/admin-jobs.html - 34 + 43 @@ -4028,7 +4032,7 @@ apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html - 342 + 348 apps/client/src/app/components/user-detail-dialog/user-detail-dialog.html @@ -4148,7 +4152,7 @@ Importar dividends apps/client/src/app/pages/portfolio/activities/import-activities-dialog/import-activities-dialog.component.ts - 137 + 136 libs/ui/src/lib/activities-table/activities-table.component.html @@ -4164,7 +4168,7 @@ S’estan important dades... apps/client/src/app/pages/portfolio/activities/import-activities-dialog/import-activities-dialog.component.ts - 175 + 174 @@ -4172,7 +4176,7 @@ La importació s’ha completat apps/client/src/app/pages/portfolio/activities/import-activities-dialog/import-activities-dialog.component.ts - 185 + 184 @@ -4188,7 +4192,7 @@ S’estan validant les dades... apps/client/src/app/pages/portfolio/activities/import-activities-dialog/import-activities-dialog.component.ts - 299 + 293 @@ -4504,7 +4508,7 @@ apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts - 76 + 75 libs/ui/src/lib/i18n.ts @@ -4524,11 +4528,11 @@ apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts - 81 + 80 apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts - 97 + 96 apps/client/src/app/pages/resources/personal-finance-tools/product-page.component.ts @@ -4548,7 +4552,7 @@ Mensualment apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts - 91 + 90 @@ -4556,7 +4560,7 @@ Anualment apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts - 92 + 91 @@ -4564,7 +4568,7 @@ Close Holding apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html - 441 + 447 @@ -4942,6 +4946,10 @@ apps/client/src/app/pages/register/user-account-registration-dialog/user-account-registration-dialog.html 88 + + libs/ui/src/lib/value/value.component.html + 18 + Personal Finance Tools @@ -5441,7 +5449,7 @@ WTD apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 196 + 197 libs/ui/src/lib/assistant/assistant.component.ts @@ -5461,7 +5469,7 @@ MTD apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 200 + 201 libs/ui/src/lib/assistant/assistant.component.ts @@ -5481,7 +5489,7 @@ any apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 208 + 209 apps/client/src/app/pages/resources/personal-finance-tools/product-page.html @@ -5501,7 +5509,7 @@ anys apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 212 + 213 libs/ui/src/lib/assistant/assistant.component.ts @@ -5653,7 +5661,7 @@ Dipòsit libs/ui/src/lib/fire-calculator/fire-calculator.component.ts - 390 + 404 @@ -5669,7 +5677,7 @@ libs/ui/src/lib/fire-calculator/fire-calculator.component.ts - 400 + 414 libs/ui/src/lib/i18n.ts @@ -5681,7 +5689,7 @@ Estalvi libs/ui/src/lib/fire-calculator/fire-calculator.component.ts - 410 + 424 @@ -5921,7 +5929,7 @@ libs/ui/src/lib/portfolio-proportion-chart/portfolio-proportion-chart.component.ts - 449 + 451 @@ -5937,7 +5945,7 @@ No Activities apps/client/src/app/components/admin-market-data/admin-market-data.component.ts - 146 + 145 @@ -5969,7 +5977,7 @@ Símbol apps/client/src/app/components/admin-jobs/admin-jobs.html - 68 + 77 apps/client/src/app/components/admin-market-data/admin-market-data.html @@ -5985,7 +5993,7 @@ apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html - 315 + 318 libs/ui/src/lib/i18n.ts @@ -6333,11 +6341,11 @@ libs/ui/src/lib/portfolio-proportion-chart/portfolio-proportion-chart.component.ts - 451 + 453 libs/ui/src/lib/portfolio-proportion-chart/portfolio-proportion-chart.component.ts - 465 + 467 libs/ui/src/lib/top-holdings/top-holdings.component.html @@ -6857,7 +6865,7 @@ Portfolio Snapshot apps/client/src/app/components/admin-jobs/admin-jobs.html - 56 + 65 @@ -6924,6 +6932,14 @@ 42 + + has been copied to the clipboard + has been copied to the clipboard + + libs/ui/src/lib/value/value.component.ts + 180 + + From the beginning From the beginning @@ -7363,7 +7379,7 @@ apps/client/src/app/components/user-account-access/user-account-access.component.ts - 260 + 257 @@ -7403,7 +7419,7 @@ AI prompt has been copied to the clipboard apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts - 201 + 199 @@ -7419,7 +7435,7 @@ Lazy apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 230 + 231 @@ -7427,7 +7443,7 @@ Instant apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 234 + 235 @@ -7467,7 +7483,7 @@ end of day apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 230 + 231 @@ -7475,7 +7491,7 @@ real-time apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 234 + 235 @@ -7483,7 +7499,7 @@ Open Duck.ai apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts - 202 + 200 @@ -7503,7 +7519,7 @@ libs/ui/src/lib/treemap-chart/treemap-chart.component.ts - 375 + 377 @@ -7515,7 +7531,7 @@ apps/client/src/app/components/home-overview/home-overview.component.ts - 55 + 54 libs/ui/src/lib/holdings-table/holdings-table.component.html @@ -7523,11 +7539,11 @@ libs/ui/src/lib/treemap-chart/treemap-chart.component.ts - 375 + 377 libs/ui/src/lib/treemap-chart/treemap-chart.component.ts - 388 + 390 @@ -7631,11 +7647,11 @@ Security token apps/client/src/app/components/admin-users/admin-users.component.ts - 239 + 235 apps/client/src/app/components/user-account-access/user-account-access.component.ts - 170 + 167 @@ -7643,7 +7659,7 @@ Do you really want to generate a new security token for this user? apps/client/src/app/components/admin-users/admin-users.component.ts - 244 + 240 @@ -7788,7 +7804,7 @@ someone apps/client/src/app/pages/public/public-page.component.ts - 59 + 61 @@ -7820,7 +7836,7 @@ Do you really want to delete this item? libs/ui/src/lib/benchmark/benchmark.component.ts - 144 + 139 @@ -7861,7 +7877,7 @@ Demo user account has been synced. apps/client/src/app/components/admin-overview/admin-overview.component.ts - 274 + 277 @@ -8075,7 +8091,7 @@ Current month apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 200 + 201 @@ -8244,7 +8260,7 @@ Do you really want to generate a new security token? apps/client/src/app/components/user-account-access/user-account-access.component.ts - 175 + 172 @@ -8268,7 +8284,7 @@ Stocks apps/client/src/app/components/markets/markets.component.ts - 52 + 51 apps/client/src/app/pages/features/features-page.html @@ -8280,7 +8296,7 @@ Cryptocurrencies apps/client/src/app/components/markets/markets.component.ts - 53 + 52 apps/client/src/app/pages/features/features-page.html @@ -8300,7 +8316,7 @@ Manage Asset Profile apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html - 465 + 471 diff --git a/apps/client/src/locales/messages.de.xlf b/apps/client/src/locales/messages.de.xlf index cad4fcc92..1a1df8cc1 100644 --- a/apps/client/src/locales/messages.de.xlf +++ b/apps/client/src/locales/messages.de.xlf @@ -50,7 +50,7 @@ Typ apps/client/src/app/components/admin-jobs/admin-jobs.html - 48 + 57 apps/client/src/app/components/user-account-access/create-or-update-access-dialog/create-or-update-access-dialog.html @@ -306,7 +306,7 @@ Jobs löschen apps/client/src/app/components/admin-jobs/admin-jobs.html - 193 + 202 @@ -314,7 +314,7 @@ Datenquelle apps/client/src/app/components/admin-jobs/admin-jobs.html - 82 + 91 apps/client/src/app/components/admin-market-data/admin-market-data.html @@ -338,7 +338,7 @@ Versuche apps/client/src/app/components/admin-jobs/admin-jobs.html - 120 + 129 @@ -346,7 +346,7 @@ Erstellt apps/client/src/app/components/admin-jobs/admin-jobs.html - 134 + 143 @@ -354,7 +354,7 @@ Abgeschlossen apps/client/src/app/components/admin-jobs/admin-jobs.html - 143 + 152 @@ -362,7 +362,7 @@ Status apps/client/src/app/components/admin-jobs/admin-jobs.html - 152 + 161 apps/client/src/app/components/admin-settings/admin-settings.component.html @@ -394,7 +394,7 @@ Historische Marktdaten apps/client/src/app/components/admin-jobs/admin-jobs.html - 54 + 63 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html @@ -406,7 +406,7 @@ Daten anzeigen apps/client/src/app/components/admin-jobs/admin-jobs.html - 208 + 217 @@ -414,7 +414,7 @@ Stacktrace anzeigen apps/client/src/app/components/admin-jobs/admin-jobs.html - 216 + 225 @@ -422,7 +422,7 @@ Job löschen apps/client/src/app/components/admin-jobs/admin-jobs.html - 224 + 233 @@ -514,7 +514,7 @@ Möchtest du diesen Gutscheincode wirklich löschen? apps/client/src/app/components/admin-overview/admin-overview.component.ts - 193 + 196 @@ -522,7 +522,7 @@ Möchtest du den Cache wirklich leeren? apps/client/src/app/components/admin-overview/admin-overview.component.ts - 230 + 233 @@ -530,7 +530,7 @@ Bitte gebe deine Systemmeldung ein: apps/client/src/app/components/admin-overview/admin-overview.component.ts - 250 + 253 @@ -650,7 +650,7 @@ Möchtest du diesen Benutzer wirklich löschen? apps/client/src/app/components/admin-users/admin-users.component.ts - 218 + 215 @@ -758,7 +758,7 @@ apps/client/src/app/components/header/header.component.ts - 297 + 298 apps/client/src/app/components/login-with-access-token-dialog/login-with-access-token-dialog.html @@ -778,15 +778,15 @@ Ups! Falsches Sicherheits-Token. apps/client/src/app/components/header/header.component.ts - 312 + 313 apps/client/src/app/components/user-account-access/user-account-access.component.ts - 154 + 152 apps/client/src/app/components/user-account-settings/user-account-settings.component.ts - 193 + 191 @@ -794,7 +794,7 @@ Aktivitäten verwalten apps/client/src/app/components/home-holdings/home-holdings.html - 65 + 64 @@ -1034,7 +1034,7 @@ Datenfehler melden apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html - 450 + 456 @@ -1082,7 +1082,7 @@ YTD apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 204 + 205 libs/ui/src/lib/assistant/assistant.component.ts @@ -1094,7 +1094,7 @@ 1J apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 208 + 209 libs/ui/src/lib/assistant/assistant.component.ts @@ -1106,7 +1106,7 @@ 5J apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 212 + 213 libs/ui/src/lib/assistant/assistant.component.ts @@ -1126,7 +1126,7 @@ Max apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 216 + 217 libs/ui/src/lib/assistant/assistant.component.ts @@ -1146,7 +1146,7 @@ apps/client/src/app/pages/portfolio/activities/import-activities-dialog/import-activities-dialog.component.ts - 196 + 195 @@ -1238,7 +1238,7 @@ Möchtest du diese Anmeldemethode wirklich löschen? apps/client/src/app/components/user-account-settings/user-account-settings.component.ts - 282 + 279 @@ -1394,7 +1394,7 @@ apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html - 375 + 381 apps/client/src/app/components/user-detail-dialog/user-detail-dialog.html @@ -1676,6 +1676,10 @@ Overview Übersicht + + apps/client/src/app/components/admin-jobs/admin-jobs.html + 7 + apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html 114 @@ -1934,7 +1938,7 @@ Aktuelle Woche apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 196 + 197 @@ -2058,7 +2062,7 @@ apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html - 342 + 348 apps/client/src/app/components/user-detail-dialog/user-detail-dialog.html @@ -2082,7 +2086,7 @@ Daten importieren... apps/client/src/app/pages/portfolio/activities/import-activities-dialog/import-activities-dialog.component.ts - 175 + 174 @@ -2090,7 +2094,7 @@ Der Import wurde abgeschlossen apps/client/src/app/pages/portfolio/activities/import-activities-dialog/import-activities-dialog.component.ts - 185 + 184 @@ -2208,6 +2212,10 @@ apps/client/src/app/pages/register/user-account-registration-dialog/user-account-registration-dialog.html 88 + + libs/ui/src/lib/value/value.component.html + 18 + Resources @@ -2398,7 +2406,7 @@ apps/client/src/app/pages/portfolio/activities/import-activities-dialog/import-activities-dialog.component.ts - 195 + 194 @@ -2410,7 +2418,7 @@ apps/client/src/app/pages/portfolio/activities/import-activities-dialog/import-activities-dialog.component.ts - 193 + 192 @@ -2530,7 +2538,7 @@ Monatlich apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts - 91 + 90 @@ -2546,7 +2554,7 @@ Einlage libs/ui/src/lib/fire-calculator/fire-calculator.component.ts - 390 + 404 @@ -2562,7 +2570,7 @@ libs/ui/src/lib/fire-calculator/fire-calculator.component.ts - 400 + 414 libs/ui/src/lib/i18n.ts @@ -2574,7 +2582,7 @@ Ersparnisse libs/ui/src/lib/fire-calculator/fire-calculator.component.ts - 410 + 424 @@ -2598,11 +2606,11 @@ Angst apps/client/src/app/components/home-market/home-market.component.ts - 42 + 41 apps/client/src/app/components/markets/markets.component.ts - 47 + 46 libs/ui/src/lib/i18n.ts @@ -2614,11 +2622,11 @@ Gier apps/client/src/app/components/home-market/home-market.component.ts - 43 + 42 apps/client/src/app/components/markets/markets.component.ts - 48 + 47 libs/ui/src/lib/i18n.ts @@ -2630,7 +2638,7 @@ Filtern nach... apps/client/src/app/components/admin-market-data/admin-market-data.component.ts - 390 + 383 @@ -2714,7 +2722,7 @@ Automatisch apps/client/src/app/components/user-account-settings/user-account-settings.component.ts - 70 + 69 apps/client/src/app/components/user-account-settings/user-account-settings.html @@ -2826,7 +2834,7 @@ Symbol apps/client/src/app/components/admin-jobs/admin-jobs.html - 68 + 77 apps/client/src/app/components/admin-market-data/admin-market-data.html @@ -2842,7 +2850,7 @@ apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html - 315 + 318 libs/ui/src/lib/i18n.ts @@ -2998,7 +3006,7 @@ libs/ui/src/lib/portfolio-proportion-chart/portfolio-proportion-chart.component.ts - 449 + 451 @@ -3018,11 +3026,11 @@ libs/ui/src/lib/portfolio-proportion-chart/portfolio-proportion-chart.component.ts - 451 + 453 libs/ui/src/lib/portfolio-proportion-chart/portfolio-proportion-chart.component.ts - 465 + 467 libs/ui/src/lib/top-holdings/top-holdings.component.html @@ -3170,7 +3178,7 @@ apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts - 76 + 75 libs/ui/src/lib/i18n.ts @@ -3218,7 +3226,7 @@ Daten validieren... apps/client/src/app/pages/portfolio/activities/import-activities-dialog/import-activities-dialog.component.ts - 299 + 293 @@ -3242,7 +3250,7 @@ Marktdaten apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html - 397 + 403 libs/common/src/lib/routes/routes.ts @@ -3294,7 +3302,7 @@ Jährlich apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts - 92 + 91 @@ -3302,7 +3310,7 @@ Dividenden importieren apps/client/src/app/pages/portfolio/activities/import-activities-dialog/import-activities-dialog.component.ts - 137 + 136 libs/ui/src/lib/activities-table/activities-table.component.html @@ -3362,7 +3370,7 @@ Keine Aktivitäten apps/client/src/app/components/admin-market-data/admin-market-data.component.ts - 146 + 145 @@ -3874,7 +3882,7 @@ Aktuelles Jahr apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 204 + 205 @@ -3918,7 +3926,7 @@ Möchtest du diese Plattform wirklich löschen? apps/client/src/app/components/admin-platform/admin-platform.component.ts - 112 + 111 @@ -4514,7 +4522,7 @@ ETFs ohne Länder apps/client/src/app/components/admin-market-data/admin-market-data.component.ts - 136 + 135 @@ -4522,7 +4530,7 @@ ETFs ohne Sektoren apps/client/src/app/components/admin-market-data/admin-market-data.component.ts - 141 + 140 @@ -4702,7 +4710,7 @@ Job ID apps/client/src/app/components/admin-jobs/admin-jobs.html - 34 + 43 @@ -4758,7 +4766,7 @@ Währungen apps/client/src/app/components/admin-market-data/admin-market-data.component.ts - 131 + 130 apps/client/src/app/pages/public/public-page.html @@ -5508,7 +5516,7 @@ Möchtest du diesen Tag wirklich löschen? apps/client/src/app/components/admin-tag/admin-tag.component.ts - 109 + 108 @@ -5608,7 +5616,7 @@ Anlageprofil apps/client/src/app/components/admin-jobs/admin-jobs.html - 52 + 61 @@ -5740,7 +5748,7 @@ Möchtest du diese Systemmeldung wirklich löschen? apps/client/src/app/components/admin-overview/admin-overview.component.ts - 206 + 209 @@ -5896,11 +5904,11 @@ apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts - 81 + 80 apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts - 97 + 96 apps/client/src/app/pages/resources/personal-finance-tools/product-page.component.ts @@ -5920,7 +5928,7 @@ Position abschliessen apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html - 441 + 447 @@ -5968,7 +5976,7 @@ WTD apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 196 + 197 libs/ui/src/lib/assistant/assistant.component.ts @@ -5988,7 +5996,7 @@ MTD apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 200 + 201 libs/ui/src/lib/assistant/assistant.component.ts @@ -6036,7 +6044,7 @@ Jahr apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 208 + 209 apps/client/src/app/pages/resources/personal-finance-tools/product-page.html @@ -6056,7 +6064,7 @@ Jahre apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 212 + 213 libs/ui/src/lib/assistant/assistant.component.ts @@ -6149,7 +6157,7 @@ Aktiv apps/client/src/app/components/home-holdings/home-holdings.component.ts - 64 + 63 @@ -6157,7 +6165,7 @@ Abgeschlossen apps/client/src/app/components/home-holdings/home-holdings.component.ts - 65 + 64 @@ -6189,7 +6197,7 @@ Job ausführen apps/client/src/app/components/admin-jobs/admin-jobs.html - 220 + 229 @@ -6197,7 +6205,7 @@ Priorität apps/client/src/app/components/admin-jobs/admin-jobs.html - 96 + 105 @@ -6253,7 +6261,7 @@ Möchtest du dieses Ghostfolio Konto wirklich schliessen? apps/client/src/app/components/user-account-settings/user-account-settings.component.ts - 208 + 205 @@ -6309,7 +6317,7 @@ Ups! Beim Einrichten der biometrischen Authentifizierung ist ein Fehler aufgetreten. apps/client/src/app/components/user-account-settings/user-account-settings.component.ts - 336 + 333 @@ -6325,7 +6333,7 @@ Benchmarks apps/client/src/app/components/admin-market-data/admin-market-data.component.ts - 126 + 125 @@ -6881,7 +6889,7 @@ Portfolio Snapshot apps/client/src/app/components/admin-jobs/admin-jobs.html - 56 + 65 @@ -6948,6 +6956,14 @@ 42 + + has been copied to the clipboard + has been copied to the clipboard + + libs/ui/src/lib/value/value.component.ts + 180 + + From the beginning Seit Beginn @@ -7387,7 +7403,7 @@ apps/client/src/app/components/user-account-access/user-account-access.component.ts - 260 + 257 @@ -7427,7 +7443,7 @@ KI-Anweisung wurde in die Zwischenablage kopiert apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts - 201 + 199 @@ -7443,7 +7459,7 @@ Verzögert apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 230 + 231 @@ -7451,7 +7467,7 @@ Sofort apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 234 + 235 @@ -7491,7 +7507,7 @@ Tagesende apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 230 + 231 @@ -7499,7 +7515,7 @@ in Echtzeit apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 234 + 235 @@ -7507,7 +7523,7 @@ Öffne Duck.ai apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts - 202 + 200 @@ -7527,7 +7543,7 @@ libs/ui/src/lib/treemap-chart/treemap-chart.component.ts - 375 + 377 @@ -7539,7 +7555,7 @@ apps/client/src/app/components/home-overview/home-overview.component.ts - 55 + 54 libs/ui/src/lib/holdings-table/holdings-table.component.html @@ -7547,11 +7563,11 @@ libs/ui/src/lib/treemap-chart/treemap-chart.component.ts - 375 + 377 libs/ui/src/lib/treemap-chart/treemap-chart.component.ts - 388 + 390 @@ -7655,11 +7671,11 @@ Sicherheits-Token apps/client/src/app/components/admin-users/admin-users.component.ts - 239 + 235 apps/client/src/app/components/user-account-access/user-account-access.component.ts - 170 + 167 @@ -7667,7 +7683,7 @@ Möchtest du für diesen Benutzer wirklich ein neues Sicherheits-Token generieren? apps/client/src/app/components/admin-users/admin-users.component.ts - 244 + 240 @@ -7788,7 +7804,7 @@ jemand apps/client/src/app/pages/public/public-page.component.ts - 59 + 61 @@ -7820,7 +7836,7 @@ Möchtest du diesen Eintrag wirklich löschen? libs/ui/src/lib/benchmark/benchmark.component.ts - 144 + 139 @@ -7861,7 +7877,7 @@ Demo Benutzerkonto wurde synchronisiert. apps/client/src/app/components/admin-overview/admin-overview.component.ts - 274 + 277 @@ -8075,7 +8091,7 @@ Aktueller Monat apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 200 + 201 @@ -8244,7 +8260,7 @@ Möchtest du wirklich ein neues Sicherheits-Token generieren? apps/client/src/app/components/user-account-access/user-account-access.component.ts - 175 + 172 @@ -8268,7 +8284,7 @@ Aktien apps/client/src/app/components/markets/markets.component.ts - 52 + 51 apps/client/src/app/pages/features/features-page.html @@ -8280,7 +8296,7 @@ Kryptowährungen apps/client/src/app/components/markets/markets.component.ts - 53 + 52 apps/client/src/app/pages/features/features-page.html @@ -8300,7 +8316,7 @@ Anlageprofil verwalten apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html - 465 + 471 diff --git a/apps/client/src/locales/messages.es.xlf b/apps/client/src/locales/messages.es.xlf index 9a932471c..26c76ef6c 100644 --- a/apps/client/src/locales/messages.es.xlf +++ b/apps/client/src/locales/messages.es.xlf @@ -51,7 +51,7 @@ Tipo apps/client/src/app/components/admin-jobs/admin-jobs.html - 48 + 57 apps/client/src/app/components/user-account-access/create-or-update-access-dialog/create-or-update-access-dialog.html @@ -307,7 +307,7 @@ Eliminar trabajos apps/client/src/app/components/admin-jobs/admin-jobs.html - 193 + 202 @@ -315,7 +315,7 @@ Fuente de datos apps/client/src/app/components/admin-jobs/admin-jobs.html - 82 + 91 apps/client/src/app/components/admin-market-data/admin-market-data.html @@ -339,7 +339,7 @@ Intentos apps/client/src/app/components/admin-jobs/admin-jobs.html - 120 + 129 @@ -347,7 +347,7 @@ Creado apps/client/src/app/components/admin-jobs/admin-jobs.html - 134 + 143 @@ -355,7 +355,7 @@ Finalizado apps/client/src/app/components/admin-jobs/admin-jobs.html - 143 + 152 @@ -363,7 +363,7 @@ Estado apps/client/src/app/components/admin-jobs/admin-jobs.html - 152 + 161 apps/client/src/app/components/admin-settings/admin-settings.component.html @@ -395,7 +395,7 @@ Datos históricos del mercado apps/client/src/app/components/admin-jobs/admin-jobs.html - 54 + 63 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html @@ -407,7 +407,7 @@ Ver datos apps/client/src/app/components/admin-jobs/admin-jobs.html - 208 + 217 @@ -415,7 +415,7 @@ Ver Stacktrace apps/client/src/app/components/admin-jobs/admin-jobs.html - 216 + 225 @@ -423,7 +423,7 @@ Eliminar trabajo apps/client/src/app/components/admin-jobs/admin-jobs.html - 224 + 233 @@ -515,7 +515,7 @@ ¿Seguro que quieres eliminar este cupón? apps/client/src/app/components/admin-overview/admin-overview.component.ts - 193 + 196 @@ -523,7 +523,7 @@ ¿Seguro que quieres limpiar la caché? apps/client/src/app/components/admin-overview/admin-overview.component.ts - 230 + 233 @@ -531,7 +531,7 @@ Por favor, establece tu mensaje del sistema: apps/client/src/app/components/admin-overview/admin-overview.component.ts - 250 + 253 @@ -635,7 +635,7 @@ ¿Seguro que quieres eliminar este usuario? apps/client/src/app/components/admin-users/admin-users.component.ts - 218 + 215 @@ -743,7 +743,7 @@ apps/client/src/app/components/header/header.component.ts - 297 + 298 apps/client/src/app/components/login-with-access-token-dialog/login-with-access-token-dialog.html @@ -763,15 +763,15 @@ ¡Vaya! Token de seguridad incorrecto. apps/client/src/app/components/header/header.component.ts - 312 + 313 apps/client/src/app/components/user-account-access/user-account-access.component.ts - 154 + 152 apps/client/src/app/components/user-account-settings/user-account-settings.component.ts - 193 + 191 @@ -779,7 +779,7 @@ Gestionar operaciones apps/client/src/app/components/home-holdings/home-holdings.html - 65 + 64 @@ -1019,7 +1019,7 @@ Reportar anomalía en los datos apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html - 450 + 456 @@ -1067,7 +1067,7 @@ YTD apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 204 + 205 libs/ui/src/lib/assistant/assistant.component.ts @@ -1079,7 +1079,7 @@ 1 año apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 208 + 209 libs/ui/src/lib/assistant/assistant.component.ts @@ -1091,7 +1091,7 @@ 5 años apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 212 + 213 libs/ui/src/lib/assistant/assistant.component.ts @@ -1111,7 +1111,7 @@ Máximo apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 216 + 217 libs/ui/src/lib/assistant/assistant.component.ts @@ -1131,7 +1131,7 @@ apps/client/src/app/pages/portfolio/activities/import-activities-dialog/import-activities-dialog.component.ts - 196 + 195 @@ -1223,7 +1223,7 @@ ¿Seguro que quieres eliminar este método de acceso? apps/client/src/app/components/user-account-settings/user-account-settings.component.ts - 282 + 279 @@ -1379,7 +1379,7 @@ apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html - 375 + 381 apps/client/src/app/components/user-detail-dialog/user-detail-dialog.html @@ -1661,6 +1661,10 @@ Overview Visión general + + apps/client/src/app/components/admin-jobs/admin-jobs.html + 7 + apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html 114 @@ -1919,7 +1923,7 @@ Semana actual apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 196 + 197 @@ -2043,7 +2047,7 @@ apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html - 342 + 348 apps/client/src/app/components/user-detail-dialog/user-detail-dialog.html @@ -2067,7 +2071,7 @@ Importando datos... apps/client/src/app/pages/portfolio/activities/import-activities-dialog/import-activities-dialog.component.ts - 175 + 174 @@ -2075,7 +2079,7 @@ La importación se ha completado apps/client/src/app/pages/portfolio/activities/import-activities-dialog/import-activities-dialog.component.ts - 185 + 184 @@ -2193,6 +2197,10 @@ apps/client/src/app/pages/register/user-account-registration-dialog/user-account-registration-dialog.html 88 + + libs/ui/src/lib/value/value.component.html + 18 + Resources @@ -2379,7 +2387,7 @@ apps/client/src/app/pages/portfolio/activities/import-activities-dialog/import-activities-dialog.component.ts - 193 + 192 @@ -2395,7 +2403,7 @@ apps/client/src/app/pages/portfolio/activities/import-activities-dialog/import-activities-dialog.component.ts - 195 + 194 @@ -2515,7 +2523,7 @@ Ahorros libs/ui/src/lib/fire-calculator/fire-calculator.component.ts - 410 + 424 @@ -2531,7 +2539,7 @@ libs/ui/src/lib/fire-calculator/fire-calculator.component.ts - 400 + 414 libs/ui/src/lib/i18n.ts @@ -2551,7 +2559,7 @@ Depósito libs/ui/src/lib/fire-calculator/fire-calculator.component.ts - 390 + 404 @@ -2559,7 +2567,7 @@ Mensual apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts - 91 + 90 @@ -2583,11 +2591,11 @@ Miedo apps/client/src/app/components/home-market/home-market.component.ts - 42 + 41 apps/client/src/app/components/markets/markets.component.ts - 47 + 46 libs/ui/src/lib/i18n.ts @@ -2599,11 +2607,11 @@ Codicia apps/client/src/app/components/home-market/home-market.component.ts - 43 + 42 apps/client/src/app/components/markets/markets.component.ts - 48 + 47 libs/ui/src/lib/i18n.ts @@ -2615,7 +2623,7 @@ Filtrar por... apps/client/src/app/components/admin-market-data/admin-market-data.component.ts - 390 + 383 @@ -2699,7 +2707,7 @@ Automático apps/client/src/app/components/user-account-settings/user-account-settings.component.ts - 70 + 69 apps/client/src/app/components/user-account-settings/user-account-settings.html @@ -2811,7 +2819,7 @@ Símbolo apps/client/src/app/components/admin-jobs/admin-jobs.html - 68 + 77 apps/client/src/app/components/admin-market-data/admin-market-data.html @@ -2827,7 +2835,7 @@ apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html - 315 + 318 libs/ui/src/lib/i18n.ts @@ -2983,7 +2991,7 @@ libs/ui/src/lib/portfolio-proportion-chart/portfolio-proportion-chart.component.ts - 449 + 451 @@ -3003,11 +3011,11 @@ libs/ui/src/lib/portfolio-proportion-chart/portfolio-proportion-chart.component.ts - 451 + 453 libs/ui/src/lib/portfolio-proportion-chart/portfolio-proportion-chart.component.ts - 465 + 467 libs/ui/src/lib/top-holdings/top-holdings.component.html @@ -3147,7 +3155,7 @@ apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts - 76 + 75 libs/ui/src/lib/i18n.ts @@ -3203,7 +3211,7 @@ Validando datos... apps/client/src/app/pages/portfolio/activities/import-activities-dialog/import-activities-dialog.component.ts - 299 + 293 @@ -3227,7 +3235,7 @@ Datos del mercado apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html - 397 + 403 libs/common/src/lib/routes/routes.ts @@ -3279,7 +3287,7 @@ Anual apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts - 92 + 91 @@ -3287,7 +3295,7 @@ Importar dividendos apps/client/src/app/pages/portfolio/activities/import-activities-dialog/import-activities-dialog.component.ts - 137 + 136 libs/ui/src/lib/activities-table/activities-table.component.html @@ -3347,7 +3355,7 @@ Sin operaciones apps/client/src/app/components/admin-market-data/admin-market-data.component.ts - 146 + 145 @@ -3851,7 +3859,7 @@ Año actual apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 204 + 205 @@ -3895,7 +3903,7 @@ ¿Seguro que quieres eliminar esta plataforma? apps/client/src/app/components/admin-platform/admin-platform.component.ts - 112 + 111 @@ -4491,7 +4499,7 @@ ETFs sin países apps/client/src/app/components/admin-market-data/admin-market-data.component.ts - 136 + 135 @@ -4499,7 +4507,7 @@ ETFs sin sectores apps/client/src/app/components/admin-market-data/admin-market-data.component.ts - 141 + 140 @@ -4679,7 +4687,7 @@ ID del trabajo apps/client/src/app/components/admin-jobs/admin-jobs.html - 34 + 43 @@ -4735,7 +4743,7 @@ Divisas apps/client/src/app/components/admin-market-data/admin-market-data.component.ts - 131 + 130 apps/client/src/app/pages/public/public-page.html @@ -4964,7 +4972,7 @@ caring about diversifying your financial resources - preocupado por diversificar tus recursos financieros + preocupado por diversificar tus recursos financieros apps/client/src/app/pages/landing/landing-page.html 201 @@ -5485,7 +5493,7 @@ ¿Seguro que quieres eliminar esta etiqueta? apps/client/src/app/components/admin-tag/admin-tag.component.ts - 109 + 108 @@ -5585,7 +5593,7 @@ Perfil de activo apps/client/src/app/components/admin-jobs/admin-jobs.html - 52 + 61 @@ -5717,7 +5725,7 @@ ¿Seguro que quieres eliminar este mensaje del sistema? apps/client/src/app/components/admin-overview/admin-overview.component.ts - 206 + 209 @@ -5873,11 +5881,11 @@ apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts - 81 + 80 apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts - 97 + 96 apps/client/src/app/pages/resources/personal-finance-tools/product-page.component.ts @@ -5897,7 +5905,7 @@ Cerrar posición apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html - 441 + 447 @@ -5945,7 +5953,7 @@ WTD apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 196 + 197 libs/ui/src/lib/assistant/assistant.component.ts @@ -5965,7 +5973,7 @@ MTD apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 200 + 201 libs/ui/src/lib/assistant/assistant.component.ts @@ -6013,7 +6021,7 @@ año apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 208 + 209 apps/client/src/app/pages/resources/personal-finance-tools/product-page.html @@ -6033,7 +6041,7 @@ años apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 212 + 213 libs/ui/src/lib/assistant/assistant.component.ts @@ -6126,7 +6134,7 @@ Activo apps/client/src/app/components/home-holdings/home-holdings.component.ts - 64 + 63 @@ -6134,7 +6142,7 @@ Cerrado apps/client/src/app/components/home-holdings/home-holdings.component.ts - 65 + 64 @@ -6166,7 +6174,7 @@ Ejecutar trabajo apps/client/src/app/components/admin-jobs/admin-jobs.html - 220 + 229 @@ -6174,7 +6182,7 @@ Prioridad apps/client/src/app/components/admin-jobs/admin-jobs.html - 96 + 105 @@ -6230,7 +6238,7 @@ ¿Seguro que quieres eliminar tu cuenta de Ghostfolio? apps/client/src/app/components/user-account-settings/user-account-settings.component.ts - 208 + 205 @@ -6286,7 +6294,7 @@ ¡Vaya! Hubo un error al configurar la autenticación biométrica. apps/client/src/app/components/user-account-settings/user-account-settings.component.ts - 336 + 333 @@ -6302,7 +6310,7 @@ Índices de referencia apps/client/src/app/components/admin-market-data/admin-market-data.component.ts - 126 + 125 @@ -6858,7 +6866,7 @@ Instantánea de la cartera apps/client/src/app/components/admin-jobs/admin-jobs.html - 56 + 65 @@ -6925,6 +6933,14 @@ 42 + + has been copied to the clipboard + has been copied to the clipboard + + libs/ui/src/lib/value/value.component.ts + 180 + + From the beginning Desde el principio @@ -7364,7 +7380,7 @@ apps/client/src/app/components/user-account-access/user-account-access.component.ts - 260 + 257 @@ -7404,7 +7420,7 @@ El prompt para la IA ha sido copiado al portapapeles apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts - 201 + 199 @@ -7420,7 +7436,7 @@ Bajo demanda apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 230 + 231 @@ -7428,7 +7444,7 @@ Instantáneo apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 234 + 235 @@ -7468,7 +7484,7 @@ final del día apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 230 + 231 @@ -7476,7 +7492,7 @@ en tiempo real apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 234 + 235 @@ -7484,7 +7500,7 @@ Abrir Duck.ai apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts - 202 + 200 @@ -7504,7 +7520,7 @@ libs/ui/src/lib/treemap-chart/treemap-chart.component.ts - 375 + 377 @@ -7516,7 +7532,7 @@ apps/client/src/app/components/home-overview/home-overview.component.ts - 55 + 54 libs/ui/src/lib/holdings-table/holdings-table.component.html @@ -7524,11 +7540,11 @@ libs/ui/src/lib/treemap-chart/treemap-chart.component.ts - 375 + 377 libs/ui/src/lib/treemap-chart/treemap-chart.component.ts - 388 + 390 @@ -7632,11 +7648,11 @@ Token de seguridad apps/client/src/app/components/admin-users/admin-users.component.ts - 239 + 235 apps/client/src/app/components/user-account-access/user-account-access.component.ts - 170 + 167 @@ -7644,7 +7660,7 @@ ¿Seguro que quieres generar un nuevo token de seguridad para este usuario? apps/client/src/app/components/admin-users/admin-users.component.ts - 244 + 240 @@ -7789,7 +7805,7 @@ alguien apps/client/src/app/pages/public/public-page.component.ts - 59 + 61 @@ -7821,7 +7837,7 @@ ¿Seguro que quieres eliminar este elemento? libs/ui/src/lib/benchmark/benchmark.component.ts - 144 + 139 @@ -7862,7 +7878,7 @@ La cuenta de usuario de demostración se ha sincronizado. apps/client/src/app/components/admin-overview/admin-overview.component.ts - 274 + 277 @@ -8076,7 +8092,7 @@ Mes actual apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 200 + 201 @@ -8245,7 +8261,7 @@ ¿Seguro que quieres generar un nuevo token de seguridad? apps/client/src/app/components/user-account-access/user-account-access.component.ts - 175 + 172 @@ -8269,7 +8285,7 @@ Acciones apps/client/src/app/components/markets/markets.component.ts - 52 + 51 apps/client/src/app/pages/features/features-page.html @@ -8281,7 +8297,7 @@ Criptomonedas apps/client/src/app/components/markets/markets.component.ts - 53 + 52 apps/client/src/app/pages/features/features-page.html @@ -8301,7 +8317,7 @@ Gestionar perfil de activo apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html - 465 + 471 diff --git a/apps/client/src/locales/messages.fr.xlf b/apps/client/src/locales/messages.fr.xlf index f01a3a505..eec144e92 100644 --- a/apps/client/src/locales/messages.fr.xlf +++ b/apps/client/src/locales/messages.fr.xlf @@ -42,7 +42,7 @@ Type apps/client/src/app/components/admin-jobs/admin-jobs.html - 48 + 57 apps/client/src/app/components/user-account-access/create-or-update-access-dialog/create-or-update-access-dialog.html @@ -362,7 +362,7 @@ Source Données apps/client/src/app/components/admin-jobs/admin-jobs.html - 82 + 91 apps/client/src/app/components/admin-market-data/admin-market-data.html @@ -386,7 +386,7 @@ Tentatives apps/client/src/app/components/admin-jobs/admin-jobs.html - 120 + 129 @@ -394,7 +394,7 @@ Créé apps/client/src/app/components/admin-jobs/admin-jobs.html - 134 + 143 @@ -402,7 +402,7 @@ Terminé apps/client/src/app/components/admin-jobs/admin-jobs.html - 143 + 152 @@ -410,7 +410,7 @@ Statut apps/client/src/app/components/admin-jobs/admin-jobs.html - 152 + 161 apps/client/src/app/components/admin-settings/admin-settings.component.html @@ -430,7 +430,7 @@ Supprimer Tâches apps/client/src/app/components/admin-jobs/admin-jobs.html - 193 + 202 @@ -450,7 +450,7 @@ Données historiques du marché apps/client/src/app/components/admin-jobs/admin-jobs.html - 54 + 63 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html @@ -462,7 +462,7 @@ Voir Données apps/client/src/app/components/admin-jobs/admin-jobs.html - 208 + 217 @@ -470,7 +470,7 @@ Voir la Stacktrace apps/client/src/app/components/admin-jobs/admin-jobs.html - 216 + 225 @@ -478,7 +478,7 @@ Supprimer Tâche apps/client/src/app/components/admin-jobs/admin-jobs.html - 224 + 233 @@ -530,7 +530,7 @@ Filtrer par... apps/client/src/app/components/admin-market-data/admin-market-data.component.ts - 390 + 383 @@ -706,7 +706,7 @@ Voulez-vous vraiment supprimer ce code promotionnel ? apps/client/src/app/components/admin-overview/admin-overview.component.ts - 193 + 196 @@ -714,7 +714,7 @@ Voulez-vous vraiment vider le cache ? apps/client/src/app/components/admin-overview/admin-overview.component.ts - 230 + 233 @@ -722,7 +722,7 @@ Veuillez définir votre message système : apps/client/src/app/components/admin-overview/admin-overview.component.ts - 250 + 253 @@ -846,7 +846,7 @@ Voulez-vous vraiment supprimer cet·te utilisateur·rice ? apps/client/src/app/components/admin-users/admin-users.component.ts - 218 + 215 @@ -978,7 +978,7 @@ apps/client/src/app/components/header/header.component.ts - 297 + 298 apps/client/src/app/components/login-with-access-token-dialog/login-with-access-token-dialog.html @@ -998,15 +998,15 @@ Oups! Jeton de Sécurité Incorrect. apps/client/src/app/components/header/header.component.ts - 312 + 313 apps/client/src/app/components/user-account-access/user-account-access.component.ts - 154 + 152 apps/client/src/app/components/user-account-settings/user-account-settings.component.ts - 193 + 191 @@ -1014,7 +1014,7 @@ Gérer les Activités apps/client/src/app/components/home-holdings/home-holdings.html - 65 + 64 @@ -1022,11 +1022,11 @@ Peur apps/client/src/app/components/home-market/home-market.component.ts - 42 + 41 apps/client/src/app/components/markets/markets.component.ts - 47 + 46 libs/ui/src/lib/i18n.ts @@ -1038,11 +1038,11 @@ Avidité apps/client/src/app/components/home-market/home-market.component.ts - 43 + 42 apps/client/src/app/components/markets/markets.component.ts - 48 + 47 libs/ui/src/lib/i18n.ts @@ -1294,7 +1294,7 @@ Signaler une Erreur de Données apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html - 450 + 456 @@ -1314,7 +1314,7 @@ CDA apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 204 + 205 libs/ui/src/lib/assistant/assistant.component.ts @@ -1326,7 +1326,7 @@ 1A apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 208 + 209 libs/ui/src/lib/assistant/assistant.component.ts @@ -1338,7 +1338,7 @@ 5A apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 212 + 213 libs/ui/src/lib/assistant/assistant.component.ts @@ -1358,7 +1358,7 @@ Max apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 216 + 217 libs/ui/src/lib/assistant/assistant.component.ts @@ -1386,7 +1386,7 @@ apps/client/src/app/pages/portfolio/activities/import-activities-dialog/import-activities-dialog.component.ts - 195 + 194 @@ -1398,7 +1398,7 @@ apps/client/src/app/pages/portfolio/activities/import-activities-dialog/import-activities-dialog.component.ts - 193 + 192 @@ -1414,7 +1414,7 @@ apps/client/src/app/pages/portfolio/activities/import-activities-dialog/import-activities-dialog.component.ts - 196 + 195 @@ -1474,7 +1474,7 @@ Auto apps/client/src/app/components/user-account-settings/user-account-settings.component.ts - 70 + 69 apps/client/src/app/components/user-account-settings/user-account-settings.html @@ -1518,7 +1518,7 @@ Voulez-vous vraiment supprimer cette méthode de connexion ? apps/client/src/app/components/user-account-settings/user-account-settings.component.ts - 282 + 279 @@ -1714,7 +1714,7 @@ apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html - 375 + 381 apps/client/src/app/components/user-detail-dialog/user-detail-dialog.html @@ -1762,7 +1762,7 @@ Données du marché apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html - 397 + 403 libs/common/src/lib/routes/routes.ts @@ -2066,7 +2066,7 @@ apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html - 342 + 348 apps/client/src/app/components/user-detail-dialog/user-detail-dialog.html @@ -2098,7 +2098,7 @@ Current week apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 196 + 197 @@ -2162,7 +2162,7 @@ Import des données... apps/client/src/app/pages/portfolio/activities/import-activities-dialog/import-activities-dialog.component.ts - 175 + 174 @@ -2170,7 +2170,7 @@ L’import est terminé apps/client/src/app/pages/portfolio/activities/import-activities-dialog/import-activities-dialog.component.ts - 185 + 184 @@ -2186,7 +2186,7 @@ Validation des données... apps/client/src/app/pages/portfolio/activities/import-activities-dialog/import-activities-dialog.component.ts - 299 + 293 @@ -2418,7 +2418,7 @@ apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts - 76 + 75 libs/ui/src/lib/i18n.ts @@ -2438,7 +2438,7 @@ Dépôt libs/ui/src/lib/fire-calculator/fire-calculator.component.ts - 390 + 404 @@ -2446,7 +2446,7 @@ Mensuel apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts - 91 + 90 @@ -2648,6 +2648,10 @@ apps/client/src/app/pages/register/user-account-registration-dialog/user-account-registration-dialog.html 88 + + libs/ui/src/lib/value/value.component.html + 18 + Resources @@ -2700,6 +2704,10 @@ Overview Aperçu + + apps/client/src/app/components/admin-jobs/admin-jobs.html + 7 + apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html 114 @@ -2858,7 +2866,7 @@ libs/ui/src/lib/fire-calculator/fire-calculator.component.ts - 400 + 414 libs/ui/src/lib/i18n.ts @@ -2870,7 +2878,7 @@ Épargne libs/ui/src/lib/fire-calculator/fire-calculator.component.ts - 410 + 424 @@ -3006,7 +3014,7 @@ libs/ui/src/lib/portfolio-proportion-chart/portfolio-proportion-chart.component.ts - 449 + 451 @@ -3014,7 +3022,7 @@ Symbole apps/client/src/app/components/admin-jobs/admin-jobs.html - 68 + 77 apps/client/src/app/components/admin-market-data/admin-market-data.html @@ -3030,7 +3038,7 @@ apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html - 315 + 318 libs/ui/src/lib/i18n.ts @@ -3242,11 +3250,11 @@ libs/ui/src/lib/portfolio-proportion-chart/portfolio-proportion-chart.component.ts - 451 + 453 libs/ui/src/lib/portfolio-proportion-chart/portfolio-proportion-chart.component.ts - 465 + 467 libs/ui/src/lib/top-holdings/top-holdings.component.html @@ -3278,7 +3286,7 @@ Annuel apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts - 92 + 91 @@ -3286,7 +3294,7 @@ Importer Dividendes apps/client/src/app/pages/portfolio/activities/import-activities-dialog/import-activities-dialog.component.ts - 137 + 136 libs/ui/src/lib/activities-table/activities-table.component.html @@ -3346,7 +3354,7 @@ No Activities apps/client/src/app/components/admin-market-data/admin-market-data.component.ts - 146 + 145 @@ -3850,7 +3858,7 @@ Current year apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 204 + 205 @@ -3894,7 +3902,7 @@ Voulez-vous vraiment supprimer cette plateforme ? apps/client/src/app/components/admin-platform/admin-platform.component.ts - 112 + 111 @@ -4490,7 +4498,7 @@ ETF sans Pays apps/client/src/app/components/admin-market-data/admin-market-data.component.ts - 136 + 135 @@ -4498,7 +4506,7 @@ ETF sans Secteurs apps/client/src/app/components/admin-market-data/admin-market-data.component.ts - 141 + 140 @@ -4678,7 +4686,7 @@ Job ID apps/client/src/app/components/admin-jobs/admin-jobs.html - 34 + 43 @@ -4734,7 +4742,7 @@ Devises apps/client/src/app/components/admin-market-data/admin-market-data.component.ts - 131 + 130 apps/client/src/app/pages/public/public-page.html @@ -5484,7 +5492,7 @@ Confirmez la suppression de ce tag ? apps/client/src/app/components/admin-tag/admin-tag.component.ts - 109 + 108 @@ -5584,7 +5592,7 @@ Profil d’Actif apps/client/src/app/components/admin-jobs/admin-jobs.html - 52 + 61 @@ -5716,7 +5724,7 @@ Confirmer la suppresion de ce message système? apps/client/src/app/components/admin-overview/admin-overview.component.ts - 206 + 209 @@ -5872,11 +5880,11 @@ apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts - 81 + 80 apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts - 97 + 96 apps/client/src/app/pages/resources/personal-finance-tools/product-page.component.ts @@ -5896,7 +5904,7 @@ Close Holding apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html - 441 + 447 @@ -5944,7 +5952,7 @@ WTD apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 196 + 197 libs/ui/src/lib/assistant/assistant.component.ts @@ -5964,7 +5972,7 @@ MTD apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 200 + 201 libs/ui/src/lib/assistant/assistant.component.ts @@ -6012,7 +6020,7 @@ année apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 208 + 209 apps/client/src/app/pages/resources/personal-finance-tools/product-page.html @@ -6032,7 +6040,7 @@ années apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 212 + 213 libs/ui/src/lib/assistant/assistant.component.ts @@ -6125,7 +6133,7 @@ Actif apps/client/src/app/components/home-holdings/home-holdings.component.ts - 64 + 63 @@ -6133,7 +6141,7 @@ Clôturé apps/client/src/app/components/home-holdings/home-holdings.component.ts - 65 + 64 @@ -6165,7 +6173,7 @@ Execute la tâche apps/client/src/app/components/admin-jobs/admin-jobs.html - 220 + 229 @@ -6173,7 +6181,7 @@ Priorité apps/client/src/app/components/admin-jobs/admin-jobs.html - 96 + 105 @@ -6229,7 +6237,7 @@ Confirmer la suppresion de votre compte Ghostfolio ? apps/client/src/app/components/user-account-settings/user-account-settings.component.ts - 208 + 205 @@ -6285,7 +6293,7 @@ Oops! Une erreur s’est produite lors de la configuration de l’authentification biométrique. apps/client/src/app/components/user-account-settings/user-account-settings.component.ts - 336 + 333 @@ -6301,7 +6309,7 @@ Benchmarks apps/client/src/app/components/admin-market-data/admin-market-data.component.ts - 126 + 125 @@ -6857,7 +6865,7 @@ Résumé du portefeuille apps/client/src/app/components/admin-jobs/admin-jobs.html - 56 + 65 @@ -6924,6 +6932,14 @@ 42 + + has been copied to the clipboard + has been copied to the clipboard + + libs/ui/src/lib/value/value.component.ts + 180 + + From the beginning Depuis le début @@ -7363,7 +7379,7 @@ apps/client/src/app/components/user-account-access/user-account-access.component.ts - 260 + 257 @@ -7403,7 +7419,7 @@ Le prompt IA a été copié dans le presse-papiers apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts - 201 + 199 @@ -7419,7 +7435,7 @@ Paresseux apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 230 + 231 @@ -7427,7 +7443,7 @@ Instantané apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 234 + 235 @@ -7467,7 +7483,7 @@ fin de journée apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 230 + 231 @@ -7475,7 +7491,7 @@ temps réel apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 234 + 235 @@ -7483,7 +7499,7 @@ Ouvrir Duck.ai apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts - 202 + 200 @@ -7503,7 +7519,7 @@ libs/ui/src/lib/treemap-chart/treemap-chart.component.ts - 375 + 377 @@ -7515,7 +7531,7 @@ apps/client/src/app/components/home-overview/home-overview.component.ts - 55 + 54 libs/ui/src/lib/holdings-table/holdings-table.component.html @@ -7523,11 +7539,11 @@ libs/ui/src/lib/treemap-chart/treemap-chart.component.ts - 375 + 377 libs/ui/src/lib/treemap-chart/treemap-chart.component.ts - 388 + 390 @@ -7631,11 +7647,11 @@ Jeton de sécurité apps/client/src/app/components/admin-users/admin-users.component.ts - 239 + 235 apps/client/src/app/components/user-account-access/user-account-access.component.ts - 170 + 167 @@ -7643,7 +7659,7 @@ Voulez-vous vraiment générer un nouveau jeton de sécurité pour cet utilisateur ? apps/client/src/app/components/admin-users/admin-users.component.ts - 244 + 240 @@ -7788,7 +7804,7 @@ quelqu’un apps/client/src/app/pages/public/public-page.component.ts - 59 + 61 @@ -7820,7 +7836,7 @@ Voulez-vous vraiment supprimer cet élément? libs/ui/src/lib/benchmark/benchmark.component.ts - 144 + 139 @@ -7861,7 +7877,7 @@ Le compte utilisateur de démonstration a été synchronisé. apps/client/src/app/components/admin-overview/admin-overview.component.ts - 274 + 277 @@ -8075,7 +8091,7 @@ Current month apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 200 + 201 @@ -8244,7 +8260,7 @@ Voulez-vous vraiment générer un nouveau jeton de sécurité? apps/client/src/app/components/user-account-access/user-account-access.component.ts - 175 + 172 @@ -8268,7 +8284,7 @@ Actions apps/client/src/app/components/markets/markets.component.ts - 52 + 51 apps/client/src/app/pages/features/features-page.html @@ -8280,7 +8296,7 @@ Crypto-monnaies apps/client/src/app/components/markets/markets.component.ts - 53 + 52 apps/client/src/app/pages/features/features-page.html @@ -8300,7 +8316,7 @@ Gérer le profil d’actif apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html - 465 + 471 diff --git a/apps/client/src/locales/messages.it.xlf b/apps/client/src/locales/messages.it.xlf index 5f06af0b4..b143bbde3 100644 --- a/apps/client/src/locales/messages.it.xlf +++ b/apps/client/src/locales/messages.it.xlf @@ -51,7 +51,7 @@ Tipo apps/client/src/app/components/admin-jobs/admin-jobs.html - 48 + 57 apps/client/src/app/components/user-account-access/create-or-update-access-dialog/create-or-update-access-dialog.html @@ -307,7 +307,7 @@ Elimina i lavori apps/client/src/app/components/admin-jobs/admin-jobs.html - 193 + 202 @@ -315,7 +315,7 @@ Sorgente dei dati apps/client/src/app/components/admin-jobs/admin-jobs.html - 82 + 91 apps/client/src/app/components/admin-market-data/admin-market-data.html @@ -339,7 +339,7 @@ Tentativi apps/client/src/app/components/admin-jobs/admin-jobs.html - 120 + 129 @@ -347,7 +347,7 @@ Creato apps/client/src/app/components/admin-jobs/admin-jobs.html - 134 + 143 @@ -355,7 +355,7 @@ Finito apps/client/src/app/components/admin-jobs/admin-jobs.html - 143 + 152 @@ -363,7 +363,7 @@ Stato apps/client/src/app/components/admin-jobs/admin-jobs.html - 152 + 161 apps/client/src/app/components/admin-settings/admin-settings.component.html @@ -395,7 +395,7 @@ Dati storici del mercato apps/client/src/app/components/admin-jobs/admin-jobs.html - 54 + 63 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html @@ -407,7 +407,7 @@ Visualizza i dati apps/client/src/app/components/admin-jobs/admin-jobs.html - 208 + 217 @@ -415,7 +415,7 @@ Visualizza Stacktrace apps/client/src/app/components/admin-jobs/admin-jobs.html - 216 + 225 @@ -423,7 +423,7 @@ Elimina il lavoro apps/client/src/app/components/admin-jobs/admin-jobs.html - 224 + 233 @@ -515,7 +515,7 @@ Vuoi davvero eliminare questo buono? apps/client/src/app/components/admin-overview/admin-overview.component.ts - 193 + 196 @@ -523,7 +523,7 @@ Vuoi davvero svuotare la cache? apps/client/src/app/components/admin-overview/admin-overview.component.ts - 230 + 233 @@ -531,7 +531,7 @@ Imposta il messaggio di sistema: apps/client/src/app/components/admin-overview/admin-overview.component.ts - 250 + 253 @@ -635,7 +635,7 @@ Vuoi davvero eliminare questo utente? apps/client/src/app/components/admin-users/admin-users.component.ts - 218 + 215 @@ -743,7 +743,7 @@ apps/client/src/app/components/header/header.component.ts - 297 + 298 apps/client/src/app/components/login-with-access-token-dialog/login-with-access-token-dialog.html @@ -763,15 +763,15 @@ Ops! Token di sicurezza errato. apps/client/src/app/components/header/header.component.ts - 312 + 313 apps/client/src/app/components/user-account-access/user-account-access.component.ts - 154 + 152 apps/client/src/app/components/user-account-settings/user-account-settings.component.ts - 193 + 191 @@ -779,7 +779,7 @@ Gestione delle attività apps/client/src/app/components/home-holdings/home-holdings.html - 65 + 64 @@ -1019,7 +1019,7 @@ Segnala un’anomalia dei dati apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html - 450 + 456 @@ -1067,7 +1067,7 @@ anno corrente apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 204 + 205 libs/ui/src/lib/assistant/assistant.component.ts @@ -1079,7 +1079,7 @@ 1 anno apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 208 + 209 libs/ui/src/lib/assistant/assistant.component.ts @@ -1091,7 +1091,7 @@ 5 anni apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 212 + 213 libs/ui/src/lib/assistant/assistant.component.ts @@ -1111,7 +1111,7 @@ Massimo apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 216 + 217 libs/ui/src/lib/assistant/assistant.component.ts @@ -1131,7 +1131,7 @@ apps/client/src/app/pages/portfolio/activities/import-activities-dialog/import-activities-dialog.component.ts - 196 + 195 @@ -1223,7 +1223,7 @@ Vuoi davvero rimuovere questo metodo di accesso? apps/client/src/app/components/user-account-settings/user-account-settings.component.ts - 282 + 279 @@ -1379,7 +1379,7 @@ apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html - 375 + 381 apps/client/src/app/components/user-detail-dialog/user-detail-dialog.html @@ -1661,6 +1661,10 @@ Overview Panoramica + + apps/client/src/app/components/admin-jobs/admin-jobs.html + 7 + apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html 114 @@ -1919,7 +1923,7 @@ Current week apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 196 + 197 @@ -2043,7 +2047,7 @@ apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html - 342 + 348 apps/client/src/app/components/user-detail-dialog/user-detail-dialog.html @@ -2067,7 +2071,7 @@ Importazione dei dati... apps/client/src/app/pages/portfolio/activities/import-activities-dialog/import-activities-dialog.component.ts - 175 + 174 @@ -2075,7 +2079,7 @@ L’importazione è stata completata apps/client/src/app/pages/portfolio/activities/import-activities-dialog/import-activities-dialog.component.ts - 185 + 184 @@ -2193,6 +2197,10 @@ apps/client/src/app/pages/register/user-account-registration-dialog/user-account-registration-dialog.html 88 + + libs/ui/src/lib/value/value.component.html + 18 + Resources @@ -2379,7 +2387,7 @@ apps/client/src/app/pages/portfolio/activities/import-activities-dialog/import-activities-dialog.component.ts - 193 + 192 @@ -2395,7 +2403,7 @@ apps/client/src/app/pages/portfolio/activities/import-activities-dialog/import-activities-dialog.component.ts - 195 + 194 @@ -2515,7 +2523,7 @@ Risparmio libs/ui/src/lib/fire-calculator/fire-calculator.component.ts - 410 + 424 @@ -2531,7 +2539,7 @@ libs/ui/src/lib/fire-calculator/fire-calculator.component.ts - 400 + 414 libs/ui/src/lib/i18n.ts @@ -2551,7 +2559,7 @@ Deposito libs/ui/src/lib/fire-calculator/fire-calculator.component.ts - 390 + 404 @@ -2559,7 +2567,7 @@ Mensile apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts - 91 + 90 @@ -2583,11 +2591,11 @@ Paura apps/client/src/app/components/home-market/home-market.component.ts - 42 + 41 apps/client/src/app/components/markets/markets.component.ts - 47 + 46 libs/ui/src/lib/i18n.ts @@ -2599,11 +2607,11 @@ Avidità apps/client/src/app/components/home-market/home-market.component.ts - 43 + 42 apps/client/src/app/components/markets/markets.component.ts - 48 + 47 libs/ui/src/lib/i18n.ts @@ -2615,7 +2623,7 @@ Filtra per... apps/client/src/app/components/admin-market-data/admin-market-data.component.ts - 390 + 383 @@ -2699,7 +2707,7 @@ Auto apps/client/src/app/components/user-account-settings/user-account-settings.component.ts - 70 + 69 apps/client/src/app/components/user-account-settings/user-account-settings.html @@ -2811,7 +2819,7 @@ Simbolo apps/client/src/app/components/admin-jobs/admin-jobs.html - 68 + 77 apps/client/src/app/components/admin-market-data/admin-market-data.html @@ -2827,7 +2835,7 @@ apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html - 315 + 318 libs/ui/src/lib/i18n.ts @@ -2983,7 +2991,7 @@ libs/ui/src/lib/portfolio-proportion-chart/portfolio-proportion-chart.component.ts - 449 + 451 @@ -3003,11 +3011,11 @@ libs/ui/src/lib/portfolio-proportion-chart/portfolio-proportion-chart.component.ts - 451 + 453 libs/ui/src/lib/portfolio-proportion-chart/portfolio-proportion-chart.component.ts - 465 + 467 libs/ui/src/lib/top-holdings/top-holdings.component.html @@ -3147,7 +3155,7 @@ apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts - 76 + 75 libs/ui/src/lib/i18n.ts @@ -3203,7 +3211,7 @@ Convalida dei dati... apps/client/src/app/pages/portfolio/activities/import-activities-dialog/import-activities-dialog.component.ts - 299 + 293 @@ -3227,7 +3235,7 @@ Dati del mercato apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html - 397 + 403 libs/common/src/lib/routes/routes.ts @@ -3279,7 +3287,7 @@ Annuale apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts - 92 + 91 @@ -3287,7 +3295,7 @@ Importa i dividendi apps/client/src/app/pages/portfolio/activities/import-activities-dialog/import-activities-dialog.component.ts - 137 + 136 libs/ui/src/lib/activities-table/activities-table.component.html @@ -3347,7 +3355,7 @@ No Activities apps/client/src/app/components/admin-market-data/admin-market-data.component.ts - 146 + 145 @@ -3851,7 +3859,7 @@ Current year apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 204 + 205 @@ -3895,7 +3903,7 @@ Vuoi davvero eliminare questa piattaforma? apps/client/src/app/components/admin-platform/admin-platform.component.ts - 112 + 111 @@ -4491,7 +4499,7 @@ ETF senza paesi apps/client/src/app/components/admin-market-data/admin-market-data.component.ts - 136 + 135 @@ -4499,7 +4507,7 @@ ETF senza settori apps/client/src/app/components/admin-market-data/admin-market-data.component.ts - 141 + 140 @@ -4679,7 +4687,7 @@ Job ID apps/client/src/app/components/admin-jobs/admin-jobs.html - 34 + 43 @@ -4735,7 +4743,7 @@ Valute apps/client/src/app/components/admin-market-data/admin-market-data.component.ts - 131 + 130 apps/client/src/app/pages/public/public-page.html @@ -5485,7 +5493,7 @@ Sei sicuro di voler eliminare questo tag? apps/client/src/app/components/admin-tag/admin-tag.component.ts - 109 + 108 @@ -5585,7 +5593,7 @@ Profilo dell’asset apps/client/src/app/components/admin-jobs/admin-jobs.html - 52 + 61 @@ -5717,7 +5725,7 @@ Confermi di voler cancellare questo messaggio di sistema? apps/client/src/app/components/admin-overview/admin-overview.component.ts - 206 + 209 @@ -5873,11 +5881,11 @@ apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts - 81 + 80 apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts - 97 + 96 apps/client/src/app/pages/resources/personal-finance-tools/product-page.component.ts @@ -5897,7 +5905,7 @@ Close Holding apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html - 441 + 447 @@ -5945,7 +5953,7 @@ Settimana corrente apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 196 + 197 libs/ui/src/lib/assistant/assistant.component.ts @@ -5965,7 +5973,7 @@ Mese corrente apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 200 + 201 libs/ui/src/lib/assistant/assistant.component.ts @@ -6013,7 +6021,7 @@ anno apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 208 + 209 apps/client/src/app/pages/resources/personal-finance-tools/product-page.html @@ -6033,7 +6041,7 @@ anni apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 212 + 213 libs/ui/src/lib/assistant/assistant.component.ts @@ -6126,7 +6134,7 @@ Attivo apps/client/src/app/components/home-holdings/home-holdings.component.ts - 64 + 63 @@ -6134,7 +6142,7 @@ Chiuso apps/client/src/app/components/home-holdings/home-holdings.component.ts - 65 + 64 @@ -6166,7 +6174,7 @@ Esegui il lavoro apps/client/src/app/components/admin-jobs/admin-jobs.html - 220 + 229 @@ -6174,7 +6182,7 @@ Priorità apps/client/src/app/components/admin-jobs/admin-jobs.html - 96 + 105 @@ -6230,7 +6238,7 @@ Confermi di voler chiudere il tuo account Ghostfolio? apps/client/src/app/components/user-account-settings/user-account-settings.component.ts - 208 + 205 @@ -6286,7 +6294,7 @@ Ops! C’è stato un errore impostando l’autenticazione biometrica. apps/client/src/app/components/user-account-settings/user-account-settings.component.ts - 336 + 333 @@ -6302,7 +6310,7 @@ Benchmarks apps/client/src/app/components/admin-market-data/admin-market-data.component.ts - 126 + 125 @@ -6858,7 +6866,7 @@ Stato del Portfolio apps/client/src/app/components/admin-jobs/admin-jobs.html - 56 + 65 @@ -6925,6 +6933,14 @@ 42 + + has been copied to the clipboard + has been copied to the clipboard + + libs/ui/src/lib/value/value.component.ts + 180 + + From the beginning Dall’inizio @@ -7364,7 +7380,7 @@ apps/client/src/app/components/user-account-access/user-account-access.component.ts - 260 + 257 @@ -7404,7 +7420,7 @@ L’AI prompt è stato copiato negli appunti apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts - 201 + 199 @@ -7420,7 +7436,7 @@ Pigro apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 230 + 231 @@ -7428,7 +7444,7 @@ Istantaneo apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 234 + 235 @@ -7468,7 +7484,7 @@ fine giornata apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 230 + 231 @@ -7476,7 +7492,7 @@ in tempo reale apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 234 + 235 @@ -7484,7 +7500,7 @@ Apri Duck.ai apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts - 202 + 200 @@ -7504,7 +7520,7 @@ libs/ui/src/lib/treemap-chart/treemap-chart.component.ts - 375 + 377 @@ -7516,7 +7532,7 @@ apps/client/src/app/components/home-overview/home-overview.component.ts - 55 + 54 libs/ui/src/lib/holdings-table/holdings-table.component.html @@ -7524,11 +7540,11 @@ libs/ui/src/lib/treemap-chart/treemap-chart.component.ts - 375 + 377 libs/ui/src/lib/treemap-chart/treemap-chart.component.ts - 388 + 390 @@ -7632,11 +7648,11 @@ Token di sicurezza apps/client/src/app/components/admin-users/admin-users.component.ts - 239 + 235 apps/client/src/app/components/user-account-access/user-account-access.component.ts - 170 + 167 @@ -7644,7 +7660,7 @@ Vuoi davvero generare un nuovo token di sicurezza per questo utente? apps/client/src/app/components/admin-users/admin-users.component.ts - 244 + 240 @@ -7789,7 +7805,7 @@ qualcuno apps/client/src/app/pages/public/public-page.component.ts - 59 + 61 @@ -7821,7 +7837,7 @@ Vuoi davvero eliminare questo elemento? libs/ui/src/lib/benchmark/benchmark.component.ts - 144 + 139 @@ -7862,7 +7878,7 @@ L’account utente demo è stato sincronizzato. apps/client/src/app/components/admin-overview/admin-overview.component.ts - 274 + 277 @@ -8076,7 +8092,7 @@ Current month apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 200 + 201 @@ -8245,7 +8261,7 @@ Vuoi davvero generare un nuovo token di sicurezza? apps/client/src/app/components/user-account-access/user-account-access.component.ts - 175 + 172 @@ -8269,7 +8285,7 @@ Azioni apps/client/src/app/components/markets/markets.component.ts - 52 + 51 apps/client/src/app/pages/features/features-page.html @@ -8281,7 +8297,7 @@ criptovalute apps/client/src/app/components/markets/markets.component.ts - 53 + 52 apps/client/src/app/pages/features/features-page.html @@ -8301,7 +8317,7 @@ Gestisci profilo risorsa apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html - 465 + 471 diff --git a/apps/client/src/locales/messages.ko.xlf b/apps/client/src/locales/messages.ko.xlf index bb361b515..4f544e4aa 100644 --- a/apps/client/src/locales/messages.ko.xlf +++ b/apps/client/src/locales/messages.ko.xlf @@ -252,7 +252,7 @@ 유형 apps/client/src/app/components/admin-jobs/admin-jobs.html - 48 + 57 apps/client/src/app/components/user-account-access/create-or-update-access-dialog/create-or-update-access-dialog.html @@ -592,7 +592,7 @@ 자산 프로필 apps/client/src/app/components/admin-jobs/admin-jobs.html - 52 + 61 @@ -600,7 +600,7 @@ 과거 시장 데이터 apps/client/src/app/components/admin-jobs/admin-jobs.html - 54 + 63 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html @@ -612,7 +612,7 @@ 데이터 소스 apps/client/src/app/components/admin-jobs/admin-jobs.html - 82 + 91 apps/client/src/app/components/admin-market-data/admin-market-data.html @@ -636,7 +636,7 @@ 시도 횟수 apps/client/src/app/components/admin-jobs/admin-jobs.html - 120 + 129 @@ -644,7 +644,7 @@ 생성됨 apps/client/src/app/components/admin-jobs/admin-jobs.html - 134 + 143 @@ -652,7 +652,7 @@ 완료됨 apps/client/src/app/components/admin-jobs/admin-jobs.html - 143 + 152 @@ -660,7 +660,7 @@ 상태 apps/client/src/app/components/admin-jobs/admin-jobs.html - 152 + 161 apps/client/src/app/components/admin-settings/admin-settings.component.html @@ -680,7 +680,7 @@ 작업 삭제 apps/client/src/app/components/admin-jobs/admin-jobs.html - 193 + 202 @@ -688,7 +688,7 @@ 데이터 보기 apps/client/src/app/components/admin-jobs/admin-jobs.html - 208 + 217 @@ -696,7 +696,7 @@ 스택트레이스 보기 apps/client/src/app/components/admin-jobs/admin-jobs.html - 216 + 225 @@ -704,7 +704,7 @@ 작업 삭제 apps/client/src/app/components/admin-jobs/admin-jobs.html - 224 + 233 @@ -756,7 +756,7 @@ 통화 apps/client/src/app/components/admin-market-data/admin-market-data.component.ts - 131 + 130 apps/client/src/app/pages/public/public-page.html @@ -768,7 +768,7 @@ 국가 정보 없는 ETF apps/client/src/app/components/admin-market-data/admin-market-data.component.ts - 136 + 135 @@ -776,7 +776,7 @@ 섹터 정보 없는 ETF apps/client/src/app/components/admin-market-data/admin-market-data.component.ts - 141 + 140 @@ -792,7 +792,7 @@ 다음 기준으로 필터... apps/client/src/app/components/admin-market-data/admin-market-data.component.ts - 390 + 383 @@ -1076,7 +1076,7 @@ 이 쿠폰을 정말 삭제하시겠습니까? apps/client/src/app/components/admin-overview/admin-overview.component.ts - 193 + 196 @@ -1084,7 +1084,7 @@ 이 시스템 메시지를 정말 삭제하시겠습니까? apps/client/src/app/components/admin-overview/admin-overview.component.ts - 206 + 209 @@ -1092,7 +1092,7 @@ 정말로 캐시를 플러시하시겠습니까? apps/client/src/app/components/admin-overview/admin-overview.component.ts - 230 + 233 @@ -1100,7 +1100,7 @@ 시스템 메시지를 설정하십시오: apps/client/src/app/components/admin-overview/admin-overview.component.ts - 250 + 253 @@ -1252,7 +1252,7 @@ 정말로 이 플랫폼을 삭제하시겠습니까? apps/client/src/app/components/admin-platform/admin-platform.component.ts - 112 + 111 @@ -1284,7 +1284,7 @@ 올해 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 204 + 205 @@ -1332,7 +1332,7 @@ 이 태그를 정말로 삭제하시겠습니까? apps/client/src/app/components/admin-tag/admin-tag.component.ts - 109 + 108 @@ -1356,7 +1356,7 @@ 이 사용자를 정말로 삭제하시겠습니까? apps/client/src/app/components/admin-users/admin-users.component.ts - 218 + 215 @@ -1512,7 +1512,7 @@ apps/client/src/app/components/header/header.component.ts - 297 + 298 apps/client/src/app/components/login-with-access-token-dialog/login-with-access-token-dialog.html @@ -1532,15 +1532,15 @@ 이런! 잘못된 보안 토큰. apps/client/src/app/components/header/header.component.ts - 312 + 313 apps/client/src/app/components/user-account-access/user-account-access.component.ts - 154 + 152 apps/client/src/app/components/user-account-settings/user-account-settings.component.ts - 193 + 191 @@ -1548,7 +1548,7 @@ 활동 관리 apps/client/src/app/components/home-holdings/home-holdings.html - 65 + 64 @@ -1556,11 +1556,11 @@ 두려움 apps/client/src/app/components/home-market/home-market.component.ts - 42 + 41 apps/client/src/app/components/markets/markets.component.ts - 47 + 46 libs/ui/src/lib/i18n.ts @@ -1572,11 +1572,11 @@ 탐욕 apps/client/src/app/components/home-market/home-market.component.ts - 43 + 42 apps/client/src/app/components/markets/markets.component.ts - 48 + 47 libs/ui/src/lib/i18n.ts @@ -1680,7 +1680,7 @@ 이번주 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 196 + 197 @@ -1960,7 +1960,7 @@ 데이터 결함 보고 apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html - 450 + 456 @@ -2148,7 +2148,7 @@ 연초 대비 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 204 + 205 libs/ui/src/lib/assistant/assistant.component.ts @@ -2160,7 +2160,7 @@ 1년 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 208 + 209 libs/ui/src/lib/assistant/assistant.component.ts @@ -2172,7 +2172,7 @@ 5년 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 212 + 213 libs/ui/src/lib/assistant/assistant.component.ts @@ -2192,7 +2192,7 @@ 맥스 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 216 + 217 libs/ui/src/lib/assistant/assistant.component.ts @@ -2296,7 +2296,7 @@ 자동 apps/client/src/app/components/user-account-settings/user-account-settings.component.ts - 70 + 69 apps/client/src/app/components/user-account-settings/user-account-settings.html @@ -2308,7 +2308,7 @@ 이 로그인 방법을 정말로 제거하시겠습니까? apps/client/src/app/components/user-account-settings/user-account-settings.component.ts - 282 + 279 @@ -2492,7 +2492,7 @@ apps/client/src/app/pages/portfolio/activities/import-activities-dialog/import-activities-dialog.component.ts - 195 + 194 @@ -2504,7 +2504,7 @@ apps/client/src/app/pages/portfolio/activities/import-activities-dialog/import-activities-dialog.component.ts - 193 + 192 @@ -2520,7 +2520,7 @@ apps/client/src/app/pages/portfolio/activities/import-activities-dialog/import-activities-dialog.component.ts - 196 + 195 @@ -2648,7 +2648,7 @@ apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html - 375 + 381 apps/client/src/app/components/user-detail-dialog/user-detail-dialog.html @@ -2744,7 +2744,7 @@ 시장 데이터 apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html - 397 + 403 libs/common/src/lib/routes/routes.ts @@ -2778,6 +2778,10 @@ Overview 개요 + + apps/client/src/app/components/admin-jobs/admin-jobs.html + 7 + apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html 114 @@ -3624,7 +3628,7 @@ 작업 ID apps/client/src/app/components/admin-jobs/admin-jobs.html - 34 + 43 @@ -3680,7 +3684,7 @@ apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html - 342 + 348 apps/client/src/app/components/user-detail-dialog/user-detail-dialog.html @@ -3808,7 +3812,7 @@ 배당금 가져오기 apps/client/src/app/pages/portfolio/activities/import-activities-dialog/import-activities-dialog.component.ts - 137 + 136 libs/ui/src/lib/activities-table/activities-table.component.html @@ -3824,7 +3828,7 @@ 데이터 가져오는 중... apps/client/src/app/pages/portfolio/activities/import-activities-dialog/import-activities-dialog.component.ts - 175 + 174 @@ -3832,7 +3836,7 @@ 가져오기가 완료되었습니다. apps/client/src/app/pages/portfolio/activities/import-activities-dialog/import-activities-dialog.component.ts - 185 + 184 @@ -3848,7 +3852,7 @@ 데이터 유효성을 검사하는 중... apps/client/src/app/pages/portfolio/activities/import-activities-dialog/import-activities-dialog.component.ts - 299 + 293 @@ -4148,7 +4152,7 @@ apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts - 76 + 75 libs/ui/src/lib/i18n.ts @@ -4168,7 +4172,7 @@ 보증금 libs/ui/src/lib/fire-calculator/fire-calculator.component.ts - 390 + 404 @@ -4176,7 +4180,7 @@ 월간 apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts - 91 + 90 @@ -4184,7 +4188,7 @@ 매년 apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts - 92 + 91 @@ -4538,6 +4542,10 @@ apps/client/src/app/pages/register/user-account-registration-dialog/user-account-registration-dialog.html 88 + + libs/ui/src/lib/value/value.component.html + 18 + Personal Finance Tools @@ -5129,7 +5137,7 @@ libs/ui/src/lib/fire-calculator/fire-calculator.component.ts - 400 + 414 libs/ui/src/lib/i18n.ts @@ -5141,7 +5149,7 @@ 저금 libs/ui/src/lib/fire-calculator/fire-calculator.component.ts - 410 + 424 @@ -5373,7 +5381,7 @@ libs/ui/src/lib/portfolio-proportion-chart/portfolio-proportion-chart.component.ts - 449 + 451 @@ -5389,7 +5397,7 @@ No Activities apps/client/src/app/components/admin-market-data/admin-market-data.component.ts - 146 + 145 @@ -5421,7 +5429,7 @@ 상징 apps/client/src/app/components/admin-jobs/admin-jobs.html - 68 + 77 apps/client/src/app/components/admin-market-data/admin-market-data.html @@ -5437,7 +5445,7 @@ apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html - 315 + 318 libs/ui/src/lib/i18n.ts @@ -5777,11 +5785,11 @@ libs/ui/src/lib/portfolio-proportion-chart/portfolio-proportion-chart.component.ts - 451 + 453 libs/ui/src/lib/portfolio-proportion-chart/portfolio-proportion-chart.component.ts - 465 + 467 libs/ui/src/lib/top-holdings/top-holdings.component.html @@ -5897,7 +5905,7 @@ 닫기 보유 apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html - 441 + 447 @@ -5921,11 +5929,11 @@ apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts - 81 + 80 apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts - 97 + 96 apps/client/src/app/pages/resources/personal-finance-tools/product-page.component.ts @@ -5985,7 +5993,7 @@ MTD apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 200 + 201 libs/ui/src/lib/assistant/assistant.component.ts @@ -5997,7 +6005,7 @@ WTD apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 196 + 197 libs/ui/src/lib/assistant/assistant.component.ts @@ -6037,7 +6045,7 @@ 년도 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 208 + 209 apps/client/src/app/pages/resources/personal-finance-tools/product-page.html @@ -6057,7 +6065,7 @@ 연령 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 212 + 213 libs/ui/src/lib/assistant/assistant.component.ts @@ -6150,7 +6158,7 @@ 닫은 apps/client/src/app/components/home-holdings/home-holdings.component.ts - 65 + 64 @@ -6158,7 +6166,7 @@ 활동적인 apps/client/src/app/components/home-holdings/home-holdings.component.ts - 64 + 63 @@ -6190,7 +6198,7 @@ 작업 실행 apps/client/src/app/components/admin-jobs/admin-jobs.html - 220 + 229 @@ -6206,7 +6214,7 @@ 우선 사항 apps/client/src/app/components/admin-jobs/admin-jobs.html - 96 + 105 @@ -6262,7 +6270,7 @@ 정말로 Ghostfolio 계정을 폐쇄하시겠습니까? apps/client/src/app/components/user-account-settings/user-account-settings.component.ts - 208 + 205 @@ -6310,7 +6318,7 @@ 이런! 생체 인증을 설정하는 중에 오류가 발생했습니다. apps/client/src/app/components/user-account-settings/user-account-settings.component.ts - 336 + 333 @@ -6350,7 +6358,7 @@ 벤치마크 apps/client/src/app/components/admin-market-data/admin-market-data.component.ts - 126 + 125 @@ -6898,7 +6906,7 @@ 포트폴리오 스냅샷 apps/client/src/app/components/admin-jobs/admin-jobs.html - 56 + 65 @@ -6957,6 +6965,14 @@ 42 + + has been copied to the clipboard + has been copied to the clipboard + + libs/ui/src/lib/value/value.component.ts + 180 + + offers a free plan 은(는) 무료 요금제를 제공합니다 @@ -7404,7 +7420,7 @@ apps/client/src/app/components/user-account-access/user-account-access.component.ts - 260 + 257 @@ -7428,7 +7444,7 @@ AI 프롬프트가 클립보드에 복사되었습니다. apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts - 201 + 199 @@ -7468,7 +7484,7 @@ 즉각적인 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 234 + 235 @@ -7476,7 +7492,7 @@ 게으른 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 230 + 231 @@ -7492,7 +7508,7 @@ 실시간 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 234 + 235 @@ -7500,7 +7516,7 @@ 하루의 끝 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 230 + 231 @@ -7508,7 +7524,7 @@ 오픈 Duck.ai apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts - 202 + 200 @@ -7528,7 +7544,7 @@ libs/ui/src/lib/treemap-chart/treemap-chart.component.ts - 375 + 377 @@ -7540,7 +7556,7 @@ apps/client/src/app/components/home-overview/home-overview.component.ts - 55 + 54 libs/ui/src/lib/holdings-table/holdings-table.component.html @@ -7548,11 +7564,11 @@ libs/ui/src/lib/treemap-chart/treemap-chart.component.ts - 375 + 377 libs/ui/src/lib/treemap-chart/treemap-chart.component.ts - 388 + 390 @@ -7656,7 +7672,7 @@ 정말로 이 사용자에 대한 새 보안 토큰을 생성하시겠습니까? apps/client/src/app/components/admin-users/admin-users.component.ts - 244 + 240 @@ -7672,11 +7688,11 @@ 보안 토큰 apps/client/src/app/components/admin-users/admin-users.component.ts - 239 + 235 apps/client/src/app/components/user-account-access/user-account-access.component.ts - 170 + 167 @@ -7789,7 +7805,7 @@ 누구 apps/client/src/app/pages/public/public-page.component.ts - 59 + 61 @@ -7821,7 +7837,7 @@ 이 항목을 정말로 삭제하시겠습니까? libs/ui/src/lib/benchmark/benchmark.component.ts - 144 + 139 @@ -7870,7 +7886,7 @@ 데모 사용자 계정이 동기화되었습니다. apps/client/src/app/components/admin-overview/admin-overview.component.ts - 274 + 277 @@ -8076,7 +8092,7 @@ 이번 달 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 200 + 201 @@ -8261,7 +8277,7 @@ 정말로 새로운 보안 토큰을 생성하시겠습니까? apps/client/src/app/components/user-account-access/user-account-access.component.ts - 175 + 172 @@ -8269,7 +8285,7 @@ 암호화폐 apps/client/src/app/components/markets/markets.component.ts - 53 + 52 apps/client/src/app/pages/features/features-page.html @@ -8281,7 +8297,7 @@ 주식 apps/client/src/app/components/markets/markets.component.ts - 52 + 51 apps/client/src/app/pages/features/features-page.html @@ -8301,7 +8317,7 @@ 자산 프로필 관리 apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html - 465 + 471 diff --git a/apps/client/src/locales/messages.nl.xlf b/apps/client/src/locales/messages.nl.xlf index fbd87961c..039969da0 100644 --- a/apps/client/src/locales/messages.nl.xlf +++ b/apps/client/src/locales/messages.nl.xlf @@ -50,7 +50,7 @@ Type apps/client/src/app/components/admin-jobs/admin-jobs.html - 48 + 57 apps/client/src/app/components/user-account-access/create-or-update-access-dialog/create-or-update-access-dialog.html @@ -306,7 +306,7 @@ Taken verwijderen apps/client/src/app/components/admin-jobs/admin-jobs.html - 193 + 202 @@ -314,7 +314,7 @@ Gegevensbron apps/client/src/app/components/admin-jobs/admin-jobs.html - 82 + 91 apps/client/src/app/components/admin-market-data/admin-market-data.html @@ -338,7 +338,7 @@ Pogingen apps/client/src/app/components/admin-jobs/admin-jobs.html - 120 + 129 @@ -346,7 +346,7 @@ Aangemaakt apps/client/src/app/components/admin-jobs/admin-jobs.html - 134 + 143 @@ -354,7 +354,7 @@ Voltooid apps/client/src/app/components/admin-jobs/admin-jobs.html - 143 + 152 @@ -362,7 +362,7 @@ Status apps/client/src/app/components/admin-jobs/admin-jobs.html - 152 + 161 apps/client/src/app/components/admin-settings/admin-settings.component.html @@ -394,7 +394,7 @@ Historische marktgegevens apps/client/src/app/components/admin-jobs/admin-jobs.html - 54 + 63 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html @@ -406,7 +406,7 @@ Bekijk gegevens apps/client/src/app/components/admin-jobs/admin-jobs.html - 208 + 217 @@ -414,7 +414,7 @@ Bekijk Stacktrace apps/client/src/app/components/admin-jobs/admin-jobs.html - 216 + 225 @@ -422,7 +422,7 @@ Taak verwijderen apps/client/src/app/components/admin-jobs/admin-jobs.html - 224 + 233 @@ -514,7 +514,7 @@ Wil je deze coupon echt verwijderen? apps/client/src/app/components/admin-overview/admin-overview.component.ts - 193 + 196 @@ -522,7 +522,7 @@ Wil je echt de cache legen? apps/client/src/app/components/admin-overview/admin-overview.component.ts - 230 + 233 @@ -530,7 +530,7 @@ Stel je systeemboodschap in: apps/client/src/app/components/admin-overview/admin-overview.component.ts - 250 + 253 @@ -634,7 +634,7 @@ Wilt je deze gebruiker echt verwijderen? apps/client/src/app/components/admin-users/admin-users.component.ts - 218 + 215 @@ -742,7 +742,7 @@ apps/client/src/app/components/header/header.component.ts - 297 + 298 apps/client/src/app/components/login-with-access-token-dialog/login-with-access-token-dialog.html @@ -762,15 +762,15 @@ Oeps! Onjuiste beveiligingstoken. apps/client/src/app/components/header/header.component.ts - 312 + 313 apps/client/src/app/components/user-account-access/user-account-access.component.ts - 154 + 152 apps/client/src/app/components/user-account-settings/user-account-settings.component.ts - 193 + 191 @@ -778,7 +778,7 @@ Activiteiten beheren apps/client/src/app/components/home-holdings/home-holdings.html - 65 + 64 @@ -1018,7 +1018,7 @@ Gegevensstoring melden apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html - 450 + 456 @@ -1066,7 +1066,7 @@ YTD apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 204 + 205 libs/ui/src/lib/assistant/assistant.component.ts @@ -1078,7 +1078,7 @@ 1J apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 208 + 209 libs/ui/src/lib/assistant/assistant.component.ts @@ -1090,7 +1090,7 @@ 5J apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 212 + 213 libs/ui/src/lib/assistant/assistant.component.ts @@ -1110,7 +1110,7 @@ Max apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 216 + 217 libs/ui/src/lib/assistant/assistant.component.ts @@ -1130,7 +1130,7 @@ apps/client/src/app/pages/portfolio/activities/import-activities-dialog/import-activities-dialog.component.ts - 196 + 195 @@ -1222,7 +1222,7 @@ Wil je deze aanmeldingsmethode echt verwijderen? apps/client/src/app/components/user-account-settings/user-account-settings.component.ts - 282 + 279 @@ -1378,7 +1378,7 @@ apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html - 375 + 381 apps/client/src/app/components/user-detail-dialog/user-detail-dialog.html @@ -1660,6 +1660,10 @@ Overview Overzicht + + apps/client/src/app/components/admin-jobs/admin-jobs.html + 7 + apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html 114 @@ -1918,7 +1922,7 @@ Huidige week apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 196 + 197 @@ -2042,7 +2046,7 @@ apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html - 342 + 348 apps/client/src/app/components/user-detail-dialog/user-detail-dialog.html @@ -2066,7 +2070,7 @@ Gegevens importeren... apps/client/src/app/pages/portfolio/activities/import-activities-dialog/import-activities-dialog.component.ts - 175 + 174 @@ -2074,7 +2078,7 @@ Importeren is voltooid apps/client/src/app/pages/portfolio/activities/import-activities-dialog/import-activities-dialog.component.ts - 185 + 184 @@ -2192,6 +2196,10 @@ apps/client/src/app/pages/register/user-account-registration-dialog/user-account-registration-dialog.html 88 + + libs/ui/src/lib/value/value.component.html + 18 + Resources @@ -2378,7 +2386,7 @@ apps/client/src/app/pages/portfolio/activities/import-activities-dialog/import-activities-dialog.component.ts - 193 + 192 @@ -2394,7 +2402,7 @@ apps/client/src/app/pages/portfolio/activities/import-activities-dialog/import-activities-dialog.component.ts - 195 + 194 @@ -2514,7 +2522,7 @@ Besparingen libs/ui/src/lib/fire-calculator/fire-calculator.component.ts - 410 + 424 @@ -2530,7 +2538,7 @@ libs/ui/src/lib/fire-calculator/fire-calculator.component.ts - 400 + 414 libs/ui/src/lib/i18n.ts @@ -2550,7 +2558,7 @@ Storting libs/ui/src/lib/fire-calculator/fire-calculator.component.ts - 390 + 404 @@ -2558,7 +2566,7 @@ Maandelijks apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts - 91 + 90 @@ -2582,11 +2590,11 @@ Angst apps/client/src/app/components/home-market/home-market.component.ts - 42 + 41 apps/client/src/app/components/markets/markets.component.ts - 47 + 46 libs/ui/src/lib/i18n.ts @@ -2598,11 +2606,11 @@ Hebzucht apps/client/src/app/components/home-market/home-market.component.ts - 43 + 42 apps/client/src/app/components/markets/markets.component.ts - 48 + 47 libs/ui/src/lib/i18n.ts @@ -2614,7 +2622,7 @@ Filter op... apps/client/src/app/components/admin-market-data/admin-market-data.component.ts - 390 + 383 @@ -2698,7 +2706,7 @@ Automatisch apps/client/src/app/components/user-account-settings/user-account-settings.component.ts - 70 + 69 apps/client/src/app/components/user-account-settings/user-account-settings.html @@ -2810,7 +2818,7 @@ Symbool apps/client/src/app/components/admin-jobs/admin-jobs.html - 68 + 77 apps/client/src/app/components/admin-market-data/admin-market-data.html @@ -2826,7 +2834,7 @@ apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html - 315 + 318 libs/ui/src/lib/i18n.ts @@ -2982,7 +2990,7 @@ libs/ui/src/lib/portfolio-proportion-chart/portfolio-proportion-chart.component.ts - 449 + 451 @@ -3002,11 +3010,11 @@ libs/ui/src/lib/portfolio-proportion-chart/portfolio-proportion-chart.component.ts - 451 + 453 libs/ui/src/lib/portfolio-proportion-chart/portfolio-proportion-chart.component.ts - 465 + 467 libs/ui/src/lib/top-holdings/top-holdings.component.html @@ -3146,7 +3154,7 @@ apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts - 76 + 75 libs/ui/src/lib/i18n.ts @@ -3202,7 +3210,7 @@ Gegevens valideren... apps/client/src/app/pages/portfolio/activities/import-activities-dialog/import-activities-dialog.component.ts - 299 + 293 @@ -3226,7 +3234,7 @@ Marktgegevens apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html - 397 + 403 libs/common/src/lib/routes/routes.ts @@ -3278,7 +3286,7 @@ Jaarlijks apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts - 92 + 91 @@ -3286,7 +3294,7 @@ Importeer dividenden apps/client/src/app/pages/portfolio/activities/import-activities-dialog/import-activities-dialog.component.ts - 137 + 136 libs/ui/src/lib/activities-table/activities-table.component.html @@ -3346,7 +3354,7 @@ Geen activiteiten apps/client/src/app/components/admin-market-data/admin-market-data.component.ts - 146 + 145 @@ -3850,7 +3858,7 @@ Huidig jaar apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 204 + 205 @@ -3894,7 +3902,7 @@ Wil je dit platform echt verwijderen? apps/client/src/app/components/admin-platform/admin-platform.component.ts - 112 + 111 @@ -4490,7 +4498,7 @@ ETF’s zonder Landen apps/client/src/app/components/admin-market-data/admin-market-data.component.ts - 136 + 135 @@ -4498,7 +4506,7 @@ ETF’s zonder Sectoren apps/client/src/app/components/admin-market-data/admin-market-data.component.ts - 141 + 140 @@ -4678,7 +4686,7 @@ Opdracht ID apps/client/src/app/components/admin-jobs/admin-jobs.html - 34 + 43 @@ -4734,7 +4742,7 @@ Valuta apps/client/src/app/components/admin-market-data/admin-market-data.component.ts - 131 + 130 apps/client/src/app/pages/public/public-page.html @@ -5484,7 +5492,7 @@ Weet u zetker dat u dit label wilt verwijderen? apps/client/src/app/components/admin-tag/admin-tag.component.ts - 109 + 108 @@ -5584,7 +5592,7 @@ Bezittingen Profiel apps/client/src/app/components/admin-jobs/admin-jobs.html - 52 + 61 @@ -5716,7 +5724,7 @@ Wilt u dit systeembericht echt verwijderen? apps/client/src/app/components/admin-overview/admin-overview.component.ts - 206 + 209 @@ -5872,11 +5880,11 @@ apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts - 81 + 80 apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts - 97 + 96 apps/client/src/app/pages/resources/personal-finance-tools/product-page.component.ts @@ -5896,7 +5904,7 @@ Sluit Holding apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html - 441 + 447 @@ -5944,7 +5952,7 @@ Week tot nu toe apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 196 + 197 libs/ui/src/lib/assistant/assistant.component.ts @@ -5964,7 +5972,7 @@ MTD apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 200 + 201 libs/ui/src/lib/assistant/assistant.component.ts @@ -6012,7 +6020,7 @@ jaar apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 208 + 209 apps/client/src/app/pages/resources/personal-finance-tools/product-page.html @@ -6032,7 +6040,7 @@ jaren apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 212 + 213 libs/ui/src/lib/assistant/assistant.component.ts @@ -6125,7 +6133,7 @@ Actief apps/client/src/app/components/home-holdings/home-holdings.component.ts - 64 + 63 @@ -6133,7 +6141,7 @@ Gesloten apps/client/src/app/components/home-holdings/home-holdings.component.ts - 65 + 64 @@ -6165,7 +6173,7 @@ Opdracht Uitvoeren apps/client/src/app/components/admin-jobs/admin-jobs.html - 220 + 229 @@ -6173,7 +6181,7 @@ Prioriteit apps/client/src/app/components/admin-jobs/admin-jobs.html - 96 + 105 @@ -6229,7 +6237,7 @@ Wilt u uw Ghostfolio account echt sluiten? apps/client/src/app/components/user-account-settings/user-account-settings.component.ts - 208 + 205 @@ -6285,7 +6293,7 @@ Oeps! Er is een fout opgetreden met het instellen van de biometrische authenticatie. apps/client/src/app/components/user-account-settings/user-account-settings.component.ts - 336 + 333 @@ -6301,7 +6309,7 @@ Benchmarks apps/client/src/app/components/admin-market-data/admin-market-data.component.ts - 126 + 125 @@ -6857,7 +6865,7 @@ Portfolio Momentopname apps/client/src/app/components/admin-jobs/admin-jobs.html - 56 + 65 @@ -6924,6 +6932,14 @@ 42 + + has been copied to the clipboard + has been copied to the clipboard + + libs/ui/src/lib/value/value.component.ts + 180 + + From the beginning Vanaf het begin @@ -7363,7 +7379,7 @@ apps/client/src/app/components/user-account-access/user-account-access.component.ts - 260 + 257 @@ -7403,7 +7419,7 @@ AI-prompt is naar het klembord gekopieerd apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts - 201 + 199 @@ -7419,7 +7435,7 @@ Lui apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 230 + 231 @@ -7427,7 +7443,7 @@ Direct apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 234 + 235 @@ -7467,7 +7483,7 @@ eind van de dag apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 230 + 231 @@ -7475,7 +7491,7 @@ real-time apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 234 + 235 @@ -7483,7 +7499,7 @@ Open Duck.ai apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts - 202 + 200 @@ -7503,7 +7519,7 @@ libs/ui/src/lib/treemap-chart/treemap-chart.component.ts - 375 + 377 @@ -7515,7 +7531,7 @@ apps/client/src/app/components/home-overview/home-overview.component.ts - 55 + 54 libs/ui/src/lib/holdings-table/holdings-table.component.html @@ -7523,11 +7539,11 @@ libs/ui/src/lib/treemap-chart/treemap-chart.component.ts - 375 + 377 libs/ui/src/lib/treemap-chart/treemap-chart.component.ts - 388 + 390 @@ -7631,11 +7647,11 @@ Beveiligingstoken apps/client/src/app/components/admin-users/admin-users.component.ts - 239 + 235 apps/client/src/app/components/user-account-access/user-account-access.component.ts - 170 + 167 @@ -7643,7 +7659,7 @@ Wilt u echt een nieuw beveiligingstoken voor deze gebruiker aanmaken? apps/client/src/app/components/admin-users/admin-users.component.ts - 244 + 240 @@ -7788,7 +7804,7 @@ iemand apps/client/src/app/pages/public/public-page.component.ts - 59 + 61 @@ -7820,7 +7836,7 @@ Wilt u dit item echt verwijderen? libs/ui/src/lib/benchmark/benchmark.component.ts - 144 + 139 @@ -7861,7 +7877,7 @@ Demo-gebruikersaccount is gesynchroniseerd. apps/client/src/app/components/admin-overview/admin-overview.component.ts - 274 + 277 @@ -8075,7 +8091,7 @@ Huidige maand apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 200 + 201 @@ -8244,7 +8260,7 @@ Wilt u echt een nieuwe securitytoken genereren? apps/client/src/app/components/user-account-access/user-account-access.component.ts - 175 + 172 @@ -8268,7 +8284,7 @@ Aandelen apps/client/src/app/components/markets/markets.component.ts - 52 + 51 apps/client/src/app/pages/features/features-page.html @@ -8280,7 +8296,7 @@ Cryptovaluta apps/client/src/app/components/markets/markets.component.ts - 53 + 52 apps/client/src/app/pages/features/features-page.html @@ -8300,7 +8316,7 @@ Beheer activaprofiel apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html - 465 + 471 diff --git a/apps/client/src/locales/messages.pl.xlf b/apps/client/src/locales/messages.pl.xlf index c7c07967f..a15609e6a 100644 --- a/apps/client/src/locales/messages.pl.xlf +++ b/apps/client/src/locales/messages.pl.xlf @@ -251,7 +251,7 @@ Typ apps/client/src/app/components/admin-jobs/admin-jobs.html - 48 + 57 apps/client/src/app/components/user-account-access/create-or-update-access-dialog/create-or-update-access-dialog.html @@ -583,7 +583,7 @@ Profil Aktywów apps/client/src/app/components/admin-jobs/admin-jobs.html - 52 + 61 @@ -591,7 +591,7 @@ Historyczne Dane Rynkowe apps/client/src/app/components/admin-jobs/admin-jobs.html - 54 + 63 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html @@ -603,7 +603,7 @@ Źródło Danych apps/client/src/app/components/admin-jobs/admin-jobs.html - 82 + 91 apps/client/src/app/components/admin-market-data/admin-market-data.html @@ -627,7 +627,7 @@ Próby apps/client/src/app/components/admin-jobs/admin-jobs.html - 120 + 129 @@ -635,7 +635,7 @@ Utworzono apps/client/src/app/components/admin-jobs/admin-jobs.html - 134 + 143 @@ -643,7 +643,7 @@ Zakończono apps/client/src/app/components/admin-jobs/admin-jobs.html - 143 + 152 @@ -651,7 +651,7 @@ Status apps/client/src/app/components/admin-jobs/admin-jobs.html - 152 + 161 apps/client/src/app/components/admin-settings/admin-settings.component.html @@ -660,7 +660,7 @@ and is driven by the efforts of its contributors - i jest rozwijany dzięki pracy jego współtwórców + i jest rozwijany dzięki pracy jego współtwórców apps/client/src/app/pages/about/overview/about-overview-page.html 49 @@ -671,7 +671,7 @@ Usuń Zadania apps/client/src/app/components/admin-jobs/admin-jobs.html - 193 + 202 @@ -679,7 +679,7 @@ Zobacz Dane apps/client/src/app/components/admin-jobs/admin-jobs.html - 208 + 217 @@ -687,7 +687,7 @@ Wyświetl Stos Wywołań apps/client/src/app/components/admin-jobs/admin-jobs.html - 216 + 225 @@ -695,7 +695,7 @@ Usuń Zadanie apps/client/src/app/components/admin-jobs/admin-jobs.html - 224 + 233 @@ -747,7 +747,7 @@ Waluty apps/client/src/app/components/admin-market-data/admin-market-data.component.ts - 131 + 130 apps/client/src/app/pages/public/public-page.html @@ -759,7 +759,7 @@ ETF-y bez Krajów apps/client/src/app/components/admin-market-data/admin-market-data.component.ts - 136 + 135 @@ -767,7 +767,7 @@ ETF-y bez Sektorów apps/client/src/app/components/admin-market-data/admin-market-data.component.ts - 141 + 140 @@ -783,7 +783,7 @@ Filtruj według... apps/client/src/app/components/admin-market-data/admin-market-data.component.ts - 390 + 383 @@ -1043,7 +1043,7 @@ Czy naprawdę chcesz usunąć ten kupon? apps/client/src/app/components/admin-overview/admin-overview.component.ts - 193 + 196 @@ -1051,7 +1051,7 @@ Czy naprawdę chcesz usunąć tę wiadomość systemową? apps/client/src/app/components/admin-overview/admin-overview.component.ts - 206 + 209 @@ -1059,7 +1059,7 @@ Czy naprawdę chcesz wyczyścić pamięć podręczną? apps/client/src/app/components/admin-overview/admin-overview.component.ts - 230 + 233 @@ -1067,7 +1067,7 @@ Proszę ustawić swoją wiadomość systemową: apps/client/src/app/components/admin-overview/admin-overview.component.ts - 250 + 253 @@ -1219,7 +1219,7 @@ Czy naprawdę chcesz usunąć tę platformę? apps/client/src/app/components/admin-platform/admin-platform.component.ts - 112 + 111 @@ -1251,7 +1251,7 @@ Obecny rok apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 204 + 205 @@ -1299,7 +1299,7 @@ Czy naprawdę chcesz usunąć ten tag? apps/client/src/app/components/admin-tag/admin-tag.component.ts - 109 + 108 @@ -1323,7 +1323,7 @@ Czy na pewno chcesz usunąć tego użytkownika? apps/client/src/app/components/admin-users/admin-users.component.ts - 218 + 215 @@ -1479,7 +1479,7 @@ apps/client/src/app/components/header/header.component.ts - 297 + 298 apps/client/src/app/components/login-with-access-token-dialog/login-with-access-token-dialog.html @@ -1499,15 +1499,15 @@ Ups! Nieprawidłowy token bezpieczeństwa. apps/client/src/app/components/header/header.component.ts - 312 + 313 apps/client/src/app/components/user-account-access/user-account-access.component.ts - 154 + 152 apps/client/src/app/components/user-account-settings/user-account-settings.component.ts - 193 + 191 @@ -1515,7 +1515,7 @@ Zarządzaj Aktywnościami apps/client/src/app/components/home-holdings/home-holdings.html - 65 + 64 @@ -1523,11 +1523,11 @@ Zagrożenie apps/client/src/app/components/home-market/home-market.component.ts - 42 + 41 apps/client/src/app/components/markets/markets.component.ts - 47 + 46 libs/ui/src/lib/i18n.ts @@ -1539,11 +1539,11 @@ Zachłanność apps/client/src/app/components/home-market/home-market.component.ts - 43 + 42 apps/client/src/app/components/markets/markets.component.ts - 48 + 47 libs/ui/src/lib/i18n.ts @@ -1580,7 +1580,7 @@ The source code is fully available as open source software (OSS) under the AGPL-3.0 license - Kod źródłowy jest w pełni dostępny jako oprogramowanie open source (OSS) na licencji AGPL-3.0 license + Kod źródłowy jest w pełni dostępny jako oprogramowanie open source (OSS) na licencji AGPL-3.0 license apps/client/src/app/pages/about/overview/about-overview-page.html 16 @@ -1647,7 +1647,7 @@ Obecny tydzień apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 196 + 197 @@ -1927,7 +1927,7 @@ Zgłoś Błąd Danych apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html - 450 + 456 @@ -2115,7 +2115,7 @@ Liczony od początku roku (year-to-date) apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 204 + 205 libs/ui/src/lib/assistant/assistant.component.ts @@ -2127,7 +2127,7 @@ 1 rok apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 208 + 209 libs/ui/src/lib/assistant/assistant.component.ts @@ -2139,7 +2139,7 @@ 5 lat apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 212 + 213 libs/ui/src/lib/assistant/assistant.component.ts @@ -2159,7 +2159,7 @@ Maksimum apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 216 + 217 libs/ui/src/lib/assistant/assistant.component.ts @@ -2263,7 +2263,7 @@ Auto apps/client/src/app/components/user-account-settings/user-account-settings.component.ts - 70 + 69 apps/client/src/app/components/user-account-settings/user-account-settings.html @@ -2275,7 +2275,7 @@ Czy na pewno chcesz usunąć tą metode logowania? apps/client/src/app/components/user-account-settings/user-account-settings.component.ts - 282 + 279 @@ -2459,7 +2459,7 @@ apps/client/src/app/pages/portfolio/activities/import-activities-dialog/import-activities-dialog.component.ts - 195 + 194 @@ -2471,7 +2471,7 @@ apps/client/src/app/pages/portfolio/activities/import-activities-dialog/import-activities-dialog.component.ts - 193 + 192 @@ -2487,7 +2487,7 @@ apps/client/src/app/pages/portfolio/activities/import-activities-dialog/import-activities-dialog.component.ts - 196 + 195 @@ -2615,7 +2615,7 @@ apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html - 375 + 381 apps/client/src/app/components/user-detail-dialog/user-detail-dialog.html @@ -2711,7 +2711,7 @@ Dane Rynkowe apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html - 397 + 403 libs/common/src/lib/routes/routes.ts @@ -2745,6 +2745,10 @@ Overview Przegląd + + apps/client/src/app/components/admin-jobs/admin-jobs.html + 7 + apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html 114 @@ -3591,7 +3595,7 @@ Job ID apps/client/src/app/components/admin-jobs/admin-jobs.html - 34 + 43 @@ -3647,7 +3651,7 @@ apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html - 342 + 348 apps/client/src/app/components/user-detail-dialog/user-detail-dialog.html @@ -3775,7 +3779,7 @@ Impotruj Dywidendy apps/client/src/app/pages/portfolio/activities/import-activities-dialog/import-activities-dialog.component.ts - 137 + 136 libs/ui/src/lib/activities-table/activities-table.component.html @@ -3791,7 +3795,7 @@ Importowanie danych... apps/client/src/app/pages/portfolio/activities/import-activities-dialog/import-activities-dialog.component.ts - 175 + 174 @@ -3799,7 +3803,7 @@ Importowanie zakończone apps/client/src/app/pages/portfolio/activities/import-activities-dialog/import-activities-dialog.component.ts - 185 + 184 @@ -3815,7 +3819,7 @@ Weryfikacja danych... apps/client/src/app/pages/portfolio/activities/import-activities-dialog/import-activities-dialog.component.ts - 299 + 293 @@ -4115,7 +4119,7 @@ apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts - 76 + 75 libs/ui/src/lib/i18n.ts @@ -4135,7 +4139,7 @@ Depozyt libs/ui/src/lib/fire-calculator/fire-calculator.component.ts - 390 + 404 @@ -4143,7 +4147,7 @@ Miesięcznie apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts - 91 + 90 @@ -4151,7 +4155,7 @@ Rocznie apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts - 92 + 91 @@ -4505,6 +4509,10 @@ apps/client/src/app/pages/register/user-account-registration-dialog/user-account-registration-dialog.html 88 + + libs/ui/src/lib/value/value.component.html + 18 + Personal Finance Tools @@ -4617,7 +4625,7 @@ Website of Thomas Kaul - Strona internetowa Thomas'a Kaul'a + Strona internetowa Thomas'a Kaul'a apps/client/src/app/pages/about/overview/about-overview-page.html 44 @@ -5060,7 +5068,7 @@ libs/ui/src/lib/fire-calculator/fire-calculator.component.ts - 400 + 414 libs/ui/src/lib/i18n.ts @@ -5072,7 +5080,7 @@ Oszczędności libs/ui/src/lib/fire-calculator/fire-calculator.component.ts - 410 + 424 @@ -5304,7 +5312,7 @@ libs/ui/src/lib/portfolio-proportion-chart/portfolio-proportion-chart.component.ts - 449 + 451 @@ -5320,7 +5328,7 @@ Brak transakcji apps/client/src/app/components/admin-market-data/admin-market-data.component.ts - 146 + 145 @@ -5352,7 +5360,7 @@ Symbol apps/client/src/app/components/admin-jobs/admin-jobs.html - 68 + 77 apps/client/src/app/components/admin-market-data/admin-market-data.html @@ -5368,7 +5376,7 @@ apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html - 315 + 318 libs/ui/src/lib/i18n.ts @@ -5708,11 +5716,11 @@ libs/ui/src/lib/portfolio-proportion-chart/portfolio-proportion-chart.component.ts - 451 + 453 libs/ui/src/lib/portfolio-proportion-chart/portfolio-proportion-chart.component.ts - 465 + 467 libs/ui/src/lib/top-holdings/top-holdings.component.html @@ -5872,11 +5880,11 @@ apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts - 81 + 80 apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts - 97 + 96 apps/client/src/app/pages/resources/personal-finance-tools/product-page.component.ts @@ -5896,7 +5904,7 @@ Zamknij pozycję apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html - 441 + 447 @@ -5944,7 +5952,7 @@ WTD apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 196 + 197 libs/ui/src/lib/assistant/assistant.component.ts @@ -5964,7 +5972,7 @@ MTD apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 200 + 201 libs/ui/src/lib/assistant/assistant.component.ts @@ -6012,7 +6020,7 @@ rok apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 208 + 209 apps/client/src/app/pages/resources/personal-finance-tools/product-page.html @@ -6032,7 +6040,7 @@ lata apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 212 + 213 libs/ui/src/lib/assistant/assistant.component.ts @@ -6125,7 +6133,7 @@ Antywne apps/client/src/app/components/home-holdings/home-holdings.component.ts - 64 + 63 @@ -6133,7 +6141,7 @@ Zamknięte apps/client/src/app/components/home-holdings/home-holdings.component.ts - 65 + 64 @@ -6165,7 +6173,7 @@ Wykonaj Zadanie apps/client/src/app/components/admin-jobs/admin-jobs.html - 220 + 229 @@ -6173,7 +6181,7 @@ Priorytet apps/client/src/app/components/admin-jobs/admin-jobs.html - 96 + 105 @@ -6229,7 +6237,7 @@ Czy na pewno chcesz zamknąć swoje konto Ghostfolio? apps/client/src/app/components/user-account-settings/user-account-settings.component.ts - 208 + 205 @@ -6285,7 +6293,7 @@ Ups! Wystąpił błąd podczas konfigurowania uwierzytelniania biometrycznego. apps/client/src/app/components/user-account-settings/user-account-settings.component.ts - 336 + 333 @@ -6301,7 +6309,7 @@ Punkty Odniesienia apps/client/src/app/components/admin-market-data/admin-market-data.component.ts - 126 + 125 @@ -6857,7 +6865,7 @@ Przegląd portfela apps/client/src/app/components/admin-jobs/admin-jobs.html - 56 + 65 @@ -6924,6 +6932,14 @@ 42 + + has been copied to the clipboard + has been copied to the clipboard + + libs/ui/src/lib/value/value.component.ts + 180 + + From the beginning Od samego początku @@ -7363,7 +7379,7 @@ apps/client/src/app/components/user-account-access/user-account-access.component.ts - 260 + 257 @@ -7403,7 +7419,7 @@ Prompt AI został skopiowany do schowka apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts - 201 + 199 @@ -7419,7 +7435,7 @@ Leniwy apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 230 + 231 @@ -7427,7 +7443,7 @@ Natychmiastowy apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 234 + 235 @@ -7467,7 +7483,7 @@ koniec dnia apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 230 + 231 @@ -7475,7 +7491,7 @@ w czasie rzeczywistym apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 234 + 235 @@ -7483,7 +7499,7 @@ Otwórz Duck.ai apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts - 202 + 200 @@ -7503,7 +7519,7 @@ libs/ui/src/lib/treemap-chart/treemap-chart.component.ts - 375 + 377 @@ -7515,7 +7531,7 @@ apps/client/src/app/components/home-overview/home-overview.component.ts - 55 + 54 libs/ui/src/lib/holdings-table/holdings-table.component.html @@ -7523,11 +7539,11 @@ libs/ui/src/lib/treemap-chart/treemap-chart.component.ts - 375 + 377 libs/ui/src/lib/treemap-chart/treemap-chart.component.ts - 388 + 390 @@ -7631,11 +7647,11 @@ Token bezpieczeństwa apps/client/src/app/components/admin-users/admin-users.component.ts - 239 + 235 apps/client/src/app/components/user-account-access/user-account-access.component.ts - 170 + 167 @@ -7643,7 +7659,7 @@ Czy napewno chcesz wygenerować nowy token bezpieczeństwa dla tego użytkownika? apps/client/src/app/components/admin-users/admin-users.component.ts - 244 + 240 @@ -7788,7 +7804,7 @@ ktoś apps/client/src/app/pages/public/public-page.component.ts - 59 + 61 @@ -7820,7 +7836,7 @@ Czy na pewno chcesz usunąć ten element? libs/ui/src/lib/benchmark/benchmark.component.ts - 144 + 139 @@ -7861,7 +7877,7 @@ Konto użytkownika demonstracyjnego zostało zsynchronizowane. apps/client/src/app/components/admin-overview/admin-overview.component.ts - 274 + 277 @@ -8075,7 +8091,7 @@ Bieżący miesiąc apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 200 + 201 @@ -8244,7 +8260,7 @@ Czy na pewno chcesz wygenerować nowy token bezpieczeństwa? apps/client/src/app/components/user-account-access/user-account-access.component.ts - 175 + 172 @@ -8268,7 +8284,7 @@ Akcje apps/client/src/app/components/markets/markets.component.ts - 52 + 51 apps/client/src/app/pages/features/features-page.html @@ -8280,7 +8296,7 @@ Kryptowaluty apps/client/src/app/components/markets/markets.component.ts - 53 + 52 apps/client/src/app/pages/features/features-page.html @@ -8300,7 +8316,7 @@ Zarządzaj profilem aktywów apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html - 465 + 471 diff --git a/apps/client/src/locales/messages.pt.xlf b/apps/client/src/locales/messages.pt.xlf index 72c1e6a3e..3531f84d7 100644 --- a/apps/client/src/locales/messages.pt.xlf +++ b/apps/client/src/locales/messages.pt.xlf @@ -42,7 +42,7 @@ Tipo apps/client/src/app/components/admin-jobs/admin-jobs.html - 48 + 57 apps/client/src/app/components/user-account-access/create-or-update-access-dialog/create-or-update-access-dialog.html @@ -362,7 +362,7 @@ Fonte de dados apps/client/src/app/components/admin-jobs/admin-jobs.html - 82 + 91 apps/client/src/app/components/admin-market-data/admin-market-data.html @@ -386,7 +386,7 @@ Tentativas apps/client/src/app/components/admin-jobs/admin-jobs.html - 120 + 129 @@ -394,7 +394,7 @@ Criado apps/client/src/app/components/admin-jobs/admin-jobs.html - 134 + 143 @@ -402,7 +402,7 @@ Terminado apps/client/src/app/components/admin-jobs/admin-jobs.html - 143 + 152 @@ -410,7 +410,7 @@ Estado apps/client/src/app/components/admin-jobs/admin-jobs.html - 152 + 161 apps/client/src/app/components/admin-settings/admin-settings.component.html @@ -430,7 +430,7 @@ Eliminar Tarefas apps/client/src/app/components/admin-jobs/admin-jobs.html - 193 + 202 @@ -450,7 +450,7 @@ Histórico de Dados de Mercado apps/client/src/app/components/admin-jobs/admin-jobs.html - 54 + 63 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html @@ -462,7 +462,7 @@ Visualizar dados apps/client/src/app/components/admin-jobs/admin-jobs.html - 208 + 217 @@ -470,7 +470,7 @@ Ver Stacktrace apps/client/src/app/components/admin-jobs/admin-jobs.html - 216 + 225 @@ -478,7 +478,7 @@ Apagar Tarefa apps/client/src/app/components/admin-jobs/admin-jobs.html - 224 + 233 @@ -530,7 +530,7 @@ Filtrar por... apps/client/src/app/components/admin-market-data/admin-market-data.component.ts - 390 + 383 @@ -606,7 +606,7 @@ Deseja realmente eliminar este cupão? apps/client/src/app/components/admin-overview/admin-overview.component.ts - 193 + 196 @@ -614,7 +614,7 @@ Deseja realmente limpar a cache? apps/client/src/app/components/admin-overview/admin-overview.component.ts - 230 + 233 @@ -622,7 +622,7 @@ Por favor, defina a sua mensagem do sistema: apps/client/src/app/components/admin-overview/admin-overview.component.ts - 250 + 253 @@ -714,7 +714,7 @@ Deseja realmente excluir este utilizador? apps/client/src/app/components/admin-users/admin-users.component.ts - 218 + 215 @@ -846,7 +846,7 @@ apps/client/src/app/components/header/header.component.ts - 297 + 298 apps/client/src/app/components/login-with-access-token-dialog/login-with-access-token-dialog.html @@ -866,15 +866,15 @@ Oops! Token de Segurança Incorreto. apps/client/src/app/components/header/header.component.ts - 312 + 313 apps/client/src/app/components/user-account-access/user-account-access.component.ts - 154 + 152 apps/client/src/app/components/user-account-settings/user-account-settings.component.ts - 193 + 191 @@ -882,7 +882,7 @@ Gerir Atividades apps/client/src/app/components/home-holdings/home-holdings.html - 65 + 64 @@ -890,11 +890,11 @@ Medo apps/client/src/app/components/home-market/home-market.component.ts - 42 + 41 apps/client/src/app/components/markets/markets.component.ts - 47 + 46 libs/ui/src/lib/i18n.ts @@ -906,11 +906,11 @@ Ganância apps/client/src/app/components/home-market/home-market.component.ts - 43 + 42 apps/client/src/app/components/markets/markets.component.ts - 48 + 47 libs/ui/src/lib/i18n.ts @@ -942,7 +942,7 @@ Depósito libs/ui/src/lib/fire-calculator/fire-calculator.component.ts - 390 + 404 @@ -1262,7 +1262,7 @@ Dados do Relatório com Problema apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html - 450 + 456 @@ -1310,7 +1310,7 @@ AATD apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 204 + 205 libs/ui/src/lib/assistant/assistant.component.ts @@ -1322,7 +1322,7 @@ 1A apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 208 + 209 libs/ui/src/lib/assistant/assistant.component.ts @@ -1334,7 +1334,7 @@ 5A apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 212 + 213 libs/ui/src/lib/assistant/assistant.component.ts @@ -1354,7 +1354,7 @@ Máx apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 216 + 217 libs/ui/src/lib/assistant/assistant.component.ts @@ -1382,7 +1382,7 @@ apps/client/src/app/pages/portfolio/activities/import-activities-dialog/import-activities-dialog.component.ts - 195 + 194 @@ -1394,7 +1394,7 @@ apps/client/src/app/pages/portfolio/activities/import-activities-dialog/import-activities-dialog.component.ts - 193 + 192 @@ -1410,7 +1410,7 @@ apps/client/src/app/pages/portfolio/activities/import-activities-dialog/import-activities-dialog.component.ts - 196 + 195 @@ -1470,7 +1470,7 @@ Auto apps/client/src/app/components/user-account-settings/user-account-settings.component.ts - 70 + 69 apps/client/src/app/components/user-account-settings/user-account-settings.html @@ -1514,7 +1514,7 @@ Deseja realmente remover este método de início de sessão? apps/client/src/app/components/user-account-settings/user-account-settings.component.ts - 282 + 279 @@ -1718,7 +1718,7 @@ apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html - 375 + 381 apps/client/src/app/components/user-detail-dialog/user-detail-dialog.html @@ -1936,6 +1936,10 @@ Overview Visão geral + + apps/client/src/app/components/admin-jobs/admin-jobs.html + 7 + apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html 114 @@ -2046,7 +2050,7 @@ apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html - 342 + 348 apps/client/src/app/components/user-detail-dialog/user-detail-dialog.html @@ -2078,7 +2082,7 @@ Current week apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 196 + 197 @@ -2158,7 +2162,7 @@ A importar dados... apps/client/src/app/pages/portfolio/activities/import-activities-dialog/import-activities-dialog.component.ts - 175 + 174 @@ -2166,7 +2170,7 @@ A importação foi concluída apps/client/src/app/pages/portfolio/activities/import-activities-dialog/import-activities-dialog.component.ts - 185 + 184 @@ -2362,7 +2366,7 @@ Mensalmente apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts - 91 + 90 @@ -2584,6 +2588,10 @@ apps/client/src/app/pages/register/user-account-registration-dialog/user-account-registration-dialog.html 88 + + libs/ui/src/lib/value/value.component.html + 18 + Resources @@ -2758,7 +2766,7 @@ libs/ui/src/lib/fire-calculator/fire-calculator.component.ts - 400 + 414 libs/ui/src/lib/i18n.ts @@ -2770,7 +2778,7 @@ Poupanças libs/ui/src/lib/fire-calculator/fire-calculator.component.ts - 410 + 424 @@ -2850,7 +2858,7 @@ libs/ui/src/lib/portfolio-proportion-chart/portfolio-proportion-chart.component.ts - 449 + 451 @@ -2858,7 +2866,7 @@ Símbolo apps/client/src/app/components/admin-jobs/admin-jobs.html - 68 + 77 apps/client/src/app/components/admin-market-data/admin-market-data.html @@ -2874,7 +2882,7 @@ apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html - 315 + 318 libs/ui/src/lib/i18n.ts @@ -3086,11 +3094,11 @@ libs/ui/src/lib/portfolio-proportion-chart/portfolio-proportion-chart.component.ts - 451 + 453 libs/ui/src/lib/portfolio-proportion-chart/portfolio-proportion-chart.component.ts - 465 + 467 libs/ui/src/lib/top-holdings/top-holdings.component.html @@ -3134,7 +3142,7 @@ Dados de Mercado apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html - 397 + 403 libs/common/src/lib/routes/routes.ts @@ -3158,7 +3166,7 @@ A validar dados... apps/client/src/app/pages/portfolio/activities/import-activities-dialog/import-activities-dialog.component.ts - 299 + 293 @@ -3210,7 +3218,7 @@ apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts - 76 + 75 libs/ui/src/lib/i18n.ts @@ -3278,7 +3286,7 @@ Anualmente apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts - 92 + 91 @@ -3286,7 +3294,7 @@ Importar Dividendos apps/client/src/app/pages/portfolio/activities/import-activities-dialog/import-activities-dialog.component.ts - 137 + 136 libs/ui/src/lib/activities-table/activities-table.component.html @@ -3346,7 +3354,7 @@ No Activities apps/client/src/app/components/admin-market-data/admin-market-data.component.ts - 146 + 145 @@ -3850,7 +3858,7 @@ Current year apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 204 + 205 @@ -3894,7 +3902,7 @@ Deseja mesmo eliminar esta plataforma? apps/client/src/app/components/admin-platform/admin-platform.component.ts - 112 + 111 @@ -4490,7 +4498,7 @@ ETFs sem países apps/client/src/app/components/admin-market-data/admin-market-data.component.ts - 136 + 135 @@ -4498,7 +4506,7 @@ ETFs sem setores apps/client/src/app/components/admin-market-data/admin-market-data.component.ts - 141 + 140 @@ -4678,7 +4686,7 @@ Job ID apps/client/src/app/components/admin-jobs/admin-jobs.html - 34 + 43 @@ -4734,7 +4742,7 @@ Moedas apps/client/src/app/components/admin-market-data/admin-market-data.component.ts - 131 + 130 apps/client/src/app/pages/public/public-page.html @@ -5484,7 +5492,7 @@ Você realmente deseja excluir esta tag? apps/client/src/app/components/admin-tag/admin-tag.component.ts - 109 + 108 @@ -5584,7 +5592,7 @@ Perfil de ativos apps/client/src/app/components/admin-jobs/admin-jobs.html - 52 + 61 @@ -5716,7 +5724,7 @@ Você realmente deseja excluir esta mensagem do sistema? apps/client/src/app/components/admin-overview/admin-overview.component.ts - 206 + 209 @@ -5872,11 +5880,11 @@ apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts - 81 + 80 apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts - 97 + 96 apps/client/src/app/pages/resources/personal-finance-tools/product-page.component.ts @@ -5896,7 +5904,7 @@ Close Holding apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html - 441 + 447 @@ -5944,7 +5952,7 @@ WTD apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 196 + 197 libs/ui/src/lib/assistant/assistant.component.ts @@ -5964,7 +5972,7 @@ MTD apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 200 + 201 libs/ui/src/lib/assistant/assistant.component.ts @@ -6012,7 +6020,7 @@ ano apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 208 + 209 apps/client/src/app/pages/resources/personal-finance-tools/product-page.html @@ -6032,7 +6040,7 @@ anos apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 212 + 213 libs/ui/src/lib/assistant/assistant.component.ts @@ -6125,7 +6133,7 @@ Ativo apps/client/src/app/components/home-holdings/home-holdings.component.ts - 64 + 63 @@ -6133,7 +6141,7 @@ Fechado apps/client/src/app/components/home-holdings/home-holdings.component.ts - 65 + 64 @@ -6165,7 +6173,7 @@ Executar trabalho apps/client/src/app/components/admin-jobs/admin-jobs.html - 220 + 229 @@ -6173,7 +6181,7 @@ Prioridade apps/client/src/app/components/admin-jobs/admin-jobs.html - 96 + 105 @@ -6229,7 +6237,7 @@ Você realmente deseja encerrar sua conta Ghostfolio? apps/client/src/app/components/user-account-settings/user-account-settings.component.ts - 208 + 205 @@ -6285,7 +6293,7 @@ Ops! Ocorreu um erro ao configurar a autenticação biométrica. apps/client/src/app/components/user-account-settings/user-account-settings.component.ts - 336 + 333 @@ -6301,7 +6309,7 @@ Referências apps/client/src/app/components/admin-market-data/admin-market-data.component.ts - 126 + 125 @@ -6857,7 +6865,7 @@ Visão geral do portfólio apps/client/src/app/components/admin-jobs/admin-jobs.html - 56 + 65 @@ -6924,6 +6932,14 @@ 42 + + has been copied to the clipboard + has been copied to the clipboard + + libs/ui/src/lib/value/value.component.ts + 180 + + From the beginning Desde o início @@ -7363,7 +7379,7 @@ apps/client/src/app/components/user-account-access/user-account-access.component.ts - 260 + 257 @@ -7403,7 +7419,7 @@ AI prompt has been copied to the clipboard apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts - 201 + 199 @@ -7419,7 +7435,7 @@ Lazy apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 230 + 231 @@ -7427,7 +7443,7 @@ Instant apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 234 + 235 @@ -7467,7 +7483,7 @@ end of day apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 230 + 231 @@ -7475,7 +7491,7 @@ real-time apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 234 + 235 @@ -7483,7 +7499,7 @@ Open Duck.ai apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts - 202 + 200 @@ -7503,7 +7519,7 @@ libs/ui/src/lib/treemap-chart/treemap-chart.component.ts - 375 + 377 @@ -7515,7 +7531,7 @@ apps/client/src/app/components/home-overview/home-overview.component.ts - 55 + 54 libs/ui/src/lib/holdings-table/holdings-table.component.html @@ -7523,11 +7539,11 @@ libs/ui/src/lib/treemap-chart/treemap-chart.component.ts - 375 + 377 libs/ui/src/lib/treemap-chart/treemap-chart.component.ts - 388 + 390 @@ -7631,11 +7647,11 @@ Security token apps/client/src/app/components/admin-users/admin-users.component.ts - 239 + 235 apps/client/src/app/components/user-account-access/user-account-access.component.ts - 170 + 167 @@ -7643,7 +7659,7 @@ Do you really want to generate a new security token for this user? apps/client/src/app/components/admin-users/admin-users.component.ts - 244 + 240 @@ -7788,7 +7804,7 @@ someone apps/client/src/app/pages/public/public-page.component.ts - 59 + 61 @@ -7820,7 +7836,7 @@ Do you really want to delete this item? libs/ui/src/lib/benchmark/benchmark.component.ts - 144 + 139 @@ -7861,7 +7877,7 @@ Demo user account has been synced. apps/client/src/app/components/admin-overview/admin-overview.component.ts - 274 + 277 @@ -8075,7 +8091,7 @@ Current month apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 200 + 201 @@ -8244,7 +8260,7 @@ Do you really want to generate a new security token? apps/client/src/app/components/user-account-access/user-account-access.component.ts - 175 + 172 @@ -8268,7 +8284,7 @@ Stocks apps/client/src/app/components/markets/markets.component.ts - 52 + 51 apps/client/src/app/pages/features/features-page.html @@ -8280,7 +8296,7 @@ Criptomoedas apps/client/src/app/components/markets/markets.component.ts - 53 + 52 apps/client/src/app/pages/features/features-page.html @@ -8300,7 +8316,7 @@ Gerenciar perfil de ativos apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html - 465 + 471 diff --git a/apps/client/src/locales/messages.tr.xlf b/apps/client/src/locales/messages.tr.xlf index 7f51580d7..e4547a2de 100644 --- a/apps/client/src/locales/messages.tr.xlf +++ b/apps/client/src/locales/messages.tr.xlf @@ -223,7 +223,7 @@ Tip apps/client/src/app/components/admin-jobs/admin-jobs.html - 48 + 57 apps/client/src/app/components/user-account-access/create-or-update-access-dialog/create-or-update-access-dialog.html @@ -543,7 +543,7 @@ Veri Kaynağı apps/client/src/app/components/admin-jobs/admin-jobs.html - 82 + 91 apps/client/src/app/components/admin-market-data/admin-market-data.html @@ -567,7 +567,7 @@ Deneme apps/client/src/app/components/admin-jobs/admin-jobs.html - 120 + 129 @@ -575,7 +575,7 @@ Oluşturuldu apps/client/src/app/components/admin-jobs/admin-jobs.html - 134 + 143 @@ -583,7 +583,7 @@ Tamamlandı apps/client/src/app/components/admin-jobs/admin-jobs.html - 143 + 152 @@ -591,7 +591,7 @@ Durum apps/client/src/app/components/admin-jobs/admin-jobs.html - 152 + 161 apps/client/src/app/components/admin-settings/admin-settings.component.html @@ -611,7 +611,7 @@ İşleri Sil apps/client/src/app/components/admin-jobs/admin-jobs.html - 193 + 202 @@ -631,7 +631,7 @@ Tarihsel Piyasa Verisi apps/client/src/app/components/admin-jobs/admin-jobs.html - 54 + 63 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html @@ -643,7 +643,7 @@ Veri Gör apps/client/src/app/components/admin-jobs/admin-jobs.html - 208 + 217 @@ -651,7 +651,7 @@ Hata İzini Görüntüle apps/client/src/app/components/admin-jobs/admin-jobs.html - 216 + 225 @@ -659,7 +659,7 @@ İşleri Sil apps/client/src/app/components/admin-jobs/admin-jobs.html - 224 + 233 @@ -711,7 +711,7 @@ Para Birimleri apps/client/src/app/components/admin-market-data/admin-market-data.component.ts - 131 + 130 apps/client/src/app/pages/public/public-page.html @@ -723,7 +723,7 @@ Ülkesi Olmayan ETF’ler apps/client/src/app/components/admin-market-data/admin-market-data.component.ts - 136 + 135 @@ -731,7 +731,7 @@ Sektörü Olmayan ETF’ler apps/client/src/app/components/admin-market-data/admin-market-data.component.ts - 141 + 140 @@ -739,7 +739,7 @@ Filtrele... apps/client/src/app/components/admin-market-data/admin-market-data.component.ts - 390 + 383 @@ -959,7 +959,7 @@ Bu kuponu gerçekten silmek istiyor musunuz? apps/client/src/app/components/admin-overview/admin-overview.component.ts - 193 + 196 @@ -967,7 +967,7 @@ Önbelleği temizlemeyi gerçekten istiyor musunuz? apps/client/src/app/components/admin-overview/admin-overview.component.ts - 230 + 233 @@ -975,7 +975,7 @@ Lütfen sistem mesajınızı belirleyin: apps/client/src/app/components/admin-overview/admin-overview.component.ts - 250 + 253 @@ -1135,7 +1135,7 @@ Bu platformu silmeyi gerçekten istiyor musunuz? apps/client/src/app/components/admin-platform/admin-platform.component.ts - 112 + 111 @@ -1167,7 +1167,7 @@ Current year apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 204 + 205 @@ -1191,7 +1191,7 @@ Bu kullanıcıyı silmeyi gerçekten istiyor musunuz? apps/client/src/app/components/admin-users/admin-users.component.ts - 218 + 215 @@ -1347,7 +1347,7 @@ apps/client/src/app/components/header/header.component.ts - 297 + 298 apps/client/src/app/components/login-with-access-token-dialog/login-with-access-token-dialog.html @@ -1367,15 +1367,15 @@ Hay Allah! Güvenlik anahtarı yanlış. apps/client/src/app/components/header/header.component.ts - 312 + 313 apps/client/src/app/components/user-account-access/user-account-access.component.ts - 154 + 152 apps/client/src/app/components/user-account-settings/user-account-settings.component.ts - 193 + 191 @@ -1383,7 +1383,7 @@ İşlemleri Yönet apps/client/src/app/components/home-holdings/home-holdings.html - 65 + 64 @@ -1391,11 +1391,11 @@ Korku apps/client/src/app/components/home-market/home-market.component.ts - 42 + 41 apps/client/src/app/components/markets/markets.component.ts - 47 + 46 libs/ui/src/lib/i18n.ts @@ -1407,11 +1407,11 @@ Açgözlülük apps/client/src/app/components/home-market/home-market.component.ts - 43 + 42 apps/client/src/app/components/markets/markets.component.ts - 48 + 47 libs/ui/src/lib/i18n.ts @@ -1515,7 +1515,7 @@ Current week apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 196 + 197 @@ -1795,7 +1795,7 @@ Rapor Veri Sorunu apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html - 450 + 456 @@ -1983,7 +1983,7 @@ YTD apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 204 + 205 libs/ui/src/lib/assistant/assistant.component.ts @@ -1995,7 +1995,7 @@ 1Y apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 208 + 209 libs/ui/src/lib/assistant/assistant.component.ts @@ -2007,7 +2007,7 @@ 5Y apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 212 + 213 libs/ui/src/lib/assistant/assistant.component.ts @@ -2027,7 +2027,7 @@ Maks. apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 216 + 217 libs/ui/src/lib/assistant/assistant.component.ts @@ -2055,7 +2055,7 @@ apps/client/src/app/pages/portfolio/activities/import-activities-dialog/import-activities-dialog.component.ts - 195 + 194 @@ -2067,7 +2067,7 @@ apps/client/src/app/pages/portfolio/activities/import-activities-dialog/import-activities-dialog.component.ts - 193 + 192 @@ -2083,7 +2083,7 @@ apps/client/src/app/pages/portfolio/activities/import-activities-dialog/import-activities-dialog.component.ts - 196 + 195 @@ -2211,7 +2211,7 @@ apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html - 375 + 381 apps/client/src/app/components/user-detail-dialog/user-detail-dialog.html @@ -2275,7 +2275,7 @@ Piyasa Verileri apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html - 397 + 403 libs/common/src/lib/routes/routes.ts @@ -2309,6 +2309,10 @@ Overview Özet + + apps/client/src/app/components/admin-jobs/admin-jobs.html + 7 + apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html 114 @@ -3099,7 +3103,7 @@ Job ID apps/client/src/app/components/admin-jobs/admin-jobs.html - 34 + 43 @@ -3147,7 +3151,7 @@ apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html - 342 + 348 apps/client/src/app/components/user-detail-dialog/user-detail-dialog.html @@ -3251,7 +3255,7 @@ Temettüleri İçe Aktar apps/client/src/app/pages/portfolio/activities/import-activities-dialog/import-activities-dialog.component.ts - 137 + 136 libs/ui/src/lib/activities-table/activities-table.component.html @@ -3267,7 +3271,7 @@ Veri içe aktarılıyor... apps/client/src/app/pages/portfolio/activities/import-activities-dialog/import-activities-dialog.component.ts - 175 + 174 @@ -3275,7 +3279,7 @@ İçe aktarma tamamlandı apps/client/src/app/pages/portfolio/activities/import-activities-dialog/import-activities-dialog.component.ts - 185 + 184 @@ -3291,7 +3295,7 @@ Veri doğrulanıyor... apps/client/src/app/pages/portfolio/activities/import-activities-dialog/import-activities-dialog.component.ts - 299 + 293 @@ -3599,7 +3603,7 @@ apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts - 76 + 75 libs/ui/src/lib/i18n.ts @@ -3619,7 +3623,7 @@ Para Yatırma libs/ui/src/lib/fire-calculator/fire-calculator.component.ts - 390 + 404 @@ -3627,7 +3631,7 @@ Aylık apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts - 91 + 90 @@ -3635,7 +3639,7 @@ Yıllık apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts - 92 + 91 @@ -4009,6 +4013,10 @@ apps/client/src/app/pages/register/user-account-registration-dialog/user-account-registration-dialog.html 88 + + libs/ui/src/lib/value/value.component.html + 18 + Personal Finance Tools @@ -4348,7 +4356,7 @@ Otomatik apps/client/src/app/components/user-account-settings/user-account-settings.component.ts - 70 + 69 apps/client/src/app/components/user-account-settings/user-account-settings.html @@ -4392,7 +4400,7 @@ Bu giriş yöntemini kaldırmayı gerçekten istiyor musunuz? apps/client/src/app/components/user-account-settings/user-account-settings.component.ts - 282 + 279 @@ -4756,7 +4764,7 @@ libs/ui/src/lib/fire-calculator/fire-calculator.component.ts - 400 + 414 libs/ui/src/lib/i18n.ts @@ -4768,7 +4776,7 @@ Tasarruflar libs/ui/src/lib/fire-calculator/fire-calculator.component.ts - 410 + 424 @@ -5000,7 +5008,7 @@ libs/ui/src/lib/portfolio-proportion-chart/portfolio-proportion-chart.component.ts - 449 + 451 @@ -5016,7 +5024,7 @@ No Activities apps/client/src/app/components/admin-market-data/admin-market-data.component.ts - 146 + 145 @@ -5048,7 +5056,7 @@ Sembol apps/client/src/app/components/admin-jobs/admin-jobs.html - 68 + 77 apps/client/src/app/components/admin-market-data/admin-market-data.html @@ -5064,7 +5072,7 @@ apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html - 315 + 318 libs/ui/src/lib/i18n.ts @@ -5352,11 +5360,11 @@ libs/ui/src/lib/portfolio-proportion-chart/portfolio-proportion-chart.component.ts - 451 + 453 libs/ui/src/lib/portfolio-proportion-chart/portfolio-proportion-chart.component.ts - 465 + 467 libs/ui/src/lib/top-holdings/top-holdings.component.html @@ -5484,7 +5492,7 @@ Bu etiketi silmeyi gerçekten istiyor musunuz? apps/client/src/app/components/admin-tag/admin-tag.component.ts - 109 + 108 @@ -5584,7 +5592,7 @@ Varlık Profili apps/client/src/app/components/admin-jobs/admin-jobs.html - 52 + 61 @@ -5716,7 +5724,7 @@ Bu sistem mesajını silmeyi gerçekten istiyor musunuz? apps/client/src/app/components/admin-overview/admin-overview.component.ts - 206 + 209 @@ -5872,11 +5880,11 @@ apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts - 81 + 80 apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts - 97 + 96 apps/client/src/app/pages/resources/personal-finance-tools/product-page.component.ts @@ -5896,7 +5904,7 @@ Close Holding apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html - 441 + 447 @@ -5944,7 +5952,7 @@ WTD apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 196 + 197 libs/ui/src/lib/assistant/assistant.component.ts @@ -5964,7 +5972,7 @@ MTD apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 200 + 201 libs/ui/src/lib/assistant/assistant.component.ts @@ -6012,7 +6020,7 @@ Yıl apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 208 + 209 apps/client/src/app/pages/resources/personal-finance-tools/product-page.html @@ -6032,7 +6040,7 @@ Yıllar apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 212 + 213 libs/ui/src/lib/assistant/assistant.component.ts @@ -6125,7 +6133,7 @@ Aktif apps/client/src/app/components/home-holdings/home-holdings.component.ts - 64 + 63 @@ -6133,7 +6141,7 @@ Kapalı apps/client/src/app/components/home-holdings/home-holdings.component.ts - 65 + 64 @@ -6165,7 +6173,7 @@ İşlemi Yürüt apps/client/src/app/components/admin-jobs/admin-jobs.html - 220 + 229 @@ -6173,7 +6181,7 @@ Öncelik apps/client/src/app/components/admin-jobs/admin-jobs.html - 96 + 105 @@ -6229,7 +6237,7 @@ Ghostfolio hesabınızı kapatmak istediğinize emin misiniz? apps/client/src/app/components/user-account-settings/user-account-settings.component.ts - 208 + 205 @@ -6285,7 +6293,7 @@ Oops! Biyometrik kimlik doğrulama ayarlanırken bir hata oluştu. apps/client/src/app/components/user-account-settings/user-account-settings.component.ts - 336 + 333 @@ -6301,7 +6309,7 @@ Kıyaslamalar apps/client/src/app/components/admin-market-data/admin-market-data.component.ts - 126 + 125 @@ -6857,7 +6865,7 @@ Portföy Anlık Görüntüsü apps/client/src/app/components/admin-jobs/admin-jobs.html - 56 + 65 @@ -6924,6 +6932,14 @@ 42 + + has been copied to the clipboard + has been copied to the clipboard + + libs/ui/src/lib/value/value.component.ts + 180 + + From the beginning Başlangıçtan beri @@ -7363,7 +7379,7 @@ apps/client/src/app/components/user-account-access/user-account-access.component.ts - 260 + 257 @@ -7403,7 +7419,7 @@ Yapay zeka istemi panoya kopyalandı apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts - 201 + 199 @@ -7419,7 +7435,7 @@ Tembel apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 230 + 231 @@ -7427,7 +7443,7 @@ Anında apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 234 + 235 @@ -7467,7 +7483,7 @@ gün sonu apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 230 + 231 @@ -7475,7 +7491,7 @@ gerçek zamanlı apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 234 + 235 @@ -7483,7 +7499,7 @@ Duck.ai’yi aç apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts - 202 + 200 @@ -7503,7 +7519,7 @@ libs/ui/src/lib/treemap-chart/treemap-chart.component.ts - 375 + 377 @@ -7515,7 +7531,7 @@ apps/client/src/app/components/home-overview/home-overview.component.ts - 55 + 54 libs/ui/src/lib/holdings-table/holdings-table.component.html @@ -7523,11 +7539,11 @@ libs/ui/src/lib/treemap-chart/treemap-chart.component.ts - 375 + 377 libs/ui/src/lib/treemap-chart/treemap-chart.component.ts - 388 + 390 @@ -7631,11 +7647,11 @@ Güvenlik belirteci apps/client/src/app/components/admin-users/admin-users.component.ts - 239 + 235 apps/client/src/app/components/user-account-access/user-account-access.component.ts - 170 + 167 @@ -7643,7 +7659,7 @@ Bu kullanıcı için yeni bir güvenlik belirteci oluşturmak istediğinize emin misiniz? apps/client/src/app/components/admin-users/admin-users.component.ts - 244 + 240 @@ -7788,7 +7804,7 @@ birisi apps/client/src/app/pages/public/public-page.component.ts - 59 + 61 @@ -7820,7 +7836,7 @@ Bu öğeyi silmek istediğinize emin misiniz? libs/ui/src/lib/benchmark/benchmark.component.ts - 144 + 139 @@ -7861,7 +7877,7 @@ Demo kullanıcı hesabı senkronize edildi. apps/client/src/app/components/admin-overview/admin-overview.component.ts - 274 + 277 @@ -8075,7 +8091,7 @@ Current month apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 200 + 201 @@ -8244,7 +8260,7 @@ Do you really want to generate a new security token? apps/client/src/app/components/user-account-access/user-account-access.component.ts - 175 + 172 @@ -8268,7 +8284,7 @@ Stocks apps/client/src/app/components/markets/markets.component.ts - 52 + 51 apps/client/src/app/pages/features/features-page.html @@ -8280,7 +8296,7 @@ Cryptocurrencies apps/client/src/app/components/markets/markets.component.ts - 53 + 52 apps/client/src/app/pages/features/features-page.html @@ -8300,7 +8316,7 @@ Manage Asset Profile apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html - 465 + 471 diff --git a/apps/client/src/locales/messages.uk.xlf b/apps/client/src/locales/messages.uk.xlf index 54bf5a08b..12b5c2bc3 100644 --- a/apps/client/src/locales/messages.uk.xlf +++ b/apps/client/src/locales/messages.uk.xlf @@ -38,7 +38,7 @@ apps/client/src/app/components/header/header.component.ts - 297 + 298 apps/client/src/app/components/login-with-access-token-dialog/login-with-access-token-dialog.html @@ -675,7 +675,7 @@ Тип apps/client/src/app/components/admin-jobs/admin-jobs.html - 48 + 57 apps/client/src/app/components/user-account-access/create-or-update-access-dialog/create-or-update-access-dialog.html @@ -695,7 +695,7 @@ Профіль активу apps/client/src/app/components/admin-jobs/admin-jobs.html - 52 + 61 @@ -703,7 +703,7 @@ Історичні ринкові дані apps/client/src/app/components/admin-jobs/admin-jobs.html - 54 + 63 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html @@ -715,7 +715,7 @@ Знімок портфеля apps/client/src/app/components/admin-jobs/admin-jobs.html - 56 + 65 @@ -723,7 +723,7 @@ Джерело даних apps/client/src/app/components/admin-jobs/admin-jobs.html - 82 + 91 apps/client/src/app/components/admin-market-data/admin-market-data.html @@ -747,7 +747,7 @@ Пріоритет apps/client/src/app/components/admin-jobs/admin-jobs.html - 96 + 105 @@ -755,7 +755,7 @@ Спроби apps/client/src/app/components/admin-jobs/admin-jobs.html - 120 + 129 @@ -763,7 +763,7 @@ Створено apps/client/src/app/components/admin-jobs/admin-jobs.html - 134 + 143 @@ -771,7 +771,7 @@ Завершено apps/client/src/app/components/admin-jobs/admin-jobs.html - 143 + 152 @@ -779,7 +779,7 @@ Статус apps/client/src/app/components/admin-jobs/admin-jobs.html - 152 + 161 apps/client/src/app/components/admin-settings/admin-settings.component.html @@ -799,7 +799,7 @@ Видалити завдання apps/client/src/app/components/admin-jobs/admin-jobs.html - 193 + 202 @@ -807,7 +807,7 @@ Переглянути дані apps/client/src/app/components/admin-jobs/admin-jobs.html - 208 + 217 @@ -815,7 +815,7 @@ Переглянути трасування apps/client/src/app/components/admin-jobs/admin-jobs.html - 216 + 225 @@ -823,7 +823,7 @@ Виконати завдання apps/client/src/app/components/admin-jobs/admin-jobs.html - 220 + 229 @@ -831,7 +831,7 @@ Видалити завдання apps/client/src/app/components/admin-jobs/admin-jobs.html - 224 + 233 @@ -839,7 +839,7 @@ Порівняльні показники apps/client/src/app/components/admin-market-data/admin-market-data.component.ts - 126 + 125 @@ -847,7 +847,7 @@ Валюти apps/client/src/app/components/admin-market-data/admin-market-data.component.ts - 131 + 130 apps/client/src/app/pages/public/public-page.html @@ -859,7 +859,7 @@ ETF без країн apps/client/src/app/components/admin-market-data/admin-market-data.component.ts - 136 + 135 @@ -867,7 +867,7 @@ ETF без секторів apps/client/src/app/components/admin-market-data/admin-market-data.component.ts - 141 + 140 @@ -875,7 +875,7 @@ Фільтрувати за... apps/client/src/app/components/admin-market-data/admin-market-data.component.ts - 390 + 383 @@ -1227,7 +1227,7 @@ Ви дійсно хочете видалити цей купон? apps/client/src/app/components/admin-overview/admin-overview.component.ts - 193 + 196 @@ -1235,7 +1235,7 @@ Ви дійсно хочете видалити це системне повідомлення? apps/client/src/app/components/admin-overview/admin-overview.component.ts - 206 + 209 @@ -1243,7 +1243,7 @@ Ви дійсно хочете очистити кеш? apps/client/src/app/components/admin-overview/admin-overview.component.ts - 230 + 233 @@ -1251,7 +1251,7 @@ Будь ласка, встановіть ваше системне повідомлення: apps/client/src/app/components/admin-overview/admin-overview.component.ts - 250 + 253 @@ -1379,7 +1379,7 @@ Ви дійсно хочете видалити цю платформу? apps/client/src/app/components/admin-platform/admin-platform.component.ts - 112 + 111 @@ -1411,7 +1411,7 @@ Current year apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 204 + 205 @@ -1595,7 +1595,7 @@ Ви дійсно хочете видалити цей тег? apps/client/src/app/components/admin-tag/admin-tag.component.ts - 109 + 108 @@ -1619,7 +1619,7 @@ Ви дійсно хочете видалити цього користувача? apps/client/src/app/components/admin-users/admin-users.component.ts - 218 + 215 @@ -1803,15 +1803,15 @@ Упс! Неправильний Секретний Токен. apps/client/src/app/components/header/header.component.ts - 312 + 313 apps/client/src/app/components/user-account-access/user-account-access.component.ts - 154 + 152 apps/client/src/app/components/user-account-settings/user-account-settings.component.ts - 193 + 191 @@ -1915,7 +1915,7 @@ Повідомити про збій даних apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html - 450 + 456 @@ -1923,7 +1923,7 @@ Активний apps/client/src/app/components/home-holdings/home-holdings.component.ts - 64 + 63 @@ -1931,7 +1931,7 @@ Закритий apps/client/src/app/components/home-holdings/home-holdings.component.ts - 65 + 64 @@ -1955,7 +1955,7 @@ Керування діяльністю apps/client/src/app/components/home-holdings/home-holdings.html - 65 + 64 @@ -1963,11 +1963,11 @@ Страх apps/client/src/app/components/home-market/home-market.component.ts - 42 + 41 apps/client/src/app/components/markets/markets.component.ts - 47 + 46 libs/ui/src/lib/i18n.ts @@ -1979,11 +1979,11 @@ Жадібність apps/client/src/app/components/home-market/home-market.component.ts - 43 + 42 apps/client/src/app/components/markets/markets.component.ts - 48 + 47 libs/ui/src/lib/i18n.ts @@ -2087,7 +2087,7 @@ Current week apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 196 + 197 @@ -2571,7 +2571,7 @@ З початку року apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 204 + 205 libs/ui/src/lib/assistant/assistant.component.ts @@ -2583,7 +2583,7 @@ 1 рік apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 208 + 209 libs/ui/src/lib/assistant/assistant.component.ts @@ -2595,7 +2595,7 @@ 5 років apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 212 + 213 libs/ui/src/lib/assistant/assistant.component.ts @@ -2615,7 +2615,7 @@ Максимум apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 216 + 217 libs/ui/src/lib/assistant/assistant.component.ts @@ -2687,7 +2687,7 @@ apps/client/src/app/components/user-account-access/user-account-access.component.ts - 260 + 257 @@ -2735,7 +2735,7 @@ apps/client/src/app/pages/portfolio/activities/import-activities-dialog/import-activities-dialog.component.ts - 196 + 195 @@ -2835,7 +2835,7 @@ Автоматичний apps/client/src/app/components/user-account-settings/user-account-settings.component.ts - 70 + 69 apps/client/src/app/components/user-account-settings/user-account-settings.html @@ -2847,7 +2847,7 @@ Ви дійсно хочете закрити ваш обліковий запис Ghostfolio? apps/client/src/app/components/user-account-settings/user-account-settings.component.ts - 208 + 205 @@ -2855,7 +2855,7 @@ Ви дійсно хочете вилучити цей спосіб входу? apps/client/src/app/components/user-account-settings/user-account-settings.component.ts - 282 + 279 @@ -2871,7 +2871,7 @@ Упс! Виникла помилка під час налаштування біометричної автентифікації. apps/client/src/app/components/user-account-settings/user-account-settings.component.ts - 336 + 333 @@ -3063,7 +3063,7 @@ apps/client/src/app/pages/portfolio/activities/import-activities-dialog/import-activities-dialog.component.ts - 195 + 194 @@ -3083,7 +3083,7 @@ apps/client/src/app/pages/portfolio/activities/import-activities-dialog/import-activities-dialog.component.ts - 193 + 192 @@ -3219,7 +3219,7 @@ apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html - 375 + 381 apps/client/src/app/components/user-detail-dialog/user-detail-dialog.html @@ -3323,7 +3323,7 @@ Ринкові дані apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html - 397 + 403 libs/common/src/lib/routes/routes.ts @@ -3357,6 +3357,10 @@ Overview Огляд + + apps/client/src/app/components/admin-jobs/admin-jobs.html + 7 + apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html 114 @@ -4252,7 +4256,7 @@ Job ID apps/client/src/app/components/admin-jobs/admin-jobs.html - 34 + 43 @@ -4308,7 +4312,7 @@ apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html - 342 + 348 apps/client/src/app/components/user-detail-dialog/user-detail-dialog.html @@ -4448,7 +4452,7 @@ Імпорт дивідендів apps/client/src/app/pages/portfolio/activities/import-activities-dialog/import-activities-dialog.component.ts - 137 + 136 libs/ui/src/lib/activities-table/activities-table.component.html @@ -4464,7 +4468,7 @@ Імпортуються дані... apps/client/src/app/pages/portfolio/activities/import-activities-dialog/import-activities-dialog.component.ts - 175 + 174 @@ -4472,7 +4476,7 @@ Імпорт завершено apps/client/src/app/pages/portfolio/activities/import-activities-dialog/import-activities-dialog.component.ts - 185 + 184 @@ -4488,7 +4492,7 @@ Перевірка даних... apps/client/src/app/pages/portfolio/activities/import-activities-dialog/import-activities-dialog.component.ts - 299 + 293 @@ -4820,7 +4824,7 @@ apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts - 76 + 75 libs/ui/src/lib/i18n.ts @@ -4840,11 +4844,11 @@ apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts - 81 + 80 apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts - 97 + 96 apps/client/src/app/pages/resources/personal-finance-tools/product-page.component.ts @@ -4864,7 +4868,7 @@ Щомісячно apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts - 91 + 90 @@ -4872,7 +4876,7 @@ Щорічно apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts - 92 + 91 @@ -4880,7 +4884,7 @@ Close Holding apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html - 441 + 447 @@ -5247,6 +5251,14 @@ 42 + + has been copied to the clipboard + has been copied to the clipboard + + libs/ui/src/lib/value/value.component.ts + 180 + + From the beginning З початку @@ -5314,6 +5326,10 @@ apps/client/src/app/pages/register/user-account-registration-dialog/user-account-registration-dialog.html 88 + + libs/ui/src/lib/value/value.component.html + 18 + Glossary @@ -6171,7 +6187,7 @@ WTD apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 196 + 197 libs/ui/src/lib/assistant/assistant.component.ts @@ -6191,7 +6207,7 @@ MTD apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 200 + 201 libs/ui/src/lib/assistant/assistant.component.ts @@ -6211,7 +6227,7 @@ рік apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 208 + 209 apps/client/src/app/pages/resources/personal-finance-tools/product-page.html @@ -6231,7 +6247,7 @@ роки apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 212 + 213 libs/ui/src/lib/assistant/assistant.component.ts @@ -6383,7 +6399,7 @@ Депозит libs/ui/src/lib/fire-calculator/fire-calculator.component.ts - 390 + 404 @@ -6399,7 +6415,7 @@ libs/ui/src/lib/fire-calculator/fire-calculator.component.ts - 400 + 414 libs/ui/src/lib/i18n.ts @@ -6411,7 +6427,7 @@ Заощадження libs/ui/src/lib/fire-calculator/fire-calculator.component.ts - 410 + 424 @@ -6763,7 +6779,7 @@ libs/ui/src/lib/portfolio-proportion-chart/portfolio-proportion-chart.component.ts - 449 + 451 @@ -6787,7 +6803,7 @@ No Activities apps/client/src/app/components/admin-market-data/admin-market-data.component.ts - 146 + 145 @@ -6819,7 +6835,7 @@ Символ apps/client/src/app/components/admin-jobs/admin-jobs.html - 68 + 77 apps/client/src/app/components/admin-market-data/admin-market-data.html @@ -6835,7 +6851,7 @@ apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html - 315 + 318 libs/ui/src/lib/i18n.ts @@ -7371,11 +7387,11 @@ libs/ui/src/lib/portfolio-proportion-chart/portfolio-proportion-chart.component.ts - 451 + 453 libs/ui/src/lib/portfolio-proportion-chart/portfolio-proportion-chart.component.ts - 465 + 467 libs/ui/src/lib/top-holdings/top-holdings.component.html @@ -7411,7 +7427,7 @@ Запит AI скопійовано в буфер обміну apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts - 201 + 199 @@ -7419,7 +7435,7 @@ Lazy apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 230 + 231 @@ -7427,7 +7443,7 @@ Instant apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 234 + 235 @@ -7467,7 +7483,7 @@ end of day apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 230 + 231 @@ -7475,7 +7491,7 @@ real-time apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 234 + 235 @@ -7483,7 +7499,7 @@ Open Duck.ai apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts - 202 + 200 @@ -7503,7 +7519,7 @@ libs/ui/src/lib/treemap-chart/treemap-chart.component.ts - 375 + 377 @@ -7515,7 +7531,7 @@ apps/client/src/app/components/home-overview/home-overview.component.ts - 55 + 54 libs/ui/src/lib/holdings-table/holdings-table.component.html @@ -7523,11 +7539,11 @@ libs/ui/src/lib/treemap-chart/treemap-chart.component.ts - 375 + 377 libs/ui/src/lib/treemap-chart/treemap-chart.component.ts - 388 + 390 @@ -7631,11 +7647,11 @@ Security token apps/client/src/app/components/admin-users/admin-users.component.ts - 239 + 235 apps/client/src/app/components/user-account-access/user-account-access.component.ts - 170 + 167 @@ -7643,7 +7659,7 @@ Do you really want to generate a new security token for this user? apps/client/src/app/components/admin-users/admin-users.component.ts - 244 + 240 @@ -7788,7 +7804,7 @@ someone apps/client/src/app/pages/public/public-page.component.ts - 59 + 61 @@ -7820,7 +7836,7 @@ Do you really want to delete this item? libs/ui/src/lib/benchmark/benchmark.component.ts - 144 + 139 @@ -7861,7 +7877,7 @@ Demo user account has been synced. apps/client/src/app/components/admin-overview/admin-overview.component.ts - 274 + 277 @@ -8075,7 +8091,7 @@ Current month apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 200 + 201 @@ -8244,7 +8260,7 @@ Do you really want to generate a new security token? apps/client/src/app/components/user-account-access/user-account-access.component.ts - 175 + 172 @@ -8268,7 +8284,7 @@ Stocks apps/client/src/app/components/markets/markets.component.ts - 52 + 51 apps/client/src/app/pages/features/features-page.html @@ -8280,7 +8296,7 @@ Cryptocurrencies apps/client/src/app/components/markets/markets.component.ts - 53 + 52 apps/client/src/app/pages/features/features-page.html @@ -8300,7 +8316,7 @@ Manage Asset Profile apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html - 465 + 471 diff --git a/apps/client/src/locales/messages.xlf b/apps/client/src/locales/messages.xlf index 7db54e0c4..fa9e6b874 100644 --- a/apps/client/src/locales/messages.xlf +++ b/apps/client/src/locales/messages.xlf @@ -235,7 +235,7 @@ Type apps/client/src/app/components/admin-jobs/admin-jobs.html - 48 + 57 apps/client/src/app/components/user-account-access/create-or-update-access-dialog/create-or-update-access-dialog.html @@ -559,14 +559,14 @@ Asset Profile apps/client/src/app/components/admin-jobs/admin-jobs.html - 52 + 61 Historical Market Data apps/client/src/app/components/admin-jobs/admin-jobs.html - 54 + 63 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html @@ -577,7 +577,7 @@ Data Source apps/client/src/app/components/admin-jobs/admin-jobs.html - 82 + 91 apps/client/src/app/components/admin-market-data/admin-market-data.html @@ -600,28 +600,28 @@ Attempts apps/client/src/app/components/admin-jobs/admin-jobs.html - 120 + 129 Created apps/client/src/app/components/admin-jobs/admin-jobs.html - 134 + 143 Finished apps/client/src/app/components/admin-jobs/admin-jobs.html - 143 + 152 Status apps/client/src/app/components/admin-jobs/admin-jobs.html - 152 + 161 apps/client/src/app/components/admin-settings/admin-settings.component.html @@ -639,28 +639,28 @@ Delete Jobs apps/client/src/app/components/admin-jobs/admin-jobs.html - 193 + 202 View Data apps/client/src/app/components/admin-jobs/admin-jobs.html - 208 + 217 View Stacktrace apps/client/src/app/components/admin-jobs/admin-jobs.html - 216 + 225 Delete Job apps/client/src/app/components/admin-jobs/admin-jobs.html - 224 + 233 @@ -708,7 +708,7 @@ Currencies apps/client/src/app/components/admin-market-data/admin-market-data.component.ts - 131 + 130 apps/client/src/app/pages/public/public-page.html @@ -719,14 +719,14 @@ ETFs without Countries apps/client/src/app/components/admin-market-data/admin-market-data.component.ts - 136 + 135 ETFs without Sectors apps/client/src/app/components/admin-market-data/admin-market-data.component.ts - 141 + 140 @@ -740,7 +740,7 @@ Filter by... apps/client/src/app/components/admin-market-data/admin-market-data.component.ts - 390 + 383 @@ -999,28 +999,28 @@ Do you really want to delete this coupon? apps/client/src/app/components/admin-overview/admin-overview.component.ts - 193 + 196 Do you really want to delete this system message? apps/client/src/app/components/admin-overview/admin-overview.component.ts - 206 + 209 Do you really want to flush the cache? apps/client/src/app/components/admin-overview/admin-overview.component.ts - 230 + 233 Please set your system message: apps/client/src/app/components/admin-overview/admin-overview.component.ts - 250 + 253 @@ -1155,7 +1155,7 @@ Do you really want to delete this platform? apps/client/src/app/components/admin-platform/admin-platform.component.ts - 112 + 111 @@ -1183,7 +1183,7 @@ Current year apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 204 + 205 @@ -1226,7 +1226,7 @@ Do you really want to delete this tag? apps/client/src/app/components/admin-tag/admin-tag.component.ts - 109 + 108 @@ -1247,7 +1247,7 @@ Do you really want to delete this user? apps/client/src/app/components/admin-users/admin-users.component.ts - 218 + 215 @@ -1389,7 +1389,7 @@ apps/client/src/app/components/header/header.component.ts - 297 + 298 apps/client/src/app/components/login-with-access-token-dialog/login-with-access-token-dialog.html @@ -1408,33 +1408,33 @@ Oops! Incorrect Security Token. apps/client/src/app/components/header/header.component.ts - 312 + 313 apps/client/src/app/components/user-account-access/user-account-access.component.ts - 154 + 152 apps/client/src/app/components/user-account-settings/user-account-settings.component.ts - 193 + 191 Manage Activities apps/client/src/app/components/home-holdings/home-holdings.html - 65 + 64 Fear apps/client/src/app/components/home-market/home-market.component.ts - 42 + 41 apps/client/src/app/components/markets/markets.component.ts - 47 + 46 libs/ui/src/lib/i18n.ts @@ -1445,11 +1445,11 @@ Greed apps/client/src/app/components/home-market/home-market.component.ts - 43 + 42 apps/client/src/app/components/markets/markets.component.ts - 48 + 47 libs/ui/src/lib/i18n.ts @@ -1541,7 +1541,7 @@ Current week apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 196 + 197 @@ -1797,7 +1797,7 @@ Report Data Glitch apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html - 450 + 456 @@ -1972,7 +1972,7 @@ YTD apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 204 + 205 libs/ui/src/lib/assistant/assistant.component.ts @@ -1983,7 +1983,7 @@ 1Y apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 208 + 209 libs/ui/src/lib/assistant/assistant.component.ts @@ -1994,7 +1994,7 @@ 5Y apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 212 + 213 libs/ui/src/lib/assistant/assistant.component.ts @@ -2012,7 +2012,7 @@ Max apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 216 + 217 libs/ui/src/lib/assistant/assistant.component.ts @@ -2105,7 +2105,7 @@ Auto apps/client/src/app/components/user-account-settings/user-account-settings.component.ts - 70 + 69 apps/client/src/app/components/user-account-settings/user-account-settings.html @@ -2116,7 +2116,7 @@ Do you really want to remove this sign in method? apps/client/src/app/components/user-account-settings/user-account-settings.component.ts - 282 + 279 @@ -2280,7 +2280,7 @@ apps/client/src/app/pages/portfolio/activities/import-activities-dialog/import-activities-dialog.component.ts - 195 + 194 @@ -2291,7 +2291,7 @@ apps/client/src/app/pages/portfolio/activities/import-activities-dialog/import-activities-dialog.component.ts - 193 + 192 @@ -2306,7 +2306,7 @@ apps/client/src/app/pages/portfolio/activities/import-activities-dialog/import-activities-dialog.component.ts - 196 + 195 @@ -2425,7 +2425,7 @@ apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html - 375 + 381 apps/client/src/app/components/user-detail-dialog/user-detail-dialog.html @@ -2512,7 +2512,7 @@ Market Data apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html - 397 + 403 libs/common/src/lib/routes/routes.ts @@ -2543,6 +2543,10 @@ Overview + + apps/client/src/app/components/admin-jobs/admin-jobs.html + 7 + apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html 114 @@ -3323,7 +3327,7 @@ Job ID apps/client/src/app/components/admin-jobs/admin-jobs.html - 34 + 43 @@ -3375,7 +3379,7 @@ apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html - 342 + 348 apps/client/src/app/components/user-detail-dialog/user-detail-dialog.html @@ -3491,7 +3495,7 @@ Import Dividends apps/client/src/app/pages/portfolio/activities/import-activities-dialog/import-activities-dialog.component.ts - 137 + 136 libs/ui/src/lib/activities-table/activities-table.component.html @@ -3506,14 +3510,14 @@ Importing data... apps/client/src/app/pages/portfolio/activities/import-activities-dialog/import-activities-dialog.component.ts - 175 + 174 Import has been completed apps/client/src/app/pages/portfolio/activities/import-activities-dialog/import-activities-dialog.component.ts - 185 + 184 @@ -3527,7 +3531,7 @@ Validating data... apps/client/src/app/pages/portfolio/activities/import-activities-dialog/import-activities-dialog.component.ts - 299 + 293 @@ -3797,7 +3801,7 @@ apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts - 76 + 75 libs/ui/src/lib/i18n.ts @@ -3815,21 +3819,21 @@ Deposit libs/ui/src/lib/fire-calculator/fire-calculator.component.ts - 390 + 404 Monthly apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts - 91 + 90 Yearly apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts - 92 + 91 @@ -4147,6 +4151,10 @@ apps/client/src/app/pages/register/user-account-registration-dialog/user-account-registration-dialog.html 88 + + libs/ui/src/lib/value/value.component.html + 18 + Personal Finance Tools @@ -4680,7 +4688,7 @@ libs/ui/src/lib/fire-calculator/fire-calculator.component.ts - 400 + 414 libs/ui/src/lib/i18n.ts @@ -4691,7 +4699,7 @@ Savings libs/ui/src/lib/fire-calculator/fire-calculator.component.ts - 410 + 424 @@ -4904,7 +4912,7 @@ libs/ui/src/lib/portfolio-proportion-chart/portfolio-proportion-chart.component.ts - 449 + 451 @@ -4918,7 +4926,7 @@ No Activities apps/client/src/app/components/admin-market-data/admin-market-data.component.ts - 146 + 145 @@ -4939,7 +4947,7 @@ Symbol apps/client/src/app/components/admin-jobs/admin-jobs.html - 68 + 77 apps/client/src/app/components/admin-market-data/admin-market-data.html @@ -4955,7 +4963,7 @@ apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html - 315 + 318 libs/ui/src/lib/i18n.ts @@ -5259,11 +5267,11 @@ libs/ui/src/lib/portfolio-proportion-chart/portfolio-proportion-chart.component.ts - 451 + 453 libs/ui/src/lib/portfolio-proportion-chart/portfolio-proportion-chart.component.ts - 465 + 467 libs/ui/src/lib/top-holdings/top-holdings.component.html @@ -5366,7 +5374,7 @@ Close Holding apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html - 441 + 447 @@ -5388,11 +5396,11 @@ apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts - 81 + 80 apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts - 97 + 96 apps/client/src/app/pages/resources/personal-finance-tools/product-page.component.ts @@ -5445,7 +5453,7 @@ MTD apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 200 + 201 libs/ui/src/lib/assistant/assistant.component.ts @@ -5456,7 +5464,7 @@ WTD apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 196 + 197 libs/ui/src/lib/assistant/assistant.component.ts @@ -5492,7 +5500,7 @@ year apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 208 + 209 apps/client/src/app/pages/resources/personal-finance-tools/product-page.html @@ -5511,7 +5519,7 @@ years apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 212 + 213 libs/ui/src/lib/assistant/assistant.component.ts @@ -5595,14 +5603,14 @@ Closed apps/client/src/app/components/home-holdings/home-holdings.component.ts - 65 + 64 Active apps/client/src/app/components/home-holdings/home-holdings.component.ts - 64 + 63 @@ -5630,7 +5638,7 @@ Execute Job apps/client/src/app/components/admin-jobs/admin-jobs.html - 220 + 229 @@ -5644,7 +5652,7 @@ Priority apps/client/src/app/components/admin-jobs/admin-jobs.html - 96 + 105 @@ -5693,7 +5701,7 @@ Do you really want to close your Ghostfolio account? apps/client/src/app/components/user-account-settings/user-account-settings.component.ts - 208 + 205 @@ -5735,7 +5743,7 @@ Oops! There was an error setting up biometric authentication. apps/client/src/app/components/user-account-settings/user-account-settings.component.ts - 336 + 333 @@ -5770,7 +5778,7 @@ Benchmarks apps/client/src/app/components/admin-market-data/admin-market-data.component.ts - 126 + 125 @@ -6268,7 +6276,7 @@ Portfolio Snapshot apps/client/src/app/components/admin-jobs/admin-jobs.html - 56 + 65 @@ -6320,6 +6328,13 @@ 42 + + has been copied to the clipboard + + libs/ui/src/lib/value/value.component.ts + 180 + + offers a free plan @@ -6724,7 +6739,7 @@ apps/client/src/app/components/user-account-access/user-account-access.component.ts - 260 + 257 @@ -6745,7 +6760,7 @@ AI prompt has been copied to the clipboard apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts - 201 + 199 @@ -6780,14 +6795,14 @@ Instant apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 234 + 235 Lazy apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 230 + 231 @@ -6801,21 +6816,21 @@ real-time apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 234 + 235 end of day apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 230 + 231 Open Duck.ai apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts - 202 + 200 @@ -6833,7 +6848,7 @@ libs/ui/src/lib/treemap-chart/treemap-chart.component.ts - 375 + 377 @@ -6844,7 +6859,7 @@ apps/client/src/app/components/home-overview/home-overview.component.ts - 55 + 54 libs/ui/src/lib/holdings-table/holdings-table.component.html @@ -6852,11 +6867,11 @@ libs/ui/src/lib/treemap-chart/treemap-chart.component.ts - 375 + 377 libs/ui/src/lib/treemap-chart/treemap-chart.component.ts - 388 + 390 @@ -6947,7 +6962,7 @@ Do you really want to generate a new security token for this user? apps/client/src/app/components/admin-users/admin-users.component.ts - 244 + 240 @@ -6961,11 +6976,11 @@ Security token apps/client/src/app/components/admin-users/admin-users.component.ts - 239 + 235 apps/client/src/app/components/user-account-access/user-account-access.component.ts - 170 + 167 @@ -7065,7 +7080,7 @@ someone apps/client/src/app/pages/public/public-page.component.ts - 59 + 61 @@ -7094,7 +7109,7 @@ Do you really want to delete this item? libs/ui/src/lib/benchmark/benchmark.component.ts - 144 + 139 @@ -7138,7 +7153,7 @@ Demo user account has been synced. apps/client/src/app/components/admin-overview/admin-overview.component.ts - 274 + 277 @@ -7322,7 +7337,7 @@ Current month apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 200 + 201 @@ -7485,14 +7500,14 @@ Do you really want to generate a new security token? apps/client/src/app/components/user-account-access/user-account-access.component.ts - 175 + 172 Cryptocurrencies apps/client/src/app/components/markets/markets.component.ts - 53 + 52 apps/client/src/app/pages/features/features-page.html @@ -7503,7 +7518,7 @@ Stocks apps/client/src/app/components/markets/markets.component.ts - 52 + 51 apps/client/src/app/pages/features/features-page.html @@ -7521,7 +7536,7 @@ Manage Asset Profile apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html - 465 + 471 diff --git a/apps/client/src/locales/messages.zh.xlf b/apps/client/src/locales/messages.zh.xlf index be465e9df..78c9b717d 100644 --- a/apps/client/src/locales/messages.zh.xlf +++ b/apps/client/src/locales/messages.zh.xlf @@ -252,7 +252,7 @@ 类型 apps/client/src/app/components/admin-jobs/admin-jobs.html - 48 + 57 apps/client/src/app/components/user-account-access/create-or-update-access-dialog/create-or-update-access-dialog.html @@ -592,7 +592,7 @@ 资产概况 apps/client/src/app/components/admin-jobs/admin-jobs.html - 52 + 61 @@ -600,7 +600,7 @@ 历史市场数据 apps/client/src/app/components/admin-jobs/admin-jobs.html - 54 + 63 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html @@ -612,7 +612,7 @@ 数据源 apps/client/src/app/components/admin-jobs/admin-jobs.html - 82 + 91 apps/client/src/app/components/admin-market-data/admin-market-data.html @@ -636,7 +636,7 @@ 尝试次数 apps/client/src/app/components/admin-jobs/admin-jobs.html - 120 + 129 @@ -644,7 +644,7 @@ 创建 apps/client/src/app/components/admin-jobs/admin-jobs.html - 134 + 143 @@ -652,7 +652,7 @@ 完成 apps/client/src/app/components/admin-jobs/admin-jobs.html - 143 + 152 @@ -660,7 +660,7 @@ 状态 apps/client/src/app/components/admin-jobs/admin-jobs.html - 152 + 161 apps/client/src/app/components/admin-settings/admin-settings.component.html @@ -680,7 +680,7 @@ 删除任务 apps/client/src/app/components/admin-jobs/admin-jobs.html - 193 + 202 @@ -688,7 +688,7 @@ 查看数据 apps/client/src/app/components/admin-jobs/admin-jobs.html - 208 + 217 @@ -696,7 +696,7 @@ 查看堆栈跟踪 apps/client/src/app/components/admin-jobs/admin-jobs.html - 216 + 225 @@ -704,7 +704,7 @@ 删除任务 apps/client/src/app/components/admin-jobs/admin-jobs.html - 224 + 233 @@ -756,7 +756,7 @@ 货币 apps/client/src/app/components/admin-market-data/admin-market-data.component.ts - 131 + 130 apps/client/src/app/pages/public/public-page.html @@ -768,7 +768,7 @@ 没有国家的 ETF apps/client/src/app/components/admin-market-data/admin-market-data.component.ts - 136 + 135 @@ -776,7 +776,7 @@ 无行业类别的 ETF apps/client/src/app/components/admin-market-data/admin-market-data.component.ts - 141 + 140 @@ -792,7 +792,7 @@ 过滤... apps/client/src/app/components/admin-market-data/admin-market-data.component.ts - 390 + 383 @@ -1052,7 +1052,7 @@ 您确实要删除此优惠券吗? apps/client/src/app/components/admin-overview/admin-overview.component.ts - 193 + 196 @@ -1060,7 +1060,7 @@ 您真的要删除这条系统消息吗? apps/client/src/app/components/admin-overview/admin-overview.component.ts - 206 + 209 @@ -1068,7 +1068,7 @@ 您真的要刷新缓存吗? apps/client/src/app/components/admin-overview/admin-overview.component.ts - 230 + 233 @@ -1076,7 +1076,7 @@ 请设置您的系统消息: apps/client/src/app/components/admin-overview/admin-overview.component.ts - 250 + 253 @@ -1228,7 +1228,7 @@ 您真的要删除这个平台吗? apps/client/src/app/components/admin-platform/admin-platform.component.ts - 112 + 111 @@ -1260,7 +1260,7 @@ 当前年份 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 204 + 205 @@ -1308,7 +1308,7 @@ 您真的要删除此标签吗? apps/client/src/app/components/admin-tag/admin-tag.component.ts - 109 + 108 @@ -1332,7 +1332,7 @@ 您真的要删除该用户吗? apps/client/src/app/components/admin-users/admin-users.component.ts - 218 + 215 @@ -1488,7 +1488,7 @@ apps/client/src/app/components/header/header.component.ts - 297 + 298 apps/client/src/app/components/login-with-access-token-dialog/login-with-access-token-dialog.html @@ -1508,15 +1508,15 @@ 哎呀!安全令牌不正确。 apps/client/src/app/components/header/header.component.ts - 312 + 313 apps/client/src/app/components/user-account-access/user-account-access.component.ts - 154 + 152 apps/client/src/app/components/user-account-settings/user-account-settings.component.ts - 193 + 191 @@ -1524,7 +1524,7 @@ 管理活动 apps/client/src/app/components/home-holdings/home-holdings.html - 65 + 64 @@ -1532,11 +1532,11 @@ 恐惧 apps/client/src/app/components/home-market/home-market.component.ts - 42 + 41 apps/client/src/app/components/markets/markets.component.ts - 47 + 46 libs/ui/src/lib/i18n.ts @@ -1548,11 +1548,11 @@ 贪婪 apps/client/src/app/components/home-market/home-market.component.ts - 43 + 42 apps/client/src/app/components/markets/markets.component.ts - 48 + 47 libs/ui/src/lib/i18n.ts @@ -1656,7 +1656,7 @@ 当前周 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 196 + 197 @@ -1936,7 +1936,7 @@ 报告数据故障 apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html - 450 + 456 @@ -2124,7 +2124,7 @@ 年初至今 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 204 + 205 libs/ui/src/lib/assistant/assistant.component.ts @@ -2136,7 +2136,7 @@ 1年 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 208 + 209 libs/ui/src/lib/assistant/assistant.component.ts @@ -2148,7 +2148,7 @@ 5年 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 212 + 213 libs/ui/src/lib/assistant/assistant.component.ts @@ -2168,7 +2168,7 @@ 最大限度 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 216 + 217 libs/ui/src/lib/assistant/assistant.component.ts @@ -2272,7 +2272,7 @@ 自动 apps/client/src/app/components/user-account-settings/user-account-settings.component.ts - 70 + 69 apps/client/src/app/components/user-account-settings/user-account-settings.html @@ -2284,7 +2284,7 @@ 您确实要删除此登录方法吗? apps/client/src/app/components/user-account-settings/user-account-settings.component.ts - 282 + 279 @@ -2468,7 +2468,7 @@ apps/client/src/app/pages/portfolio/activities/import-activities-dialog/import-activities-dialog.component.ts - 195 + 194 @@ -2480,7 +2480,7 @@ apps/client/src/app/pages/portfolio/activities/import-activities-dialog/import-activities-dialog.component.ts - 193 + 192 @@ -2496,7 +2496,7 @@ apps/client/src/app/pages/portfolio/activities/import-activities-dialog/import-activities-dialog.component.ts - 196 + 195 @@ -2624,7 +2624,7 @@ apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html - 375 + 381 apps/client/src/app/components/user-detail-dialog/user-detail-dialog.html @@ -2720,7 +2720,7 @@ 市场数据 apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html - 397 + 403 libs/common/src/lib/routes/routes.ts @@ -2754,6 +2754,10 @@ Overview 概述 + + apps/client/src/app/components/admin-jobs/admin-jobs.html + 7 + apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html 114 @@ -3608,7 +3612,7 @@ 作业 ID apps/client/src/app/components/admin-jobs/admin-jobs.html - 34 + 43 @@ -3664,7 +3668,7 @@ apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html - 342 + 348 apps/client/src/app/components/user-detail-dialog/user-detail-dialog.html @@ -3792,7 +3796,7 @@ 导入股息 apps/client/src/app/pages/portfolio/activities/import-activities-dialog/import-activities-dialog.component.ts - 137 + 136 libs/ui/src/lib/activities-table/activities-table.component.html @@ -3808,7 +3812,7 @@ 正在导入数据... apps/client/src/app/pages/portfolio/activities/import-activities-dialog/import-activities-dialog.component.ts - 175 + 174 @@ -3816,7 +3820,7 @@ 导入已完成 apps/client/src/app/pages/portfolio/activities/import-activities-dialog/import-activities-dialog.component.ts - 185 + 184 @@ -3832,7 +3836,7 @@ 验证数据... apps/client/src/app/pages/portfolio/activities/import-activities-dialog/import-activities-dialog.component.ts - 299 + 293 @@ -4132,7 +4136,7 @@ apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts - 76 + 75 libs/ui/src/lib/i18n.ts @@ -4152,7 +4156,7 @@ 存款 libs/ui/src/lib/fire-calculator/fire-calculator.component.ts - 390 + 404 @@ -4160,7 +4164,7 @@ 每月 apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts - 91 + 90 @@ -4168,7 +4172,7 @@ 每年 apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts - 92 + 91 @@ -4522,6 +4526,10 @@ apps/client/src/app/pages/register/user-account-registration-dialog/user-account-registration-dialog.html 88 + + libs/ui/src/lib/value/value.component.html + 18 + Personal Finance Tools @@ -5113,7 +5121,7 @@ libs/ui/src/lib/fire-calculator/fire-calculator.component.ts - 400 + 414 libs/ui/src/lib/i18n.ts @@ -5125,7 +5133,7 @@ 储蓄 libs/ui/src/lib/fire-calculator/fire-calculator.component.ts - 410 + 424 @@ -5357,7 +5365,7 @@ libs/ui/src/lib/portfolio-proportion-chart/portfolio-proportion-chart.component.ts - 449 + 451 @@ -5373,7 +5381,7 @@ No Activities apps/client/src/app/components/admin-market-data/admin-market-data.component.ts - 146 + 145 @@ -5397,7 +5405,7 @@ 代码 apps/client/src/app/components/admin-jobs/admin-jobs.html - 68 + 77 apps/client/src/app/components/admin-market-data/admin-market-data.html @@ -5413,7 +5421,7 @@ apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html - 315 + 318 libs/ui/src/lib/i18n.ts @@ -5753,11 +5761,11 @@ libs/ui/src/lib/portfolio-proportion-chart/portfolio-proportion-chart.component.ts - 451 + 453 libs/ui/src/lib/portfolio-proportion-chart/portfolio-proportion-chart.component.ts - 465 + 467 libs/ui/src/lib/top-holdings/top-holdings.component.html @@ -5873,7 +5881,7 @@ 关闭持仓 apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html - 441 + 447 @@ -5897,11 +5905,11 @@ apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts - 81 + 80 apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts - 97 + 96 apps/client/src/app/pages/resources/personal-finance-tools/product-page.component.ts @@ -5961,7 +5969,7 @@ 本月至今 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 200 + 201 libs/ui/src/lib/assistant/assistant.component.ts @@ -5973,7 +5981,7 @@ 本周至今 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 196 + 197 libs/ui/src/lib/assistant/assistant.component.ts @@ -6013,7 +6021,7 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 208 + 209 apps/client/src/app/pages/resources/personal-finance-tools/product-page.html @@ -6033,7 +6041,7 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 212 + 213 libs/ui/src/lib/assistant/assistant.component.ts @@ -6126,7 +6134,7 @@ 已关闭 apps/client/src/app/components/home-holdings/home-holdings.component.ts - 65 + 64 @@ -6134,7 +6142,7 @@ 活跃 apps/client/src/app/components/home-holdings/home-holdings.component.ts - 64 + 63 @@ -6166,7 +6174,7 @@ 执行作业 apps/client/src/app/components/admin-jobs/admin-jobs.html - 220 + 229 @@ -6174,7 +6182,7 @@ 优先级 apps/client/src/app/components/admin-jobs/admin-jobs.html - 96 + 105 @@ -6230,7 +6238,7 @@ 您确定要关闭您的 Ghostfolio 账户吗? apps/client/src/app/components/user-account-settings/user-account-settings.component.ts - 208 + 205 @@ -6286,7 +6294,7 @@ 哎呀!设置生物识别认证时发生错误。 apps/client/src/app/components/user-account-settings/user-account-settings.component.ts - 336 + 333 @@ -6302,7 +6310,7 @@ 基准 apps/client/src/app/components/admin-market-data/admin-market-data.component.ts - 126 + 125 @@ -6858,7 +6866,7 @@ 投资组合快照 apps/client/src/app/components/admin-jobs/admin-jobs.html - 56 + 65 @@ -6925,6 +6933,14 @@ 42 + + has been copied to the clipboard + has been copied to the clipboard + + libs/ui/src/lib/value/value.component.ts + 180 + + From the beginning 从头开始 @@ -7364,7 +7380,7 @@ apps/client/src/app/components/user-account-access/user-account-access.component.ts - 260 + 257 @@ -7404,7 +7420,7 @@ AI 提示已复制到剪贴板 apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts - 201 + 199 @@ -7420,7 +7436,7 @@ 延迟 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 230 + 231 @@ -7428,7 +7444,7 @@ 即时 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 234 + 235 @@ -7468,7 +7484,7 @@ 收盘 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 230 + 231 @@ -7476,7 +7492,7 @@ 实时 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 234 + 235 @@ -7484,7 +7500,7 @@ 打开 Duck.ai apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts - 202 + 200 @@ -7504,7 +7520,7 @@ libs/ui/src/lib/treemap-chart/treemap-chart.component.ts - 375 + 377 @@ -7516,7 +7532,7 @@ apps/client/src/app/components/home-overview/home-overview.component.ts - 55 + 54 libs/ui/src/lib/holdings-table/holdings-table.component.html @@ -7524,11 +7540,11 @@ libs/ui/src/lib/treemap-chart/treemap-chart.component.ts - 375 + 377 libs/ui/src/lib/treemap-chart/treemap-chart.component.ts - 388 + 390 @@ -7632,11 +7648,11 @@ 安全令牌 apps/client/src/app/components/admin-users/admin-users.component.ts - 239 + 235 apps/client/src/app/components/user-account-access/user-account-access.component.ts - 170 + 167 @@ -7644,7 +7660,7 @@ 您确定要为此用户生成新的安全令牌吗? apps/client/src/app/components/admin-users/admin-users.component.ts - 244 + 240 @@ -7789,7 +7805,7 @@ 某人 apps/client/src/app/pages/public/public-page.component.ts - 59 + 61 @@ -7821,7 +7837,7 @@ 您确定要删除此项目吗? libs/ui/src/lib/benchmark/benchmark.component.ts - 144 + 139 @@ -7862,7 +7878,7 @@ 演示用户账户已同步。 apps/client/src/app/components/admin-overview/admin-overview.component.ts - 274 + 277 @@ -8076,7 +8092,7 @@ 当前月份 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 200 + 201 @@ -8245,7 +8261,7 @@ 您真的想要生成一个新的安全令牌吗? apps/client/src/app/components/user-account-access/user-account-access.component.ts - 175 + 172 @@ -8269,7 +8285,7 @@ 股票 apps/client/src/app/components/markets/markets.component.ts - 52 + 51 apps/client/src/app/pages/features/features-page.html @@ -8281,7 +8297,7 @@ 加密货币 apps/client/src/app/components/markets/markets.component.ts - 53 + 52 apps/client/src/app/pages/features/features-page.html @@ -8301,7 +8317,7 @@ 管理资产概况 apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html - 465 + 471 From 584d74c3c932f7c75b918059f067e24df0a0ffca Mon Sep 17 00:00:00 2001 From: Thomas Kaul <4159106+dtslvr@users.noreply.github.com> Date: Tue, 31 Mar 2026 17:52:47 +0200 Subject: [PATCH 189/224] Task/upgrade stripe to version 20.4.1 (#6631) * Upgrade stripe to version 20.4.1 * Update changelog --- CHANGELOG.md | 1 + apps/api/src/app/subscription/subscription.service.ts | 2 +- package-lock.json | 8 ++++---- package.json | 2 +- 4 files changed, 7 insertions(+), 6 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 274851846..01ca53dc4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -18,6 +18,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Improved the language localization for Spanish (`es`) - Upgraded `countries-list` from version `3.2.2` to `3.3.0` - Upgraded `ng-extract-i18n-merge` from `3.2.1` to `3.3.0` +- Upgraded `stripe` from version `20.3.0` to `20.4.1` ## 2.251.0 - 2026-03-24 diff --git a/apps/api/src/app/subscription/subscription.service.ts b/apps/api/src/app/subscription/subscription.service.ts index 689ee3e6a..877ea0ee4 100644 --- a/apps/api/src/app/subscription/subscription.service.ts +++ b/apps/api/src/app/subscription/subscription.service.ts @@ -35,7 +35,7 @@ export class SubscriptionService { this.stripe = new Stripe( this.configurationService.get('STRIPE_SECRET_KEY'), { - apiVersion: '2026-01-28.clover' + apiVersion: '2026-02-25.clover' } ); } diff --git a/package-lock.json b/package-lock.json index 81128f284..1f4295a6a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -89,7 +89,7 @@ "passport-openidconnect": "0.1.2", "reflect-metadata": "0.2.2", "rxjs": "7.8.1", - "stripe": "20.3.0", + "stripe": "20.4.1", "svgmap": "2.19.2", "tablemark": "4.1.0", "twitter-api-v2": "1.29.0", @@ -32351,9 +32351,9 @@ } }, "node_modules/stripe": { - "version": "20.3.0", - "resolved": "https://registry.npmjs.org/stripe/-/stripe-20.3.0.tgz", - "integrity": "sha512-DYzcmV1MfYhycr1GwjCjeQVYk9Gu8dpxyTlu7qeDCsuguug7oUTxPsUQuZeSf/OPzK7pofqobvOKVqAwlpgf/Q==", + "version": "20.4.1", + "resolved": "https://registry.npmjs.org/stripe/-/stripe-20.4.1.tgz", + "integrity": "sha512-axCguHItc8Sxt0HC6aSkdVRPffjYPV7EQqZRb2GkIa8FzWDycE7nHJM19C6xAIynH1Qp1/BHiopSi96jGBxT0w==", "license": "MIT", "engines": { "node": ">=16" diff --git a/package.json b/package.json index 535469559..b7f9bc2e7 100644 --- a/package.json +++ b/package.json @@ -134,7 +134,7 @@ "passport-openidconnect": "0.1.2", "reflect-metadata": "0.2.2", "rxjs": "7.8.1", - "stripe": "20.3.0", + "stripe": "20.4.1", "svgmap": "2.19.2", "tablemark": "4.1.0", "twitter-api-v2": "1.29.0", From 7e182aa6a23614f8a40c7c9add6c13b550da9e68 Mon Sep 17 00:00:00 2001 From: Thomas Kaul <4159106+dtslvr@users.noreply.github.com> Date: Tue, 31 Mar 2026 18:58:03 +0200 Subject: [PATCH 190/224] Task/improve language localization for DE 20260331 (#6642) * Improve translation * Update changelog --- CHANGELOG.md | 1 + apps/client/src/locales/messages.de.xlf | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 01ca53dc4..89055d018 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 ### Changed +- Improved the language localization for German (`de`) - Improved the language localization for Spanish (`es`) - Upgraded `countries-list` from version `3.2.2` to `3.3.0` - Upgraded `ng-extract-i18n-merge` from `3.2.1` to `3.3.0` diff --git a/apps/client/src/locales/messages.de.xlf b/apps/client/src/locales/messages.de.xlf index 1a1df8cc1..ff12aebcb 100644 --- a/apps/client/src/locales/messages.de.xlf +++ b/apps/client/src/locales/messages.de.xlf @@ -6958,7 +6958,7 @@ has been copied to the clipboard - has been copied to the clipboard + wurde in die Zwischenablage kopiert libs/ui/src/lib/value/value.component.ts 180 From d702685ce39f5646cdd8abd3076764c050dae705 Mon Sep 17 00:00:00 2001 From: Thomas Kaul <4159106+dtslvr@users.noreply.github.com> Date: Tue, 31 Mar 2026 19:03:07 +0200 Subject: [PATCH 191/224] Feature/add copy-to-clipboard button to user detail dialog (#6641) * Add copy-to-clipboard button to user id * Update changelog --- CHANGELOG.md | 1 + .../components/user-detail-dialog/user-detail-dialog.html | 8 +++++++- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 89055d018..407767cac 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,6 +12,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Added support for a copy-to-clipboard functionality in the value component - Extended the holding detail dialog by adding a copy-to-clipboard button for the ISIN number (experimental) - Extended the holding detail dialog by adding a copy-to-clipboard button for the symbol (experimental) +- Extended the user detail dialog of the admin control panel’s users section by adding a copy-to-clipboard button for the user id ### Changed 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 570dcf4d6..e9af86942 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 @@ -27,7 +27,13 @@
    - User ID + User ID
    - @if (user?.settings?.isExperimentalFeatures) { + @if (user()?.settings?.isExperimentalFeatures) {
    GET {{ baseUrl }}/api/v1/public/{{ @@ -69,7 +69,7 @@ class="no-max-width" xPosition="before" > - @if (user?.settings?.isExperimentalFeatures) { + @if (user()?.settings?.isExperimentalFeatures) { } @if ( - user?.settings?.isExperimentalFeatures || element.type === 'PUBLIC' + user()?.settings?.isExperimentalFeatures || + element.type === 'PUBLIC' ) {
    } @@ -100,7 +101,7 @@ - - + +
    diff --git a/apps/client/src/app/components/access-table/access-table.component.ts b/apps/client/src/app/components/access-table/access-table.component.ts index 76548c45d..122b4f88b 100644 --- a/apps/client/src/app/components/access-table/access-table.component.ts +++ b/apps/client/src/app/components/access-table/access-table.component.ts @@ -7,11 +7,12 @@ import { Clipboard, ClipboardModule } from '@angular/cdk/clipboard'; import { ChangeDetectionStrategy, Component, + computed, CUSTOM_ELEMENTS_SCHEMA, - EventEmitter, - Input, - OnChanges, - Output + effect, + inject, + input, + output } from '@angular/core'; import { MatButtonModule } from '@angular/material/button'; import { MatMenuModule } from '@angular/material/menu'; @@ -46,23 +47,32 @@ import ms from 'ms'; templateUrl: './access-table.component.html', styleUrls: ['./access-table.component.scss'] }) -export class GfAccessTableComponent implements OnChanges { - @Input() accesses: Access[]; - @Input() showActions: boolean; - @Input() user: User; - - @Output() accessDeleted = new EventEmitter(); - @Output() accessToUpdate = new EventEmitter(); - - public baseUrl = window.location.origin; - public dataSource: MatTableDataSource; - public displayedColumns = []; - - public constructor( - private clipboard: Clipboard, - private notificationService: NotificationService, - private snackBar: MatSnackBar - ) { +export class GfAccessTableComponent { + public readonly accesses = input.required(); + public readonly showActions = input(false); + public readonly user = input.required(); + + public readonly accessDeleted = output(); + public readonly accessToUpdate = output(); + + protected readonly baseUrl = window.location.origin; + protected readonly dataSource = new MatTableDataSource(); + + protected readonly displayedColumns = computed(() => { + const columns = ['alias', 'grantee', 'type', 'details']; + + if (this.showActions()) { + columns.push('actions'); + } + + return columns; + }); + + private readonly clipboard = inject(Clipboard); + private readonly notificationService = inject(NotificationService); + private readonly snackBar = inject(MatSnackBar); + + public constructor() { addIcons({ copyOutline, createOutline, @@ -72,27 +82,19 @@ export class GfAccessTableComponent implements OnChanges { lockOpenOutline, removeCircleOutline }); - } - public ngOnChanges() { - this.displayedColumns = ['alias', 'grantee', 'type', 'details']; - - if (this.showActions) { - this.displayedColumns.push('actions'); - } - - if (this.accesses) { - this.dataSource = new MatTableDataSource(this.accesses); - } + effect(() => { + this.dataSource.data = this.accesses() ?? []; + }); } - public getPublicUrl(aId: string): string { - const languageCode = this.user.settings.language; + protected getPublicUrl(aId: string) { + const languageCode = this.user().settings.language; return `${this.baseUrl}/${languageCode}/${publicRoutes.public.path}/${aId}`; } - public onCopyUrlToClipboard(aId: string): void { + protected onCopyUrlToClipboard(aId: string) { this.clipboard.copy(this.getPublicUrl(aId)); this.snackBar.open( @@ -104,7 +106,7 @@ export class GfAccessTableComponent implements OnChanges { ); } - public onDeleteAccess(aId: string) { + protected onDeleteAccess(aId: string) { this.notificationService.confirm({ confirmFn: () => { this.accessDeleted.emit(aId); @@ -114,7 +116,7 @@ export class GfAccessTableComponent implements OnChanges { }); } - public onUpdateAccess(aId: string) { + protected onUpdateAccess(aId: string) { this.accessToUpdate.emit(aId); } } From 7056b2b9923bfcfa2e0a45853abfe2d7938af651 Mon Sep 17 00:00:00 2001 From: Thomas Kaul <4159106+dtslvr@users.noreply.github.com> Date: Thu, 2 Apr 2026 17:28:06 +0200 Subject: [PATCH 193/224] Task/refresh cryptocurrencies list 20260401 (#6647) * Update cryptocurrencies.json * Update changelog --- CHANGELOG.md | 1 + .../cryptocurrencies/cryptocurrencies.json | 252 ++++++++++++++---- 2 files changed, 201 insertions(+), 52 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 407767cac..aabb98610 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,6 +16,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Changed +- Refreshed the cryptocurrencies list - Improved the language localization for German (`de`) - Improved the language localization for Spanish (`es`) - Upgraded `countries-list` from version `3.2.2` to `3.3.0` diff --git a/apps/api/src/assets/cryptocurrencies/cryptocurrencies.json b/apps/api/src/assets/cryptocurrencies/cryptocurrencies.json index d00ded6ef..96502ca05 100644 --- a/apps/api/src/assets/cryptocurrencies/cryptocurrencies.json +++ b/apps/api/src/assets/cryptocurrencies/cryptocurrencies.json @@ -443,12 +443,14 @@ "AIAGENTAPP": "Aiagent.app", "AIAI": "All In AI", "AIAKITA": "AiAkita", + "AIAO": "AlgosOne AI Token", "AIAT": "AI Analysis Token", "AIAV": "AI AVatar", "AIB": "AdvancedInternetBlock", "AIBABYDOGE": "AIBabyDoge", "AIBB": "AiBB", "AIBCOIN": "AIBLOCK", + "AIBINANCE": "AI Binance", "AIBK": "AIB Utility Token", "AIBOT": "CherryAI", "AIBU": "AIBUZZ TOKEN", @@ -567,6 +569,7 @@ "AIX9": "AthenaX9", "AIXBT": "aixbt by Virtuals", "AIXCB": "aixCB by Virtuals", + "AIXDROP": "AIXDROP", "AIXERC": "AI-X", "AIXT": "AIXTerminal", "AJC": "AI Judge Companion", @@ -653,6 +656,7 @@ "ALLIN": "All in", "ALLMEE": "All.me", "ALLO": "Allora", + "ALLOCA": "Alloca", "ALM": "Alium Finance", "ALMAN": "Alman", "ALMANAK": "Almanak", @@ -676,6 +680,7 @@ "ALPHAAI": "Alpha AI", "ALPHABET": "Alphabet", "ALPHAC": "Alpha Coin", + "ALPHADEX": "Alpha DEX", "ALPHAF": "Alpha Fi", "ALPHAG": "Alpha Gardeners", "ALPHAPETTO": "Alpha Petto Shells", @@ -760,6 +765,7 @@ "AMX": "Amero", "AMY": "Amygws", "AMZE": "The Amaze World", + "AMZNON": "Amazon (Ondo Tokenized)", "AMZNX": "Amazon xStocks", "ANA": "Nirvana ANA", "ANAL": "AnalCoin", @@ -792,12 +798,13 @@ "ANGLE": "ANGLE", "ANGO": "Aureus Nummus Gold", "ANGRYSLERF": "ANGRYSLERF", - "ANI": "Anime Token", + "ANI": "Ani Grok Companion (anicompanion.net)", "ANIM": "Animalia", "ANIMA": "Realm Anima", "ANIME": "Animecoin", "ANIMECOIN": "Animecoin", "ANIMEONBASE": "Anime", + "ANIMETOKEN": "Anime Token (animetoken.in)", "ANITA": "Anita AI", "ANJ": "Aragon Court", "ANJI": "Anji", @@ -839,6 +846,7 @@ "ANVL": "Anvil", "ANVLV1": "Anvil v1", "ANW": "Anchor Neural World", + "ANWANG": "SAFE", "ANY": "Anyswap", "ANYONE": "ANyONe Protocol", "ANZENUSD": "Anzen Finance", @@ -1030,6 +1038,7 @@ "ARRO": "Arro Social", "ARROW": "Arrow Token", "ARRR": "Pirate Chain", + "ARSE": "ARSe", "ARSL": "Aquarius Loan", "ARSW": "ArthSwap", "ART": "LiveArt", @@ -1117,6 +1126,7 @@ "ASTONV": "Aston Villa Fan Token", "ASTR": "Astar", "ASTRA": "Astra Protocol", + "ASTRAAI": "AstraAI", "ASTRADAO": "Astra DAO", "ASTRAFER": "Astrafer", "ASTRAFERV1": "Astrafer v1", @@ -1216,11 +1226,12 @@ "AUN": "Authoreon", "AUNIT": "Aunit", "AUPC": "Authpaper", - "AUR": "AUREO", + "AUR": "Aurix", "AURA": "aura", "AURABAL": "Aura BAL", "AURAF": "Aura Finance", "AURANET": "Aura Network", + "AUREO": "AUREO", "AURO": "Aurora", "AURORA": "Aurora", "AURORAC": "Auroracoin", @@ -1277,6 +1288,7 @@ "AVINOC": "AVINOC", "AVIVE": "Avive World", "AVL": "AVL", + "AVLT": "Altura Vault Tokens", "AVM": "AVM (Atomicals)", "AVME": "AVME", "AVN": "AVNRich", @@ -1420,6 +1432,7 @@ "BABYFB": "Baby Floki Billionaire", "BABYFLOKI": "BabyFloki", "BABYFLOKIZILLA": "BabyFlokiZilla", + "BABYFROG": "Baby Frog Coin", "BABYG": "BabyGME", "BABYGME": "Baby GameStop", "BABYGOAT": "Baby Goat", @@ -1576,7 +1589,7 @@ "BAOV1": "BaoToken v1", "BAP3X": "bAP3X", "BAR": "FC Barcelona Fan Token", - "BARA": "Capybara", + "BARA": "Capybara Nation", "BARAKATUH": "Barakatuh", "BARC": "The Blu Arctic Water Company", "BARD": "Lombard", @@ -1589,7 +1602,6 @@ "BART": "BarterTrade", "BARTKRC": "BART Token", "BARY": "Bary", - "BAS": "Basis Share", "BASEAI": "BaseAI", "BASEBEAR": "BBQ", "BASECAT": "BASE CAT", @@ -1605,6 +1617,7 @@ "BASEDP": "Based Pepe", "BASEDR": "Based Rabbit", "BASEDS": "BasedSwap", + "BASEDSB": "Based Street Bets", "BASEDTURBO": "Based Turbo", "BASEDV1": "Based Money v1", "BASEHEROES": "Baseheroes", @@ -1620,6 +1633,8 @@ "BASIL": "Basilisk", "BASIS": "Basis", "BASISCOIN": "Basis Coin", + "BASISSHAREV1": "Basis Share", + "BASISSHAREV2": "Basis Share", "BASK": "BasketDAO", "BAST": "Bast", "BASTET": "Bastet Goddess", @@ -1684,6 +1699,7 @@ "BCA": "Bitcoin Atom", "BCAC": "Business Credit Alliance Chain", "BCAI": "Bright Crypto Ai", + "BCAK": "BCAK", "BCAP": "Blockchain Capital", "BCAPV1": "Blockchain Capital v1", "BCAT": "BitClave", @@ -1740,6 +1756,7 @@ "BCZERO": "Buggyra Coin Zero", "BD": "BlastDEX", "BD20": "BRC-20 DEX", + "BDAG": "BlockDAG", "BDAY": "Birthday Cake", "BDB": "Big Data Block", "BDC": "BILLION•DOLLAR•CAT", @@ -1983,6 +2000,7 @@ "BIGSB": "BigShortBets", "BIGTIME": "Big Time", "BIGTOWN": "Burp", + "BIGTROUT": "The Big Trout", "BIGUP": "BigUp", "BIH": "BitHostCoin", "BIHU": "Key", @@ -1998,6 +2016,8 @@ "BIN": "Binemon", "BINA": "Binance Mascort Dog", "BINAN": "Binance Mascot", + "BINANCEAI": "Binance AI", + "BINANCEAIPRO": "Binance Ai Pro", "BINANCED": "BinanceDog On Sol", "BINANCEDOG": "Binancedog", "BINANCIENS": "Binanciens", @@ -2106,6 +2126,7 @@ "BITUSD": "bitUSD", "BITV": "Bitvolt", "BITVOLT": "BitVolt", + "BITWHITE": "BitWhite", "BITWORLD": "Bit World Token", "BITX": "BitScreener", "BITXOXO": "Bitxoxo", @@ -2492,7 +2513,8 @@ "BOOKIE": "BookieBot", "BOOKO": "Book of Pets", "BOOKOF": "BOOK OF NOTHING", - "BOOM": "Boomco", + "BOOM": "Boom", + "BOOMCO": "BOOM", "BOOMCOIN": "Boom Token", "BOOMDAO": "BOOM DAO", "BOOMER": "Boomer", @@ -2530,6 +2552,7 @@ "BOSSBABY": "BossBaby", "BOSSBURGER": "Boss Burger", "BOSSCOQ": "THE COQFATHER", + "BOSSIE": "BOSSIE", "BOST": "BoostCoin", "BOSU": "Bosu Inu", "BOT": "HyperBot", @@ -2718,7 +2741,7 @@ "BSAFU": "BlockSAFU", "BSAI": "Bitcoin Silver AI", "BSATOSHI": "BabySatoshi", - "BSB": "Based Street Bets", + "BSB": "Block Street", "BSC": "BSC Layer", "BSCAKE": "Bunscake", "BSCBURN": "BSCBURN", @@ -2888,9 +2911,10 @@ "BTTY": "Bitcointry Token", "BTU": "BTU Protocol", "BTV": "Bitvote", - "BTW": "BitWhite", + "BTW": "Bitway", "BTX": "Bitradex Token", "BTXC": "Bettex coin", + "BTXEX": "BTXEX", "BTY": "Bityuan", "BTYC": "BigTycoon", "BTZ": "BitzCoin", @@ -3110,6 +3134,7 @@ "CAL": "FitBurn", "CALC": "CaliphCoin", "CALCI": "Calcium", + "CALCIFY": "CalcifyTech", "CALI": "CaliCoin", "CALL": "Global Crypto Alliance", "CALLISTO": "Callisto Network", @@ -3151,6 +3176,7 @@ "CAPY": "Capybara", "CAPYBARA": "Capybara", "CAPYBARA1995": "Capybara", + "CAPYBARACOIN": "Capybara", "CAR": "Central African Republic Meme", "CARAT": "AlaskaGoldRush", "CARATSTOKEN": "Carats Token", @@ -3507,6 +3533,7 @@ "CHH": "Chihuahua Token", "CHI": "Chi Gastoken", "CHIB": "Chiba Inu", + "CHIBI": "Chibification", "CHICA": "CHICA", "CHICKS": "SolChicks", "CHIDO": "Chinese Doge Wow", @@ -3771,6 +3798,7 @@ "COBE": "Castle of Blackwater", "COBY": "Coby", "COC": "Coin of the champions", + "COCA": "COCA", "COCAINE": "THE GOOD STUFF", "COCK": "Shibacock", "COCO": "coco", @@ -4027,6 +4055,7 @@ "CRBRUS": "Cerberus", "CRC": "CryCash", "CRCL": "Circle", + "CRCLON": "Circle Internet Group (Ondo Tokenized)", "CRCLX": "Circle xStock", "CRD": "CRD Network", "CRDC": "Cardiocoin", @@ -4111,6 +4140,7 @@ "CRTAI": "CRT AI Network", "CRTB": "Coritiba F.C. Fan Token", "CRTM": "Cryptum", + "CRTR": "CREATOR", "CRTS": "Cratos", "CRU": "Crust Network", "CRUD": "CRUDE OIL BRENT", @@ -4135,6 +4165,7 @@ "CRYPT": "CryptCoin", "CRYPTAL": "CrypTalk", "CRYPTER": "Crypteriumcoin", + "CRYPTO": "Cryptocurrency Coin", "CRYPTOA": "CryptoAI", "CRYPTOAGENT": "CRYPTO AGENT TRUMP", "CRYPTOAI": "CryptoAI", @@ -4345,11 +4376,12 @@ "CYBONK": "CYBONK", "CYBR": "CYBR", "CYBRO": "Cybro Token", - "CYC": "Cyclone Protocol", + "CYC": "Cycle Network Token", "CYCAT": "Chi Yamada Cat", "CYCE": "Crypto Carbon Energy", "CYCEV1": "Crypto Carbon Energy v1", "CYCLE": "Cycle Finance", + "CYCLONEPROTOCOL": "Cyclone Protocol", "CYCLUB": "Cyclub", "CYCON": "CONUN", "CYDER": "Cyder Coin", @@ -4369,6 +4401,7 @@ "CYS": "Cysic", "CYT": "Cryptokenz", "CZ": "CHANGPENG ZHAO (changpengzhao.club)", + "CZAI": "CZ AI Agent", "CZBOOK": "CZ BOOK", "CZBROCCOLI": "Cz Broccoli", "CZC": "Crazy Coin", @@ -4401,7 +4434,8 @@ "DACS": "Dacsee", "DACXI": "Dacxi", "DAD": "DAD", - "DADA": "DADA", + "DADA": "DADACOIN", + "DADACOINTOP": "DADA", "DADDY": "Daddy Tate", "DADDYCHILL": "Daddy Chill", "DADDYDOGE": "Daddy Doge", @@ -4857,7 +4891,8 @@ "DILIGENT": "Diligent Pepe", "DILL": "dillwifit", "DIM": "DIMCOIN", - "DIME": "DimeCoin", + "DIME": "DIME", + "DIMECOIN": "DimeCoin", "DIMO": "DIMO", "DIN": "DIN", "DINE": "Dinero", @@ -4886,6 +4921,7 @@ "DISCOVERY": "DiscoveryIoT", "DISK": "Dark Lisk", "DISPEPE": "Disabled Pepe", + "DISTORTED": "Distorted Face", "DISTR": "Distributed Autonomous Organization", "DISTRIBUTE": "DISTRIBUTE", "DIT": "Ditcoin", @@ -5325,7 +5361,8 @@ "DUCKIES": "Yellow Duckies", "DUCKO": "Duck Off Coin", "DUCKV1": "UNITPROV1", - "DUCKY": "Ducky Duck", + "DUCKY": "Ducky", + "DUCKY0X71": "Ducky Duck", "DUCX": "DucatusX", "DUDE": "DuDe", "DUEL": "GameGPT", @@ -5493,6 +5530,7 @@ "ECHOD": "EchoDEX", "ECHT": "e-Chat", "ECI": "Euro Cup Inu", + "ECKODAO": "eckoDAO", "ECL": "ECLAT", "ECLD": "Ethernity Cloud", "ECLIP": "Eclipse Fi", @@ -5891,7 +5929,8 @@ "ESN": "Ethersocial", "ESNC": "Galaxy Arena Metaverse", "ESOL": "Earn Solana", - "ESP": "Espers", + "ESP": "Espresso", + "ESPERS": "Espers", "ESPL": "ESPL ARENA", "ESPORTS": "Yooldo Games", "ESPR": "Espresso Bot", @@ -6250,7 +6289,7 @@ "FCT": "FirmaChain", "FCTC": "FaucetCoin", "FCTR": "FactorDAO", - "FDC": "Fidance", + "FDC": "FDrive Coin", "FDGC": "FINTECH DIGITAL GOLD COIN", "FDLS": "FIDELIS", "FDM": "Fandom", @@ -6323,6 +6362,7 @@ "FIC": "Filecash", "FID": "Fidira", "FIDA": "Bonfida", + "FIDANCE": "Fidance", "FIDD": "Fidelity Digital Dollar", "FIDLE": "Fidlecoin", "FIDO": "FIDO", @@ -6334,6 +6374,7 @@ "FIFTY": "FIFTYONEFIFTY", "FIG": "FlowCom", "FIGH": "FIGHT FIGHT FIGHT", + "FIGHT": "FIGHT", "FIGHT2MAGA": "Fight to MAGA", "FIGHTMAGA": "FIGHT MAGA", "FIGHTPEPE": "FIGHT PEPE", @@ -6605,6 +6646,7 @@ "FORTKNOX": "Fort Knox", "FORTUNA": "Fortuna", "FORTUNE": "Fortune", + "FORU": "ForU AI", "FORWARD": "Forward Protocol", "FOTA": "Fight Of The Ages", "FOTO": "Unique Photo", @@ -6639,6 +6681,7 @@ "FR": "Freedom Reserve", "FRA": "Findora", "FRAC": "FractalCoin", + "FRACTON": "Fracton Protocol", "FRAG": "Fragmetric", "FRANK": "Frank", "FRANKLIN": "Franklin", @@ -6662,10 +6705,13 @@ "FREEDO": "Freedom", "FREEDOG": "Freedogs", "FREEDOM": "Freedom Protocol Token", + "FREEDOMOFMONEY": "Freedom of Money", "FREELA": "DecentralFree", "FREEPAVEL": "Free Pavel", "FREEROSS": "FreeRossDAO", "FREET": "FreeTrump", + "FREEWAYV1": "Freeway Token", + "FREEWAYV2": "Freeway Token", "FREL": "Freela", "FREN": "FREN", "FRENC": "Frencoin", @@ -6737,7 +6783,7 @@ "FSTC": "FastCoin", "FSTR": "Fourth Star", "FSW": "Falconswap", - "FT": "Fracton Protocol", + "FT": "Flying Tulip", "FTB": "Fit&Beat", "FTC": "Futurex", "FTD": "42DAO", @@ -6831,8 +6877,9 @@ "FWCL": "Legends", "FWH": "FigureWifHat", "FWOG": "Fwog", - "FWT": "Freeway Token", + "FWT": "FadeWallet Token", "FWW": "Farmers World Wood", + "FWX": "Future Warriors X", "FX": "Function X", "FXAKV": "Akiverse Governance", "FXB": "FxBox", @@ -6865,6 +6912,7 @@ "GAD": "Green App Development", "GAFA": "Gafa", "GAFI": "GameFi", + "GAG": "GAG Token", "GAGA": "Gaga", "GAI": "GraphAI", "GAIA": "Gaia Token", @@ -6909,9 +6957,10 @@ "GAMEIN": "Game Infinity", "GAMER": "GameStation", "GAMERFI": "GamerFI", - "GAMES": "Gamestarter", + "GAMES": "GAME•OF•BITCOIN", "GAMEST": "GameStop Coin", "GAMESTARS": "Game Stars", + "GAMESTARTER": "Gamestarter", "GAMESTO": "GameStop", "GAMESTOP": "GameStop", "GAMESTUMP": "GAMESTUMP", @@ -7066,6 +7115,7 @@ "GEO": "GeoCoin", "GEOD": "GEODNET", "GEODB": "GeoDB", + "GEODE": "Geode Chain", "GEOJ": "Geojam", "GEOL": "GeoLeaf", "GEON": "Geon", @@ -7081,6 +7131,7 @@ "GETA": "Getaverse", "GETH": "Guarded Ether", "GETLIT": "LIT", + "GETRICHQUICK": "GET RICH QUICK", "GETX": "Guaranteed Ethurance Token Extra", "GEX": "Gexan", "GEZY": "EZZY GAME GEZY", @@ -7420,7 +7471,7 @@ "GOW39": "God Of Wealth", "GOYOO": "GoYoo", "GOZ": "Göztepe S.K. Fan Token", - "GP": "Wizards And Dragons", + "GP": "Graphite", "GPAWS": "Golden Paws", "GPBP": "Genius Playboy Billionaire Philanthropist", "GPCX": "Good Person Coin", @@ -7428,11 +7479,13 @@ "GPKR": "Gold Poker", "GPL": "Gold Pressed Latinum", "GPLX": "Gplx", + "GPM": "GOLD PUMP MEME", "GPN": "Gamepass Network", "GPO": "GoldPesa Option", "GPPT": "Pluto Project Coin", "GPRO": "GoldPro", "GPS": "GoPlus Security", + "GPST": "GPStarter", "GPSTOKEN": "GPS Token", "GPT": "QnA3.AI", "GPT4O": "GPT-4o", @@ -7456,7 +7509,8 @@ "GRAM": "Gram", "GRAND": "Grand Theft Ape", "GRANDCOIN": "GrandCoin", - "GRANDMA": "Grandma", + "GRANDMA": "Minecraft Grandma Fund", + "GRANDMASOL": "Grandma", "GRANT": "GrantiX Token", "GRAPE": "GrapeCoin", "GRAPHGRAIAI": "GraphGrail AI", @@ -7682,10 +7736,12 @@ "HAC": "Hackspace Capital", "HACD": "Hacash Diamond", "HACH": "Hachiko", - "HACHI": "Hachi", + "HACHI": "Hachiko", "HACHIK": "Hachiko", "HACHIKO": "Hachiko Inu Token", + "HACHIKOINU": "Hachiko Inu", "HACHIONB": "Hachi On Base", + "HACHITOKEN": "Hachi", "HACK": "HACK", "HADES": "Hades", "HAEDAL": "Haedal Protocol", @@ -7732,6 +7788,7 @@ "HAR": "Harambe Coin", "HARAM": "HARAM", "HARAMBE": "Harambe on Solana", + "HARAMBEAI": "Harambe AI Token", "HARD": "Kava Lend", "HARE": "Hare Token", "HAREPLUS": "Hare Plus", @@ -7878,6 +7935,7 @@ "HFUN": "Hypurr Fun", "HGEN": "HGEN DAO", "HGET": "Hedget", + "HGG": "Hedera Guild Game", "HGHG": "HUGHUG Coin", "HGO": "HireGo", "HGOLD": "HollyGold", @@ -7993,6 +8051,7 @@ "HNC": "Hellenic Coin", "HNCN": "Huncoin", "HND": "Hundred Finance", + "HNO": "HNO Coin", "HNS": "Handshake", "HNST": "Honest", "HNT": "Helium", @@ -8323,6 +8382,7 @@ "IDOLINU": "IDOLINU", "IDOODLES": "IDOODLES", "IDORU": "Vip2Fan", + "IDOS": "IDOS", "IDRISS": "IDRISS", "IDRT": "Rupiah Token", "IDRX": "IDRX", @@ -8465,6 +8525,7 @@ "INN": "Innova", "INNBC": "Innovative Bioresearch Coin", "INNOU": "Innou", + "INNOVAMINEX": "InnovaMinex", "INO": "Ino Coin", "INOVAI": "INOVAI", "INP": "Ionic Pocket Token", @@ -8477,6 +8538,7 @@ "INSANITY": "Insanity Coin", "INSC": "INSC (Ordinals)", "INSE": "INSECT", + "INSIGHTPROTOCOL": "Insight Protocol", "INSN": "Industry Sonic", "INSP": "Inspect", "INSPI": "InspireAI", @@ -8515,7 +8577,7 @@ "INVITE": "INVITE Token", "INVOX": "Invox Finance", "INVX": "Investx", - "INX": "Insight Protocol", + "INX": "Infinex", "INXM": "InMax", "INXT": "Internxt", "INXTOKEN": "INX Token", @@ -8643,6 +8705,7 @@ "IVIP": "iVipCoin", "IVN": "IVN Security", "IVPAY": "ivendPay", + "IVT": "ivault Token", "IVY": "IvyKoin", "IVZ": "InvisibleCoin", "IW": "iWallet", @@ -8886,6 +8949,7 @@ "JUP": "Jupiter", "JUPI": "Jupiter", "JUPSOL": "Jupiter Staked SOL", + "JUPUSD": "Jupiter USD", "JUR": "Jur", "JUS": "Just The Tip", "JUSD": "JUSD Stable Token", @@ -8970,6 +9034,7 @@ "KARA": "KarateCat", "KARAT": "KARAT Galaxy", "KARATE": "Karate Combat", + "KARATTOKEN": "Karat", "KAREN": "KarenCoin", "KARMA": "Karma", "KARMAD": "Karma DAO", @@ -8985,10 +9050,9 @@ "KASSIAHOME": "Kassia Home", "KASTA": "Kasta", "KASTER": "King Aster", - "KAT": "Karat", + "KAT": "Katana Network", "KATA": "Katana Inu", "KATANA": "Katana Finance", - "KATANANET": "Katana Network", "KATCHU": "Katchu Coin", "KATT": "Katt Daddy", "KATYCAT": "Katy Perry Fans", @@ -8998,6 +9062,7 @@ "KAWA": "Kawakami Inu", "KAWS": "Kaws", "KAYI": "Kayı", + "KAYYO": "Kayyo", "KBBB": "KILL BIG BEAUTIFUL BILL", "KBC": "Karatgold coin", "KBD": "Kyberdyne", @@ -9029,7 +9094,7 @@ "KDOE": "Kudoe", "KDOGE": "KingDoge", "KDT": "Kenyan Digital Token", - "KDX": "eckoDAO", + "KDX": "Kodexa", "KEANU": "Keanu Inu", "KEC": "KEYCO", "KED": "Klingon Empire Darsek", @@ -9114,11 +9179,15 @@ "KIMA": "Kima", "KIMBA": "The White Lion", "KIMBO": "Kimbo", - "KIMCHI": "KIMCHI.finance", + "KIMCH": "Kimchi", + "KIMCHI": "Kimchi Coin", + "KIMCHICTO": "Kimchi", + "KIMCHIFINANCE": "KIMCHI.finance", "KIMIAI": "Kimi AI Agent", - "KIN": "Kin", + "KIN": "KinToken", "KIND": "Kind Ads", "KINE": "Kine Protocol", + "KINECOSYSTEM": "Kin", "KINET": "KinetixFi", "KING": "LRT Squared", "KING93": "King93", @@ -9237,6 +9306,7 @@ "KNUT": "Knut From Zoo", "KNUXX": "Knuxx Bully of ETH", "KNW": "Knowledge", + "KNX": "KnoxNet", "KO": "Kyuzo's Friends", "KOAI": "KOI", "KOALA": "KOALA", @@ -9380,6 +9450,7 @@ "KUSH": "KushCoin", "KUSUNOKI": "Kusunoki Samurai", "KUV": "Kuverit", + "KVAI": "Kvants AI", "KVERSE": "KEEPs Coin", "KVI": "KVI Chain", "KVNT": "KVANT", @@ -9398,7 +9469,7 @@ "KXUSD": "kxUSD", "KYCC": "KYCCOIN", "KYL": "Kylin Network", - "KYO": "Kayyo", + "KYO": "Kyo", "KYOKO": "Kyoko", "KYRA": "KYRA", "KYSOL": "Kyros Restaked SOL", @@ -9571,6 +9642,7 @@ "LENARD": "Lenard", "LEND": "Aave", "LENDA": "Lenda", + "LENDFLARE": "Lend Flare Dao", "LENDS": "Lends", "LENFI": "Lenfi", "LENIN": "LeninCoin", @@ -9615,7 +9687,7 @@ "LFI": "LunaFi", "LFIT": "LFIT", "LFNTY": "Lifinity", - "LFT": "Lend Flare Dao", + "LFT": "LIFEFORM Token", "LFW": "Linked Finance World", "LGBT": "Let's Go Brandon Token", "LGBTQ": "LGBTQoin", @@ -9721,6 +9793,7 @@ "LISTEN": "Listen", "LISUSD": "lisUSD", "LIT": "Lighter", + "LITCOIN": "Litcoin", "LITE": "Lite USD", "LITEBTC": "LiteBitcoin", "LITENETT": "Litenett", @@ -9790,6 +9863,7 @@ "LNQ": "LinqAI", "LNR": "LNR", "LNRV2": "Lunar", + "LNS": "LIFE Coin", "LNT": "Lottonation", "LNX": "Lunox Token", "LOA": "League of Ancients", @@ -9798,6 +9872,7 @@ "LOAN": "Lendoit", "LOBO": "LOBO•THE•WOLF•PUP", "LOBS": "Lobstex", + "LOBSTAR": "Lobstar", "LOC": "LockTrip", "LOCAT": "LOVE CAT", "LOCC": "Low Orbit Crypto Cannon", @@ -9830,6 +9905,7 @@ "LOLLY": "Lollipop", "LOLLYBOMB": "LollyBomb", "LOLO": "Lolo", + "LOLONBSC": "LOL", "LON": "Tokenlon", "LONG": "Longdrink Finance", "LONGEVITY": "longevity", @@ -9843,8 +9919,9 @@ "LOOMV1": "Loom Network v1", "LOON": "Loon Network", "LOONG": "PlumpyDragons", - "LOOP": "LOOP", + "LOOP": "LoopNetwork", "LOOPIN": "LooPIN Network", + "LOOPMARKETS": "LOOP", "LOOPY": "Loopy", "LOOT": "LootBot", "LOOTEX": "Lootex", @@ -9988,8 +10065,9 @@ "LULU": "LULU", "LUM": "Luminous", "LUMA": "LUMA Token", - "LUMI": "LUMI Credits", + "LUMI": "LumiShare", "LUMIA": "Lumia", + "LUMICREDITS": "LUMI Credits", "LUMIO": "Solana Mascot", "LUMO": "Lumo-8B-Instruct", "LUMOS": "Lumos", @@ -10079,6 +10157,7 @@ "MABA": "Make America Based Again", "MAC": "MachineCoin", "MACHO": "macho", + "MACMINI": "Mac mini", "MACRO": "Macro Millions", "MACROPROTOCOL": "Macro Protocol", "MADA": "MilkADA", @@ -10178,6 +10257,7 @@ "MANTA": "Manta Network", "MANTI": "Mantis", "MANTLE": "Mantle", + "MANTRA": "MANTRA", "MANUSAI": "Manus AI Agent", "MANYU": "Manyu", "MANYUDOG": "MANYU", @@ -10210,10 +10290,11 @@ "MARMAJ": "marmaj", "MAROV1": "TTC PROTOCOL", "MAROV2": "Maro", - "MARS": "Mars", + "MARS": "MetaMars", "MARS4": "MARS4", "MARSC": "MarsCoin", "MARSCOIN": "MarsCoin", + "MARSERC": "Mars", "MARSH": "Unmarshal", "MARSMI": "MarsMi", "MARSO": "Marso.Tech", @@ -10544,6 +10625,7 @@ "METANIA": "METANIA V2", "METANIAV1": "METANIAGAMES", "METANO": "Metano", + "METAON": "Meta Platforms (Ondo Tokenized)", "METAPK": "Metapocket", "METAPLACE": "Metaplace", "METAQ": "MetaQ", @@ -10739,7 +10821,7 @@ "MINTYS": "MintySwap", "MINU": "Minu", "MINUTE": "MINUTE Vault (NFTX)", - "MINX": "InnovaMinex", + "MINX": "Modern Innovation Network Token", "MIO": "Miner One token", "MIODIO": "MIODIOCOIN", "MIOTA": "IOTA", @@ -10949,7 +11031,9 @@ "MOLK": "Mobilink Token", "MOLLARS": "MollarsToken", "MOLLY": "Molly", + "MOLO": "MOLO CHAIN", "MOLT": "Moltbook", + "MOLTID": "MoltID", "MOM": "Mother of Memes", "MOMA": "Mochi Market", "MOMIJI": "MAGA Momiji", @@ -10986,6 +11070,7 @@ "MONKAS": "Monkas", "MONKE": "Monkecoin", "MONKEY": "Monkey", + "MONKEYC": "Monkey Cult", "MONKEYS": "Monkeys Token", "MONKU": "Monku", "MONKY": "Wise Monkey", @@ -10998,6 +11083,7 @@ "MONST": "Monstock", "MONSTA": "Cake Monster", "MONSTE": "Monster", + "MONSTRO": "Monstro DeFi", "MONT": "Monarch Token", "MONTE": "Monte", "MOO": "MooMonster", @@ -11027,6 +11113,7 @@ "MOOND": "Dark Moon", "MOONDAY": "Moonday Finance", "MOONDO": "MOON DOGE", + "MOONDOG": "MOONDOGE", "MOONDOGE": "MOONDOGE", "MOONED": "MoonEdge", "MOONER": "CoinMooner", @@ -11077,6 +11164,7 @@ "MOUNTA": "Mountain Protocol", "MOUTAI": "Moutai", "MOV": "MovieCoin", + "MOVA": "MOVA", "MOVD": "MOVE Network", "MOVE": "Movement", "MOVER": "Mover", @@ -11107,6 +11195,7 @@ "MPLUS": "M+Plus", "MPLX": "Metaplex", "MPM": "Monopoly Meta", + "MPP": "MegPrime Token", "MPRO": "MediumProject", "MPS": "Mt Pelerin Shares", "MPT": "Miracleplay Token", @@ -11177,6 +11266,7 @@ "MSTAR": "MerlinStarter", "MSTETH": "Eigenpie mstETH", "MSTO": "Millennium Sapphire", + "MSTRON": "MicroStrategy (Ondo Tokenized)", "MSTRX": "MicroStrategy xStock", "MSU": "MetaSoccer", "MSUSHI": "Sushi (Multichain)", @@ -11264,6 +11354,7 @@ "MUON": "Micron Technology (Ondo Tokenized)", "MURA": "Murasaki", "MURATIAI": "MuratiAI", + "MUSA": "Mansa AI", "MUSCAT": "MusCat", "MUSD": "MetaMask USD", "MUSDC": "USD Coin (Multichain)", @@ -11662,6 +11753,7 @@ "NIC": "NewInvestCoin", "NICE": "Nice", "NICEC": "NiceCoin", + "NICKELS": "Nickel", "NIETZSCHEAN": "Nietzschean Penguin", "NIF": "Unifty", "NIFT": "Niftify", @@ -11762,6 +11854,7 @@ "NOHAT": "DogWifNoHat", "NOIA": "Syntropy", "NOICE": "noice", + "NOIRSHARES": "NoirShares", "NOIS": "Nois Network", "NOIZ": "NOIZ", "NOKA": "Noka Solana AI", @@ -11835,7 +11928,7 @@ "NRN": "Neuron", "NRO": "Neuro", "NRP": "Neural Protocol", - "NRS": "NoirShares", + "NRS": "Nereus", "NRV": "Nerve Finance", "NRVE": "Narrative", "NRX": "Neironix", @@ -12033,6 +12126,8 @@ "ODDZ": "Oddz", "ODE": "ODEM", "ODGN": "OrdiGen", + "ODIC": "ODIC Token", + "ODIK": "ODIK", "ODIN": "Odin Protocol", "ODMC": "ODMCoin", "ODN": "Obsidian", @@ -12221,12 +12316,15 @@ "OPENCHAT": "OpenChat", "OPENCUSTODY": "Open Custody Protocol", "OPENDAO": "OpenDAO", + "OPENECO": "OPEN Ticketing Ecosystem", + "OPENECOV1": "GET Protocol", "OPENGO": "OPEN Governance Token", "OPENON": "Opendoor Technologies (Ondo Tokenized)", "OPENP": "Open Platform", "OPENRI": "Open Rights Exchange", "OPENSOURCE": "Open Source Network", "OPENSWAP": "OpenSwap Optimism Token", + "OPENV": "OpenVPP", "OPENVC": "OpenVoiceCoin", "OPENW": "OpenWorld", "OPENX": "OpenxAI", @@ -12240,9 +12338,8 @@ "OPINU": "Optimus Inu", "OPIUM": "Opium", "OPMND": "Open Mind Network", - "OPN": "OPEN Ticketing Ecosystem", + "OPN": "OPINION", "OPNN": "Opennity", - "OPNV1": "GET Protocol", "OPP": "Opporty", "OPS": "Octopus Protocol", "OPSC": "OpenSourceCoin", @@ -12482,6 +12579,7 @@ "PANGEA": "PANGEA", "PANIC": "PanicSwap", "PANO": "PanoVerse", + "PANTH": "Panther AI", "PANTHER": "Panther Protocol", "PANTOS": "Pantos", "PAO": "South Pao", @@ -12628,7 +12726,7 @@ "PEAN": "Peanut the Squirrel (peanut-token.xyz)", "PEANIE": "Peanie", "PEANU": "PEANUT INU", - "PEANUT": "#1 Tiktok Squirrel", + "PEANUT": "Peanut", "PEAQ": "peaq", "PEAR": "Pear Swap", "PEARL": "Pearl Finance", @@ -12682,9 +12780,11 @@ "PENGYX": "PengyX", "PENIS": "PenisGrow", "PENJ": "Penjamin Blinkerton", + "PENNIES": "Penny", "PENP": "Penpie", "PENR": "Penrose Finance", "PENTA": "Penta", + "PENTAG": "Pentagon", "PEON": "Peon", "PEOPLE": "ConstitutionDAO", "PEOPLEFB": "PEOPLE", @@ -12740,6 +12840,7 @@ "PEPEPI": "PEPEPi", "PEPER": "Baby Pepe", "PEPERA": "PEPERA", + "PEPESDOG": "Pepes Dog", "PEPESOL": "PEPE SOL", "PEPESOLCTO": "Pepe (pepesolcto.vip)", "PEPESORA": "Pepe Sora AI", @@ -12784,6 +12885,7 @@ "PESOBIT": "PesoBit", "PESTO": "Pesto the Baby King Penguin", "PET": "Hello Pets", + "PETAH": "ピータさん", "PETE": "PETE", "PETERTODD": "Peter Todd", "PETF": "PEPE ETF", @@ -12899,6 +13001,7 @@ "PIKE": "Pike Token", "PIKO": "Pinnako", "PIKZ": "PIKZ", + "PILL": "life changing pill", "PILLAR": "PillarFi", "PILOT": "Unipilot", "PIM": "PIM", @@ -12929,6 +13032,7 @@ "PIPO": "Pipo", "PIPONHL": "PiP", "PIPPIN": "pippin", + "PIPPKIN": "Pippkin The Horse", "PIPT": "Power Index Pool Token", "PIRATE": "Pirate Nation", "PIRATECASH": "PirateCash", @@ -13070,6 +13174,7 @@ "PMR": "Pomerium Utility Token", "PMT": "Public Masterpiece Token", "PMTN": "Peer Mountain", + "PMUSD": "Precious Metals USD", "PMX": "Phillip Morris xStock", "PNB": "Pink BNB", "PNC": "PlatiniumCoin", @@ -13440,8 +13545,9 @@ "PUMPTRUMP": "PUMP TRUMP", "PUMPY": "WOW MOON LAMBO PUMPPPPPPY", "PUN": "Punkko", - "PUNCH": "PUNCHWORD", + "PUNCH": "パンチ (Punch) (punchonsolana.fun)", "PUNCHI": "Punchimals", + "PUNCHWORD": "PUNCHWORD (punchword.com)", "PUNDIAI": "Pundi AI", "PUNDIX": "Pundi X", "PUNDU": "Pundu", @@ -13450,7 +13556,7 @@ "PUNK": "PunkCity", "PUNKAI": "PunkAI", "PUNKV": "Punk Vault (NFTX)", - "PUP": "Puppy Coin", + "PUP": "PUP", "PUPA": "PupaCoin", "PUPPER": "Pupper", "PUPPET": "Puppet", @@ -13596,6 +13702,7 @@ "QQBC": "QQBC IPFS BLOCKCHAIN", "QQQ": "Poseidon Network", "QQQF": "Standard Crypto Fund", + "QQQON": "Invesco QQQ (Ondo Tokenized)", "QQQX": "Nasdaq xStock", "QR": "Qrolli", "QRK": "QuarkCoin", @@ -13670,6 +13777,7 @@ "QWT": "QoWatt", "QXC": "QuantumXC", "R1": "Recast1", + "R2": "R2", "R2R": "CitiOs", "R34P": "R34P", "R3FI": "r3fi.finance", @@ -13708,6 +13816,7 @@ "RAILS": "Rails Token", "RAIN": "Rain", "RAINBOW": "Rainbow Token", + "RAINBOWTOKEN": "Rainbow Token", "RAINC": "RainCheck", "RAINCO": "Rain Coin", "RAINI": "Rainicorn", @@ -13780,7 +13889,7 @@ "RBXDEFI": "RBX", "RBXS": "RBXSamurai", "RBY": "RubyCoin", - "RC": "Russiacoin", + "RC": "Rebel Cars", "RC20": "RoboCalls", "RCADE": "RCADE", "RCC": "Reality Clash", @@ -13880,6 +13989,7 @@ "REFUND": "Refund", "REG": "RealToken Ecosystem Governance", "REGALCOIN": "Regalcoin", + "REGARISK": "REGA Risk Sharing Token", "REGE": "Regent of the North Winds", "REGEN": "Regen Network", "REGENT": "REGENT COIN", @@ -13943,7 +14053,8 @@ "RETH": "Rocket Pool ETH", "RETH2": "rETH2", "RETIK": "Retik Finance", - "RETIRE": "Retire Token", + "RETIRE": "The Last Play", + "RETIRETOKEN": "Retire Token", "RETSA": "Retsa Coin", "REU": "REUCOIN", "REUNI": "Reunit Wallet", @@ -13996,6 +14107,7 @@ "RHOC": "RChain", "RHP": "Rhypton Club", "RHUB": "ROLLHUB", + "RHYPURR": "rHYPURR", "RIA": "aRIA Currency", "RIB": "Ribus", "RIBB": "Ribbit", @@ -14004,7 +14116,7 @@ "RICE": "RICE AI", "RICECOIN": "RiceCoin", "RICEFARM": "RiceFarm", - "RICH": "GET RICH QUICK", + "RICH": "Ostrich", "RICHCOIN": "RICHCOIN", "RICHIE": "Richie2.0", "RICHIEV1": "Richie", @@ -14096,7 +14208,7 @@ "RMV": "Reality Metaverse", "RNAPEPE": "RNA PEPE", "RNB": "Rentible", - "RNBW": "Rainbow Token", + "RNBW": "Rainbow", "RNC": "ReturnCoin", "RND": "The RandomDAO", "RNDR": "Render Token", @@ -14110,15 +14222,16 @@ "ROA": "ROA CORE", "ROAD": "ROAD", "ROAM": "Roam Token", - "ROAR": "Alpha DEX", + "ROAR": "Roaring Kitty", "ROARINGCAT": "Roaring Kitty", "ROB": "ROB", "ROBET": "RoBet", "ROBI": "Robin Rug", "ROBIN": "Robin of Da Hood", "ROBINH": "ROBIN HOOD", - "ROBO": "RoboHero", + "ROBO": "Robo Token", "ROBOCOIN": "First Bitcoin ATM", + "ROBOHERO": "RoboHero", "ROBOTA": "TAXI", "ROBOTAXI": "ROBOTAXI", "ROC": "Rasputin Online Coin", @@ -14176,6 +14289,7 @@ "ROSX": "Roseon", "ROT": "Rotten", "ROTTY": "ROTTYCOIN", + "ROU": "ROUTINE COIN", "ROUGE": "Rouge Studio", "ROUND": "RoundCoin", "ROUP": "Roup (Ordinals)", @@ -14227,7 +14341,7 @@ "RSRV": "Reserve", "RSRV1": "Reserve Rights v1", "RSS3": "RSS3", - "RST": "REGA Risk Sharing Token", + "RST": "Runesoul", "RSTK": "Restake Finance", "RSUN": "RisingSun", "RSUSHI": "Sushi (Rainbow Bridge)", @@ -14244,6 +14358,7 @@ "RTH": "Rotharium", "RTK": "RetaFi", "RTM": "Raptoreum", + "RTP": "Return to Player", "RTR": "Restore The Republic", "RTT": "Restore Truth Token", "RTX": "RateX", @@ -14283,6 +14398,7 @@ "RUSH": "RUSH COIN", "RUSHCMC": "RUSHCMC", "RUSSELL": "Russell", + "RUSSIACOIN": "Russiacoin", "RUST": "RustCoin", "RUSTBITS": "Rustbits", "RUTH": "RUTH", @@ -14332,7 +14448,7 @@ "RYOSHI": "Ryoshis Vision", "RYS": "RefundYourSOL", "RYT": "Real Yield Token", - "RYU": "The Blue Dragon", + "RYU": "RyuJin", "RYZ": "Anryze", "RZR": "Rezor", "RZTO": "RZTO Token", @@ -14611,7 +14727,7 @@ "SECT": "SECTBOT", "SECTO": "Sector Finance", "SEDA": "SEDA Protocol", - "SEED": "Superbloom", + "SEED": "SEED", "SEEDS": "SeedShares", "SEEDV": "Seed Venture", "SEEDX": "SEEDx", @@ -14739,6 +14855,7 @@ "SHAMAN": "Shaman King Inu", "SHAN": "Shanum", "SHANG": "Shanghai Inu", + "SHAPE": "Shape", "SHAR": "Shark Cat", "SHARBI": "SHARBI", "SHARDS": "WorldShards", @@ -14931,7 +15048,8 @@ "SILV": "Silver Surfer Solana", "SILV2": "Escrowed Illuvium 2", "SILVA": "Silva Token", - "SILVER": "SILVER", + "SILVER": "silver coin", + "SILVERETHCLUB": "SILVER (silvereth.club)", "SILVERKRC": "Silver KRC-20", "SILVERNOV": "Silvernova Token", "SILVERSTAND": "Silver Standard", @@ -15155,6 +15273,7 @@ "SMURFCATSOL": "Real Smurf Cat", "SMX": "Snapmuse.io", "SN": "SpaceN", + "SN3": "Supernova Nebula3", "SNA": "SUKUYANA", "SNAC": "SnackboxAI", "SNACK": "Crypto Snack", @@ -15279,6 +15398,7 @@ "SOLAREU": "Solareum", "SOLARFARM": "SolarFarm", "SOLARIX": "SOLARIX", + "SOLARX": "SolarX", "SOLAV": "SOLAV TOKEN", "SOLBANK": "Solbank", "SOLBET": "SOL STREET BETS", @@ -15287,7 +15407,8 @@ "SOLBULL": "SOLBULL", "SOLC": "SolCard", "SOLCASH": "SOLCash", - "SOLCAT": "SOLCAT", + "SOLCAT": "CatSolHat", + "SOLCATMEME": "SOLCAT", "SOLCEX": "SolCex", "SOLCHICKSSHARDS": "SolChicks Shards", "SOLE": "SoleCoin", @@ -15336,7 +15457,7 @@ "SOLVE": "SOLVE", "SOLVEX": "SOLVEX", "SOLWIF": "Solwif", - "SOLX": "SolarX", + "SOLX": "Solaxy", "SOLXD": "Solxdex", "SOLY": "Solamander", "SOLYMPICS": "Solympics", @@ -15736,8 +15857,8 @@ "STOGE": "Stoner Doge Finance", "STOIC": "stoicDAO", "STON": "STON", - "STONE": "Stone Token", "STONEDE": "Stone DeFi", + "STONETOKEN": "Stone Token", "STONK": "STONK", "STONKS": "STONKS", "STOP": "LETSTOP", @@ -15850,6 +15971,7 @@ "SUMMIT": "Summit", "SUMMITTHE": "SUMMIT", "SUMO": "Sumokoin", + "SUMR": "SummerToken", "SUN": "Sun Token", "SUNC": "Sunrise", "SUNCAT": "Suncat", @@ -15904,6 +16026,7 @@ "SUSDA": "sUSDa", "SUSDE": "Ethena Staked USDe", "SUSDS": "Savings USDS", + "SUSDT": "SkyTrade Pro", "SUSDX": "Staked USDX", "SUSHI": "Sushi", "SUSX": "Savings USX", @@ -16095,6 +16218,7 @@ "TAP": "TAP FANTASY", "TAPC": "Tap Coin", "TAPCOIN": "TAP FANTASY", + "TAPP": "TAPP", "TAPPINGCOIN": "TappingCoin", "TAPROOT": "Taproot Exchange", "TAPS": "TapSwap", @@ -16225,6 +16349,7 @@ "TEMP": "Tempus", "TEMPLE": "TempleDAO", "TEN": "TEN", + "TENCENTAI": "Tencent AI", "TEND": "Tendies", "TENDIE": "TendieSwap", "TENET": "TENET", @@ -16259,6 +16384,7 @@ "TESOURO": "Etherfuse TESOURO", "TEST": "Test", "TESTA": "Testa", + "TESTICLE": "Testicle", "TET": "Tectum", "TETH": "Treehouse ETH", "TETHYS": "Tethys", @@ -16298,6 +16424,7 @@ "THEAICOIN": "AI", "THEB": "The Boys Club", "THEBLOX": "The Blox Project", + "THEBLUEDRAGON": "The Blue Dragon", "THEC": "The CocktailBar", "THECA": "Theca", "THECAT": "THECAT", @@ -16327,6 +16454,7 @@ "THETAN": "Thetan Coin", "THETRANSFERTOKEN": "The Transfer Token", "THETRIBE": "The Tribe", + "THEWHALE": "The Whale killer", "THEX": "Thore Exchange", "THG": "Thetan Arena", "THIK": "ThikDik", @@ -16384,6 +16512,7 @@ "TIKI": "Tiki Token", "TIKTOK": "Tiktok", "TIKTOKEN": "TikToken", + "TILECOIN": "TileCoin", "TIM": "TIMTIM GAMES", "TIME": "Chrono.tech", "TIMEFUN": "timefun", @@ -16710,6 +16839,7 @@ "TRR": "Terran Coin", "TRSCT": "Transactra Finance", "TRST": "TrustCoin", + "TRT": "TRUST AI", "TRTL": "TurtleCoin", "TRTT": "Trittium", "TRU": "TrueFi", @@ -16866,6 +16996,7 @@ "TUTC": "TUTUT COIN", "TUTELLUS": "Tutellus", "TUTTER": "Tutter", + "TUURNT": "TuurnT", "TUX": "Tux The Penguin", "TUZKI": "Tuzki", "TUZLA": "Tuzlaspor Token", @@ -17180,6 +17311,7 @@ "USDCSO": "USD Coin (Portal from Solana)", "USDCV": "USD CoinVertible", "USDD": "USDD", + "USDDD": "USDDD", "USDDV1": "USDD v1", "USDE": "Ethena USDe", "USDEBT": "USDEBT", @@ -17188,6 +17320,7 @@ "USDFL": "USDFreeLiquidity", "USDG": "Global Dollar", "USDGLOBI": "Globiance USD Stablecoin", + "USDGO": "USDGO", "USDGV1": "USDG v1", "USDGV2": "USDG", "USDH": "USDH", @@ -17212,6 +17345,7 @@ "USDS": "Sky Dollar", "USDSB": "USDSB", "USDSTABLY": "StableUSD", + "USDSUI": "USDsui", "USDT": "Tether", "USDT0": "USDT0", "USDT1": "USDT1", @@ -17314,6 +17448,7 @@ "VALENTINE": "Valentine", "VALI": "VALIMARKET", "VALID": "Validator Token", + "VALLEYDAO": "ValleyDAO Token", "VALOR": "Valor Token", "VALORBIT": "Valorbit", "VALU": "Value", @@ -17384,6 +17519,7 @@ "VEE": "BLOCKv", "VEED": "VEED", "VEEN": "LIVEEN", + "VEETOKEN": "Vee Token", "VEG": "BitVegan", "VEGA": "Vega Protocol", "VEGAS": "Vegas", @@ -17401,6 +17537,7 @@ "VELODV1": "Velodrome v1", "VELOX": "Velox", "VELOXPROJECT": "Velox", + "VELT": "VELTRIXA", "VELVET": "Velvet", "VEMP": "vEmpire DDAO", "VEN": "VeChain Old", @@ -17463,6 +17600,7 @@ "VICA": "ViCA Token", "VICE": "VICE Token", "VICEX": "ViceToken", + "VICPAY": "VICTORUM", "VICS": "RoboF", "VICT": "Victory Impact Coin", "VICTORIUM": "Victorium", @@ -17498,6 +17636,7 @@ "VIRTUALMINING": "VirtualMining Coin", "VIRTUM": "VIRTUMATE", "VIS": "Vigorus", + "VISAON": "Visa (Ondo Tokenized)", "VISIO": "Visio", "VISION": "VisionGame", "VISIONCITY": "Vision City", @@ -17868,6 +18007,7 @@ "WEFI": "WeFi", "WEGEN": "WeGen Platform", "WEGI": "Wegie", + "WEGL": "White Eagle", "WEGLD": "Wrapped EGLD", "WEHMND": "Wrapped eHMND", "WEHODL": "HODL", @@ -18081,6 +18221,7 @@ "WMXWOM": "Wombex WOM", "WNCG": "Wrapped NCG", "WND": "WonderHero", + "WNDGAME": "Wizards And Dragons", "WNDR": "Wonderman Nation", "WNE": "Winee3", "WNEAR": "Wrapped Near", @@ -18149,6 +18290,7 @@ "WORLDLIBERTYICU": "World Liberty Financial", "WORLDLIBERTYSOL": "World Liberty Financial", "WORLDOFD": "World of Defish", + "WORLDW": "World War 3", "WORM": "HealthyWorm", "WORX": "Worx", "WOS": "Wolf Of Solana", @@ -18360,6 +18502,7 @@ "XCPO": "Copico", "XCR": "Crypti", "XCRE": "Creatio", + "XCREDI": "xCREDI", "XCRX": "xCRX", "XCT": "C-Bits", "XCUR": "Curate", @@ -18443,6 +18586,7 @@ "XIL": "Xillion", "XIN": "Mixin", "XING": "Xing Xing", + "XINGXING": "星星", "XINU": "XINU", "XIO": "Blockzero Labs", "XION": "XION", @@ -18612,7 +18756,7 @@ "XT3": "Xt3ch", "XTAG": "xHashtag", "XTAL": "XTAL", - "XTC": "TileCoin", + "XTC": "Xitcoin", "XTECH": "X-TECH", "XTER": "Xterio", "XTK": "xToken", @@ -18748,6 +18892,7 @@ "YFL": "YF Link", "YFO": "YFIONE", "YFPRO": "YFPRO Finance", + "YFSX": "YFSX", "YFTE": "YFTether", "YFV": "YFValue", "YFX": "Your Futures Exchange", @@ -18952,6 +19097,7 @@ "ZFL": "Zuflo Coin", "ZFLOKI": "zkFloki", "ZFM": "ZFMCOIN", + "ZGC": "Z Generation Coin", "ZGD": "ZambesiGold", "ZGEM": "GemSwap", "ZHC": "ZHC : Zero Hour Cash", @@ -19129,11 +19275,13 @@ "分红狗头": "分红狗头", "哭哭马": "哭哭马", "安": "安", + "小龙虾": "币安小龙虾", "币安人生": "币安人生", "恶俗企鹅": "恶俗企鹅", "我踏马来了": "我踏马来了", "狗屎": "狗屎", "老子": "老子", "雪球": "雪球", - "黑马": "黑马" + "黑马": "黑马", + "龙虾": "龙虾" } From 5f232c741c7da06ed999b8cf679f0e9c58841581 Mon Sep 17 00:00:00 2001 From: Thomas Kaul <4159106+dtslvr@users.noreply.github.com> Date: Thu, 2 Apr 2026 19:45:13 +0200 Subject: [PATCH 194/224] Task/eliminate OnDestroy lifecycle hook in subscription interstitial dialog component (#6654) Eliminate OnDestroy lifecycle hook --- ...subscription-interstitial-dialog.component.ts | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) diff --git a/apps/client/src/app/components/subscription-interstitial-dialog/subscription-interstitial-dialog.component.ts b/apps/client/src/app/components/subscription-interstitial-dialog/subscription-interstitial-dialog.component.ts index 0d616b92e..d10be10bd 100644 --- a/apps/client/src/app/components/subscription-interstitial-dialog/subscription-interstitial-dialog.component.ts +++ b/apps/client/src/app/components/subscription-interstitial-dialog/subscription-interstitial-dialog.component.ts @@ -7,9 +7,11 @@ import { ChangeDetectorRef, Component, CUSTOM_ELEMENTS_SCHEMA, + DestroyRef, Inject, OnInit } from '@angular/core'; +import { takeUntilDestroyed } from '@angular/core/rxjs-interop'; import { MatButtonModule } from '@angular/material/button'; import { MAT_DIALOG_DATA, @@ -21,8 +23,8 @@ import { IonIcon } from '@ionic/angular/standalone'; import { addIcons } from 'ionicons'; import { arrowForwardOutline, checkmarkCircleOutline } from 'ionicons/icons'; import ms from 'ms'; -import { interval, Subject } from 'rxjs'; -import { take, takeUntil, tap } from 'rxjs/operators'; +import { interval } from 'rxjs'; +import { take, tap } from 'rxjs/operators'; import { SubscriptionInterstitialDialogParams } from './interfaces/interfaces'; @@ -51,11 +53,10 @@ export class GfSubscriptionInterstitialDialogComponent implements OnInit { public routerLinkPricing = publicRoutes.pricing.routerLink; public variantIndex: number; - private unsubscribeSubject = new Subject(); - public constructor( private changeDetectorRef: ChangeDetectorRef, @Inject(MAT_DIALOG_DATA) public data: SubscriptionInterstitialDialogParams, + private destroyRef: DestroyRef, public dialogRef: MatDialogRef ) { this.variantIndex = Math.floor( @@ -76,7 +77,7 @@ export class GfSubscriptionInterstitialDialogComponent implements OnInit { this.changeDetectorRef.markForCheck(); }), - takeUntil(this.unsubscribeSubject) + takeUntilDestroyed(this.destroyRef) ) .subscribe(); } @@ -84,9 +85,4 @@ export class GfSubscriptionInterstitialDialogComponent implements OnInit { public closeDialog() { this.dialogRef.close({}); } - - public ngOnDestroy() { - this.unsubscribeSubject.next(); - this.unsubscribeSubject.complete(); - } } From 6da77e6417a3f85eb6dd533c5f2ce72ad2a40c02 Mon Sep 17 00:00:00 2001 From: Thomas Kaul <4159106+dtslvr@users.noreply.github.com> Date: Thu, 2 Apr 2026 19:45:53 +0200 Subject: [PATCH 195/224] Task/eliminate OnDestroy lifecycle hook in pricing page component (#6657) Eliminate OnDestroy lifecycle hook --- .../pages/pricing/pricing-page.component.ts | 21 +++++++------------ 1 file changed, 8 insertions(+), 13 deletions(-) diff --git a/apps/client/src/app/pages/pricing/pricing-page.component.ts b/apps/client/src/app/pages/pricing/pricing-page.component.ts index 831f0809c..08c561fc8 100644 --- a/apps/client/src/app/pages/pricing/pricing-page.component.ts +++ b/apps/client/src/app/pages/pricing/pricing-page.component.ts @@ -12,9 +12,10 @@ import { ChangeDetectorRef, Component, CUSTOM_ELEMENTS_SCHEMA, - OnDestroy, + DestroyRef, OnInit } from '@angular/core'; +import { takeUntilDestroyed } from '@angular/core/rxjs-interop'; import { MatButtonModule } from '@angular/material/button'; import { MatCardModule } from '@angular/material/card'; import { MatTooltipModule } from '@angular/material/tooltip'; @@ -27,8 +28,8 @@ import { informationCircleOutline } from 'ionicons/icons'; import { StringValue } from 'ms'; -import { EMPTY, Subject } from 'rxjs'; -import { catchError, takeUntil } from 'rxjs/operators'; +import { EMPTY } from 'rxjs'; +import { catchError } from 'rxjs/operators'; @Component({ host: { class: 'page' }, @@ -46,7 +47,7 @@ import { catchError, takeUntil } from 'rxjs/operators'; styleUrls: ['./pricing-page.scss'], templateUrl: './pricing-page.html' }) -export class GfPricingPageComponent implements OnDestroy, OnInit { +export class GfPricingPageComponent implements OnInit { public baseCurrency: string; public coupon: number; public couponId: string; @@ -92,11 +93,10 @@ export class GfPricingPageComponent implements OnDestroy, OnInit { public routerLinkRegister = publicRoutes.register.routerLink; public user: User; - private unsubscribeSubject = new Subject(); - public constructor( private changeDetectorRef: ChangeDetectorRef, private dataService: DataService, + private destroyRef: DestroyRef, private notificationService: NotificationService, private userService: UserService ) { @@ -124,7 +124,7 @@ export class GfPricingPageComponent implements OnDestroy, OnInit { this.price = subscriptionOffer?.price; this.userService.stateChanged - .pipe(takeUntil(this.unsubscribeSubject)) + .pipe(takeUntilDestroyed(this.destroyRef)) .subscribe((state) => { if (state?.user) { this.user = state.user; @@ -161,15 +161,10 @@ export class GfPricingPageComponent implements OnDestroy, OnInit { return EMPTY; }), - takeUntil(this.unsubscribeSubject) + takeUntilDestroyed(this.destroyRef) ) .subscribe(({ sessionUrl }) => { window.location.href = sessionUrl; }); } - - public ngOnDestroy() { - this.unsubscribeSubject.next(); - this.unsubscribeSubject.complete(); - } } From c9499408e35cf74860d0a1f306088d980e4d54a5 Mon Sep 17 00:00:00 2001 From: Thomas Kaul <4159106+dtslvr@users.noreply.github.com> Date: Thu, 2 Apr 2026 19:46:45 +0200 Subject: [PATCH 196/224] Task/eliminate OnDestroy lifecycle hook in user account membership component (#6655) Eliminate OnDestroy lifecycle hook --- .../user-account-membership.component.ts | 29 ++++++++----------- 1 file changed, 12 insertions(+), 17 deletions(-) diff --git a/apps/client/src/app/components/user-account-membership/user-account-membership.component.ts b/apps/client/src/app/components/user-account-membership/user-account-membership.component.ts index 92fd0d590..b13a983fc 100644 --- a/apps/client/src/app/components/user-account-membership/user-account-membership.component.ts +++ b/apps/client/src/app/components/user-account-membership/user-account-membership.component.ts @@ -14,15 +14,16 @@ import { ChangeDetectionStrategy, ChangeDetectorRef, Component, - OnDestroy + DestroyRef } from '@angular/core'; +import { takeUntilDestroyed } from '@angular/core/rxjs-interop'; import { MatButtonModule } from '@angular/material/button'; import { MatCardModule } from '@angular/material/card'; import { MatSnackBar } from '@angular/material/snack-bar'; import { RouterModule } from '@angular/router'; import ms, { StringValue } from 'ms'; -import { EMPTY, Subject } from 'rxjs'; -import { catchError, takeUntil } from 'rxjs/operators'; +import { EMPTY } from 'rxjs'; +import { catchError } from 'rxjs/operators'; @Component({ changeDetection: ChangeDetectionStrategy.OnPush, @@ -38,7 +39,7 @@ import { catchError, takeUntil } from 'rxjs/operators'; styleUrls: ['./user-account-membership.scss'], templateUrl: './user-account-membership.html' }) -export class GfUserAccountMembershipComponent implements OnDestroy { +export class GfUserAccountMembershipComponent { public baseCurrency: string; public coupon: number; public couponId: string; @@ -54,11 +55,10 @@ export class GfUserAccountMembershipComponent implements OnDestroy { 'mailto:hi@ghostfol.io?Subject=Ghostfolio Premium Trial&body=Hello%0D%0DI am interested in Ghostfolio Premium. Can you please send me a coupon code to try it for some time?%0D%0DKind regards'; public user: User; - private unsubscribeSubject = new Subject(); - public constructor( private changeDetectorRef: ChangeDetectorRef, private dataService: DataService, + private destroyRef: DestroyRef, private notificationService: NotificationService, private snackBar: MatSnackBar, private userService: UserService @@ -73,7 +73,7 @@ export class GfUserAccountMembershipComponent implements OnDestroy { ); this.userService.stateChanged - .pipe(takeUntil(this.unsubscribeSubject)) + .pipe(takeUntilDestroyed(this.destroyRef)) .subscribe((state) => { if (state?.user) { this.user = state.user; @@ -118,7 +118,7 @@ export class GfUserAccountMembershipComponent implements OnDestroy { return EMPTY; }), - takeUntil(this.unsubscribeSubject) + takeUntilDestroyed(this.destroyRef) ) .subscribe(({ sessionUrl }) => { window.location.href = sessionUrl; @@ -142,7 +142,7 @@ export class GfUserAccountMembershipComponent implements OnDestroy { return EMPTY; }), - takeUntil(this.unsubscribeSubject) + takeUntilDestroyed(this.destroyRef) ) .subscribe(({ apiKey }) => { this.notificationService.alert({ @@ -180,7 +180,7 @@ export class GfUserAccountMembershipComponent implements OnDestroy { return EMPTY; }), - takeUntil(this.unsubscribeSubject) + takeUntilDestroyed(this.destroyRef) ) .subscribe(() => { const snackBarRef = this.snackBar.open( @@ -193,14 +193,14 @@ export class GfUserAccountMembershipComponent implements OnDestroy { snackBarRef .afterDismissed() - .pipe(takeUntil(this.unsubscribeSubject)) + .pipe(takeUntilDestroyed(this.destroyRef)) .subscribe(() => { window.location.reload(); }); snackBarRef .onAction() - .pipe(takeUntil(this.unsubscribeSubject)) + .pipe(takeUntilDestroyed(this.destroyRef)) .subscribe(() => { window.location.reload(); }); @@ -210,9 +210,4 @@ export class GfUserAccountMembershipComponent implements OnDestroy { title: $localize`Please enter your coupon code.` }); } - - public ngOnDestroy() { - this.unsubscribeSubject.next(); - this.unsubscribeSubject.complete(); - } } From e934cc4224a4ef8025705c2ab203db57e51ba636 Mon Sep 17 00:00:00 2001 From: Thomas Kaul <4159106+dtslvr@users.noreply.github.com> Date: Thu, 2 Apr 2026 19:49:26 +0200 Subject: [PATCH 197/224] Release 2.252.0 (#6658) --- CHANGELOG.md | 2 +- package-lock.json | 4 ++-- package.json | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index aabb98610..d3984ca7f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,7 +5,7 @@ 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 +## 2.252.0 - 2026-03-02 ### Added diff --git a/package-lock.json b/package-lock.json index 1f4295a6a..49974055d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "ghostfolio", - "version": "2.251.0", + "version": "2.252.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "ghostfolio", - "version": "2.251.0", + "version": "2.252.0", "hasInstallScript": true, "license": "AGPL-3.0", "dependencies": { diff --git a/package.json b/package.json index b7f9bc2e7..cf5787a4c 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "ghostfolio", - "version": "2.251.0", + "version": "2.252.0", "homepage": "https://ghostfol.io", "license": "AGPL-3.0", "repository": "https://github.com/ghostfolio/ghostfolio", From 3ad4428604e395a4d2b480c5763f675e044f8df5 Mon Sep 17 00:00:00 2001 From: Trevin Chow Date: Thu, 2 Apr 2026 23:49:14 -0700 Subject: [PATCH 198/224] Feature/eliminate OnDestroy lifecycle hook from markets page component (#6653) Eliminate OnDestroy lifecycle hook --- .../src/app/pages/markets/markets-page.component.ts | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/apps/client/src/app/pages/markets/markets-page.component.ts b/apps/client/src/app/pages/markets/markets-page.component.ts index 1ab97c3e0..c70cb8120 100644 --- a/apps/client/src/app/pages/markets/markets-page.component.ts +++ b/apps/client/src/app/pages/markets/markets-page.component.ts @@ -1,7 +1,6 @@ import { GfHomeMarketComponent } from '@ghostfolio/client/components/home-market/home-market.component'; -import { Component, OnDestroy } from '@angular/core'; -import { Subject } from 'rxjs'; +import { Component } from '@angular/core'; @Component({ host: { class: 'page' }, @@ -10,11 +9,4 @@ import { Subject } from 'rxjs'; styleUrls: ['./markets-page.scss'], templateUrl: './markets-page.html' }) -export class GfMarketsPageComponent implements OnDestroy { - private unsubscribeSubject = new Subject(); - - public ngOnDestroy() { - this.unsubscribeSubject.next(); - this.unsubscribeSubject.complete(); - } -} +export class GfMarketsPageComponent {} From 2d2259a0f5a942d41b7ca1a6fec14681ca56fc74 Mon Sep 17 00:00:00 2001 From: Erwin <111194281+Erwin-N@users.noreply.github.com> Date: Fri, 3 Apr 2026 08:50:58 +0200 Subject: [PATCH 199/224] Task/eliminate OnDestroy lifecycle hook from home watchlist component (#6659) Eliminate OnDestroy lifecycle hook --- .../home-watchlist.component.ts | 31 +++++++------------ 1 file changed, 12 insertions(+), 19 deletions(-) diff --git a/apps/client/src/app/components/home-watchlist/home-watchlist.component.ts b/apps/client/src/app/components/home-watchlist/home-watchlist.component.ts index 4adb4e54f..e6f366351 100644 --- a/apps/client/src/app/components/home-watchlist/home-watchlist.component.ts +++ b/apps/client/src/app/components/home-watchlist/home-watchlist.component.ts @@ -15,9 +15,10 @@ import { ChangeDetectorRef, Component, CUSTOM_ELEMENTS_SCHEMA, - OnDestroy, + DestroyRef, OnInit } from '@angular/core'; +import { takeUntilDestroyed } from '@angular/core/rxjs-interop'; import { MatButtonModule } from '@angular/material/button'; import { MatDialog } from '@angular/material/dialog'; import { ActivatedRoute, Router, RouterModule } from '@angular/router'; @@ -25,8 +26,6 @@ import { IonIcon } from '@ionic/angular/standalone'; import { addIcons } from 'ionicons'; import { addOutline } from 'ionicons/icons'; import { DeviceDetectorService } from 'ngx-device-detector'; -import { Subject } from 'rxjs'; -import { takeUntil } from 'rxjs/operators'; import { GfCreateWatchlistItemDialogComponent } from './create-watchlist-item-dialog/create-watchlist-item-dialog.component'; import { CreateWatchlistItemDialogParams } from './create-watchlist-item-dialog/interfaces/interfaces'; @@ -45,7 +44,7 @@ import { CreateWatchlistItemDialogParams } from './create-watchlist-item-dialog/ styleUrls: ['./home-watchlist.scss'], templateUrl: './home-watchlist.html' }) -export class GfHomeWatchlistComponent implements OnDestroy, OnInit { +export class GfHomeWatchlistComponent implements OnInit { public deviceType: string; public hasImpersonationId: boolean; public hasPermissionToCreateWatchlistItem: boolean; @@ -53,11 +52,10 @@ export class GfHomeWatchlistComponent implements OnDestroy, OnInit { public user: User; public watchlist: Benchmark[]; - private unsubscribeSubject = new Subject(); - public constructor( private changeDetectorRef: ChangeDetectorRef, private dataService: DataService, + private destroyRef: DestroyRef, private deviceService: DeviceDetectorService, private dialog: MatDialog, private impersonationStorageService: ImpersonationStorageService, @@ -69,13 +67,13 @@ export class GfHomeWatchlistComponent implements OnDestroy, OnInit { this.impersonationStorageService .onChangeHasImpersonation() - .pipe(takeUntil(this.unsubscribeSubject)) + .pipe(takeUntilDestroyed(this.destroyRef)) .subscribe((impersonationId) => { this.hasImpersonationId = !!impersonationId; }); this.route.queryParams - .pipe(takeUntil(this.unsubscribeSubject)) + .pipe(takeUntilDestroyed(this.destroyRef)) .subscribe((params) => { if (params['createWatchlistItemDialog']) { this.openCreateWatchlistItemDialog(); @@ -83,7 +81,7 @@ export class GfHomeWatchlistComponent implements OnDestroy, OnInit { }); this.userService.stateChanged - .pipe(takeUntil(this.unsubscribeSubject)) + .pipe(takeUntilDestroyed(this.destroyRef)) .subscribe((state) => { if (state?.user) { this.user = state.user; @@ -118,7 +116,7 @@ export class GfHomeWatchlistComponent implements OnDestroy, OnInit { }: AssetProfileIdentifier) { this.dataService .deleteWatchlistItem({ dataSource, symbol }) - .pipe(takeUntil(this.unsubscribeSubject)) + .pipe(takeUntilDestroyed(this.destroyRef)) .subscribe({ next: () => { return this.loadWatchlistData(); @@ -126,15 +124,10 @@ export class GfHomeWatchlistComponent implements OnDestroy, OnInit { }); } - public ngOnDestroy() { - this.unsubscribeSubject.next(); - this.unsubscribeSubject.complete(); - } - private loadWatchlistData() { this.dataService .fetchWatchlist() - .pipe(takeUntil(this.unsubscribeSubject)) + .pipe(takeUntilDestroyed(this.destroyRef)) .subscribe(({ watchlist }) => { this.watchlist = watchlist; @@ -145,7 +138,7 @@ export class GfHomeWatchlistComponent implements OnDestroy, OnInit { private openCreateWatchlistItemDialog() { this.userService .get() - .pipe(takeUntil(this.unsubscribeSubject)) + .pipe(takeUntilDestroyed(this.destroyRef)) .subscribe((user) => { this.user = user; @@ -163,12 +156,12 @@ export class GfHomeWatchlistComponent implements OnDestroy, OnInit { dialogRef .afterClosed() - .pipe(takeUntil(this.unsubscribeSubject)) + .pipe(takeUntilDestroyed(this.destroyRef)) .subscribe(({ dataSource, symbol } = {}) => { if (dataSource && symbol) { this.dataService .postWatchlistItem({ dataSource, symbol }) - .pipe(takeUntil(this.unsubscribeSubject)) + .pipe(takeUntilDestroyed(this.destroyRef)) .subscribe({ next: () => this.loadWatchlistData() }); From 33ff0403ea457a34983845d21743b03f1535ca7d Mon Sep 17 00:00:00 2001 From: Erwin <111194281+Erwin-N@users.noreply.github.com> Date: Fri, 3 Apr 2026 08:52:50 +0200 Subject: [PATCH 200/224] Task/eliminate OnDestroy lifecycle hook from user account settings component (#6661) Eliminate OnDestroy lifecycle hook --- .../user-account-settings.component.ts | 43 ++++++++----------- 1 file changed, 19 insertions(+), 24 deletions(-) diff --git a/apps/client/src/app/components/user-account-settings/user-account-settings.component.ts b/apps/client/src/app/components/user-account-settings/user-account-settings.component.ts index 0cf18df36..72bbfc2c6 100644 --- a/apps/client/src/app/components/user-account-settings/user-account-settings.component.ts +++ b/apps/client/src/app/components/user-account-settings/user-account-settings.component.ts @@ -18,9 +18,10 @@ import { ChangeDetectorRef, Component, CUSTOM_ELEMENTS_SCHEMA, - OnDestroy, + DestroyRef, OnInit } from '@angular/core'; +import { takeUntilDestroyed } from '@angular/core/rxjs-interop'; import { FormBuilder, FormsModule, @@ -43,8 +44,8 @@ import { format, parseISO } from 'date-fns'; import { addIcons } from 'ionicons'; import { eyeOffOutline, eyeOutline } from 'ionicons/icons'; import ms from 'ms'; -import { EMPTY, Subject, throwError } from 'rxjs'; -import { catchError, takeUntil } from 'rxjs/operators'; +import { EMPTY, throwError } from 'rxjs'; +import { catchError } from 'rxjs/operators'; @Component({ changeDetection: ChangeDetectionStrategy.OnPush, @@ -65,7 +66,7 @@ import { catchError, takeUntil } from 'rxjs/operators'; styleUrls: ['./user-account-settings.scss'], templateUrl: './user-account-settings.html' }) -export class GfUserAccountSettingsComponent implements OnDestroy, OnInit { +export class GfUserAccountSettingsComponent implements OnInit { public appearancePlaceholder = $localize`Auto`; public baseCurrency: string; public currencies: string[] = []; @@ -98,11 +99,10 @@ export class GfUserAccountSettingsComponent implements OnDestroy, OnInit { ]; public user: User; - private unsubscribeSubject = new Subject(); - public constructor( private changeDetectorRef: ChangeDetectorRef, private dataService: DataService, + private destroyRef: DestroyRef, private formBuilder: FormBuilder, private notificationService: NotificationService, private settingsStorageService: SettingsStorageService, @@ -116,7 +116,7 @@ export class GfUserAccountSettingsComponent implements OnDestroy, OnInit { this.currencies = currencies; this.userService.stateChanged - .pipe(takeUntil(this.unsubscribeSubject)) + .pipe(takeUntilDestroyed(this.destroyRef)) .subscribe((state) => { if (state?.user) { this.user = state.user; @@ -157,11 +157,11 @@ export class GfUserAccountSettingsComponent implements OnDestroy, OnInit { public onChangeUserSetting(aKey: string, aValue: string) { this.dataService .putUserSetting({ [aKey]: aValue }) - .pipe(takeUntil(this.unsubscribeSubject)) + .pipe(takeUntilDestroyed(this.destroyRef)) .subscribe(() => { this.userService .get(true) - .pipe(takeUntil(this.unsubscribeSubject)) + .pipe(takeUntilDestroyed(this.destroyRef)) .subscribe((user) => { this.user = user; @@ -193,7 +193,7 @@ export class GfUserAccountSettingsComponent implements OnDestroy, OnInit { return EMPTY; }), - takeUntil(this.unsubscribeSubject) + takeUntilDestroyed(this.destroyRef) ) .subscribe(() => { this.userService.signOut(); @@ -209,11 +209,11 @@ export class GfUserAccountSettingsComponent implements OnDestroy, OnInit { public onExperimentalFeaturesChange(aEvent: MatSlideToggleChange) { this.dataService .putUserSetting({ isExperimentalFeatures: aEvent.checked }) - .pipe(takeUntil(this.unsubscribeSubject)) + .pipe(takeUntilDestroyed(this.destroyRef)) .subscribe(() => { this.userService .get(true) - .pipe(takeUntil(this.unsubscribeSubject)) + .pipe(takeUntilDestroyed(this.destroyRef)) .subscribe((user) => { this.user = user; @@ -225,7 +225,7 @@ export class GfUserAccountSettingsComponent implements OnDestroy, OnInit { public onExport() { this.dataService .fetchExport() - .pipe(takeUntil(this.unsubscribeSubject)) + .pipe(takeUntilDestroyed(this.destroyRef)) .subscribe((data) => { for (const activity of data.activities) { delete activity.id; @@ -245,11 +245,11 @@ export class GfUserAccountSettingsComponent implements OnDestroy, OnInit { public onRestrictedViewChange(aEvent: MatSlideToggleChange) { this.dataService .putUserSetting({ isRestrictedView: aEvent.checked }) - .pipe(takeUntil(this.unsubscribeSubject)) + .pipe(takeUntilDestroyed(this.destroyRef)) .subscribe(() => { this.userService .get(true) - .pipe(takeUntil(this.unsubscribeSubject)) + .pipe(takeUntilDestroyed(this.destroyRef)) .subscribe((user) => { this.user = user; @@ -284,11 +284,11 @@ export class GfUserAccountSettingsComponent implements OnDestroy, OnInit { public onViewModeChange(aEvent: MatSlideToggleChange) { this.dataService .putUserSetting({ viewMode: aEvent.checked === true ? 'ZEN' : 'DEFAULT' }) - .pipe(takeUntil(this.unsubscribeSubject)) + .pipe(takeUntilDestroyed(this.destroyRef)) .subscribe(() => { this.userService .get(true) - .pipe(takeUntil(this.unsubscribeSubject)) + .pipe(takeUntilDestroyed(this.destroyRef)) .subscribe((user) => { this.user = user; @@ -297,11 +297,6 @@ export class GfUserAccountSettingsComponent implements OnDestroy, OnInit { }); } - public ngOnDestroy() { - this.unsubscribeSubject.next(); - this.unsubscribeSubject.complete(); - } - private deregisterDevice() { this.webAuthnService .deregister() @@ -311,7 +306,7 @@ export class GfUserAccountSettingsComponent implements OnDestroy, OnInit { return EMPTY; }), - takeUntil(this.unsubscribeSubject) + takeUntilDestroyed(this.destroyRef) ) .subscribe(() => { this.update(); @@ -341,7 +336,7 @@ export class GfUserAccountSettingsComponent implements OnDestroy, OnInit { return error; }); }), - takeUntil(this.unsubscribeSubject) + takeUntilDestroyed(this.destroyRef) ) .subscribe({ next: () => { From ebae16c36b1e457e3339a7c27e98476cd1fc8d4a Mon Sep 17 00:00:00 2001 From: Erwin <111194281+Erwin-N@users.noreply.github.com> Date: Fri, 3 Apr 2026 08:55:14 +0200 Subject: [PATCH 201/224] Task/eliminate OnDestroy lifecycle hook from user account access component (#6660) Eliminate OnDestroy lifecycle hook --- ...reate-or-update-access-dialog.component.ts | 21 +++++---------- .../user-account-access.component.ts | 27 ++++++++----------- 2 files changed, 18 insertions(+), 30 deletions(-) diff --git a/apps/client/src/app/components/user-account-access/create-or-update-access-dialog/create-or-update-access-dialog.component.ts b/apps/client/src/app/components/user-account-access/create-or-update-access-dialog/create-or-update-access-dialog.component.ts index 5c87b2f63..a4fadeecf 100644 --- a/apps/client/src/app/components/user-account-access/create-or-update-access-dialog/create-or-update-access-dialog.component.ts +++ b/apps/client/src/app/components/user-account-access/create-or-update-access-dialog/create-or-update-access-dialog.component.ts @@ -7,10 +7,11 @@ import { ChangeDetectionStrategy, ChangeDetectorRef, Component, + DestroyRef, Inject, - OnDestroy, OnInit } from '@angular/core'; +import { takeUntilDestroyed } from '@angular/core/rxjs-interop'; import { FormBuilder, FormGroup, @@ -28,7 +29,7 @@ import { MatFormFieldModule } from '@angular/material/form-field'; import { MatInputModule } from '@angular/material/input'; import { MatSelectModule } from '@angular/material/select'; import { StatusCodes } from 'http-status-codes'; -import { EMPTY, Subject, catchError, takeUntil } from 'rxjs'; +import { EMPTY, catchError } from 'rxjs'; import { CreateOrUpdateAccessDialogParams } from './interfaces/interfaces'; @@ -48,19 +49,16 @@ import { CreateOrUpdateAccessDialogParams } from './interfaces/interfaces'; styleUrls: ['./create-or-update-access-dialog.scss'], templateUrl: 'create-or-update-access-dialog.html' }) -export class GfCreateOrUpdateAccessDialogComponent - implements OnDestroy, OnInit -{ +export class GfCreateOrUpdateAccessDialogComponent implements OnInit { public accessForm: FormGroup; public mode: 'create' | 'update'; - private unsubscribeSubject = new Subject(); - public constructor( private changeDetectorRef: ChangeDetectorRef, @Inject(MAT_DIALOG_DATA) private data: CreateOrUpdateAccessDialogParams, public dialogRef: MatDialogRef, private dataService: DataService, + private destroyRef: DestroyRef, private formBuilder: FormBuilder, private notificationService: NotificationService ) { @@ -113,11 +111,6 @@ export class GfCreateOrUpdateAccessDialogComponent } } - public ngOnDestroy() { - this.unsubscribeSubject.next(); - this.unsubscribeSubject.complete(); - } - private async createAccess() { const access: CreateAccessDto = { alias: this.accessForm.get('alias').value, @@ -144,7 +137,7 @@ export class GfCreateOrUpdateAccessDialogComponent return EMPTY; }), - takeUntil(this.unsubscribeSubject) + takeUntilDestroyed(this.destroyRef) ) .subscribe(() => { this.dialogRef.close(access); @@ -181,7 +174,7 @@ export class GfCreateOrUpdateAccessDialogComponent return EMPTY; }), - takeUntil(this.unsubscribeSubject) + takeUntilDestroyed(this.destroyRef) ) .subscribe(() => { this.dialogRef.close(access); diff --git a/apps/client/src/app/components/user-account-access/user-account-access.component.ts b/apps/client/src/app/components/user-account-access/user-account-access.component.ts index 4f744a087..4ca088775 100644 --- a/apps/client/src/app/components/user-account-access/user-account-access.component.ts +++ b/apps/client/src/app/components/user-account-access/user-account-access.component.ts @@ -13,9 +13,10 @@ import { ChangeDetectorRef, Component, CUSTOM_ELEMENTS_SCHEMA, - OnDestroy, + DestroyRef, OnInit } from '@angular/core'; +import { takeUntilDestroyed } from '@angular/core/rxjs-interop'; import { FormBuilder, ReactiveFormsModule, Validators } from '@angular/forms'; import { MatButtonModule } from '@angular/material/button'; import { MatDialog, MatDialogModule } from '@angular/material/dialog'; @@ -26,8 +27,8 @@ import { IonIcon } from '@ionic/angular/standalone'; import { addIcons } from 'ionicons'; import { addOutline, eyeOffOutline, eyeOutline } from 'ionicons/icons'; import { DeviceDetectorService } from 'ngx-device-detector'; -import { EMPTY, Subject } from 'rxjs'; -import { catchError, takeUntil } from 'rxjs/operators'; +import { EMPTY } from 'rxjs'; +import { catchError } from 'rxjs/operators'; import { GfCreateOrUpdateAccessDialogComponent } from './create-or-update-access-dialog/create-or-update-access-dialog.component'; import { CreateOrUpdateAccessDialogParams } from './create-or-update-access-dialog/interfaces/interfaces'; @@ -51,7 +52,7 @@ import { CreateOrUpdateAccessDialogParams } from './create-or-update-access-dial styleUrls: ['./user-account-access.scss'], templateUrl: './user-account-access.html' }) -export class GfUserAccountAccessComponent implements OnDestroy, OnInit { +export class GfUserAccountAccessComponent implements OnInit { public accessesGet: Access[]; public accessesGive: Access[]; public deviceType: string; @@ -64,11 +65,10 @@ export class GfUserAccountAccessComponent implements OnDestroy, OnInit { }); public user: User; - private unsubscribeSubject = new Subject(); - public constructor( private changeDetectorRef: ChangeDetectorRef, private dataService: DataService, + private destroyRef: DestroyRef, private deviceService: DeviceDetectorService, private dialog: MatDialog, private formBuilder: FormBuilder, @@ -85,7 +85,7 @@ export class GfUserAccountAccessComponent implements OnDestroy, OnInit { ); this.userService.stateChanged - .pipe(takeUntil(this.unsubscribeSubject)) + .pipe(takeUntilDestroyed(this.destroyRef)) .subscribe((state) => { if (state?.user) { this.user = state.user; @@ -110,7 +110,7 @@ export class GfUserAccountAccessComponent implements OnDestroy, OnInit { }); this.route.queryParams - .pipe(takeUntil(this.unsubscribeSubject)) + .pipe(takeUntilDestroyed(this.destroyRef)) .subscribe((params) => { if (params['createDialog']) { this.openCreateAccessDialog(); @@ -131,7 +131,7 @@ export class GfUserAccountAccessComponent implements OnDestroy, OnInit { public onDeleteAccess(aId: string) { this.dataService .deleteAccess(aId) - .pipe(takeUntil(this.unsubscribeSubject)) + .pipe(takeUntilDestroyed(this.destroyRef)) .subscribe({ next: () => { this.update(); @@ -154,7 +154,7 @@ export class GfUserAccountAccessComponent implements OnDestroy, OnInit { return EMPTY; }), - takeUntil(this.unsubscribeSubject) + takeUntilDestroyed(this.destroyRef) ) .subscribe(({ accessToken }) => { this.notificationService.alert({ @@ -179,11 +179,6 @@ export class GfUserAccountAccessComponent implements OnDestroy, OnInit { }); } - public ngOnDestroy() { - this.unsubscribeSubject.next(); - this.unsubscribeSubject.complete(); - } - private openCreateAccessDialog() { const dialogRef = this.dialog.open< GfCreateOrUpdateAccessDialogComponent, @@ -261,7 +256,7 @@ export class GfUserAccountAccessComponent implements OnDestroy, OnInit { this.dataService .fetchAccesses() - .pipe(takeUntil(this.unsubscribeSubject)) + .pipe(takeUntilDestroyed(this.destroyRef)) .subscribe((accesses) => { this.accessesGive = accesses; From 6f86505c8feb63d6bd3d8981ccb500689c476b50 Mon Sep 17 00:00:00 2001 From: Thomas Kaul <4159106+dtslvr@users.noreply.github.com> Date: Fri, 3 Apr 2026 09:41:24 +0200 Subject: [PATCH 202/224] Task/eliminate OnDestroy lifecycle hook in API page component (#6656) Eliminate OnDestroy lifecycle hook --- .../src/app/pages/api/api-page.component.ts | 28 +++++++++---------- 1 file changed, 13 insertions(+), 15 deletions(-) diff --git a/apps/client/src/app/pages/api/api-page.component.ts b/apps/client/src/app/pages/api/api-page.component.ts index 353605380..357a08bbd 100644 --- a/apps/client/src/app/pages/api/api-page.component.ts +++ b/apps/client/src/app/pages/api/api-page.component.ts @@ -14,9 +14,10 @@ import { import { CommonModule } from '@angular/common'; import { HttpClient, HttpHeaders, HttpParams } from '@angular/common/http'; -import { Component, OnInit } from '@angular/core'; +import { Component, DestroyRef, OnInit } from '@angular/core'; +import { takeUntilDestroyed } from '@angular/core/rxjs-interop'; import { format, startOfYear } from 'date-fns'; -import { map, Observable, Subject, takeUntil } from 'rxjs'; +import { map, Observable } from 'rxjs'; @Component({ host: { class: 'page' }, @@ -35,9 +36,11 @@ export class GfApiPageComponent implements OnInit { public status$: Observable; private apiKey: string; - private unsubscribeSubject = new Subject(); - public constructor(private http: HttpClient) {} + public constructor( + private destroyRef: DestroyRef, + private http: HttpClient + ) {} public ngOnInit() { this.apiKey = prompt($localize`Please enter your Ghostfolio API key:`); @@ -51,18 +54,13 @@ export class GfApiPageComponent implements OnInit { this.status$ = this.fetchStatus(); } - public ngOnDestroy() { - this.unsubscribeSubject.next(); - this.unsubscribeSubject.complete(); - } - private fetchAssetProfile({ symbol }: { symbol: string }) { return this.http .get( `/api/v1/data-providers/ghostfolio/asset-profile/${symbol}`, { headers: this.getHeaders() } ) - .pipe(takeUntil(this.unsubscribeSubject)); + .pipe(takeUntilDestroyed(this.destroyRef)); } private fetchDividends({ symbol }: { symbol: string }) { @@ -82,7 +80,7 @@ export class GfApiPageComponent implements OnInit { map(({ dividends }) => { return dividends; }), - takeUntil(this.unsubscribeSubject) + takeUntilDestroyed(this.destroyRef) ); } @@ -103,7 +101,7 @@ export class GfApiPageComponent implements OnInit { map(({ historicalData }) => { return historicalData; }), - takeUntil(this.unsubscribeSubject) + takeUntilDestroyed(this.destroyRef) ); } @@ -129,7 +127,7 @@ export class GfApiPageComponent implements OnInit { map(({ items }) => { return items; }), - takeUntil(this.unsubscribeSubject) + takeUntilDestroyed(this.destroyRef) ); } @@ -145,7 +143,7 @@ export class GfApiPageComponent implements OnInit { map(({ quotes }) => { return quotes; }), - takeUntil(this.unsubscribeSubject) + takeUntilDestroyed(this.destroyRef) ); } @@ -155,7 +153,7 @@ export class GfApiPageComponent implements OnInit { '/api/v2/data-providers/ghostfolio/status', { headers: this.getHeaders() } ) - .pipe(takeUntil(this.unsubscribeSubject)); + .pipe(takeUntilDestroyed(this.destroyRef)); } private getHeaders() { From c311d835fadc3b34713095b4ad51a3a0167e0182 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rapha=C3=ABl=20TISON?= <13355624+Airthee@users.noreply.github.com> Date: Fri, 3 Apr 2026 09:45:02 +0200 Subject: [PATCH 203/224] Feature/add type filter to activities table component (#6622) * Add type filter * Update changelog --------- Co-authored-by: Thomas Kaul <4159106+dtslvr@users.noreply.github.com> --- CHANGELOG.md | 6 + .../app/activities/activities.controller.ts | 7 +- .../src/app/activities/activities.service.ts | 2 +- apps/api/src/app/export/export.controller.ts | 5 + apps/api/src/app/export/export.service.ts | 5 +- .../activities/activities-page.component.ts | 18 ++- .../portfolio/activities/activities-page.html | 2 + .../activities-table.component.html | 134 +++++++++++------- .../activities-table.component.ts | 27 +++- libs/ui/src/lib/services/data.service.ts | 12 ++ .../migration.sql | 2 + prisma/schema.prisma | 1 + 12 files changed, 161 insertions(+), 60 deletions(-) create mode 100644 prisma/migrations/20260321200654_added_index_for_type_to_order/migration.sql diff --git a/CHANGELOG.md b/CHANGELOG.md index d3984ca7f..53461fd8f 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 + +### Added + +- Added support for filtering by activity type on the activities page (experimental) + ## 2.252.0 - 2026-03-02 ### Added diff --git a/apps/api/src/app/activities/activities.controller.ts b/apps/api/src/app/activities/activities.controller.ts index 141fd4c82..6b0440dc4 100644 --- a/apps/api/src/app/activities/activities.controller.ts +++ b/apps/api/src/app/activities/activities.controller.ts @@ -37,7 +37,7 @@ import { } from '@nestjs/common'; import { REQUEST } from '@nestjs/core'; import { AuthGuard } from '@nestjs/passport'; -import { Order, Prisma } from '@prisma/client'; +import { Order, Prisma, Type as ActivityType } from '@prisma/client'; import { parseISO } from 'date-fns'; import { StatusCodes, getReasonPhrase } from 'http-status-codes'; @@ -112,6 +112,7 @@ export class ActivitiesController { public async getAllActivities( @Headers(HEADER_KEY_IMPERSONATION.toLowerCase()) impersonationId: string, @Query('accounts') filterByAccounts?: string, + @Query('activityTypes') filterByTypes?: string, @Query('assetClasses') filterByAssetClasses?: string, @Query('dataSource') filterByDataSource?: string, @Query('range') dateRange?: DateRange, @@ -139,6 +140,9 @@ export class ActivitiesController { const impersonationUserId = await this.impersonationService.validateImpersonationId(impersonationId); + + const types = (filterByTypes?.split(',') as ActivityType[]) ?? []; + const userCurrency = this.request.user.settings.settings.baseCurrency; const { activities, count } = await this.activitiesService.getActivities({ @@ -147,6 +151,7 @@ export class ActivitiesController { sortColumn, sortDirection, startDate, + types, userCurrency, includeDrafts: true, skip: isNaN(skip) ? undefined : skip, diff --git a/apps/api/src/app/activities/activities.service.ts b/apps/api/src/app/activities/activities.service.ts index 89b9468f8..58b9c11a4 100644 --- a/apps/api/src/app/activities/activities.service.ts +++ b/apps/api/src/app/activities/activities.service.ts @@ -629,7 +629,7 @@ export class ActivitiesService { orderBy = [{ [sortColumn]: sortDirection }]; } - if (types) { + if (types?.length > 0) { where.type = { in: types }; } diff --git a/apps/api/src/app/export/export.controller.ts b/apps/api/src/app/export/export.controller.ts index 6fda8f17f..4f4f4e6dd 100644 --- a/apps/api/src/app/export/export.controller.ts +++ b/apps/api/src/app/export/export.controller.ts @@ -15,6 +15,7 @@ import { } from '@nestjs/common'; import { REQUEST } from '@nestjs/core'; import { AuthGuard } from '@nestjs/passport'; +import { Type as ActivityType } from '@prisma/client'; import { ExportService } from './export.service'; @@ -33,12 +34,15 @@ export class ExportController { public async export( @Query('accounts') filterByAccounts?: string, @Query('activityIds') filterByActivityIds?: string, + @Query('activityTypes') filterByTypes?: string, @Query('assetClasses') filterByAssetClasses?: string, @Query('dataSource') filterByDataSource?: string, @Query('symbol') filterBySymbol?: string, @Query('tags') filterByTags?: string ): Promise { const activityIds = filterByActivityIds?.split(',') ?? []; + const activityTypes = (filterByTypes?.split(',') as ActivityType[]) ?? []; + const filters = this.apiService.buildFiltersFromQueryParams({ filterByAccounts, filterByAssetClasses, @@ -49,6 +53,7 @@ export class ExportController { return this.exportService.export({ activityIds, + activityTypes, filters, userId: this.request.user.id, userSettings: this.request.user.settings.settings diff --git a/apps/api/src/app/export/export.service.ts b/apps/api/src/app/export/export.service.ts index 4f2fb3309..4da942cd7 100644 --- a/apps/api/src/app/export/export.service.ts +++ b/apps/api/src/app/export/export.service.ts @@ -10,7 +10,7 @@ import { } from '@ghostfolio/common/interfaces'; import { Injectable } from '@nestjs/common'; -import { Platform, Prisma } from '@prisma/client'; +import { Platform, Prisma, Type as ActivityType } from '@prisma/client'; import { groupBy, uniqBy } from 'lodash'; @Injectable() @@ -24,11 +24,13 @@ export class ExportService { public async export({ activityIds, + activityTypes, filters, userId, userSettings }: { activityIds?: string[]; + activityTypes?: ActivityType[]; filters?: Filter[]; userId: string; userSettings: UserSettings; @@ -44,6 +46,7 @@ export class ExportService { includeDrafts: true, sortColumn: 'date', sortDirection: 'asc', + types: activityTypes, userCurrency: userSettings?.baseCurrency, withExcludedAccountsAndActivities: true }); diff --git a/apps/client/src/app/pages/portfolio/activities/activities-page.component.ts b/apps/client/src/app/pages/portfolio/activities/activities-page.component.ts index b9dc9077c..faadef54f 100644 --- a/apps/client/src/app/pages/portfolio/activities/activities-page.component.ts +++ b/apps/client/src/app/pages/portfolio/activities/activities-page.component.ts @@ -54,6 +54,7 @@ import { ImportActivitiesDialogParams } from './import-activities-dialog/interfa templateUrl: './activities-page.html' }) export class GfActivitiesPageComponent implements OnInit { + public activityTypesFilter: string[] = []; public dataSource: MatTableDataSource; public deviceType: string; public hasImpersonationId: boolean; @@ -141,6 +142,9 @@ export class GfActivitiesPageComponent implements OnInit { this.dataService .fetchActivities({ range, + activityTypes: this.activityTypesFilter.length + ? this.activityTypesFilter + : undefined, filters: this.userService.getFilters(), skip: this.pageIndex * this.pageSize, sortColumn: this.sortColumn, @@ -217,7 +221,12 @@ export class GfActivitiesPageComponent implements OnInit { let fetchExportParams: any = { activityIds }; if (!activityIds) { - fetchExportParams = { filters: this.userService.getFilters() }; + fetchExportParams = { + activityTypes: this.activityTypesFilter.length + ? this.activityTypesFilter + : undefined, + filters: this.userService.getFilters() + }; } this.dataService @@ -318,6 +327,13 @@ export class GfActivitiesPageComponent implements OnInit { this.fetchActivities(); } + public onTypesFilterChanged(aTypes: string[]) { + this.activityTypesFilter = aTypes; + this.pageIndex = 0; + + this.fetchActivities(); + } + public onUpdateActivity(aActivity: Activity) { this.router.navigate([], { queryParams: { activityId: aActivity.id, editDialog: true } diff --git a/apps/client/src/app/pages/portfolio/activities/activities-page.html b/apps/client/src/app/pages/portfolio/activities/activities-page.html index 80ad71b79..2a72dcfd2 100644 --- a/apps/client/src/app/pages/portfolio/activities/activities-page.html +++ b/apps/client/src/app/pages/portfolio/activities/activities-page.html @@ -10,6 +10,7 @@ [hasPermissionToCreateActivity]="hasPermissionToCreateActivity" [hasPermissionToDeleteActivity]="hasPermissionToDeleteActivity" [hasPermissionToExportActivities]="!hasImpersonationId" + [hasPermissionToFilterByType]="user?.settings?.isExperimentalFeatures" [locale]="user?.settings?.locale" [pageIndex]="pageIndex" [pageSize]="pageSize" @@ -32,6 +33,7 @@ (importDividends)="onImportDividends()" (pageChanged)="onChangePage($event)" (sortChanged)="onSortChanged($event)" + (typesFilterChanged)="onTypesFilterChanged($event)" />
    diff --git a/libs/ui/src/lib/activities-table/activities-table.component.html b/libs/ui/src/lib/activities-table/activities-table.component.html index bdb1e6373..b8fe962d7 100644 --- a/libs/ui/src/lib/activities-table/activities-table.component.html +++ b/libs/ui/src/lib/activities-table/activities-table.component.html @@ -1,77 +1,101 @@ -@if (hasPermissionToCreateActivity) { -
    - - @if (hasPermissionToExportActivities) { - +
    +
    + @if (hasPermissionToFilterByType) { + + Type + + @for ( + activityType of activityTypesTranslationMap | keyvalue; + track activityType.key + ) { + + {{ activityType.value }} + + } + + } - +
    + + @if (hasPermissionToCreateActivity) { +
    @if (hasPermissionToExportActivities) { + } + + - } - @if (hasPermissionToExportActivities) { + @if (hasPermissionToExportActivities) { + + } + @if (hasPermissionToExportActivities) { + + } +
    - } -
    - -
    -
    -} + +
    + } +
    (); @Output() selectedActivities = new EventEmitter(); @Output() sortChanged = new EventEmitter(); + @Output() typesFilterChanged = new EventEmitter(); @ViewChild(MatPaginator) paginator: MatPaginator; @ViewChild(MatSort) sort: MatSort; + public activityTypesTranslationMap = new Map(); public hasDrafts = false; public hasErrors = false; public isUUID = isUUID; public selectedRows = new SelectionModel(true, []); + public typesFilter = new FormControl([]); public readonly dataSource = input.required< MatTableDataSource | undefined @@ -189,6 +201,13 @@ export class GfActivitiesTableComponent private readonly unsubscribeSubject = new Subject(); public constructor() { + for (const type of Object.keys(ActivityType) as ActivityType[]) { + this.activityTypesTranslationMap.set( + ActivityType[type], + translate(ActivityType[type]) + ); + } + addIcons({ alertCircleOutline, calendarClearOutline, @@ -214,6 +233,12 @@ export class GfActivitiesTableComponent this.selectedActivities.emit(selectedRows.source.selected); }); } + + this.typesFilter.valueChanges + .pipe(takeUntil(this.unsubscribeSubject)) + .subscribe((types) => { + this.typesFilterChanged.emit(types ?? []); + }); } public ngAfterViewInit() { diff --git a/libs/ui/src/lib/services/data.service.ts b/libs/ui/src/lib/services/data.service.ts index f3e3fb81f..7f2dac0b1 100644 --- a/libs/ui/src/lib/services/data.service.ts +++ b/libs/ui/src/lib/services/data.service.ts @@ -209,6 +209,7 @@ export class DataService { } public fetchActivities({ + activityTypes, filters, range, skip, @@ -216,6 +217,7 @@ export class DataService { sortDirection, take }: { + activityTypes?: string[]; filters?: Filter[]; range?: DateRange; skip?: number; @@ -225,6 +227,10 @@ export class DataService { }): Observable { let params = this.buildFiltersAsQueryParams({ filters }); + if (activityTypes?.length) { + params = params.append('activityTypes', activityTypes.join(',')); + } + if (range) { params = params.append('range', range); } @@ -411,9 +417,11 @@ export class DataService { public fetchExport({ activityIds, + activityTypes, filters }: { activityIds?: string[]; + activityTypes?: string[]; filters?: Filter[]; } = {}) { let params = this.buildFiltersAsQueryParams({ filters }); @@ -422,6 +430,10 @@ export class DataService { params = params.append('activityIds', activityIds.join(',')); } + if (activityTypes?.length) { + params = params.append('activityTypes', activityTypes.join(',')); + } + return this.http.get('/api/v1/export', { params }); diff --git a/prisma/migrations/20260321200654_added_index_for_type_to_order/migration.sql b/prisma/migrations/20260321200654_added_index_for_type_to_order/migration.sql new file mode 100644 index 000000000..ba4d1b1ff --- /dev/null +++ b/prisma/migrations/20260321200654_added_index_for_type_to_order/migration.sql @@ -0,0 +1,2 @@ +-- CreateIndex +CREATE INDEX "Order_type_idx" ON "Order"("type"); diff --git a/prisma/schema.prisma b/prisma/schema.prisma index 232dde9ca..50aac91fb 100644 --- a/prisma/schema.prisma +++ b/prisma/schema.prisma @@ -158,6 +158,7 @@ model Order { @@index([accountId]) @@index([date]) @@index([isDraft]) + @@index([type]) @@index([userId]) } From 1b26b6ced04b5eaa50317b087163e9dbeaf34d04 Mon Sep 17 00:00:00 2001 From: Erwin <111194281+Erwin-N@users.noreply.github.com> Date: Fri, 3 Apr 2026 16:57:19 +0200 Subject: [PATCH 204/224] Task/eliminate OnDestroy lifecycle hook from activities table page (#6672) Eliminate OnDestroy lifecycle hook --- .../activities-table.component.ts | 20 ++++++------------- 1 file changed, 6 insertions(+), 14 deletions(-) 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 4d88960b9..ffc07f09c 100644 --- a/libs/ui/src/lib/activities-table/activities-table.component.ts +++ b/libs/ui/src/lib/activities-table/activities-table.component.ts @@ -20,9 +20,9 @@ import { CUSTOM_ELEMENTS_SCHEMA, ChangeDetectionStrategy, Component, + DestroyRef, EventEmitter, Input, - OnDestroy, OnInit, Output, ViewChild, @@ -30,6 +30,7 @@ import { inject, input } from '@angular/core'; +import { takeUntilDestroyed } from '@angular/core/rxjs-interop'; import { FormControl, ReactiveFormsModule } from '@angular/forms'; import { MatButtonModule } from '@angular/material/button'; import { MatCheckboxModule } from '@angular/material/checkbox'; @@ -68,7 +69,6 @@ import { trashOutline } from 'ionicons/icons'; import { NgxSkeletonLoaderModule } from 'ngx-skeleton-loader'; -import { Subject, takeUntil } from 'rxjs'; import { GfActivityTypeComponent } from '../activity-type/activity-type.component'; import { GfEntityLogoComponent } from '../entity-logo/entity-logo.component'; @@ -102,9 +102,7 @@ import { GfValueComponent } from '../value/value.component'; styleUrls: ['./activities-table.component.scss'], templateUrl: './activities-table.component.html' }) -export class GfActivitiesTableComponent - implements AfterViewInit, OnDestroy, OnInit -{ +export class GfActivitiesTableComponent implements AfterViewInit, OnInit { @Input() baseCurrency: string; @Input() deviceType: string; @Input() hasActivities: boolean; @@ -198,9 +196,8 @@ export class GfActivitiesTableComponent }); private readonly notificationService = inject(NotificationService); - private readonly unsubscribeSubject = new Subject(); - public constructor() { + public constructor(private destroyRef: DestroyRef) { for (const type of Object.keys(ActivityType) as ActivityType[]) { this.activityTypesTranslationMap.set( ActivityType[type], @@ -228,14 +225,14 @@ export class GfActivitiesTableComponent if (this.showCheckbox()) { this.toggleAllRows(); this.selectedRows.changed - .pipe(takeUntil(this.unsubscribeSubject)) + .pipe(takeUntilDestroyed(this.destroyRef)) .subscribe((selectedRows) => { this.selectedActivities.emit(selectedRows.source.selected); }); } this.typesFilter.valueChanges - .pipe(takeUntil(this.unsubscribeSubject)) + .pipe(takeUntilDestroyed(this.destroyRef)) .subscribe((types) => { this.typesFilterChanged.emit(types ?? []); }); @@ -367,9 +364,4 @@ export class GfActivitiesTableComponent this.selectedActivities.emit(this.selectedRows.selected); } - - public ngOnDestroy() { - this.unsubscribeSubject.next(); - this.unsubscribeSubject.complete(); - } } From 875f173c34ecdec91d632389dfbeac0ae17779b3 Mon Sep 17 00:00:00 2001 From: Erwin <111194281+Erwin-N@users.noreply.github.com> Date: Fri, 3 Apr 2026 17:01:51 +0200 Subject: [PATCH 205/224] Task/eliminate OnDestroy lifecycle hook from benchmark detail dialog component (#6675) Eliminate OnDestroy lifecycle hook --- .../benchmark-detail-dialog.component.ts | 17 +++++------------ 1 file changed, 5 insertions(+), 12 deletions(-) diff --git a/libs/ui/src/lib/benchmark/benchmark-detail-dialog/benchmark-detail-dialog.component.ts b/libs/ui/src/lib/benchmark/benchmark-detail-dialog/benchmark-detail-dialog.component.ts index 2f4c18288..0c75b5954 100644 --- a/libs/ui/src/lib/benchmark/benchmark-detail-dialog/benchmark-detail-dialog.component.ts +++ b/libs/ui/src/lib/benchmark/benchmark-detail-dialog/benchmark-detail-dialog.component.ts @@ -12,18 +12,17 @@ import { ChangeDetectionStrategy, ChangeDetectorRef, Component, + DestroyRef, Inject, - OnDestroy, OnInit } from '@angular/core'; +import { takeUntilDestroyed } from '@angular/core/rxjs-interop'; import { MAT_DIALOG_DATA, MatDialogModule, MatDialogRef } from '@angular/material/dialog'; import { format } from 'date-fns'; -import { Subject } from 'rxjs'; -import { takeUntil } from 'rxjs/operators'; import { GfLineChartComponent } from '../../line-chart/line-chart.component'; import { GfValueComponent } from '../../value/value.component'; @@ -44,16 +43,15 @@ import { BenchmarkDetailDialogParams } from './interfaces/interfaces'; styleUrls: ['./benchmark-detail-dialog.component.scss'], templateUrl: 'benchmark-detail-dialog.html' }) -export class GfBenchmarkDetailDialogComponent implements OnDestroy, OnInit { +export class GfBenchmarkDetailDialogComponent implements OnInit { public assetProfile: AdminMarketDataDetails['assetProfile']; public historicalDataItems: LineChartItem[]; public value: number; - private unsubscribeSubject = new Subject(); - public constructor( private changeDetectorRef: ChangeDetectorRef, private dataService: DataService, + private destroyRef: DestroyRef, public dialogRef: MatDialogRef, @Inject(MAT_DIALOG_DATA) public data: BenchmarkDetailDialogParams ) {} @@ -64,7 +62,7 @@ export class GfBenchmarkDetailDialogComponent implements OnDestroy, OnInit { dataSource: this.data.dataSource, symbol: this.data.symbol }) - .pipe(takeUntil(this.unsubscribeSubject)) + .pipe(takeUntilDestroyed(this.destroyRef)) .subscribe(({ assetProfile, marketData }) => { this.assetProfile = assetProfile; @@ -88,9 +86,4 @@ export class GfBenchmarkDetailDialogComponent implements OnDestroy, OnInit { public onClose() { this.dialogRef.close(); } - - public ngOnDestroy() { - this.unsubscribeSubject.next(); - this.unsubscribeSubject.complete(); - } } From 2cdfeb84d6768523ea8994a31b922ace16831836 Mon Sep 17 00:00:00 2001 From: Erwin <111194281+Erwin-N@users.noreply.github.com> Date: Fri, 3 Apr 2026 17:03:26 +0200 Subject: [PATCH 206/224] Task/eliminate OnDestroy lifecycle hook from create watchlist item dialog component (#6676) Eliminate OnDestroy lifecycle hook --- .../create-watchlist-item-dialog.component.ts | 17 ++--------------- 1 file changed, 2 insertions(+), 15 deletions(-) diff --git a/apps/client/src/app/components/home-watchlist/create-watchlist-item-dialog/create-watchlist-item-dialog.component.ts b/apps/client/src/app/components/home-watchlist/create-watchlist-item-dialog/create-watchlist-item-dialog.component.ts index 60d74be92..4669a827d 100644 --- a/apps/client/src/app/components/home-watchlist/create-watchlist-item-dialog/create-watchlist-item-dialog.component.ts +++ b/apps/client/src/app/components/home-watchlist/create-watchlist-item-dialog/create-watchlist-item-dialog.component.ts @@ -1,11 +1,6 @@ import { GfSymbolAutocompleteComponent } from '@ghostfolio/ui/symbol-autocomplete'; -import { - ChangeDetectionStrategy, - Component, - OnDestroy, - OnInit -} from '@angular/core'; +import { ChangeDetectionStrategy, Component, OnInit } from '@angular/core'; import { AbstractControl, FormBuilder, @@ -19,7 +14,6 @@ import { import { MatButtonModule } from '@angular/material/button'; import { MatDialogModule, MatDialogRef } from '@angular/material/dialog'; import { MatFormFieldModule } from '@angular/material/form-field'; -import { Subject } from 'rxjs'; @Component({ changeDetection: ChangeDetectionStrategy.OnPush, @@ -36,11 +30,9 @@ import { Subject } from 'rxjs'; styleUrls: ['./create-watchlist-item-dialog.component.scss'], templateUrl: 'create-watchlist-item-dialog.html' }) -export class GfCreateWatchlistItemDialogComponent implements OnDestroy, OnInit { +export class GfCreateWatchlistItemDialogComponent implements OnInit { public createWatchlistItemForm: FormGroup; - private unsubscribeSubject = new Subject(); - public constructor( public readonly dialogRef: MatDialogRef, public readonly formBuilder: FormBuilder @@ -69,11 +61,6 @@ export class GfCreateWatchlistItemDialogComponent implements OnDestroy, OnInit { }); } - public ngOnDestroy() { - this.unsubscribeSubject.next(); - this.unsubscribeSubject.complete(); - } - private validator(control: AbstractControl): ValidationErrors { const searchSymbolControl = control.get('searchSymbol'); From 77b94b28ac2918ae71cc00272ee1acab54331f0b Mon Sep 17 00:00:00 2001 From: Thomas Kaul <4159106+dtslvr@users.noreply.github.com> Date: Fri, 3 Apr 2026 18:12:49 +0200 Subject: [PATCH 207/224] Task/eliminate OnDestroy lifecycle hook in SaaS FAQ page component (#6663) Eliminate OnDestroy lifecycle hook --- .../app/pages/faq/saas/saas-page.component.ts | 16 +++++----------- 1 file changed, 5 insertions(+), 11 deletions(-) diff --git a/apps/client/src/app/pages/faq/saas/saas-page.component.ts b/apps/client/src/app/pages/faq/saas/saas-page.component.ts index 4429fe492..0c221f047 100644 --- a/apps/client/src/app/pages/faq/saas/saas-page.component.ts +++ b/apps/client/src/app/pages/faq/saas/saas-page.component.ts @@ -7,11 +7,11 @@ import { ChangeDetectorRef, Component, CUSTOM_ELEMENTS_SCHEMA, - OnDestroy + DestroyRef } from '@angular/core'; +import { takeUntilDestroyed } from '@angular/core/rxjs-interop'; import { MatCardModule } from '@angular/material/card'; import { RouterModule } from '@angular/router'; -import { Subject, takeUntil } from 'rxjs'; @Component({ host: { class: 'page' }, @@ -21,7 +21,7 @@ import { Subject, takeUntil } from 'rxjs'; styleUrls: ['./saas-page.scss'], templateUrl: './saas-page.html' }) -export class GfSaasPageComponent implements OnDestroy { +export class GfSaasPageComponent { public pricingUrl = `https://ghostfol.io/${document.documentElement.lang}/${publicRoutes.pricing.path}`; public routerLinkAccount = internalRoutes.account.routerLink; public routerLinkAccountMembership = @@ -30,16 +30,15 @@ export class GfSaasPageComponent implements OnDestroy { public routerLinkRegister = publicRoutes.register.routerLink; public user: User; - private unsubscribeSubject = new Subject(); - public constructor( private changeDetectorRef: ChangeDetectorRef, + private destroyRef: DestroyRef, private userService: UserService ) {} public ngOnInit() { this.userService.stateChanged - .pipe(takeUntil(this.unsubscribeSubject)) + .pipe(takeUntilDestroyed(this.destroyRef)) .subscribe((state) => { if (state?.user) { this.user = state.user; @@ -48,9 +47,4 @@ export class GfSaasPageComponent implements OnDestroy { } }); } - - public ngOnDestroy() { - this.unsubscribeSubject.next(); - this.unsubscribeSubject.complete(); - } } From 8f9c31a5640130bb7c3cd4645a7bcd9906833475 Mon Sep 17 00:00:00 2001 From: Thomas Kaul <4159106+dtslvr@users.noreply.github.com> Date: Fri, 3 Apr 2026 18:13:30 +0200 Subject: [PATCH 208/224] Task/eliminate OnDestroy lifecycle hook in user detail dialog component (#6664) Eliminate OnDestroy lifecycle hook --- .../user-detail-dialog.component.ts | 19 +++++++------------ 1 file changed, 7 insertions(+), 12 deletions(-) diff --git a/apps/client/src/app/components/user-detail-dialog/user-detail-dialog.component.ts b/apps/client/src/app/components/user-detail-dialog/user-detail-dialog.component.ts index 6f7f4ead6..fec2d4b06 100644 --- a/apps/client/src/app/components/user-detail-dialog/user-detail-dialog.component.ts +++ b/apps/client/src/app/components/user-detail-dialog/user-detail-dialog.component.ts @@ -7,10 +7,11 @@ import { ChangeDetectorRef, Component, CUSTOM_ELEMENTS_SCHEMA, + DestroyRef, Inject, - OnDestroy, OnInit } from '@angular/core'; +import { takeUntilDestroyed } from '@angular/core/rxjs-interop'; import { MatButtonModule } from '@angular/material/button'; import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog'; import { MatDialogModule } from '@angular/material/dialog'; @@ -18,8 +19,8 @@ import { MatMenuModule } from '@angular/material/menu'; import { IonIcon } from '@ionic/angular/standalone'; import { addIcons } from 'ionicons'; import { ellipsisVertical } from 'ionicons/icons'; -import { EMPTY, Subject } from 'rxjs'; -import { catchError, takeUntil } from 'rxjs/operators'; +import { EMPTY } from 'rxjs'; +import { catchError } from 'rxjs/operators'; import { UserDetailDialogParams } from './interfaces/interfaces'; @@ -38,15 +39,14 @@ import { UserDetailDialogParams } from './interfaces/interfaces'; styleUrls: ['./user-detail-dialog.component.scss'], templateUrl: './user-detail-dialog.html' }) -export class GfUserDetailDialogComponent implements OnDestroy, OnInit { +export class GfUserDetailDialogComponent implements OnInit { public user: AdminUserResponse; - private unsubscribeSubject = new Subject(); - public constructor( private adminService: AdminService, private changeDetectorRef: ChangeDetectorRef, @Inject(MAT_DIALOG_DATA) public data: UserDetailDialogParams, + private destroyRef: DestroyRef, public dialogRef: MatDialogRef ) { addIcons({ @@ -58,7 +58,7 @@ export class GfUserDetailDialogComponent implements OnDestroy, OnInit { this.adminService .fetchUserById(this.data.userId) .pipe( - takeUntil(this.unsubscribeSubject), + takeUntilDestroyed(this.destroyRef), catchError(() => { this.dialogRef.close(); @@ -82,9 +82,4 @@ export class GfUserDetailDialogComponent implements OnDestroy, OnInit { public onClose() { this.dialogRef.close(); } - - public ngOnDestroy() { - this.unsubscribeSubject.next(); - this.unsubscribeSubject.complete(); - } } From d9e934aa6b206acd14c76c218d662e5e1a65456a Mon Sep 17 00:00:00 2001 From: Kenrick Tandrian <60643640+KenTandrian@users.noreply.github.com> Date: Sat, 4 Apr 2026 12:57:58 +0700 Subject: [PATCH 209/224] Task/improve type safety for routes by implementing satisfies operator (#6681) * Improve type safety --- .../admin-users/admin-users.component.ts | 2 +- .../app/components/footer/footer.component.ts | 8 ++++---- .../home-overview/home-overview.component.ts | 2 +- .../src/app/pages/about/about-page.routes.ts | 10 +++++----- .../about/changelog/changelog-page.routes.ts | 2 +- .../about/license/license-page.routes.ts | 2 +- .../oss-friends/oss-friends-page.routes.ts | 2 +- .../privacy-policy-page.routes.ts | 2 +- .../terms-of-service-page.routes.ts | 2 +- .../src/app/pages/admin/admin-page.routes.ts | 20 +++++++++---------- ...tfolio-joins-oss-friends-page.component.ts | 2 +- .../src/app/pages/faq/faq-page.routes.ts | 4 ++-- .../app/pages/faq/saas/saas-page.component.ts | 2 +- .../app/pages/faq/saas/saas-page.routes.ts | 2 +- .../self-hosting/self-hosting-page.routes.ts | 2 +- .../src/app/pages/home/home-page.routes.ts | 20 +++++++++---------- .../activities/activities-page.routes.ts | 2 +- .../analysis/analysis-page.routes.ts | 2 +- .../pages/portfolio/portfolio-page.routes.ts | 8 ++++---- .../glossary/resources-glossary.component.ts | 2 +- .../glossary/resources-glossary.routes.ts | 2 +- .../guides/resources-guides.routes.ts | 2 +- .../markets/resources-markets.routes.ts | 2 +- .../overview/resources-overview.component.ts | 12 +++++------ .../personal-finance-tools-page.routes.ts | 6 +++--- .../pages/resources/resources-page.routes.ts | 8 ++++---- .../user-account/user-account-page.routes.ts | 8 ++++---- .../src/app/pages/zen/zen-page.routes.ts | 4 ++-- libs/common/src/lib/routes/routes.ts | 8 ++++---- .../assistant-list-item.component.ts | 2 +- .../src/lib/assistant/assistant.component.ts | 6 +++--- .../no-transactions-info.component.ts | 2 +- 32 files changed, 80 insertions(+), 80 deletions(-) diff --git a/apps/client/src/app/components/admin-users/admin-users.component.ts b/apps/client/src/app/components/admin-users/admin-users.component.ts index 3b57ba1c8..874bbc1db 100644 --- a/apps/client/src/app/components/admin-users/admin-users.component.ts +++ b/apps/client/src/app/components/admin-users/admin-users.component.ts @@ -89,7 +89,7 @@ export class GfAdminUsersComponent implements OnInit { public isLoading = false; public pageSize = DEFAULT_PAGE_SIZE; public routerLinkAdminControlUsers = - internalRoutes.adminControl.subRoutes?.users.routerLink; + internalRoutes.adminControl.subRoutes.users.routerLink; public totalItems = 0; public user: User; diff --git a/apps/client/src/app/components/footer/footer.component.ts b/apps/client/src/app/components/footer/footer.component.ts index d06e711b9..48f010565 100644 --- a/apps/client/src/app/components/footer/footer.component.ts +++ b/apps/client/src/app/components/footer/footer.component.ts @@ -33,13 +33,13 @@ export class GfFooterComponent implements OnChanges { public hasPermissionToAccessFearAndGreedIndex: boolean; public routerLinkAbout = publicRoutes.about.routerLink; public routerLinkAboutChangelog = - publicRoutes.about.subRoutes?.changelog.routerLink; + publicRoutes.about.subRoutes.changelog.routerLink; public routerLinkAboutLicense = - publicRoutes.about.subRoutes?.license.routerLink; + publicRoutes.about.subRoutes.license.routerLink; public routerLinkAboutPrivacyPolicy = - publicRoutes.about.subRoutes?.privacyPolicy.routerLink; + publicRoutes.about.subRoutes.privacyPolicy.routerLink; public routerLinkAboutTermsOfService = - publicRoutes.about.subRoutes?.termsOfService.routerLink; + publicRoutes.about.subRoutes.termsOfService.routerLink; public routerLinkBlog = publicRoutes.blog.routerLink; public routerLinkFaq = publicRoutes.faq.routerLink; public routerLinkFeatures = publicRoutes.features.routerLink; diff --git a/apps/client/src/app/components/home-overview/home-overview.component.ts b/apps/client/src/app/components/home-overview/home-overview.component.ts index 9b4f646c3..58284d27d 100644 --- a/apps/client/src/app/components/home-overview/home-overview.component.ts +++ b/apps/client/src/app/components/home-overview/home-overview.component.ts @@ -56,7 +56,7 @@ export class GfHomeOverviewComponent implements OnInit { public routerLinkAccounts = internalRoutes.accounts.routerLink; public routerLinkPortfolio = internalRoutes.portfolio.routerLink; public routerLinkPortfolioActivities = - internalRoutes.portfolio.subRoutes?.activities.routerLink; + internalRoutes.portfolio.subRoutes.activities.routerLink; public showDetails = false; public unit: string; public user: User; diff --git a/apps/client/src/app/pages/about/about-page.routes.ts b/apps/client/src/app/pages/about/about-page.routes.ts index b4466fbab..4cb13280a 100644 --- a/apps/client/src/app/pages/about/about-page.routes.ts +++ b/apps/client/src/app/pages/about/about-page.routes.ts @@ -15,29 +15,29 @@ export const routes: Routes = [ import('./overview/about-overview-page.routes').then((m) => m.routes) }, { - path: publicRoutes.about.subRoutes?.changelog.path, + path: publicRoutes.about.subRoutes.changelog.path, loadChildren: () => import('./changelog/changelog-page.routes').then((m) => m.routes) }, { - path: publicRoutes.about.subRoutes?.license.path, + path: publicRoutes.about.subRoutes.license.path, loadChildren: () => import('./license/license-page.routes').then((m) => m.routes) }, { - path: publicRoutes.about.subRoutes?.ossFriends.path, + path: publicRoutes.about.subRoutes.ossFriends.path, loadChildren: () => import('./oss-friends/oss-friends-page.routes').then((m) => m.routes) }, { - path: publicRoutes.about.subRoutes?.privacyPolicy.path, + path: publicRoutes.about.subRoutes.privacyPolicy.path, loadChildren: () => import('./privacy-policy/privacy-policy-page.routes').then( (m) => m.routes ) }, { - path: publicRoutes.about.subRoutes?.termsOfService.path, + path: publicRoutes.about.subRoutes.termsOfService.path, loadChildren: () => import('./terms-of-service/terms-of-service-page.routes').then( (m) => m.routes diff --git a/apps/client/src/app/pages/about/changelog/changelog-page.routes.ts b/apps/client/src/app/pages/about/changelog/changelog-page.routes.ts index 7b67283e9..523218acc 100644 --- a/apps/client/src/app/pages/about/changelog/changelog-page.routes.ts +++ b/apps/client/src/app/pages/about/changelog/changelog-page.routes.ts @@ -10,6 +10,6 @@ export const routes: Routes = [ canActivate: [AuthGuard], component: GfChangelogPageComponent, path: '', - title: publicRoutes.about.subRoutes?.changelog.title + title: publicRoutes.about.subRoutes.changelog.title } ]; diff --git a/apps/client/src/app/pages/about/license/license-page.routes.ts b/apps/client/src/app/pages/about/license/license-page.routes.ts index 45de6aaa2..1684bb0c5 100644 --- a/apps/client/src/app/pages/about/license/license-page.routes.ts +++ b/apps/client/src/app/pages/about/license/license-page.routes.ts @@ -10,6 +10,6 @@ export const routes: Routes = [ canActivate: [AuthGuard], component: GfLicensePageComponent, path: '', - title: publicRoutes.about.subRoutes?.license.title + title: publicRoutes.about.subRoutes.license.title } ]; diff --git a/apps/client/src/app/pages/about/oss-friends/oss-friends-page.routes.ts b/apps/client/src/app/pages/about/oss-friends/oss-friends-page.routes.ts index dfe65d962..8dbb9d52a 100644 --- a/apps/client/src/app/pages/about/oss-friends/oss-friends-page.routes.ts +++ b/apps/client/src/app/pages/about/oss-friends/oss-friends-page.routes.ts @@ -10,6 +10,6 @@ export const routes: Routes = [ canActivate: [AuthGuard], component: GfOpenSourceSoftwareFriendsPageComponent, path: '', - title: publicRoutes.about.subRoutes?.ossFriends.title + title: publicRoutes.about.subRoutes.ossFriends.title } ]; diff --git a/apps/client/src/app/pages/about/privacy-policy/privacy-policy-page.routes.ts b/apps/client/src/app/pages/about/privacy-policy/privacy-policy-page.routes.ts index 934e06289..e87436c17 100644 --- a/apps/client/src/app/pages/about/privacy-policy/privacy-policy-page.routes.ts +++ b/apps/client/src/app/pages/about/privacy-policy/privacy-policy-page.routes.ts @@ -10,6 +10,6 @@ export const routes: Routes = [ canActivate: [AuthGuard], component: GfPrivacyPolicyPageComponent, path: '', - title: publicRoutes.about.subRoutes?.privacyPolicy.title + title: publicRoutes.about.subRoutes.privacyPolicy.title } ]; diff --git a/apps/client/src/app/pages/about/terms-of-service/terms-of-service-page.routes.ts b/apps/client/src/app/pages/about/terms-of-service/terms-of-service-page.routes.ts index caf8751f1..34d7a72d0 100644 --- a/apps/client/src/app/pages/about/terms-of-service/terms-of-service-page.routes.ts +++ b/apps/client/src/app/pages/about/terms-of-service/terms-of-service-page.routes.ts @@ -10,6 +10,6 @@ export const routes: Routes = [ canActivate: [AuthGuard], component: GfTermsOfServicePageComponent, path: '', - title: publicRoutes.about.subRoutes?.termsOfService.title + title: publicRoutes.about.subRoutes.termsOfService.title } ]; diff --git a/apps/client/src/app/pages/admin/admin-page.routes.ts b/apps/client/src/app/pages/admin/admin-page.routes.ts index 08fce248c..c5309edbb 100644 --- a/apps/client/src/app/pages/admin/admin-page.routes.ts +++ b/apps/client/src/app/pages/admin/admin-page.routes.ts @@ -20,29 +20,29 @@ export const routes: Routes = [ title: internalRoutes.adminControl.title }, { - path: internalRoutes.adminControl.subRoutes?.jobs.path, + path: internalRoutes.adminControl.subRoutes.jobs.path, component: GfAdminJobsComponent, - title: internalRoutes.adminControl.subRoutes?.jobs.title + title: internalRoutes.adminControl.subRoutes.jobs.title }, { - path: internalRoutes.adminControl.subRoutes?.marketData.path, + path: internalRoutes.adminControl.subRoutes.marketData.path, component: GfAdminMarketDataComponent, - title: internalRoutes.adminControl.subRoutes?.marketData.title + title: internalRoutes.adminControl.subRoutes.marketData.title }, { - path: internalRoutes.adminControl.subRoutes?.settings.path, + path: internalRoutes.adminControl.subRoutes.settings.path, component: GfAdminSettingsComponent, - title: internalRoutes.adminControl.subRoutes?.settings.title + title: internalRoutes.adminControl.subRoutes.settings.title }, { - path: internalRoutes.adminControl.subRoutes?.users.path, + path: internalRoutes.adminControl.subRoutes.users.path, component: GfAdminUsersComponent, - title: internalRoutes.adminControl.subRoutes?.users.title + title: internalRoutes.adminControl.subRoutes.users.title }, { - path: `${internalRoutes.adminControl.subRoutes?.users.path}/:userId`, + path: `${internalRoutes.adminControl.subRoutes.users.path}/:userId`, component: GfAdminUsersComponent, - title: internalRoutes.adminControl.subRoutes?.users.title + title: internalRoutes.adminControl.subRoutes.users.title } ], component: AdminPageComponent, diff --git a/apps/client/src/app/pages/blog/2023/08/ghostfolio-joins-oss-friends/ghostfolio-joins-oss-friends-page.component.ts b/apps/client/src/app/pages/blog/2023/08/ghostfolio-joins-oss-friends/ghostfolio-joins-oss-friends-page.component.ts index 4b62e4449..c5a9cf178 100644 --- a/apps/client/src/app/pages/blog/2023/08/ghostfolio-joins-oss-friends/ghostfolio-joins-oss-friends-page.component.ts +++ b/apps/client/src/app/pages/blog/2023/08/ghostfolio-joins-oss-friends/ghostfolio-joins-oss-friends-page.component.ts @@ -12,6 +12,6 @@ import { RouterModule } from '@angular/router'; }) export class GhostfolioJoinsOssFriendsPageComponent { public routerLinkAboutOssFriends = - publicRoutes.about.subRoutes?.ossFriends.routerLink; + publicRoutes.about.subRoutes.ossFriends.routerLink; public routerLinkBlog = publicRoutes.blog.routerLink; } diff --git a/apps/client/src/app/pages/faq/faq-page.routes.ts b/apps/client/src/app/pages/faq/faq-page.routes.ts index f80304a08..2999e3c80 100644 --- a/apps/client/src/app/pages/faq/faq-page.routes.ts +++ b/apps/client/src/app/pages/faq/faq-page.routes.ts @@ -15,12 +15,12 @@ export const routes: Routes = [ import('./overview/faq-overview-page.routes').then((m) => m.routes) }, { - path: publicRoutes.faq.subRoutes?.saas.path, + path: publicRoutes.faq.subRoutes.saas.path, loadChildren: () => import('./saas/saas-page.routes').then((m) => m.routes) }, { - path: publicRoutes.faq.subRoutes?.selfHosting.path, + path: publicRoutes.faq.subRoutes.selfHosting.path, loadChildren: () => import('./self-hosting/self-hosting-page.routes').then( (m) => m.routes diff --git a/apps/client/src/app/pages/faq/saas/saas-page.component.ts b/apps/client/src/app/pages/faq/saas/saas-page.component.ts index 0c221f047..3f44653d2 100644 --- a/apps/client/src/app/pages/faq/saas/saas-page.component.ts +++ b/apps/client/src/app/pages/faq/saas/saas-page.component.ts @@ -25,7 +25,7 @@ export class GfSaasPageComponent { public pricingUrl = `https://ghostfol.io/${document.documentElement.lang}/${publicRoutes.pricing.path}`; public routerLinkAccount = internalRoutes.account.routerLink; public routerLinkAccountMembership = - internalRoutes.account.subRoutes?.membership.routerLink; + internalRoutes.account.subRoutes.membership.routerLink; public routerLinkMarkets = publicRoutes.markets.routerLink; public routerLinkRegister = publicRoutes.register.routerLink; public user: User; diff --git a/apps/client/src/app/pages/faq/saas/saas-page.routes.ts b/apps/client/src/app/pages/faq/saas/saas-page.routes.ts index d68893640..dcb574c38 100644 --- a/apps/client/src/app/pages/faq/saas/saas-page.routes.ts +++ b/apps/client/src/app/pages/faq/saas/saas-page.routes.ts @@ -10,6 +10,6 @@ export const routes: Routes = [ canActivate: [AuthGuard], component: GfSaasPageComponent, path: '', - title: `${publicRoutes.faq.subRoutes?.saas.title} - ${publicRoutes.faq.title}` + title: `${publicRoutes.faq.subRoutes.saas.title} - ${publicRoutes.faq.title}` } ]; diff --git a/apps/client/src/app/pages/faq/self-hosting/self-hosting-page.routes.ts b/apps/client/src/app/pages/faq/self-hosting/self-hosting-page.routes.ts index ccf034421..d08cdb312 100644 --- a/apps/client/src/app/pages/faq/self-hosting/self-hosting-page.routes.ts +++ b/apps/client/src/app/pages/faq/self-hosting/self-hosting-page.routes.ts @@ -10,6 +10,6 @@ export const routes: Routes = [ canActivate: [AuthGuard], component: GfSelfHostingPageComponent, path: '', - title: `${publicRoutes.faq.subRoutes?.selfHosting.title} - ${publicRoutes.faq.title}` + title: `${publicRoutes.faq.subRoutes.selfHosting.title} - ${publicRoutes.faq.title}` } ]; diff --git a/apps/client/src/app/pages/home/home-page.routes.ts b/apps/client/src/app/pages/home/home-page.routes.ts index 436826674..82ef1e521 100644 --- a/apps/client/src/app/pages/home/home-page.routes.ts +++ b/apps/client/src/app/pages/home/home-page.routes.ts @@ -20,29 +20,29 @@ export const routes: Routes = [ component: GfHomeOverviewComponent }, { - path: internalRoutes.home.subRoutes?.holdings.path, + path: internalRoutes.home.subRoutes.holdings.path, component: GfHomeHoldingsComponent, - title: internalRoutes.home.subRoutes?.holdings.title + title: internalRoutes.home.subRoutes.holdings.title }, { - path: internalRoutes.home.subRoutes?.summary.path, + path: internalRoutes.home.subRoutes.summary.path, component: GfHomeSummaryComponent, - title: internalRoutes.home.subRoutes?.summary.title + title: internalRoutes.home.subRoutes.summary.title }, { - path: internalRoutes.home.subRoutes?.markets.path, + path: internalRoutes.home.subRoutes.markets.path, component: GfHomeMarketComponent, - title: internalRoutes.home.subRoutes?.markets.title + title: internalRoutes.home.subRoutes.markets.title }, { - path: internalRoutes.home.subRoutes?.marketsPremium.path, + path: internalRoutes.home.subRoutes.marketsPremium.path, component: GfMarketsComponent, - title: internalRoutes.home.subRoutes?.marketsPremium.title + title: internalRoutes.home.subRoutes.marketsPremium.title }, { - path: internalRoutes.home.subRoutes?.watchlist.path, + path: internalRoutes.home.subRoutes.watchlist.path, component: GfHomeWatchlistComponent, - title: internalRoutes.home.subRoutes?.watchlist.title + title: internalRoutes.home.subRoutes.watchlist.title } ], component: GfHomePageComponent, diff --git a/apps/client/src/app/pages/portfolio/activities/activities-page.routes.ts b/apps/client/src/app/pages/portfolio/activities/activities-page.routes.ts index e1c75f6cc..c96c8a558 100644 --- a/apps/client/src/app/pages/portfolio/activities/activities-page.routes.ts +++ b/apps/client/src/app/pages/portfolio/activities/activities-page.routes.ts @@ -10,6 +10,6 @@ export const routes: Routes = [ canActivate: [AuthGuard], component: GfActivitiesPageComponent, path: '', - title: internalRoutes.portfolio.subRoutes?.activities.title + title: internalRoutes.portfolio.subRoutes.activities.title } ]; diff --git a/apps/client/src/app/pages/portfolio/analysis/analysis-page.routes.ts b/apps/client/src/app/pages/portfolio/analysis/analysis-page.routes.ts index 343d6ced5..91cf4c91b 100644 --- a/apps/client/src/app/pages/portfolio/analysis/analysis-page.routes.ts +++ b/apps/client/src/app/pages/portfolio/analysis/analysis-page.routes.ts @@ -10,6 +10,6 @@ export const routes: Routes = [ canActivate: [AuthGuard], component: GfAnalysisPageComponent, path: '', - title: internalRoutes.portfolio.subRoutes?.analysis.title + title: internalRoutes.portfolio.subRoutes.analysis.title } ]; diff --git a/apps/client/src/app/pages/portfolio/portfolio-page.routes.ts b/apps/client/src/app/pages/portfolio/portfolio-page.routes.ts index a4fdc3f61..aeebf4a6b 100644 --- a/apps/client/src/app/pages/portfolio/portfolio-page.routes.ts +++ b/apps/client/src/app/pages/portfolio/portfolio-page.routes.ts @@ -15,22 +15,22 @@ export const routes: Routes = [ import('./analysis/analysis-page.routes').then((m) => m.routes) }, { - path: internalRoutes.portfolio.subRoutes?.activities.path, + path: internalRoutes.portfolio.subRoutes.activities.path, loadChildren: () => import('./activities/activities-page.routes').then((m) => m.routes) }, { - path: internalRoutes.portfolio.subRoutes?.allocations.path, + path: internalRoutes.portfolio.subRoutes.allocations.path, loadChildren: () => import('./allocations/allocations-page.routes').then((m) => m.routes) }, { - path: internalRoutes.portfolio.subRoutes?.fire.path, + path: internalRoutes.portfolio.subRoutes.fire.path, loadChildren: () => import('./fire/fire-page.routes').then((m) => m.routes) }, { - path: internalRoutes.portfolio.subRoutes?.xRay.path, + path: internalRoutes.portfolio.subRoutes.xRay.path, loadChildren: () => import('./x-ray/x-ray-page.routes').then((m) => m.routes) } diff --git a/apps/client/src/app/pages/resources/glossary/resources-glossary.component.ts b/apps/client/src/app/pages/resources/glossary/resources-glossary.component.ts index 9c86f2c83..112619239 100644 --- a/apps/client/src/app/pages/resources/glossary/resources-glossary.component.ts +++ b/apps/client/src/app/pages/resources/glossary/resources-glossary.component.ts @@ -16,7 +16,7 @@ export class ResourcesGlossaryPageComponent implements OnInit { public hasPermissionForSubscription: boolean; public info: InfoItem; public routerLinkResourcesPersonalFinanceTools = - publicRoutes.resources.subRoutes?.personalFinanceTools.routerLink; + publicRoutes.resources.subRoutes.personalFinanceTools.routerLink; public constructor(private dataService: DataService) { this.info = this.dataService.fetchInfo(); diff --git a/apps/client/src/app/pages/resources/glossary/resources-glossary.routes.ts b/apps/client/src/app/pages/resources/glossary/resources-glossary.routes.ts index 4096dfecd..2f864155a 100644 --- a/apps/client/src/app/pages/resources/glossary/resources-glossary.routes.ts +++ b/apps/client/src/app/pages/resources/glossary/resources-glossary.routes.ts @@ -8,6 +8,6 @@ export const routes: Routes = [ { component: ResourcesGlossaryPageComponent, path: '', - title: publicRoutes.resources.subRoutes?.glossary.title + title: publicRoutes.resources.subRoutes.glossary.title } ]; diff --git a/apps/client/src/app/pages/resources/guides/resources-guides.routes.ts b/apps/client/src/app/pages/resources/guides/resources-guides.routes.ts index eb8c39e24..f9f65f44a 100644 --- a/apps/client/src/app/pages/resources/guides/resources-guides.routes.ts +++ b/apps/client/src/app/pages/resources/guides/resources-guides.routes.ts @@ -8,6 +8,6 @@ export const routes: Routes = [ { component: ResourcesGuidesComponent, path: '', - title: publicRoutes.resources.subRoutes?.guides.title + title: publicRoutes.resources.subRoutes.guides.title } ]; diff --git a/apps/client/src/app/pages/resources/markets/resources-markets.routes.ts b/apps/client/src/app/pages/resources/markets/resources-markets.routes.ts index a56dc7cf7..4bcb66789 100644 --- a/apps/client/src/app/pages/resources/markets/resources-markets.routes.ts +++ b/apps/client/src/app/pages/resources/markets/resources-markets.routes.ts @@ -8,6 +8,6 @@ export const routes: Routes = [ { component: ResourcesMarketsComponent, path: '', - title: publicRoutes.resources.subRoutes?.markets.title + title: publicRoutes.resources.subRoutes.markets.title } ]; diff --git a/apps/client/src/app/pages/resources/overview/resources-overview.component.ts b/apps/client/src/app/pages/resources/overview/resources-overview.component.ts index 310f16a5e..81338200f 100644 --- a/apps/client/src/app/pages/resources/overview/resources-overview.component.ts +++ b/apps/client/src/app/pages/resources/overview/resources-overview.component.ts @@ -20,20 +20,20 @@ export class ResourcesOverviewComponent { { description: 'Explore our guides to help you get started with investing and managing your finances.', - routerLink: publicRoutes.resources.subRoutes?.guides.routerLink, - title: publicRoutes.resources.subRoutes?.guides.title + routerLink: publicRoutes.resources.subRoutes.guides.routerLink, + title: publicRoutes.resources.subRoutes.guides.title }, { description: 'Access various market resources and tools to stay informed about financial markets.', - routerLink: publicRoutes.resources.subRoutes?.markets.routerLink, - title: publicRoutes.resources.subRoutes?.markets.title + routerLink: publicRoutes.resources.subRoutes.markets.routerLink, + title: publicRoutes.resources.subRoutes.markets.title }, { description: 'Learn key financial terms and concepts in our comprehensive glossary.', - routerLink: publicRoutes.resources.subRoutes?.glossary.routerLink, - title: publicRoutes.resources.subRoutes?.glossary.title + routerLink: publicRoutes.resources.subRoutes.glossary.routerLink, + title: publicRoutes.resources.subRoutes.glossary.title } ]; } diff --git a/apps/client/src/app/pages/resources/personal-finance-tools/personal-finance-tools-page.routes.ts b/apps/client/src/app/pages/resources/personal-finance-tools/personal-finance-tools-page.routes.ts index 081c34000..9081f6b28 100644 --- a/apps/client/src/app/pages/resources/personal-finance-tools/personal-finance-tools-page.routes.ts +++ b/apps/client/src/app/pages/resources/personal-finance-tools/personal-finance-tools-page.routes.ts @@ -11,7 +11,7 @@ export const routes: Routes = [ canActivate: [AuthGuard], component: PersonalFinanceToolsPageComponent, path: '', - title: publicRoutes.resources.subRoutes?.personalFinanceTools.title + title: publicRoutes.resources.subRoutes.personalFinanceTools.title }, ...personalFinanceTools.map(({ alias, key, name }) => { return { @@ -23,8 +23,8 @@ export const routes: Routes = [ return GfProductPageComponent; } ), - path: `${publicRoutes.resources.subRoutes?.personalFinanceTools.subRoutes?.product.path}-${alias ?? key}`, - title: `${publicRoutes.resources.subRoutes?.personalFinanceTools.subRoutes?.product.title} ${name}` + path: `${publicRoutes.resources.subRoutes.personalFinanceTools.subRoutes.product.path}-${alias ?? key}`, + title: `${publicRoutes.resources.subRoutes.personalFinanceTools.subRoutes.product.title} ${name}` }; }) ]; diff --git a/apps/client/src/app/pages/resources/resources-page.routes.ts b/apps/client/src/app/pages/resources/resources-page.routes.ts index 6e59f0995..107988238 100644 --- a/apps/client/src/app/pages/resources/resources-page.routes.ts +++ b/apps/client/src/app/pages/resources/resources-page.routes.ts @@ -16,22 +16,22 @@ export const routes: Routes = [ import('./overview/resources-overview.routes').then((m) => m.routes) }, { - path: publicRoutes.resources.subRoutes?.glossary.path, + path: publicRoutes.resources.subRoutes.glossary.path, loadChildren: () => import('./glossary/resources-glossary.routes').then((m) => m.routes) }, { - path: publicRoutes.resources.subRoutes?.guides.path, + path: publicRoutes.resources.subRoutes.guides.path, loadChildren: () => import('./guides/resources-guides.routes').then((m) => m.routes) }, { - path: publicRoutes.resources.subRoutes?.markets.path, + path: publicRoutes.resources.subRoutes.markets.path, loadChildren: () => import('./markets/resources-markets.routes').then((m) => m.routes) }, { - path: publicRoutes.resources.subRoutes?.personalFinanceTools.path, + path: publicRoutes.resources.subRoutes.personalFinanceTools.path, loadChildren: () => import('./personal-finance-tools/personal-finance-tools-page.routes').then( (m) => m.routes diff --git a/apps/client/src/app/pages/user-account/user-account-page.routes.ts b/apps/client/src/app/pages/user-account/user-account-page.routes.ts index 7eac1298e..5d0f5b202 100644 --- a/apps/client/src/app/pages/user-account/user-account-page.routes.ts +++ b/apps/client/src/app/pages/user-account/user-account-page.routes.ts @@ -18,14 +18,14 @@ export const routes: Routes = [ title: internalRoutes.account.title }, { - path: internalRoutes.account.subRoutes?.membership.path, + path: internalRoutes.account.subRoutes.membership.path, component: GfUserAccountMembershipComponent, - title: internalRoutes.account.subRoutes?.membership.title + title: internalRoutes.account.subRoutes.membership.title }, { - path: internalRoutes.account.subRoutes?.access.path, + path: internalRoutes.account.subRoutes.access.path, component: GfUserAccountAccessComponent, - title: internalRoutes.account.subRoutes?.access.title + title: internalRoutes.account.subRoutes.access.title } ], component: GfUserAccountPageComponent, diff --git a/apps/client/src/app/pages/zen/zen-page.routes.ts b/apps/client/src/app/pages/zen/zen-page.routes.ts index 38929dc85..60e163ca4 100644 --- a/apps/client/src/app/pages/zen/zen-page.routes.ts +++ b/apps/client/src/app/pages/zen/zen-page.routes.ts @@ -16,9 +16,9 @@ export const routes: Routes = [ component: GfHomeOverviewComponent }, { - path: internalRoutes.zen.subRoutes?.holdings.path, + path: internalRoutes.zen.subRoutes.holdings.path, component: GfHomeHoldingsComponent, - title: internalRoutes.home.subRoutes?.holdings.title + title: internalRoutes.home.subRoutes.holdings.title } ], component: GfZenPageComponent, diff --git a/libs/common/src/lib/routes/routes.ts b/libs/common/src/lib/routes/routes.ts index 53ecd104e..2785efdde 100644 --- a/libs/common/src/lib/routes/routes.ts +++ b/libs/common/src/lib/routes/routes.ts @@ -15,7 +15,7 @@ if (typeof window !== 'undefined') { }; } -export const internalRoutes: Record = { +export const internalRoutes = { account: { path: 'account', routerLink: ['/account'], @@ -169,9 +169,9 @@ export const internalRoutes: Record = { }, title: $localize`Overview` } -}; +} satisfies Record; -export const publicRoutes: Record = { +export const publicRoutes = { about: { path: $localize`:kebab-case@@routes.about:about`, routerLink: ['/' + $localize`:kebab-case@@routes.about:about`], @@ -336,4 +336,4 @@ export const publicRoutes: Record = { path: $localize`:kebab-case@@routes.start:start`, routerLink: ['/' + $localize`:kebab-case@@routes.start:start`] } -}; +} satisfies Record; diff --git a/libs/ui/src/lib/assistant/assistant-list-item/assistant-list-item.component.ts b/libs/ui/src/lib/assistant/assistant-list-item/assistant-list-item.component.ts index 05750cea4..36127a566 100644 --- a/libs/ui/src/lib/assistant/assistant-list-item/assistant-list-item.component.ts +++ b/libs/ui/src/lib/assistant/assistant-list-item/assistant-list-item.component.ts @@ -67,7 +67,7 @@ export class GfAssistantListItemComponent }; this.routerLink = - internalRoutes.adminControl.subRoutes?.marketData.routerLink ?? []; + internalRoutes.adminControl.subRoutes.marketData.routerLink ?? []; } else if (this.item?.mode === SearchMode.HOLDING) { this.queryParams = { dataSource: this.item.dataSource, diff --git a/libs/ui/src/lib/assistant/assistant.component.ts b/libs/ui/src/lib/assistant/assistant.component.ts index 1c67e4fa2..22d276cd3 100644 --- a/libs/ui/src/lib/assistant/assistant.component.ts +++ b/libs/ui/src/lib/assistant/assistant.component.ts @@ -717,7 +717,7 @@ export class GfAssistantComponent implements OnChanges, OnDestroy, OnInit { private searchQuickLinks(aSearchTerm: string): SearchResultItem[] { const searchTerm = aSearchTerm.toLowerCase(); - const allRoutes = Object.values(internalRoutes) + const allRoutes = Object.values(internalRoutes) .filter(({ excludeFromAssistant }) => { if (isFunction(excludeFromAssistant)) { return excludeFromAssistant(this.user); @@ -725,13 +725,13 @@ export class GfAssistantComponent implements OnChanges, OnDestroy, OnInit { return !excludeFromAssistant; }) - .reduce((acc, route) => { + .reduce((acc, route) => { acc.push(route); if (route.subRoutes) { acc.push(...Object.values(route.subRoutes)); } return acc; - }, [] as InternalRoute[]); + }, []); const fuse = new Fuse(allRoutes, { keys: ['title'], diff --git a/libs/ui/src/lib/no-transactions-info/no-transactions-info.component.ts b/libs/ui/src/lib/no-transactions-info/no-transactions-info.component.ts index 9ca91d111..8691dc998 100644 --- a/libs/ui/src/lib/no-transactions-info/no-transactions-info.component.ts +++ b/libs/ui/src/lib/no-transactions-info/no-transactions-info.component.ts @@ -24,5 +24,5 @@ export class GfNoTransactionsInfoComponent { @HostBinding('class.has-border') @Input() hasBorder = true; public routerLinkPortfolioActivities = - internalRoutes.portfolio.subRoutes?.activities.routerLink; + internalRoutes.portfolio.subRoutes.activities.routerLink; } From 453d8d88189eee069d0d6cc5d376a9368aefa22c Mon Sep 17 00:00:00 2001 From: Kenrick Tandrian <60643640+KenTandrian@users.noreply.github.com> Date: Sun, 5 Apr 2026 14:08:07 +0700 Subject: [PATCH 210/224] Task/improve type safety in create or update account dialog (#6683) * Improve type safety --- ...eate-or-update-account-dialog.component.ts | 58 +++++++++---------- 1 file changed, 29 insertions(+), 29 deletions(-) diff --git a/apps/client/src/app/pages/accounts/create-or-update-account-dialog/create-or-update-account-dialog.component.ts b/apps/client/src/app/pages/accounts/create-or-update-account-dialog/create-or-update-account-dialog.component.ts index 6cdd18251..53d8380e1 100644 --- a/apps/client/src/app/pages/accounts/create-or-update-account-dialog/create-or-update-account-dialog.component.ts +++ b/apps/client/src/app/pages/accounts/create-or-update-account-dialog/create-or-update-account-dialog.component.ts @@ -5,7 +5,7 @@ import { GfEntityLogoComponent } from '@ghostfolio/ui/entity-logo'; import { DataService } from '@ghostfolio/ui/services'; import { CommonModule, NgClass } from '@angular/common'; -import { ChangeDetectionStrategy, Component, Inject } from '@angular/core'; +import { ChangeDetectionStrategy, Component, inject } from '@angular/core'; import { AbstractControl, FormBuilder, @@ -51,17 +51,17 @@ import { CreateOrUpdateAccountDialogParams } from './interfaces/interfaces'; templateUrl: 'create-or-update-account-dialog.html' }) export class GfCreateOrUpdateAccountDialogComponent { - public accountForm: FormGroup; - public currencies: string[] = []; - public filteredPlatforms: Observable; - public platforms: Platform[] = []; - - public constructor( - @Inject(MAT_DIALOG_DATA) public data: CreateOrUpdateAccountDialogParams, - private dataService: DataService, - public dialogRef: MatDialogRef, - private formBuilder: FormBuilder - ) {} + protected accountForm: FormGroup; + protected currencies: string[] = []; + protected filteredPlatforms: Observable | undefined; + protected platforms: Platform[] = []; + + protected readonly data = + inject(MAT_DIALOG_DATA); + private readonly dataService = inject(DataService); + private readonly dialogRef = + inject>(MatDialogRef); + private readonly formBuilder = inject(FormBuilder); public ngOnInit() { const { currencies } = this.dataService.fetchInfo(); @@ -93,18 +93,18 @@ export class GfCreateOrUpdateAccountDialogComponent { this.filteredPlatforms = this.accountForm .get('platformId') - .valueChanges.pipe( + ?.valueChanges.pipe( startWith(''), - map((value) => { + map((value: Platform | string) => { const name = typeof value === 'string' ? value : value?.name; - return name ? this.filter(name as string) : this.platforms.slice(); + return name ? this.filter(name) : this.platforms.slice(); }) ); }); } - public autoCompleteCheck() { - const inputValue = this.accountForm.get('platformId').value; + protected autoCompleteCheck() { + const inputValue = this.accountForm.get('platformId')?.value; if (typeof inputValue === 'string') { const matchingEntry = this.platforms.find(({ name }) => { @@ -112,28 +112,28 @@ export class GfCreateOrUpdateAccountDialogComponent { }); if (matchingEntry) { - this.accountForm.get('platformId').setValue(matchingEntry); + this.accountForm.get('platformId')?.setValue(matchingEntry); } } } - public displayFn(platform: Platform) { + protected displayFn(platform: Platform) { return platform?.name ?? ''; } - public onCancel() { + protected onCancel() { this.dialogRef.close(); } - public async onSubmit() { + protected async onSubmit() { const account: CreateAccountDto | UpdateAccountDto = { - balance: this.accountForm.get('balance').value, - comment: this.accountForm.get('comment').value || null, - currency: this.accountForm.get('currency').value, - id: this.accountForm.get('accountId').value, - isExcluded: this.accountForm.get('isExcluded').value, - name: this.accountForm.get('name').value, - platformId: this.accountForm.get('platformId').value?.id || null + balance: this.accountForm.get('balance')?.value, + comment: this.accountForm.get('comment')?.value || null, + currency: this.accountForm.get('currency')?.value, + id: this.accountForm.get('accountId')?.value, + isExcluded: this.accountForm.get('isExcluded')?.value, + name: this.accountForm.get('name')?.value, + platformId: this.accountForm.get('platformId')?.value?.id || null }; try { @@ -177,7 +177,7 @@ export class GfCreateOrUpdateAccountDialogComponent { const filterValue = value.toLowerCase(); return this.platforms.filter(({ name }) => { - return name.toLowerCase().startsWith(filterValue); + return name?.toLowerCase().startsWith(filterValue); }); } } From 50751d3eb9798ba7379a8f05a047b283cab20491 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rapha=C3=ABl=20TISON?= <13355624+Airthee@users.noreply.github.com> Date: Sun, 5 Apr 2026 09:08:53 +0200 Subject: [PATCH 211/224] Task/show loading state on activities type filter change (#6677) * Show loading state on activities type filter change --------- Co-authored-by: Thomas Kaul <4159106+dtslvr@users.noreply.github.com> --- .../activities/activities-page.component.ts | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/apps/client/src/app/pages/portfolio/activities/activities-page.component.ts b/apps/client/src/app/pages/portfolio/activities/activities-page.component.ts index faadef54f..acd6cba10 100644 --- a/apps/client/src/app/pages/portfolio/activities/activities-page.component.ts +++ b/apps/client/src/app/pages/portfolio/activities/activities-page.component.ts @@ -65,7 +65,7 @@ export class GfActivitiesPageComponent implements OnInit { public routeQueryParams: Subscription; public sortColumn = 'date'; public sortDirection: SortDirection = 'desc'; - public totalItems: number; + public totalItems: number | undefined; public user: User; public constructor( @@ -135,8 +135,11 @@ export class GfActivitiesPageComponent implements OnInit { } public fetchActivities() { - const dateRange = this.user?.settings?.dateRange; + // Reset dataSource and totalItems to show loading state + this.dataSource = undefined; + this.totalItems = undefined; + const dateRange = this.user?.settings?.dateRange; const range = this.isCalendarYear(dateRange) ? dateRange : undefined; this.dataService @@ -200,6 +203,8 @@ export class GfActivitiesPageComponent implements OnInit { .subscribe(); this.fetchActivities(); + + this.changeDetectorRef.markForCheck(); }); } @@ -214,6 +219,8 @@ export class GfActivitiesPageComponent implements OnInit { .subscribe(); this.fetchActivities(); + + this.changeDetectorRef.markForCheck(); }); } @@ -289,6 +296,8 @@ export class GfActivitiesPageComponent implements OnInit { .subscribe(); this.fetchActivities(); + + this.changeDetectorRef.markForCheck(); }); } @@ -316,6 +325,8 @@ export class GfActivitiesPageComponent implements OnInit { .subscribe(); this.fetchActivities(); + + this.changeDetectorRef.markForCheck(); }); } @@ -365,6 +376,8 @@ export class GfActivitiesPageComponent implements OnInit { .subscribe({ next: () => { this.fetchActivities(); + + this.changeDetectorRef.markForCheck(); } }); } @@ -422,6 +435,8 @@ export class GfActivitiesPageComponent implements OnInit { .subscribe(); this.fetchActivities(); + + this.changeDetectorRef.markForCheck(); } }); } From 211745d93480badf8f00a451ec2bff4f10caf8ad Mon Sep 17 00:00:00 2001 From: Kenrick Tandrian <60643640+KenTandrian@users.noreply.github.com> Date: Sun, 5 Apr 2026 22:42:10 +0700 Subject: [PATCH 212/224] Task/improve type safety in create or update activity dialog component (#6682) Improve type safety --- ...ate-or-update-activity-dialog.component.ts | 234 +++++++++--------- .../create-or-update-activity-dialog.html | 10 +- .../interfaces/interfaces.ts | 4 +- 3 files changed, 121 insertions(+), 127 deletions(-) diff --git a/apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.component.ts b/apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.component.ts index 9cc312b25..277701862 100644 --- a/apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.component.ts +++ b/apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.component.ts @@ -1,5 +1,6 @@ import { UserService } from '@ghostfolio/client/services/user/user.service'; import { ASSET_CLASS_MAPPING } from '@ghostfolio/common/config'; +import { locale as defaultLocale } from '@ghostfolio/common/config'; import { CreateOrderDto, UpdateOrderDto } from '@ghostfolio/common/dtos'; import { getDateFormatString } from '@ghostfolio/common/helper'; import { @@ -89,11 +90,11 @@ export class GfCreateOrUpdateActivityDialogComponent { public assetSubClassOptions: AssetClassSelectorOption[] = []; public currencies: string[] = []; - public currencyOfAssetProfile: string; - public currentMarketPrice = null; + public currencyOfAssetProfile: string | undefined; + public currentMarketPrice: number | null = null; public defaultDateFormat: string; public defaultLookupItems: LookupItem[] = []; - public hasPermissionToCreateOwnTag: boolean; + public hasPermissionToCreateOwnTag: boolean | undefined; public isLoading = false; public isToday = isToday; public mode: 'create' | 'update'; @@ -106,7 +107,7 @@ export class GfCreateOrUpdateActivityDialogComponent { private changeDetectorRef: ChangeDetectorRef, @Inject(MAT_DIALOG_DATA) public data: CreateOrUpdateActivityDialogParams, private dataService: DataService, - private dateAdapter: DateAdapter, + private dateAdapter: DateAdapter, private destroyRef: DestroyRef, public dialogRef: MatDialogRef, private formBuilder: FormBuilder, @@ -121,7 +122,7 @@ export class GfCreateOrUpdateActivityDialogComponent { this.hasPermissionToCreateOwnTag = this.data.user?.settings?.isExperimentalFeatures && hasPermission(this.data.user?.permissions, permissions.createOwnTag); - this.locale = this.data.user?.settings?.locale; + this.locale = this.data.user.settings.locale ?? defaultLocale; this.mode = this.data.activity?.id ? 'update' : 'create'; this.dateAdapter.setLocale(this.locale); @@ -136,34 +137,25 @@ export class GfCreateOrUpdateActivityDialogComponent { .pipe(takeUntilDestroyed(this.destroyRef)) .subscribe(({ holdings }) => { this.defaultLookupItems = holdings - .filter(({ assetSubClass }) => { - return !['CASH'].includes(assetSubClass); + .filter(({ assetProfile }) => { + return !['CASH'].includes(assetProfile.assetSubClass); }) .sort((a, b) => { return a.name?.localeCompare(b.name); }) - .map( - ({ - assetClass, - assetSubClass, - currency, - dataSource, - name, - symbol - }) => { - return { - assetClass, - assetSubClass, - currency, - dataSource, - name, - symbol, - dataProviderInfo: { - isPremium: false - } - }; - } - ); + .map(({ assetProfile }) => { + return { + assetClass: assetProfile.assetClass, + assetSubClass: assetProfile.assetSubClass, + currency: assetProfile.currency ?? '', + dataProviderInfo: { + isPremium: false + }, + dataSource: assetProfile.dataSource, + name: assetProfile.name ?? '', + symbol: assetProfile.symbol + }; + }); this.changeDetectorRef.markForCheck(); }); @@ -242,25 +234,25 @@ export class GfCreateOrUpdateActivityDialogComponent { .subscribe(async () => { if ( ['BUY', 'FEE', 'VALUABLE'].includes( - this.activityForm.get('type').value + this.activityForm.get('type')?.value ) ) { this.total = - this.activityForm.get('quantity').value * - this.activityForm.get('unitPrice').value + - (this.activityForm.get('fee').value ?? 0); + this.activityForm.get('quantity')?.value * + this.activityForm.get('unitPrice')?.value + + (this.activityForm.get('fee')?.value ?? 0); } else { this.total = - this.activityForm.get('quantity').value * - this.activityForm.get('unitPrice').value - - (this.activityForm.get('fee').value ?? 0); + this.activityForm.get('quantity')?.value * + this.activityForm.get('unitPrice')?.value - + (this.activityForm.get('fee')?.value ?? 0); } this.changeDetectorRef.markForCheck(); }); - this.activityForm.get('accountId').valueChanges.subscribe((accountId) => { - const type = this.activityForm.get('type').value; + this.activityForm.get('accountId')?.valueChanges.subscribe((accountId) => { + const type = this.activityForm.get('type')?.value; if (['FEE', 'INTEREST', 'LIABILITY', 'VALUABLE'].includes(type)) { const currency = @@ -268,15 +260,15 @@ export class GfCreateOrUpdateActivityDialogComponent { return id === accountId; })?.currency ?? this.data.user.settings.baseCurrency; - this.activityForm.get('currency').setValue(currency); - this.activityForm.get('currencyOfUnitPrice').setValue(currency); + this.activityForm.get('currency')?.setValue(currency); + this.activityForm.get('currencyOfUnitPrice')?.setValue(currency); if (['FEE', 'INTEREST'].includes(type)) { - if (this.activityForm.get('accountId').value) { - this.activityForm.get('updateAccountBalance').enable(); + if (this.activityForm.get('accountId')?.value) { + this.activityForm.get('updateAccountBalance')?.enable(); } else { - this.activityForm.get('updateAccountBalance').disable(); - this.activityForm.get('updateAccountBalance').setValue(false); + this.activityForm.get('updateAccountBalance')?.disable(); + this.activityForm.get('updateAccountBalance')?.setValue(false); } } } @@ -284,7 +276,7 @@ export class GfCreateOrUpdateActivityDialogComponent { this.activityForm .get('assetClass') - .valueChanges.pipe(takeUntilDestroyed(this.destroyRef)) + ?.valueChanges.pipe(takeUntilDestroyed(this.destroyRef)) .subscribe((assetClass) => { const assetSubClasses = ASSET_CLASS_MAPPING.get(assetClass) ?? []; @@ -297,28 +289,28 @@ export class GfCreateOrUpdateActivityDialogComponent { }) .sort((a, b) => a.label.localeCompare(b.label)); - this.activityForm.get('assetSubClass').setValue(null); + this.activityForm.get('assetSubClass')?.setValue(null); this.changeDetectorRef.markForCheck(); }); - this.activityForm.get('date').valueChanges.subscribe(() => { - if (isToday(this.activityForm.get('date').value)) { - this.activityForm.get('updateAccountBalance').enable(); + this.activityForm.get('date')?.valueChanges.subscribe(() => { + if (isToday(this.activityForm.get('date')?.value)) { + this.activityForm.get('updateAccountBalance')?.enable(); } else { - this.activityForm.get('updateAccountBalance').disable(); - this.activityForm.get('updateAccountBalance').setValue(false); + this.activityForm.get('updateAccountBalance')?.disable(); + this.activityForm.get('updateAccountBalance')?.setValue(false); } this.changeDetectorRef.markForCheck(); }); - this.activityForm.get('searchSymbol').valueChanges.subscribe(() => { - if (this.activityForm.get('searchSymbol').invalid) { + this.activityForm.get('searchSymbol')?.valueChanges.subscribe(() => { + if (this.activityForm.get('searchSymbol')?.invalid) { this.data.activity.SymbolProfile = null; } else if ( ['BUY', 'DIVIDEND', 'SELL'].includes( - this.activityForm.get('type').value + this.activityForm.get('type')?.value ) ) { this.updateAssetProfile(); @@ -327,7 +319,7 @@ export class GfCreateOrUpdateActivityDialogComponent { this.changeDetectorRef.markForCheck(); }); - this.activityForm.get('tags').valueChanges.subscribe((tags: Tag[]) => { + this.activityForm.get('tags')?.valueChanges.subscribe((tags: Tag[]) => { const newTag = tags.find(({ id }) => { return id === undefined; }); @@ -337,7 +329,7 @@ export class GfCreateOrUpdateActivityDialogComponent { .postTag({ ...newTag, userId: this.data.user.id }) .pipe(takeUntilDestroyed(this.destroyRef)) .subscribe((tag) => { - this.activityForm.get('tags').setValue( + this.activityForm.get('tags')?.setValue( tags.map((currentTag) => { if (currentTag.id === undefined) { return tag; @@ -357,106 +349,106 @@ export class GfCreateOrUpdateActivityDialogComponent { this.activityForm .get('type') - .valueChanges.pipe(takeUntilDestroyed(this.destroyRef)) + ?.valueChanges.pipe(takeUntilDestroyed(this.destroyRef)) .subscribe((type: ActivityType) => { if ( type === 'VALUABLE' || - (this.activityForm.get('dataSource').value === 'MANUAL' && + (this.activityForm.get('dataSource')?.value === 'MANUAL' && type === 'BUY') ) { const currency = this.data.accounts.find(({ id }) => { - return id === this.activityForm.get('accountId').value; + return id === this.activityForm.get('accountId')?.value; })?.currency ?? this.data.user.settings.baseCurrency; - this.activityForm.get('currency').setValue(currency); - this.activityForm.get('currencyOfUnitPrice').setValue(currency); + this.activityForm.get('currency')?.setValue(currency); + this.activityForm.get('currencyOfUnitPrice')?.setValue(currency); this.activityForm .get('dataSource') - .removeValidators(Validators.required); - this.activityForm.get('dataSource').updateValueAndValidity(); - this.activityForm.get('fee').setValue(0); - this.activityForm.get('name').setValidators(Validators.required); - this.activityForm.get('name').updateValueAndValidity(); + ?.removeValidators(Validators.required); + this.activityForm.get('dataSource')?.updateValueAndValidity(); + this.activityForm.get('fee')?.setValue(0); + this.activityForm.get('name')?.setValidators(Validators.required); + this.activityForm.get('name')?.updateValueAndValidity(); if (type === 'VALUABLE') { - this.activityForm.get('quantity').setValue(1); + this.activityForm.get('quantity')?.setValue(1); } this.activityForm .get('searchSymbol') - .removeValidators(Validators.required); - this.activityForm.get('searchSymbol').updateValueAndValidity(); - this.activityForm.get('updateAccountBalance').disable(); - this.activityForm.get('updateAccountBalance').setValue(false); + ?.removeValidators(Validators.required); + this.activityForm.get('searchSymbol')?.updateValueAndValidity(); + this.activityForm.get('updateAccountBalance')?.disable(); + this.activityForm.get('updateAccountBalance')?.setValue(false); } else if (['FEE', 'INTEREST', 'LIABILITY'].includes(type)) { const currency = this.data.accounts.find(({ id }) => { - return id === this.activityForm.get('accountId').value; + return id === this.activityForm.get('accountId')?.value; })?.currency ?? this.data.user.settings.baseCurrency; - this.activityForm.get('currency').setValue(currency); - this.activityForm.get('currencyOfUnitPrice').setValue(currency); + this.activityForm.get('currency')?.setValue(currency); + this.activityForm.get('currencyOfUnitPrice')?.setValue(currency); this.activityForm .get('dataSource') - .removeValidators(Validators.required); - this.activityForm.get('dataSource').updateValueAndValidity(); + ?.removeValidators(Validators.required); + this.activityForm.get('dataSource')?.updateValueAndValidity(); if (['INTEREST', 'LIABILITY'].includes(type)) { - this.activityForm.get('fee').setValue(0); + this.activityForm.get('fee')?.setValue(0); } - this.activityForm.get('name').setValidators(Validators.required); - this.activityForm.get('name').updateValueAndValidity(); + this.activityForm.get('name')?.setValidators(Validators.required); + this.activityForm.get('name')?.updateValueAndValidity(); if (type === 'FEE') { - this.activityForm.get('quantity').setValue(0); + this.activityForm.get('quantity')?.setValue(0); } else if (['INTEREST', 'LIABILITY'].includes(type)) { - this.activityForm.get('quantity').setValue(1); + this.activityForm.get('quantity')?.setValue(1); } this.activityForm .get('searchSymbol') - .removeValidators(Validators.required); - this.activityForm.get('searchSymbol').updateValueAndValidity(); + ?.removeValidators(Validators.required); + this.activityForm.get('searchSymbol')?.updateValueAndValidity(); if (type === 'FEE') { - this.activityForm.get('unitPrice').setValue(0); + this.activityForm.get('unitPrice')?.setValue(0); } if ( ['FEE', 'INTEREST'].includes(type) && - this.activityForm.get('accountId').value + this.activityForm.get('accountId')?.value ) { - this.activityForm.get('updateAccountBalance').enable(); + this.activityForm.get('updateAccountBalance')?.enable(); } else { - this.activityForm.get('updateAccountBalance').disable(); - this.activityForm.get('updateAccountBalance').setValue(false); + this.activityForm.get('updateAccountBalance')?.disable(); + this.activityForm.get('updateAccountBalance')?.setValue(false); } } else { this.activityForm .get('dataSource') - .setValidators(Validators.required); - this.activityForm.get('dataSource').updateValueAndValidity(); - this.activityForm.get('name').removeValidators(Validators.required); - this.activityForm.get('name').updateValueAndValidity(); + ?.setValidators(Validators.required); + this.activityForm.get('dataSource')?.updateValueAndValidity(); + this.activityForm.get('name')?.removeValidators(Validators.required); + this.activityForm.get('name')?.updateValueAndValidity(); this.activityForm .get('searchSymbol') - .setValidators(Validators.required); - this.activityForm.get('searchSymbol').updateValueAndValidity(); - this.activityForm.get('updateAccountBalance').enable(); + ?.setValidators(Validators.required); + this.activityForm.get('searchSymbol')?.updateValueAndValidity(); + this.activityForm.get('updateAccountBalance')?.enable(); } this.changeDetectorRef.markForCheck(); }); - this.activityForm.get('type').setValue(this.data.activity?.type); + this.activityForm.get('type')?.setValue(this.data.activity?.type); if (this.data.activity?.id) { - this.activityForm.get('searchSymbol').disable(); - this.activityForm.get('type').disable(); + this.activityForm.get('searchSymbol')?.disable(); + this.activityForm.get('type')?.disable(); } if (this.data.activity?.SymbolProfile?.symbol) { @@ -476,7 +468,7 @@ export class GfCreateOrUpdateActivityDialogComponent { public applyCurrentMarketPrice() { this.activityForm.patchValue({ - currencyOfUnitPrice: this.activityForm.get('currency').value, + currencyOfUnitPrice: this.activityForm.get('currency')?.value, unitPrice: this.currentMarketPrice }); } @@ -495,42 +487,42 @@ export class GfCreateOrUpdateActivityDialogComponent { public async onSubmit() { const activity: CreateOrderDto | UpdateOrderDto = { - accountId: this.activityForm.get('accountId').value, - assetClass: this.activityForm.get('assetClass').value, - assetSubClass: this.activityForm.get('assetSubClass').value, - comment: this.activityForm.get('comment').value || null, - currency: this.activityForm.get('currency').value, - customCurrency: this.activityForm.get('currencyOfUnitPrice').value, + accountId: this.activityForm.get('accountId')?.value, + assetClass: this.activityForm.get('assetClass')?.value, + assetSubClass: this.activityForm.get('assetSubClass')?.value, + comment: this.activityForm.get('comment')?.value || null, + currency: this.activityForm.get('currency')?.value, + customCurrency: this.activityForm.get('currencyOfUnitPrice')?.value, dataSource: ['FEE', 'INTEREST', 'LIABILITY', 'VALUABLE'].includes( - this.activityForm.get('type').value + this.activityForm.get('type')?.value ) ? 'MANUAL' - : this.activityForm.get('dataSource').value, - date: this.activityForm.get('date').value, - fee: this.activityForm.get('fee').value, - quantity: this.activityForm.get('quantity').value, + : this.activityForm.get('dataSource')?.value, + date: this.activityForm.get('date')?.value, + fee: this.activityForm.get('fee')?.value, + quantity: this.activityForm.get('quantity')?.value, symbol: (['FEE', 'INTEREST', 'LIABILITY', 'VALUABLE'].includes( - this.activityForm.get('type').value + this.activityForm.get('type')?.value ) ? undefined : this.activityForm.get('searchSymbol')?.value?.symbol) ?? this.activityForm.get('name')?.value, - tags: this.activityForm.get('tags').value?.map(({ id }) => { + tags: this.activityForm.get('tags')?.value?.map(({ id }) => { return id; }), type: - this.activityForm.get('type').value === 'VALUABLE' + this.activityForm.get('type')?.value === 'VALUABLE' ? 'BUY' - : this.activityForm.get('type').value, - unitPrice: this.activityForm.get('unitPrice').value + : this.activityForm.get('type')?.value, + unitPrice: this.activityForm.get('unitPrice')?.value }; try { if (this.mode === 'create') { activity.updateAccountBalance = this.activityForm.get( 'updateAccountBalance' - ).value; + )?.value; await validateObjectForForm({ classDto: CreateOrderDto, @@ -563,8 +555,8 @@ export class GfCreateOrUpdateActivityDialogComponent { this.dataService .fetchSymbolItem({ - dataSource: this.activityForm.get('searchSymbol').value.dataSource, - symbol: this.activityForm.get('searchSymbol').value.symbol + dataSource: this.activityForm.get('searchSymbol')?.value.dataSource, + symbol: this.activityForm.get('searchSymbol')?.value.symbol }) .pipe( catchError(() => { @@ -580,9 +572,9 @@ export class GfCreateOrUpdateActivityDialogComponent { ) .subscribe(({ currency, dataSource, marketPrice }) => { if (this.mode === 'create') { - this.activityForm.get('currency').setValue(currency); - this.activityForm.get('currencyOfUnitPrice').setValue(currency); - this.activityForm.get('dataSource').setValue(dataSource); + this.activityForm.get('currency')?.setValue(currency); + this.activityForm.get('currencyOfUnitPrice')?.setValue(currency); + this.activityForm.get('dataSource')?.setValue(dataSource); } this.currencyOfAssetProfile = currency; diff --git a/apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html b/apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html index 278ddcbbd..038da44cb 100644 --- a/apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html +++ b/apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html @@ -15,7 +15,7 @@ Type {{ - typesTranslationMap[activityForm.get('type').value] + typesTranslationMap[activityForm.get('type')?.value] }} @@ -128,7 +128,7 @@
    @@ -228,7 +228,7 @@ @if ( currencyOfAssetProfile === - activityForm.get('currencyOfUnitPrice').value && + activityForm.get('currencyOfUnitPrice')?.value && currentMarketPrice && ['BUY', 'SELL'].includes(data.activity.type) && isToday(activityForm.get('date')?.value) @@ -262,7 +262,7 @@ matTextSuffix [ngClass]="{ 'd-none': !activityForm.get('currency')?.value }" > - {{ activityForm.get('currencyOfUnitPrice').value }} + {{ activityForm.get('currencyOfUnitPrice')?.value }}
    diff --git a/apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/interfaces/interfaces.ts b/apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/interfaces/interfaces.ts index 5206aacf9..322bcc076 100644 --- a/apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/interfaces/interfaces.ts +++ b/apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/interfaces/interfaces.ts @@ -4,6 +4,8 @@ import { Account } from '@prisma/client'; export interface CreateOrUpdateActivityDialogParams { accounts: Account[]; - activity: Activity; + activity: Omit & { + SymbolProfile: Activity['SymbolProfile'] | null; + }; user: User; } From c17bc77c3bc3fac2c7e629e43a4eb23bd6b9d9de Mon Sep 17 00:00:00 2001 From: Thomas Kaul <4159106+dtslvr@users.noreply.github.com> Date: Mon, 6 Apr 2026 08:50:27 +0200 Subject: [PATCH 213/224] Task/upgrade prisma to version 6.19.3 (#6686) * Upgrade prisma to version 6.19.3 * Update changelog --- CHANGELOG.md | 4 ++ package-lock.json | 130 ++++++++++++++++++++++++---------------------- package.json | 4 +- 3 files changed, 75 insertions(+), 63 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 53461fd8f..f5d57d96b 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 - Added support for filtering by activity type on the activities page (experimental) +### Changed + +- Upgraded `prisma` from version `6.19.0` to `6.19.3` + ## 2.252.0 - 2026-03-02 ### Added diff --git a/package-lock.json b/package-lock.json index 49974055d..824703b65 100644 --- a/package-lock.json +++ b/package-lock.json @@ -41,7 +41,7 @@ "@nestjs/schedule": "6.1.1", "@nestjs/serve-static": "5.0.4", "@openrouter/ai-sdk-provider": "0.7.2", - "@prisma/client": "6.19.0", + "@prisma/client": "6.19.3", "@simplewebauthn/browser": "13.2.2", "@simplewebauthn/server": "13.2.2", "ai": "4.3.16", @@ -150,7 +150,7 @@ "nx": "22.5.3", "prettier": "3.8.1", "prettier-plugin-organize-attributes": "1.0.0", - "prisma": "6.19.0", + "prisma": "6.19.3", "react": "18.2.0", "react-dom": "18.2.0", "replace-in-file": "8.4.0", @@ -10492,9 +10492,9 @@ "license": "MIT" }, "node_modules/@prisma/client": { - "version": "6.19.0", - "resolved": "https://registry.npmjs.org/@prisma/client/-/client-6.19.0.tgz", - "integrity": "sha512-QXFT+N/bva/QI2qoXmjBzL7D6aliPffIwP+81AdTGq0FXDoLxLkWivGMawG8iM5B9BKfxLIXxfWWAF6wbuJU6g==", + "version": "6.19.3", + "resolved": "https://registry.npmjs.org/@prisma/client/-/client-6.19.3.tgz", + "integrity": "sha512-mKq3jQFhjvko5LTJFHGilsuQs+W+T3Gm451NzuTDGQxwCzwXHYnIu2zGkRoW+Exq3Rob7yp2MfzSrdIiZVhrBg==", "hasInstallScript": true, "license": "Apache-2.0", "engines": { @@ -10514,66 +10514,66 @@ } }, "node_modules/@prisma/config": { - "version": "6.19.0", - "resolved": "https://registry.npmjs.org/@prisma/config/-/config-6.19.0.tgz", - "integrity": "sha512-zwCayme+NzI/WfrvFEtkFhhOaZb/hI+X8TTjzjJ252VbPxAl2hWHK5NMczmnG9sXck2lsXrxIZuK524E25UNmg==", + "version": "6.19.3", + "resolved": "https://registry.npmjs.org/@prisma/config/-/config-6.19.3.tgz", + "integrity": "sha512-CBPT44BjlQxEt8kiMEauji2WHTDoVBOKl7UlewXmUgBPnr/oPRZC3psci5chJnYmH0ivEIog2OU9PGWoki3DLQ==", "devOptional": true, "license": "Apache-2.0", "dependencies": { "c12": "3.1.0", "deepmerge-ts": "7.1.5", - "effect": "3.18.4", + "effect": "3.21.0", "empathic": "2.0.0" } }, "node_modules/@prisma/debug": { - "version": "6.19.0", - "resolved": "https://registry.npmjs.org/@prisma/debug/-/debug-6.19.0.tgz", - "integrity": "sha512-8hAdGG7JmxrzFcTzXZajlQCidX0XNkMJkpqtfbLV54wC6LSSX6Vni25W/G+nAANwLnZ2TmwkfIuWetA7jJxJFA==", + "version": "6.19.3", + "resolved": "https://registry.npmjs.org/@prisma/debug/-/debug-6.19.3.tgz", + "integrity": "sha512-ljkJ+SgpXNktLG0Q/n4JGYCkKf0f8oYLyjImS2I8e2q2WCfdRRtWER062ZV/ixaNP2M2VKlWXVJiGzZaUgbKZw==", "devOptional": true, "license": "Apache-2.0" }, "node_modules/@prisma/engines": { - "version": "6.19.0", - "resolved": "https://registry.npmjs.org/@prisma/engines/-/engines-6.19.0.tgz", - "integrity": "sha512-pMRJ+1S6NVdXoB8QJAPIGpKZevFjxhKt0paCkRDTZiczKb7F4yTgRP8M4JdVkpQwmaD4EoJf6qA+p61godDokw==", + "version": "6.19.3", + "resolved": "https://registry.npmjs.org/@prisma/engines/-/engines-6.19.3.tgz", + "integrity": "sha512-RSYxtlYFl5pJ8ZePgMv0lZ9IzVCOdTPOegrs2qcbAEFrBI1G33h6wyC9kjQvo0DnYEhEVY0X4LsuFHXLKQk88g==", "devOptional": true, "hasInstallScript": true, "license": "Apache-2.0", "dependencies": { - "@prisma/debug": "6.19.0", - "@prisma/engines-version": "6.19.0-26.2ba551f319ab1df4bc874a89965d8b3641056773", - "@prisma/fetch-engine": "6.19.0", - "@prisma/get-platform": "6.19.0" + "@prisma/debug": "6.19.3", + "@prisma/engines-version": "7.1.1-3.c2990dca591cba766e3b7ef5d9e8a84796e47ab7", + "@prisma/fetch-engine": "6.19.3", + "@prisma/get-platform": "6.19.3" } }, "node_modules/@prisma/engines-version": { - "version": "6.19.0-26.2ba551f319ab1df4bc874a89965d8b3641056773", - "resolved": "https://registry.npmjs.org/@prisma/engines-version/-/engines-version-6.19.0-26.2ba551f319ab1df4bc874a89965d8b3641056773.tgz", - "integrity": "sha512-gV7uOBQfAFlWDvPJdQxMT1aSRur3a0EkU/6cfbAC5isV67tKDWUrPauyaHNpB+wN1ebM4A9jn/f4gH+3iHSYSQ==", + "version": "7.1.1-3.c2990dca591cba766e3b7ef5d9e8a84796e47ab7", + "resolved": "https://registry.npmjs.org/@prisma/engines-version/-/engines-version-7.1.1-3.c2990dca591cba766e3b7ef5d9e8a84796e47ab7.tgz", + "integrity": "sha512-03bgb1VD5gvuumNf+7fVGBzfpJPjmqV423l/WxsWk2cNQ42JD0/SsFBPhN6z8iAvdHs07/7ei77SKu7aZfq8bA==", "devOptional": true, "license": "Apache-2.0" }, "node_modules/@prisma/fetch-engine": { - "version": "6.19.0", - "resolved": "https://registry.npmjs.org/@prisma/fetch-engine/-/fetch-engine-6.19.0.tgz", - "integrity": "sha512-OOx2Lda0DGrZ1rodADT06ZGqHzr7HY7LNMaFE2Vp8dp146uJld58sRuasdX0OiwpHgl8SqDTUKHNUyzEq7pDdQ==", + "version": "6.19.3", + "resolved": "https://registry.npmjs.org/@prisma/fetch-engine/-/fetch-engine-6.19.3.tgz", + "integrity": "sha512-tKtl/qco9Nt7LU5iKhpultD8O4vMCZcU2CHjNTnRrL1QvSUr5W/GcyFPjNL87GtRrwBc7ubXXD9xy4EvLvt8JA==", "devOptional": true, "license": "Apache-2.0", "dependencies": { - "@prisma/debug": "6.19.0", - "@prisma/engines-version": "6.19.0-26.2ba551f319ab1df4bc874a89965d8b3641056773", - "@prisma/get-platform": "6.19.0" + "@prisma/debug": "6.19.3", + "@prisma/engines-version": "7.1.1-3.c2990dca591cba766e3b7ef5d9e8a84796e47ab7", + "@prisma/get-platform": "6.19.3" } }, "node_modules/@prisma/get-platform": { - "version": "6.19.0", - "resolved": "https://registry.npmjs.org/@prisma/get-platform/-/get-platform-6.19.0.tgz", - "integrity": "sha512-ym85WDO2yDhC3fIXHWYpG3kVMBA49cL1XD2GCsCF8xbwoy2OkDQY44gEbAt2X46IQ4Apq9H6g0Ex1iFfPqEkHA==", + "version": "6.19.3", + "resolved": "https://registry.npmjs.org/@prisma/get-platform/-/get-platform-6.19.3.tgz", + "integrity": "sha512-xFj1VcJ1N3MKooOQAGO0W5tsd0W2QzIvW7DD7c/8H14Zmp4jseeWAITm+w2LLoLrlhoHdPPh0NMZ8mfL6puoHA==", "devOptional": true, "license": "Apache-2.0", "dependencies": { - "@prisma/debug": "6.19.0" + "@prisma/debug": "6.19.3" } }, "node_modules/@redis/client": { @@ -16949,9 +16949,9 @@ "license": "MIT" }, "node_modules/confbox": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/confbox/-/confbox-0.2.2.tgz", - "integrity": "sha512-1NB+BKqhtNipMsov4xI/NnhCKp9XG9NamYp5PVm9klAT0fsrNPjaFICsCFhNhwZJKNh7zB/3q8qXz0E9oaMNtQ==", + "version": "0.2.4", + "resolved": "https://registry.npmjs.org/confbox/-/confbox-0.2.4.tgz", + "integrity": "sha512-ysOGlgTFbN2/Y6Cg3Iye8YKulHw+R2fNXHrgSmXISQdMnomY6eNDprVdW9R5xBguEqI954+S6709UyiO7B+6OQ==", "devOptional": true, "license": "MIT" }, @@ -18548,9 +18548,9 @@ } }, "node_modules/defu": { - "version": "6.1.4", - "resolved": "https://registry.npmjs.org/defu/-/defu-6.1.4.tgz", - "integrity": "sha512-mEQCMmwJu317oSz8CwdIOdwf3xMif1ttiM8LTufzc3g6kR+9Pe236twL8j3IYT1F7GfRgGcW6MWxzZjLIkuHIg==", + "version": "6.1.6", + "resolved": "https://registry.npmjs.org/defu/-/defu-6.1.6.tgz", + "integrity": "sha512-f8mefEW4WIVg4LckePx3mALjQSPQgFlg9U8yaPdlsbdYcHQyj9n2zL2LJEA52smeYxOvmd/nB7TpMtHGMTHcug==", "devOptional": true, "license": "MIT" }, @@ -18910,9 +18910,9 @@ "license": "MIT" }, "node_modules/effect": { - "version": "3.18.4", - "resolved": "https://registry.npmjs.org/effect/-/effect-3.18.4.tgz", - "integrity": "sha512-b1LXQJLe9D11wfnOKAk3PKxuqYshQ0Heez+y5pnkd3jLj1yx9QhM72zZ9uUrOQyNvrs2GZZd/3maL0ZV18YuDA==", + "version": "3.21.0", + "resolved": "https://registry.npmjs.org/effect/-/effect-3.21.0.tgz", + "integrity": "sha512-PPN80qRokCd1f015IANNhrwOnLO7GrrMQfk4/lnZRE/8j7UPWrNNjPV0uBrZutI/nHzernbW+J0hdqQysHiSnQ==", "devOptional": true, "license": "MIT", "dependencies": { @@ -20104,9 +20104,9 @@ } }, "node_modules/exsolve": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/exsolve/-/exsolve-1.0.7.tgz", - "integrity": "sha512-VO5fQUzZtI6C+vx4w/4BWJpg3s/5l+6pRQEHzFRM8WFi4XffSP1Z+4qi7GbjWbvRQEbdIco5mIMq+zX4rPuLrw==", + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/exsolve/-/exsolve-1.0.8.tgz", + "integrity": "sha512-LmDxfWXwcTArk8fUEnOfSZpHOJ6zOMUJKOtFLFqJLoKJetuQG874Uc7/Kki7zFLzYybmZhp1M7+98pfMqeX8yA==", "devOptional": true, "license": "MIT" }, @@ -27177,25 +27177,30 @@ } }, "node_modules/nypm": { - "version": "0.6.2", - "resolved": "https://registry.npmjs.org/nypm/-/nypm-0.6.2.tgz", - "integrity": "sha512-7eM+hpOtrKrBDCh7Ypu2lJ9Z7PNZBdi/8AT3AX8xoCj43BBVHD0hPSTEvMtkMpfs8FCqBGhxB+uToIQimA111g==", + "version": "0.6.5", + "resolved": "https://registry.npmjs.org/nypm/-/nypm-0.6.5.tgz", + "integrity": "sha512-K6AJy1GMVyfyMXRVB88700BJqNUkByijGJM8kEHpLdcAt+vSQAVfkWWHYzuRXHSY6xA2sNc5RjTj0p9rE2izVQ==", "devOptional": true, "license": "MIT", "dependencies": { - "citty": "^0.1.6", - "consola": "^3.4.2", + "citty": "^0.2.0", "pathe": "^2.0.3", - "pkg-types": "^2.3.0", - "tinyexec": "^1.0.1" + "tinyexec": "^1.0.2" }, "bin": { "nypm": "dist/cli.mjs" }, "engines": { - "node": "^14.16.0 || >=16.10.0" + "node": ">=18" } }, + "node_modules/nypm/node_modules/citty": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/citty/-/citty-0.2.2.tgz", + "integrity": "sha512-+6vJA3L98yv+IdfKGZHBNiGW5KHn22e/JwID0Strsz8h4S/csAu/OuICwxrg44k5MRiZHWIo8XXuJgQTriRP4w==", + "devOptional": true, + "license": "MIT" + }, "node_modules/oauth": { "version": "0.10.2", "resolved": "https://registry.npmjs.org/oauth/-/oauth-0.10.2.tgz", @@ -29200,15 +29205,15 @@ } }, "node_modules/prisma": { - "version": "6.19.0", - "resolved": "https://registry.npmjs.org/prisma/-/prisma-6.19.0.tgz", - "integrity": "sha512-F3eX7K+tWpkbhl3l4+VkFtrwJlLXbAM+f9jolgoUZbFcm1DgHZ4cq9AgVEgUym2au5Ad/TDLN8lg83D+M10ycw==", + "version": "6.19.3", + "resolved": "https://registry.npmjs.org/prisma/-/prisma-6.19.3.tgz", + "integrity": "sha512-++ZJ0ijLrDJF6hNB4t4uxg2br3fC4H9Yc9tcbjr2fcNFP3rh/SBNrAgjhsqBU4Ght8JPrVofG/ZkXfnSfnYsFg==", "devOptional": true, "hasInstallScript": true, "license": "Apache-2.0", "dependencies": { - "@prisma/config": "6.19.0", - "@prisma/engines": "6.19.0" + "@prisma/config": "6.19.3", + "@prisma/engines": "6.19.3" }, "bin": { "prisma": "build/index.js" @@ -32951,11 +32956,14 @@ "license": "MIT" }, "node_modules/tinyexec": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/tinyexec/-/tinyexec-1.0.1.tgz", - "integrity": "sha512-5uC6DDlmeqiOwCPmK9jMSdOuZTh8bU39Ys6yidB+UTt5hfZUPGAypSgFRiEp+jbi9qH40BLDvy85jIU88wKSqw==", + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/tinyexec/-/tinyexec-1.0.4.tgz", + "integrity": "sha512-u9r3uZC0bdpGOXtlxUIdwf9pkmvhqJdrVCH9fapQtgy/OeTTMZ1nqH7agtvEfmGui6e1XxjcdrlxvxJvc3sMqw==", "devOptional": true, - "license": "MIT" + "license": "MIT", + "engines": { + "node": ">=18" + } }, "node_modules/tinyglobby": { "version": "0.2.15", diff --git a/package.json b/package.json index cf5787a4c..812aa4cfa 100644 --- a/package.json +++ b/package.json @@ -86,7 +86,7 @@ "@nestjs/schedule": "6.1.1", "@nestjs/serve-static": "5.0.4", "@openrouter/ai-sdk-provider": "0.7.2", - "@prisma/client": "6.19.0", + "@prisma/client": "6.19.3", "@simplewebauthn/browser": "13.2.2", "@simplewebauthn/server": "13.2.2", "ai": "4.3.16", @@ -195,7 +195,7 @@ "nx": "22.5.3", "prettier": "3.8.1", "prettier-plugin-organize-attributes": "1.0.0", - "prisma": "6.19.0", + "prisma": "6.19.3", "react": "18.2.0", "react-dom": "18.2.0", "replace-in-file": "8.4.0", From ced2b5518255c1ccc46aea44308fc06e5a5f3626 Mon Sep 17 00:00:00 2001 From: Thomas Kaul <4159106+dtslvr@users.noreply.github.com> Date: Mon, 6 Apr 2026 08:51:18 +0200 Subject: [PATCH 214/224] Task/remove NEW badge from settings tab in admin control page (#6687) Remove NEW badge --- apps/client/src/app/pages/admin/admin-page.component.ts | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/apps/client/src/app/pages/admin/admin-page.component.ts b/apps/client/src/app/pages/admin/admin-page.component.ts index 284d3c41d..66312ef33 100644 --- a/apps/client/src/app/pages/admin/admin-page.component.ts +++ b/apps/client/src/app/pages/admin/admin-page.component.ts @@ -47,11 +47,7 @@ export class AdminPageComponent implements OnInit { }, { iconName: 'settings-outline', - label: - internalRoutes.adminControl.subRoutes.settings.title + - '' + - $localize`new` + - '', + label: internalRoutes.adminControl.subRoutes.settings.title, routerLink: internalRoutes.adminControl.subRoutes.settings.routerLink }, { From 10e185766af6546c98433bece73a6b33cdee7d59 Mon Sep 17 00:00:00 2001 From: Trevin Chow Date: Sun, 5 Apr 2026 23:54:40 -0700 Subject: [PATCH 215/224] Task/remove unused getCategoryName() from rule classes (#6688) Remove unused getCategoryName() --- apps/api/src/models/rule.ts | 2 -- .../rules/account-cluster-risk/current-investment.ts | 7 ------- .../models/rules/account-cluster-risk/single-account.ts | 7 ------- .../src/models/rules/asset-class-cluster-risk/equity.ts | 7 ------- .../models/rules/asset-class-cluster-risk/fixed-income.ts | 7 ------- .../base-currency-current-investment.ts | 7 ------- .../rules/currency-cluster-risk/current-investment.ts | 7 ------- .../economic-market-cluster-risk/developed-markets.ts | 7 ------- .../rules/economic-market-cluster-risk/emerging-markets.ts | 7 ------- .../models/rules/emergency-fund/emergency-fund-setup.ts | 7 ------- .../models/rules/fees/fee-ratio-total-investment-volume.ts | 7 ------- apps/api/src/models/rules/liquidity/buying-power.ts | 7 ------- .../rules/regional-market-cluster-risk/asia-pacific.ts | 4 ---- .../rules/regional-market-cluster-risk/emerging-markets.ts | 4 ---- .../models/rules/regional-market-cluster-risk/europe.ts | 4 ---- .../src/models/rules/regional-market-cluster-risk/japan.ts | 4 ---- .../rules/regional-market-cluster-risk/north-america.ts | 4 ---- 17 files changed, 99 deletions(-) diff --git a/apps/api/src/models/rule.ts b/apps/api/src/models/rule.ts index 622375b5b..5603964c5 100644 --- a/apps/api/src/models/rule.ts +++ b/apps/api/src/models/rule.ts @@ -70,8 +70,6 @@ export abstract class Rule implements RuleInterface { public abstract evaluate(aRuleSettings: T): EvaluationResult; - public abstract getCategoryName(): string; - public abstract getConfiguration(): Partial< PortfolioReportRule['configuration'] >; diff --git a/apps/api/src/models/rules/account-cluster-risk/current-investment.ts b/apps/api/src/models/rules/account-cluster-risk/current-investment.ts index 0004d394e..400a2506f 100644 --- a/apps/api/src/models/rules/account-cluster-risk/current-investment.ts +++ b/apps/api/src/models/rules/account-cluster-risk/current-investment.ts @@ -98,13 +98,6 @@ export class AccountClusterRiskCurrentInvestment extends Rule { }; } - public getCategoryName() { - return this.i18nService.getTranslation({ - id: 'rule.accountClusterRisk.category', - languageCode: this.getLanguageCode() - }); - } - public getConfiguration() { return { threshold: { diff --git a/apps/api/src/models/rules/account-cluster-risk/single-account.ts b/apps/api/src/models/rules/account-cluster-risk/single-account.ts index 9988ea3cc..e4ee99064 100644 --- a/apps/api/src/models/rules/account-cluster-risk/single-account.ts +++ b/apps/api/src/models/rules/account-cluster-risk/single-account.ts @@ -57,13 +57,6 @@ export class AccountClusterRiskSingleAccount extends Rule { }; } - public getCategoryName() { - return this.i18nService.getTranslation({ - id: 'rule.accountClusterRisk.category', - languageCode: this.getLanguageCode() - }); - } - public getConfiguration() { return undefined; } diff --git a/apps/api/src/models/rules/asset-class-cluster-risk/equity.ts b/apps/api/src/models/rules/asset-class-cluster-risk/equity.ts index f70756e91..372b0bb06 100644 --- a/apps/api/src/models/rules/asset-class-cluster-risk/equity.ts +++ b/apps/api/src/models/rules/asset-class-cluster-risk/equity.ts @@ -85,13 +85,6 @@ export class AssetClassClusterRiskEquity extends Rule { }; } - public getCategoryName() { - return this.i18nService.getTranslation({ - id: 'rule.assetClassClusterRisk.category', - languageCode: this.getLanguageCode() - }); - } - public getConfiguration() { return { threshold: { diff --git a/apps/api/src/models/rules/asset-class-cluster-risk/fixed-income.ts b/apps/api/src/models/rules/asset-class-cluster-risk/fixed-income.ts index 3bd835e4d..404b4cd32 100644 --- a/apps/api/src/models/rules/asset-class-cluster-risk/fixed-income.ts +++ b/apps/api/src/models/rules/asset-class-cluster-risk/fixed-income.ts @@ -85,13 +85,6 @@ export class AssetClassClusterRiskFixedIncome extends Rule { }; } - public getCategoryName() { - return this.i18nService.getTranslation({ - id: 'rule.assetClassClusterRisk.category', - languageCode: this.getLanguageCode() - }); - } - public getConfiguration() { return { threshold: { diff --git a/apps/api/src/models/rules/currency-cluster-risk/base-currency-current-investment.ts b/apps/api/src/models/rules/currency-cluster-risk/base-currency-current-investment.ts index d3176582f..83c72eeb8 100644 --- a/apps/api/src/models/rules/currency-cluster-risk/base-currency-current-investment.ts +++ b/apps/api/src/models/rules/currency-cluster-risk/base-currency-current-investment.ts @@ -82,13 +82,6 @@ export class CurrencyClusterRiskBaseCurrencyCurrentInvestment extends Rule { }; } - public getCategoryName() { - return this.i18nService.getTranslation({ - id: 'rule.currencyClusterRisk.category', - languageCode: this.getLanguageCode() - }); - } - public getConfiguration() { return { threshold: { diff --git a/apps/api/src/models/rules/economic-market-cluster-risk/developed-markets.ts b/apps/api/src/models/rules/economic-market-cluster-risk/developed-markets.ts index df9b78eef..70f09f58c 100644 --- a/apps/api/src/models/rules/economic-market-cluster-risk/developed-markets.ts +++ b/apps/api/src/models/rules/economic-market-cluster-risk/developed-markets.ts @@ -76,13 +76,6 @@ export class EconomicMarketClusterRiskDevelopedMarkets extends Rule { }; } - public getCategoryName() { - return this.i18nService.getTranslation({ - id: 'rule.economicMarketClusterRisk.category', - languageCode: this.getLanguageCode() - }); - } - public getConfiguration() { return { threshold: { diff --git a/apps/api/src/models/rules/economic-market-cluster-risk/emerging-markets.ts b/apps/api/src/models/rules/economic-market-cluster-risk/emerging-markets.ts index 4583dc50a..120c3f6a2 100644 --- a/apps/api/src/models/rules/economic-market-cluster-risk/emerging-markets.ts +++ b/apps/api/src/models/rules/economic-market-cluster-risk/emerging-markets.ts @@ -76,13 +76,6 @@ export class EconomicMarketClusterRiskEmergingMarkets extends Rule { }; } - public getCategoryName() { - return this.i18nService.getTranslation({ - id: 'rule.economicMarketClusterRisk.category', - languageCode: this.getLanguageCode() - }); - } - public getConfiguration() { return { threshold: { diff --git a/apps/api/src/models/rules/emergency-fund/emergency-fund-setup.ts b/apps/api/src/models/rules/emergency-fund/emergency-fund-setup.ts index b956263f8..fcbd99d54 100644 --- a/apps/api/src/models/rules/emergency-fund/emergency-fund-setup.ts +++ b/apps/api/src/models/rules/emergency-fund/emergency-fund-setup.ts @@ -40,13 +40,6 @@ export class EmergencyFundSetup extends Rule { }; } - public getCategoryName() { - return this.i18nService.getTranslation({ - id: 'rule.emergencyFund.category', - languageCode: this.getLanguageCode() - }); - } - public getConfiguration() { return undefined; } diff --git a/apps/api/src/models/rules/fees/fee-ratio-total-investment-volume.ts b/apps/api/src/models/rules/fees/fee-ratio-total-investment-volume.ts index 07bf5fa2c..23f9076e8 100644 --- a/apps/api/src/models/rules/fees/fee-ratio-total-investment-volume.ts +++ b/apps/api/src/models/rules/fees/fee-ratio-total-investment-volume.ts @@ -56,13 +56,6 @@ export class FeeRatioTotalInvestmentVolume extends Rule { }; } - public getCategoryName() { - return this.i18nService.getTranslation({ - id: 'rule.fees.category', - languageCode: this.getLanguageCode() - }); - } - public getConfiguration() { return { threshold: { diff --git a/apps/api/src/models/rules/liquidity/buying-power.ts b/apps/api/src/models/rules/liquidity/buying-power.ts index 541750d7e..7e8b96143 100644 --- a/apps/api/src/models/rules/liquidity/buying-power.ts +++ b/apps/api/src/models/rules/liquidity/buying-power.ts @@ -63,13 +63,6 @@ export class BuyingPower extends Rule { }; } - public getCategoryName() { - return this.i18nService.getTranslation({ - id: 'rule.liquidity.category', - languageCode: this.getLanguageCode() - }); - } - public getConfiguration() { return { threshold: { diff --git a/apps/api/src/models/rules/regional-market-cluster-risk/asia-pacific.ts b/apps/api/src/models/rules/regional-market-cluster-risk/asia-pacific.ts index 1242df759..4723389b0 100644 --- a/apps/api/src/models/rules/regional-market-cluster-risk/asia-pacific.ts +++ b/apps/api/src/models/rules/regional-market-cluster-risk/asia-pacific.ts @@ -70,10 +70,6 @@ export class RegionalMarketClusterRiskAsiaPacific extends Rule { }; } - public getCategoryName() { - return 'Regional Market Cluster Risk'; // TODO: Replace hardcoded text with i18n translation - } - public getConfiguration() { return { threshold: { diff --git a/apps/api/src/models/rules/regional-market-cluster-risk/emerging-markets.ts b/apps/api/src/models/rules/regional-market-cluster-risk/emerging-markets.ts index 8486d843b..d4695406a 100644 --- a/apps/api/src/models/rules/regional-market-cluster-risk/emerging-markets.ts +++ b/apps/api/src/models/rules/regional-market-cluster-risk/emerging-markets.ts @@ -72,10 +72,6 @@ export class RegionalMarketClusterRiskEmergingMarkets extends Rule { }; } - public getCategoryName() { - return 'Regional Market Cluster Risk'; // TODO: Replace hardcoded text with i18n translation - } - public getConfiguration() { return { threshold: { diff --git a/apps/api/src/models/rules/regional-market-cluster-risk/europe.ts b/apps/api/src/models/rules/regional-market-cluster-risk/europe.ts index 459848db4..c5cb4d134 100644 --- a/apps/api/src/models/rules/regional-market-cluster-risk/europe.ts +++ b/apps/api/src/models/rules/regional-market-cluster-risk/europe.ts @@ -70,10 +70,6 @@ export class RegionalMarketClusterRiskEurope extends Rule { }; } - public getCategoryName() { - return 'Regional Market Cluster Risk'; // TODO: Replace hardcoded text with i18n translation - } - public getConfiguration() { return { threshold: { diff --git a/apps/api/src/models/rules/regional-market-cluster-risk/japan.ts b/apps/api/src/models/rules/regional-market-cluster-risk/japan.ts index d9c1cff6b..fc9ab92ee 100644 --- a/apps/api/src/models/rules/regional-market-cluster-risk/japan.ts +++ b/apps/api/src/models/rules/regional-market-cluster-risk/japan.ts @@ -70,10 +70,6 @@ export class RegionalMarketClusterRiskJapan extends Rule { }; } - public getCategoryName() { - return 'Regional Market Cluster Risk'; // TODO: Replace hardcoded text with i18n translation - } - public getConfiguration() { return { threshold: { diff --git a/apps/api/src/models/rules/regional-market-cluster-risk/north-america.ts b/apps/api/src/models/rules/regional-market-cluster-risk/north-america.ts index 6180a2cc5..8bd3fb0cf 100644 --- a/apps/api/src/models/rules/regional-market-cluster-risk/north-america.ts +++ b/apps/api/src/models/rules/regional-market-cluster-risk/north-america.ts @@ -70,10 +70,6 @@ export class RegionalMarketClusterRiskNorthAmerica extends Rule { }; } - public getCategoryName() { - return 'Regional Market Cluster Risk'; // TODO: Replace hardcoded text with i18n translation - } - public getConfiguration() { return { threshold: { From 56c4626bbd6b447902b1fb079da6aa66bc3affaa Mon Sep 17 00:00:00 2001 From: Thomas Kaul <4159106+dtslvr@users.noreply.github.com> Date: Mon, 6 Apr 2026 08:55:23 +0200 Subject: [PATCH 216/224] Feature/add copy-to-clipboard button to version of admin overview (#6670) * Add copy-to-clipboard button to version * Update changelog --- CHANGELOG.md | 1 + .../src/app/components/admin-overview/admin-overview.html | 5 ++++- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f5d57d96b..3a6488ab6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Added - Added support for filtering by activity type on the activities page (experimental) +- Extended the admin control panel by adding a copy-to-clipboard button for the application version ### Changed diff --git a/apps/client/src/app/components/admin-overview/admin-overview.html b/apps/client/src/app/components/admin-overview/admin-overview.html index f0a6ea1d5..55fa8dac5 100644 --- a/apps/client/src/app/components/admin-overview/admin-overview.html +++ b/apps/client/src/app/components/admin-overview/admin-overview.html @@ -6,7 +6,10 @@
    Version
    - +
    From c3ca05bbddd4866f7acd6ad33ae1062de4485dc0 Mon Sep 17 00:00:00 2001 From: Kenrick Tandrian <60643640+KenTandrian@users.noreply.github.com> Date: Mon, 6 Apr 2026 13:56:10 +0700 Subject: [PATCH 217/224] Task/improve type safety in create or update access dialog (#6685) Improve type safety --- ...reate-or-update-access-dialog.component.ts | 80 +++++++++++-------- .../create-or-update-access-dialog.html | 4 +- 2 files changed, 47 insertions(+), 37 deletions(-) diff --git a/apps/client/src/app/components/user-account-access/create-or-update-access-dialog/create-or-update-access-dialog.component.ts b/apps/client/src/app/components/user-account-access/create-or-update-access-dialog/create-or-update-access-dialog.component.ts index a4fadeecf..97bd272d4 100644 --- a/apps/client/src/app/components/user-account-access/create-or-update-access-dialog/create-or-update-access-dialog.component.ts +++ b/apps/client/src/app/components/user-account-access/create-or-update-access-dialog/create-or-update-access-dialog.component.ts @@ -3,12 +3,13 @@ import { validateObjectForForm } from '@ghostfolio/common/utils'; import { NotificationService } from '@ghostfolio/ui/notifications'; import { DataService } from '@ghostfolio/ui/services'; +import type { HttpErrorResponse } from '@angular/common/http'; import { ChangeDetectionStrategy, ChangeDetectorRef, Component, DestroyRef, - Inject, + inject, OnInit } from '@angular/core'; import { takeUntilDestroyed } from '@angular/core/rxjs-interop'; @@ -50,18 +51,24 @@ import { CreateOrUpdateAccessDialogParams } from './interfaces/interfaces'; templateUrl: 'create-or-update-access-dialog.html' }) export class GfCreateOrUpdateAccessDialogComponent implements OnInit { - public accessForm: FormGroup; - public mode: 'create' | 'update'; - - public constructor( - private changeDetectorRef: ChangeDetectorRef, - @Inject(MAT_DIALOG_DATA) private data: CreateOrUpdateAccessDialogParams, - public dialogRef: MatDialogRef, - private dataService: DataService, - private destroyRef: DestroyRef, - private formBuilder: FormBuilder, - private notificationService: NotificationService - ) { + protected accessForm: FormGroup; + protected mode: 'create' | 'update'; + + private readonly changeDetectorRef = inject(ChangeDetectorRef); + + private readonly data = + inject(MAT_DIALOG_DATA); + + private readonly dataService = inject(DataService); + private readonly destroyRef = inject(DestroyRef); + + private readonly dialogRef = + inject>(MatDialogRef); + + private readonly formBuilder = inject(FormBuilder); + private readonly notificationService = inject(NotificationService); + + public constructor() { this.mode = this.data.access?.id ? 'update' : 'create'; } @@ -81,22 +88,25 @@ export class GfCreateOrUpdateAccessDialogComponent implements OnInit { ] }); - this.accessForm.get('type').valueChanges.subscribe((accessType) => { - const granteeUserIdControl = this.accessForm.get('granteeUserId'); - const permissionsControl = this.accessForm.get('permissions'); + this.accessForm + .get('type') + ?.valueChanges.pipe(takeUntilDestroyed(this.destroyRef)) + .subscribe((accessType) => { + const granteeUserIdControl = this.accessForm.get('granteeUserId'); + const permissionsControl = this.accessForm.get('permissions'); - if (accessType === 'PRIVATE') { - granteeUserIdControl.setValidators(Validators.required); - } else { - granteeUserIdControl.clearValidators(); - granteeUserIdControl.setValue(null); - permissionsControl.setValue(this.data.access.permissions[0]); - } + if (accessType === 'PRIVATE') { + granteeUserIdControl?.setValidators(Validators.required); + } else { + granteeUserIdControl?.clearValidators(); + granteeUserIdControl?.setValue(null); + permissionsControl?.setValue(this.data.access.permissions[0]); + } - granteeUserIdControl.updateValueAndValidity(); + granteeUserIdControl?.updateValueAndValidity(); - this.changeDetectorRef.markForCheck(); - }); + this.changeDetectorRef.markForCheck(); + }); } public onCancel() { @@ -113,9 +123,9 @@ export class GfCreateOrUpdateAccessDialogComponent implements OnInit { private async createAccess() { const access: CreateAccessDto = { - alias: this.accessForm.get('alias').value, - granteeUserId: this.accessForm.get('granteeUserId').value, - permissions: [this.accessForm.get('permissions').value] + alias: this.accessForm.get('alias')?.value, + granteeUserId: this.accessForm.get('granteeUserId')?.value, + permissions: [this.accessForm.get('permissions')?.value] }; try { @@ -128,7 +138,7 @@ export class GfCreateOrUpdateAccessDialogComponent implements OnInit { this.dataService .postAccess(access) .pipe( - catchError((error) => { + catchError((error: HttpErrorResponse) => { if (error.status === StatusCodes.BAD_REQUEST) { this.notificationService.alert({ title: $localize`Oops! Could not grant access.` @@ -149,10 +159,10 @@ export class GfCreateOrUpdateAccessDialogComponent implements OnInit { private async updateAccess() { const access: UpdateAccessDto = { - alias: this.accessForm.get('alias').value, - granteeUserId: this.accessForm.get('granteeUserId').value, + alias: this.accessForm.get('alias')?.value, + granteeUserId: this.accessForm.get('granteeUserId')?.value, id: this.data.access.id, - permissions: [this.accessForm.get('permissions').value] + permissions: [this.accessForm.get('permissions')?.value] }; try { @@ -165,8 +175,8 @@ export class GfCreateOrUpdateAccessDialogComponent implements OnInit { this.dataService .putAccess(access) .pipe( - catchError(({ status }) => { - if (status.status === StatusCodes.BAD_REQUEST) { + catchError(({ status }: HttpErrorResponse) => { + if (status === StatusCodes.BAD_REQUEST) { this.notificationService.alert({ title: $localize`Oops! Could not update access.` }); diff --git a/apps/client/src/app/components/user-account-access/create-or-update-access-dialog/create-or-update-access-dialog.html b/apps/client/src/app/components/user-account-access/create-or-update-access-dialog/create-or-update-access-dialog.html index 11669041d..93614b55a 100644 --- a/apps/client/src/app/components/user-account-access/create-or-update-access-dialog/create-or-update-access-dialog.html +++ b/apps/client/src/app/components/user-account-access/create-or-update-access-dialog/create-or-update-access-dialog.html @@ -38,13 +38,13 @@ Permission Restricted view - @if (accessForm.get('type').value === 'PRIVATE') { + @if (accessForm.get('type')?.value === 'PRIVATE') { View }
    - @if (accessForm.get('type').value === 'PRIVATE') { + @if (accessForm.get('type')?.value === 'PRIVATE') {
    From b994d983590bbcc8455b642ae90f510fb1cad9a7 Mon Sep 17 00:00:00 2001 From: Thomas Kaul <4159106+dtslvr@users.noreply.github.com> Date: Mon, 6 Apr 2026 11:11:51 +0200 Subject: [PATCH 218/224] Task/extend ToS (#6690) * Extend ToS * Update changelog --- CHANGELOG.md | 1 + apps/client/src/assets/terms-of-service.md | 12 +++++++++++- 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3a6488ab6..d6a539243 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,6 +14,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Changed +- Extended the terms of service for the _Ghostfolio_ SaaS (cloud) to include _Paid Plans_ and _Refund Policy_ - Upgraded `prisma` from version `6.19.0` to `6.19.3` ## 2.252.0 - 2026-03-02 diff --git a/apps/client/src/assets/terms-of-service.md b/apps/client/src/assets/terms-of-service.md index d2a6e598d..4f62eee5b 100644 --- a/apps/client/src/assets/terms-of-service.md +++ b/apps/client/src/assets/terms-of-service.md @@ -51,8 +51,18 @@ This Agreement constitutes the entire agreement between the User and LICENSEE re LICENSEE reserves the right to modify this Agreement at any time. Users are encouraged to review this Agreement periodically for updates. Continued use of the Service after changes to this Agreement constitutes acceptance of the modified terms. +## Paid Plans + +LICENSEE offers paid plans (such as [Ghostfolio Premium](https://ghostfol.io/en/pricing)) for a fixed term as specified at the time of purchase. Paid plans do not renew automatically. + +LICENSEE may change the features or pricing of paid plans. For any existing paid plan, if a material feature is removed, LICENSEE may, acting in good faith, offer a pro-rata refund for the unused portion of the term upon the User’s request. + +## Refund Policy + +LICENSEE may offer a free trial of paid plans. Users are encouraged to use any available free trial to evaluate the Service before purchasing. While all purchases are final, a refund may be requested within fourteen (14) days of the purchase date by contacting LICENSEE. Requests after this period will not be honored. + By accessing or using the Service, or downloading data provided by the Service, the User acknowledges that they have read, understood, and agreed to be bound by this Terms of Service Agreement. For any questions or concerns regarding this Agreement, please contact us [here](https://ghostfol.io/en/about). -Date of Last Revision: March 29, 2025 +Date of Last Revision: April 6, 2026 From dd31c18e2dceb4b8d3c38df96b8de90f34f31cf2 Mon Sep 17 00:00:00 2001 From: David Requeno <108202767+DavidReque@users.noreply.github.com> Date: Mon, 6 Apr 2026 03:12:41 -0600 Subject: [PATCH 219/224] Bugfix/fix broken allocation charts in presenter view (#6689) * Fix broken allocation charts in presenter view * Update changelog --------- Co-authored-by: Thomas Kaul <4159106+dtslvr@users.noreply.github.com> --- CHANGELOG.md | 8 +++++ .../allocations/allocations-page.component.ts | 19 ++++++----- .../allocations/allocations-page.html | 32 ++++++++----------- 3 files changed, 33 insertions(+), 26 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d6a539243..dff59ac5a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -17,6 +17,14 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Extended the terms of service for the _Ghostfolio_ SaaS (cloud) to include _Paid Plans_ and _Refund Policy_ - Upgraded `prisma` from version `6.19.0` to `6.19.3` +### Fixed + +- Fixed the allocations by account chart on the allocations page in the _Presenter View_ +- Fixed the allocations by asset class chart on the allocations page in the _Presenter View_ +- Fixed the allocations by currency chart on the allocations page in the _Presenter View_ +- Fixed the allocations by ETF provider chart on the allocations page in the _Presenter View_ +- Fixed the allocations by platform chart on the allocations page in the _Presenter View_ + ## 2.252.0 - 2026-03-02 ### Added 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 367716d2d..b0282c937 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 @@ -159,10 +159,9 @@ export class GfAllocationsPageComponent implements OnInit { if (state?.user) { this.user = state.user; - this.worldMapChartFormat = - this.hasImpersonationId || this.user.settings.isRestrictedView - ? `{0}%` - : `{0} ${this.user?.settings?.baseCurrency}`; + this.worldMapChartFormat = this.showValuesInPercentage() + ? `{0}%` + : `{0} ${this.user?.settings?.baseCurrency}`; this.isLoading = true; @@ -310,7 +309,7 @@ export class GfAllocationsPageComponent implements OnInit { ] of Object.entries(this.portfolioDetails.accounts)) { let value = 0; - if (this.hasImpersonationId) { + if (this.showValuesInPercentage()) { value = valueInPercentage; } else { value = valueInBaseCurrency; @@ -328,7 +327,7 @@ export class GfAllocationsPageComponent implements OnInit { )) { let value = 0; - if (this.hasImpersonationId) { + if (this.showValuesInPercentage()) { value = position.allocationInPercentage; } else { value = position.valueInBaseCurrency; @@ -491,7 +490,7 @@ export class GfAllocationsPageComponent implements OnInit { ] of Object.entries(this.portfolioDetails.platforms)) { let value = 0; - if (this.hasImpersonationId) { + if (this.showValuesInPercentage()) { value = valueInPercentage; } else { value = valueInBaseCurrency; @@ -506,7 +505,7 @@ export class GfAllocationsPageComponent implements OnInit { this.topHoldings = Object.values(this.topHoldingsMap) .map(({ name, value }) => { - if (this.hasImpersonationId || this.user.settings.isRestrictedView) { + if (this.showValuesInPercentage()) { return { name, allocationInPercentage: value, @@ -597,4 +596,8 @@ export class GfAllocationsPageComponent implements OnInit { this.router.navigate(['.'], { relativeTo: this.route }); }); } + + public showValuesInPercentage() { + return this.hasImpersonationId || this.user?.settings?.isRestrictedView; + } } 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 8d5503840..0b75c6d8f 100644 --- a/apps/client/src/app/pages/portfolio/allocations/allocations-page.html +++ b/apps/client/src/app/pages/portfolio/allocations/allocations-page.html @@ -25,11 +25,9 @@ @@ -49,7 +47,7 @@ [baseCurrency]="user?.settings?.baseCurrency" [colorScheme]="user?.settings?.colorScheme" [data]="platforms" - [isInPercent]="hasImpersonationId || user.settings.isRestrictedView" + [isInPercent]="showValuesInPercentage()" [keys]="['id']" [locale]="user?.settings?.locale" /> @@ -71,7 +69,7 @@ [baseCurrency]="user?.settings?.baseCurrency" [colorScheme]="user?.settings?.colorScheme" [data]="holdings" - [isInPercent]="hasImpersonationId || user.settings.isRestrictedView" + [isInPercent]="showValuesInPercentage()" [keys]="['currency']" [locale]="user?.settings?.locale" /> @@ -93,7 +91,7 @@ [baseCurrency]="user?.settings?.baseCurrency" [colorScheme]="user?.settings?.colorScheme" [data]="holdings" - [isInPercent]="hasImpersonationId || user.settings.isRestrictedView" + [isInPercent]="showValuesInPercentage()" [keys]="['assetClassLabel', 'assetSubClassLabel']" [locale]="user?.settings?.locale" /> @@ -114,7 +112,7 @@ [baseCurrency]="user?.settings?.baseCurrency" [colorScheme]="user?.settings?.colorScheme" [data]="symbols" - [isInPercent]="hasImpersonationId || user.settings.isRestrictedView" + [isInPercent]="showValuesInPercentage()" [keys]="['symbol']" [locale]="user?.settings?.locale" [showLabels]="deviceType !== 'mobile'" @@ -138,7 +136,7 @@ [baseCurrency]="user?.settings?.baseCurrency" [colorScheme]="user?.settings?.colorScheme" [data]="sectors" - [isInPercent]="hasImpersonationId || user.settings.isRestrictedView" + [isInPercent]="showValuesInPercentage()" [keys]="['name']" [locale]="user?.settings?.locale" [maxItems]="10" @@ -161,7 +159,7 @@ [baseCurrency]="user?.settings?.baseCurrency" [colorScheme]="user?.settings?.colorScheme" [data]="continents" - [isInPercent]="hasImpersonationId || user.settings.isRestrictedView" + [isInPercent]="showValuesInPercentage()" [keys]="['name']" [locale]="user?.settings?.locale" /> @@ -183,7 +181,7 @@ [baseCurrency]="user?.settings?.baseCurrency" [colorScheme]="user?.settings?.colorScheme" [data]="marketsAdvanced" - [isInPercent]="hasImpersonationId || user.settings.isRestrictedView" + [isInPercent]="showValuesInPercentage()" [locale]="user?.settings?.locale" /> @@ -206,9 +204,7 @@
    @@ -272,7 +268,7 @@ [baseCurrency]="user?.settings?.baseCurrency" [colorScheme]="user?.settings?.colorScheme" [data]="countries" - [isInPercent]="hasImpersonationId || user.settings.isRestrictedView" + [isInPercent]="showValuesInPercentage()" [keys]="['name']" [locale]="user?.settings?.locale" [maxItems]="10" @@ -291,7 +287,7 @@ [baseCurrency]="user?.settings?.baseCurrency" [colorScheme]="user?.settings?.colorScheme" [data]="accounts" - [isInPercent]="hasImpersonationId || user.settings.isRestrictedView" + [isInPercent]="showValuesInPercentage()" [keys]="['id']" [locale]="user?.settings?.locale" (proportionChartClicked)="onAccountChartClicked($event)" @@ -314,7 +310,7 @@ [baseCurrency]="user?.settings?.baseCurrency" [colorScheme]="user?.settings?.colorScheme" [data]="holdings" - [isInPercent]="hasImpersonationId || user.settings.isRestrictedView" + [isInPercent]="showValuesInPercentage()" [keys]="['etfProvider']" [locale]="user?.settings?.locale" /> From cebf15284e73884a57da725dc5c715b699812e91 Mon Sep 17 00:00:00 2001 From: Thomas Kaul <4159106+dtslvr@users.noreply.github.com> Date: Mon, 6 Apr 2026 15:43:16 +0200 Subject: [PATCH 220/224] Task/refactor input in world map chart component (#6692) Refactor input to isInPercentage --- .../src/app/pages/portfolio/allocations/allocations-page.html | 2 +- apps/client/src/app/pages/public/public-page.html | 2 +- .../lib/world-map-chart/world-map-chart.component.stories.ts | 4 ++-- libs/ui/src/lib/world-map-chart/world-map-chart.component.ts | 4 ++-- 4 files changed, 6 insertions(+), 6 deletions(-) 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 0b75c6d8f..530b528e6 100644 --- a/apps/client/src/app/pages/portfolio/allocations/allocations-page.html +++ b/apps/client/src/app/pages/portfolio/allocations/allocations-page.html @@ -204,7 +204,7 @@ diff --git a/apps/client/src/app/pages/public/public-page.html b/apps/client/src/app/pages/public/public-page.html index c422f9006..53132442b 100644 --- a/apps/client/src/app/pages/public/public-page.html +++ b/apps/client/src/app/pages/public/public-page.html @@ -154,7 +154,7 @@
    diff --git a/libs/ui/src/lib/world-map-chart/world-map-chart.component.stories.ts b/libs/ui/src/lib/world-map-chart/world-map-chart.component.stories.ts index bdc983ae3..6d9d85295 100644 --- a/libs/ui/src/lib/world-map-chart/world-map-chart.component.stories.ts +++ b/libs/ui/src/lib/world-map-chart/world-map-chart.component.stories.ts @@ -44,7 +44,7 @@ export const Default: Story = { }) ), format: `{0} ${DEFAULT_CURRENCY}`, - isInPercent: false + isInPercentage: false } }; @@ -52,6 +52,6 @@ export const InPercentage: Story = { args: { countries: VWRL_COUNTRY_ALLOCATION, format: '{0}%', - isInPercent: true + isInPercentage: true } }; diff --git a/libs/ui/src/lib/world-map-chart/world-map-chart.component.ts b/libs/ui/src/lib/world-map-chart/world-map-chart.component.ts index 2a926cf7c..f86d4d010 100644 --- a/libs/ui/src/lib/world-map-chart/world-map-chart.component.ts +++ b/libs/ui/src/lib/world-map-chart/world-map-chart.component.ts @@ -21,7 +21,7 @@ import svgMap from 'svgmap'; export class GfWorldMapChartComponent implements OnChanges, OnDestroy { @Input() countries: { [code: string]: { name?: string; value: number } }; @Input() format: string; - @Input() isInPercent = false; + @Input() isInPercentage = false; @Input() locale = getLocale(); public isLoading = true; @@ -47,7 +47,7 @@ export class GfWorldMapChartComponent implements OnChanges, OnDestroy { } private initialize() { - if (this.isInPercent) { + if (this.isInPercentage) { // Convert value of countries to percentage let sum = 0; Object.keys(this.countries).map((country) => { From 71ffd045cf75497f8324a271d6f05578ff6c3113 Mon Sep 17 00:00:00 2001 From: Thomas Kaul <4159106+dtslvr@users.noreply.github.com> Date: Mon, 6 Apr 2026 15:44:31 +0200 Subject: [PATCH 221/224] Task/refactor input in investment chart component (#6693) * Refactor input to isInPercentage --- .../account-detail-dialog.html | 2 +- .../investment-chart/investment-chart.component.ts | 14 +++++++------- .../pages/portfolio/analysis/analysis-page.html | 12 +++++++++--- 3 files changed, 17 insertions(+), 11 deletions(-) diff --git a/apps/client/src/app/components/account-detail-dialog/account-detail-dialog.html b/apps/client/src/app/components/account-detail-dialog/account-detail-dialog.html index e41d3415c..54e786734 100644 --- a/apps/client/src/app/components/account-detail-dialog/account-detail-dialog.html +++ b/apps/client/src/app/components/account-detail-dialog/account-detail-dialog.html @@ -24,7 +24,7 @@ class="h-100" [currency]="user?.settings?.baseCurrency" [historicalDataItems]="historicalDataItems" - [isInPercent]=" + [isInPercentage]=" data.hasImpersonationId || user.settings.isRestrictedView " [isLoading]="isLoadingChart" diff --git a/apps/client/src/app/components/investment-chart/investment-chart.component.ts b/apps/client/src/app/components/investment-chart/investment-chart.component.ts index 53d4f5693..21a7ac85a 100644 --- a/apps/client/src/app/components/investment-chart/investment-chart.component.ts +++ b/apps/client/src/app/components/investment-chart/investment-chart.component.ts @@ -61,7 +61,7 @@ export class GfInvestmentChartComponent implements OnChanges, OnDestroy { @Input() currency: string; @Input() groupBy: GroupBy; @Input() historicalDataItems: LineChartItem[] = []; - @Input() isInPercent = false; + @Input() isInPercentage = false; @Input() isLoading = false; @Input() locale = getLocale(); @Input() savingsRate = 0; @@ -119,7 +119,7 @@ export class GfInvestmentChartComponent implements OnChanges, OnDestroy { data: this.investments.map(({ date, investment }) => { return { x: parseDate(date).getTime(), - y: this.isInPercent ? investment * 100 : investment + y: this.isInPercentage ? investment * 100 : investment }; }), label: this.benchmarkDataLabel, @@ -139,7 +139,7 @@ export class GfInvestmentChartComponent implements OnChanges, OnDestroy { data: this.values.map(({ date, value }) => { return { x: parseDate(date).getTime(), - y: this.isInPercent ? value * 100 : value + y: this.isInPercentage ? value * 100 : value }; }), fill: false, @@ -251,7 +251,7 @@ export class GfInvestmentChartComponent implements OnChanges, OnDestroy { border: { display: false }, - display: !this.isInPercent, + display: !this.isInPercentage, grid: { color: ({ scale, tick }) => { if ( @@ -292,10 +292,10 @@ export class GfInvestmentChartComponent implements OnChanges, OnDestroy { return { ...getTooltipOptions({ colorScheme: this.colorScheme, - currency: this.isInPercent ? undefined : this.currency, + currency: this.isInPercentage ? undefined : this.currency, groupBy: this.groupBy, - locale: this.isInPercent ? undefined : this.locale, - unit: this.isInPercent ? '%' : undefined + locale: this.isInPercentage ? undefined : this.locale, + unit: this.isInPercentage ? '%' : undefined }), mode: 'index', position: 'top', diff --git a/apps/client/src/app/pages/portfolio/analysis/analysis-page.html b/apps/client/src/app/pages/portfolio/analysis/analysis-page.html index 517ad7101..c4e8f610b 100644 --- a/apps/client/src/app/pages/portfolio/analysis/analysis-page.html +++ b/apps/client/src/app/pages/portfolio/analysis/analysis-page.html @@ -417,7 +417,9 @@ [benchmarkDataLabel]="portfolioEvolutionDataLabel" [currency]="user?.settings?.baseCurrency" [historicalDataItems]="performanceDataItems" - [isInPercent]="hasImpersonationId || user.settings.isRestrictedView" + [isInPercentage]=" + hasImpersonationId || user.settings.isRestrictedView + " [isLoading]="isLoadingInvestmentChart" [locale]="user?.settings?.locale" /> @@ -473,7 +475,9 @@ [benchmarkDataLabel]="investmentTimelineDataLabel" [currency]="user?.settings?.baseCurrency" [groupBy]="mode" - [isInPercent]="hasImpersonationId || user.settings.isRestrictedView" + [isInPercentage]=" + hasImpersonationId || user.settings.isRestrictedView + " [isLoading]="isLoadingInvestmentTimelineChart" [locale]="user?.settings?.locale" [savingsRate]="savingsRate" @@ -508,7 +512,9 @@ [benchmarkDataLabel]="dividendTimelineDataLabel" [currency]="user?.settings?.baseCurrency" [groupBy]="mode" - [isInPercent]="hasImpersonationId || user.settings.isRestrictedView" + [isInPercentage]=" + hasImpersonationId || user.settings.isRestrictedView + " [isLoading]="isLoadingDividendTimelineChart" [locale]="user?.settings?.locale" /> From b32f24a45c47f1560e7a7bdbdb0c04a4f312490f Mon Sep 17 00:00:00 2001 From: Thomas Kaul <4159106+dtslvr@users.noreply.github.com> Date: Mon, 6 Apr 2026 15:47:39 +0200 Subject: [PATCH 222/224] Task/refactor input in portfolio proportion chart component (#6691) * Refactor input to isInPercentage --- .../asset-profile-dialog.html | 4 ++-- .../holding-detail-dialog.html | 4 ++-- .../allocations/allocations-page.html | 20 +++++++++---------- .../src/app/pages/public/public-page.html | 8 ++++---- ...olio-proportion-chart.component.stories.ts | 2 +- .../portfolio-proportion-chart.component.ts | 6 +++--- 6 files changed, 22 insertions(+), 22 deletions(-) diff --git a/apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html b/apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html index 6b3141bfe..7354ca5f8 100644 --- a/apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html +++ b/apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html @@ -280,7 +280,7 @@ @@ -290,7 +290,7 @@ diff --git a/apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html b/apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html index b8cb8dda2..11771dee2 100644 --- a/apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html +++ b/apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html @@ -286,7 +286,7 @@ [baseCurrency]="data.baseCurrency" [colorScheme]="data.colorScheme" [data]="sectors" - [isInPercent]="true" + [isInPercentage]="true" [keys]="['name']" [locale]="data.locale" [maxItems]="10" @@ -298,7 +298,7 @@ [baseCurrency]="data.baseCurrency" [colorScheme]="data.colorScheme" [data]="countries" - [isInPercent]="true" + [isInPercentage]="true" [keys]="['name']" [locale]="data.locale" [maxItems]="10" 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 530b528e6..33431ce5d 100644 --- a/apps/client/src/app/pages/portfolio/allocations/allocations-page.html +++ b/apps/client/src/app/pages/portfolio/allocations/allocations-page.html @@ -47,7 +47,7 @@ [baseCurrency]="user?.settings?.baseCurrency" [colorScheme]="user?.settings?.colorScheme" [data]="platforms" - [isInPercent]="showValuesInPercentage()" + [isInPercentage]="showValuesInPercentage()" [keys]="['id']" [locale]="user?.settings?.locale" /> @@ -69,7 +69,7 @@ [baseCurrency]="user?.settings?.baseCurrency" [colorScheme]="user?.settings?.colorScheme" [data]="holdings" - [isInPercent]="showValuesInPercentage()" + [isInPercentage]="showValuesInPercentage()" [keys]="['currency']" [locale]="user?.settings?.locale" /> @@ -91,7 +91,7 @@ [baseCurrency]="user?.settings?.baseCurrency" [colorScheme]="user?.settings?.colorScheme" [data]="holdings" - [isInPercent]="showValuesInPercentage()" + [isInPercentage]="showValuesInPercentage()" [keys]="['assetClassLabel', 'assetSubClassLabel']" [locale]="user?.settings?.locale" /> @@ -112,7 +112,7 @@ [baseCurrency]="user?.settings?.baseCurrency" [colorScheme]="user?.settings?.colorScheme" [data]="symbols" - [isInPercent]="showValuesInPercentage()" + [isInPercentage]="showValuesInPercentage()" [keys]="['symbol']" [locale]="user?.settings?.locale" [showLabels]="deviceType !== 'mobile'" @@ -136,7 +136,7 @@ [baseCurrency]="user?.settings?.baseCurrency" [colorScheme]="user?.settings?.colorScheme" [data]="sectors" - [isInPercent]="showValuesInPercentage()" + [isInPercentage]="showValuesInPercentage()" [keys]="['name']" [locale]="user?.settings?.locale" [maxItems]="10" @@ -159,7 +159,7 @@ [baseCurrency]="user?.settings?.baseCurrency" [colorScheme]="user?.settings?.colorScheme" [data]="continents" - [isInPercent]="showValuesInPercentage()" + [isInPercentage]="showValuesInPercentage()" [keys]="['name']" [locale]="user?.settings?.locale" /> @@ -181,7 +181,7 @@ [baseCurrency]="user?.settings?.baseCurrency" [colorScheme]="user?.settings?.colorScheme" [data]="marketsAdvanced" - [isInPercent]="showValuesInPercentage()" + [isInPercentage]="showValuesInPercentage()" [locale]="user?.settings?.locale" /> @@ -268,7 +268,7 @@ [baseCurrency]="user?.settings?.baseCurrency" [colorScheme]="user?.settings?.colorScheme" [data]="countries" - [isInPercent]="showValuesInPercentage()" + [isInPercentage]="showValuesInPercentage()" [keys]="['name']" [locale]="user?.settings?.locale" [maxItems]="10" @@ -287,7 +287,7 @@ [baseCurrency]="user?.settings?.baseCurrency" [colorScheme]="user?.settings?.colorScheme" [data]="accounts" - [isInPercent]="showValuesInPercentage()" + [isInPercentage]="showValuesInPercentage()" [keys]="['id']" [locale]="user?.settings?.locale" (proportionChartClicked)="onAccountChartClicked($event)" @@ -310,7 +310,7 @@ [baseCurrency]="user?.settings?.baseCurrency" [colorScheme]="user?.settings?.colorScheme" [data]="holdings" - [isInPercent]="showValuesInPercentage()" + [isInPercentage]="showValuesInPercentage()" [keys]="['etfProvider']" [locale]="user?.settings?.locale" /> diff --git a/apps/client/src/app/pages/public/public-page.html b/apps/client/src/app/pages/public/public-page.html index 53132442b..9e5fd3748 100644 --- a/apps/client/src/app/pages/public/public-page.html +++ b/apps/client/src/app/pages/public/public-page.html @@ -73,7 +73,7 @@ @@ -98,7 +98,7 @@ @@ -115,7 +115,7 @@ @@ -134,7 +134,7 @@ diff --git a/libs/ui/src/lib/portfolio-proportion-chart/portfolio-proportion-chart.component.stories.ts b/libs/ui/src/lib/portfolio-proportion-chart/portfolio-proportion-chart.component.stories.ts index b5a3d6819..8ee9a4c7f 100644 --- a/libs/ui/src/lib/portfolio-proportion-chart/portfolio-proportion-chart.component.stories.ts +++ b/libs/ui/src/lib/portfolio-proportion-chart/portfolio-proportion-chart.component.stories.ts @@ -77,7 +77,7 @@ export const InPercentage: Story = { JP: { name: 'Japan', value: 0 }, BE: { name: 'Belgium', value: 0 } }, - isInPercent: true, + isInPercentage: true, keys: ['name'] } }; diff --git a/libs/ui/src/lib/portfolio-proportion-chart/portfolio-proportion-chart.component.ts b/libs/ui/src/lib/portfolio-proportion-chart/portfolio-proportion-chart.component.ts index 2f5d9e4f7..4021bf97f 100644 --- a/libs/ui/src/lib/portfolio-proportion-chart/portfolio-proportion-chart.component.ts +++ b/libs/ui/src/lib/portfolio-proportion-chart/portfolio-proportion-chart.component.ts @@ -74,7 +74,7 @@ export class GfPortfolioProportionChartComponent value: number; }; } = {}; - @Input() isInPercent = false; + @Input() isInPercentage = false; @Input() keys: string[] = []; @Input() locale = getLocale(); @Input() maxItems?: number; @@ -198,7 +198,7 @@ export class GfPortfolioProportionChartComponent }); } - if (this.isInPercent) { + if (this.isInPercentage) { const totalValueInPercentage = getSum( Object.values(chartData).map(({ value }) => { return value; @@ -465,7 +465,7 @@ export class GfPortfolioProportionChartComponent if ((context.raw as number) === Number.MAX_SAFE_INTEGER) { return $localize`No data available`; - } else if (this.isInPercent) { + } else if (this.isInPercentage) { return [`${name ?? symbol}`, `${percentage.toFixed(2)}%`]; } else { const value = context.raw as number; From 7c8cbb721f759dda9f4c29caeec5be1b3d01dce2 Mon Sep 17 00:00:00 2001 From: Thomas Kaul <4159106+dtslvr@users.noreply.github.com> Date: Mon, 6 Apr 2026 15:56:37 +0200 Subject: [PATCH 223/224] Release 2.253.0 (#6695) --- CHANGELOG.md | 2 +- package-lock.json | 4 ++-- package.json | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index dff59ac5a..6624570cf 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,7 +5,7 @@ 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 +## 2.253.0 - 2026-03-06 ### Added diff --git a/package-lock.json b/package-lock.json index 824703b65..9afcf7af7 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "ghostfolio", - "version": "2.252.0", + "version": "2.253.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "ghostfolio", - "version": "2.252.0", + "version": "2.253.0", "hasInstallScript": true, "license": "AGPL-3.0", "dependencies": { diff --git a/package.json b/package.json index 812aa4cfa..686065630 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "ghostfolio", - "version": "2.252.0", + "version": "2.253.0", "homepage": "https://ghostfol.io", "license": "AGPL-3.0", "repository": "https://github.com/ghostfolio/ghostfolio", From a58a3525e9d746054ed903241c14087a418be72d Mon Sep 17 00:00:00 2001 From: Thomas Kaul <4159106+dtslvr@users.noreply.github.com> Date: Tue, 7 Apr 2026 12:05:39 +0200 Subject: [PATCH 224/224] Task/clean up log in user account access component (#6697) Clean up --- .../user-account-access/user-account-access.component.ts | 2 -- 1 file changed, 2 deletions(-) diff --git a/apps/client/src/app/components/user-account-access/user-account-access.component.ts b/apps/client/src/app/components/user-account-access/user-account-access.component.ts index 4ca088775..f8620c745 100644 --- a/apps/client/src/app/components/user-account-access/user-account-access.component.ts +++ b/apps/client/src/app/components/user-account-access/user-account-access.component.ts @@ -212,8 +212,6 @@ export class GfUserAccountAccessComponent implements OnInit { }); if (!access) { - console.log('Could not find access.'); - return; }