Browse Source

Merge remote-tracking branch 'upstream/feature/migrate-from-angular-material-design-2-to-3' into feature/restore-bg-color-of-fab

pull/5322/head
KenTandrian 3 weeks ago
parent
commit
15dddabab8
  1. 24
      CHANGELOG.md
  2. 2
      DEVELOPMENT.md
  3. 52
      apps/api/src/app/endpoints/sitemap/sitemap.service.ts
  4. 7
      apps/api/src/app/export/export.service.ts
  5. 5
      apps/api/src/app/user/user.service.ts
  6. 10
      apps/api/src/middlewares/html-template.middleware.ts
  7. 4
      apps/api/src/services/tag/tag.service.ts
  8. 4
      apps/client/src/app/components/header/header.component.html
  9. 14
      apps/client/src/index.html
  10. 30
      apps/client/src/locales/messages.ca.xlf
  11. 2
      apps/client/src/locales/messages.de.xlf
  12. 34
      apps/client/src/locales/messages.es.xlf
  13. 34
      apps/client/src/locales/messages.pl.xlf
  14. 7
      apps/client/src/styles.scss
  15. 14
      apps/client/src/styles/theme.scss
  16. 6
      package-lock.json
  17. 6
      package.json

24
CHANGELOG.md

@ -11,6 +11,30 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Migrated from _Material Design_ 2 to _Material Design_ 3 - Migrated from _Material Design_ 2 to _Material Design_ 3
## Next
### Changed
- Migrated from _Material Design_ 2 to _Material Design_ 3
## 2.189.0 - 2025-08-05
### Changed
- Improved the meta data in `html` files
- Removed `ts-node` from the database seeding process
- Improved the language localization for Catalan (`ca`)
- Improved the language localization for German (`de`)
- Upgraded the `Node.js` engine from version `>=22` to `>=22.18.0` (`package.json`)
## 2.188.0 - 2025-08-02
### Changed
- Enhanced the performance of the dynamically composed sitemap
- Improved the language localization for Polish (`pl`)
- Improved the language localization for Spanish (`es`)
## 2.187.0 - 2025-08-02 ## 2.187.0 - 2025-08-02
### Added ### Added

2
DEVELOPMENT.md

@ -5,7 +5,7 @@
### Prerequisites ### Prerequisites
- [Docker](https://www.docker.com/products/docker-desktop) - [Docker](https://www.docker.com/products/docker-desktop)
- [Node.js](https://nodejs.org/en/download) (version 22+) - [Node.js](https://nodejs.org/en/download) (version `>=22.18.0`)
- Create a local copy of this Git repository (clone) - Create a local copy of this Git repository (clone)
- Copy the file `.env.dev` to `.env` and populate it with your data (`cp .env.dev .env`) - Copy the file `.env.dev` to `.env` and populate it with your data (`cp .env.dev .env`)

52
apps/api/src/app/endpoints/sitemap/sitemap.service.ts

@ -21,18 +21,42 @@ export class SitemapService {
const rootUrl = this.configurationService.get('ROOT_URL'); const rootUrl = this.configurationService.get('ROOT_URL');
return SUPPORTED_LANGUAGE_CODES.flatMap((languageCode) => { return SUPPORTED_LANGUAGE_CODES.flatMap((languageCode) => {
const resourcesPath = this.i18nService.getTranslation({
languageCode,
id: publicRoutes.resources.path.match(
SitemapService.TRANSLATION_TAGGED_MESSAGE_REGEX
).groups.id
});
const personalFinanceToolsPath = this.i18nService.getTranslation({
languageCode,
id: publicRoutes.resources.subRoutes.personalFinanceTools.path.match(
SitemapService.TRANSLATION_TAGGED_MESSAGE_REGEX
).groups.id
});
const productPath = this.i18nService.getTranslation({
languageCode,
id: publicRoutes.resources.subRoutes.personalFinanceTools.subRoutes.product.path.match(
SitemapService.TRANSLATION_TAGGED_MESSAGE_REGEX
).groups.id
});
return personalFinanceTools.map(({ alias, key }) => { return personalFinanceTools.map(({ alias, key }) => {
const route = const location = [
publicRoutes.resources.subRoutes.personalFinanceTools.subRoutes
.product;
const params = {
currentDate,
languageCode,
rootUrl, rootUrl,
urlPostfix: alias ?? key languageCode,
}; resourcesPath,
personalFinanceToolsPath,
return this.createRouteSitemapUrl({ ...params, route }); `${productPath}-${alias ?? key}`
].join('/');
return [
' <url>',
` <loc>${location}</loc>`,
` <lastmod>${currentDate}T00:00:00+00:00</lastmod>`,
' </url>'
].join('\n');
}); });
}).join('\n'); }).join('\n');
} }
@ -58,14 +82,12 @@ export class SitemapService {
currentDate, currentDate,
languageCode, languageCode,
rootUrl, rootUrl,
route, route
urlPostfix
}: { }: {
currentDate: string; currentDate: string;
languageCode: string; languageCode: string;
rootUrl: string; rootUrl: string;
route?: PublicRoute; route?: PublicRoute;
urlPostfix?: string;
}): string { }): string {
const segments = const segments =
route?.routerLink.map((link) => { route?.routerLink.map((link) => {
@ -83,9 +105,7 @@ export class SitemapService {
return segment.replace(/^\/+|\/+$/, ''); return segment.replace(/^\/+|\/+$/, '');
}) ?? []; }) ?? [];
const location = const location = [rootUrl, languageCode, ...segments].join('/');
[rootUrl, languageCode, ...segments].join('/') +
(urlPostfix ? `-${urlPostfix}` : '');
return [ return [
' <url>', ' <url>',

7
apps/api/src/app/export/export.service.ts

@ -141,15 +141,16 @@ export class ExportService {
); );
const tags = (await this.tagService.getTagsForUser(userId)) const tags = (await this.tagService.getTagsForUser(userId))
.filter( .filter(({ id, isUsed }) => {
({ id, isUsed }) => return (
isUsed && isUsed &&
activities.some((activity) => { activities.some((activity) => {
return activity.tags.some(({ id: tagId }) => { return activity.tags.some(({ id: tagId }) => {
return tagId === id; return tagId === id;
}); });
}) })
) );
})
.map(({ id, name }) => { .map(({ id, name }) => {
return { return {
id, id,

5
apps/api/src/app/user/user.service.ts

@ -28,6 +28,7 @@ import {
DEFAULT_LANGUAGE_CODE, DEFAULT_LANGUAGE_CODE,
PROPERTY_IS_READ_ONLY_MODE, PROPERTY_IS_READ_ONLY_MODE,
PROPERTY_SYSTEM_MESSAGE, PROPERTY_SYSTEM_MESSAGE,
TAG_ID_EXCLUDE_FROM_ANALYSIS,
locale locale
} from '@ghostfolio/common/config'; } from '@ghostfolio/common/config';
import { import {
@ -121,7 +122,9 @@ export class UserService {
const access = userData[0]; const access = userData[0];
const activitiesCount = userData[1]; const activitiesCount = userData[1];
const firstActivity = userData[2]; const firstActivity = userData[2];
let tags = userData[3]; let tags = userData[3].filter((tag) => {
return tag.id !== TAG_ID_EXCLUDE_FROM_ANALYSIS;
});
let systemMessage: SystemMessage; let systemMessage: SystemMessage;

10
apps/api/src/middlewares/html-template.middleware.ts

@ -154,13 +154,9 @@ export class HtmlTemplateMiddleware implements NestMiddleware {
if (filename === '/assets/LICENSE') { if (filename === '/assets/LICENSE') {
return true; return true;
} else if ( } else if (
filename.includes('auth/ey') || filename.endsWith('-de.fi') ||
filename.includes( filename.endsWith('-markets.sh') ||
'personal-finance-tools/open-source-alternative-to-de.fi' filename.includes('auth/ey')
) ||
filename.includes(
'personal-finance-tools/open-source-alternative-to-markets.sh'
)
) { ) {
return false; return false;
} }

4
apps/api/src/services/tag/tag.service.ts

@ -1,5 +1,4 @@
import { PrismaService } from '@ghostfolio/api/services/prisma/prisma.service'; import { PrismaService } from '@ghostfolio/api/services/prisma/prisma.service';
import { TAG_ID_EXCLUDE_FROM_ANALYSIS } from '@ghostfolio/common/config';
import { Injectable } from '@nestjs/common'; import { Injectable } from '@nestjs/common';
import { Prisma, Tag } from '@prisma/client'; import { Prisma, Tag } from '@prisma/client';
@ -80,8 +79,7 @@ export class TagService {
id, id,
name, name,
userId, userId,
isUsed: isUsed: _count.activities > 0
_count.activities > 0 && ![TAG_ID_EXCLUDE_FROM_ANALYSIS].includes(id)
})); }));
} }

4
apps/client/src/app/components/header/header.component.html

@ -12,7 +12,7 @@
</a> </a>
</div> </div>
<span class="gf-spacer"></span> <span class="gf-spacer"></span>
<ul class="alig-items-center d-flex list-inline m-0 px-2"> <ul class="align-items-center d-flex list-inline m-0 px-2">
<li class="list-inline-item"> <li class="list-inline-item">
<a <a
class="d-none d-sm-block rounded" class="d-none d-sm-block rounded"
@ -347,7 +347,7 @@
</a> </a>
</div> </div>
<span class="gf-spacer"></span> <span class="gf-spacer"></span>
<ul class="alig-items-center d-flex list-inline m-0 px-2"> <ul class="align-items-center d-flex list-inline m-0 px-2">
<li class="list-inline-item"> <li class="list-inline-item">
<a <a
class="d-none d-sm-block rounded" class="d-none d-sm-block rounded"

14
apps/client/src/index.html

@ -9,10 +9,7 @@
<meta content="${keywords}" name="keywords" /> <meta content="${keywords}" name="keywords" />
<meta content="yes" name="mobile-web-app-capable" /> <meta content="yes" name="mobile-web-app-capable" />
<meta content="summary_large_image" name="twitter:card" /> <meta content="summary_large_image" name="twitter:card" />
<meta <meta content="${description}" name="twitter:description" />
content="Ghostfolio is a personal finance dashboard to keep track of your assets like stocks, ETFs or cryptocurrencies"
name="twitter:description"
/>
<meta content="${rootUrl}/${featureGraphicPath}" name="twitter:image" /> <meta content="${rootUrl}/${featureGraphicPath}" name="twitter:image" />
<meta content="${title}" name="twitter:title" /> <meta content="${title}" name="twitter:title" />
<meta <meta
@ -20,13 +17,14 @@
name="viewport" name="viewport"
/> />
<meta content="#FFFFFF" name="theme-color" /> <meta content="#FFFFFF" name="theme-color" />
<meta content="" property="og:description" /> <meta content="${description}" property="og:description" />
<meta content="${rootUrl}/${featureGraphicPath}" property="og:image" />
<meta content="${languageCode}" property="og:locale" />
<meta content="${title}" property="og:site_name" />
<meta content="${title}" property="og:title" /> <meta content="${title}" property="og:title" />
<meta content="website" property="og:type" /> <meta content="website" property="og:type" />
<meta content="${rootUrl}${path}" property="og:url" />
<meta content="${rootUrl}/${featureGraphicPath}" property="og:image" />
<meta content="${currentDate}T00:00:00+00:00" property="og:updated_time" /> <meta content="${currentDate}T00:00:00+00:00" property="og:updated_time" />
<meta content="${title}" property="og:site_name" /> <meta content="${rootUrl}${path}" property="og:url" />
<link <link
href="../assets/apple-touch-icon.png" href="../assets/apple-touch-icon.png"

30
apps/client/src/locales/messages.ca.xlf

@ -1664,7 +1664,7 @@
</trans-unit> </trans-unit>
<trans-unit id="5303806780432428245" datatype="html"> <trans-unit id="5303806780432428245" datatype="html">
<source>Indonesia</source> <source>Indonesia</source>
<target state="new">Indonesia</target> <target state="translated">Indonèsia</target>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">libs/ui/src/lib/i18n.ts</context> <context context-type="sourcefile">libs/ui/src/lib/i18n.ts</context>
<context context-type="linenumber">88</context> <context context-type="linenumber">88</context>
@ -4049,7 +4049,7 @@
</trans-unit> </trans-unit>
<trans-unit id="79310201207169632" datatype="html"> <trans-unit id="79310201207169632" datatype="html">
<source>Exclude from Analysis</source> <source>Exclude from Analysis</source>
<target state="new">Exclude from Analysis</target> <target state="translated">Excluir de l’anàlisi</target>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/accounts/create-or-update-account-dialog/create-or-update-account-dialog.html</context> <context context-type="sourcefile">apps/client/src/app/pages/accounts/create-or-update-account-dialog/create-or-update-account-dialog.html</context>
<context context-type="linenumber">90</context> <context context-type="linenumber">90</context>
@ -4409,7 +4409,7 @@
</trans-unit> </trans-unit>
<trans-unit id="6962217007874959362" datatype="html"> <trans-unit id="6962217007874959362" datatype="html">
<source> Our official Ghostfolio Premium cloud offering is the easiest way to get started. Due to the time it saves, this will be the best option for most people. Revenue is used to cover operational costs for the hosting infrastructure and professional data providers, and to fund ongoing development. </source> <source> Our official Ghostfolio Premium cloud offering is the easiest way to get started. Due to the time it saves, this will be the best option for most people. Revenue is used to cover operational costs for the hosting infrastructure and professional data providers, and to fund ongoing development. </source>
<target state="new"> La nostra oferta oficial al núvol Ghostfolio Premium és la manera més senzilla de començar. A causa del temps que estalvia, aquesta serà la millor opció per a la majoria de la gent. Els ingressos s’utilitzen per cobrir els costos de la infraestructura d’allotjament i per finançar el desenvolupament en curs. </target> <target state="translated"> La nostra oferta oficial al núvol Ghostfolio Premium és la manera més senzilla de començar. A causa del temps que estalvia, aquesta serà la millor opció per a la majoria de la gent. Els ingressos s’utilitzen per cobrir els costos de la infraestructura d’allotjament i per finançar el desenvolupament en curs. </target>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/pricing/pricing-page.html</context> <context context-type="sourcefile">apps/client/src/app/pages/pricing/pricing-page.html</context>
<context context-type="linenumber">7</context> <context context-type="linenumber">7</context>
@ -5846,7 +5846,7 @@
</trans-unit> </trans-unit>
<trans-unit id="1189482335778578193" datatype="html"> <trans-unit id="1189482335778578193" datatype="html">
<source>Extreme Fear</source> <source>Extreme Fear</source>
<target state="new">Extreme Fear</target> <target state="translated">Por extrema</target>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">libs/ui/src/lib/i18n.ts</context> <context context-type="sourcefile">libs/ui/src/lib/i18n.ts</context>
<context context-type="linenumber">104</context> <context context-type="linenumber">104</context>
@ -5854,7 +5854,7 @@
</trans-unit> </trans-unit>
<trans-unit id="2634398159221205491" datatype="html"> <trans-unit id="2634398159221205491" datatype="html">
<source>Extreme Greed</source> <source>Extreme Greed</source>
<target state="new">Extreme Greed</target> <target state="translated">Avarícia extrema</target>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">libs/ui/src/lib/i18n.ts</context> <context context-type="sourcefile">libs/ui/src/lib/i18n.ts</context>
<context context-type="linenumber">105</context> <context context-type="linenumber">105</context>
@ -5862,7 +5862,7 @@
</trans-unit> </trans-unit>
<trans-unit id="3511545370905854666" datatype="html"> <trans-unit id="3511545370905854666" datatype="html">
<source>Neutral</source> <source>Neutral</source>
<target state="new">Neutral</target> <target state="translated">Neutral</target>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">libs/ui/src/lib/i18n.ts</context> <context context-type="sourcefile">libs/ui/src/lib/i18n.ts</context>
<context context-type="linenumber">108</context> <context context-type="linenumber">108</context>
@ -5870,7 +5870,7 @@
</trans-unit> </trans-unit>
<trans-unit id="1488866007739765367" datatype="html"> <trans-unit id="1488866007739765367" datatype="html">
<source>Valid until</source> <source>Valid until</source>
<target state="new">Valid until</target> <target state="translated">Vàlid fins a</target>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-settings/admin-settings.component.html</context> <context context-type="sourcefile">apps/client/src/app/components/admin-settings/admin-settings.component.html</context>
<context context-type="linenumber">74</context> <context context-type="linenumber">74</context>
@ -5882,7 +5882,7 @@
</trans-unit> </trans-unit>
<trans-unit id="8539938855673078773" datatype="html"> <trans-unit id="8539938855673078773" datatype="html">
<source>Time to add your first activity.</source> <source>Time to add your first activity.</source>
<target state="new">Time to add your first activity.</target> <target state="translated">És hora d’afegir la teva primera activitat.</target>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">libs/ui/src/lib/no-transactions-info/no-transactions-info.component.html</context> <context context-type="sourcefile">libs/ui/src/lib/no-transactions-info/no-transactions-info.component.html</context>
<context context-type="linenumber">12</context> <context context-type="linenumber">12</context>
@ -5890,7 +5890,7 @@
</trans-unit> </trans-unit>
<trans-unit id="4893616715766810081" datatype="html"> <trans-unit id="4893616715766810081" datatype="html">
<source>No data available</source> <source>No data available</source>
<target state="new">No data available</target> <target state="translated">No hi ha dades disponibles</target>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/portfolio/allocations/allocations-page.html</context> <context context-type="sourcefile">apps/client/src/app/pages/portfolio/allocations/allocations-page.html</context>
<context context-type="linenumber">250</context> <context context-type="linenumber">250</context>
@ -5918,7 +5918,7 @@
</trans-unit> </trans-unit>
<trans-unit id="7215101881367554791" datatype="html"> <trans-unit id="7215101881367554791" datatype="html">
<source>Show more</source> <source>Show more</source>
<target state="new">Show more</target> <target state="translated">Mostra més</target>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">libs/ui/src/lib/top-holdings/top-holdings.component.html</context> <context context-type="sourcefile">libs/ui/src/lib/top-holdings/top-holdings.component.html</context>
<context context-type="linenumber">174</context> <context context-type="linenumber">174</context>
@ -5926,7 +5926,7 @@
</trans-unit> </trans-unit>
<trans-unit id="4455104386790567151" datatype="html"> <trans-unit id="4455104386790567151" datatype="html">
<source>Alternative</source> <source>Alternative</source>
<target state="new">Alternative</target> <target state="translated">Alternativa</target>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/resources/personal-finance-tools/product-page.component.ts</context> <context context-type="sourcefile">apps/client/src/app/pages/resources/personal-finance-tools/product-page.component.ts</context>
<context context-type="linenumber">80</context> <context context-type="linenumber">80</context>
@ -5934,7 +5934,7 @@
</trans-unit> </trans-unit>
<trans-unit id="2818570902941667477" datatype="html"> <trans-unit id="2818570902941667477" datatype="html">
<source>App</source> <source>App</source>
<target state="new">App</target> <target state="translated">Aplicació</target>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/resources/personal-finance-tools/product-page.component.ts</context> <context context-type="sourcefile">apps/client/src/app/pages/resources/personal-finance-tools/product-page.component.ts</context>
<context context-type="linenumber">81</context> <context context-type="linenumber">81</context>
@ -5942,7 +5942,7 @@
</trans-unit> </trans-unit>
<trans-unit id="647668541461749965" datatype="html"> <trans-unit id="647668541461749965" datatype="html">
<source>Budgeting</source> <source>Budgeting</source>
<target state="new">Budgeting</target> <target state="translated">Pressupost</target>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/resources/personal-finance-tools/product-page.component.ts</context> <context context-type="sourcefile">apps/client/src/app/pages/resources/personal-finance-tools/product-page.component.ts</context>
<context context-type="linenumber">82</context> <context context-type="linenumber">82</context>
@ -5950,7 +5950,7 @@
</trans-unit> </trans-unit>
<trans-unit id="1274247756500564795" datatype="html"> <trans-unit id="1274247756500564795" datatype="html">
<source>Community</source> <source>Community</source>
<target state="new">Community</target> <target state="translated">Comunitat</target>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/app.component.html</context> <context context-type="sourcefile">apps/client/src/app/app.component.html</context>
<context context-type="linenumber">130</context> <context context-type="linenumber">130</context>
@ -6006,7 +6006,7 @@
</trans-unit> </trans-unit>
<trans-unit id="4622218074144052433" datatype="html"> <trans-unit id="4622218074144052433" datatype="html">
<source>Family Office</source> <source>Family Office</source>
<target state="new">Family Office</target> <target state="translated">Oficina familiar</target>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/resources/personal-finance-tools/product-page.component.ts</context> <context context-type="sourcefile">apps/client/src/app/pages/resources/personal-finance-tools/product-page.component.ts</context>
<context context-type="linenumber">84</context> <context context-type="linenumber">84</context>

2
apps/client/src/locales/messages.de.xlf

@ -5605,7 +5605,7 @@
</trans-unit> </trans-unit>
<trans-unit id="637740912956205466" datatype="html"> <trans-unit id="637740912956205466" datatype="html">
<source> If you retire today, you would be able to withdraw <x id="START_TAG_SPAN" ctype="x-span" equiv-text="&lt;span class=&quot;font-weight-bold&quot; &gt;"/><x id="START_TAG_GF_VALUE" ctype="x-gf_value" equiv-text="&lt;gf-value class=&quot;d-inline-block&quot; [isCurrency]=&quot;true&quot; [locale]=&quot;user?.settings?.locale&quot; [unit]=&quot;user?.settings?.baseCurrency&quot; [value]=&quot;withdrawalRatePerYear?.toNumber()&quot; /&gt;"/><x id="CLOSE_TAG_GF_VALUE" ctype="x-gf_value" equiv-text="&lt;gf-value class=&quot;d-inline-block&quot; [isCurrency]=&quot;true&quot; [locale]=&quot;user?.settings?.locale&quot; [unit]=&quot;user?.settings?.baseCurrency&quot; [value]=&quot;fireWealth?.toNumber()&quot; /&gt;"/> per year<x id="CLOSE_TAG_SPAN" ctype="x-span" equiv-text="&lt;/span&gt;"/> or <x id="START_TAG_SPAN" ctype="x-span" equiv-text="&lt;span class=&quot;font-weight-bold&quot; &gt;"/><x id="START_TAG_GF_VALUE_1" ctype="x-gf_value_1" equiv-text="&lt;gf-value class=&quot;d-inline-block&quot; [isCurrency]=&quot;true&quot; [locale]=&quot;user?.settings?.locale&quot; [unit]=&quot;user?.settings?.baseCurrency&quot; [value]=&quot;withdrawalRatePerMonth?.toNumber()&quot; /&gt;"/><x id="CLOSE_TAG_GF_VALUE" ctype="x-gf_value" equiv-text="&lt;gf-value class=&quot;d-inline-block&quot; [isCurrency]=&quot;true&quot; [locale]=&quot;user?.settings?.locale&quot; [unit]=&quot;user?.settings?.baseCurrency&quot; [value]=&quot;fireWealth?.toNumber()&quot; /&gt;"/> per month<x id="CLOSE_TAG_SPAN" ctype="x-span" equiv-text="&lt;/span&gt;"/>, based on your total assets of <x id="START_TAG_SPAN" ctype="x-span" equiv-text="&lt;span class=&quot;font-weight-bold&quot; &gt;"/><x id="START_TAG_GF_VALUE_2" ctype="x-gf_value_2" equiv-text="&lt;gf-value class=&quot;d-inline-block&quot; [isCurrency]=&quot;true&quot; [locale]=&quot;user?.settings?.locale&quot; [unit]=&quot;user?.settings?.baseCurrency&quot; [value]=&quot;fireWealth?.toNumber()&quot; /&gt;"/><x id="CLOSE_TAG_GF_VALUE" ctype="x-gf_value" equiv-text="&lt;gf-value class=&quot;d-inline-block&quot; [isCurrency]=&quot;true&quot; [locale]=&quot;user?.settings?.locale&quot; [unit]=&quot;user?.settings?.baseCurrency&quot; [value]=&quot;fireWealth?.toNumber()&quot; /&gt;"/><x id="CLOSE_TAG_SPAN" ctype="x-span" equiv-text="&lt;/span&gt;"/> and a withdrawal rate of 4%. </source> <source> If you retire today, you would be able to withdraw <x id="START_TAG_SPAN" ctype="x-span" equiv-text="&lt;span class=&quot;font-weight-bold&quot; &gt;"/><x id="START_TAG_GF_VALUE" ctype="x-gf_value" equiv-text="&lt;gf-value class=&quot;d-inline-block&quot; [isCurrency]=&quot;true&quot; [locale]=&quot;user?.settings?.locale&quot; [unit]=&quot;user?.settings?.baseCurrency&quot; [value]=&quot;withdrawalRatePerYear?.toNumber()&quot; /&gt;"/><x id="CLOSE_TAG_GF_VALUE" ctype="x-gf_value" equiv-text="&lt;gf-value class=&quot;d-inline-block&quot; [isCurrency]=&quot;true&quot; [locale]=&quot;user?.settings?.locale&quot; [unit]=&quot;user?.settings?.baseCurrency&quot; [value]=&quot;fireWealth?.toNumber()&quot; /&gt;"/> per year<x id="CLOSE_TAG_SPAN" ctype="x-span" equiv-text="&lt;/span&gt;"/> or <x id="START_TAG_SPAN" ctype="x-span" equiv-text="&lt;span class=&quot;font-weight-bold&quot; &gt;"/><x id="START_TAG_GF_VALUE_1" ctype="x-gf_value_1" equiv-text="&lt;gf-value class=&quot;d-inline-block&quot; [isCurrency]=&quot;true&quot; [locale]=&quot;user?.settings?.locale&quot; [unit]=&quot;user?.settings?.baseCurrency&quot; [value]=&quot;withdrawalRatePerMonth?.toNumber()&quot; /&gt;"/><x id="CLOSE_TAG_GF_VALUE" ctype="x-gf_value" equiv-text="&lt;gf-value class=&quot;d-inline-block&quot; [isCurrency]=&quot;true&quot; [locale]=&quot;user?.settings?.locale&quot; [unit]=&quot;user?.settings?.baseCurrency&quot; [value]=&quot;fireWealth?.toNumber()&quot; /&gt;"/> per month<x id="CLOSE_TAG_SPAN" ctype="x-span" equiv-text="&lt;/span&gt;"/>, based on your total assets of <x id="START_TAG_SPAN" ctype="x-span" equiv-text="&lt;span class=&quot;font-weight-bold&quot; &gt;"/><x id="START_TAG_GF_VALUE_2" ctype="x-gf_value_2" equiv-text="&lt;gf-value class=&quot;d-inline-block&quot; [isCurrency]=&quot;true&quot; [locale]=&quot;user?.settings?.locale&quot; [unit]=&quot;user?.settings?.baseCurrency&quot; [value]=&quot;fireWealth?.toNumber()&quot; /&gt;"/><x id="CLOSE_TAG_GF_VALUE" ctype="x-gf_value" equiv-text="&lt;gf-value class=&quot;d-inline-block&quot; [isCurrency]=&quot;true&quot; [locale]=&quot;user?.settings?.locale&quot; [unit]=&quot;user?.settings?.baseCurrency&quot; [value]=&quot;fireWealth?.toNumber()&quot; /&gt;"/><x id="CLOSE_TAG_SPAN" ctype="x-span" equiv-text="&lt;/span&gt;"/> and a withdrawal rate of 4%. </source>
<target state="translated"> Wenn du heute in den Ruhestand gehen würdest, könnest du <x id="START_TAG_SPAN" ctype="x-span" equiv-text="&lt;span class=&quot;font-weight-bold&quot; &gt;"/><x id="START_TAG_GF_VALUE" ctype="x-gf_value" equiv-text="&lt;gf-value class=&quot;d-inline-block&quot; [isCurrency]=&quot;true&quot; [locale]=&quot;user?.settings?.locale&quot; [unit]=&quot;user?.settings?.baseCurrency&quot; [value]=&quot;withdrawalRatePerYear?.toNumber()&quot; /&gt;"/><x id="CLOSE_TAG_GF_VALUE" ctype="x-gf_value" equiv-text="&lt;gf-value class=&quot;d-inline-block&quot; [isCurrency]=&quot;true&quot; [locale]=&quot;user?.settings?.locale&quot; [unit]=&quot;user?.settings?.baseCurrency&quot; [value]=&quot;fireWealth?.toNumber()&quot; /&gt;"/> pro Jahr<x id="CLOSE_TAG_SPAN" ctype="x-span" equiv-text="&lt;/span&gt;"/> oder <x id="START_TAG_SPAN" ctype="x-span" equiv-text="&lt;span class=&quot;font-weight-bold&quot; &gt;"/><x id="START_TAG_GF_VALUE_1" ctype="x-gf_value_1" equiv-text="&lt;gf-value class=&quot;d-inline-block&quot; [isCurrency]=&quot;true&quot; [locale]=&quot;user?.settings?.locale&quot; [unit]=&quot;user?.settings?.baseCurrency&quot; [value]=&quot;withdrawalRatePerMonth?.toNumber()&quot; /&gt;"/><x id="CLOSE_TAG_GF_VALUE" ctype="x-gf_value" equiv-text="&lt;gf-value class=&quot;d-inline-block&quot; [isCurrency]=&quot;true&quot; [locale]=&quot;user?.settings?.locale&quot; [unit]=&quot;user?.settings?.baseCurrency&quot; [value]=&quot;fireWealth?.toNumber()&quot; /&gt;"/> pro Monat<x id="CLOSE_TAG_SPAN" ctype="x-span" equiv-text="&lt;/span&gt;"/>entnehmen, bezogen auf dein Gesamtanlagevermögen von <x id="START_TAG_SPAN" ctype="x-span" equiv-text="&lt;span class=&quot;font-weight-bold&quot; &gt;"/><x id="START_TAG_GF_VALUE_2" ctype="x-gf_value_2" equiv-text="&lt;gf-value class=&quot;d-inline-block&quot; [isCurrency]=&quot;true&quot; [locale]=&quot;user?.settings?.locale&quot; [unit]=&quot;user?.settings?.baseCurrency&quot; [value]=&quot;fireWealth?.toNumber()&quot; /&gt;"/><x id="CLOSE_TAG_GF_VALUE" ctype="x-gf_value" equiv-text="&lt;gf-value class=&quot;d-inline-block&quot; [isCurrency]=&quot;true&quot; [locale]=&quot;user?.settings?.locale&quot; [unit]=&quot;user?.settings?.baseCurrency&quot; [value]=&quot;fireWealth?.toNumber()&quot; /&gt;"/><x id="CLOSE_TAG_SPAN" ctype="x-span" equiv-text="&lt;/span&gt;"/> und einer Entnahmerate von 4%. </target> <target state="translated"> Wenn du heute in den Ruhestand gehen würdest, könnest du <x id="START_TAG_SPAN" ctype="x-span" equiv-text="&lt;span class=&quot;font-weight-bold&quot; &gt;"/><x id="START_TAG_GF_VALUE" ctype="x-gf_value" equiv-text="&lt;gf-value class=&quot;d-inline-block&quot; [isCurrency]=&quot;true&quot; [locale]=&quot;user?.settings?.locale&quot; [unit]=&quot;user?.settings?.baseCurrency&quot; [value]=&quot;withdrawalRatePerYear?.toNumber()&quot; /&gt;"/><x id="CLOSE_TAG_GF_VALUE" ctype="x-gf_value" equiv-text="&lt;gf-value class=&quot;d-inline-block&quot; [isCurrency]=&quot;true&quot; [locale]=&quot;user?.settings?.locale&quot; [unit]=&quot;user?.settings?.baseCurrency&quot; [value]=&quot;fireWealth?.toNumber()&quot; /&gt;"/> pro Jahr<x id="CLOSE_TAG_SPAN" ctype="x-span" equiv-text="&lt;/span&gt;"/> oder <x id="START_TAG_SPAN" ctype="x-span" equiv-text="&lt;span class=&quot;font-weight-bold&quot; &gt;"/><x id="START_TAG_GF_VALUE_1" ctype="x-gf_value_1" equiv-text="&lt;gf-value class=&quot;d-inline-block&quot; [isCurrency]=&quot;true&quot; [locale]=&quot;user?.settings?.locale&quot; [unit]=&quot;user?.settings?.baseCurrency&quot; [value]=&quot;withdrawalRatePerMonth?.toNumber()&quot; /&gt;"/><x id="CLOSE_TAG_GF_VALUE" ctype="x-gf_value" equiv-text="&lt;gf-value class=&quot;d-inline-block&quot; [isCurrency]=&quot;true&quot; [locale]=&quot;user?.settings?.locale&quot; [unit]=&quot;user?.settings?.baseCurrency&quot; [value]=&quot;fireWealth?.toNumber()&quot; /&gt;"/> pro Monat<x id="CLOSE_TAG_SPAN" ctype="x-span" equiv-text="&lt;/span&gt;"/> entnehmen, bezogen auf dein Gesamtanlagevermögen von <x id="START_TAG_SPAN" ctype="x-span" equiv-text="&lt;span class=&quot;font-weight-bold&quot; &gt;"/><x id="START_TAG_GF_VALUE_2" ctype="x-gf_value_2" equiv-text="&lt;gf-value class=&quot;d-inline-block&quot; [isCurrency]=&quot;true&quot; [locale]=&quot;user?.settings?.locale&quot; [unit]=&quot;user?.settings?.baseCurrency&quot; [value]=&quot;fireWealth?.toNumber()&quot; /&gt;"/><x id="CLOSE_TAG_GF_VALUE" ctype="x-gf_value" equiv-text="&lt;gf-value class=&quot;d-inline-block&quot; [isCurrency]=&quot;true&quot; [locale]=&quot;user?.settings?.locale&quot; [unit]=&quot;user?.settings?.baseCurrency&quot; [value]=&quot;fireWealth?.toNumber()&quot; /&gt;"/><x id="CLOSE_TAG_SPAN" ctype="x-span" equiv-text="&lt;/span&gt;"/> und einer Entnahmerate von 4%. </target>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/portfolio/fire/fire-page.html</context> <context context-type="sourcefile">apps/client/src/app/pages/portfolio/fire/fire-page.html</context>
<context context-type="linenumber">68</context> <context context-type="linenumber">68</context>

34
apps/client/src/locales/messages.es.xlf

@ -2236,7 +2236,7 @@
</trans-unit> </trans-unit>
<trans-unit id="79310201207169632" datatype="html"> <trans-unit id="79310201207169632" datatype="html">
<source>Exclude from Analysis</source> <source>Exclude from Analysis</source>
<target state="new">Exclude from Analysis</target> <target state="translated">Excluir del análisis</target>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/accounts/create-or-update-account-dialog/create-or-update-account-dialog.html</context> <context context-type="sourcefile">apps/client/src/app/pages/accounts/create-or-update-account-dialog/create-or-update-account-dialog.html</context>
<context context-type="linenumber">90</context> <context context-type="linenumber">90</context>
@ -7154,7 +7154,7 @@
</trans-unit> </trans-unit>
<trans-unit id="2937898953036699236" datatype="html"> <trans-unit id="2937898953036699236" datatype="html">
<source>and I agree to the <x id="START_LINK" ctype="x-a" equiv-text="&lt;a class=&quot;font-weight-bold&quot; target=&quot;_blank&quot; [routerLink]=&quot;routerLinkAboutTermsOfService&quot; &gt;"/>Terms of Service<x id="CLOSE_LINK" ctype="x-a" equiv-text="&lt;/a &gt;"/>.</source> <source>and I agree to the <x id="START_LINK" ctype="x-a" equiv-text="&lt;a class=&quot;font-weight-bold&quot; target=&quot;_blank&quot; [routerLink]=&quot;routerLinkAboutTermsOfService&quot; &gt;"/>Terms of Service<x id="CLOSE_LINK" ctype="x-a" equiv-text="&lt;/a &gt;"/>.</source>
<target state="new">and I agree to the <x id="START_LINK" ctype="x-a" equiv-text="&lt;a class=&quot;font-weight-bold&quot; target=&quot;_blank&quot; [routerLink]=&quot;routerLinkAboutTermsOfService&quot; &gt;"/>Terms of Service<x id="CLOSE_LINK" ctype="x-a" equiv-text="&lt;/a &gt;"/>.</target> <target state="translated">y acepto los <x id="START_LINK" ctype="x-a" equiv-text="&lt;a class=&quot;font-weight-bold&quot; target=&quot;_blank&quot; [routerLink]=&quot;routerLinkAboutTermsOfService&quot; &gt;"/>Términos del servicio<x id="CLOSE_LINK" ctype="x-a" equiv-text="&lt;/a&gt;"/>.</target>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/register/show-access-token-dialog/show-access-token-dialog.html</context> <context context-type="sourcefile">apps/client/src/app/pages/register/show-access-token-dialog/show-access-token-dialog.html</context>
<context context-type="linenumber">34</context> <context context-type="linenumber">34</context>
@ -7162,7 +7162,7 @@
</trans-unit> </trans-unit>
<trans-unit id="3606972039333274390" datatype="html"> <trans-unit id="3606972039333274390" datatype="html">
<source><x id="PH" equiv-text="assetProfileIdentifier.symbol"/> (<x id="PH_1" equiv-text="assetProfileIdentifier.dataSource"/>) is already in use.</source> <source><x id="PH" equiv-text="assetProfileIdentifier.symbol"/> (<x id="PH_1" equiv-text="assetProfileIdentifier.dataSource"/>) is already in use.</source>
<target state="new"><x id="PH" equiv-text="assetProfileIdentifier.symbol"/> (<x id="PH_1" equiv-text="assetProfileIdentifier.dataSource"/>) is already in use.</target> <target state="translated"><x id="PH" equiv-text="assetProfileIdentifier.symbol"/> (<x id="PH_1" equiv-text="assetProfileIdentifier.dataSource"/>) ya está en uso.</target>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts</context> <context context-type="sourcefile">apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts</context>
<context context-type="linenumber">563</context> <context context-type="linenumber">563</context>
@ -7170,7 +7170,7 @@
</trans-unit> </trans-unit>
<trans-unit id="5612909502553004436" datatype="html"> <trans-unit id="5612909502553004436" datatype="html">
<source>An error occurred while updating to <x id="PH" equiv-text="assetProfileIdentifier.symbol"/> (<x id="PH_1" equiv-text="assetProfileIdentifier.dataSource"/>).</source> <source>An error occurred while updating to <x id="PH" equiv-text="assetProfileIdentifier.symbol"/> (<x id="PH_1" equiv-text="assetProfileIdentifier.dataSource"/>).</source>
<target state="new">An error occurred while updating to <x id="PH" equiv-text="assetProfileIdentifier.symbol"/> (<x id="PH_1" equiv-text="assetProfileIdentifier.dataSource"/>).</target> <target state="translated">Ocurrió un error al actualizar a <x id="PH" equiv-text="assetProfileIdentifier.symbol"/> (<x id="PH_1" equiv-text="assetProfileIdentifier.dataSource"/>).</target>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts</context> <context context-type="sourcefile">apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts</context>
<context context-type="linenumber">571</context> <context context-type="linenumber">571</context>
@ -7468,7 +7468,7 @@
</trans-unit> </trans-unit>
<trans-unit id="routes.resources.markets" datatype="html"> <trans-unit id="routes.resources.markets" datatype="html">
<source>markets</source> <source>markets</source>
<target state="new">markets</target> <target state="translated">mercados</target>
<note priority="1" from="description">kebab-case</note> <note priority="1" from="description">kebab-case</note>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">libs/common/src/lib/routes/routes.ts</context> <context context-type="sourcefile">libs/common/src/lib/routes/routes.ts</context>
@ -7481,7 +7481,7 @@
</trans-unit> </trans-unit>
<trans-unit id="2813275520458225294" datatype="html"> <trans-unit id="2813275520458225294" datatype="html">
<source> Fuel your <x id="START_TAG_STRONG" ctype="x-strong" equiv-text="&lt;strong&gt;"/>self-hosted Ghostfolio<x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="&lt;/strong&gt;"/> with a <x id="START_TAG_STRONG" ctype="x-strong" equiv-text="&lt;strong&gt;"/>powerful data provider<x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="&lt;/strong&gt;"/> to access <x id="START_TAG_STRONG" ctype="x-strong" equiv-text="&lt;strong&gt;"/>80,000+ tickers<x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="&lt;/strong&gt;"/> from over <x id="START_TAG_STRONG" ctype="x-strong" equiv-text="&lt;strong&gt;"/>50 exchanges<x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="&lt;/strong&gt;"/> worldwide. </source> <source> Fuel your <x id="START_TAG_STRONG" ctype="x-strong" equiv-text="&lt;strong&gt;"/>self-hosted Ghostfolio<x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="&lt;/strong&gt;"/> with a <x id="START_TAG_STRONG" ctype="x-strong" equiv-text="&lt;strong&gt;"/>powerful data provider<x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="&lt;/strong&gt;"/> to access <x id="START_TAG_STRONG" ctype="x-strong" equiv-text="&lt;strong&gt;"/>80,000+ tickers<x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="&lt;/strong&gt;"/> from over <x id="START_TAG_STRONG" ctype="x-strong" equiv-text="&lt;strong&gt;"/>50 exchanges<x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="&lt;/strong&gt;"/> worldwide. </source>
<target state="new"> Fuel your <x id="START_TAG_STRONG" ctype="x-strong" equiv-text="&lt;strong&gt;"/>self-hosted Ghostfolio<x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="&lt;/strong&gt;"/> with a <x id="START_TAG_STRONG" ctype="x-strong" equiv-text="&lt;strong&gt;"/>powerful data provider<x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="&lt;/strong&gt;"/> to access <x id="START_TAG_STRONG" ctype="x-strong" equiv-text="&lt;strong&gt;"/>80,000+ tickers<x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="&lt;/strong&gt;"/> from over <x id="START_TAG_STRONG" ctype="x-strong" equiv-text="&lt;strong&gt;"/>50 exchanges<x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="&lt;/strong&gt;"/> worldwide. </target> <target state="translated">Alimenta tu <x id="START_TAG_STRONG" ctype="x-strong" equiv-text="&lt;strong&gt;"/>Ghostfolio autoalojado<x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="&lt;/strong&gt;"/> con un <x id="START_TAG_STRONG" ctype="x-strong" equiv-text="&lt;strong&gt;"/>proveedor de datos potente<x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="&lt;/strong&gt;"/> para acceder a más de <x id="START_TAG_STRONG" ctype="x-strong" equiv-text="&lt;strong&gt;"/>80.000 tickers<x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="&lt;/strong&gt;"/> de más de <x id="START_TAG_STRONG" ctype="x-strong" equiv-text="&lt;strong&gt;"/>50 intercambios<x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="&lt;/strong&gt;"/> a nivel mundial.</target>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-settings/admin-settings.component.html</context> <context context-type="sourcefile">apps/client/src/app/components/admin-settings/admin-settings.component.html</context>
<context context-type="linenumber">16</context> <context context-type="linenumber">16</context>
@ -7489,7 +7489,7 @@
</trans-unit> </trans-unit>
<trans-unit id="4579866450954197004" datatype="html"> <trans-unit id="4579866450954197004" datatype="html">
<source>Get Access</source> <source>Get Access</source>
<target state="new">Get Access</target> <target state="translated">Obtener acceso</target>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-settings/admin-settings.component.html</context> <context context-type="sourcefile">apps/client/src/app/components/admin-settings/admin-settings.component.html</context>
<context context-type="linenumber">27</context> <context context-type="linenumber">27</context>
@ -7497,7 +7497,7 @@
</trans-unit> </trans-unit>
<trans-unit id="819996403327805209" datatype="html"> <trans-unit id="819996403327805209" datatype="html">
<source>Learn more</source> <source>Learn more</source>
<target state="new">Learn more</target> <target state="translated">Aprender más</target>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-settings/admin-settings.component.html</context> <context context-type="sourcefile">apps/client/src/app/components/admin-settings/admin-settings.component.html</context>
<context context-type="linenumber">38</context> <context context-type="linenumber">38</context>
@ -7505,7 +7505,7 @@
</trans-unit> </trans-unit>
<trans-unit id="5743832581969115624" datatype="html"> <trans-unit id="5743832581969115624" datatype="html">
<source>Limited Offer!</source> <source>Limited Offer!</source>
<target state="new">Limited Offer!</target> <target state="translated">¡Oferta limitada!</target>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/pricing/pricing-page.html</context> <context context-type="sourcefile">apps/client/src/app/pages/pricing/pricing-page.html</context>
<context context-type="linenumber">312</context> <context context-type="linenumber">312</context>
@ -7513,7 +7513,7 @@
</trans-unit> </trans-unit>
<trans-unit id="2415916442984615985" datatype="html"> <trans-unit id="2415916442984615985" datatype="html">
<source>Get <x id="INTERPOLATION" equiv-text="{{ durationExtension }}"/> extra</source> <source>Get <x id="INTERPOLATION" equiv-text="{{ durationExtension }}"/> extra</source>
<target state="new">Get <x id="INTERPOLATION" equiv-text="{{ durationExtension }}"/> extra</target> <target state="translated">Obtén <x id="INTERPOLATION" equiv-text="{{ durationExtension }}"/> extra</target>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/pricing/pricing-page.html</context> <context context-type="sourcefile">apps/client/src/app/pages/pricing/pricing-page.html</context>
<context context-type="linenumber">314</context> <context context-type="linenumber">314</context>
@ -7521,7 +7521,7 @@
</trans-unit> </trans-unit>
<trans-unit id="3955868613858648955" datatype="html"> <trans-unit id="3955868613858648955" datatype="html">
<source>Available</source> <source>Available</source>
<target state="new">Available</target> <target state="translated">Disponible</target>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/data-provider-status/data-provider-status.component.html</context> <context context-type="sourcefile">apps/client/src/app/components/data-provider-status/data-provider-status.component.html</context>
<context context-type="linenumber">3</context> <context context-type="linenumber">3</context>
@ -7529,7 +7529,7 @@
</trans-unit> </trans-unit>
<trans-unit id="5643561794785412000" datatype="html"> <trans-unit id="5643561794785412000" datatype="html">
<source>Unavailable</source> <source>Unavailable</source>
<target state="new">Unavailable</target> <target state="translated">No disponible</target>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/data-provider-status/data-provider-status.component.html</context> <context context-type="sourcefile">apps/client/src/app/components/data-provider-status/data-provider-status.component.html</context>
<context context-type="linenumber">5</context> <context context-type="linenumber">5</context>
@ -7537,7 +7537,7 @@
</trans-unit> </trans-unit>
<trans-unit id="7387635272539030076" datatype="html"> <trans-unit id="7387635272539030076" datatype="html">
<source>new</source> <source>new</source>
<target state="new">new</target> <target state="translated">nuevo</target>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-settings/admin-settings.component.html</context> <context context-type="sourcefile">apps/client/src/app/components/admin-settings/admin-settings.component.html</context>
<context context-type="linenumber">67</context> <context context-type="linenumber">67</context>
@ -7549,7 +7549,7 @@
</trans-unit> </trans-unit>
<trans-unit id="rule.accountClusterRiskCurrentInvestment" datatype="html"> <trans-unit id="rule.accountClusterRiskCurrentInvestment" datatype="html">
<source>Investment</source> <source>Investment</source>
<target state="new">Investment</target> <target state="translated">Inversión</target>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/i18n/i18n-page.html</context> <context context-type="sourcefile">apps/client/src/app/pages/i18n/i18n-page.html</context>
<context context-type="linenumber">15</context> <context context-type="linenumber">15</context>
@ -7557,7 +7557,7 @@
</trans-unit> </trans-unit>
<trans-unit id="rule.accountClusterRiskCurrentInvestment.false" datatype="html"> <trans-unit id="rule.accountClusterRiskCurrentInvestment.false" datatype="html">
<source> Over ${thresholdMax}% of your current investment is at ${maxAccountName} (${maxInvestmentRatio}%) </source> <source> Over ${thresholdMax}% of your current investment is at ${maxAccountName} (${maxInvestmentRatio}%) </source>
<target state="new"> Over ${thresholdMax}% of your current investment is at ${maxAccountName} (${maxInvestmentRatio}%) </target> <target state="translated">Más del ${thresholdMax}% de tu inversión actual está en ${maxAccountName} (${maxInvestmentRatio}%)</target>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/i18n/i18n-page.html</context> <context context-type="sourcefile">apps/client/src/app/pages/i18n/i18n-page.html</context>
<context context-type="linenumber">17</context> <context context-type="linenumber">17</context>
@ -7565,7 +7565,7 @@
</trans-unit> </trans-unit>
<trans-unit id="rule.accountClusterRiskCurrentInvestment.true" datatype="html"> <trans-unit id="rule.accountClusterRiskCurrentInvestment.true" datatype="html">
<source> The major part of your current investment is at ${maxAccountName} (${maxInvestmentRatio}%) and does not exceed ${thresholdMax}% </source> <source> The major part of your current investment is at ${maxAccountName} (${maxInvestmentRatio}%) and does not exceed ${thresholdMax}% </source>
<target state="new"> The major part of your current investment is at ${maxAccountName} (${maxInvestmentRatio}%) and does not exceed ${thresholdMax}% </target> <target state="translated">La mayor parte de tu inversión actual está en ${maxAccountName} (${maxInvestmentRatio}%) y no excede el ${thresholdMax}%</target>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/i18n/i18n-page.html</context> <context context-type="sourcefile">apps/client/src/app/pages/i18n/i18n-page.html</context>
<context context-type="linenumber">24</context> <context context-type="linenumber">24</context>
@ -7573,7 +7573,7 @@
</trans-unit> </trans-unit>
<trans-unit id="rule.assetClassClusterRiskEquity" datatype="html"> <trans-unit id="rule.assetClassClusterRiskEquity" datatype="html">
<source>Equity</source> <source>Equity</source>
<target state="new">Equity</target> <target state="translated">Acciones</target>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/i18n/i18n-page.html</context> <context context-type="sourcefile">apps/client/src/app/pages/i18n/i18n-page.html</context>
<context context-type="linenumber">41</context> <context context-type="linenumber">41</context>

34
apps/client/src/locales/messages.pl.xlf

@ -3964,7 +3964,7 @@
</trans-unit> </trans-unit>
<trans-unit id="6962217007874959362" datatype="html"> <trans-unit id="6962217007874959362" datatype="html">
<source> Our official Ghostfolio Premium cloud offering is the easiest way to get started. Due to the time it saves, this will be the best option for most people. Revenue is used to cover operational costs for the hosting infrastructure and professional data providers, and to fund ongoing development. </source> <source> Our official Ghostfolio Premium cloud offering is the easiest way to get started. Due to the time it saves, this will be the best option for most people. Revenue is used to cover operational costs for the hosting infrastructure and professional data providers, and to fund ongoing development. </source>
<target state="new"> Nasza oficjalna chmurowa usługa Ghostfolio Premium jest najprostszym sposobem by rozpocząć przygodę z Ghostfolio. To najlepsza opcja dla większości osób ze względu na czas, jaki można dzięki niej zaoszczędzić. Uzyskany przychód jest wykorzystywany do pokrycia kosztów infrastruktury hostingowej i finansowania bieżącego rozwoju. </target> <target state="translated">Nasza oficjalna chmurowa usługa Ghostfolio Premium jest najprostszym sposobem, aby rozpocząć przygodę z Ghostfolio. To najlepsza opcja dla większości osób ze względu na czas, jaki można dzięki niej zaoszczędzić. Uzyskany przychód jest wykorzystywany do pokrycia kosztów infrastruktury hostingowej i finansowania bieżącego rozwoju.</target>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/pricing/pricing-page.html</context> <context context-type="sourcefile">apps/client/src/app/pages/pricing/pricing-page.html</context>
<context context-type="linenumber">7</context> <context context-type="linenumber">7</context>
@ -5718,7 +5718,7 @@
</trans-unit> </trans-unit>
<trans-unit id="5303806780432428245" datatype="html"> <trans-unit id="5303806780432428245" datatype="html">
<source>Indonesia</source> <source>Indonesia</source>
<target state="new">Indonesia</target> <target state="translated">Indonezja</target>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">libs/ui/src/lib/i18n.ts</context> <context context-type="sourcefile">libs/ui/src/lib/i18n.ts</context>
<context context-type="linenumber">88</context> <context context-type="linenumber">88</context>
@ -7322,7 +7322,7 @@
</trans-unit> </trans-unit>
<trans-unit id="rule.emergencyFundSetup" datatype="html"> <trans-unit id="rule.emergencyFundSetup" datatype="html">
<source>Set up</source> <source>Set up</source>
<target state="new">Fundusz awaryjny: Utworzenie</target> <target state="translated">Fundusz awaryjny: Utworzenie</target>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/i18n/i18n-page.html</context> <context context-type="sourcefile">apps/client/src/app/pages/i18n/i18n-page.html</context>
<context context-type="linenumber">132</context> <context context-type="linenumber">132</context>
@ -7402,7 +7402,7 @@
</trans-unit> </trans-unit>
<trans-unit id="440264111109852789" datatype="html"> <trans-unit id="440264111109852789" datatype="html">
<source>Live Demo</source> <source>Live Demo</source>
<target state="new">Live Demo</target> <target state="translated">Demonstracja na żywo</target>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context> <context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
<context context-type="linenumber">49</context> <context context-type="linenumber">49</context>
@ -7426,7 +7426,7 @@
</trans-unit> </trans-unit>
<trans-unit id="rule.accountClusterRiskSingleAccount" datatype="html"> <trans-unit id="rule.accountClusterRiskSingleAccount" datatype="html">
<source>Single Account</source> <source>Single Account</source>
<target state="new">Single Account</target> <target state="translated">Konto pojedyncze</target>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/i18n/i18n-page.html</context> <context context-type="sourcefile">apps/client/src/app/pages/i18n/i18n-page.html</context>
<context context-type="linenumber">28</context> <context context-type="linenumber">28</context>
@ -7434,7 +7434,7 @@
</trans-unit> </trans-unit>
<trans-unit id="rule.accountClusterRiskSingleAccount.false" datatype="html"> <trans-unit id="rule.accountClusterRiskSingleAccount.false" datatype="html">
<source> Your net worth is managed by a single account </source> <source> Your net worth is managed by a single account </source>
<target state="new"> Your net worth is managed by a single account </target> <target state="translated">Twój majątek netto jest zarządzany przez jedno konto</target>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/i18n/i18n-page.html</context> <context context-type="sourcefile">apps/client/src/app/pages/i18n/i18n-page.html</context>
<context context-type="linenumber">30</context> <context context-type="linenumber">30</context>
@ -7442,7 +7442,7 @@
</trans-unit> </trans-unit>
<trans-unit id="rule.accountClusterRiskSingleAccount.true" datatype="html"> <trans-unit id="rule.accountClusterRiskSingleAccount.true" datatype="html">
<source> Your net worth is managed by ${accountsLength} accounts </source> <source> Your net worth is managed by ${accountsLength} accounts </source>
<target state="new"> Your net worth is managed by ${accountsLength} accounts </target> <target state="translated">Twój majątek netto jest zarządzany przez ${accountsLength} konta</target>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/i18n/i18n-page.html</context> <context context-type="sourcefile">apps/client/src/app/pages/i18n/i18n-page.html</context>
<context context-type="linenumber">36</context> <context context-type="linenumber">36</context>
@ -7450,7 +7450,7 @@
</trans-unit> </trans-unit>
<trans-unit id="routes.resources.personalFinanceTools" datatype="html"> <trans-unit id="routes.resources.personalFinanceTools" datatype="html">
<source>personal-finance-tools</source> <source>personal-finance-tools</source>
<target state="new">personal-finance-tools</target> <target state="translated">narzedzia-finansowe-osobiste</target>
<note priority="1" from="description">kebab-case</note> <note priority="1" from="description">kebab-case</note>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">libs/common/src/lib/routes/routes.ts</context> <context context-type="sourcefile">libs/common/src/lib/routes/routes.ts</context>
@ -7467,7 +7467,7 @@
</trans-unit> </trans-unit>
<trans-unit id="routes.resources.markets" datatype="html"> <trans-unit id="routes.resources.markets" datatype="html">
<source>markets</source> <source>markets</source>
<target state="new">markets</target> <target state="translated">rynki</target>
<note priority="1" from="description">kebab-case</note> <note priority="1" from="description">kebab-case</note>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">libs/common/src/lib/routes/routes.ts</context> <context context-type="sourcefile">libs/common/src/lib/routes/routes.ts</context>
@ -7488,7 +7488,7 @@
</trans-unit> </trans-unit>
<trans-unit id="4579866450954197004" datatype="html"> <trans-unit id="4579866450954197004" datatype="html">
<source>Get Access</source> <source>Get Access</source>
<target state="new">Get Access</target> <target state="translated">Uzyskaj dostęp</target>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-settings/admin-settings.component.html</context> <context context-type="sourcefile">apps/client/src/app/components/admin-settings/admin-settings.component.html</context>
<context context-type="linenumber">27</context> <context context-type="linenumber">27</context>
@ -7496,7 +7496,7 @@
</trans-unit> </trans-unit>
<trans-unit id="819996403327805209" datatype="html"> <trans-unit id="819996403327805209" datatype="html">
<source>Learn more</source> <source>Learn more</source>
<target state="new">Learn more</target> <target state="translated">Dowiedz się więcej</target>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-settings/admin-settings.component.html</context> <context context-type="sourcefile">apps/client/src/app/components/admin-settings/admin-settings.component.html</context>
<context context-type="linenumber">38</context> <context context-type="linenumber">38</context>
@ -7504,7 +7504,7 @@
</trans-unit> </trans-unit>
<trans-unit id="5743832581969115624" datatype="html"> <trans-unit id="5743832581969115624" datatype="html">
<source>Limited Offer!</source> <source>Limited Offer!</source>
<target state="new">Limited Offer!</target> <target state="translated">Oferta ograniczona czasowo!</target>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/pricing/pricing-page.html</context> <context context-type="sourcefile">apps/client/src/app/pages/pricing/pricing-page.html</context>
<context context-type="linenumber">312</context> <context context-type="linenumber">312</context>
@ -7512,7 +7512,7 @@
</trans-unit> </trans-unit>
<trans-unit id="2415916442984615985" datatype="html"> <trans-unit id="2415916442984615985" datatype="html">
<source>Get <x id="INTERPOLATION" equiv-text="{{ durationExtension }}"/> extra</source> <source>Get <x id="INTERPOLATION" equiv-text="{{ durationExtension }}"/> extra</source>
<target state="new">Get <x id="INTERPOLATION" equiv-text="{{ durationExtension }}"/> extra</target> <target state="translated">Uzyskaj <x id="INTERPOLATION" equiv-text="{{ durationExtension }}"/> dodatkowo</target>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/pricing/pricing-page.html</context> <context context-type="sourcefile">apps/client/src/app/pages/pricing/pricing-page.html</context>
<context context-type="linenumber">314</context> <context context-type="linenumber">314</context>
@ -7520,7 +7520,7 @@
</trans-unit> </trans-unit>
<trans-unit id="3955868613858648955" datatype="html"> <trans-unit id="3955868613858648955" datatype="html">
<source>Available</source> <source>Available</source>
<target state="new">Available</target> <target state="translated">Dostępny</target>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/data-provider-status/data-provider-status.component.html</context> <context context-type="sourcefile">apps/client/src/app/components/data-provider-status/data-provider-status.component.html</context>
<context context-type="linenumber">3</context> <context context-type="linenumber">3</context>
@ -7528,7 +7528,7 @@
</trans-unit> </trans-unit>
<trans-unit id="5643561794785412000" datatype="html"> <trans-unit id="5643561794785412000" datatype="html">
<source>Unavailable</source> <source>Unavailable</source>
<target state="new">Unavailable</target> <target state="translated">Niedostępny</target>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/data-provider-status/data-provider-status.component.html</context> <context context-type="sourcefile">apps/client/src/app/components/data-provider-status/data-provider-status.component.html</context>
<context context-type="linenumber">5</context> <context context-type="linenumber">5</context>
@ -7536,7 +7536,7 @@
</trans-unit> </trans-unit>
<trans-unit id="7387635272539030076" datatype="html"> <trans-unit id="7387635272539030076" datatype="html">
<source>new</source> <source>new</source>
<target state="new">new</target> <target state="translated">nowy</target>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-settings/admin-settings.component.html</context> <context context-type="sourcefile">apps/client/src/app/components/admin-settings/admin-settings.component.html</context>
<context context-type="linenumber">67</context> <context context-type="linenumber">67</context>
@ -7548,7 +7548,7 @@
</trans-unit> </trans-unit>
<trans-unit id="rule.accountClusterRiskCurrentInvestment" datatype="html"> <trans-unit id="rule.accountClusterRiskCurrentInvestment" datatype="html">
<source>Investment</source> <source>Investment</source>
<target state="new">Investment</target> <target state="translated">Inwestycja</target>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/i18n/i18n-page.html</context> <context context-type="sourcefile">apps/client/src/app/pages/i18n/i18n-page.html</context>
<context context-type="linenumber">15</context> <context context-type="linenumber">15</context>

7
apps/client/src/styles.scss

@ -251,11 +251,6 @@ body {
} }
} }
.mat-mdc-card {
--mat-card-elevated-container-color: var(--dark-background);
--mat-card-outlined-container-color: var(--dark-background);
}
.mat-mdc-paginator { .mat-mdc-paginator {
background-color: rgba(var(--palette-foreground-base-dark), 0.02); background-color: rgba(var(--palette-foreground-base-dark), 0.02);
} }
@ -407,8 +402,6 @@ ngx-skeleton-loader {
.mat-mdc-card { .mat-mdc-card {
.mat-mdc-card-title { .mat-mdc-card-title {
--mat-card-title-text-line-height: 1.2;
margin-bottom: 0.5rem; margin-bottom: 0.5rem;
} }
} }

14
apps/client/src/styles/theme.scss

@ -158,6 +158,13 @@ $_tertiary: map.merge(map.get($_palettes, tertiary), $_rest);
@include mat.all-component-themes($gf-theme-default); @include mat.all-component-themes($gf-theme-default);
@include mat.card-overrides(
(
outlined-container-color: var(--light-background),
outlined-outline-color: rgba(var(--dark-dividers)),
title-text-line-height: 1.2
)
);
@include mat.fab-overrides( @include mat.fab-overrides(
( (
container-color: var(--gf-theme-primary-500) container-color: var(--gf-theme-primary-500)
@ -189,6 +196,13 @@ $_tertiary: map.merge(map.get($_palettes, tertiary), $_rest);
@include mat.all-component-themes($gf-theme-dark); @include mat.all-component-themes($gf-theme-dark);
@include mat.card-overrides(
(
outlined-container-color: var(--dark-background),
outlined-outline-color: rgba(var(--light-dividers)),
title-text-line-height: 1.2
)
);
@include mat.fab-overrides( @include mat.fab-overrides(
( (
container-color: var(--gf-theme-primary-500) container-color: var(--gf-theme-primary-500)

6
package-lock.json

@ -1,12 +1,12 @@
{ {
"name": "ghostfolio", "name": "ghostfolio",
"version": "2.187.0", "version": "2.189.0",
"lockfileVersion": 3, "lockfileVersion": 3,
"requires": true, "requires": true,
"packages": { "packages": {
"": { "": {
"name": "ghostfolio", "name": "ghostfolio",
"version": "2.187.0", "version": "2.189.0",
"hasInstallScript": true, "hasInstallScript": true,
"license": "AGPL-3.0", "license": "AGPL-3.0",
"dependencies": { "dependencies": {
@ -163,7 +163,7 @@
"webpack-bundle-analyzer": "4.10.2" "webpack-bundle-analyzer": "4.10.2"
}, },
"engines": { "engines": {
"node": ">=22" "node": ">=22.18.0"
} }
}, },
"node_modules/@adobe/css-tools": { "node_modules/@adobe/css-tools": {

6
package.json

@ -1,6 +1,6 @@
{ {
"name": "ghostfolio", "name": "ghostfolio",
"version": "2.187.0", "version": "2.189.0",
"homepage": "https://ghostfol.io", "homepage": "https://ghostfol.io",
"license": "AGPL-3.0", "license": "AGPL-3.0",
"repository": "https://github.com/ghostfolio/ghostfolio", "repository": "https://github.com/ghostfolio/ghostfolio",
@ -209,9 +209,9 @@
"webpack-bundle-analyzer": "4.10.2" "webpack-bundle-analyzer": "4.10.2"
}, },
"engines": { "engines": {
"node": ">=22" "node": ">=22.18.0"
}, },
"prisma": { "prisma": {
"seed": "npx ts-node --compiler-options {\"module\":\"CommonJS\"} prisma/seed.ts" "seed": "node prisma/seed.ts"
} }
} }

Loading…
Cancel
Save