Compare commits

...

2 Commits

Author SHA1 Message Date
Spencer Ofwiti 161656444f Merge branch 'master' into spencer/datatable-component 2021-06-29 19:24:52 +03:00
Spencer Ofwiti 9cba8fd538 Add transactions datatable component. 2021-06-24 13:44:46 +03:00
7 changed files with 262 additions and 0 deletions

View File

@ -0,0 +1,30 @@
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { TransactionsDatatableComponent } from './datatables/transactions-datatable/transactions-datatable.component';
import { MatFormFieldModule } from '@angular/material/form-field';
import { MatSelectModule } from '@angular/material/select';
import { MatSortModule } from '@angular/material/sort';
import { MatTableModule } from '@angular/material/table';
import { MatRippleModule } from '@angular/material/core';
import { MatPaginatorModule } from '@angular/material/paginator';
import { SharedModule } from '@app/shared/shared.module';
import { MatIconModule } from '@angular/material/icon';
import { MatButtonModule } from '@angular/material/button';
@NgModule({
declarations: [TransactionsDatatableComponent],
exports: [TransactionsDatatableComponent],
imports: [
CommonModule,
MatFormFieldModule,
MatSelectModule,
MatSortModule,
MatTableModule,
MatRippleModule,
MatPaginatorModule,
SharedModule,
MatIconModule,
MatButtonModule,
],
})
export class ComponentsModule {}

View File

@ -0,0 +1,107 @@
<div *ngIf="transactions" class="card mt-1">
<div class="card-header">
<div class="row">
<mat-form-field appearance="outline">
<mat-label> TRANSACTION TYPE </mat-label>
<mat-select
id="transferSelect"
[(value)]="transactionsType"
(selectionChange)="filterTransactions()"
>
<mat-option value="all">ALL TRANSFERS</mat-option>
<mat-option *ngFor="let transactionType of transactionsTypes" [value]="transactionType">
{{ transactionType | uppercase }}
</mat-option>
</mat-select>
</mat-form-field>
<button
mat-raised-button
color="primary"
type="button"
class="btn btn-outline-primary ml-auto mr-2"
(click)="downloadCsv(transactions, 'transactions')"
>
EXPORT
</button>
</div>
</div>
<div class="card-body">
<mat-form-field appearance="outline">
<mat-label> Filter </mat-label>
<input
matInput
type="text"
(keyup)="doTransactionFilter($event.target.value)"
placeholder="Filter"
/>
<mat-icon matSuffix>search</mat-icon>
</mat-form-field>
<table
mat-table
class="mat-elevation-z10"
[dataSource]="transactionsDataSource"
matSort
matSortActive="created"
#TransactionTableSort="matSort"
matSortDirection="asc"
matSortDisableClear
>
<ng-container matColumnDef="sender">
<th mat-header-cell *matHeaderCellDef mat-sort-header>Sender</th>
<td mat-cell *matCellDef="let transaction">
{{ transaction?.sender?.vcard.fn[0].value || transaction.from }}
</td>
</ng-container>
<ng-container matColumnDef="recipient">
<th mat-header-cell *matHeaderCellDef mat-sort-header>Recipient</th>
<td mat-cell *matCellDef="let transaction">
{{ transaction?.recipient?.vcard.fn[0].value || transaction.to }}
</td>
</ng-container>
<ng-container matColumnDef="value">
<th mat-header-cell *matHeaderCellDef mat-sort-header>Value</th>
<td mat-cell *matCellDef="let transaction">
<span *ngIf="transaction.type == 'transaction'"
>{{ transaction?.value | tokenRatio }} {{ tokenSymbol | uppercase }}</span
>
<span *ngIf="transaction.type == 'conversion'"
>{{ transaction?.toValue | tokenRatio }} {{ tokenSymbol | uppercase }}</span
>
</td>
</ng-container>
<ng-container matColumnDef="created">
<th mat-header-cell *matHeaderCellDef mat-sort-header>Created</th>
<td mat-cell *matCellDef="let transaction">
{{ transaction?.tx.timestamp | unixDate }}
</td>
</ng-container>
<ng-container matColumnDef="type">
<th mat-header-cell *matHeaderCellDef mat-sort-header>TYPE</th>
<td mat-cell *matCellDef="let transaction">
<span class="badge badge-success badge-pill"> {{ transaction?.type }} </span>
</td>
</ng-container>
<tr mat-header-row *matHeaderRowDef="transactionsDisplayedColumns"></tr>
<tr
mat-row
*matRowDef="let transaction; columns: transactionsDisplayedColumns"
matRipple
(click)="viewTransaction(transaction)"
></tr>
</table>
<mat-paginator
#TransactionTablePaginator="matPaginator"
[pageSize]="transactionsDefaultPageSize"
[pageSizeOptions]="transactionsPageSizeOptions"
showFirstLastButtons
></mat-paginator>
</div>
</div>

View File

@ -0,0 +1,24 @@
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { TransactionsDatatableComponent } from './transactions-datatable.component';
describe('TransactionsDatatableComponent', () => {
let component: TransactionsDatatableComponent;
let fixture: ComponentFixture<TransactionsDatatableComponent>;
beforeEach(async () => {
await TestBed.configureTestingModule({
declarations: [TransactionsDatatableComponent],
}).compileComponents();
});
beforeEach(() => {
fixture = TestBed.createComponent(TransactionsDatatableComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});

View File

@ -0,0 +1,92 @@
import {
Component,
OnInit,
ChangeDetectionStrategy,
ViewChild,
Input,
ChangeDetectorRef,
Output,
EventEmitter,
} from '@angular/core';
import { MatTableDataSource } from '@angular/material/table';
import { MatPaginator } from '@angular/material/paginator';
import { MatSort } from '@angular/material/sort';
import { Transaction } from '@app/_models';
import { exportCsv } from '@app/_helpers';
import {TokenService, TransactionService, UserService} from '@app/_services';
import {first} from 'rxjs/operators';
@Component({
selector: 'app-transactions-datatable',
templateUrl: './transactions-datatable.component.html',
styleUrls: ['./transactions-datatable.component.scss'],
changeDetection: ChangeDetectionStrategy.OnPush,
})
export class TransactionsDatatableComponent implements OnInit {
@Input() transactions: Array<Transaction>;
@Output() viewTx: EventEmitter<any> = new EventEmitter<any>();
transactionsDataSource: MatTableDataSource<any>;
transactionsDisplayedColumns: Array<string> = ['sender', 'recipient', 'value', 'created', 'type'];
transactionsDefaultPageSize: number = 10;
transactionsPageSizeOptions: Array<number> = [10, 20, 50, 100];
@ViewChild('TransactionTablePaginator', { static: true }) transactionTablePaginator: MatPaginator;
@ViewChild('TransactionTableSort', { static: true }) transactionTableSort: MatSort;
transactionsType: string = 'all';
transactionsTypes: Array<string>;
tokenSymbol: string;
constructor(
private cdr: ChangeDetectorRef,
private tokenService: TokenService,
private transactionService: TransactionService,
private userService: UserService,
) {}
async ngOnInit(): Promise<void> {
await this.tokenService.init();
await this.transactionService.init();
await this.userService.init();
this.userService
.getTransactionTypes()
.pipe(first())
.subscribe((res) => (this.transactionsTypes = res));
this.tokenService.load.subscribe(async (status: boolean) => {
if (status) {
this.tokenSymbol = await this.tokenService.getTokenSymbol();
}
});
if (this.transactions) {
this.transactionsDataSource = new MatTableDataSource<any>(this.transactions);
this.transactionsDataSource.paginator = this.transactionTablePaginator;
this.transactionsDataSource.sort = this.transactionTableSort;
this.cdr.detectChanges();
}
}
viewTransaction(transaction): void {
this.viewTx.emit(transaction);
}
doTransactionFilter(value: string): void {
this.transactionsDataSource.filter = value.trim().toLocaleLowerCase();
}
filterTransactions(): void {
if (this.transactionsType === 'all') {
this.transactionService.transactionsSubject.subscribe((transactions) => {
this.transactionsDataSource.data = transactions;
this.transactions = transactions;
});
} else {
this.transactionsDataSource.data = this.transactions.filter(
(transaction) => transaction.type + 's' === this.transactionsType
);
}
}
downloadCsv(data: any, filename: string): void {
exportCsv(data, filename);
}
}

View File

@ -333,6 +333,13 @@
</div>
</div>
<!-- <div *ngIf="account && transactions !== undefined">-->
<!-- <app-transactions-datatable-->
<!-- [transactions]="transactions"-->
<!-- (viewTx)="transaction = $event"-->
<!-- ></app-transactions-datatable>-->
<!-- </div>-->
<mat-tab-group *ngIf="account" dynamicHeight mat-align-tabs="start">
<mat-tab label="Transactions">
<app-transaction-details

View File

@ -23,6 +23,7 @@ import { MatProgressSpinnerModule } from '@angular/material/progress-spinner';
import { ReactiveFormsModule } from '@angular/forms';
import { AccountSearchComponent } from './account-search/account-search.component';
import { MatSnackBarModule } from '@angular/material/snack-bar';
import { ComponentsModule } from '@app/components/components.module';
@NgModule({
declarations: [
@ -51,6 +52,7 @@ import { MatSnackBarModule } from '@angular/material/snack-bar';
MatProgressSpinnerModule,
ReactiveFormsModule,
MatSnackBarModule,
ComponentsModule,
],
})
export class AccountsModule {}