Merge branch 'main' of github.com:ghostfolio/ghostfolio
All checks were successful
Docker image CD / build_and_push (push) Successful in 21m24s
All checks were successful
Docker image CD / build_and_push (push) Successful in 21m24s
This commit is contained in:
commit
575615b972
15
CHANGELOG.md
15
CHANGELOG.md
@ -5,6 +5,21 @@ 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).
|
||||
|
||||
## 2.158.0 - 2025-04-30
|
||||
|
||||
### Added
|
||||
|
||||
- Added support to delete an asset from the watchlist (experimental)
|
||||
|
||||
### Changed
|
||||
|
||||
- Renamed `Order` to `activities` in the `Account` database schema
|
||||
- Improved the language localization for German (`de`)
|
||||
|
||||
### Fixed
|
||||
|
||||
- Fixed an issue with the saving of activities with type `INTEREST`, `ITEM` and `LIABILITY`
|
||||
|
||||
## 2.157.1 - 2025-04-29
|
||||
|
||||
### Added
|
||||
|
@ -57,17 +57,17 @@ export class AccountController {
|
||||
@HasPermission(permissions.deleteAccount)
|
||||
@UseGuards(AuthGuard('jwt'), HasPermissionGuard)
|
||||
public async deleteAccount(@Param('id') id: string): Promise<AccountModel> {
|
||||
const account = await this.accountService.accountWithOrders(
|
||||
const account = await this.accountService.accountWithActivities(
|
||||
{
|
||||
id_userId: {
|
||||
id,
|
||||
userId: this.request.user.id
|
||||
}
|
||||
},
|
||||
{ Order: true }
|
||||
{ activities: true }
|
||||
);
|
||||
|
||||
if (!account || account?.Order.length > 0) {
|
||||
if (!account || account?.activities.length > 0) {
|
||||
throw new HttpException(
|
||||
getReasonPhrase(StatusCodes.FORBIDDEN),
|
||||
StatusCodes.FORBIDDEN
|
||||
|
@ -39,12 +39,12 @@ export class AccountService {
|
||||
return account;
|
||||
}
|
||||
|
||||
public async accountWithOrders(
|
||||
public async accountWithActivities(
|
||||
accountWhereUniqueInput: Prisma.AccountWhereUniqueInput,
|
||||
accountInclude: Prisma.AccountInclude
|
||||
): Promise<
|
||||
Account & {
|
||||
Order?: Order[];
|
||||
activities?: Order[];
|
||||
}
|
||||
> {
|
||||
return this.prismaService.account.findUnique({
|
||||
@ -62,8 +62,8 @@ export class AccountService {
|
||||
orderBy?: Prisma.AccountOrderByWithRelationInput;
|
||||
}): Promise<
|
||||
(Account & {
|
||||
activities?: Order[];
|
||||
balances?: AccountBalance[];
|
||||
Order?: Order[];
|
||||
Platform?: Platform;
|
||||
})[]
|
||||
> {
|
||||
@ -140,7 +140,7 @@ export class AccountService {
|
||||
|
||||
public async getAccounts(aUserId: string): Promise<Account[]> {
|
||||
const accounts = await this.accounts({
|
||||
include: { Order: true, Platform: true },
|
||||
include: { activities: true, Platform: true },
|
||||
orderBy: { name: 'asc' },
|
||||
where: { userId: aUserId }
|
||||
});
|
||||
@ -148,15 +148,15 @@ export class AccountService {
|
||||
return accounts.map((account) => {
|
||||
let transactionCount = 0;
|
||||
|
||||
for (const order of account.Order) {
|
||||
if (!order.isDraft) {
|
||||
for (const { isDraft } of account.activities) {
|
||||
if (!isDraft) {
|
||||
transactionCount += 1;
|
||||
}
|
||||
}
|
||||
|
||||
const result = { ...account, transactionCount };
|
||||
|
||||
delete result.Order;
|
||||
delete result.activities;
|
||||
|
||||
return result;
|
||||
});
|
||||
|
@ -100,7 +100,7 @@ export class OrderService {
|
||||
userId: string;
|
||||
}
|
||||
): Promise<Order> {
|
||||
let Account: Prisma.AccountCreateNestedOneWithoutOrderInput;
|
||||
let Account: Prisma.AccountCreateNestedOneWithoutActivitiesInput;
|
||||
|
||||
if (data.accountId) {
|
||||
Account = {
|
||||
|
@ -139,7 +139,7 @@ export class PortfolioService {
|
||||
}
|
||||
|
||||
if (filterByDataSource && filterBySymbol) {
|
||||
where.Order = {
|
||||
where.activities = {
|
||||
some: {
|
||||
SymbolProfile: {
|
||||
AND: [
|
||||
@ -154,7 +154,7 @@ export class PortfolioService {
|
||||
const [accounts, details] = await Promise.all([
|
||||
this.accountService.accounts({
|
||||
where,
|
||||
include: { Order: true, Platform: true },
|
||||
include: { activities: true, Platform: true },
|
||||
orderBy: { name: 'asc' }
|
||||
}),
|
||||
this.getDetails({
|
||||
@ -170,8 +170,8 @@ export class PortfolioService {
|
||||
return accounts.map((account) => {
|
||||
let transactionCount = 0;
|
||||
|
||||
for (const order of account.Order) {
|
||||
if (!order.isDraft) {
|
||||
for (const { isDraft } of account.activities) {
|
||||
if (!isDraft) {
|
||||
transactionCount += 1;
|
||||
}
|
||||
}
|
||||
@ -195,7 +195,7 @@ export class PortfolioService {
|
||||
)
|
||||
};
|
||||
|
||||
delete result.Order;
|
||||
delete result.activities;
|
||||
|
||||
return result;
|
||||
});
|
||||
|
@ -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();
|
||||
|
@ -12,8 +12,10 @@
|
||||
<gf-benchmark
|
||||
[benchmarks]="watchlist"
|
||||
[deviceType]="deviceType"
|
||||
[hasPermissionToDeleteItem]="hasPermissionToDeleteWatchlistItem"
|
||||
[locale]="user?.settings?.locale || undefined"
|
||||
[user]="user"
|
||||
(itemDeleted)="onWatchlistItemDeleted($event)"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -238,7 +238,7 @@ export class CreateOrUpdateActivityDialog implements OnDestroy {
|
||||
.get('dataSource')
|
||||
.removeValidators(Validators.required);
|
||||
this.activityForm.get('dataSource').updateValueAndValidity();
|
||||
this.activityForm.get('fee').reset();
|
||||
this.activityForm.get('fee').setValue(0);
|
||||
this.activityForm.get('name').setValidators(Validators.required);
|
||||
this.activityForm.get('name').updateValueAndValidity();
|
||||
this.activityForm.get('quantity').setValue(1);
|
||||
@ -248,11 +248,7 @@ export class CreateOrUpdateActivityDialog implements OnDestroy {
|
||||
this.activityForm.get('searchSymbol').updateValueAndValidity();
|
||||
this.activityForm.get('updateAccountBalance').disable();
|
||||
this.activityForm.get('updateAccountBalance').setValue(false);
|
||||
} else if (
|
||||
type === 'FEE' ||
|
||||
type === 'INTEREST' ||
|
||||
type === 'LIABILITY'
|
||||
) {
|
||||
} else if (['FEE', 'INTEREST', 'LIABILITY'].includes(type)) {
|
||||
this.activityForm
|
||||
.get('accountId')
|
||||
.removeValidators(Validators.required);
|
||||
@ -271,12 +267,8 @@ export class CreateOrUpdateActivityDialog implements OnDestroy {
|
||||
.removeValidators(Validators.required);
|
||||
this.activityForm.get('dataSource').updateValueAndValidity();
|
||||
|
||||
if (
|
||||
(type === 'FEE' && this.activityForm.get('fee').value === 0) ||
|
||||
type === 'INTEREST' ||
|
||||
type === 'LIABILITY'
|
||||
) {
|
||||
this.activityForm.get('fee').reset();
|
||||
if (['INTEREST', 'LIABILITY'].includes(type)) {
|
||||
this.activityForm.get('fee').setValue(0);
|
||||
}
|
||||
|
||||
this.activityForm.get('name').setValidators(Validators.required);
|
||||
@ -284,7 +276,7 @@ export class CreateOrUpdateActivityDialog implements OnDestroy {
|
||||
|
||||
if (type === 'FEE') {
|
||||
this.activityForm.get('quantity').setValue(0);
|
||||
} else if (type === 'INTEREST' || type === 'LIABILITY') {
|
||||
} else if (['INTEREST', 'LIABILITY'].includes(type)) {
|
||||
this.activityForm.get('quantity').setValue(1);
|
||||
}
|
||||
|
||||
|
@ -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');
|
||||
}
|
||||
|
@ -1237,6 +1237,10 @@
|
||||
<context context-type="sourcefile">libs/ui/src/lib/activities-table/activities-table.component.html</context>
|
||||
<context context-type="linenumber">457</context>
|
||||
</context-group>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">libs/ui/src/lib/benchmark/benchmark.component.html</context>
|
||||
<context context-type="linenumber">142</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="8280212421112607879" datatype="html">
|
||||
<source>Do you really want to delete this account?</source>
|
||||
@ -4959,7 +4963,7 @@
|
||||
</context-group>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">libs/ui/src/lib/benchmark/benchmark.component.html</context>
|
||||
<context context-type="linenumber">141</context>
|
||||
<context context-type="linenumber">174</context>
|
||||
</context-group>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">libs/ui/src/lib/top-holdings/top-holdings.component.html</context>
|
||||
@ -7961,6 +7965,14 @@
|
||||
<context context-type="linenumber">29</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="627795342008207050" datatype="html">
|
||||
<source>Do you really want to delete this item?</source>
|
||||
<target state="new">Do you really want to delete this item?</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">libs/ui/src/lib/benchmark/benchmark.component.ts</context>
|
||||
<context context-type="linenumber">122</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
</body>
|
||||
</file>
|
||||
</xliff>
|
||||
|
@ -300,6 +300,10 @@
|
||||
<context context-type="sourcefile">libs/ui/src/lib/activities-table/activities-table.component.html</context>
|
||||
<context context-type="linenumber">457</context>
|
||||
</context-group>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">libs/ui/src/lib/benchmark/benchmark.component.html</context>
|
||||
<context context-type="linenumber">142</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="8280212421112607879" datatype="html">
|
||||
<source>Do you really want to delete this account?</source>
|
||||
@ -4686,7 +4690,7 @@
|
||||
</context-group>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">libs/ui/src/lib/benchmark/benchmark.component.html</context>
|
||||
<context context-type="linenumber">141</context>
|
||||
<context context-type="linenumber">174</context>
|
||||
</context-group>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">libs/ui/src/lib/top-holdings/top-holdings.component.html</context>
|
||||
@ -7961,6 +7965,14 @@
|
||||
<context context-type="linenumber">29</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="627795342008207050" datatype="html">
|
||||
<source>Do you really want to delete this item?</source>
|
||||
<target state="translated">Möchtest du diesen Eintrag wirklich löschen?</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">libs/ui/src/lib/benchmark/benchmark.component.ts</context>
|
||||
<context context-type="linenumber">122</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
</body>
|
||||
</file>
|
||||
</xliff>
|
||||
|
@ -301,6 +301,10 @@
|
||||
<context context-type="sourcefile">libs/ui/src/lib/activities-table/activities-table.component.html</context>
|
||||
<context context-type="linenumber">457</context>
|
||||
</context-group>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">libs/ui/src/lib/benchmark/benchmark.component.html</context>
|
||||
<context context-type="linenumber">142</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="8280212421112607879" datatype="html">
|
||||
<source>Do you really want to delete this account?</source>
|
||||
@ -4663,7 +4667,7 @@
|
||||
</context-group>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">libs/ui/src/lib/benchmark/benchmark.component.html</context>
|
||||
<context context-type="linenumber">141</context>
|
||||
<context context-type="linenumber">174</context>
|
||||
</context-group>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">libs/ui/src/lib/top-holdings/top-holdings.component.html</context>
|
||||
@ -7962,6 +7966,14 @@
|
||||
<context context-type="linenumber">29</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="627795342008207050" datatype="html">
|
||||
<source>Do you really want to delete this item?</source>
|
||||
<target state="new">Do you really want to delete this item?</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">libs/ui/src/lib/benchmark/benchmark.component.ts</context>
|
||||
<context context-type="linenumber">122</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
</body>
|
||||
</file>
|
||||
</xliff>
|
||||
|
@ -356,6 +356,10 @@
|
||||
<context context-type="sourcefile">libs/ui/src/lib/activities-table/activities-table.component.html</context>
|
||||
<context context-type="linenumber">457</context>
|
||||
</context-group>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">libs/ui/src/lib/benchmark/benchmark.component.html</context>
|
||||
<context context-type="linenumber">142</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="8280212421112607879" datatype="html">
|
||||
<source>Do you really want to delete this account?</source>
|
||||
@ -4662,7 +4666,7 @@
|
||||
</context-group>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">libs/ui/src/lib/benchmark/benchmark.component.html</context>
|
||||
<context context-type="linenumber">141</context>
|
||||
<context context-type="linenumber">174</context>
|
||||
</context-group>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">libs/ui/src/lib/top-holdings/top-holdings.component.html</context>
|
||||
@ -7961,6 +7965,14 @@
|
||||
<context context-type="linenumber">29</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="627795342008207050" datatype="html">
|
||||
<source>Do you really want to delete this item?</source>
|
||||
<target state="new">Do you really want to delete this item?</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">libs/ui/src/lib/benchmark/benchmark.component.ts</context>
|
||||
<context context-type="linenumber">122</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
</body>
|
||||
</file>
|
||||
</xliff>
|
||||
|
@ -301,6 +301,10 @@
|
||||
<context context-type="sourcefile">libs/ui/src/lib/activities-table/activities-table.component.html</context>
|
||||
<context context-type="linenumber">457</context>
|
||||
</context-group>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">libs/ui/src/lib/benchmark/benchmark.component.html</context>
|
||||
<context context-type="linenumber">142</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="8280212421112607879" datatype="html">
|
||||
<source>Do you really want to delete this account?</source>
|
||||
@ -4663,7 +4667,7 @@
|
||||
</context-group>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">libs/ui/src/lib/benchmark/benchmark.component.html</context>
|
||||
<context context-type="linenumber">141</context>
|
||||
<context context-type="linenumber">174</context>
|
||||
</context-group>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">libs/ui/src/lib/top-holdings/top-holdings.component.html</context>
|
||||
@ -7962,6 +7966,14 @@
|
||||
<context context-type="linenumber">29</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="627795342008207050" datatype="html">
|
||||
<source>Do you really want to delete this item?</source>
|
||||
<target state="new">Do you really want to delete this item?</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">libs/ui/src/lib/benchmark/benchmark.component.ts</context>
|
||||
<context context-type="linenumber">122</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
</body>
|
||||
</file>
|
||||
</xliff>
|
||||
|
@ -300,6 +300,10 @@
|
||||
<context context-type="sourcefile">libs/ui/src/lib/activities-table/activities-table.component.html</context>
|
||||
<context context-type="linenumber">457</context>
|
||||
</context-group>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">libs/ui/src/lib/benchmark/benchmark.component.html</context>
|
||||
<context context-type="linenumber">142</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="8280212421112607879" datatype="html">
|
||||
<source>Do you really want to delete this account?</source>
|
||||
@ -4662,7 +4666,7 @@
|
||||
</context-group>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">libs/ui/src/lib/benchmark/benchmark.component.html</context>
|
||||
<context context-type="linenumber">141</context>
|
||||
<context context-type="linenumber">174</context>
|
||||
</context-group>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">libs/ui/src/lib/top-holdings/top-holdings.component.html</context>
|
||||
@ -7961,6 +7965,14 @@
|
||||
<context context-type="linenumber">29</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="627795342008207050" datatype="html">
|
||||
<source>Do you really want to delete this item?</source>
|
||||
<target state="new">Do you really want to delete this item?</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">libs/ui/src/lib/benchmark/benchmark.component.ts</context>
|
||||
<context context-type="linenumber">122</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
</body>
|
||||
</file>
|
||||
</xliff>
|
||||
|
@ -1165,6 +1165,10 @@
|
||||
<context context-type="sourcefile">libs/ui/src/lib/activities-table/activities-table.component.html</context>
|
||||
<context context-type="linenumber">457</context>
|
||||
</context-group>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">libs/ui/src/lib/benchmark/benchmark.component.html</context>
|
||||
<context context-type="linenumber">142</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="8280212421112607879" datatype="html">
|
||||
<source>Do you really want to delete this account?</source>
|
||||
@ -4571,7 +4575,7 @@
|
||||
</context-group>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">libs/ui/src/lib/benchmark/benchmark.component.html</context>
|
||||
<context context-type="linenumber">141</context>
|
||||
<context context-type="linenumber">174</context>
|
||||
</context-group>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">libs/ui/src/lib/top-holdings/top-holdings.component.html</context>
|
||||
@ -7961,6 +7965,14 @@
|
||||
<context context-type="linenumber">29</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="627795342008207050" datatype="html">
|
||||
<source>Do you really want to delete this item?</source>
|
||||
<target state="new">Do you really want to delete this item?</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">libs/ui/src/lib/benchmark/benchmark.component.ts</context>
|
||||
<context context-type="linenumber">122</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
</body>
|
||||
</file>
|
||||
</xliff>
|
||||
|
@ -356,6 +356,10 @@
|
||||
<context context-type="sourcefile">libs/ui/src/lib/activities-table/activities-table.component.html</context>
|
||||
<context context-type="linenumber">457</context>
|
||||
</context-group>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">libs/ui/src/lib/benchmark/benchmark.component.html</context>
|
||||
<context context-type="linenumber">142</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="8280212421112607879" datatype="html">
|
||||
<source>Do you really want to delete this account?</source>
|
||||
@ -4662,7 +4666,7 @@
|
||||
</context-group>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">libs/ui/src/lib/benchmark/benchmark.component.html</context>
|
||||
<context context-type="linenumber">141</context>
|
||||
<context context-type="linenumber">174</context>
|
||||
</context-group>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">libs/ui/src/lib/top-holdings/top-holdings.component.html</context>
|
||||
@ -7961,6 +7965,14 @@
|
||||
<context context-type="linenumber">29</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="627795342008207050" datatype="html">
|
||||
<source>Do you really want to delete this item?</source>
|
||||
<target state="new">Do you really want to delete this item?</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">libs/ui/src/lib/benchmark/benchmark.component.ts</context>
|
||||
<context context-type="linenumber">122</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
</body>
|
||||
</file>
|
||||
</xliff>
|
||||
|
@ -1125,6 +1125,10 @@
|
||||
<context context-type="sourcefile">libs/ui/src/lib/activities-table/activities-table.component.html</context>
|
||||
<context context-type="linenumber">457</context>
|
||||
</context-group>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">libs/ui/src/lib/benchmark/benchmark.component.html</context>
|
||||
<context context-type="linenumber">142</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="8280212421112607879" datatype="html">
|
||||
<source>Do you really want to delete this account?</source>
|
||||
@ -4059,7 +4063,7 @@
|
||||
</context-group>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">libs/ui/src/lib/benchmark/benchmark.component.html</context>
|
||||
<context context-type="linenumber">141</context>
|
||||
<context context-type="linenumber">174</context>
|
||||
</context-group>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">libs/ui/src/lib/top-holdings/top-holdings.component.html</context>
|
||||
@ -7961,6 +7965,14 @@
|
||||
<context context-type="linenumber">29</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="627795342008207050" datatype="html">
|
||||
<source>Do you really want to delete this item?</source>
|
||||
<target state="new">Do you really want to delete this item?</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">libs/ui/src/lib/benchmark/benchmark.component.ts</context>
|
||||
<context context-type="linenumber">122</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
</body>
|
||||
</file>
|
||||
</xliff>
|
||||
|
@ -1253,6 +1253,10 @@
|
||||
<context context-type="sourcefile">libs/ui/src/lib/activities-table/activities-table.component.html</context>
|
||||
<context context-type="linenumber">457</context>
|
||||
</context-group>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">libs/ui/src/lib/benchmark/benchmark.component.html</context>
|
||||
<context context-type="linenumber">142</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="8280212421112607879" datatype="html">
|
||||
<source>Do you really want to delete this account?</source>
|
||||
@ -5211,7 +5215,7 @@
|
||||
</context-group>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">libs/ui/src/lib/benchmark/benchmark.component.html</context>
|
||||
<context context-type="linenumber">141</context>
|
||||
<context context-type="linenumber">174</context>
|
||||
</context-group>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">libs/ui/src/lib/top-holdings/top-holdings.component.html</context>
|
||||
@ -7961,6 +7965,14 @@
|
||||
<context context-type="linenumber">29</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="627795342008207050" datatype="html">
|
||||
<source>Do you really want to delete this item?</source>
|
||||
<target state="new">Do you really want to delete this item?</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">libs/ui/src/lib/benchmark/benchmark.component.ts</context>
|
||||
<context context-type="linenumber">122</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
</body>
|
||||
</file>
|
||||
</xliff>
|
||||
|
@ -1132,6 +1132,10 @@
|
||||
<context context-type="sourcefile">libs/ui/src/lib/activities-table/activities-table.component.html</context>
|
||||
<context context-type="linenumber">457</context>
|
||||
</context-group>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">libs/ui/src/lib/benchmark/benchmark.component.html</context>
|
||||
<context context-type="linenumber">142</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="8280212421112607879" datatype="html">
|
||||
<source>Do you really want to delete this account?</source>
|
||||
@ -4225,7 +4229,7 @@
|
||||
</context-group>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">libs/ui/src/lib/benchmark/benchmark.component.html</context>
|
||||
<context context-type="linenumber">141</context>
|
||||
<context context-type="linenumber">174</context>
|
||||
</context-group>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">libs/ui/src/lib/top-holdings/top-holdings.component.html</context>
|
||||
@ -7199,6 +7203,13 @@
|
||||
<context context-type="linenumber">29</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="627795342008207050" datatype="html">
|
||||
<source>Do you really want to delete this item?</source>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">libs/ui/src/lib/benchmark/benchmark.component.ts</context>
|
||||
<context context-type="linenumber">122</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
</body>
|
||||
</file>
|
||||
</xliff>
|
||||
|
@ -1174,6 +1174,10 @@
|
||||
<context context-type="sourcefile">libs/ui/src/lib/activities-table/activities-table.component.html</context>
|
||||
<context context-type="linenumber">457</context>
|
||||
</context-group>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">libs/ui/src/lib/benchmark/benchmark.component.html</context>
|
||||
<context context-type="linenumber">142</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="8280212421112607879" datatype="html">
|
||||
<source>Do you really want to delete this account?</source>
|
||||
@ -4580,7 +4584,7 @@
|
||||
</context-group>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">libs/ui/src/lib/benchmark/benchmark.component.html</context>
|
||||
<context context-type="linenumber">141</context>
|
||||
<context context-type="linenumber">174</context>
|
||||
</context-group>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">libs/ui/src/lib/top-holdings/top-holdings.component.html</context>
|
||||
@ -7962,6 +7966,14 @@
|
||||
<context context-type="linenumber">29</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="627795342008207050" datatype="html">
|
||||
<source>Do you really want to delete this item?</source>
|
||||
<target state="new">Do you really want to delete this item?</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">libs/ui/src/lib/benchmark/benchmark.component.ts</context>
|
||||
<context context-type="linenumber">122</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
</body>
|
||||
</file>
|
||||
</xliff>
|
||||
|
@ -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"
|
||||
|
@ -1,3 +1,5 @@
|
||||
import { ConfirmationDialogType } from '@ghostfolio/client/core/notification/confirmation-dialog/confirmation-dialog.type';
|
||||
import { NotificationService } from '@ghostfolio/client/core/notification/notification.service';
|
||||
import { getLocale, resolveMarketCondition } from '@ghostfolio/common/helper';
|
||||
import {
|
||||
AssetProfileIdentifier,
|
||||
@ -13,11 +15,15 @@ import {
|
||||
CUSTOM_ELEMENTS_SCHEMA,
|
||||
ChangeDetectionStrategy,
|
||||
Component,
|
||||
EventEmitter,
|
||||
Input,
|
||||
OnChanges,
|
||||
OnDestroy
|
||||
OnDestroy,
|
||||
Output
|
||||
} from '@angular/core';
|
||||
import { MatButtonModule } from '@angular/material/button';
|
||||
import { MatDialog } from '@angular/material/dialog';
|
||||
import { MatMenuModule } from '@angular/material/menu';
|
||||
import { MatTableModule } from '@angular/material/table';
|
||||
import { ActivatedRoute, Router, RouterModule } from '@angular/router';
|
||||
import { isNumber } from 'lodash';
|
||||
@ -33,6 +39,8 @@ import { BenchmarkDetailDialogParams } from './benchmark-detail-dialog/interface
|
||||
CommonModule,
|
||||
GfTrendIndicatorComponent,
|
||||
GfValueComponent,
|
||||
MatButtonModule,
|
||||
MatMenuModule,
|
||||
MatTableModule,
|
||||
NgxSkeletonLoaderModule,
|
||||
RouterModule
|
||||
@ -45,10 +53,19 @@ import { BenchmarkDetailDialogParams } from './benchmark-detail-dialog/interface
|
||||
export class GfBenchmarkComponent implements OnChanges, OnDestroy {
|
||||
@Input() benchmarks: Benchmark[];
|
||||
@Input() deviceType: string;
|
||||
@Input() hasPermissionToDeleteItem: boolean;
|
||||
@Input() locale = getLocale();
|
||||
@Input() user: User;
|
||||
|
||||
public displayedColumns = ['name', 'date', 'change', 'marketCondition'];
|
||||
@Output() itemDeleted = new EventEmitter<AssetProfileIdentifier>();
|
||||
|
||||
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 }
|
||||
|
4
package-lock.json
generated
4
package-lock.json
generated
@ -1,12 +1,12 @@
|
||||
{
|
||||
"name": "ghostfolio",
|
||||
"version": "2.157.1",
|
||||
"version": "2.158.0",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "ghostfolio",
|
||||
"version": "2.157.1",
|
||||
"version": "2.158.0",
|
||||
"hasInstallScript": true,
|
||||
"license": "AGPL-3.0",
|
||||
"dependencies": {
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "ghostfolio",
|
||||
"version": "2.157.1",
|
||||
"version": "2.158.0",
|
||||
"homepage": "https://ghostfol.io",
|
||||
"license": "AGPL-3.0",
|
||||
"repository": "https://github.com/ghostfolio/ghostfolio",
|
||||
|
@ -26,6 +26,7 @@ model Access {
|
||||
}
|
||||
|
||||
model Account {
|
||||
activities Order[]
|
||||
balance Float @default(0)
|
||||
balances AccountBalance[]
|
||||
comment String?
|
||||
@ -39,7 +40,6 @@ model Account {
|
||||
userId String
|
||||
Platform Platform? @relation(fields: [platformId], references: [id])
|
||||
User User @relation(fields: [userId], onDelete: Cascade, references: [id])
|
||||
Order Order[]
|
||||
|
||||
@@id([id, userId])
|
||||
@@index([currency])
|
||||
|
Loading…
x
Reference in New Issue
Block a user