Feature/support delete activities with filtering (#3394)

* Support delete activities with filtering

* Update changelog

---------

Co-authored-by: Thomas Kaul <4159106+dtslvr@users.noreply.github.com>
pull/3355/head
Gerard Du Pre 3 weeks ago committed by GitHub
parent 782d131b0d
commit 8319b216bb
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

@ -13,7 +13,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Changed
- Disabled the button to delete all activities on the portfolio activities page if there are active filters
- Improved the delete all activities functionality on the portfolio activities page to work with the filters of the assistant
- Upgraded `Nx` from version `18.3.3` to `19.0.2`
### Fixed

@ -11,7 +11,7 @@ import {
DATA_GATHERING_QUEUE_PRIORITY_HIGH,
HEADER_KEY_IMPERSONATION
} from '@ghostfolio/common/config';
import { hasPermission, permissions } from '@ghostfolio/common/permissions';
import { permissions } from '@ghostfolio/common/permissions';
import type { DateRange, RequestWithUser } from '@ghostfolio/common/types';
import {
@ -53,8 +53,20 @@ export class OrderController {
@Delete()
@HasPermission(permissions.deleteOrder)
@UseGuards(AuthGuard('jwt'), HasPermissionGuard)
public async deleteOrders(): Promise<number> {
public async deleteOrders(
@Query('accounts') filterByAccounts?: string,
@Query('assetClasses') filterByAssetClasses?: string,
@Query('tags') filterByTags?: string
): Promise<number> {
const filters = this.apiService.buildFiltersFromQueryParams({
filterByAccounts,
filterByAssetClasses,
filterByTags
});
return this.orderService.deleteOrders({
filters,
userCurrency: this.request.user.Settings.settings.baseCurrency,
userId: this.request.user.id
});
}

@ -194,16 +194,36 @@ export class OrderService {
return order;
}
public async deleteOrders(where: Prisma.OrderWhereInput): Promise<number> {
public async deleteOrders({
filters,
userCurrency,
userId
}: {
filters?: Filter[];
userCurrency: string;
userId: string;
}): Promise<number> {
const { activities } = await this.getOrders({
filters,
userId,
userCurrency,
includeDrafts: true,
withExcludedAccounts: true
});
const { count } = await this.prismaService.order.deleteMany({
where
where: {
id: {
in: activities.map(({ id }) => {
return id;
})
}
}
});
this.eventEmitter.emit(
PortfolioChangedEvent.getName(),
new PortfolioChangedEvent({
userId: <string>where.userId
})
new PortfolioChangedEvent({ userId })
);
return count;

@ -142,32 +142,24 @@ export class ActivitiesPageComponent implements OnDestroy, OnInit {
this.openCreateActivityDialog(aActivity);
}
public onDeleteActivity(aId: string) {
public onDeleteActivities() {
this.dataService
.deleteActivity(aId)
.deleteActivities({
filters: this.userService.getFilters()
})
.pipe(takeUntil(this.unsubscribeSubject))
.subscribe({
next: () => {
this.fetchActivities();
}
.subscribe(() => {
this.fetchActivities();
});
}
public onDeleteAllActivities() {
const confirmation = confirm(
$localize`Do you really want to delete all your activities?`
);
if (confirmation) {
this.dataService
.deleteAllActivities()
.pipe(takeUntil(this.unsubscribeSubject))
.subscribe({
next: () => {
this.fetchActivities();
}
});
}
public onDeleteActivity(aId: string) {
this.dataService
.deleteActivity(aId)
.pipe(takeUntil(this.unsubscribeSubject))
.subscribe(() => {
this.fetchActivities();
});
}
public onExport(activityIds?: string[]) {
@ -348,7 +340,6 @@ export class ActivitiesPageComponent implements OnDestroy, OnInit {
hasPermission(this.user.permissions, permissions.createOrder);
this.hasPermissionToDeleteActivity =
!this.hasImpersonationId &&
hasPermission(this.user.permissions, permissions.deleteOrder) &&
!this.userService.hasFilters();
hasPermission(this.user.permissions, permissions.deleteOrder);
}
}

@ -20,10 +20,10 @@
[sortColumn]="sortColumn"
[sortDirection]="sortDirection"
[totalItems]="totalItems"
(activitiesDeleted)="onDeleteActivities()"
(activityDeleted)="onDeleteActivity($event)"
(activityToClone)="onCloneActivity($event)"
(activityToUpdate)="onUpdateActivity($event)"
(deleteAllActivities)="onDeleteAllActivities()"
(export)="onExport()"
(exportDrafts)="onExportDrafts($event)"
(import)="onImport()"

@ -256,12 +256,14 @@ export class DataService {
return this.http.delete<any>(`/api/v1/account-balance/${aId}`);
}
public deleteActivity(aId: string) {
return this.http.delete<any>(`/api/v1/order/${aId}`);
public deleteActivities({ filters }) {
let params = this.buildFiltersAsQueryParams({ filters });
return this.http.delete<any>(`/api/v1/order`, { params });
}
public deleteAllActivities() {
return this.http.delete<any>(`/api/v1/order`);
public deleteActivity(aId: string) {
return this.http.delete<any>(`/api/v1/order/${aId}`);
}
public deleteBenchmark({ dataSource, symbol }: UniqueAsset) {

@ -59,11 +59,11 @@
class="align-items-center d-flex"
mat-menu-item
[disabled]="!hasPermissionToDeleteActivity"
(click)="onDeleteAllActivities()"
(click)="onDeleteActivities()"
>
<span class="align-items-center d-flex">
<ion-icon class="mr-2" name="trash-outline" />
<span i18n>Delete all Activities</span>
<span i18n>Delete Activities</span>
</span>
</button>
</mat-menu>

@ -92,10 +92,10 @@ export class GfActivitiesTableComponent
@Input() sortDisabled = false;
@Input() totalItems = Number.MAX_SAFE_INTEGER;
@Output() activitiesDeleted = new EventEmitter<void>();
@Output() activityDeleted = new EventEmitter<string>();
@Output() activityToClone = new EventEmitter<OrderWithAccount>();
@Output() activityToUpdate = new EventEmitter<OrderWithAccount>();
@Output() deleteAllActivities = new EventEmitter<void>();
@Output() export = new EventEmitter<void>();
@Output() exportDrafts = new EventEmitter<string[]>();
@Output() import = new EventEmitter<void>();
@ -211,6 +211,16 @@ export class GfActivitiesTableComponent
this.activityToClone.emit(aActivity);
}
public onDeleteActivities() {
const confirmation = confirm(
$localize`Do you really want to delete these activities?`
);
if (confirmation) {
this.activitiesDeleted.emit();
}
}
public onDeleteActivity(aId: string) {
const confirmation = confirm(
$localize`Do you really want to delete this activity?`
@ -241,10 +251,6 @@ export class GfActivitiesTableComponent
);
}
public onDeleteAllActivities() {
this.deleteAllActivities.emit();
}
public onImport() {
this.import.emit();
}

Loading…
Cancel
Save