Skip to content

Commit

Permalink
Feature/support delete activities with filtering (#3394)
Browse files Browse the repository at this point in the history
* Support delete activities with filtering

* Update changelog

---------

Co-authored-by: Thomas Kaul <[email protected]>
  • Loading branch information
GerardPolloRebozado and dtslvr committed May 12, 2024
1 parent 782d131 commit 8319b21
Show file tree
Hide file tree
Showing 8 changed files with 74 additions and 43 deletions.
2 changes: 1 addition & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
16 changes: 14 additions & 2 deletions apps/api/src/app/order/order.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down Expand Up @@ -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
});
}
Expand Down
30 changes: 25 additions & 5 deletions apps/api/src/app/order/order.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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[]) {
Expand Down Expand Up @@ -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);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,10 @@ <h1 class="d-none d-sm-block h3 mb-3 text-center" i18n>Activities</h1>
[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()"
Expand Down
10 changes: 6 additions & 4 deletions apps/client/src/app/services/data.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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>
Expand Down
16 changes: 11 additions & 5 deletions libs/ui/src/lib/activities-table/activities-table.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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>();
Expand Down Expand Up @@ -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?`
Expand Down Expand Up @@ -241,10 +251,6 @@ export class GfActivitiesTableComponent
);
}

public onDeleteAllActivities() {
this.deleteAllActivities.emit();
}

public onImport() {
this.import.emit();
}
Expand Down

0 comments on commit 8319b21

Please sign in to comment.