From 17ef147da7406d0a3a70f87ce48025104c65357b Mon Sep 17 00:00:00 2001
From: csehatt741 <77381875+csehatt741@users.noreply.github.com>
Date: Thu, 12 Jun 2025 18:40:26 +0200
Subject: [PATCH] Feature/add current holdings as default options of symbol
search in create or update activity dialog (#4892)
* Add current holdings as default options of symbol search in create or update activity dialog
* Update changelog
---
CHANGELOG.md | 4 ++
...ate-or-update-activity-dialog.component.ts | 39 +++++++++++++++++++
.../create-or-update-activity-dialog.html | 1 +
.../symbol-autocomplete.component.ts | 14 ++++---
4 files changed, 53 insertions(+), 5 deletions(-)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 9077bc99e..9907e0522 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -7,6 +7,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
## Unreleased
+### Added
+
+- Added the current holdings as default options of the symbol search in the create or update activity dialog
+
### Changed
- Migrated the `HtmlTemplateMiddleware` to use `@Injectable()`
diff --git a/apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.component.ts b/apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.component.ts
index 4982125fe..154571077 100644
--- a/apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.component.ts
+++ b/apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.component.ts
@@ -2,6 +2,7 @@ import { CreateOrderDto } from '@ghostfolio/api/app/order/create-order.dto';
import { UpdateOrderDto } from '@ghostfolio/api/app/order/update-order.dto';
import { UserService } from '@ghostfolio/client/services/user/user.service';
import { getDateFormatString } from '@ghostfolio/common/helper';
+import { LookupItem } from '@ghostfolio/common/interfaces';
import { hasPermission, permissions } from '@ghostfolio/common/permissions';
import { translate } from '@ghostfolio/ui/i18n';
@@ -44,6 +45,7 @@ export class CreateOrUpdateActivityDialog implements OnDestroy {
public currencyOfAssetProfile: string;
public currentMarketPrice = null;
public defaultDateFormat: string;
+ public defaultLookupItems: LookupItem[] = [];
public hasPermissionToCreateOwnTag: boolean;
public isLoading = false;
public isToday = isToday;
@@ -83,6 +85,43 @@ export class CreateOrUpdateActivityDialog implements OnDestroy {
this.defaultDateFormat = getDateFormatString(this.locale);
this.platforms = platforms;
+ this.dataService
+ .fetchPortfolioHoldings()
+ .pipe(takeUntil(this.unsubscribeSubject))
+ .subscribe(({ holdings }) => {
+ this.defaultLookupItems = holdings
+ .filter(({ assetSubClass }) => {
+ return !['CASH'].includes(assetSubClass);
+ })
+ .sort((a, b) => {
+ return a.name?.localeCompare(b.name);
+ })
+ .map(
+ ({
+ assetClass,
+ assetSubClass,
+ currency,
+ dataSource,
+ name,
+ symbol
+ }) => {
+ return {
+ assetClass,
+ assetSubClass,
+ currency,
+ dataSource,
+ name,
+ symbol,
+ dataProviderInfo: {
+ isPremium: false
+ }
+ };
+ }
+ );
+
+ this.changeDetectorRef.markForCheck();
+ });
+
this.tagsAvailable =
this.data.user?.tags?.map((tag) => {
return {
diff --git a/apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html b/apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html
index a1ca6e323..6392456b5 100644
--- a/apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html
+++ b/apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html
@@ -124,6 +124,7 @@
Name, symbol or ISIN
diff --git a/libs/ui/src/lib/symbol-autocomplete/symbol-autocomplete.component.ts b/libs/ui/src/lib/symbol-autocomplete/symbol-autocomplete.component.ts
index 4d73e3c53..4fb974c54 100644
--- a/libs/ui/src/lib/symbol-autocomplete/symbol-autocomplete.component.ts
+++ b/libs/ui/src/lib/symbol-autocomplete/symbol-autocomplete.component.ts
@@ -12,8 +12,10 @@ import {
Component,
ElementRef,
Input,
+ OnChanges,
OnDestroy,
OnInit,
+ SimpleChanges,
ViewChild
} from '@angular/core';
import {
@@ -74,7 +76,7 @@ import { GfPremiumIndicatorComponent } from '../premium-indicator';
})
export class GfSymbolAutocompleteComponent
extends AbstractMatFormField
- implements OnInit, OnDestroy
+ implements OnChanges, OnDestroy, OnInit
{
@Input() public defaultLookupItems: LookupItem[] = [];
@Input() public isLoading = false;
@@ -107,10 +109,6 @@ export class GfSymbolAutocompleteComponent
this.control.disable();
}
- if (this.defaultLookupItems?.length) {
- this.showDefaultOptions();
- }
-
this.control.valueChanges
.pipe(takeUntil(this.unsubscribeSubject))
.subscribe(() => {
@@ -159,6 +157,12 @@ export class GfSymbolAutocompleteComponent
});
}
+ public ngOnChanges(changes: SimpleChanges) {
+ if (changes['defaultLookupItems'] && this.defaultLookupItems?.length) {
+ this.showDefaultOptions();
+ }
+ }
+
public displayFn(aLookupItem: LookupItem) {
return aLookupItem?.symbol ?? '';
}