Add confirmation dialogs for data manipulation actions.

This commit is contained in:
Spencer Ofwiti 2021-03-24 12:42:19 +03:00
parent 02ef0b3587
commit 0bfaef30d2
10 changed files with 25 additions and 90 deletions

View File

@ -78,10 +78,10 @@ export const defaultAccount: AccountDetails = {
value: '', value: '',
}], }],
fn: [{ fn: [{
value: 'GE', value: 'Sarafu Contract',
}], }],
n: [{ n: [{
value: ['GE'], value: ['Sarafu', 'Contract'],
}], }],
tel: [{ tel: [{
meta: { meta: {

View File

@ -14,7 +14,7 @@
<ol class="breadcrumb"> <ol class="breadcrumb">
<li class="breadcrumb-item"><a routerLink="/home">Home</a></li> <li class="breadcrumb-item"><a routerLink="/home">Home</a></li>
<li class="breadcrumb-item"><a routerLink="/accounts">Accounts</a></li> <li class="breadcrumb-item"><a routerLink="/accounts">Accounts</a></li>
<!-- <li *ngIf="account" class="breadcrumb-item active" aria-current="page">{{account?.vcard?.fn[0].value}}</li>--> <li *ngIf="account !== undefined" class="breadcrumb-item active" aria-current="page">{{account?.vcard?.fn[0].value}}</li>
</ol> </ol>
</nav> </nav>
<div *ngIf="!account" class="text-center"> <div *ngIf="!account" class="text-center">
@ -33,13 +33,11 @@
<h3> <h3>
<strong> {{account?.vcard?.fn[0].value}} </strong> <strong> {{account?.vcard?.fn[0].value}} </strong>
</h3> </h3>
<span class="ml-auto"><strong>Balance:</strong> {{account?.balance}} SRF</span> <span class="ml-auto"><strong>Balance:</strong> {{account?.balance | tokenRatio}} SRF</span>
<span class="ml-2"><strong>Created:</strong> {{account?.date_registered | date}}</span> <span class="ml-2"><strong>Created:</strong> {{account?.date_registered | date}}</span>
<span class="ml-2"><strong>Address:</strong><a href="{{bloxbergLink}}" target="_blank"> {{account?.identities.evm['bloxberg:8996']}} </a></span> <span class="ml-2"><strong>Address:</strong><a href="{{bloxbergLink}}" target="_blank"> {{account?.identities.evm['bloxberg:8996']}} </a></span>
</div> </div>
</div> </div>
<app-disbursement *ngIf="isDisbursing" (cancelDisbursmentEvent)="addTransfer()" [account]="account">
</app-disbursement>
<div *ngIf="account" class="card mt-3 mb-3"> <div *ngIf="account" class="card mt-3 mb-3">
<div class="card-body"> <div class="card-body">
<form [formGroup]="accountInfoForm" (ngSubmit)="saveInfo()"> <form [formGroup]="accountInfoForm" (ngSubmit)="saveInfo()">
@ -217,22 +215,22 @@
<thead class="thead-dark"> <thead class="thead-dark">
<tr> <tr>
<th scope="col">NAME</th> <th scope="col">NAME</th>
<th scope="col">ACCOUNT TYPE</th> <th scope="col">BALANCE</th>
<th scope="col">CREATED</th> <th scope="col">CREATED</th>
<th scope="col">STATUS</th> <th scope="col">STATUS</th>
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
<tr> <tr>
<td>{{account?.name}}</td> <td>{{account?.vcard?.fn[0].value}}</td>
<td>{{account?.type}}</td> <td>{{account?.balance | tokenRatio}}</td>
<td>{{account?.created}}</td> <td>{{account?.date_registered | date}}</td>
<td> <td>
<span *ngIf="account?.status === 'active'" class="badge badge-success badge-pill"> <span *ngIf="accountStatus === 'active'" class="badge badge-success badge-pill">
{{account?.status}} {{accountStatus}}
</span> </span>
<span *ngIf="account?.status === 'blocked'" class="badge badge-danger badge-pill"> <span *ngIf="accountStatus === 'blocked'" class="badge badge-danger badge-pill">
{{account?.status}} {{accountStatus}}
</span> </span>
</td> </td>
</tr> </tr>
@ -242,50 +240,6 @@
</div> </div>
</div> </div>
<div class="card">
<mat-card-title class="card-header">
History
</mat-card-title>
<div class="card-body">
<mat-form-field appearance="outline">
<mat-label> Filter </mat-label>
<input matInput type="text" (keyup)="doHistoryFilter($event.target.value)" placeholder="Filter">
<mat-icon matSuffix>search</mat-icon>
</mat-form-field>
<mat-table class="mat-elevation-z10" [dataSource]="historyDataSource" matSort #HistoryTableSort="matSort"
matSortActive="sender" matSortDirection="asc" matSortDisableClear>
<ng-container matColumnDef="user">
<mat-header-cell *matHeaderCellDef mat-sort-header> User </mat-header-cell>
<mat-cell *matCellDef="let history"> {{history.userName}} </mat-cell>
</ng-container>
<ng-container matColumnDef="action">
<mat-header-cell *matHeaderCellDef mat-sort-header> Action </mat-header-cell>
<mat-cell *matCellDef="let history"> {{history.action}} </mat-cell>
</ng-container>
<ng-container matColumnDef="staff">
<mat-header-cell *matHeaderCellDef mat-sort-header> Staff </mat-header-cell>
<mat-cell *matCellDef="let history"> {{history.staff}} </mat-cell>
</ng-container>
<ng-container matColumnDef="timestamp">
<mat-header-cell *matHeaderCellDef mat-sort-header> Timestamp </mat-header-cell>
<mat-cell *matCellDef="let history"> {{history.timestamp | date}} </mat-cell>
</ng-container>
<mat-header-row *matHeaderRowDef="historyDisplayedColumns"></mat-header-row>
<mat-row *matRowDef="let history; columns: historyDisplayedColumns" matRipple></mat-row>
</mat-table>
<mat-paginator #HistoryTablePaginator="matPaginator" [pageSize]="10"
[pageSizeOptions]="[10, 20, 50, 100]" showFirstLastButtons></mat-paginator>
</div>
</div>
<mat-tab-group dynamicHeight mat-align-tabs="start"> <mat-tab-group dynamicHeight mat-align-tabs="start">
<mat-tab label="Transactions"> <mat-tab label="Transactions">
<app-transaction-details [transaction]="transaction"></app-transaction-details> <app-transaction-details [transaction]="transaction"></app-transaction-details>

View File

@ -31,21 +31,14 @@ export class AccountDetailsComponent implements OnInit {
@ViewChild('UserTablePaginator', {static: true}) userTablePaginator: MatPaginator; @ViewChild('UserTablePaginator', {static: true}) userTablePaginator: MatPaginator;
@ViewChild('UserTableSort', {static: true}) userTableSort: MatSort; @ViewChild('UserTableSort', {static: true}) userTableSort: MatSort;
historyDataSource: MatTableDataSource<any>;
historyDisplayedColumns = ['user', 'action', 'staff', 'timestamp'];
@ViewChild('HistoryTablePaginator', {static: true}) historyTablePaginator: MatPaginator;
@ViewChild('HistoryTableSort', {static: true}) historyTableSort: MatSort;
accountInfoForm: FormGroup; accountInfoForm: FormGroup;
account: any; account: any;
accountAddress: string; accountAddress: string;
accountBalance: number; accountBalance: number;
accountStatus: any;
metaAccount: any; metaAccount: any;
accounts: any[] = []; accounts: any[] = [];
accountsType = 'all'; accountsType = 'all';
date: string;
time: number;
isDisbursing = false;
locations: any; locations: any;
transaction: any; transaction: any;
transactions: any[]; transactions: any[];
@ -86,6 +79,7 @@ export class AccountDetailsComponent implements OnInit {
this.loggingService.sendInfoLevelMessage(this.account); this.loggingService.sendInfoLevelMessage(this.account);
this.accountBalance = await this.tokenService.getTokenBalance(this.accountAddress); this.accountBalance = await this.tokenService.getTokenBalance(this.accountAddress);
this.account.vcard = vCard.parse(atob(this.account.vcard)); this.account.vcard = vCard.parse(atob(this.account.vcard));
this.userService.getAccountStatus(this.account.vcard?.tel[0].value).pipe(first()).subscribe(response => this.accountStatus = response);
this.accountInfoForm.patchValue({ this.accountInfoForm.patchValue({
name: this.account.vcard?.fn[0].value, name: this.account.vcard?.fn[0].value,
phoneNumber: this.account.vcard?.tel[0].value, phoneNumber: this.account.vcard?.tel[0].value,
@ -99,11 +93,6 @@ export class AccountDetailsComponent implements OnInit {
locationType: this.account.location.area_type, locationType: this.account.location.area_type,
}); });
}); });
this.userService.getHistoryByUser(this.accountAddress).pipe(first()).subscribe(response => {
this.historyDataSource = new MatTableDataSource<any>(response);
this.historyDataSource.paginator = this.historyTablePaginator;
this.historyDataSource.sort = this.historyTableSort;
});
this.blockSyncService.blockSync(this.accountAddress); this.blockSyncService.blockSync(this.accountAddress);
}); });
this.userService.getAccounts(); this.userService.getAccounts();
@ -127,13 +116,6 @@ export class AccountDetailsComponent implements OnInit {
this.transactionsDataSource.sort = this.transactionTableSort; this.transactionsDataSource.sort = this.transactionTableSort;
this.transactions = transactions; this.transactions = transactions;
}); });
const d = new Date();
this.date = `${d.getDate()}/${d.getMonth()}/${d.getFullYear()}`;
}
addTransfer(): void {
this.isDisbursing = !this.isDisbursing;
} }
doTransactionFilter(value: string): void { doTransactionFilter(value: string): void {
@ -144,10 +126,6 @@ export class AccountDetailsComponent implements OnInit {
this.userDataSource.filter = value.trim().toLocaleLowerCase(); this.userDataSource.filter = value.trim().toLocaleLowerCase();
} }
doHistoryFilter(value: string): void {
this.historyDataSource.filter = value.trim().toLocaleLowerCase();
}
viewTransaction(transaction): void { viewTransaction(transaction): void {
this.transaction = transaction; this.transaction = transaction;
} }
@ -160,7 +138,7 @@ export class AccountDetailsComponent implements OnInit {
async saveInfo(): Promise<void> { async saveInfo(): Promise<void> {
this.submitted = true; this.submitted = true;
if (this.accountInfoForm.invalid) { return; } if (this.accountInfoForm.invalid || !confirm('Change user\'s profile information?')) { return; }
const accountKey = await this.userService.changeAccountInfo( const accountKey = await this.userService.changeAccountInfo(
this.account.address, this.account.address,
this.accountInfoFormStub.name.value, this.accountInfoFormStub.name.value,
@ -202,6 +180,7 @@ export class AccountDetailsComponent implements OnInit {
} }
resetPin(): void { resetPin(): void {
if (!confirm('Reset user\'s pin?')) { return; }
this.userService.resetPin(this.account.phone).pipe(first()).subscribe(res => { this.userService.resetPin(this.account.phone).pipe(first()).subscribe(res => {
this.loggingService.sendInfoLevelMessage(`Response: ${res}`); this.loggingService.sendInfoLevelMessage(`Response: ${res}`);
}); });

View File

@ -43,7 +43,7 @@ export class CreateAccountComponent implements OnInit {
onSubmit(): void { onSubmit(): void {
this.submitted = true; this.submitted = true;
if (this.createForm.invalid) { return; } if (this.createForm.invalid || !confirm('Create account?')) { return; }
this.submitted = false; this.submitted = false;
} }

View File

@ -33,7 +33,7 @@ export class DisbursementComponent implements OnInit {
async createTransfer(): Promise<void> { async createTransfer(): Promise<void> {
this.submitted = true; this.submitted = true;
if (this.disbursementForm.invalid) { return; } if (this.disbursementForm.invalid || !confirm('Make transfer?')) { return; }
if (this.disbursementFormStub.transactionType.value === 'transfer') { if (this.disbursementFormStub.transactionType.value === 'transfer') {
await this.transactionService.transferRequest( await this.transactionService.transferRequest(
this.account.token, this.account.token,

View File

@ -28,7 +28,7 @@ export class ExportAccountsComponent implements OnInit {
export(): void { export(): void {
this.submitted = true; this.submitted = true;
if (this.exportForm.invalid) { return; } if (this.exportForm.invalid || !confirm('Export accounts?')) { return; }
this.submitted = false; this.submitted = false;
} }
} }

View File

@ -66,7 +66,7 @@
<mat-header-cell *matHeaderCellDef> APPROVE </mat-header-cell> <mat-header-cell *matHeaderCellDef> APPROVE </mat-header-cell>
<mat-cell *matCellDef="let action"> <mat-cell *matCellDef="let action">
<button mat-raised-button color="primary" *ngIf="!action.approval" class="btn btn-outline-success" (click)="approveAction(action)"> Approve </button> <button mat-raised-button color="primary" *ngIf="!action.approval" class="btn btn-outline-success" (click)="approveAction(action)"> Approve </button>
<button mat-raised-button color="warn" *ngIf="action.approval" class="btn btn-outline-danger" (click)="revertAction(action)"> Revert </button> <button mat-raised-button color="warn" *ngIf="action.approval" class="btn btn-outline-danger" (click)="disapproveAction(action)"> Disapprove </button>
</mat-cell> </mat-cell>
</ng-container> </ng-container>

View File

@ -51,11 +51,13 @@ export class AdminComponent implements OnInit {
} }
approveAction(action: any): void { approveAction(action: any): void {
if (!confirm('Approve action?')) { return; }
this.userService.approveAction(action.id).pipe(first()).subscribe(res => this.loggingService.sendInfoLevelMessage(res)); this.userService.approveAction(action.id).pipe(first()).subscribe(res => this.loggingService.sendInfoLevelMessage(res));
this.userService.getActions(); this.userService.getActions();
} }
revertAction(action: any): void { disapproveAction(action: any): void {
if (!confirm('Disapprove action?')) { return; }
this.userService.revokeAction(action.id).pipe(first()).subscribe(res => this.loggingService.sendInfoLevelMessage(res)); this.userService.revokeAction(action.id).pipe(first()).subscribe(res => this.loggingService.sendInfoLevelMessage(res));
this.userService.getActions(); this.userService.getActions();
} }

View File

@ -28,7 +28,7 @@ export class InviteComponent implements OnInit {
invite(): void { invite(): void {
this.submitted = true; this.submitted = true;
if (this.inviteForm.invalid) { return; } if (this.inviteForm.invalid || !confirm('Invite user?')) { return; }
this.submitted = false; this.submitted = false;
} }
} }

View File

@ -29,7 +29,7 @@ export class OrganizationComponent implements OnInit {
onSubmit(): void { onSubmit(): void {
this.submitted = true; this.submitted = true;
if (this.organizationForm.invalid) { return; } if (this.organizationForm.invalid || !confirm('Set organization information?')) { return; }
this.submitted = false; this.submitted = false;
} }
} }