From 6c6f20c3fdbc1dc636bfc50532cf01dbac05ff7e Mon Sep 17 00:00:00 2001
From: Kenrick Tandrian <60643640+KenTandrian@users.noreply.github.com>
Date: Fri, 20 Feb 2026 23:28:06 +0700
Subject: [PATCH 4/9] Task/improve type safety in account balances component
(#6352)
* fix(lib): add type annotations for date adapter
* fix(lib): handle form value possibly null
* fix(lint): use arrow fn for validators
* fix(lib): accounts table typings
* fix(lib): remove unsubscribeSubject due to lack of observable
* fix(lib): remove validators variable
* feat(lib): implement inject functions
* feat(lib): make locale an input signal
* feat(lib): make showActions an input signal
* feat(lib): make accountId an input signal
* feat(lib): make accountCurrency an input signal
* feat(lib): make accountBalances an input signal
* feat(lib): make sort a viewChild signal
* feat(lib): implement isNil
---
.../account-balances.component.html | 10 +--
.../account-balances.component.ts | 68 +++++++++----------
.../accounts-table.component.ts | 2 +-
3 files changed, 37 insertions(+), 43 deletions(-)
diff --git a/libs/ui/src/lib/account-balances/account-balances.component.html b/libs/ui/src/lib/account-balances/account-balances.component.html
index caef922ed..29037a985 100644
--- a/libs/ui/src/lib/account-balances/account-balances.component.html
+++ b/libs/ui/src/lib/account-balances/account-balances.component.html
@@ -12,7 +12,7 @@
Date
|
-
+
|
@@ -37,7 +37,7 @@
@@ -58,7 +58,7 @@
|
- @if (showActions) {
+ @if (showActions()) {
diff --git a/libs/ui/src/lib/activities-filter/activities-filter.component.ts b/libs/ui/src/lib/activities-filter/activities-filter.component.ts
index 34f883c67..25fad683d 100644
--- a/libs/ui/src/lib/activities-filter/activities-filter.component.ts
+++ b/libs/ui/src/lib/activities-filter/activities-filter.component.ts
@@ -8,14 +8,14 @@ import {
ChangeDetectionStrategy,
Component,
ElementRef,
- EventEmitter,
Input,
OnChanges,
- OnDestroy,
- Output,
SimpleChanges,
- ViewChild
+ ViewChild,
+ input,
+ output
} from '@angular/core';
+import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
import { FormControl, ReactiveFormsModule } from '@angular/forms';
import {
MatAutocomplete,
@@ -30,8 +30,7 @@ import { IonIcon } from '@ionic/angular/standalone';
import { addIcons } from 'ionicons';
import { closeOutline, searchOutline } from 'ionicons/icons';
import { groupBy } from 'lodash';
-import { BehaviorSubject, Observable, Subject } from 'rxjs';
-import { takeUntil } from 'rxjs/operators';
+import { BehaviorSubject } from 'rxjs';
import { translate } from '../i18n';
@@ -53,28 +52,26 @@ import { translate } from '../i18n';
styleUrls: ['./activities-filter.component.scss'],
templateUrl: './activities-filter.component.html'
})
-export class GfActivitiesFilterComponent implements OnChanges, OnDestroy {
+export class GfActivitiesFilterComponent implements OnChanges {
@Input() allFilters: Filter[];
- @Input() isLoading: boolean;
- @Input() placeholder: string;
- @Output() valueChanged = new EventEmitter();
+ @ViewChild('autocomplete') protected matAutocomplete: MatAutocomplete;
+ @ViewChild('searchInput') protected searchInput: ElementRef;
- @ViewChild('autocomplete') matAutocomplete: MatAutocomplete;
- @ViewChild('searchInput') searchInput: ElementRef;
+ public readonly isLoading = input.required();
+ public readonly placeholder = input.required();
+ public readonly valueChanged = output();
- public filterGroups$: Subject = new BehaviorSubject([]);
- public filters$: Subject = new BehaviorSubject([]);
- public filters: Observable = this.filters$.asObservable();
- public searchControl = new FormControl(undefined);
- public selectedFilters: Filter[] = [];
- public separatorKeysCodes: number[] = [ENTER, COMMA];
-
- private unsubscribeSubject = new Subject();
+ protected readonly filterGroups$ = new BehaviorSubject([]);
+ protected readonly searchControl = new FormControl(
+ null
+ );
+ protected selectedFilters: Filter[] = [];
+ protected readonly separatorKeysCodes: number[] = [ENTER, COMMA];
public constructor() {
this.searchControl.valueChanges
- .pipe(takeUntil(this.unsubscribeSubject))
+ .pipe(takeUntilDestroyed())
.subscribe((filterOrSearchTerm) => {
if (filterOrSearchTerm) {
const searchTerm =
@@ -97,41 +94,39 @@ export class GfActivitiesFilterComponent implements OnChanges, OnDestroy {
}
}
- public onAddFilter({ input, value }: MatChipInputEvent) {
+ public onAddFilter({ chipInput, value }: MatChipInputEvent) {
if (value?.trim()) {
this.updateFilters();
}
// Reset the input value
- if (input) {
- input.value = '';
+ if (chipInput.inputElement) {
+ chipInput.inputElement.value = '';
}
- this.searchControl.setValue(undefined);
+ this.searchControl.setValue(null);
}
public onRemoveFilter(aFilter: Filter) {
- this.selectedFilters = this.selectedFilters.filter((filter) => {
- return filter.id !== aFilter.id;
+ this.selectedFilters = this.selectedFilters.filter(({ id }) => {
+ return id !== aFilter.id;
});
this.updateFilters();
}
public onSelectFilter(event: MatAutocompleteSelectedEvent) {
- this.selectedFilters.push(
- this.allFilters.find((filter) => {
- return filter.id === event.option.value;
- })
- );
+ const filter = this.allFilters.find(({ id }) => {
+ return id === event.option.value;
+ });
+
+ if (filter) {
+ this.selectedFilters.push(filter);
+ }
+
this.updateFilters();
this.searchInput.nativeElement.value = '';
- this.searchControl.setValue(undefined);
- }
-
- public ngOnDestroy() {
- this.unsubscribeSubject.next();
- this.unsubscribeSubject.complete();
+ this.searchControl.setValue(null);
}
private getGroupedFilters(searchTerm?: string) {
@@ -139,23 +134,23 @@ export class GfActivitiesFilterComponent implements OnChanges, OnDestroy {
this.allFilters
.filter((filter) => {
// Filter selected filters
- return !this.selectedFilters.some((selectedFilter) => {
- return selectedFilter.id === filter.id;
+ return !this.selectedFilters.some(({ id }) => {
+ return id === filter.id;
});
})
.filter((filter) => {
if (searchTerm) {
// Filter by search term
return filter.label
- .toLowerCase()
+ ?.toLowerCase()
.includes(searchTerm.toLowerCase());
}
return filter;
})
- .sort((a, b) => a.label?.localeCompare(b.label)),
- (filter) => {
- return filter.type;
+ .sort((a, b) => (a.label ?? '').localeCompare(b.label ?? '')),
+ ({ type }) => {
+ return type;
}
);
From 25200bfd6d45871d109db8eca2f4004029d2a58c Mon Sep 17 00:00:00 2001
From: Thomas Kaul <4159106+dtslvr@users.noreply.github.com>
Date: Sat, 21 Feb 2026 08:33:51 +0100
Subject: [PATCH 8/9] Task/improve usability of portfolio summary in presenter
view (#6360)
* Improve usability in presenter view
* Update changelog
---
CHANGELOG.md | 1 +
.../portfolio-summary/portfolio-summary.component.html | 7 +++++--
2 files changed, 6 insertions(+), 2 deletions(-)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index c0fb2b2e4..594b8faa1 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -9,6 +9,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Changed
+- Improved the usability of the portfolio summary tab on the home page in the _Presenter View_
- Refreshed the cryptocurrencies list
- Improved the language localization for German (`de`)
- Improved the language localization for Spanish (`es`)
diff --git a/apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html b/apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html
index 99e0c9a53..0e26a49a8 100644
--- a/apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html
+++ b/apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html
@@ -184,18 +184,21 @@
[ngClass]="{
'cursor-pointer':
hasPermissionToUpdateUserSettings &&
+ !user?.settings?.isRestrictedView &&
user?.subscription?.type !== 'Basic'
}"
(click)="
hasPermissionToUpdateUserSettings &&
+ !user?.settings?.isRestrictedView &&
user?.subscription?.type !== 'Basic' &&
onEditEmergencyFund()
"
>
@if (
hasPermissionToUpdateUserSettings &&
- user?.subscription?.type !== 'Basic' &&
- !isLoading
+ !isLoading &&
+ !user?.settings?.isRestrictedView &&
+ user?.subscription?.type !== 'Basic'
) {
Date: Sat, 21 Feb 2026 08:37:55 +0100
Subject: [PATCH 9/9] Release 2.241.0 (#6361)
---
CHANGELOG.md | 2 +-
package-lock.json | 4 ++--
package.json | 2 +-
3 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 594b8faa1..6f485abeb 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -5,7 +5,7 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
-## Unreleased
+## 2.241.0 - 2026-02-21
### Changed
diff --git a/package-lock.json b/package-lock.json
index 636147048..2a6d30cc8 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,12 +1,12 @@
{
"name": "ghostfolio",
- "version": "2.240.0",
+ "version": "2.241.0",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "ghostfolio",
- "version": "2.240.0",
+ "version": "2.241.0",
"hasInstallScript": true,
"license": "AGPL-3.0",
"dependencies": {
diff --git a/package.json b/package.json
index 4bfdd1cb1..3dcfde537 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "ghostfolio",
- "version": "2.240.0",
+ "version": "2.241.0",
"homepage": "https://ghostfol.io",
"license": "AGPL-3.0",
"repository": "https://github.com/ghostfolio/ghostfolio",
| |