diff --git a/CHANGELOG.md b/CHANGELOG.md
index 8bd42dc7e..419d4596e 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -5,6 +5,18 @@ 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 Portuguese (`pt`)
+- Upgraded `@keyv/redis` from version `4.3.4` to `4.4.0`
+- Upgraded `zone.js` from version `0.15.0` to `0.15.1`
+
+### Fixed
+
+- Restricted the date range change permission in the _Zen Mode_
+
## 2.169.0 - 2025-06-08
### Changed
diff --git a/apps/client/src/app/app.component.ts b/apps/client/src/app/app.component.ts
index 8b9348835..5e5a0b9eb 100644
--- a/apps/client/src/app/app.component.ts
+++ b/apps/client/src/app/app.component.ts
@@ -3,7 +3,11 @@ import { HoldingDetailDialogParams } from '@ghostfolio/client/components/holding
import { getCssVariable } from '@ghostfolio/common/helper';
import { InfoItem, User } from '@ghostfolio/common/interfaces';
import { hasPermission, permissions } from '@ghostfolio/common/permissions';
-import { publicRoutes, routes } from '@ghostfolio/common/routes/routes';
+import {
+ internalRoutes,
+ publicRoutes,
+ routes
+} from '@ghostfolio/common/routes/routes';
import { ColorScheme } from '@ghostfolio/common/types';
import { DOCUMENT } from '@angular/common';
@@ -160,12 +164,14 @@ export class AppComponent implements OnDestroy, OnInit {
this.currentSubRoute = urlSegments[1]?.path;
if (
- (this.currentRoute === 'home' && !this.currentSubRoute) ||
- (this.currentRoute === 'home' &&
- this.currentSubRoute === 'holdings') ||
- (this.currentRoute === 'portfolio' && !this.currentSubRoute) ||
- (this.currentRoute === 'zen' && !this.currentSubRoute) ||
- (this.currentRoute === 'zen' && this.currentSubRoute === 'holdings')
+ ((this.currentRoute === internalRoutes.home.path &&
+ !this.currentSubRoute) ||
+ (this.currentRoute === internalRoutes.home.path &&
+ this.currentSubRoute ===
+ internalRoutes.home.subRoutes.holdings.path) ||
+ (this.currentRoute === internalRoutes.portfolio.path &&
+ !this.currentSubRoute)) &&
+ this.user?.settings?.viewMode !== 'ZEN'
) {
this.hasPermissionToChangeDateRange = true;
} else {
@@ -173,14 +179,19 @@ export class AppComponent implements OnDestroy, OnInit {
}
if (
- (this.currentRoute === 'home' &&
- this.currentSubRoute === 'holdings') ||
- (this.currentRoute === 'portfolio' && !this.currentSubRoute) ||
- (this.currentRoute === 'portfolio' &&
- this.currentSubRoute === 'activities') ||
- (this.currentRoute === 'portfolio' &&
- this.currentSubRoute === 'allocations') ||
- (this.currentRoute === 'zen' && this.currentSubRoute === 'holdings')
+ (this.currentRoute === internalRoutes.home.path &&
+ this.currentSubRoute ===
+ internalRoutes.home.subRoutes.holdings.path) ||
+ (this.currentRoute === internalRoutes.portfolio.path &&
+ !this.currentSubRoute) ||
+ (this.currentRoute === internalRoutes.portfolio.path &&
+ this.currentSubRoute ===
+ internalRoutes.portfolio.subRoutes.activities.path) ||
+ (this.currentRoute === internalRoutes.portfolio.path &&
+ this.currentSubRoute === routes.allocations) ||
+ (this.currentRoute === internalRoutes.zen.path &&
+ this.currentSubRoute ===
+ internalRoutes.home.subRoutes.holdings.path)
) {
this.hasPermissionToChangeFilters = true;
} else {
@@ -188,25 +199,25 @@ export class AppComponent implements OnDestroy, OnInit {
}
this.hasTabs =
- (this.currentRoute === this.routerLinkAbout[0].slice(1) ||
- this.currentRoute === this.routerLinkFaq[0].slice(1) ||
- this.currentRoute === this.routerLinkResources[0].slice(1) ||
- this.currentRoute === 'account' ||
- this.currentRoute === 'admin' ||
- this.currentRoute === 'home' ||
- this.currentRoute === 'portfolio' ||
- this.currentRoute === 'zen') &&
+ (this.currentRoute === routes.about ||
+ this.currentRoute === routes.faq ||
+ this.currentRoute === routes.resources ||
+ this.currentRoute === routes.account ||
+ this.currentRoute === routes.adminControl ||
+ this.currentRoute === internalRoutes.home.path ||
+ this.currentRoute === internalRoutes.portfolio.path ||
+ this.currentRoute === internalRoutes.zen.path) &&
this.deviceType !== 'mobile';
this.showFooter =
- (this.currentRoute === 'blog' ||
- this.currentRoute === this.routerLinkFeatures[0].slice(1) ||
- this.currentRoute === this.routerLinkMarkets[0].slice(1) ||
- this.currentRoute === 'open' ||
- this.currentRoute === 'p' ||
- this.currentRoute === this.routerLinkPricing[0].slice(1) ||
- this.currentRoute === this.routerLinkRegister[0].slice(1) ||
- this.currentRoute === 'start') &&
+ (this.currentRoute === routes.blog ||
+ this.currentRoute === routes.features ||
+ this.currentRoute === routes.markets ||
+ this.currentRoute === publicRoutes.openStartup.path ||
+ this.currentRoute === routes.public ||
+ this.currentRoute === routes.pricing ||
+ this.currentRoute === publicRoutes.register.path ||
+ this.currentRoute === routes.start) &&
this.deviceType !== 'mobile';
if (this.deviceType === 'mobile') {
diff --git a/apps/client/src/locales/messages.pt.xlf b/apps/client/src/locales/messages.pt.xlf
index 167938e6a..5acde7d90 100644
--- a/apps/client/src/locales/messages.pt.xlf
+++ b/apps/client/src/locales/messages.pt.xlf
@@ -5095,7 +5095,7 @@
Are you ready?
- Are you ready?
+ São you preparar?
apps/client/src/app/pages/landing/landing-page.html
431
@@ -5216,7 +5216,7 @@
This overview page features a curated collection of personal finance tools compared to the open source alternative Ghostfolio. If you value transparency, data privacy, and community collaboration, Ghostfolio provides an excellent opportunity to take control of your financial management.
- This overview page features a curated collection of personal finance tools compared to the open source alternative Ghostfolio. If you value transparency, data privacy, and community collaboration, Ghostfolio provides an excellent opportunity to take control of your financial management.
+ Esta página de visão geral apresenta uma coleção selecionada de ferramentas de finanças pessoais em comparação com a alternativa de código abertoGhostfolio. Se você valoriza transparência, privacidade de dados e colaboração comunitária, o Ghostfolio oferece uma excelente oportunidade para assumir o controle de sua gestão financeira.
apps/client/src/app/pages/resources/personal-finance-tools/personal-finance-tools-page.html
8
@@ -5589,7 +5589,7 @@
Search
- Search
+ Procurar
apps/client/src/app/components/admin-market-data/create-asset-profile-dialog/create-asset-profile-dialog.html
16
@@ -5621,7 +5621,7 @@
User
- User
+ Usuário
apps/client/src/app/components/admin-users/admin-users.html
29
@@ -5637,7 +5637,7 @@
Open Source Wealth Management Software
- Open Source Wealth Management Software
+ Software de gerenciamento de patrimônio de código aberto
apps/client/src/app/pages/i18n/i18n-page.html
30
@@ -5645,7 +5645,7 @@
app, asset, cryptocurrency, dashboard, etf, finance, management, performance, portfolio, software, stock, trading, wealth, web3
- app, asset, cryptocurrency, dashboard, etf, finance, management, performance, portfolio, software, stock, trading, wealth, web3
+ aplicativo, ativo, criptomoeda, painel, etf, finanças, gestão, desempenho, portfólio, software, ação, negociação, riqueza, web3
apps/client/src/app/pages/i18n/i18n-page.html
9
@@ -5653,7 +5653,7 @@
Oops, cash balance transfer has failed.
- Oops, cash balance transfer has failed.
+ Ops, a transferência do saldo em dinheiro falhou.
apps/client/src/app/pages/accounts/accounts-page.component.ts
318
@@ -5661,7 +5661,7 @@
Extreme Fear
- Extreme Fear
+ Medo Extremo
libs/ui/src/lib/i18n.ts
100
@@ -5669,7 +5669,7 @@
Extreme Greed
- Extreme Greed
+ Ganância Extrema
libs/ui/src/lib/i18n.ts
101
@@ -5677,7 +5677,7 @@
Neutral
- Neutral
+ Neutro
libs/ui/src/lib/i18n.ts
104
@@ -5685,7 +5685,7 @@
Oops! Could not parse historical data.
- Oops! Could not parse historical data.
+ 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
@@ -5693,7 +5693,7 @@
Do you really want to delete this system message?
- Do you really want to delete this system message?
+ Você realmente deseja excluir esta mensagem do sistema?
apps/client/src/app/components/admin-overview/admin-overview.component.ts
155
@@ -5701,7 +5701,7 @@
50-Day Trend
- 50-Day Trend
+ Tendência de 50 dias
libs/ui/src/lib/benchmark/benchmark.component.html
25
@@ -5709,7 +5709,7 @@
200-Day Trend
- 200-Day Trend
+ Tendência de 200 dias
libs/ui/src/lib/benchmark/benchmark.component.html
54
@@ -5717,7 +5717,7 @@
Cash Balances
- Cash Balances
+ Saldos de caixa
apps/client/src/app/components/account-detail-dialog/account-detail-dialog.html
124
@@ -5725,7 +5725,7 @@
Starting from
- Starting from
+ A partir de
apps/client/src/app/pages/resources/personal-finance-tools/product-page.html
289
@@ -5737,7 +5737,7 @@
year
- year
+ ano
apps/client/src/app/pages/resources/personal-finance-tools/product-page.html
290
@@ -5749,7 +5749,7 @@
Do you really want to delete this account balance?
- Do you really want to delete this account balance?
+ Você realmente deseja excluir o saldo desta conta?
libs/ui/src/lib/account-balances/account-balances.component.ts
109
@@ -5757,7 +5757,7 @@
If a translation is missing, kindly support us in extending it here.
- If a translation is missing, kindly support us in extending it here.
+ Se faltar uma tradução, por favor, ajude-nos a estendê-la here.
apps/client/src/app/components/user-account-settings/user-account-settings.html
58
@@ -5765,7 +5765,7 @@
The current market price is
- The current market price is
+ O preço de mercado atual é
apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts
536
@@ -5773,7 +5773,7 @@
Test
- Test
+ Teste
apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html
473
@@ -5781,7 +5781,7 @@
Date Range
- Date Range
+ Período
libs/ui/src/lib/assistant/assistant.html
95
@@ -5801,7 +5801,7 @@
Restricted view
- Restricted view
+ Visualização restrita
apps/client/src/app/components/access-table/access-table.component.html
26
@@ -5813,7 +5813,7 @@
Oops! Could not grant access.
- Oops! Could not grant access.
+ Ops! Não foi possível conceder acesso.
apps/client/src/app/components/user-account-access/create-or-update-access-dialog/create-or-update-access-dialog.component.ts
91
@@ -5821,7 +5821,7 @@
Private
- Private
+ Privado
apps/client/src/app/components/user-account-access/create-or-update-access-dialog/create-or-update-access-dialog.html
24
@@ -5829,7 +5829,7 @@
Job Queue
- Job Queue
+ Fila de trabalhos
apps/client/src/app/pages/admin/admin-page-routing.module.ts
26
diff --git a/package-lock.json b/package-lock.json
index f32b2412e..6a585a001 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -30,7 +30,7 @@
"@dfinity/principal": "0.15.7",
"@dinero.js/currencies": "2.0.0-alpha.8",
"@internationalized/number": "3.6.0",
- "@keyv/redis": "4.3.4",
+ "@keyv/redis": "4.4.0",
"@nestjs/bull": "11.0.2",
"@nestjs/cache-manager": "3.0.1",
"@nestjs/common": "11.1.3",
@@ -90,7 +90,7 @@
"twitter-api-v2": "1.23.0",
"uuid": "11.1.0",
"yahoo-finance2": "3.3.5",
- "zone.js": "0.15.0"
+ "zone.js": "0.15.1"
},
"devDependencies": {
"@angular-devkit/build-angular": "19.2.1",
@@ -4962,13 +4962,13 @@
}
},
"node_modules/@keyv/redis": {
- "version": "4.3.4",
- "resolved": "https://registry.npmjs.org/@keyv/redis/-/redis-4.3.4.tgz",
- "integrity": "sha512-PLWmawfq9McxEvtHa2Uj5WjI7g6qWtv2eOvXvXJ9tkwEV5vLkqA+pFeZ/0pz9xvP20NQiAkGm4521YJ0DhuFiw==",
+ "version": "4.4.0",
+ "resolved": "https://registry.npmjs.org/@keyv/redis/-/redis-4.4.0.tgz",
+ "integrity": "sha512-n/KEj3S7crVkoykggqsMUtcjNGvjagGPlJYgO/r6m9hhGZfhp1txJElHxcdJ1ANi/LJoBuOSILj15g6HD2ucqQ==",
"license": "MIT",
"dependencies": {
- "cluster-key-slot": "^1.1.2",
- "redis": "^4.7.0"
+ "@redis/client": "^1.6.0",
+ "cluster-key-slot": "^1.1.2"
},
"engines": {
"node": ">= 18"
@@ -9875,19 +9875,10 @@
"@prisma/debug": "6.8.2"
}
},
- "node_modules/@redis/bloom": {
- "version": "1.2.0",
- "resolved": "https://registry.npmjs.org/@redis/bloom/-/bloom-1.2.0.tgz",
- "integrity": "sha512-HG2DFjYKbpNmVXsa0keLHp/3leGJz1mjh09f2RLGGLQZzSHpkmZWuwJbAvo3QcRY8p80m5+ZdXZdYOSBLlp7Cg==",
- "license": "MIT",
- "peerDependencies": {
- "@redis/client": "^1.0.0"
- }
- },
"node_modules/@redis/client": {
- "version": "1.6.0",
- "resolved": "https://registry.npmjs.org/@redis/client/-/client-1.6.0.tgz",
- "integrity": "sha512-aR0uffYI700OEEH4gYnitAnv3vzVGXCFvYfdpu/CJKvk4pHfLPEy/JSZyrpQ+15WhXe1yJRXLtfQ84s4mEXnPg==",
+ "version": "1.6.1",
+ "resolved": "https://registry.npmjs.org/@redis/client/-/client-1.6.1.tgz",
+ "integrity": "sha512-/KCsg3xSlR+nCK8/8ZYSknYxvXHwubJrU82F3Lm1Fp6789VQ0/3RJKfsmRXjqfaTA++23CvC3hqmqe/2GEt6Kw==",
"license": "MIT",
"dependencies": {
"cluster-key-slot": "1.1.2",
@@ -9898,42 +9889,6 @@
"node": ">=14"
}
},
- "node_modules/@redis/graph": {
- "version": "1.1.1",
- "resolved": "https://registry.npmjs.org/@redis/graph/-/graph-1.1.1.tgz",
- "integrity": "sha512-FEMTcTHZozZciLRl6GiiIB4zGm5z5F3F6a6FZCyrfxdKOhFlGkiAqlexWMBzCi4DcRoyiOsuLfW+cjlGWyExOw==",
- "license": "MIT",
- "peerDependencies": {
- "@redis/client": "^1.0.0"
- }
- },
- "node_modules/@redis/json": {
- "version": "1.0.7",
- "resolved": "https://registry.npmjs.org/@redis/json/-/json-1.0.7.tgz",
- "integrity": "sha512-6UyXfjVaTBTJtKNG4/9Z8PSpKE6XgSyEb8iwaqDcy+uKrd/DGYHTWkUdnQDyzm727V7p21WUMhsqz5oy65kPcQ==",
- "license": "MIT",
- "peerDependencies": {
- "@redis/client": "^1.0.0"
- }
- },
- "node_modules/@redis/search": {
- "version": "1.2.0",
- "resolved": "https://registry.npmjs.org/@redis/search/-/search-1.2.0.tgz",
- "integrity": "sha512-tYoDBbtqOVigEDMAcTGsRlMycIIjwMCgD8eR2t0NANeQmgK/lvxNAvYyb6bZDD4frHRhIHkJu2TBRvB0ERkOmw==",
- "license": "MIT",
- "peerDependencies": {
- "@redis/client": "^1.0.0"
- }
- },
- "node_modules/@redis/time-series": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/@redis/time-series/-/time-series-1.1.0.tgz",
- "integrity": "sha512-c1Q99M5ljsIuc4YdaCwfUEXsofakb9c8+Zse2qxTadu8TalLXuAESzLvFAvNVbkmSlvlzIQOLpBCmWI9wTOt+g==",
- "license": "MIT",
- "peerDependencies": {
- "@redis/client": "^1.0.0"
- }
- },
"node_modules/@rollup/rollup-android-arm-eabi": {
"version": "4.34.8",
"resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.34.8.tgz",
@@ -29778,23 +29733,6 @@
"node": ">=8"
}
},
- "node_modules/redis": {
- "version": "4.7.0",
- "resolved": "https://registry.npmjs.org/redis/-/redis-4.7.0.tgz",
- "integrity": "sha512-zvmkHEAdGMn+hMRXuMBtu4Vo5P6rHQjLoHftu+lBqq8ZTA3RCVC/WzD790bkKKiNFp7d5/9PcSD19fJyyRvOdQ==",
- "license": "MIT",
- "workspaces": [
- "./packages/*"
- ],
- "dependencies": {
- "@redis/bloom": "1.2.0",
- "@redis/client": "1.6.0",
- "@redis/graph": "1.1.1",
- "@redis/json": "1.0.7",
- "@redis/search": "1.2.0",
- "@redis/time-series": "1.1.0"
- }
- },
"node_modules/redis-errors": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/redis-errors/-/redis-errors-1.2.0.tgz",
@@ -35854,9 +35792,9 @@
}
},
"node_modules/zone.js": {
- "version": "0.15.0",
- "resolved": "https://registry.npmjs.org/zone.js/-/zone.js-0.15.0.tgz",
- "integrity": "sha512-9oxn0IIjbCZkJ67L+LkhYWRyAy7axphb3VgE2MBDlOqnmHMPWGYMxJxBYFueFq/JGY2GMwS0rU+UCLunEmy5UA==",
+ "version": "0.15.1",
+ "resolved": "https://registry.npmjs.org/zone.js/-/zone.js-0.15.1.tgz",
+ "integrity": "sha512-XE96n56IQpJM7NAoXswY3XRLcWFW83xe0BiAOeMD7K5k5xecOeul3Qcpx6GqEeeHNkW5DWL5zOyTbEfB4eti8w==",
"license": "MIT"
}
}
diff --git a/package.json b/package.json
index 86cadad72..4ed3dc73b 100644
--- a/package.json
+++ b/package.json
@@ -76,7 +76,7 @@
"@dfinity/principal": "0.15.7",
"@dinero.js/currencies": "2.0.0-alpha.8",
"@internationalized/number": "3.6.0",
- "@keyv/redis": "4.3.4",
+ "@keyv/redis": "4.4.0",
"@nestjs/bull": "11.0.2",
"@nestjs/cache-manager": "3.0.1",
"@nestjs/common": "11.1.3",
@@ -136,7 +136,7 @@
"twitter-api-v2": "1.23.0",
"uuid": "11.1.0",
"yahoo-finance2": "3.3.5",
- "zone.js": "0.15.0"
+ "zone.js": "0.15.1"
},
"devDependencies": {
"@angular-devkit/build-angular": "19.2.1",