From 73f009e43b26ebacd8a39eaf6b880824aaaf4719 Mon Sep 17 00:00:00 2001 From: Kenrick Tandrian <60643640+KenTandrian@users.noreply.github.com> Date: Wed, 30 Apr 2025 16:00:03 +0700 Subject: [PATCH] Feature/extend GUI to delete watchlist item (#4624) * Extend GUI to delete watchlist item * Update changelog --- CHANGELOG.md | 6 ++++ .../home-watchlist.component.ts | 25 ++++++++++++- .../home-watchlist/home-watchlist.html | 2 ++ apps/client/src/app/services/data.service.ts | 4 +++ .../lib/benchmark/benchmark.component.html | 33 +++++++++++++++++ .../src/lib/benchmark/benchmark.component.ts | 35 +++++++++++++++++-- 6 files changed, 101 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3850390e6..d103ff6e0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,12 @@ 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 + +### Added + +- Added support to delete an asset from the watchlist (experimental) + ## 2.157.1 - 2025-04-29 ### Added diff --git a/apps/client/src/app/components/home-watchlist/home-watchlist.component.ts b/apps/client/src/app/components/home-watchlist/home-watchlist.component.ts index 0198ab27a..daf512b34 100644 --- a/apps/client/src/app/components/home-watchlist/home-watchlist.component.ts +++ b/apps/client/src/app/components/home-watchlist/home-watchlist.component.ts @@ -1,6 +1,10 @@ import { DataService } from '@ghostfolio/client/services/data.service'; import { UserService } from '@ghostfolio/client/services/user/user.service'; -import { Benchmark, User } from '@ghostfolio/common/interfaces'; +import { + AssetProfileIdentifier, + Benchmark, + User +} from '@ghostfolio/common/interfaces'; import { hasPermission, permissions } from '@ghostfolio/common/permissions'; import { GfBenchmarkComponent } from '@ghostfolio/ui/benchmark'; import { GfPremiumIndicatorComponent } from '@ghostfolio/ui/premium-indicator'; @@ -41,6 +45,7 @@ import { CreateWatchlistItemDialogParams } from './create-watchlist-item-dialog/ export class HomeWatchlistComponent implements OnDestroy, OnInit { public deviceType: string; public hasPermissionToCreateWatchlistItem: boolean; + public hasPermissionToDeleteWatchlistItem: boolean; public user: User; public watchlist: Benchmark[]; @@ -75,6 +80,10 @@ export class HomeWatchlistComponent implements OnDestroy, OnInit { this.user.permissions, permissions.createWatchlistItem ); + this.hasPermissionToDeleteWatchlistItem = hasPermission( + this.user.permissions, + permissions.deleteWatchlistItem + ); this.changeDetectorRef.markForCheck(); } @@ -85,6 +94,20 @@ export class HomeWatchlistComponent implements OnDestroy, OnInit { this.loadWatchlistData(); } + public onWatchlistItemDeleted({ + dataSource, + symbol + }: AssetProfileIdentifier) { + this.dataService + .deleteWatchlistItem({ dataSource, symbol }) + .pipe(takeUntil(this.unsubscribeSubject)) + .subscribe({ + next: () => { + return this.loadWatchlistData(); + } + }); + } + public ngOnDestroy() { this.unsubscribeSubject.next(); this.unsubscribeSubject.complete(); diff --git a/apps/client/src/app/components/home-watchlist/home-watchlist.html b/apps/client/src/app/components/home-watchlist/home-watchlist.html index 0a2e37279..ef073d331 100644 --- a/apps/client/src/app/components/home-watchlist/home-watchlist.html +++ b/apps/client/src/app/components/home-watchlist/home-watchlist.html @@ -12,8 +12,10 @@ diff --git a/apps/client/src/app/services/data.service.ts b/apps/client/src/app/services/data.service.ts index 526c61972..353bc4153 100644 --- a/apps/client/src/app/services/data.service.ts +++ b/apps/client/src/app/services/data.service.ts @@ -327,6 +327,10 @@ export class DataService { return this.http.delete(`/api/v1/user/${aId}`); } + public deleteWatchlistItem({ dataSource, symbol }: AssetProfileIdentifier) { + return this.http.delete(`/api/v1/watchlist/${dataSource}/${symbol}`); + } + public fetchAccesses() { return this.http.get('/api/v1/access'); } diff --git a/libs/ui/src/lib/benchmark/benchmark.component.html b/libs/ui/src/lib/benchmark/benchmark.component.html index 270690f35..14ff7f9f2 100644 --- a/libs/ui/src/lib/benchmark/benchmark.component.html +++ b/libs/ui/src/lib/benchmark/benchmark.component.html @@ -113,6 +113,39 @@ + + + + @if (hasPermissionToDeleteItem) { + + + + } + + + + + Delete + + + + + + (); + + public displayedColumns = [ + 'name', + 'date', + 'change', + 'marketCondition', + 'actions' + ]; public isLoading = true; public isNumber = isNumber; public resolveMarketCondition = resolveMarketCondition; @@ -58,6 +75,7 @@ export class GfBenchmarkComponent implements OnChanges, OnDestroy { public constructor( private dialog: MatDialog, + private notificationService: NotificationService, private route: ActivatedRoute, private router: Router ) { @@ -89,11 +107,22 @@ export class GfBenchmarkComponent implements OnChanges, OnDestroy { 'trend200d', 'date', 'change', - 'marketCondition' + 'marketCondition', + 'actions' ]; } } + public onDeleteItem({ dataSource, symbol }: AssetProfileIdentifier) { + this.notificationService.confirm({ + confirmFn: () => { + this.itemDeleted.emit({ dataSource, symbol }); + }, + confirmType: ConfirmationDialogType.Warn, + title: $localize`Do you really want to delete this item?` + }); + } + public onOpenBenchmarkDialog({ dataSource, symbol }: AssetProfileIdentifier) { this.router.navigate([], { queryParams: { dataSource, symbol, benchmarkDetailDialog: true }