From 7ca88702a9f6eb22847b16662f7a56449780d9ed Mon Sep 17 00:00:00 2001 From: Kenrick Tandrian <60643640+KenTandrian@users.noreply.github.com> Date: Thu, 9 Jul 2026 22:52:23 +0700 Subject: [PATCH 1/4] Task/improve type safety in user account membership component (#7286) * fix(client): resolve type errors * feat(client): enforce encapsulation * fix(client): remove unused variable * feat(client): enforce immutability * feat(client): replace constructor based DI with inject functions --- .../user-account-membership.component.ts | 54 +++++++++---------- 1 file changed, 27 insertions(+), 27 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 bdf2c3eb6..74ee2f64a 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 @@ -3,7 +3,6 @@ import { ConfirmationDialogType } from '@ghostfolio/common/enums'; import { getDateFormatString } from '@ghostfolio/common/helper'; import { User } from '@ghostfolio/common/interfaces'; import { hasPermission, permissions } from '@ghostfolio/common/permissions'; -import { publicRoutes } from '@ghostfolio/common/routes/routes'; import { GfMembershipCardComponent } from '@ghostfolio/ui/membership-card'; import { NotificationService } from '@ghostfolio/ui/notifications'; import { GfPremiumIndicatorComponent } from '@ghostfolio/ui/premium-indicator'; @@ -14,7 +13,8 @@ import { ChangeDetectionStrategy, ChangeDetectorRef, Component, - DestroyRef + DestroyRef, + inject } from '@angular/core'; import { takeUntilDestroyed } from '@angular/core/rxjs-interop'; import { MatButtonModule } from '@angular/material/button'; @@ -40,29 +40,29 @@ import { catchError } from 'rxjs/operators'; templateUrl: './user-account-membership.html' }) export class GfUserAccountMembershipComponent { - public baseCurrency: string; - public coupon: number; - public couponId: string; - public defaultDateFormat: string; - public durationExtension: StringValue; - public hasPermissionForSubscription: boolean; - public hasPermissionToCreateApiKey: boolean; - public hasPermissionToUpdateUserSettings: boolean; - public price: number; - public priceId: string; - public routerLinkPricing = publicRoutes.pricing.routerLink; - public trySubscriptionMail = + protected readonly baseCurrency: string; + protected coupon: number | undefined; + protected defaultDateFormat: string; + protected durationExtension: StringValue | undefined; + protected readonly hasPermissionForSubscription: boolean; + protected hasPermissionToCreateApiKey: boolean; + protected hasPermissionToUpdateUserSettings: boolean; + protected price: number; + protected readonly trySubscriptionMail = '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; - - public constructor( - private changeDetectorRef: ChangeDetectorRef, - private dataService: DataService, - private destroyRef: DestroyRef, - private notificationService: NotificationService, - private snackBar: MatSnackBar, - private userService: UserService - ) { + protected user: User; + + private couponId: string | undefined; + private priceId: string; + + private readonly changeDetectorRef = inject(ChangeDetectorRef); + private readonly dataService = inject(DataService); + private readonly destroyRef = inject(DestroyRef); + private readonly notificationService = inject(NotificationService); + private readonly snackBar = inject(MatSnackBar); + private readonly userService = inject(UserService); + + public constructor() { const { baseCurrency, globalPermissions } = this.dataService.fetchInfo(); this.baseCurrency = baseCurrency; @@ -104,7 +104,7 @@ export class GfUserAccountMembershipComponent { }); } - public onCheckout() { + protected onCheckout() { this.dataService .createStripeCheckoutSession({ couponId: this.couponId, @@ -125,7 +125,7 @@ export class GfUserAccountMembershipComponent { }); } - public onGenerateApiKey() { + protected onGenerateApiKey() { this.notificationService.confirm({ confirmFn: () => { this.dataService @@ -158,7 +158,7 @@ export class GfUserAccountMembershipComponent { }); } - public onRedeemCoupon() { + protected onRedeemCoupon() { this.notificationService.prompt({ confirmFn: (value) => { const couponCode = value?.trim(); From bc2cc8b6fdbeb3c9bc7b8207f3f7dfb41220d568 Mon Sep 17 00:00:00 2001 From: Thomas Kaul <4159106+dtslvr@users.noreply.github.com> Date: Thu, 9 Jul 2026 17:53:12 +0200 Subject: [PATCH 2/4] Task/set change detection strategy to OnPush in blog page components (#7288) * Set change detection strategy to OnPush * Update changelog --- CHANGELOG.md | 1 + .../07/hallo-ghostfolio/hallo-ghostfolio-page.component.ts | 3 ++- .../07/hello-ghostfolio/hello-ghostfolio-page.component.ts | 3 ++- .../first-months-in-open-source-page.component.ts | 3 ++- .../ghostfolio-meets-internet-identity-page.component.ts | 3 ++- .../how-do-i-get-my-finances-in-order-page.component.ts | 3 ++- .../500-stars-on-github-page.component.ts | 3 ++- .../hacktoberfest-2022-page.component.ts | 3 ++- .../black-friday-2022/black-friday-2022-page.component.ts | 3 ++- ...ce-of-tracking-your-personal-finances-page.component.ts | 3 ++- .../ghostfolio-auf-sackgeld-vorgestellt-page.component.ts | 3 ++- .../ghostfolio-meets-umbrel-page.component.ts | 3 ++- .../1000-stars-on-github-page.component.ts | 3 ++- ...r-financial-potential-with-ghostfolio-page.component.ts | 3 ++- .../exploring-the-path-to-fire-page.component.ts | 3 ++- .../ghostfolio-joins-oss-friends-page.component.ts | 3 ++- .../2023/09/ghostfolio-2/ghostfolio-2-page.component.ts | 3 ++- .../hacktoberfest-2023-page.component.ts | 3 ++- .../11/black-week-2023/black-week-2023-page.component.ts | 3 ++- .../hacktoberfest-2023-debriefing-page.component.ts | 3 ++- .../hacktoberfest-2024-page.component.ts | 3 ++- .../11/black-weeks-2024/black-weeks-2024-page.component.ts | 3 ++- .../hacktoberfest-2025-page.component.ts | 3 ++- .../11/black-weeks-2025/black-weeks-2025-page.component.ts | 3 ++- .../2026/04/ghostfolio-3/ghostfolio-3-page.component.ts | 3 ++- apps/client/src/app/pages/blog/blog-page.component.ts | 7 ++++++- 26 files changed, 55 insertions(+), 25 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d8c54fac3..2f0d44848 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 - Migrated the deprecated `@nx/webpack:webpack` executor to `@nx/webpack/plugin` +- Set the change detection strategy to `OnPush` in the blog page components - Set the change detection strategy to `OnPush` in the markets overview - Improved the language localization for Chinese (`zh`) diff --git a/apps/client/src/app/pages/blog/2021/07/hallo-ghostfolio/hallo-ghostfolio-page.component.ts b/apps/client/src/app/pages/blog/2021/07/hallo-ghostfolio/hallo-ghostfolio-page.component.ts index 597c8d998..ac6ec5c9e 100644 --- a/apps/client/src/app/pages/blog/2021/07/hallo-ghostfolio/hallo-ghostfolio-page.component.ts +++ b/apps/client/src/app/pages/blog/2021/07/hallo-ghostfolio/hallo-ghostfolio-page.component.ts @@ -1,10 +1,11 @@ import { publicRoutes } from '@ghostfolio/common/routes/routes'; -import { Component } from '@angular/core'; +import { ChangeDetectionStrategy, Component } from '@angular/core'; import { MatButtonModule } from '@angular/material/button'; import { RouterModule } from '@angular/router'; @Component({ + changeDetection: ChangeDetectionStrategy.OnPush, host: { class: 'page' }, imports: [MatButtonModule, RouterModule], selector: 'gf-hallo-ghostfolio-page', diff --git a/apps/client/src/app/pages/blog/2021/07/hello-ghostfolio/hello-ghostfolio-page.component.ts b/apps/client/src/app/pages/blog/2021/07/hello-ghostfolio/hello-ghostfolio-page.component.ts index dd29cfd80..22fe85853 100644 --- a/apps/client/src/app/pages/blog/2021/07/hello-ghostfolio/hello-ghostfolio-page.component.ts +++ b/apps/client/src/app/pages/blog/2021/07/hello-ghostfolio/hello-ghostfolio-page.component.ts @@ -1,10 +1,11 @@ import { publicRoutes } from '@ghostfolio/common/routes/routes'; -import { Component } from '@angular/core'; +import { ChangeDetectionStrategy, Component } from '@angular/core'; import { MatButtonModule } from '@angular/material/button'; import { RouterModule } from '@angular/router'; @Component({ + changeDetection: ChangeDetectionStrategy.OnPush, host: { class: 'page' }, imports: [MatButtonModule, RouterModule], selector: 'gf-hello-ghostfolio-page', diff --git a/apps/client/src/app/pages/blog/2022/01/first-months-in-open-source/first-months-in-open-source-page.component.ts b/apps/client/src/app/pages/blog/2022/01/first-months-in-open-source/first-months-in-open-source-page.component.ts index 91b05896d..2ab59f5ce 100644 --- a/apps/client/src/app/pages/blog/2022/01/first-months-in-open-source/first-months-in-open-source-page.component.ts +++ b/apps/client/src/app/pages/blog/2022/01/first-months-in-open-source/first-months-in-open-source-page.component.ts @@ -1,10 +1,11 @@ import { publicRoutes } from '@ghostfolio/common/routes/routes'; -import { Component } from '@angular/core'; +import { ChangeDetectionStrategy, Component } from '@angular/core'; import { MatButtonModule } from '@angular/material/button'; import { RouterModule } from '@angular/router'; @Component({ + changeDetection: ChangeDetectionStrategy.OnPush, host: { class: 'page' }, imports: [MatButtonModule, RouterModule], selector: 'gf-first-months-in-open-source-page', diff --git a/apps/client/src/app/pages/blog/2022/07/ghostfolio-meets-internet-identity/ghostfolio-meets-internet-identity-page.component.ts b/apps/client/src/app/pages/blog/2022/07/ghostfolio-meets-internet-identity/ghostfolio-meets-internet-identity-page.component.ts index c410dd2b2..2f2409131 100644 --- a/apps/client/src/app/pages/blog/2022/07/ghostfolio-meets-internet-identity/ghostfolio-meets-internet-identity-page.component.ts +++ b/apps/client/src/app/pages/blog/2022/07/ghostfolio-meets-internet-identity/ghostfolio-meets-internet-identity-page.component.ts @@ -1,10 +1,11 @@ import { publicRoutes } from '@ghostfolio/common/routes/routes'; -import { Component } from '@angular/core'; +import { ChangeDetectionStrategy, Component } from '@angular/core'; import { MatButtonModule } from '@angular/material/button'; import { RouterModule } from '@angular/router'; @Component({ + changeDetection: ChangeDetectionStrategy.OnPush, host: { class: 'page' }, imports: [MatButtonModule, RouterModule], selector: 'gf-ghostfolio-meets-internet-identity-page', diff --git a/apps/client/src/app/pages/blog/2022/07/how-do-i-get-my-finances-in-order/how-do-i-get-my-finances-in-order-page.component.ts b/apps/client/src/app/pages/blog/2022/07/how-do-i-get-my-finances-in-order/how-do-i-get-my-finances-in-order-page.component.ts index 812151600..f40170ba6 100644 --- a/apps/client/src/app/pages/blog/2022/07/how-do-i-get-my-finances-in-order/how-do-i-get-my-finances-in-order-page.component.ts +++ b/apps/client/src/app/pages/blog/2022/07/how-do-i-get-my-finances-in-order/how-do-i-get-my-finances-in-order-page.component.ts @@ -1,10 +1,11 @@ import { publicRoutes } from '@ghostfolio/common/routes/routes'; -import { Component } from '@angular/core'; +import { ChangeDetectionStrategy, Component } from '@angular/core'; import { MatButtonModule } from '@angular/material/button'; import { RouterModule } from '@angular/router'; @Component({ + changeDetection: ChangeDetectionStrategy.OnPush, host: { class: 'page' }, imports: [MatButtonModule, RouterModule], selector: 'gf-how-do-i-get-my-finances-in-order-page', diff --git a/apps/client/src/app/pages/blog/2022/08/500-stars-on-github/500-stars-on-github-page.component.ts b/apps/client/src/app/pages/blog/2022/08/500-stars-on-github/500-stars-on-github-page.component.ts index 9004ac0e2..2627f4134 100644 --- a/apps/client/src/app/pages/blog/2022/08/500-stars-on-github/500-stars-on-github-page.component.ts +++ b/apps/client/src/app/pages/blog/2022/08/500-stars-on-github/500-stars-on-github-page.component.ts @@ -1,10 +1,11 @@ import { publicRoutes } from '@ghostfolio/common/routes/routes'; -import { Component } from '@angular/core'; +import { ChangeDetectionStrategy, Component } from '@angular/core'; import { MatButtonModule } from '@angular/material/button'; import { RouterModule } from '@angular/router'; @Component({ + changeDetection: ChangeDetectionStrategy.OnPush, host: { class: 'page' }, imports: [MatButtonModule, RouterModule], selector: 'gf-500-stars-on-github-page', diff --git a/apps/client/src/app/pages/blog/2022/10/hacktoberfest-2022/hacktoberfest-2022-page.component.ts b/apps/client/src/app/pages/blog/2022/10/hacktoberfest-2022/hacktoberfest-2022-page.component.ts index fd34a6470..9e9fc2f8d 100644 --- a/apps/client/src/app/pages/blog/2022/10/hacktoberfest-2022/hacktoberfest-2022-page.component.ts +++ b/apps/client/src/app/pages/blog/2022/10/hacktoberfest-2022/hacktoberfest-2022-page.component.ts @@ -1,10 +1,11 @@ import { publicRoutes } from '@ghostfolio/common/routes/routes'; -import { Component } from '@angular/core'; +import { ChangeDetectionStrategy, Component } from '@angular/core'; import { MatButtonModule } from '@angular/material/button'; import { RouterModule } from '@angular/router'; @Component({ + changeDetection: ChangeDetectionStrategy.OnPush, host: { class: 'page' }, imports: [MatButtonModule, RouterModule], selector: 'gf-hacktoberfest-2022-page', diff --git a/apps/client/src/app/pages/blog/2022/11/black-friday-2022/black-friday-2022-page.component.ts b/apps/client/src/app/pages/blog/2022/11/black-friday-2022/black-friday-2022-page.component.ts index dd13d5b4d..2b57cb09e 100644 --- a/apps/client/src/app/pages/blog/2022/11/black-friday-2022/black-friday-2022-page.component.ts +++ b/apps/client/src/app/pages/blog/2022/11/black-friday-2022/black-friday-2022-page.component.ts @@ -1,11 +1,12 @@ import { publicRoutes } from '@ghostfolio/common/routes/routes'; import { GfPremiumIndicatorComponent } from '@ghostfolio/ui/premium-indicator'; -import { Component } from '@angular/core'; +import { ChangeDetectionStrategy, Component } from '@angular/core'; import { MatButtonModule } from '@angular/material/button'; import { RouterModule } from '@angular/router'; @Component({ + changeDetection: ChangeDetectionStrategy.OnPush, host: { class: 'page' }, imports: [GfPremiumIndicatorComponent, MatButtonModule, RouterModule], selector: 'gf-black-friday-2022-page', diff --git a/apps/client/src/app/pages/blog/2022/12/the-importance-of-tracking-your-personal-finances/the-importance-of-tracking-your-personal-finances-page.component.ts b/apps/client/src/app/pages/blog/2022/12/the-importance-of-tracking-your-personal-finances/the-importance-of-tracking-your-personal-finances-page.component.ts index 6e5a19f3c..4df232ea3 100644 --- a/apps/client/src/app/pages/blog/2022/12/the-importance-of-tracking-your-personal-finances/the-importance-of-tracking-your-personal-finances-page.component.ts +++ b/apps/client/src/app/pages/blog/2022/12/the-importance-of-tracking-your-personal-finances/the-importance-of-tracking-your-personal-finances-page.component.ts @@ -1,10 +1,11 @@ import { publicRoutes } from '@ghostfolio/common/routes/routes'; -import { Component } from '@angular/core'; +import { ChangeDetectionStrategy, Component } from '@angular/core'; import { MatButtonModule } from '@angular/material/button'; import { RouterModule } from '@angular/router'; @Component({ + changeDetection: ChangeDetectionStrategy.OnPush, host: { class: 'page' }, imports: [MatButtonModule, RouterModule], selector: 'gf-the-importance-of-tracking-your-personal-finances-page', diff --git a/apps/client/src/app/pages/blog/2023/01/ghostfolio-auf-sackgeld-vorgestellt/ghostfolio-auf-sackgeld-vorgestellt-page.component.ts b/apps/client/src/app/pages/blog/2023/01/ghostfolio-auf-sackgeld-vorgestellt/ghostfolio-auf-sackgeld-vorgestellt-page.component.ts index 53d670184..fb3f226ca 100644 --- a/apps/client/src/app/pages/blog/2023/01/ghostfolio-auf-sackgeld-vorgestellt/ghostfolio-auf-sackgeld-vorgestellt-page.component.ts +++ b/apps/client/src/app/pages/blog/2023/01/ghostfolio-auf-sackgeld-vorgestellt/ghostfolio-auf-sackgeld-vorgestellt-page.component.ts @@ -1,10 +1,11 @@ import { publicRoutes } from '@ghostfolio/common/routes/routes'; -import { Component } from '@angular/core'; +import { ChangeDetectionStrategy, Component } from '@angular/core'; import { MatButtonModule } from '@angular/material/button'; import { RouterModule } from '@angular/router'; @Component({ + changeDetection: ChangeDetectionStrategy.OnPush, host: { class: 'page' }, imports: [MatButtonModule, RouterModule], selector: 'gf-ghostfolio-auf-sackgeld-vorgestellt-page', diff --git a/apps/client/src/app/pages/blog/2023/02/ghostfolio-meets-umbrel/ghostfolio-meets-umbrel-page.component.ts b/apps/client/src/app/pages/blog/2023/02/ghostfolio-meets-umbrel/ghostfolio-meets-umbrel-page.component.ts index cb8dffcd3..3533af5c4 100644 --- a/apps/client/src/app/pages/blog/2023/02/ghostfolio-meets-umbrel/ghostfolio-meets-umbrel-page.component.ts +++ b/apps/client/src/app/pages/blog/2023/02/ghostfolio-meets-umbrel/ghostfolio-meets-umbrel-page.component.ts @@ -1,10 +1,11 @@ import { publicRoutes } from '@ghostfolio/common/routes/routes'; -import { Component } from '@angular/core'; +import { ChangeDetectionStrategy, Component } from '@angular/core'; import { MatButtonModule } from '@angular/material/button'; import { RouterModule } from '@angular/router'; @Component({ + changeDetection: ChangeDetectionStrategy.OnPush, host: { class: 'page' }, imports: [MatButtonModule, RouterModule], selector: 'gf-ghostfolio-meets-umbrel-page', diff --git a/apps/client/src/app/pages/blog/2023/03/1000-stars-on-github/1000-stars-on-github-page.component.ts b/apps/client/src/app/pages/blog/2023/03/1000-stars-on-github/1000-stars-on-github-page.component.ts index 60cc4177d..7a7d0197c 100644 --- a/apps/client/src/app/pages/blog/2023/03/1000-stars-on-github/1000-stars-on-github-page.component.ts +++ b/apps/client/src/app/pages/blog/2023/03/1000-stars-on-github/1000-stars-on-github-page.component.ts @@ -1,10 +1,11 @@ import { publicRoutes } from '@ghostfolio/common/routes/routes'; -import { Component } from '@angular/core'; +import { ChangeDetectionStrategy, Component } from '@angular/core'; import { MatButtonModule } from '@angular/material/button'; import { RouterModule } from '@angular/router'; @Component({ + changeDetection: ChangeDetectionStrategy.OnPush, host: { class: 'page' }, imports: [MatButtonModule, RouterModule], selector: 'gf-1000-stars-on-github-page', diff --git a/apps/client/src/app/pages/blog/2023/05/unlock-your-financial-potential-with-ghostfolio/unlock-your-financial-potential-with-ghostfolio-page.component.ts b/apps/client/src/app/pages/blog/2023/05/unlock-your-financial-potential-with-ghostfolio/unlock-your-financial-potential-with-ghostfolio-page.component.ts index 5781674a6..de4d9a3c2 100644 --- a/apps/client/src/app/pages/blog/2023/05/unlock-your-financial-potential-with-ghostfolio/unlock-your-financial-potential-with-ghostfolio-page.component.ts +++ b/apps/client/src/app/pages/blog/2023/05/unlock-your-financial-potential-with-ghostfolio/unlock-your-financial-potential-with-ghostfolio-page.component.ts @@ -1,10 +1,11 @@ import { publicRoutes } from '@ghostfolio/common/routes/routes'; -import { Component } from '@angular/core'; +import { ChangeDetectionStrategy, Component } from '@angular/core'; import { MatButtonModule } from '@angular/material/button'; import { RouterModule } from '@angular/router'; @Component({ + changeDetection: ChangeDetectionStrategy.OnPush, host: { class: 'page' }, imports: [MatButtonModule, RouterModule], selector: 'gf-unlock-your-financial-potential-with-ghostfolio-page', diff --git a/apps/client/src/app/pages/blog/2023/07/exploring-the-path-to-fire/exploring-the-path-to-fire-page.component.ts b/apps/client/src/app/pages/blog/2023/07/exploring-the-path-to-fire/exploring-the-path-to-fire-page.component.ts index 6c7bb2ae2..79adc0e93 100644 --- a/apps/client/src/app/pages/blog/2023/07/exploring-the-path-to-fire/exploring-the-path-to-fire-page.component.ts +++ b/apps/client/src/app/pages/blog/2023/07/exploring-the-path-to-fire/exploring-the-path-to-fire-page.component.ts @@ -1,10 +1,11 @@ import { publicRoutes } from '@ghostfolio/common/routes/routes'; -import { Component } from '@angular/core'; +import { ChangeDetectionStrategy, Component } from '@angular/core'; import { MatButtonModule } from '@angular/material/button'; import { RouterModule } from '@angular/router'; @Component({ + changeDetection: ChangeDetectionStrategy.OnPush, host: { class: 'page' }, imports: [MatButtonModule, RouterModule], selector: 'gf-exploring-the-path-to-fire-page-page', 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 c5a9cf178..937212d0c 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 @@ -1,10 +1,11 @@ import { publicRoutes } from '@ghostfolio/common/routes/routes'; -import { Component } from '@angular/core'; +import { ChangeDetectionStrategy, Component } from '@angular/core'; import { MatButtonModule } from '@angular/material/button'; import { RouterModule } from '@angular/router'; @Component({ + changeDetection: ChangeDetectionStrategy.OnPush, host: { class: 'page' }, imports: [MatButtonModule, RouterModule], selector: 'gf-ghostfolio-joins-oss-friends-page', diff --git a/apps/client/src/app/pages/blog/2023/09/ghostfolio-2/ghostfolio-2-page.component.ts b/apps/client/src/app/pages/blog/2023/09/ghostfolio-2/ghostfolio-2-page.component.ts index 197bc3e6b..3971b725b 100644 --- a/apps/client/src/app/pages/blog/2023/09/ghostfolio-2/ghostfolio-2-page.component.ts +++ b/apps/client/src/app/pages/blog/2023/09/ghostfolio-2/ghostfolio-2-page.component.ts @@ -1,10 +1,11 @@ import { publicRoutes } from '@ghostfolio/common/routes/routes'; -import { Component } from '@angular/core'; +import { ChangeDetectionStrategy, Component } from '@angular/core'; import { MatButtonModule } from '@angular/material/button'; import { RouterModule } from '@angular/router'; @Component({ + changeDetection: ChangeDetectionStrategy.OnPush, host: { class: 'page' }, imports: [MatButtonModule, RouterModule], selector: 'gf-ghostfolio-2-page', diff --git a/apps/client/src/app/pages/blog/2023/09/hacktoberfest-2023/hacktoberfest-2023-page.component.ts b/apps/client/src/app/pages/blog/2023/09/hacktoberfest-2023/hacktoberfest-2023-page.component.ts index 1cf3f20a5..77d8f7ee0 100644 --- a/apps/client/src/app/pages/blog/2023/09/hacktoberfest-2023/hacktoberfest-2023-page.component.ts +++ b/apps/client/src/app/pages/blog/2023/09/hacktoberfest-2023/hacktoberfest-2023-page.component.ts @@ -1,10 +1,11 @@ import { publicRoutes } from '@ghostfolio/common/routes/routes'; -import { Component } from '@angular/core'; +import { ChangeDetectionStrategy, Component } from '@angular/core'; import { MatButtonModule } from '@angular/material/button'; import { RouterModule } from '@angular/router'; @Component({ + changeDetection: ChangeDetectionStrategy.OnPush, host: { class: 'page' }, imports: [MatButtonModule, RouterModule], selector: 'gf-hacktoberfest-2023-page', diff --git a/apps/client/src/app/pages/blog/2023/11/black-week-2023/black-week-2023-page.component.ts b/apps/client/src/app/pages/blog/2023/11/black-week-2023/black-week-2023-page.component.ts index 09c13cfa2..a4503c99b 100644 --- a/apps/client/src/app/pages/blog/2023/11/black-week-2023/black-week-2023-page.component.ts +++ b/apps/client/src/app/pages/blog/2023/11/black-week-2023/black-week-2023-page.component.ts @@ -1,11 +1,12 @@ import { publicRoutes } from '@ghostfolio/common/routes/routes'; import { GfPremiumIndicatorComponent } from '@ghostfolio/ui/premium-indicator'; -import { Component } from '@angular/core'; +import { ChangeDetectionStrategy, Component } from '@angular/core'; import { MatButtonModule } from '@angular/material/button'; import { RouterModule } from '@angular/router'; @Component({ + changeDetection: ChangeDetectionStrategy.OnPush, host: { class: 'page' }, imports: [GfPremiumIndicatorComponent, MatButtonModule, RouterModule], selector: 'gf-black-week-2023-page', diff --git a/apps/client/src/app/pages/blog/2023/11/hacktoberfest-2023-debriefing/hacktoberfest-2023-debriefing-page.component.ts b/apps/client/src/app/pages/blog/2023/11/hacktoberfest-2023-debriefing/hacktoberfest-2023-debriefing-page.component.ts index 7c8b37931..14ff67a04 100644 --- a/apps/client/src/app/pages/blog/2023/11/hacktoberfest-2023-debriefing/hacktoberfest-2023-debriefing-page.component.ts +++ b/apps/client/src/app/pages/blog/2023/11/hacktoberfest-2023-debriefing/hacktoberfest-2023-debriefing-page.component.ts @@ -1,10 +1,11 @@ import { publicRoutes } from '@ghostfolio/common/routes/routes'; -import { Component } from '@angular/core'; +import { ChangeDetectionStrategy, Component } from '@angular/core'; import { MatButtonModule } from '@angular/material/button'; import { RouterModule } from '@angular/router'; @Component({ + changeDetection: ChangeDetectionStrategy.OnPush, host: { class: 'page' }, imports: [MatButtonModule, RouterModule], selector: 'gf-hacktoberfest-2023-debriefing-page', diff --git a/apps/client/src/app/pages/blog/2024/09/hacktoberfest-2024/hacktoberfest-2024-page.component.ts b/apps/client/src/app/pages/blog/2024/09/hacktoberfest-2024/hacktoberfest-2024-page.component.ts index 47f61adad..abfa39ffc 100644 --- a/apps/client/src/app/pages/blog/2024/09/hacktoberfest-2024/hacktoberfest-2024-page.component.ts +++ b/apps/client/src/app/pages/blog/2024/09/hacktoberfest-2024/hacktoberfest-2024-page.component.ts @@ -1,10 +1,11 @@ import { publicRoutes } from '@ghostfolio/common/routes/routes'; -import { Component } from '@angular/core'; +import { ChangeDetectionStrategy, Component } from '@angular/core'; import { MatButtonModule } from '@angular/material/button'; import { RouterModule } from '@angular/router'; @Component({ + changeDetection: ChangeDetectionStrategy.OnPush, host: { class: 'page' }, imports: [MatButtonModule, RouterModule], selector: 'gf-hacktoberfest-2024-page', diff --git a/apps/client/src/app/pages/blog/2024/11/black-weeks-2024/black-weeks-2024-page.component.ts b/apps/client/src/app/pages/blog/2024/11/black-weeks-2024/black-weeks-2024-page.component.ts index d15f081f8..38b7b80c4 100644 --- a/apps/client/src/app/pages/blog/2024/11/black-weeks-2024/black-weeks-2024-page.component.ts +++ b/apps/client/src/app/pages/blog/2024/11/black-weeks-2024/black-weeks-2024-page.component.ts @@ -1,11 +1,12 @@ import { publicRoutes } from '@ghostfolio/common/routes/routes'; import { GfPremiumIndicatorComponent } from '@ghostfolio/ui/premium-indicator'; -import { Component } from '@angular/core'; +import { ChangeDetectionStrategy, Component } from '@angular/core'; import { MatButtonModule } from '@angular/material/button'; import { RouterModule } from '@angular/router'; @Component({ + changeDetection: ChangeDetectionStrategy.OnPush, host: { class: 'page' }, imports: [GfPremiumIndicatorComponent, MatButtonModule, RouterModule], selector: 'gf-black-weeks-2024-page', diff --git a/apps/client/src/app/pages/blog/2025/09/hacktoberfest-2025/hacktoberfest-2025-page.component.ts b/apps/client/src/app/pages/blog/2025/09/hacktoberfest-2025/hacktoberfest-2025-page.component.ts index 72990ca47..88c70723d 100644 --- a/apps/client/src/app/pages/blog/2025/09/hacktoberfest-2025/hacktoberfest-2025-page.component.ts +++ b/apps/client/src/app/pages/blog/2025/09/hacktoberfest-2025/hacktoberfest-2025-page.component.ts @@ -1,10 +1,11 @@ import { publicRoutes } from '@ghostfolio/common/routes/routes'; -import { Component } from '@angular/core'; +import { ChangeDetectionStrategy, Component } from '@angular/core'; import { MatButtonModule } from '@angular/material/button'; import { RouterModule } from '@angular/router'; @Component({ + changeDetection: ChangeDetectionStrategy.OnPush, host: { class: 'page' }, imports: [MatButtonModule, RouterModule], selector: 'gf-hacktoberfest-2025-page', diff --git a/apps/client/src/app/pages/blog/2025/11/black-weeks-2025/black-weeks-2025-page.component.ts b/apps/client/src/app/pages/blog/2025/11/black-weeks-2025/black-weeks-2025-page.component.ts index c5947abf4..b98be9c76 100644 --- a/apps/client/src/app/pages/blog/2025/11/black-weeks-2025/black-weeks-2025-page.component.ts +++ b/apps/client/src/app/pages/blog/2025/11/black-weeks-2025/black-weeks-2025-page.component.ts @@ -1,11 +1,12 @@ import { publicRoutes } from '@ghostfolio/common/routes/routes'; import { GfPremiumIndicatorComponent } from '@ghostfolio/ui/premium-indicator'; -import { Component } from '@angular/core'; +import { ChangeDetectionStrategy, Component } from '@angular/core'; import { MatButtonModule } from '@angular/material/button'; import { RouterModule } from '@angular/router'; @Component({ + changeDetection: ChangeDetectionStrategy.OnPush, host: { class: 'page' }, imports: [GfPremiumIndicatorComponent, MatButtonModule, RouterModule], selector: 'gf-black-weeks-2025-page', diff --git a/apps/client/src/app/pages/blog/2026/04/ghostfolio-3/ghostfolio-3-page.component.ts b/apps/client/src/app/pages/blog/2026/04/ghostfolio-3/ghostfolio-3-page.component.ts index 63cd09d9c..e8e0c6da9 100644 --- a/apps/client/src/app/pages/blog/2026/04/ghostfolio-3/ghostfolio-3-page.component.ts +++ b/apps/client/src/app/pages/blog/2026/04/ghostfolio-3/ghostfolio-3-page.component.ts @@ -1,10 +1,11 @@ import { publicRoutes } from '@ghostfolio/common/routes/routes'; -import { Component } from '@angular/core'; +import { ChangeDetectionStrategy, Component } from '@angular/core'; import { MatButtonModule } from '@angular/material/button'; import { RouterModule } from '@angular/router'; @Component({ + changeDetection: ChangeDetectionStrategy.OnPush, host: { class: 'page' }, imports: [MatButtonModule, RouterModule], selector: 'gf-ghostfolio-3-page', 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 7f2c56d2d..f3227e3b0 100644 --- a/apps/client/src/app/pages/blog/blog-page.component.ts +++ b/apps/client/src/app/pages/blog/blog-page.component.ts @@ -1,7 +1,11 @@ import { hasPermission, permissions } from '@ghostfolio/common/permissions'; import { DataService } from '@ghostfolio/ui/services'; -import { Component, CUSTOM_ELEMENTS_SCHEMA } from '@angular/core'; +import { + ChangeDetectionStrategy, + Component, + CUSTOM_ELEMENTS_SCHEMA +} from '@angular/core'; import { MatCardModule } from '@angular/material/card'; import { RouterModule } from '@angular/router'; import { IonIcon } from '@ionic/angular/standalone'; @@ -9,6 +13,7 @@ import { addIcons } from 'ionicons'; import { chevronForwardOutline } from 'ionicons/icons'; @Component({ + changeDetection: ChangeDetectionStrategy.OnPush, host: { class: 'page' }, imports: [IonIcon, MatCardModule, RouterModule], schemas: [CUSTOM_ELEMENTS_SCHEMA], From 517b9a90e5169d60faaf990294e35fa6fcffcd35 Mon Sep 17 00:00:00 2001 From: Thomas Kaul <4159106+dtslvr@users.noreply.github.com> Date: Thu, 9 Jul 2026 17:53:55 +0200 Subject: [PATCH 3/4] Task/change wording in admin settings component (#7287) Change wording --- .../app/components/admin-settings/admin-settings.component.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 8ee6250e5..643737c4d 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 @@ -76,7 +76,7 @@ newpopular } From d083c80ece9d1cd363a8200c8503f9b7e20ec30b Mon Sep 17 00:00:00 2001 From: Thomas Kaul <4159106+dtslvr@users.noreply.github.com> Date: Thu, 9 Jul 2026 17:54:53 +0200 Subject: [PATCH 4/4] Task/extend personal finance tools (20260709) (#7284) Extend personal finance tools --- libs/common/src/lib/personal-finance-tools.ts | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/libs/common/src/lib/personal-finance-tools.ts b/libs/common/src/lib/personal-finance-tools.ts index 28b3f8495..b3aae6a02 100644 --- a/libs/common/src/lib/personal-finance-tools.ts +++ b/libs/common/src/lib/personal-finance-tools.ts @@ -14,6 +14,13 @@ export const personalFinanceTools: Product[] = [ slogan: 'Lifetime Personal Finance Control, One Single Payment.', url: 'https://www.mechcad.net' }, + { + categories: ['WEALTH_MANAGEMENT'], + key: 'akkuro', + name: 'Akkuro', + slogan: 'Composable Banking', + url: 'https://akkuro.com' + }, { categories: ['ETF_TRACKING', 'STOCK_TRACKING'], founded: 2023, @@ -215,7 +222,7 @@ export const personalFinanceTools: Product[] = [ name: 'Buxfer', origin: 'US', platforms: ['WEB'], - pricingPerYear: '$48', + pricingPerYear: '$96', regions: ['Global'], slogan: 'Take control of your financial future', url: 'https://www.buxfer.com'