Feature/add support to create account cash balances (#3260)
* Add support to create account cash balances * Update changelog --------- Co-authored-by: Thomas Kaul <4159106+dtslvr@users.noreply.github.com>
This commit is contained in:
parent
22d63c6102
commit
dfacbed66d
@ -10,6 +10,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||||||
### Added
|
### Added
|
||||||
|
|
||||||
- Added the date range support to the portfolio holdings page
|
- Added the date range support to the portfolio holdings page
|
||||||
|
- Added support to create an account balance
|
||||||
|
|
||||||
### Changed
|
### Changed
|
||||||
|
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
import { AccountService } from '@ghostfolio/api/app/account/account.service';
|
||||||
import { HasPermission } from '@ghostfolio/api/decorators/has-permission.decorator';
|
import { HasPermission } from '@ghostfolio/api/decorators/has-permission.decorator';
|
||||||
import { HasPermissionGuard } from '@ghostfolio/api/guards/has-permission.guard';
|
import { HasPermissionGuard } from '@ghostfolio/api/guards/has-permission.guard';
|
||||||
import { permissions } from '@ghostfolio/common/permissions';
|
import { permissions } from '@ghostfolio/common/permissions';
|
||||||
@ -5,6 +6,8 @@ import type { RequestWithUser } from '@ghostfolio/common/types';
|
|||||||
|
|
||||||
import {
|
import {
|
||||||
Controller,
|
Controller,
|
||||||
|
Body,
|
||||||
|
Post,
|
||||||
Delete,
|
Delete,
|
||||||
HttpException,
|
HttpException,
|
||||||
Inject,
|
Inject,
|
||||||
@ -17,14 +20,50 @@ import { AccountBalance } from '@prisma/client';
|
|||||||
import { StatusCodes, getReasonPhrase } from 'http-status-codes';
|
import { StatusCodes, getReasonPhrase } from 'http-status-codes';
|
||||||
|
|
||||||
import { AccountBalanceService } from './account-balance.service';
|
import { AccountBalanceService } from './account-balance.service';
|
||||||
|
import { CreateAccountBalanceDto } from './create-account-balance.dto';
|
||||||
|
|
||||||
@Controller('account-balance')
|
@Controller('account-balance')
|
||||||
export class AccountBalanceController {
|
export class AccountBalanceController {
|
||||||
public constructor(
|
public constructor(
|
||||||
private readonly accountBalanceService: AccountBalanceService,
|
private readonly accountBalanceService: AccountBalanceService,
|
||||||
|
private readonly accountService: AccountService,
|
||||||
@Inject(REQUEST) private readonly request: RequestWithUser
|
@Inject(REQUEST) private readonly request: RequestWithUser
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
|
@HasPermission(permissions.createAccountBalance)
|
||||||
|
@Post()
|
||||||
|
@UseGuards(AuthGuard('jwt'), HasPermissionGuard)
|
||||||
|
public async createAccountBalance(
|
||||||
|
@Body() data: CreateAccountBalanceDto
|
||||||
|
): Promise<AccountBalance> {
|
||||||
|
const account = await this.accountService.account({
|
||||||
|
id_userId: {
|
||||||
|
id: data.accountId,
|
||||||
|
userId: this.request.user.id
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!account) {
|
||||||
|
throw new HttpException(
|
||||||
|
getReasonPhrase(StatusCodes.FORBIDDEN),
|
||||||
|
StatusCodes.FORBIDDEN
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return this.accountBalanceService.createAccountBalance({
|
||||||
|
Account: {
|
||||||
|
connect: {
|
||||||
|
id_userId: {
|
||||||
|
id: account.id,
|
||||||
|
userId: account.userId
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
date: data.date,
|
||||||
|
value: data.balance
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
@HasPermission(permissions.deleteAccountBalance)
|
@HasPermission(permissions.deleteAccountBalance)
|
||||||
@Delete(':id')
|
@Delete(':id')
|
||||||
@UseGuards(AuthGuard('jwt'), HasPermissionGuard)
|
@UseGuards(AuthGuard('jwt'), HasPermissionGuard)
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
import { AccountService } from '@ghostfolio/api/app/account/account.service';
|
||||||
import { ExchangeRateDataModule } from '@ghostfolio/api/services/exchange-rate-data/exchange-rate-data.module';
|
import { ExchangeRateDataModule } from '@ghostfolio/api/services/exchange-rate-data/exchange-rate-data.module';
|
||||||
import { PrismaModule } from '@ghostfolio/api/services/prisma/prisma.module';
|
import { PrismaModule } from '@ghostfolio/api/services/prisma/prisma.module';
|
||||||
|
|
||||||
@ -10,6 +11,6 @@ import { AccountBalanceService } from './account-balance.service';
|
|||||||
controllers: [AccountBalanceController],
|
controllers: [AccountBalanceController],
|
||||||
exports: [AccountBalanceService],
|
exports: [AccountBalanceService],
|
||||||
imports: [ExchangeRateDataModule, PrismaModule],
|
imports: [ExchangeRateDataModule, PrismaModule],
|
||||||
providers: [AccountBalanceService]
|
providers: [AccountBalanceService, AccountService]
|
||||||
})
|
})
|
||||||
export class AccountBalanceModule {}
|
export class AccountBalanceModule {}
|
||||||
|
@ -0,0 +1,12 @@
|
|||||||
|
import { IsISO8601, IsNumber, IsUUID } from 'class-validator';
|
||||||
|
|
||||||
|
export class CreateAccountBalanceDto {
|
||||||
|
@IsUUID()
|
||||||
|
accountId: string;
|
||||||
|
|
||||||
|
@IsNumber()
|
||||||
|
balance: number;
|
||||||
|
|
||||||
|
@IsISO8601()
|
||||||
|
date: string;
|
||||||
|
}
|
@ -140,15 +140,33 @@ export class AccountDetailDialog implements OnDestroy, OnInit {
|
|||||||
this.dialogRef.close();
|
this.dialogRef.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public onAddAccountBalance({
|
||||||
|
balance,
|
||||||
|
date
|
||||||
|
}: {
|
||||||
|
balance: number;
|
||||||
|
date: Date;
|
||||||
|
}) {
|
||||||
|
this.dataService
|
||||||
|
.postAccountBalance({
|
||||||
|
balance,
|
||||||
|
date,
|
||||||
|
accountId: this.data.accountId
|
||||||
|
})
|
||||||
|
.pipe(takeUntil(this.unsubscribeSubject))
|
||||||
|
.subscribe(() => {
|
||||||
|
this.fetchAccountBalances();
|
||||||
|
this.fetchPortfolioPerformance();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
public onDeleteAccountBalance(aId: string) {
|
public onDeleteAccountBalance(aId: string) {
|
||||||
this.dataService
|
this.dataService
|
||||||
.deleteAccountBalance(aId)
|
.deleteAccountBalance(aId)
|
||||||
.pipe(takeUntil(this.unsubscribeSubject))
|
.pipe(takeUntil(this.unsubscribeSubject))
|
||||||
.subscribe({
|
.subscribe(() => {
|
||||||
next: () => {
|
this.fetchAccountBalances();
|
||||||
this.fetchAccountBalances();
|
this.fetchPortfolioPerformance();
|
||||||
this.fetchPortfolioPerformance();
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -115,6 +115,7 @@
|
|||||||
</ng-template>
|
</ng-template>
|
||||||
<gf-account-balances
|
<gf-account-balances
|
||||||
[accountBalances]="accountBalances"
|
[accountBalances]="accountBalances"
|
||||||
|
[accountCurrency]="currency"
|
||||||
[accountId]="data.accountId"
|
[accountId]="data.accountId"
|
||||||
[locale]="user?.settings?.locale"
|
[locale]="user?.settings?.locale"
|
||||||
[showActions]="
|
[showActions]="
|
||||||
@ -122,6 +123,7 @@
|
|||||||
hasPermissionToDeleteAccountBalance &&
|
hasPermissionToDeleteAccountBalance &&
|
||||||
!user.settings.isRestrictedView
|
!user.settings.isRestrictedView
|
||||||
"
|
"
|
||||||
|
(accountBalanceCreated)="onAddAccountBalance($event)"
|
||||||
(accountBalanceDeleted)="onDeleteAccountBalance($event)"
|
(accountBalanceDeleted)="onDeleteAccountBalance($event)"
|
||||||
/>
|
/>
|
||||||
</mat-tab>
|
</mat-tab>
|
||||||
|
@ -42,7 +42,11 @@ import { translate } from '@ghostfolio/ui/i18n';
|
|||||||
import { HttpClient, HttpParams } from '@angular/common/http';
|
import { HttpClient, HttpParams } from '@angular/common/http';
|
||||||
import { Injectable } from '@angular/core';
|
import { Injectable } from '@angular/core';
|
||||||
import { SortDirection } from '@angular/material/sort';
|
import { SortDirection } from '@angular/material/sort';
|
||||||
import { DataSource, Order as OrderModel } from '@prisma/client';
|
import {
|
||||||
|
AccountBalance,
|
||||||
|
DataSource,
|
||||||
|
Order as OrderModel
|
||||||
|
} from '@prisma/client';
|
||||||
import { format, parseISO } from 'date-fns';
|
import { format, parseISO } from 'date-fns';
|
||||||
import { cloneDeep, groupBy, isNumber } from 'lodash';
|
import { cloneDeep, groupBy, isNumber } from 'lodash';
|
||||||
import { Observable } from 'rxjs';
|
import { Observable } from 'rxjs';
|
||||||
@ -611,6 +615,22 @@ export class DataService {
|
|||||||
return this.http.post<OrderModel>(`/api/v1/account`, aAccount);
|
return this.http.post<OrderModel>(`/api/v1/account`, aAccount);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public postAccountBalance({
|
||||||
|
accountId,
|
||||||
|
balance,
|
||||||
|
date
|
||||||
|
}: {
|
||||||
|
accountId: string;
|
||||||
|
balance: number;
|
||||||
|
date: Date;
|
||||||
|
}) {
|
||||||
|
return this.http.post<AccountBalance>(`/api/v1/account-balance`, {
|
||||||
|
accountId,
|
||||||
|
balance,
|
||||||
|
date
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
public postBenchmark(benchmark: UniqueAsset) {
|
public postBenchmark(benchmark: UniqueAsset) {
|
||||||
return this.http.post(`/api/v1/benchmark`, benchmark);
|
return this.http.post(`/api/v1/benchmark`, benchmark);
|
||||||
}
|
}
|
||||||
|
@ -7,6 +7,7 @@ export const permissions = {
|
|||||||
accessAssistant: 'accessAssistant',
|
accessAssistant: 'accessAssistant',
|
||||||
createAccess: 'createAccess',
|
createAccess: 'createAccess',
|
||||||
createAccount: 'createAccount',
|
createAccount: 'createAccount',
|
||||||
|
createAccountBalance: 'createAccountBalance',
|
||||||
createOrder: 'createOrder',
|
createOrder: 'createOrder',
|
||||||
createPlatform: 'createPlatform',
|
createPlatform: 'createPlatform',
|
||||||
createTag: 'createTag',
|
createTag: 'createTag',
|
||||||
@ -47,6 +48,7 @@ export function getPermissions(aRole: Role): string[] {
|
|||||||
permissions.accessAssistant,
|
permissions.accessAssistant,
|
||||||
permissions.createAccess,
|
permissions.createAccess,
|
||||||
permissions.createAccount,
|
permissions.createAccount,
|
||||||
|
permissions.createAccountBalance,
|
||||||
permissions.deleteAccountBalance,
|
permissions.deleteAccountBalance,
|
||||||
permissions.createOrder,
|
permissions.createOrder,
|
||||||
permissions.createPlatform,
|
permissions.createPlatform,
|
||||||
@ -75,6 +77,7 @@ export function getPermissions(aRole: Role): string[] {
|
|||||||
permissions.accessAssistant,
|
permissions.accessAssistant,
|
||||||
permissions.createAccess,
|
permissions.createAccess,
|
||||||
permissions.createAccount,
|
permissions.createAccount,
|
||||||
|
permissions.createAccountBalance,
|
||||||
permissions.createOrder,
|
permissions.createOrder,
|
||||||
permissions.deleteAccess,
|
permissions.deleteAccess,
|
||||||
permissions.deleteAccount,
|
permissions.deleteAccount,
|
||||||
|
@ -1,60 +1,106 @@
|
|||||||
<table
|
<form [formGroup]="accountBalanceForm" (ngSubmit)="onSubmitAccountBalance()">
|
||||||
class="gf-table w-100"
|
<table
|
||||||
mat-table
|
class="gf-table w-100"
|
||||||
matSort
|
mat-table
|
||||||
matSortActive="date"
|
matSort
|
||||||
matSortDirection="desc"
|
matSortActive="date"
|
||||||
[dataSource]="dataSource"
|
matSortDirection="desc"
|
||||||
>
|
[dataSource]="dataSource"
|
||||||
<ng-container matColumnDef="date">
|
>
|
||||||
<th *matHeaderCellDef class="px-2" mat-header-cell mat-sort-header>
|
<ng-container matColumnDef="date">
|
||||||
<ng-container i18n>Date</ng-container>
|
<th *matHeaderCellDef class="px-2" mat-header-cell mat-sort-header>
|
||||||
</th>
|
<ng-container i18n>Date</ng-container>
|
||||||
<td *matCellDef="let element" class="px-2" mat-cell>
|
</th>
|
||||||
<gf-value [isDate]="true" [locale]="locale" [value]="element?.date" />
|
<td *matCellDef="let element" class="px-2" mat-cell>
|
||||||
</td>
|
<gf-value [isDate]="true" [locale]="locale" [value]="element?.date" />
|
||||||
</ng-container>
|
</td>
|
||||||
|
<td *matFooterCellDef class="px-2" mat-footer-cell>
|
||||||
|
<mat-form-field appearance="outline" class="py-1 without-hint">
|
||||||
|
<input formControlName="date" matInput [matDatepicker]="date" />
|
||||||
|
<mat-datepicker-toggle matSuffix [for]="date">
|
||||||
|
<ion-icon
|
||||||
|
class="text-muted"
|
||||||
|
matDatepickerToggleIcon
|
||||||
|
name="calendar-clear-outline"
|
||||||
|
/>
|
||||||
|
</mat-datepicker-toggle>
|
||||||
|
<mat-datepicker #date />
|
||||||
|
</mat-form-field>
|
||||||
|
</td>
|
||||||
|
</ng-container>
|
||||||
|
|
||||||
<ng-container matColumnDef="value">
|
<ng-container matColumnDef="value">
|
||||||
<th *matHeaderCellDef class="px-2 text-right" mat-header-cell>
|
<th *matHeaderCellDef class="px-2 text-right" mat-header-cell>
|
||||||
<ng-container i18n>Value</ng-container>
|
<ng-container i18n>Value</ng-container>
|
||||||
</th>
|
</th>
|
||||||
<td *matCellDef="let element" class="px-2" mat-cell>
|
<td *matCellDef="let element" class="px-2" mat-cell>
|
||||||
<div class="d-flex justify-content-end">
|
<div class="d-flex justify-content-end">
|
||||||
<gf-value
|
<gf-value
|
||||||
[isCurrency]="true"
|
[isCurrency]="true"
|
||||||
[locale]="locale"
|
[locale]="locale"
|
||||||
[unit]="element?.Account?.currency"
|
[unit]="element?.Account?.currency"
|
||||||
[value]="element?.value"
|
[value]="element?.value"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</td>
|
</td>
|
||||||
</ng-container>
|
<td *matFooterCellDef class="px-2" mat-footer-cell>
|
||||||
|
<div class="d-flex justify-content-end">
|
||||||
|
<mat-form-field appearance="outline" class="without-hint">
|
||||||
|
<input formControlName="balance" matInput type="number" />
|
||||||
|
<div class="ml-2" matTextSuffix>
|
||||||
|
{{ accountCurrency }}
|
||||||
|
</div>
|
||||||
|
</mat-form-field>
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
</ng-container>
|
||||||
|
|
||||||
<ng-container matColumnDef="actions" stickyEnd>
|
<ng-container matColumnDef="actions" stickyEnd>
|
||||||
<th *matHeaderCellDef class="px-1 text-center" mat-header-cell></th>
|
<th *matHeaderCellDef class="px-1 text-center" mat-header-cell></th>
|
||||||
<td *matCellDef="let element" class="px-1 text-center" mat-cell>
|
<td *matCellDef="let element" class="px-1 text-center" mat-cell>
|
||||||
@if (showActions) {
|
@if (showActions) {
|
||||||
|
<button
|
||||||
|
class="mx-1 no-min-width px-2"
|
||||||
|
mat-button
|
||||||
|
type="button"
|
||||||
|
[matMenuTriggerFor]="accountBalanceMenu"
|
||||||
|
(click)="$event.stopPropagation()"
|
||||||
|
>
|
||||||
|
<ion-icon name="ellipsis-horizontal" />
|
||||||
|
</button>
|
||||||
|
}
|
||||||
|
<mat-menu #accountBalanceMenu="matMenu" xPosition="before">
|
||||||
|
<button
|
||||||
|
mat-menu-item
|
||||||
|
type="button"
|
||||||
|
(click)="onDeleteAccountBalance(element.id)"
|
||||||
|
>
|
||||||
|
<span class="align-items-center d-flex">
|
||||||
|
<ion-icon class="mr-2" name="trash-outline" />
|
||||||
|
<span i18n>Delete</span>
|
||||||
|
</span>
|
||||||
|
</button>
|
||||||
|
</mat-menu>
|
||||||
|
</td>
|
||||||
|
<td *matFooterCellDef class="px-1 text-center" mat-footer-cell>
|
||||||
<button
|
<button
|
||||||
class="mx-1 no-min-width px-2"
|
class="mx-1 no-min-width px-2"
|
||||||
mat-button
|
color="primary"
|
||||||
[matMenuTriggerFor]="accountBalanceMenu"
|
mat-flat-button
|
||||||
(click)="$event.stopPropagation()"
|
type="submit"
|
||||||
|
[disabled]="accountBalanceForm.invalid"
|
||||||
>
|
>
|
||||||
<ion-icon name="ellipsis-horizontal" />
|
<span i18n>Add</span>
|
||||||
</button>
|
</button>
|
||||||
}
|
</td>
|
||||||
<mat-menu #accountBalanceMenu="matMenu" xPosition="before">
|
</ng-container>
|
||||||
<button mat-menu-item (click)="onDeleteAccountBalance(element.id)">
|
|
||||||
<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 *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>
|
<tr
|
||||||
|
*matFooterRowDef="displayedColumns"
|
||||||
|
mat-footer-row
|
||||||
|
[hidden]="!showActions"
|
||||||
|
></tr>
|
||||||
|
</table>
|
||||||
|
</form>
|
||||||
|
@ -1,3 +1,10 @@
|
|||||||
:host {
|
:host {
|
||||||
display: block;
|
display: block;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
:host-context(.is-dark-theme) {
|
||||||
|
input {
|
||||||
|
color: rgb(var(--light-primary-text));
|
||||||
|
background-color: rgb(var(--palette-foreground-text-light));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -14,7 +14,17 @@ import {
|
|||||||
Output,
|
Output,
|
||||||
ViewChild
|
ViewChild
|
||||||
} from '@angular/core';
|
} from '@angular/core';
|
||||||
|
import {
|
||||||
|
FormGroup,
|
||||||
|
FormControl,
|
||||||
|
Validators,
|
||||||
|
ReactiveFormsModule
|
||||||
|
} from '@angular/forms';
|
||||||
import { MatButtonModule } from '@angular/material/button';
|
import { MatButtonModule } from '@angular/material/button';
|
||||||
|
import { DateAdapter } from '@angular/material/core';
|
||||||
|
import { MatDatepickerModule } from '@angular/material/datepicker';
|
||||||
|
import { MatFormFieldModule } from '@angular/material/form-field';
|
||||||
|
import { MatInputModule } from '@angular/material/input';
|
||||||
import { MatMenuModule } from '@angular/material/menu';
|
import { MatMenuModule } from '@angular/material/menu';
|
||||||
import { MatSort, MatSortModule } from '@angular/material/sort';
|
import { MatSort, MatSortModule } from '@angular/material/sort';
|
||||||
import { MatTableDataSource, MatTableModule } from '@angular/material/table';
|
import { MatTableDataSource, MatTableModule } from '@angular/material/table';
|
||||||
@ -29,9 +39,13 @@ import { GfValueComponent } from '../value';
|
|||||||
CommonModule,
|
CommonModule,
|
||||||
GfValueComponent,
|
GfValueComponent,
|
||||||
MatButtonModule,
|
MatButtonModule,
|
||||||
|
MatDatepickerModule,
|
||||||
|
MatFormFieldModule,
|
||||||
|
MatInputModule,
|
||||||
MatMenuModule,
|
MatMenuModule,
|
||||||
MatSortModule,
|
MatSortModule,
|
||||||
MatTableModule
|
MatTableModule,
|
||||||
|
ReactiveFormsModule
|
||||||
],
|
],
|
||||||
schemas: [CUSTOM_ELEMENTS_SCHEMA],
|
schemas: [CUSTOM_ELEMENTS_SCHEMA],
|
||||||
selector: 'gf-account-balances',
|
selector: 'gf-account-balances',
|
||||||
@ -43,24 +57,38 @@ export class GfAccountBalancesComponent
|
|||||||
implements OnChanges, OnDestroy, OnInit
|
implements OnChanges, OnDestroy, OnInit
|
||||||
{
|
{
|
||||||
@Input() accountBalances: AccountBalancesResponse['balances'];
|
@Input() accountBalances: AccountBalancesResponse['balances'];
|
||||||
|
@Input() accountCurrency: string;
|
||||||
@Input() accountId: string;
|
@Input() accountId: string;
|
||||||
@Input() locale = getLocale();
|
@Input() locale = getLocale();
|
||||||
@Input() showActions = true;
|
@Input() showActions = true;
|
||||||
|
|
||||||
|
@Output() accountBalanceCreated = new EventEmitter<{
|
||||||
|
balance: number;
|
||||||
|
date: Date;
|
||||||
|
}>();
|
||||||
@Output() accountBalanceDeleted = new EventEmitter<string>();
|
@Output() accountBalanceDeleted = new EventEmitter<string>();
|
||||||
|
|
||||||
@ViewChild(MatSort) sort: MatSort;
|
@ViewChild(MatSort) sort: MatSort;
|
||||||
|
|
||||||
|
public accountBalanceForm = new FormGroup({
|
||||||
|
balance: new FormControl(0, Validators.required),
|
||||||
|
date: new FormControl(new Date(), Validators.required)
|
||||||
|
});
|
||||||
|
|
||||||
public dataSource: MatTableDataSource<
|
public dataSource: MatTableDataSource<
|
||||||
AccountBalancesResponse['balances'][0]
|
AccountBalancesResponse['balances'][0]
|
||||||
> = new MatTableDataSource();
|
> = new MatTableDataSource();
|
||||||
|
|
||||||
public displayedColumns: string[] = ['date', 'value', 'actions'];
|
public displayedColumns: string[] = ['date', 'value', 'actions'];
|
||||||
|
public Validators = Validators;
|
||||||
|
|
||||||
private unsubscribeSubject = new Subject<void>();
|
private unsubscribeSubject = new Subject<void>();
|
||||||
|
|
||||||
public constructor() {}
|
public constructor(private dateAdapter: DateAdapter<any>) {}
|
||||||
|
|
||||||
public ngOnInit() {}
|
public ngOnInit() {
|
||||||
|
this.dateAdapter.setLocale(this.locale);
|
||||||
|
}
|
||||||
|
|
||||||
public ngOnChanges() {
|
public ngOnChanges() {
|
||||||
if (this.accountBalances) {
|
if (this.accountBalances) {
|
||||||
@ -81,6 +109,10 @@ export class GfAccountBalancesComponent
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public onSubmitAccountBalance() {
|
||||||
|
this.accountBalanceCreated.emit(this.accountBalanceForm.getRawValue());
|
||||||
|
}
|
||||||
|
|
||||||
public ngOnDestroy() {
|
public ngOnDestroy() {
|
||||||
this.unsubscribeSubject.next();
|
this.unsubscribeSubject.next();
|
||||||
this.unsubscribeSubject.complete();
|
this.unsubscribeSubject.complete();
|
||||||
|
Loading…
x
Reference in New Issue
Block a user