Browse Source

Add account page logic

pull/58/head
Thomas 4 years ago
parent
commit
0eeb5591b6
  1. 91
      apps/api/src/app/account/account.controller.ts
  2. 4
      apps/api/src/app/account/account.module.ts
  3. 82
      apps/api/src/app/account/account.service.ts
  4. 2
      apps/client/src/app/app.component.ts
  5. 51
      apps/client/src/app/components/accounts-table/accounts-table.component.html
  6. 18
      apps/client/src/app/components/accounts-table/accounts-table.component.ts
  7. 2
      apps/client/src/app/components/transactions-table/transactions-table.component.html
  8. 30
      apps/client/src/app/pages/accounts/accounts-page.component.ts
  9. 8
      apps/client/src/app/pages/accounts/accounts-page.html
  10. 4
      apps/client/src/app/pages/accounts/create-or-update-account-dialog/create-or-update-account-dialog.html
  11. 5
      libs/helper/src/lib/permissions.ts

91
apps/api/src/app/account/account.controller.ts

@ -17,8 +17,7 @@ import {
} from '@nestjs/common'; } from '@nestjs/common';
import { REQUEST } from '@nestjs/core'; import { REQUEST } from '@nestjs/core';
import { AuthGuard } from '@nestjs/passport'; import { AuthGuard } from '@nestjs/passport';
import { Order as OrderModel } from '@prisma/client'; import { Account as AccountModel } from '@prisma/client';
import { parseISO } from 'date-fns';
import { StatusCodes, getReasonPhrase } from 'http-status-codes'; import { StatusCodes, getReasonPhrase } from 'http-status-codes';
import { AccountService } from './account.service'; import { AccountService } from './account.service';
@ -35,11 +34,11 @@ export class AccountController {
@Delete(':id') @Delete(':id')
@UseGuards(AuthGuard('jwt')) @UseGuards(AuthGuard('jwt'))
public async deleteOrder(@Param('id') id: string): Promise<OrderModel> { public async deleteAccount(@Param('id') id: string): Promise<AccountModel> {
if ( if (
!hasPermission( !hasPermission(
getPermissions(this.request.user.role), getPermissions(this.request.user.role),
permissions.deleteOrder permissions.deleteAccount
) )
) { ) {
throw new HttpException( throw new HttpException(
@ -48,7 +47,7 @@ export class AccountController {
); );
} }
return this.accountService.deleteOrder( return this.accountService.deleteAccount(
{ {
id_userId: { id_userId: {
id, id,
@ -61,23 +60,17 @@ export class AccountController {
@Get() @Get()
@UseGuards(AuthGuard('jwt')) @UseGuards(AuthGuard('jwt'))
public async getAllOrders( public async getAllAccounts(
@Headers('impersonation-id') impersonationId @Headers('impersonation-id') impersonationId
): Promise<OrderModel[]> { ): Promise<AccountModel[]> {
const impersonationUserId = await this.impersonationService.validateImpersonationId( const impersonationUserId = await this.impersonationService.validateImpersonationId(
impersonationId, impersonationId,
this.request.user.id this.request.user.id
); );
let orders = await this.accountService.orders({ let accounts = await this.accountService.accounts({
include: { include: { Platform: true },
Account: { orderBy: { name: 'desc' },
include: {
Platform: true
}
}
},
orderBy: { date: 'desc' },
where: { userId: impersonationUserId || this.request.user.id } where: { userId: impersonationUserId || this.request.user.id }
}); });
@ -88,16 +81,20 @@ export class AccountController {
permissions.readForeignPortfolio permissions.readForeignPortfolio
) )
) { ) {
orders = nullifyValuesInObjects(orders, ['fee', 'quantity', 'unitPrice']); accounts = nullifyValuesInObjects(accounts, [
'fee',
'quantity',
'unitPrice'
]);
} }
return orders; return accounts;
} }
@Get(':id') @Get(':id')
@UseGuards(AuthGuard('jwt')) @UseGuards(AuthGuard('jwt'))
public async getOrderById(@Param('id') id: string): Promise<OrderModel> { public async getAccountById(@Param('id') id: string): Promise<AccountModel> {
return this.accountService.order({ return this.accountService.account({
id_userId: { id_userId: {
id, id,
userId: this.request.user.id userId: this.request.user.id
@ -107,13 +104,13 @@ export class AccountController {
@Post() @Post()
@UseGuards(AuthGuard('jwt')) @UseGuards(AuthGuard('jwt'))
public async createOrder( public async createAccount(
@Body() data: CreateAccountDto @Body() data: CreateAccountDto
): Promise<OrderModel> { ): Promise<AccountModel> {
if ( if (
!hasPermission( !hasPermission(
getPermissions(this.request.user.role), getPermissions(this.request.user.role),
permissions.createOrder permissions.createAccount
) )
) { ) {
throw new HttpException( throw new HttpException(
@ -122,24 +119,13 @@ export class AccountController {
); );
} }
const date = parseISO(data.date);
const accountId = data.accountId;
delete data.accountId;
if (data.platformId) { if (data.platformId) {
const platformId = data.platformId; const platformId = data.platformId;
delete data.platformId; delete data.platformId;
return this.accountService.createOrder( return this.accountService.createAccount(
{ {
...data, ...data,
date,
Account: {
connect: {
id_userId: { id: accountId, userId: this.request.user.id }
}
},
Platform: { connect: { id: platformId } }, Platform: { connect: { id: platformId } },
User: { connect: { id: this.request.user.id } } User: { connect: { id: this.request.user.id } }
}, },
@ -148,15 +134,9 @@ export class AccountController {
} else { } else {
delete data.platformId; delete data.platformId;
return this.accountService.createOrder( return this.accountService.createAccount(
{ {
...data, ...data,
date,
Account: {
connect: {
id_userId: { id: accountId, userId: this.request.user.id }
}
},
User: { connect: { id: this.request.user.id } } User: { connect: { id: this.request.user.id } }
}, },
this.request.user.id this.request.user.id
@ -170,7 +150,7 @@ export class AccountController {
if ( if (
!hasPermission( !hasPermission(
getPermissions(this.request.user.role), getPermissions(this.request.user.role),
permissions.updateOrder permissions.updateAccount
) )
) { ) {
throw new HttpException( throw new HttpException(
@ -179,32 +159,21 @@ export class AccountController {
); );
} }
const originalOrder = await this.accountService.order({ const originalAccount = await this.accountService.account({
id_userId: { id_userId: {
id, id,
userId: this.request.user.id userId: this.request.user.id
} }
}); });
const date = parseISO(data.date);
const accountId = data.accountId;
delete data.accountId;
if (data.platformId) { if (data.platformId) {
const platformId = data.platformId; const platformId = data.platformId;
delete data.platformId; delete data.platformId;
return this.accountService.updateOrder( return this.accountService.updateAccount(
{ {
data: { data: {
...data, ...data,
date,
Account: {
connect: {
id_userId: { id: accountId, userId: this.request.user.id }
}
},
Platform: { connect: { id: platformId } }, Platform: { connect: { id: platformId } },
User: { connect: { id: this.request.user.id } } User: { connect: { id: this.request.user.id } }
}, },
@ -221,17 +190,11 @@ export class AccountController {
// platformId is null, remove it // platformId is null, remove it
delete data.platformId; delete data.platformId;
return this.accountService.updateOrder( return this.accountService.updateAccount(
{ {
data: { data: {
...data, ...data,
date, Platform: originalAccount.platformId
Account: {
connect: {
id_userId: { id: accountId, userId: this.request.user.id }
}
},
Platform: originalOrder.platformId
? { disconnect: true } ? { disconnect: true }
: undefined, : undefined,
User: { connect: { id: this.request.user.id } } User: { connect: { id: this.request.user.id } }

4
apps/api/src/app/account/account.module.ts

@ -1,5 +1,4 @@
import { ConfigurationService } from '@ghostfolio/api/services/configuration.service'; import { ConfigurationService } from '@ghostfolio/api/services/configuration.service';
import { DataGatheringService } from '@ghostfolio/api/services/data-gathering.service';
import { DataProviderService } from '@ghostfolio/api/services/data-provider.service'; import { DataProviderService } from '@ghostfolio/api/services/data-provider.service';
import { AlphaVantageService } from '@ghostfolio/api/services/data-provider/alpha-vantage/alpha-vantage.service'; import { AlphaVantageService } from '@ghostfolio/api/services/data-provider/alpha-vantage/alpha-vantage.service';
import { GhostfolioScraperApiService } from '@ghostfolio/api/services/data-provider/ghostfolio-scraper-api/ghostfolio-scraper-api.service'; import { GhostfolioScraperApiService } from '@ghostfolio/api/services/data-provider/ghostfolio-scraper-api/ghostfolio-scraper-api.service';
@ -9,7 +8,6 @@ import { ImpersonationService } from '@ghostfolio/api/services/impersonation.ser
import { PrismaService } from '@ghostfolio/api/services/prisma.service'; import { PrismaService } from '@ghostfolio/api/services/prisma.service';
import { Module } from '@nestjs/common'; import { Module } from '@nestjs/common';
import { CacheService } from '../cache/cache.service';
import { RedisCacheModule } from '../redis-cache/redis-cache.module'; import { RedisCacheModule } from '../redis-cache/redis-cache.module';
import { AccountController } from './account.controller'; import { AccountController } from './account.controller';
import { AccountService } from './account.service'; import { AccountService } from './account.service';
@ -20,9 +18,7 @@ import { AccountService } from './account.service';
providers: [ providers: [
AccountService, AccountService,
AlphaVantageService, AlphaVantageService,
CacheService,
ConfigurationService, ConfigurationService,
DataGatheringService,
DataProviderService, DataProviderService,
GhostfolioScraperApiService, GhostfolioScraperApiService,
ImpersonationService, ImpersonationService,

82
apps/api/src/app/account/account.service.ts

@ -1,40 +1,35 @@
import { DataGatheringService } from '@ghostfolio/api/services/data-gathering.service';
import { PrismaService } from '@ghostfolio/api/services/prisma.service'; import { PrismaService } from '@ghostfolio/api/services/prisma.service';
import { Injectable } from '@nestjs/common'; import { Injectable } from '@nestjs/common';
import { Order, Prisma } from '@prisma/client'; import { Account, Prisma } from '@prisma/client';
import { CacheService } from '../cache/cache.service';
import { RedisCacheService } from '../redis-cache/redis-cache.service'; import { RedisCacheService } from '../redis-cache/redis-cache.service';
import { OrderWithPlatform } from './interfaces/order-with-platform.type';
@Injectable() @Injectable()
export class AccountService { export class AccountService {
public constructor( public constructor(
private readonly cacheService: CacheService,
private readonly dataGatheringService: DataGatheringService,
private readonly redisCacheService: RedisCacheService, private readonly redisCacheService: RedisCacheService,
private prisma: PrismaService private prisma: PrismaService
) {} ) {}
public async order( public async account(
orderWhereUniqueInput: Prisma.OrderWhereUniqueInput accountWhereUniqueInput: Prisma.AccountWhereUniqueInput
): Promise<Order | null> { ): Promise<Account | null> {
return this.prisma.order.findUnique({ return this.prisma.account.findUnique({
where: orderWhereUniqueInput where: accountWhereUniqueInput
}); });
} }
public async orders(params: { public async accounts(params: {
include?: Prisma.OrderInclude; include?: Prisma.AccountInclude;
skip?: number; skip?: number;
take?: number; take?: number;
cursor?: Prisma.OrderWhereUniqueInput; cursor?: Prisma.AccountWhereUniqueInput;
where?: Prisma.OrderWhereInput; where?: Prisma.AccountWhereInput;
orderBy?: Prisma.OrderOrderByInput; orderBy?: Prisma.AccountOrderByInput;
}): Promise<OrderWithPlatform[]> { }): Promise<Account[]> {
const { include, skip, take, cursor, where, orderBy } = params; const { include, skip, take, cursor, where, orderBy } = params;
return this.prisma.order.findMany({ return this.prisma.account.findMany({
cursor, cursor,
include, include,
orderBy, orderBy,
@ -44,60 +39,35 @@ export class AccountService {
}); });
} }
public async createOrder( public async createAccount(
data: Prisma.OrderCreateInput, data: Prisma.AccountCreateInput,
aUserId: string aUserId: string
): Promise<Order> { ): Promise<Account> {
this.redisCacheService.remove(`${aUserId}.portfolio`); return this.prisma.account.create({
// Gather symbol data of order in the background
this.dataGatheringService.gatherSymbols([
{
date: <Date>data.date,
symbol: data.symbol
}
]);
await this.cacheService.flush(aUserId);
return this.prisma.order.create({
data data
}); });
} }
public async deleteOrder( public async deleteAccount(
where: Prisma.OrderWhereUniqueInput, where: Prisma.AccountWhereUniqueInput,
aUserId: string aUserId: string
): Promise<Order> { ): Promise<Account> {
this.redisCacheService.remove(`${aUserId}.portfolio`); this.redisCacheService.remove(`${aUserId}.portfolio`);
return this.prisma.order.delete({ return this.prisma.account.delete({
where where
}); });
} }
public async updateOrder( public async updateAccount(
params: { params: {
where: Prisma.OrderWhereUniqueInput; where: Prisma.AccountWhereUniqueInput;
data: Prisma.OrderUpdateInput; data: Prisma.AccountUpdateInput;
}, },
aUserId: string aUserId: string
): Promise<Order> { ): Promise<Account> {
const { data, where } = params; const { data, where } = params;
return this.prisma.account.update({
this.redisCacheService.remove(`${aUserId}.portfolio`);
// Gather symbol data of order in the background
this.dataGatheringService.gatherSymbols([
{
date: <Date>data.date,
symbol: <string>data.symbol
}
]);
await this.cacheService.flush(aUserId);
return this.prisma.order.update({
data, data,
where where
}); });

2
apps/client/src/app/app.component.ts

@ -74,7 +74,7 @@ export class AppComponent implements OnDestroy, OnInit {
this.canCreateAccount = hasPermission( this.canCreateAccount = hasPermission(
this.user.permissions, this.user.permissions,
permissions.createAccount permissions.createUserAccount
); );
this.cd.markForCheck(); this.cd.markForCheck();

51
apps/client/src/app/components/accounts-table/accounts-table.component.html

@ -9,49 +9,44 @@
<ng-container matColumnDef="account"> <ng-container matColumnDef="account">
<th *matHeaderCellDef i18n mat-header-cell mat-sort-header>Name</th> <th *matHeaderCellDef i18n mat-header-cell mat-sort-header>Name</th>
<td *matCellDef="let element" mat-cell> <td *matCellDef="let element" mat-cell>
<div class="d-flex"> {{ element.name }}
<gf-symbol-icon
*ngIf="element.Account?.Platform?.url"
class="mr-2"
[tooltip]="element.Account?.Platform?.name"
[url]="element.Account?.Platform?.url"
></gf-symbol-icon>
<span class="d-none d-lg-block">{{ element.Account?.name }}</span>
</div>
</td> </td>
</ng-container> </ng-container>
<ng-container matColumnDef="type"> <ng-container matColumnDef="type">
<th <th
*matHeaderCellDef *matHeaderCellDef
class="justify-content-center" class="d-none d-lg-table-cell justify-content-center"
i18n i18n
mat-header-cell mat-header-cell
mat-sort-header mat-sort-header
> >
Type Type
</th> </th>
<td mat-cell *matCellDef="let element" class="text-center"> <td
<div mat-cell
class="d-inline-flex justify-content-center pl-1 pr-2 py-1 type-badge" *matCellDef="let element"
[ngClass]="element.type == 'BUY' ? 'buy' : 'sell'" class="d-none d-lg-table-cell text-center"
> >
<ion-icon <div class="d-inline-flex justify-content-center px-2 py-1 type-badge">
class="mr-1" <span>{{ element.accountType }}</span>
[name]="
element.type === 'BUY'
? 'arrow-forward-circle-outline'
: 'arrow-back-circle-outline'
"
></ion-icon>
<span>{{ element.type }}</span>
</div> </div>
</td> </td>
</ng-container> </ng-container>
<ng-container matColumnDef="symbol"> <ng-container matColumnDef="platform">
<th *matHeaderCellDef i18n mat-header-cell mat-sort-header>Platform</th> <th *matHeaderCellDef i18n mat-header-cell mat-sort-header>Platform</th>
<td mat-cell *matCellDef="let element">{{ element.symbol }}</td> <td mat-cell *matCellDef="let element">
<div class="d-flex">
<gf-symbol-icon
*ngIf="element.Platform?.url"
class="mr-1"
[tooltip]=""
[url]="element.Platform?.url"
></gf-symbol-icon>
<span>{{ element.Platform?.name }}</span>
</div>
</td>
</ng-container> </ng-container>
<ng-container matColumnDef="actions"> <ng-container matColumnDef="actions">
@ -66,10 +61,10 @@
<ion-icon name="ellipsis-vertical"></ion-icon> <ion-icon name="ellipsis-vertical"></ion-icon>
</button> </button>
<mat-menu #accountMenu="matMenu" xPosition="before"> <mat-menu #accountMenu="matMenu" xPosition="before">
<button i18n mat-menu-item (click)="onUpdateTransaction(element)"> <button i18n mat-menu-item (click)="onUpdateAccount(element)">
Edit Edit
</button> </button>
<button i18n mat-menu-item (click)="onDeleteTransaction(element.id)"> <button i18n mat-menu-item (click)="onDeleteAccount(element.id)">
Delete Delete
</button> </button>
</mat-menu> </mat-menu>

18
apps/client/src/app/components/accounts-table/accounts-table.component.ts

@ -29,8 +29,8 @@ export class AccountsTableComponent implements OnChanges, OnDestroy, OnInit {
@Input() locale: string; @Input() locale: string;
@Input() showActions: boolean; @Input() showActions: boolean;
@Output() transactionDeleted = new EventEmitter<string>(); @Output() accountDeleted = new EventEmitter<string>();
@Output() transactionToUpdate = new EventEmitter<OrderModel>(); @Output() accountToUpdate = new EventEmitter<OrderModel>();
@ViewChild(MatSort) sort: MatSort; @ViewChild(MatSort) sort: MatSort;
@ -50,7 +50,7 @@ export class AccountsTableComponent implements OnChanges, OnDestroy, OnInit {
public ngOnInit() {} public ngOnInit() {}
public ngOnChanges() { public ngOnChanges() {
this.displayedColumns = ['account', 'type', 'symbol']; this.displayedColumns = ['account', 'type', 'platform'];
this.isLoading = true; this.isLoading = true;
@ -66,18 +66,16 @@ export class AccountsTableComponent implements OnChanges, OnDestroy, OnInit {
} }
} }
public onDeleteTransaction(aId: string) { public onDeleteAccount(aId: string) {
const confirmation = confirm( const confirmation = confirm('Do you really want to delete this account?');
'Do you really want to delete this transaction?'
);
if (confirmation) { if (confirmation) {
this.transactionDeleted.emit(aId); this.accountDeleted.emit(aId);
} }
} }
public onUpdateTransaction(aTransaction: OrderModel) { public onUpdateAccount(aAccount: OrderModel) {
this.transactionToUpdate.emit(aTransaction); this.accountToUpdate.emit(aAccount);
} }
public ngOnDestroy() { public ngOnDestroy() {

2
apps/client/src/app/components/transactions-table/transactions-table.component.html

@ -23,7 +23,7 @@
<div class="d-flex"> <div class="d-flex">
<gf-symbol-icon <gf-symbol-icon
*ngIf="element.Account?.Platform?.url" *ngIf="element.Account?.Platform?.url"
class="mr-2" class="mr-1"
[tooltip]="element.Account?.Platform?.name" [tooltip]="element.Account?.Platform?.name"
[url]="element.Account?.Platform?.url" [url]="element.Account?.Platform?.url"
></gf-symbol-icon> ></gf-symbol-icon>

30
apps/client/src/app/pages/accounts/accounts-page.component.ts

@ -23,8 +23,8 @@ export class AccountsPageComponent implements OnInit {
public accounts: OrderModel[]; public accounts: OrderModel[];
public deviceType: string; public deviceType: string;
public hasImpersonationId: boolean; public hasImpersonationId: boolean;
public hasPermissionToCreateOrder: boolean; public hasPermissionToCreateAccount: boolean;
public hasPermissionToDeleteOrder: boolean; public hasPermissionToDeleteAccount: boolean;
public routeQueryParams: Subscription; public routeQueryParams: Subscription;
public user: User; public user: User;
@ -47,14 +47,14 @@ export class AccountsPageComponent implements OnInit {
.pipe(takeUntil(this.unsubscribeSubject)) .pipe(takeUntil(this.unsubscribeSubject))
.subscribe((params) => { .subscribe((params) => {
if (params['createDialog']) { if (params['createDialog']) {
this.openCreateTransactionDialog(); this.openCreateAccountDialog();
} else if (params['editDialog']) { } else if (params['editDialog']) {
if (this.accounts) { if (this.accounts) {
const transaction = this.accounts.find((transaction) => { const account = this.accounts.find((account) => {
return transaction.id === params['transactionId']; return account.id === params['transactionId'];
}); });
this.openUpdateTransactionDialog(transaction); this.openUpdateAccountDialog(account);
} else { } else {
this.router.navigate(['.'], { relativeTo: this.route }); this.router.navigate(['.'], { relativeTo: this.route });
} }
@ -80,13 +80,13 @@ export class AccountsPageComponent implements OnInit {
.subscribe(() => { .subscribe(() => {
this.dataService.fetchUser().subscribe((user) => { this.dataService.fetchUser().subscribe((user) => {
this.user = user; this.user = user;
this.hasPermissionToCreateOrder = hasPermission( this.hasPermissionToCreateAccount = hasPermission(
user.permissions, user.permissions,
permissions.createOrder permissions.createAccount
); );
this.hasPermissionToDeleteOrder = hasPermission( this.hasPermissionToDeleteAccount = hasPermission(
user.permissions, user.permissions,
permissions.deleteOrder permissions.deleteAccount
); );
this.cd.markForCheck(); this.cd.markForCheck();
@ -108,7 +108,7 @@ export class AccountsPageComponent implements OnInit {
}); });
} }
public onDeleteTransaction(aId: string) { public onDeleteAccount(aId: string) {
this.dataService.deleteAccount(aId).subscribe({ this.dataService.deleteAccount(aId).subscribe({
next: () => { next: () => {
this.fetchAccounts(); this.fetchAccounts();
@ -116,13 +116,13 @@ export class AccountsPageComponent implements OnInit {
}); });
} }
public onUpdateTransaction(aTransaction: OrderModel) { public onUpdateAccount(aAccount: OrderModel) {
this.router.navigate([], { this.router.navigate([], {
queryParams: { editDialog: true, transactionId: aTransaction.id } queryParams: { editDialog: true, transactionId: aAccount.id }
}); });
} }
public openUpdateTransactionDialog({ public openUpdateAccountDialog({
accountId, accountId,
currency, currency,
dataSource, dataSource,
@ -176,7 +176,7 @@ export class AccountsPageComponent implements OnInit {
this.unsubscribeSubject.complete(); this.unsubscribeSubject.complete();
} }
private openCreateTransactionDialog(): void { private openCreateAccountDialog(): void {
const dialogRef = this.dialog.open(CreateOrUpdateAccountDialog, { const dialogRef = this.dialog.open(CreateOrUpdateAccountDialog, {
data: { data: {
accounts: this.user?.accounts, accounts: this.user?.accounts,

8
apps/client/src/app/pages/accounts/accounts-page.html

@ -7,15 +7,15 @@
[baseCurrency]="user?.settings?.baseCurrency" [baseCurrency]="user?.settings?.baseCurrency"
[deviceType]="deviceType" [deviceType]="deviceType"
[locale]="user?.settings?.locale" [locale]="user?.settings?.locale"
[showActions]="!hasImpersonationId && hasPermissionToDeleteOrder" [showActions]="!hasImpersonationId && hasPermissionToDeleteAccount"
(transactionDeleted)="onDeleteTransaction($event)" (accountDeleted)="onDeleteAccount($event)"
(transactionToUpdate)="onUpdateTransaction($event)" (accountToUpdate)="onUpdateAccount($event)"
></gf-accounts-table> ></gf-accounts-table>
</div> </div>
</div> </div>
<div <div
*ngIf="!hasImpersonationId && hasPermissionToCreateOrder" *ngIf="!hasImpersonationId && hasPermissionToCreateAccount"
class="fab-container" class="fab-container"
> >
<a <a

4
apps/client/src/app/pages/accounts/create-or-update-account-dialog/create-or-update-account-dialog.html

@ -1,4 +1,4 @@
<form #addTransactionForm="ngForm" class="d-flex flex-column h-100"> <form #addAccountForm="ngForm" class="d-flex flex-column h-100">
<h1 *ngIf="data.transaction.id" mat-dialog-title i18n>Update account</h1> <h1 *ngIf="data.transaction.id" mat-dialog-title i18n>Update account</h1>
<h1 *ngIf="!data.transaction.id" mat-dialog-title i18n>Add account</h1> <h1 *ngIf="!data.transaction.id" mat-dialog-title i18n>Add account</h1>
<div class="flex-grow-1" mat-dialog-content> <div class="flex-grow-1" mat-dialog-content>
@ -154,7 +154,7 @@
color="primary" color="primary"
i18n i18n
mat-flat-button mat-flat-button
[disabled]="!(addTransactionForm.form.valid && data.transaction.symbol)" [disabled]="!(addAccountForm.form.valid && data.transaction.symbol)"
[mat-dialog-close]="data" [mat-dialog-close]="data"
> >
Save Save

5
libs/helper/src/lib/permissions.ts

@ -9,10 +9,13 @@ export const permissions = {
accessFearAndGreedIndex: 'accessFearAndGreedIndex', accessFearAndGreedIndex: 'accessFearAndGreedIndex',
createAccount: 'createAccount', createAccount: 'createAccount',
createOrder: 'createOrder', createOrder: 'createOrder',
createUserAccount: 'createUserAccount',
deleteAccount: 'deleteAcccount',
deleteOrder: 'deleteOrder', deleteOrder: 'deleteOrder',
enableSocialLogin: 'enableSocialLogin', enableSocialLogin: 'enableSocialLogin',
enableSubscription: 'enableSubscription', enableSubscription: 'enableSubscription',
readForeignPortfolio: 'readForeignPortfolio', readForeignPortfolio: 'readForeignPortfolio',
updateAccount: 'updateAccount',
updateOrder: 'updateOrder', updateOrder: 'updateOrder',
updateUserSettings: 'updateUserSettings' updateUserSettings: 'updateUserSettings'
}; };
@ -37,7 +40,7 @@ export function getPermissions(aRole: Role): string[] {
]; ];
case 'DEMO': case 'DEMO':
return [permissions.createAccount]; return [permissions.createUserAccount];
case 'USER': case 'USER':
return [ return [

Loading…
Cancel
Save