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>
This commit is contained in:
parent
782d131b0d
commit
8319b216bb
@ -13,7 +13,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||||||
|
|
||||||
### Changed
|
### 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`
|
- Upgraded `Nx` from version `18.3.3` to `19.0.2`
|
||||||
|
|
||||||
### Fixed
|
### Fixed
|
||||||
|
@ -11,7 +11,7 @@ import {
|
|||||||
DATA_GATHERING_QUEUE_PRIORITY_HIGH,
|
DATA_GATHERING_QUEUE_PRIORITY_HIGH,
|
||||||
HEADER_KEY_IMPERSONATION
|
HEADER_KEY_IMPERSONATION
|
||||||
} from '@ghostfolio/common/config';
|
} 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 type { DateRange, RequestWithUser } from '@ghostfolio/common/types';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
@ -53,8 +53,20 @@ export class OrderController {
|
|||||||
@Delete()
|
@Delete()
|
||||||
@HasPermission(permissions.deleteOrder)
|
@HasPermission(permissions.deleteOrder)
|
||||||
@UseGuards(AuthGuard('jwt'), HasPermissionGuard)
|
@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({
|
return this.orderService.deleteOrders({
|
||||||
|
filters,
|
||||||
|
userCurrency: this.request.user.Settings.settings.baseCurrency,
|
||||||
userId: this.request.user.id
|
userId: this.request.user.id
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -194,16 +194,36 @@ export class OrderService {
|
|||||||
return order;
|
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({
|
const { count } = await this.prismaService.order.deleteMany({
|
||||||
where
|
where: {
|
||||||
|
id: {
|
||||||
|
in: activities.map(({ id }) => {
|
||||||
|
return id;
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
this.eventEmitter.emit(
|
this.eventEmitter.emit(
|
||||||
PortfolioChangedEvent.getName(),
|
PortfolioChangedEvent.getName(),
|
||||||
new PortfolioChangedEvent({
|
new PortfolioChangedEvent({ userId })
|
||||||
userId: <string>where.userId
|
|
||||||
})
|
|
||||||
);
|
);
|
||||||
|
|
||||||
return count;
|
return count;
|
||||||
|
@ -142,34 +142,26 @@ export class ActivitiesPageComponent implements OnDestroy, OnInit {
|
|||||||
this.openCreateActivityDialog(aActivity);
|
this.openCreateActivityDialog(aActivity);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public onDeleteActivities() {
|
||||||
|
this.dataService
|
||||||
|
.deleteActivities({
|
||||||
|
filters: this.userService.getFilters()
|
||||||
|
})
|
||||||
|
.pipe(takeUntil(this.unsubscribeSubject))
|
||||||
|
.subscribe(() => {
|
||||||
|
this.fetchActivities();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
public onDeleteActivity(aId: string) {
|
public onDeleteActivity(aId: string) {
|
||||||
this.dataService
|
this.dataService
|
||||||
.deleteActivity(aId)
|
.deleteActivity(aId)
|
||||||
.pipe(takeUntil(this.unsubscribeSubject))
|
.pipe(takeUntil(this.unsubscribeSubject))
|
||||||
.subscribe({
|
.subscribe(() => {
|
||||||
next: () => {
|
this.fetchActivities();
|
||||||
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 onExport(activityIds?: string[]) {
|
public onExport(activityIds?: string[]) {
|
||||||
let fetchExportParams: any = { activityIds };
|
let fetchExportParams: any = { activityIds };
|
||||||
|
|
||||||
@ -348,7 +340,6 @@ export class ActivitiesPageComponent implements OnDestroy, OnInit {
|
|||||||
hasPermission(this.user.permissions, permissions.createOrder);
|
hasPermission(this.user.permissions, permissions.createOrder);
|
||||||
this.hasPermissionToDeleteActivity =
|
this.hasPermissionToDeleteActivity =
|
||||||
!this.hasImpersonationId &&
|
!this.hasImpersonationId &&
|
||||||
hasPermission(this.user.permissions, permissions.deleteOrder) &&
|
hasPermission(this.user.permissions, permissions.deleteOrder);
|
||||||
!this.userService.hasFilters();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -20,10 +20,10 @@
|
|||||||
[sortColumn]="sortColumn"
|
[sortColumn]="sortColumn"
|
||||||
[sortDirection]="sortDirection"
|
[sortDirection]="sortDirection"
|
||||||
[totalItems]="totalItems"
|
[totalItems]="totalItems"
|
||||||
|
(activitiesDeleted)="onDeleteActivities()"
|
||||||
(activityDeleted)="onDeleteActivity($event)"
|
(activityDeleted)="onDeleteActivity($event)"
|
||||||
(activityToClone)="onCloneActivity($event)"
|
(activityToClone)="onCloneActivity($event)"
|
||||||
(activityToUpdate)="onUpdateActivity($event)"
|
(activityToUpdate)="onUpdateActivity($event)"
|
||||||
(deleteAllActivities)="onDeleteAllActivities()"
|
|
||||||
(export)="onExport()"
|
(export)="onExport()"
|
||||||
(exportDrafts)="onExportDrafts($event)"
|
(exportDrafts)="onExportDrafts($event)"
|
||||||
(import)="onImport()"
|
(import)="onImport()"
|
||||||
|
@ -256,12 +256,14 @@ export class DataService {
|
|||||||
return this.http.delete<any>(`/api/v1/account-balance/${aId}`);
|
return this.http.delete<any>(`/api/v1/account-balance/${aId}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
public deleteActivity(aId: string) {
|
public deleteActivities({ filters }) {
|
||||||
return this.http.delete<any>(`/api/v1/order/${aId}`);
|
let params = this.buildFiltersAsQueryParams({ filters });
|
||||||
|
|
||||||
|
return this.http.delete<any>(`/api/v1/order`, { params });
|
||||||
}
|
}
|
||||||
|
|
||||||
public deleteAllActivities() {
|
public deleteActivity(aId: string) {
|
||||||
return this.http.delete<any>(`/api/v1/order`);
|
return this.http.delete<any>(`/api/v1/order/${aId}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
public deleteBenchmark({ dataSource, symbol }: UniqueAsset) {
|
public deleteBenchmark({ dataSource, symbol }: UniqueAsset) {
|
||||||
|
@ -59,11 +59,11 @@
|
|||||||
class="align-items-center d-flex"
|
class="align-items-center d-flex"
|
||||||
mat-menu-item
|
mat-menu-item
|
||||||
[disabled]="!hasPermissionToDeleteActivity"
|
[disabled]="!hasPermissionToDeleteActivity"
|
||||||
(click)="onDeleteAllActivities()"
|
(click)="onDeleteActivities()"
|
||||||
>
|
>
|
||||||
<span class="align-items-center d-flex">
|
<span class="align-items-center d-flex">
|
||||||
<ion-icon class="mr-2" name="trash-outline" />
|
<ion-icon class="mr-2" name="trash-outline" />
|
||||||
<span i18n>Delete all Activities</span>
|
<span i18n>Delete Activities</span>
|
||||||
</span>
|
</span>
|
||||||
</button>
|
</button>
|
||||||
</mat-menu>
|
</mat-menu>
|
||||||
|
@ -92,10 +92,10 @@ export class GfActivitiesTableComponent
|
|||||||
@Input() sortDisabled = false;
|
@Input() sortDisabled = false;
|
||||||
@Input() totalItems = Number.MAX_SAFE_INTEGER;
|
@Input() totalItems = Number.MAX_SAFE_INTEGER;
|
||||||
|
|
||||||
|
@Output() activitiesDeleted = new EventEmitter<void>();
|
||||||
@Output() activityDeleted = new EventEmitter<string>();
|
@Output() activityDeleted = new EventEmitter<string>();
|
||||||
@Output() activityToClone = new EventEmitter<OrderWithAccount>();
|
@Output() activityToClone = new EventEmitter<OrderWithAccount>();
|
||||||
@Output() activityToUpdate = new EventEmitter<OrderWithAccount>();
|
@Output() activityToUpdate = new EventEmitter<OrderWithAccount>();
|
||||||
@Output() deleteAllActivities = new EventEmitter<void>();
|
|
||||||
@Output() export = new EventEmitter<void>();
|
@Output() export = new EventEmitter<void>();
|
||||||
@Output() exportDrafts = new EventEmitter<string[]>();
|
@Output() exportDrafts = new EventEmitter<string[]>();
|
||||||
@Output() import = new EventEmitter<void>();
|
@Output() import = new EventEmitter<void>();
|
||||||
@ -211,6 +211,16 @@ export class GfActivitiesTableComponent
|
|||||||
this.activityToClone.emit(aActivity);
|
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) {
|
public onDeleteActivity(aId: string) {
|
||||||
const confirmation = confirm(
|
const confirmation = confirm(
|
||||||
$localize`Do you really want to delete this activity?`
|
$localize`Do you really want to delete this activity?`
|
||||||
@ -241,10 +251,6 @@ export class GfActivitiesTableComponent
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
public onDeleteAllActivities() {
|
|
||||||
this.deleteAllActivities.emit();
|
|
||||||
}
|
|
||||||
|
|
||||||
public onImport() {
|
public onImport() {
|
||||||
this.import.emit();
|
this.import.emit();
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user