diff --git a/CHANGELOG.md b/CHANGELOG.md
index 7109fc62c0..fcb9052866 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -7,13 +7,20 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
## Unreleased
+### Added
+
+- Added the stack trace logging for `MaxListenersExceededWarning` occurrences
+
### Changed
+- Refactored the deprecated animation providers (`provideAnimations()` and `provideNoopAnimations()`)
- Improved the language localization for German (`de`)
+- Improved the language localization for Polish (`pl`)
### Fixed
- Fixed an issue with the localization in the _FIRE_ page
+- Improved the spacing in the testimonial section on the landing page
## 3.32.0 - 2026-07-22
diff --git a/apps/api/src/main.ts b/apps/api/src/main.ts
index 77d571ea0b..b30a20323e 100644
--- a/apps/api/src/main.ts
+++ b/apps/api/src/main.ts
@@ -26,6 +26,15 @@ import { AppModule } from './app/app.module';
import { environment } from './environments/environment';
const logger = new Logger('Bootstrap');
+const processWarningLogger = new Logger('ProcessWarning');
+
+process.on('warning', ({ name, stack }) => {
+ if (name === 'MaxListenersExceededWarning') {
+ // Log the stack trace of MaxListenersExceededWarning occurrences to identify
+ // the event emitter and the call site which registers the listeners
+ processWarningLogger.warn(stack);
+ }
+});
async function bootstrap() {
// Respect HTTP_PROXY / HTTPS_PROXY / NO_PROXY for outbound HTTP requests
diff --git a/apps/client/src/app/pages/landing/landing-page.html b/apps/client/src/app/pages/landing/landing-page.html
index cb86b471db..bdd5f422f6 100644
--- a/apps/client/src/app/pages/landing/landing-page.html
+++ b/apps/client/src/app/pages/landing/landing-page.html
@@ -247,11 +247,11 @@
@if (testimonial.url) {
{{
testimonial.author
- }}
+ }},
} @else {
- {{ testimonial.author }}
+ {{ testimonial.author }},
}
- ,
{{ testimonial.country }}
diff --git a/apps/client/src/locales/messages.pl.xlf b/apps/client/src/locales/messages.pl.xlf
index a5d535a06d..1068a7d573 100644
--- a/apps/client/src/locales/messages.pl.xlf
+++ b/apps/client/src/locales/messages.pl.xlf
@@ -6518,7 +6518,7 @@
Active
- Antywne
+ Aktywne
apps/client/src/app/components/home-holdings/home-holdings.component.ts
64
diff --git a/apps/client/src/main.ts b/apps/client/src/main.ts
index 45901baeca..3e80df9c73 100644
--- a/apps/client/src/main.ts
+++ b/apps/client/src/main.ts
@@ -23,7 +23,6 @@ import {
import { MatSnackBarModule } from '@angular/material/snack-bar';
import { MatTooltipModule } from '@angular/material/tooltip';
import { bootstrapApplication } from '@angular/platform-browser';
-import { provideAnimations } from '@angular/platform-browser/animations';
import { RouterModule, TitleStrategy } from '@angular/router';
import { ServiceWorkerModule } from '@angular/service-worker';
import { provideIonicAngular } from '@ionic/angular/standalone';
@@ -82,7 +81,6 @@ import { environment } from './environments/environment';
),
LanguageService,
ModulePreloadService,
- provideAnimations(),
provideHttpClient(withInterceptorsFromDi()),
provideIonicAngular(),
provideMarkdown(),
diff --git a/libs/ui/src/lib/carousel/carousel.component.ts b/libs/ui/src/lib/carousel/carousel.component.ts
index 4ecd12c79b..f47d41ae5f 100644
--- a/libs/ui/src/lib/carousel/carousel.component.ts
+++ b/libs/ui/src/lib/carousel/carousel.component.ts
@@ -1,4 +1,5 @@
import {
+ ANIMATION_MODULE_TYPE,
CUSTOM_ELEMENTS_SCHEMA,
ChangeDetectionStrategy,
Component,
@@ -11,7 +12,6 @@ import {
ViewChild
} from '@angular/core';
import { MatButtonModule } from '@angular/material/button';
-import { ANIMATION_MODULE_TYPE } from '@angular/platform-browser/animations';
import { IonIcon } from '@ionic/angular/standalone';
import { addIcons } from 'ionicons';
import { chevronBackOutline, chevronForwardOutline } from 'ionicons/icons';
diff --git a/libs/ui/src/lib/entity-logo/entity-logo.component.stories.ts b/libs/ui/src/lib/entity-logo/entity-logo.component.stories.ts
index 6c89718bd2..45a9962944 100644
--- a/libs/ui/src/lib/entity-logo/entity-logo.component.stories.ts
+++ b/libs/ui/src/lib/entity-logo/entity-logo.component.stories.ts
@@ -1,6 +1,5 @@
import { CommonModule } from '@angular/common';
-import { importProvidersFrom } from '@angular/core';
-import { provideNoopAnimations } from '@angular/platform-browser/animations';
+import { ANIMATION_MODULE_TYPE, importProvidersFrom } from '@angular/core';
import { applicationConfig, Meta, StoryObj } from '@storybook/angular';
import { EntityLogoImageSourceServiceMock } from '../mocks/entity-logo-image-source.service.mock';
@@ -13,8 +12,11 @@ export default {
decorators: [
applicationConfig({
providers: [
- provideNoopAnimations(),
importProvidersFrom(CommonModule),
+ {
+ provide: ANIMATION_MODULE_TYPE,
+ useValue: 'NoopAnimations'
+ },
{
provide: EntityLogoImageSourceService,
useValue: new EntityLogoImageSourceServiceMock()
diff --git a/libs/ui/src/lib/fire-calculator/fire-calculator.component.stories.ts b/libs/ui/src/lib/fire-calculator/fire-calculator.component.stories.ts
index ad80499d7b..f4528aac63 100644
--- a/libs/ui/src/lib/fire-calculator/fire-calculator.component.stories.ts
+++ b/libs/ui/src/lib/fire-calculator/fire-calculator.component.stories.ts
@@ -1,6 +1,7 @@
import { DEFAULT_LOCALE } from '@ghostfolio/common/config';
import { CommonModule } from '@angular/common';
+import { ANIMATION_MODULE_TYPE } from '@angular/core';
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
import '@angular/localize/init';
import { MatButtonModule } from '@angular/material/button';
@@ -8,7 +9,6 @@ import { provideNativeDateAdapter } from '@angular/material/core';
import { MatDatepickerModule } from '@angular/material/datepicker';
import { MatFormFieldModule } from '@angular/material/form-field';
import { MatInputModule } from '@angular/material/input';
-import { NoopAnimationsModule } from '@angular/platform-browser/animations';
import { moduleMetadata } from '@storybook/angular';
import type { Meta, StoryObj } from '@storybook/angular';
import { NgxSkeletonLoaderModule } from 'ngx-skeleton-loader';
@@ -32,10 +32,16 @@ export default {
MatFormFieldModule,
MatInputModule,
NgxSkeletonLoaderModule,
- NoopAnimationsModule,
ReactiveFormsModule
],
- providers: [FireCalculatorService, provideNativeDateAdapter()]
+ providers: [
+ FireCalculatorService,
+ provideNativeDateAdapter(),
+ {
+ provide: ANIMATION_MODULE_TYPE,
+ useValue: 'NoopAnimations'
+ }
+ ]
})
]
} as Meta;
diff --git a/libs/ui/src/lib/symbol-autocomplete/symbol-autocomplete.component.stories.ts b/libs/ui/src/lib/symbol-autocomplete/symbol-autocomplete.component.stories.ts
index de7a09a042..5bae01c70f 100644
--- a/libs/ui/src/lib/symbol-autocomplete/symbol-autocomplete.component.stories.ts
+++ b/libs/ui/src/lib/symbol-autocomplete/symbol-autocomplete.component.stories.ts
@@ -2,14 +2,13 @@ import { LookupItem } from '@ghostfolio/common/interfaces';
import { CommonModule } from '@angular/common';
import { HttpClient } from '@angular/common/http';
-import { importProvidersFrom } from '@angular/core';
+import { ANIMATION_MODULE_TYPE, importProvidersFrom } from '@angular/core';
import {
FormControl,
FormsModule,
NgControl,
ReactiveFormsModule
} from '@angular/forms';
-import { provideNoopAnimations } from '@angular/platform-browser/animations';
import { applicationConfig, Meta, StoryObj } from '@storybook/angular';
import { HttpClientMock } from '../mocks/httpClient.mock';
@@ -75,8 +74,11 @@ export default {
decorators: [
applicationConfig({
providers: [
- provideNoopAnimations(),
importProvidersFrom(CommonModule, FormsModule, ReactiveFormsModule),
+ {
+ provide: ANIMATION_MODULE_TYPE,
+ useValue: 'NoopAnimations'
+ },
{
provide: NgControl,
useValue: {
diff --git a/libs/ui/src/lib/tags-selector/tags-selector.component.stories.ts b/libs/ui/src/lib/tags-selector/tags-selector.component.stories.ts
index d11175fd1c..48aeaffe31 100644
--- a/libs/ui/src/lib/tags-selector/tags-selector.component.stories.ts
+++ b/libs/ui/src/lib/tags-selector/tags-selector.component.stories.ts
@@ -1,6 +1,6 @@
import { CommonModule } from '@angular/common';
+import { ANIMATION_MODULE_TYPE } from '@angular/core';
import '@angular/localize/init';
-import { NoopAnimationsModule } from '@angular/platform-browser/animations';
import { Meta, moduleMetadata, StoryObj } from '@storybook/angular';
import { GfTagsSelectorComponent } from './tags-selector.component';
@@ -10,7 +10,13 @@ export default {
component: GfTagsSelectorComponent,
decorators: [
moduleMetadata({
- imports: [CommonModule, NoopAnimationsModule]
+ imports: [CommonModule],
+ providers: [
+ {
+ provide: ANIMATION_MODULE_TYPE,
+ useValue: 'NoopAnimations'
+ }
+ ]
})
]
} as Meta;
diff --git a/libs/ui/src/lib/top-holdings/top-holdings.component.html b/libs/ui/src/lib/top-holdings/top-holdings.component.html
index 11900106ae..60f8032891 100644
--- a/libs/ui/src/lib/top-holdings/top-holdings.component.html
+++ b/libs/ui/src/lib/top-holdings/top-holdings.component.html
@@ -58,7 +58,7 @@
mat-cell
[attr.colspan]="displayedColumns.length"
>
-
+
collapsed',
- animate('225ms cubic-bezier(0.4, 0.0, 0.2, 1)')
- )
- ])
- ],
changeDetection: ChangeDetectionStrategy.OnPush,
imports: [
GfValueComponent,
diff --git a/libs/ui/src/lib/value/value.component.stories.ts b/libs/ui/src/lib/value/value.component.stories.ts
index 5a285e89ba..a5971b2520 100644
--- a/libs/ui/src/lib/value/value.component.stories.ts
+++ b/libs/ui/src/lib/value/value.component.stories.ts
@@ -1,5 +1,5 @@
+import { ANIMATION_MODULE_TYPE } from '@angular/core';
import '@angular/localize/init';
-import { provideNoopAnimations } from '@angular/platform-browser/animations';
import { applicationConfig, moduleMetadata } from '@storybook/angular';
import type { Meta, StoryObj } from '@storybook/angular';
import { NgxSkeletonLoaderModule } from 'ngx-skeleton-loader';
@@ -11,7 +11,12 @@ export default {
component: GfValueComponent,
decorators: [
applicationConfig({
- providers: [provideNoopAnimations()]
+ providers: [
+ {
+ provide: ANIMATION_MODULE_TYPE,
+ useValue: 'NoopAnimations'
+ }
+ ]
}),
moduleMetadata({
imports: [NgxSkeletonLoaderModule]