Browse Source

Activate account selector in transaction dialog

pull/60/head
Thomas 4 years ago
parent
commit
8501ddbc6e
  1. 21
      apps/api/src/app/account/account.controller.ts
  2. 16
      apps/api/src/app/account/account.service.ts
  3. 9
      apps/client/src/app/components/accounts-table/accounts-table.component.html
  4. 2
      apps/client/src/app/components/accounts-table/accounts-table.component.ts
  5. 2
      apps/client/src/app/pages/accounts/accounts-page.component.ts
  6. 24
      apps/client/src/app/pages/analysis/analysis-page.html
  7. 14
      apps/client/src/app/pages/transactions/create-or-update-transaction-dialog/create-or-update-transaction-dialog.html

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

@ -17,7 +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 { Account as AccountModel } from '@prisma/client'; import { Account as AccountModel, Order } from '@prisma/client';
import { StatusCodes, getReasonPhrase } from 'http-status-codes'; import { StatusCodes, getReasonPhrase } from 'http-status-codes';
import { AccountService } from './account.service'; import { AccountService } from './account.service';
@ -47,14 +47,17 @@ export class AccountController {
); );
} }
const account = await this.accountService.account({ const account = await this.accountService.accountWithOrders(
id_userId: { {
id, id_userId: {
userId: this.request.user.id id,
} userId: this.request.user.id
}); }
},
{ Order: true }
);
if (account.isDefault) { if (account?.isDefault || account?.Order.length > 0) {
throw new HttpException( throw new HttpException(
getReasonPhrase(StatusCodes.FORBIDDEN), getReasonPhrase(StatusCodes.FORBIDDEN),
StatusCodes.FORBIDDEN StatusCodes.FORBIDDEN
@ -83,7 +86,7 @@ export class AccountController {
); );
let accounts = await this.accountService.accounts({ let accounts = await this.accountService.accounts({
include: { Platform: true }, include: { Order: true, Platform: true },
orderBy: { name: 'asc' }, orderBy: { name: 'asc' },
where: { userId: impersonationUserId || this.request.user.id } where: { userId: impersonationUserId || this.request.user.id }
}); });

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

@ -1,6 +1,6 @@
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 { Account, Prisma } from '@prisma/client'; import { Account, Order, Prisma } from '@prisma/client';
import { RedisCacheService } from '../redis-cache/redis-cache.service'; import { RedisCacheService } from '../redis-cache/redis-cache.service';
@ -19,6 +19,20 @@ export class AccountService {
}); });
} }
public async accountWithOrders(
accountWhereUniqueInput: Prisma.AccountWhereUniqueInput,
accountInclude: Prisma.AccountInclude
): Promise<
Account & {
Order?: Order[];
}
> {
return this.prisma.account.findUnique({
include: accountInclude,
where: accountWhereUniqueInput
});
}
public async accounts(params: { public async accounts(params: {
include?: Prisma.AccountInclude; include?: Prisma.AccountInclude;
skip?: number; skip?: number;

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

@ -67,7 +67,7 @@
<button <button
i18n i18n
mat-menu-item mat-menu-item
[disabled]="element.isDefault" [disabled]="element.isDefault || element.Order?.length > 0"
(click)="onDeleteAccount(element.id)" (click)="onDeleteAccount(element.id)"
> >
Delete Delete
@ -76,6 +76,13 @@
</td> </td>
</ng-container> </ng-container>
<ng-container matColumnDef="transactions">
<th *matHeaderCellDef i18n mat-header-cell mat-sort-header>Transactions</th>
<td *matCellDef="let element" mat-cell>
{{ element.Order?.length }}
</td>
</ng-container>
<tr *matHeaderRowDef="displayedColumns" mat-header-row></tr> <tr *matHeaderRowDef="displayedColumns" mat-header-row></tr>
<tr *matRowDef="let row; columns: displayedColumns" mat-row></tr> <tr *matRowDef="let row; columns: displayedColumns" mat-row></tr>
</table> </table>

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

@ -50,7 +50,7 @@ export class AccountsTableComponent implements OnChanges, OnDestroy, OnInit {
public ngOnInit() {} public ngOnInit() {}
public ngOnChanges() { public ngOnChanges() {
this.displayedColumns = ['account', 'type', 'platform']; this.displayedColumns = ['account', 'type', 'platform', 'transactions'];
if (this.showActions) { if (this.showActions) {
this.displayedColumns.push('actions'); this.displayedColumns.push('actions');

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

@ -8,7 +8,7 @@ import { DataService } from '@ghostfolio/client/services/data.service';
import { ImpersonationStorageService } from '@ghostfolio/client/services/impersonation-storage.service'; import { ImpersonationStorageService } from '@ghostfolio/client/services/impersonation-storage.service';
import { TokenStorageService } from '@ghostfolio/client/services/token-storage.service'; import { TokenStorageService } from '@ghostfolio/client/services/token-storage.service';
import { hasPermission, permissions } from '@ghostfolio/helper'; import { hasPermission, permissions } from '@ghostfolio/helper';
import { AccountType, Account as AccountModel } from '@prisma/client'; import { Account as AccountModel, AccountType } from '@prisma/client';
import { DeviceDetectorService } from 'ngx-device-detector'; import { DeviceDetectorService } from 'ngx-device-detector';
import { Subject, Subscription } from 'rxjs'; import { Subject, Subscription } from 'rxjs';
import { takeUntil } from 'rxjs/operators'; import { takeUntil } from 'rxjs/operators';

24
apps/client/src/app/pages/analysis/analysis-page.html

@ -36,7 +36,29 @@
<div class="col-md-6"> <div class="col-md-6">
<mat-card class="mb-3"> <mat-card class="mb-3">
<mat-card-header class="w-100"> <mat-card-header class="w-100">
<mat-card-title i18n>By Platform</mat-card-title> <mat-card-title i18n>By Account</mat-card-title>
<gf-toggle
[defaultValue]="period"
[isLoading]="false"
[options]="periodOptions"
(change)="onChangePeriod($event.value)"
></gf-toggle>
</mat-card-header>
<mat-card-content>
<gf-portfolio-proportion-chart
key="name"
[baseCurrency]="user?.settings?.baseCurrency"
[isInPercent]="hasImpersonationId"
[locale]="user?.settings?.locale"
[positions]="platforms"
></gf-portfolio-proportion-chart>
</mat-card-content>
</mat-card>
</div>
<div class="col-md-6">
<mat-card class="mb-3">
<mat-card-header class="w-100">
<mat-card-title class="text-muted" i18n>By Platform</mat-card-title>
<gf-toggle <gf-toggle
[defaultValue]="period" [defaultValue]="period"
[isLoading]="false" [isLoading]="false"

14
apps/client/src/app/pages/transactions/create-or-update-transaction-dialog/create-or-update-transaction-dialog.html

@ -121,11 +121,10 @@
/> />
</mat-form-field> </mat-form-field>
</div> </div>
<div class="d-none"> <div>
<mat-form-field appearance="outline" class="w-100"> <mat-form-field appearance="outline" class="w-100">
<mat-label i18n>Account</mat-label> <mat-label i18n>Account</mat-label>
<mat-select <mat-select
disabled
name="accountId" name="accountId"
required required
[(value)]="data.transaction.accountId" [(value)]="data.transaction.accountId"
@ -136,17 +135,6 @@
</mat-select> </mat-select>
</mat-form-field> </mat-form-field>
</div> </div>
<div>
<mat-form-field appearance="outline" class="w-100">
<mat-label i18n>Platform</mat-label>
<mat-select name="platformId" [(value)]="data.transaction.platformId">
<mat-option [value]="null"></mat-option>
<mat-option *ngFor="let platform of platforms" [value]="platform.id"
>{{ platform.name }}</mat-option
>
</mat-select>
</mat-form-field>
</div>
</div> </div>
<div class="justify-content-end" mat-dialog-actions> <div class="justify-content-end" mat-dialog-actions>
<button i18n mat-button (click)="onCancel()">Cancel</button> <button i18n mat-button (click)="onCancel()">Cancel</button>

Loading…
Cancel
Save