Loading CHANGELOG.md +6 −0 Original line number Diff line number Diff line Loading @@ -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 Loading apps/client/src/app/components/home-watchlist/home-watchlist.component.ts +24 −1 Original line number Diff line number Diff line 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'; Loading Loading @@ -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[]; Loading Loading @@ -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(); } Loading @@ -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(); Loading apps/client/src/app/components/home-watchlist/home-watchlist.html +2 −0 Original line number Diff line number Diff line Loading @@ -12,8 +12,10 @@ <gf-benchmark [benchmarks]="watchlist" [deviceType]="deviceType" [hasPermissionToDeleteItem]="hasPermissionToDeleteWatchlistItem" [locale]="user?.settings?.locale || undefined" [user]="user" (itemDeleted)="onWatchlistItemDeleted($event)" /> </div> </div> Loading apps/client/src/app/services/data.service.ts +4 −0 Original line number Diff line number Diff line Loading @@ -327,6 +327,10 @@ export class DataService { return this.http.delete<any>(`/api/v1/user/${aId}`); } public deleteWatchlistItem({ dataSource, symbol }: AssetProfileIdentifier) { return this.http.delete<any>(`/api/v1/watchlist/${dataSource}/${symbol}`); } public fetchAccesses() { return this.http.get<Access[]>('/api/v1/access'); } Loading libs/ui/src/lib/benchmark/benchmark.component.html +33 −0 Original line number Diff line number Diff line Loading @@ -113,6 +113,39 @@ </td> </ng-container> <ng-container matColumnDef="actions" stickyEnd> <th *matHeaderCellDef class="px-1 text-center" mat-header-cell></th> <td *matCellDef="let element" class="px-1 text-center" mat-cell> @if (hasPermissionToDeleteItem) { <button class="mx-1 no-min-width px-2" mat-button [matMenuTriggerFor]="benchmarkMenu" (click)="$event.stopPropagation()" > <ion-icon name="ellipsis-horizontal" /> </button> } <mat-menu #benchmarkMenu="matMenu" xPosition="before"> <button mat-menu-item [disabled]="!hasPermissionToDeleteItem" (click)=" onDeleteItem({ dataSource: element.dataSource, symbol: element.symbol }) " > <span class="align-items-center d-flex"> <ion-icon class="mr-2" name="trash-outline" /> <span i18n>Delete</span> </span> </button> </mat-menu> </td> </ng-container> <tr *matHeaderRowDef="displayedColumns" mat-header-row></tr> <tr *matRowDef="let row; columns: displayedColumns" Loading Loading
CHANGELOG.md +6 −0 Original line number Diff line number Diff line Loading @@ -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 Loading
apps/client/src/app/components/home-watchlist/home-watchlist.component.ts +24 −1 Original line number Diff line number Diff line 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'; Loading Loading @@ -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[]; Loading Loading @@ -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(); } Loading @@ -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(); Loading
apps/client/src/app/components/home-watchlist/home-watchlist.html +2 −0 Original line number Diff line number Diff line Loading @@ -12,8 +12,10 @@ <gf-benchmark [benchmarks]="watchlist" [deviceType]="deviceType" [hasPermissionToDeleteItem]="hasPermissionToDeleteWatchlistItem" [locale]="user?.settings?.locale || undefined" [user]="user" (itemDeleted)="onWatchlistItemDeleted($event)" /> </div> </div> Loading
apps/client/src/app/services/data.service.ts +4 −0 Original line number Diff line number Diff line Loading @@ -327,6 +327,10 @@ export class DataService { return this.http.delete<any>(`/api/v1/user/${aId}`); } public deleteWatchlistItem({ dataSource, symbol }: AssetProfileIdentifier) { return this.http.delete<any>(`/api/v1/watchlist/${dataSource}/${symbol}`); } public fetchAccesses() { return this.http.get<Access[]>('/api/v1/access'); } Loading
libs/ui/src/lib/benchmark/benchmark.component.html +33 −0 Original line number Diff line number Diff line Loading @@ -113,6 +113,39 @@ </td> </ng-container> <ng-container matColumnDef="actions" stickyEnd> <th *matHeaderCellDef class="px-1 text-center" mat-header-cell></th> <td *matCellDef="let element" class="px-1 text-center" mat-cell> @if (hasPermissionToDeleteItem) { <button class="mx-1 no-min-width px-2" mat-button [matMenuTriggerFor]="benchmarkMenu" (click)="$event.stopPropagation()" > <ion-icon name="ellipsis-horizontal" /> </button> } <mat-menu #benchmarkMenu="matMenu" xPosition="before"> <button mat-menu-item [disabled]="!hasPermissionToDeleteItem" (click)=" onDeleteItem({ dataSource: element.dataSource, symbol: element.symbol }) " > <span class="align-items-center d-flex"> <ion-icon class="mr-2" name="trash-outline" /> <span i18n>Delete</span> </span> </button> </mat-menu> </td> </ng-container> <tr *matHeaderRowDef="displayedColumns" mat-header-row></tr> <tr *matRowDef="let row; columns: displayedColumns" Loading