diff --git a/CHANGELOG.md b/CHANGELOG.md index a41357a63..3869e2f9e 100644 --- a/CHANGELOG.md +++ b/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 +## 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 ### Added diff --git a/DEVELOPMENT.md b/DEVELOPMENT.md index 31b0507bb..6ea0b5e40 100644 --- a/DEVELOPMENT.md +++ b/DEVELOPMENT.md @@ -5,7 +5,7 @@ ### Prerequisites - [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) - Copy the file `.env.dev` to `.env` and populate it with your data (`cp .env.dev .env`) diff --git a/apps/api/src/app/endpoints/sitemap/sitemap.service.ts b/apps/api/src/app/endpoints/sitemap/sitemap.service.ts index d18fe884a..3774d2274 100644 --- a/apps/api/src/app/endpoints/sitemap/sitemap.service.ts +++ b/apps/api/src/app/endpoints/sitemap/sitemap.service.ts @@ -21,18 +21,42 @@ export class SitemapService { const rootUrl = this.configurationService.get('ROOT_URL'); 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 }) => { - const route = - publicRoutes.resources.subRoutes.personalFinanceTools.subRoutes - .product; - const params = { - currentDate, - languageCode, + const location = [ rootUrl, - urlPostfix: alias ?? key - }; - - return this.createRouteSitemapUrl({ ...params, route }); + languageCode, + resourcesPath, + personalFinanceToolsPath, + `${productPath}-${alias ?? key}` + ].join('/'); + + return [ + ' ', + ` ${location}`, + ` ${currentDate}T00:00:00+00:00`, + ' ' + ].join('\n'); }); }).join('\n'); } @@ -58,14 +82,12 @@ export class SitemapService { currentDate, languageCode, rootUrl, - route, - urlPostfix + route }: { currentDate: string; languageCode: string; rootUrl: string; route?: PublicRoute; - urlPostfix?: string; }): string { const segments = route?.routerLink.map((link) => { @@ -83,9 +105,7 @@ export class SitemapService { return segment.replace(/^\/+|\/+$/, ''); }) ?? []; - const location = - [rootUrl, languageCode, ...segments].join('/') + - (urlPostfix ? `-${urlPostfix}` : ''); + const location = [rootUrl, languageCode, ...segments].join('/'); return [ ' ', diff --git a/apps/api/src/app/export/export.service.ts b/apps/api/src/app/export/export.service.ts index 09168b505..7d78bdf22 100644 --- a/apps/api/src/app/export/export.service.ts +++ b/apps/api/src/app/export/export.service.ts @@ -141,15 +141,16 @@ export class ExportService { ); const tags = (await this.tagService.getTagsForUser(userId)) - .filter( - ({ id, isUsed }) => + .filter(({ id, isUsed }) => { + return ( isUsed && activities.some((activity) => { return activity.tags.some(({ id: tagId }) => { return tagId === id; }); }) - ) + ); + }) .map(({ id, name }) => { return { id, diff --git a/apps/api/src/app/user/user.service.ts b/apps/api/src/app/user/user.service.ts index a043761fa..405c4c0b0 100644 --- a/apps/api/src/app/user/user.service.ts +++ b/apps/api/src/app/user/user.service.ts @@ -28,6 +28,7 @@ import { DEFAULT_LANGUAGE_CODE, PROPERTY_IS_READ_ONLY_MODE, PROPERTY_SYSTEM_MESSAGE, + TAG_ID_EXCLUDE_FROM_ANALYSIS, locale } from '@ghostfolio/common/config'; import { @@ -121,7 +122,9 @@ export class UserService { const access = userData[0]; const activitiesCount = userData[1]; 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; diff --git a/apps/api/src/middlewares/html-template.middleware.ts b/apps/api/src/middlewares/html-template.middleware.ts index 5cf353e9a..75ec37480 100644 --- a/apps/api/src/middlewares/html-template.middleware.ts +++ b/apps/api/src/middlewares/html-template.middleware.ts @@ -154,13 +154,9 @@ export class HtmlTemplateMiddleware implements NestMiddleware { if (filename === '/assets/LICENSE') { return true; } else if ( - filename.includes('auth/ey') || - filename.includes( - 'personal-finance-tools/open-source-alternative-to-de.fi' - ) || - filename.includes( - 'personal-finance-tools/open-source-alternative-to-markets.sh' - ) + filename.endsWith('-de.fi') || + filename.endsWith('-markets.sh') || + filename.includes('auth/ey') ) { return false; } diff --git a/apps/api/src/services/tag/tag.service.ts b/apps/api/src/services/tag/tag.service.ts index c38abe592..eb2d7bfef 100644 --- a/apps/api/src/services/tag/tag.service.ts +++ b/apps/api/src/services/tag/tag.service.ts @@ -1,5 +1,4 @@ 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 { Prisma, Tag } from '@prisma/client'; @@ -80,8 +79,7 @@ export class TagService { id, name, userId, - isUsed: - _count.activities > 0 && ![TAG_ID_EXCLUDE_FROM_ANALYSIS].includes(id) + isUsed: _count.activities > 0 })); } diff --git a/apps/client/src/app/components/header/header.component.html b/apps/client/src/app/components/header/header.component.html index fb78a5de1..13b987f2f 100644 --- a/apps/client/src/app/components/header/header.component.html +++ b/apps/client/src/app/components/header/header.component.html @@ -12,7 +12,7 @@ -