Commit 1360c62a authored by Pieterjan Vanhoof's avatar Pieterjan Vanhoof Committed by GitHub

Merge pull request #243 from stratisproject/ui

Show complete transaction info, show confirmations, split coin notation from coin abbreviation
parents 93b14f87 e10d0e5f
export class TransactionInfo {
constructor(transactionType: string, transactionId: string, transactionAmount: number, transactionAddress: any, transactionFee: number, transactionConfirmedInBlock: number, transactionTimestamp: number) {
this.transactionType = transactionType;
this.transactionId = transactionId;
this.transactionAmount = transactionAmount;
this.transactionAddress = transactionAddress;
this.transactionFee = transactionFee;
this.transactionConfirmedInBlock = transactionConfirmedInBlock;
this.transactionTimestamp = transactionTimestamp;
}
public transactionType: string;
public transactionId: string;
public transactionAmount: number;
public transactionAddress: string;
public transactionFee: number;
public transactionConfirmedInBlock?: number;
public transactionTimestamp: number;
}
export class WalletInfo {
constructor(walletName: string, coinType: number) {
constructor(walletName: string) {
this.walletName = walletName;
this.coinType = coinType;
}
public walletName: string;
public coinType: number;
}
......@@ -13,46 +13,46 @@ export class CoinNotationPipe implements PipeTransform {
private coinNotation: number;
private decimalLimit = 8;
transform(value: any): any {
transform(value: number): number {
let temp;
if (typeof value === 'number') {
switch (this.getCoinUnit()) {
case "BTC":
temp = value / 100000000;
return temp.toFixed(this.decimalLimit) + " BTC";
return temp.toFixed(this.decimalLimit);
case "mBTC":
temp = value / 100000;
return temp.toFixed(this.decimalLimit) + " mBTC";
return temp.toFixed(this.decimalLimit);
case "uBTC":
temp = value / 100;
return temp.toFixed(this.decimalLimit) + " uBTC";
return temp.toFixed(this.decimalLimit);
case "TBTC":
temp = value / 100000000;
return temp.toFixed(this.decimalLimit) + " TBTC";
return temp.toFixed(this.decimalLimit);
case "TmBTC":
temp = value / 100000;
return temp.toFixed(this.decimalLimit) + " TmBTC";
return temp.toFixed(this.decimalLimit);
case "TuBTC":
temp = value / 100;
return temp.toFixed(this.decimalLimit) + " TuBTC";
return temp.toFixed(this.decimalLimit);
case "STRAT":
temp = value / 100000000;
return temp.toFixed(this.decimalLimit) + " STRAT";
return temp.toFixed(this.decimalLimit);
case "mSTRAT":
temp = value / 100000;
return temp.toFixed(this.decimalLimit) + " mSTRAT";
return temp.toFixed(this.decimalLimit);
case "uSTRAT":
temp = value / 100;
return temp.toFixed(this.decimalLimit) + " uSTRAT";
return temp.toFixed(this.decimalLimit);
case "TSTRAT":
temp = value / 100000000;
return temp.toFixed(this.decimalLimit) + " TSTRAT";
return temp.toFixed(this.decimalLimit);
case "TmSTRAT":
temp = value / 100000;
return temp.toFixed(this.decimalLimit) + " TmSTRAT";
return temp.toFixed(this.decimalLimit);
case "TuSTRAT":
temp = value / 100;
return temp.toFixed(this.decimalLimit) + " TuSTRAT";
return temp.toFixed(this.decimalLimit);
}
}
}
......
......@@ -9,8 +9,8 @@
<h5>Active balance</h5>
<p class="lead">
<!--<strong><span class="h2">29</span>.76500293</strong>-->
<strong>{{confirmedBalance | coinNotation }}</strong>
<!--<small class="text-uppercase">btc</small>-->
<strong>{{ confirmedBalance | coinNotation }}</strong>
<small class="text-uppercase"> {{ coinUnit }}</small>
</p>
</div>
<!-- /col-->
......@@ -25,7 +25,8 @@
<div class="col-xs-12 col-md-4 text-left">
<h5>Unconfirmed balance</h5>
<p class="lead">
<strong>{{unconfirmedBalance | coinNotation }}</strong>
<strong>{{ unconfirmedBalance | coinNotation }}</strong>
<small class="text-uppercase"> {{ coinUnit }}</small>
</p>
</div>
<!-- /col-->
......@@ -46,14 +47,21 @@
<!-- TRANSACTIONS -->
<section id="transaction" class="container">
<h5>Latest Transactions</h5>
<div *ngIf="transactions; else noTransactions">
<div *ngFor="let transaction of transactions; let i=index">
<div *ngIf="transactionArray; else noTransactions">
<div *ngFor="let transaction of transactionArray; let i=index">
<div class="card" *ngIf="i<3" (click)="openTransactionDetailDialog(transaction)">
<div class="card-block text-nowrap">
<ul class="list-inline row">
<li class="list-inline-item hidden-xs-down col-3 text-uppercase align-bottom">{{ transaction.type }}</li>
<li class="list-inline-item col-4 amount text-left align-baseline"><!--<span class="text-success">+</span>--> {{ transaction.amount | coinNotation }} <!--<small class="text-uppercase">btc</small> <span class="badge badge-danger text-capitalize">unconfirmed</span>--></li>
<li class="list-inline-item col text-right align-baseline transactionDate">{{ transaction.timestamp * 1000 | date:'medium' }}</li>
<li class="list-inline-item hidden-xs-down col-3 text-uppercase align-bottom">{{ transaction.transactionType }}</li>
<li class="list-inline-item col-4 amount text-left align-baseline">
<span *ngIf="transaction.transactionType == 'received'" class="text-success">+</span>
<span *ngIf="transaction.transactionType == 'sent'" class="text-danger">-</span>
{{ transaction.transactionAmount | coinNotation }}
<small class="text-uppercase">{{ coinUnit }}</small>
<span *ngIf="transaction.transactionConfirmedInBlock" class="badge badge-success text-capitalize">Confirmed</span>
<span *ngIf="!transaction.transactionConfirmedInBlock" class="badge badge-warning text-capitalize">Pending</span>
</li>
<li class="list-inline-item col text-right align-baseline transactionDate">{{ transaction.transactionTimestamp * 1000 | date:'medium' }}</li>
</ul>
</div>
</div>
......
......@@ -4,6 +4,7 @@ import { NgbModal, NgbActiveModal } from '@ng-bootstrap/ng-bootstrap';
import { ApiService } from '../../shared/services/api.service';
import { GlobalService } from '../../shared/services/global.service';
import { WalletInfo } from '../../shared/classes/wallet-info';
import { TransactionInfo } from '../../shared/classes/transaction-info';
import { SendComponent } from '../send/send.component';
import { ReceiveComponent } from '../receive/receive.component';
......@@ -23,12 +24,14 @@ export class DashboardComponent implements OnInit {
public confirmedBalance: number;
public unconfirmedBalance: number;
public transactions: any;
public transactionArray: TransactionInfo[];
public coinUnit: string;
private walletBalanceSubscription: Subscription;
private walletHistorySubscription: Subscription;
ngOnInit() {
this.startSubscriptions();
this.coinUnit = this.globalService.getCoinUnit();
};
ngOnDestroy() {
......@@ -43,13 +46,13 @@ export class DashboardComponent implements OnInit {
const modalRef = this.modalService.open(ReceiveComponent);
};
public openTransactionDetailDialog(transaction: any) {
public openTransactionDetailDialog(transaction: TransactionInfo) {
const modalRef = this.modalService.open(TransactionDetailsComponent);
modalRef.componentInstance.transaction = transaction;
}
private getWalletBalance() {
let walletInfo = new WalletInfo(this.globalService.getWalletName(), this.globalService.getCoinType())
let walletInfo = new WalletInfo(this.globalService.getWalletName());
this.walletBalanceSubscription = this.apiService.getWalletBalance(walletInfo)
.subscribe(
response => {
......@@ -81,14 +84,17 @@ export class DashboardComponent implements OnInit {
;
};
// todo: add history in seperate service to make it reusable
private getHistory() {
let walletInfo = new WalletInfo(this.globalService.getWalletName(), this.globalService.getCoinType())
let walletInfo = new WalletInfo(this.globalService.getWalletName());
let historyResponse;
this.walletHistorySubscription = this.apiService.getWalletHistory(walletInfo)
.subscribe(
response => {
if (response.status >= 200 && response.status < 400) {
if (response.json().transactionsHistory.length > 0) {
this.transactions = response.json().transactionsHistory;
historyResponse = response.json().transactionsHistory;
this.getTransactionInfo(historyResponse);
}
}
},
......@@ -114,6 +120,33 @@ export class DashboardComponent implements OnInit {
;
};
private getTransactionInfo(transactions: any) {
this.transactionArray = [];
for (let transaction of transactions) {
let transactionType;
if (transaction.type === "send") {
transactionType = "sent";
} else if (transaction.type === "received") {
transactionType = "received";
}
let transactionId = transaction.id;
let transactionAmount = transaction.amount;
let transactionAddress;
if (transaction.payments[0]) {
transactionAddress = transaction.payments[0].destinationAddress;
} else if (transaction.toAddress) {
transactionAddress = transaction.toAddress;
}
let transactionFee = transaction.fee;
let transactionConfirmedInBlock = transaction.confirmedInBlock;
let transactionTimestamp = transaction.timestamp;
let transactionConfirmed;
this.transactionArray.push(new TransactionInfo(transactionType, transactionId, transactionAmount, transactionAddress, transactionFee, transactionConfirmedInBlock, transactionTimestamp));
}
}
private cancelSubscriptions() {
if (this.walletBalanceSubscription) {
this.walletBalanceSubscription.unsubscribe();
......
......@@ -25,12 +25,19 @@
<div *ngFor="let transaction of transactions">
<div class="card" (click)="openTransactionDetailDialog(transaction)">
<div class="card-block text-nowrap">
<ul class="list-inline row">
<li class="list-inline-item hidden-xs-down col text-uppercase align-bottom">{{ transaction.type }}</li>
<li class="list-inline-item col-4 amount text-left align-baseline"><!--<span class="text-success">+</span>--> {{ transaction.amount | coinNotation }} <!--<small class="text-uppercase">btc</small> <span class="badge badge-danger text-capitalize">unconfirmed</span>--></li>
<li class="list-inline-item col text-right align-baseline transactionDate">{{ transaction.timestamp * 1000 | date:'medium' }}</li>
</ul>
</div>
<ul class="list-inline row">
<li class="list-inline-item hidden-xs-down col-3 text-uppercase align-bottom">{{ transaction.transactionType }}</li>
<li class="list-inline-item col-4 amount text-left align-baseline">
<span *ngIf="transaction.transactionType == 'received'" class="text-success">+</span>
<span *ngIf="transaction.transactionType == 'sent'" class="text-danger">-</span>
{{ transaction.transactionAmount | coinNotation }}
<small class="text-uppercase"> {{ coinUnit }} </small>
<span *ngIf="transaction.transactionConfirmedInBlock" class="badge badge-success text-capitalize">Confirmed</span>
<span *ngIf="!transaction.transactionConfirmedInBlock" class="badge badge-warning text-capitalize">Pending</span>
</li>
<li class="list-inline-item col text-right align-baseline transactionDate">{{ transaction.transactionTimestamp * 1000 | date:'medium' }}</li>
</ul>
</div>
</div>
</div>
</div>
......
......@@ -5,6 +5,7 @@ import { ApiService } from '../../shared/services/api.service';
import { GlobalService } from '../../shared/services/global.service';
import { WalletInfo } from '../../shared/classes/wallet-info';
import { TransactionInfo } from '../../shared/classes/transaction-info';
import { Observable } from 'rxjs/Rx';
import { Subscription } from 'rxjs/Subscription';
......@@ -20,12 +21,14 @@ import { TransactionDetailsComponent } from '../transaction-details/transaction-
export class HistoryComponent {
constructor(private apiService: ApiService, private globalService: GlobalService, private modalService: NgbModal) {}
public transactions: any;
public transactions: TransactionInfo[];
public coinUnit: string;
private errorMessage: string;
private walletHistorySubscription: Subscription;
ngOnInit() {
this.startSubscriptions();
this.coinUnit = this.globalService.getCoinUnit();
}
ngOnDestroy() {
......@@ -37,14 +40,17 @@ export class HistoryComponent {
modalRef.componentInstance.transaction = transaction;
}
// todo: add history in seperate service to make it reusable
private getHistory() {
let walletInfo = new WalletInfo(this.globalService.getWalletName(), this.globalService.getCoinType())
let walletInfo = new WalletInfo(this.globalService.getWalletName())
let historyResponse;
this.walletHistorySubscription = this.apiService.getWalletHistory(walletInfo)
.subscribe(
response => {
if (response.status >= 200 && response.status < 400) {
if (response.json().transactionsHistory.length > 0) {
this.transactions = response.json().transactionsHistory;
historyResponse = response.json().transactionsHistory;
this.getTransactionInfo(historyResponse);
}
}
},
......@@ -70,6 +76,33 @@ export class HistoryComponent {
;
};
private getTransactionInfo(transactions: any) {
this.transactions = [];
for (let transaction of transactions) {
let transactionType;
if (transaction.type === "send") {
transactionType = "sent";
} else if (transaction.type === "received") {
transactionType = "received";
}
let transactionId = transaction.id;
let transactionAmount = transaction.amount;
let transactionAddress;
if (transaction.payments[0]) {
transactionAddress = transaction.payments[0].destinationAddress;
} else if (transaction.toAddress) {
transactionAddress = transaction.toAddress;
}
let transactionFee = transaction.fee;
let transactionConfirmedInBlock = transaction.confirmedInBlock;
let transactionTimestamp = transaction.timestamp;
let transactionConfirmed;
this.transactions.push(new TransactionInfo(transactionType, transactionId, transactionAmount, transactionAddress, transactionFee, transactionConfirmedInBlock, transactionTimestamp));
}
}
private cancelSubscriptions() {
if(this.walletHistorySubscription) {
this.walletHistorySubscription.unsubscribe();
......
......@@ -29,7 +29,7 @@ export class ReceiveComponent {
}
private getUnusedReceiveAddresses() {
let walletInfo = new WalletInfo(this.globalService.getWalletName(), this.globalService.getCoinType())
let walletInfo = new WalletInfo(this.globalService.getWalletName())
this.apiService.getUnusedReceiveAddress(walletInfo)
.subscribe(
response => {
......
......@@ -32,8 +32,8 @@ export class StatusBarComponent implements OnInit {
this.cancelSubscriptions();
}
getGeneralWalletInfo() {
let walletInfo = new WalletInfo(this.globalService.getWalletName(), this.globalService.getCoinType())
private getGeneralWalletInfo() {
let walletInfo = new WalletInfo(this.globalService.getWalletName())
this.generalWalletInfoSubscription = this.apiService.getGeneralInfo(walletInfo)
.subscribe(
response => {
......
......@@ -8,28 +8,34 @@
<h5 class="modal-title text-uppercase" id="modalDetail">Transaction Details</h5>
<ul class="list-inline row">
<li class="list-inline-item col blockLabel">Type</li>
<li class="list-inline-item col-9 blockText text-capitalize">{{ transaction.type }}</li>
<li class="list-inline-item col-9 blockText text-capitalize">{{ transaction.transactionType }}</li>
</ul>
<ul class="list-inline row">
<li class="list-inline-item col blockLabel">Amount</li>
<li class="list-inline-item col-9 blockText text-success">{{transaction.amount | coinNotation }}</li>
<li *ngIf="transaction.transactionType == 'received'" class="list-inline-item col-9 blockText text-success">{{ transaction.transactionAmount | coinNotation }} {{ coinUnit }}</li>
<li *ngIf="transaction.transactionType == 'sent'" class="list-inline-item col-9 blockText text-danger">-{{ transaction.transactionAmount | coinNotation }} {{ coinUnit }}</li>
</ul>
<!--<ul class="list-inline row">
<li class="list-inline-item col blockLabel">From</li>
<li class="list-inline-item col-9 blockText"><code>n4kVJQarwwdmsXDdgNnJHgBSpZ8MhSkNBx</code></li>
</ul>-->
<ul class="list-inline row">
<li class="list-inline-item col blockLabel">Date</li>
<li class="list-inline-item col-9 blockText">{{ transaction.timestamp * 1000 | date:'medium' }}</li>
<li *ngIf="transaction.transactionType == 'received'" class="list-inline-item col blockLabel">From</li>
<li *ngIf="transaction.transactionType == 'sent'" class="list-inline-item col blockLabel">To</li>
<li class="list-inline-item col-9 blockText"><code>{{ transaction.transactionAddress }}</code></li>
</ul>
<ul class="list-inline row">
<li class="list-inline-item col blockLabel">Date</li>
<li class="list-inline-item col-9 blockText">{{ transaction.transactionTimestamp * 1000 | date:'medium' }}</li>
</ul>
<ul *ngIf="transaction.transactionConfirmedInBlock" class="list-inline row">
<li class="list-inline-item col blockLabel">Block</li>
<li class="list-inline-item col-9 blockText">#{{ transaction.confirmedInBlock }}</li>
<li class="list-inline-item col-9 blockText">#{{ transaction.transactionConfirmedInBlock }}</li>
</ul>
<ul class="list-inline row">
<li class="list-inline-item col blockLabel">Confirmations</li>
<li class="list-inline-item col-9 blockText">{{ confirmations }}</li>
</ul>
<ul class="list-inline row">
<li class="list-inline-item col blockLabel mb-3">Transaction ID</li>
<li class="list-inline-item col-10 blockID"><code>{{ transaction.id }}</code></li>
<span class="float-right"><a ngxClipboard [cbContent]="transaction.id" (click)="onCopiedClick()">copy</a></span>
<li class="list-inline-item col-10 blockID"><code>{{ transaction.transactionId }}</code></li>
<span class="float-right"><a ngxClipboard [cbContent]="transaction.transactionId" (click)="onCopiedClick()">copy</a></span>
<div class="col-12">
<span class="badge badge-success list-inline-item col" *ngIf="copied">The transaction ID has been copied to your clipboard.</span>
</div>
......
import { Component, Input, OnInit } from '@angular/core';
import { Component, Input, OnInit, OnDestroy } from '@angular/core';
import { NgbModal, NgbActiveModal } from '@ng-bootstrap/ng-bootstrap';
import { Subscription } from 'rxjs/Subscription';
import { WalletInfo } from '../../shared/classes/wallet-info';
import { TransactionInfo } from '../../shared/classes/transaction-info';
import { ApiService } from '../../shared/services/api.service';
import { GlobalService } from '../../shared/services/global.service';
@Component({
selector: 'transaction-details',
templateUrl: './transaction-details.component.html',
styleUrls: ['./transaction-details.component.css']
})
export class TransactionDetailsComponent implements OnInit {
export class TransactionDetailsComponent implements OnInit, OnDestroy {
@Input() transaction;
constructor(public activeModal: NgbActiveModal) {}
@Input() transaction: TransactionInfo;
constructor(private apiService: ApiService, private globalService: GlobalService, public activeModal: NgbActiveModal) {}
public copied: boolean = false;
public coinUnit: string;
private generalWalletInfoSubscription: Subscription;
private lastBlockSyncedHeight: number;
private confirmations: number;
ngOnInit() {
this.startSubscriptions();
this.coinUnit = this.globalService.getCoinUnit();
}
ngOnDestroy() {
this.cancelSubscriptions();
}
public onCopiedClick() {
this.copied = true;
}
private getGeneralWalletInfo() {
let walletInfo = new WalletInfo(this.globalService.getWalletName())
this.generalWalletInfoSubscription = this.apiService.getGeneralInfo(walletInfo)
.subscribe(
response => {
if (response.status >= 200 && response.status < 400) {
let generalWalletInfoResponse = response.json();
this.lastBlockSyncedHeight = generalWalletInfoResponse.lastBlockSyncedHeight;
this.getConfirmations(this.transaction);
}
},
error => {
console.log(error);
if (error.status === 0) {
alert("Something went wrong while connecting to the API. Please restart the application.");
} else if (error.status >= 400) {
if (!error.json().errors[0]) {
console.log(error);
}
else {
if (error.json().errors[0].description) {
alert(error.json().errors[0].description);
} else {
this.cancelSubscriptions();
this.startSubscriptions();
}
}
}
}
)
;
};
private getConfirmations(transaction: TransactionInfo) {
if (transaction.transactionConfirmedInBlock) {
this.confirmations = this.lastBlockSyncedHeight - Number(transaction.transactionConfirmedInBlock) + 1;
} else {
this.confirmations = 0;
}
}
private cancelSubscriptions() {
if(this.generalWalletInfoSubscription) {
this.generalWalletInfoSubscription.unsubscribe();
}
};
private startSubscriptions() {
this.getGeneralWalletInfo();
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment