Commit 1ada87f5 authored by Pieterjan Vanhoof's avatar Pieterjan Vanhoof Committed by GitHub

Merge pull request #279 from stratisproject/design

Various UI improvements
parents 786e4ea6 b87dc1e7
......@@ -12,9 +12,11 @@ import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
import { LoginComponent } from './login/login.component';
import { GenericModalComponent } from './shared/components/generic-modal/generic-modal.component';
import { ApiService } from './shared/services/api.service';
import { GlobalService } from './shared/services/global.service';
import { ModalService } from './shared/services/modal.service';
import { SendComponent } from './wallet/send/send.component';
import { SendConfirmationComponent } from './wallet/send/send-confirmation/send-confirmation.component';
......@@ -37,6 +39,7 @@ import { LogoutConfirmationComponent } from './wallet/logout-confirmation/logout
],
declarations: [
AppComponent,
GenericModalComponent,
LoginComponent,
LogoutConfirmationComponent,
SendComponent,
......@@ -45,13 +48,14 @@ import { LogoutConfirmationComponent } from './wallet/logout-confirmation/logout
TransactionDetailsComponent
],
entryComponents: [
GenericModalComponent,
SendComponent,
SendConfirmationComponent,
ReceiveComponent,
TransactionDetailsComponent,
LogoutConfirmationComponent
],
providers: [ ApiService, GlobalService, Title ],
providers: [ ApiService, GlobalService, ModalService, Title ],
bootstrap: [ AppComponent ]
})
......
......@@ -4,6 +4,8 @@ import { Router } from '@angular/router';
import { GlobalService } from '../shared/services/global.service';
import { ApiService } from '../shared/services/api.service';
import { ModalService } from '../shared/services/modal.service';
import { WalletLoad } from '../shared/classes/wallet-load';
@Component({
......@@ -13,7 +15,7 @@ import { WalletLoad } from '../shared/classes/wallet-load';
})
export class LoginComponent implements OnInit {
constructor(private globalService: GlobalService, private apiService: ApiService, private router: Router, private fb: FormBuilder) {
constructor(private globalService: GlobalService, private apiService: ApiService, private genericModalService: ModalService, private router: Router, private fb: FormBuilder) {
this.buildDecryptForm();
}
......@@ -84,13 +86,13 @@ export class LoginComponent implements OnInit {
},
error => {
if (error.status === 0) {
alert("Something went wrong while connecting to the API. Please restart the application.");
this.genericModalService.openModal(null, null);
} else if (error.status >= 400) {
if (!error.json().errors[0]) {
console.log(error);
}
else {
alert(error.json().errors[0].message);
this.genericModalService.openModal(null, error.json().errors[0].message);
}
}
}
......@@ -137,13 +139,13 @@ export class LoginComponent implements OnInit {
error => {
this.isDecrypting = false;
if (error.status === 0) {
alert("Something went wrong while connecting to the API. Please restart the application.");
this.genericModalService.openModal(null, null);
} else if (error.status >= 400) {
if (!error.json().errors[0]) {
console.log(error);
}
else {
alert(error.json().errors[0].message);
this.genericModalService.openModal(null, error.json().errors[0].message);
}
}
},
......@@ -164,13 +166,13 @@ export class LoginComponent implements OnInit {
error => {
this.isDecrypting = false;
if (error.status === 0) {
alert("Something went wrong while connecting to the API. Please restart the application.");
this.genericModalService.openModal(null, null);
} else if (error.status >= 400) {
if (!error.json().errors[0]) {
console.log(error);
}
else {
alert(error.json().errors[0].message);
this.genericModalService.openModal(null, error.json().errors[0].message);
}
}
}
......
......@@ -4,6 +4,7 @@ import { Router } from '@angular/router';
import { GlobalService } from '../../shared/services/global.service';
import { ApiService } from '../../shared/services/api.service';
import { ModalService } from '../../shared/services/modal.service';
import { PasswordValidationDirective } from '../../shared/directives/password-validation.directive';
......@@ -17,7 +18,7 @@ import { Mnemonic } from '../../shared/classes/mnemonic';
})
export class CreateComponent implements OnInit {
constructor(private globalService: GlobalService, private apiService: ApiService, private router: Router, private fb: FormBuilder) {
constructor(private globalService: GlobalService, private apiService: ApiService, private genericModalService: ModalService, private router: Router, private fb: FormBuilder) {
this.buildCreateForm();
}
......@@ -125,13 +126,13 @@ export class CreateComponent implements OnInit {
error => {
console.log(error);
if (error.status === 0) {
alert("Something went wrong while connecting to the API. Please restart the application.");
this.genericModalService.openModal(null, null);
} else if (error.status >= 400) {
if (!error.json().errors[0]) {
console.log(error);
}
else {
alert(error.json().errors[0].message);
this.genericModalService.openModal(null, error.json().errors[0].message);
}
}
}
......@@ -152,13 +153,13 @@ export class CreateComponent implements OnInit {
console.log(error);
this.isCreating = false;
if (error.status === 0) {
alert("Something went wrong while connecting to the API. Please restart the application.");
this.genericModalService.openModal(null, null);
} else if (error.status >= 400) {
if (!error.json().errors[0]) {
console.log(error);
}
else {
alert(error.json().errors[0].message);
this.genericModalService.openModal(null, error.json().errors[0].message);
}
}
},
......@@ -173,7 +174,8 @@ export class CreateComponent implements OnInit {
.subscribe(
response => {
if (response.status >= 200 && response.status < 400){
alert("Your wallet has been created.\n\nPlease write down your 12 word passphrase: \n" + this.mnemonic + "\n\nYou can recover your wallet on any computer with:\n- your passphrase AND\n- your password AND\n- the wallet creation time\n\nUnlike most other wallets if an attacker acquires your passphrase, it will not be able to hack your wallet without knowing your password. On the contrary, unlike other wallets, you will not be able to recover your wallet only with your passphrase if you lose your password.");
let walletBody = "Your wallet has been created.<br><br>Please write down your 12 word passphrase: <br>" + this.mnemonic + "<br><br>You can recover your wallet on any computer with:<br>- your passphrase AND<br>- your password AND<br>- the wallet creation time<br><br>Unlike most other wallets if an attacker acquires your passphrase, it will not be able to hack your wallet without knowing your password. On the contrary, unlike other wallets, you will not be able to recover your wallet only with your passphrase if you lose your password.";
this.genericModalService.openModal("Wallet Info", walletBody);
this.router.navigate(['']);
}
},
......@@ -181,13 +183,13 @@ export class CreateComponent implements OnInit {
this.isCreating = false;
console.log(error);
if (error.status === 0) {
alert("Something went wrong while connecting to the API. Please restart the application.");
this.genericModalService.openModal(null, null);
} else if (error.status >= 400) {
if (!error.json().errors[0]) {
console.log(error);
}
else {
alert(error.json().errors[0].message);
this.genericModalService.openModal(null, error.json().errors[0].message);
}
}
}
......
......@@ -5,6 +5,7 @@ import { BsDatepickerConfig } from 'ngx-bootstrap/datepicker';
import { GlobalService } from '../../shared/services/global.service';
import { ApiService } from '../../shared/services/api.service';
import { ModalService } from '../../shared/services/modal.service';
import { WalletRecovery } from '../../shared/classes/wallet-recovery';
......@@ -15,7 +16,7 @@ import { WalletRecovery } from '../../shared/classes/wallet-recovery';
})
export class RecoverComponent implements OnInit {
constructor(private globalService: GlobalService, private apiService: ApiService, private router: Router, private fb: FormBuilder) {
constructor(private globalService: GlobalService, private apiService: ApiService, private genericModalService: ModalService, private router: Router, private fb: FormBuilder) {
this.buildRecoverForm();
}
......@@ -128,7 +129,7 @@ export class RecoverComponent implements OnInit {
this.isRecovering = false;
console.log(error);
if (error.status === 0) {
alert("Something went wrong while connecting to the API. Please restart the application.");
this.genericModalService.openModal(null, null);
} else if (error.status >= 400) {
if (!error.json().errors[0]) {
console.log(error);
......@@ -150,7 +151,8 @@ export class RecoverComponent implements OnInit {
.subscribe(
response => {
if (response.status >= 200 && response.status < 400) {
alert("Your wallet has been recovered. \nYou will be redirected to the decryption page.");
let body = "Your wallet has been recovered. \nYou will be redirected to the decryption page.";
this.genericModalService.openModal("Wallet Recovered", body);
this.router.navigate([''])
}
this.AlertIfNeeded(bitcoinErrorMessage, stratisErrorMessage);
......@@ -159,7 +161,7 @@ export class RecoverComponent implements OnInit {
this.isRecovering = false;
console.log(error);
if (error.status === 0) {
alert("Something went wrong while connecting to the API. Please restart the application.");
this.genericModalService.openModal(null, null);
} else if (error.status >= 400) {
if (!error.json().errors[0]) {
console.log(error);
......@@ -177,7 +179,7 @@ export class RecoverComponent implements OnInit {
private AlertIfNeeded(bitcoinErrorMessage: string, stratisErrorMessage: string) {
if(bitcoinErrorMessage !== "" || stratisErrorMessage !== "") {
let errorMessage = "Bitcoin wallet recovery:\n" + bitcoinErrorMessage + "\n\nStratis wallet recovery:\n" + stratisErrorMessage;
alert(errorMessage);
this.genericModalService.openModal(null, errorMessage);
}
}
}
export class TransactionBuilding {
constructor(walletName: string, coinType: number, accountName: string, password: string, destinationAddress: string, amount: string, feeType: string, allowUnconfirmed: boolean) {
constructor(walletName: string, accountName: string, password: string, destinationAddress: string, amount: string, feeType: string, allowUnconfirmed: boolean) {
this.walletName = walletName;
this.coinType = coinType;
this.accountName = accountName;
this.password = password;
this.destinationAddress = destinationAddress;
......@@ -12,7 +11,6 @@ export class TransactionBuilding {
}
walletName: string;
coinType: number;
accountName: string;
password: string;
destinationAddress: string;
......
<div id="modalGeneric" tabindex="-1">
<div class="modal-dialog modalBg">
<div>
<div class="modal-header">
<div class="bubble"><i class="icon-download"></i></div>
</div>
<div class="modal-body">
<h5 class="modal-title text-uppercase" id="modalReceive">{{ title }}</h5>
<div [innerHTML]="body">
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-lg btn-primary" (click)="activeModal.close('Close click')">OK</button>
</div>
</div>
</div>
</div>
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { GenericModalComponent } from './generic-modal.component';
describe('GenericModalComponent', () => {
let component: GenericModalComponent;
let fixture: ComponentFixture<GenericModalComponent>;
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [ GenericModalComponent ]
})
.compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(GenericModalComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});
import { Component, OnInit, Input } from '@angular/core';
import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap';
@Component({
selector: 'app-generic-modal',
templateUrl: './generic-modal.component.html',
styleUrls: ['./generic-modal.component.css']
})
export class GenericModalComponent implements OnInit {
@Input() public title: string = "Something went wrong";
@Input() public body: string = "Something went wrong while connecting to the API. Please restart the application.";
constructor(public activeModal: NgbActiveModal) {}
ngOnInit() {
}
}
......@@ -168,6 +168,23 @@ export class ApiService {
.map((response: Response) => response);
}
/**
* Get the maximum sendable amount for a given fee from the API
*/
getMaximumBalance(data): Observable<any> {
this.getCurrentCoin();
let params: URLSearchParams = new URLSearchParams();
params.set('walletName', data.walletName);
params.set('accountName', "account 0");
params.set('feeType', data.feeType);
params.set('allowUnconfirmed', "true");
return this.http
.get(this.currentApiUrl + '/wallet/maxbalance', new RequestOptions({headers: this.headers, search: params}))
.map((response: Response) => response);
}
/**
* Get a wallets transaction history info from the API.
*/
......
import {Injectable} from "@angular/core";
import { NgbModal, NgbActiveModal } from '@ng-bootstrap/ng-bootstrap';
import { GenericModalComponent } from '../components/generic-modal/generic-modal.component';
@Injectable()
export class ModalService {
constructor(private modalService: NgbModal) {}
public openModal(title, body) {
const modalRef = this.modalService.open(GenericModalComponent)
if (title) {
modalRef.componentInstance.title = title;
}
if (body) {
modalRef.componentInstance.body = body;
}
}
}
......@@ -4,14 +4,11 @@
<!-- JUMBOTRON-->
<div class="jumbotron jumbotron-fluid">
<div class="container">
<div class="col-xs-12 text-left">
<h5 class="text-capitalize walletName">{{ walletName }}</h5>
</div>
<div class="row d-flex align-items-center">
<div class="col-xs-12 col-md-3 text-left">
<h5>Active Wallet</h5>
<p class="lead">
<strong>{{ walletName }}</strong>
</p>
</div>
<div class="col-xs-12 col-md-3 text-left">
<div class="col-md-4 text-left">
<h5>Active balance</h5>
<p class="lead">
<!--<strong><span class="h2">29</span>.76500293</strong>-->
......@@ -28,7 +25,7 @@
<small class="text-uppercase">usd</small>
</p>
</div>-->
<div class="col-xs-12 col-md-3 text-left">
<div class="col-md-4 text-left">
<h5>Unconfirmed balance</h5>
<p class="lead">
<strong>{{ (unconfirmedBalance | coinNotation) || (0 | coinNotation) }}</strong>
......@@ -36,7 +33,7 @@
</p>
</div>
<!-- /col-->
<div class="col-xs-12 col-md-3 text-right">
<div class="col-md-4 text-right">
<p>
<a class="btn btn-secondary" data-toggle="modal" data-target="#modalReceive" role="button" (click)="openReceiveDialog()">Receive</a>
<a class="btn btn-primary ml-2" data-toggle="modal" data-target="#modalSend" role="button" (click)="openSendDialog()">Send</a>
......@@ -58,16 +55,18 @@
<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.transactionType }}</li>
<li class="list-inline-item col-4 amount text-left align-baseline">
<li class="list-inline-item hidden-xs-down col-2 text-uppercase align-bottom">{{ transaction.transactionType }}</li>
<li class="list-inline-item col-3 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 + transaction.transactionFee | coinNotation }}
<small class="text-uppercase">{{ coinUnit }}</small>
</li>
<li class="list-inline-item col amount text-left align-baseline">
<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>
<li class="list-inline-item col-3 text-right align-baseline transactionDate">{{ transaction.transactionTimestamp * 1000 | date:'medium' }}</li>
</ul>
</div>
</div>
......
......@@ -3,6 +3,7 @@ import { NgbModal, NgbActiveModal } from '@ng-bootstrap/ng-bootstrap';
import { ApiService } from '../../shared/services/api.service';
import { GlobalService } from '../../shared/services/global.service';
import { ModalService } from '../../shared/services/modal.service';
import { WalletInfo } from '../../shared/classes/wallet-info';
import { TransactionInfo } from '../../shared/classes/transaction-info';
......@@ -20,7 +21,7 @@ import { Subscription } from 'rxjs/Subscription';
})
export class DashboardComponent implements OnInit {
constructor(private apiService: ApiService, private globalService: GlobalService, private modalService: NgbModal) {}
constructor(private apiService: ApiService, private globalService: GlobalService, private modalService: NgbModal, private genericModalService: ModalService) {}
public walletName: string;
public coinUnit: string;
......@@ -68,14 +69,14 @@ export class DashboardComponent implements OnInit {
console.log(error);
if (error.status === 0) {
this.cancelSubscriptions();
alert("Something went wrong while connecting to the API. Please restart the application.");
this.genericModalService.openModal(null, null);
} 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);
this.genericModalService.openModal(null, error.json().errors[0].description);
} else {
this.cancelSubscriptions();
this.startSubscriptions();
......@@ -105,14 +106,14 @@ export class DashboardComponent implements OnInit {
console.log(error);
if (error.status === 0) {
this.cancelSubscriptions();
alert("Something went wrong while connecting to the API. Please restart the application.");
this.genericModalService.openModal(null, null);
} 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);
this.genericModalService.openModal(null, error.json().errors[0].description);
} else {
this.cancelSubscriptions();
this.startSubscriptions();
......
......@@ -3,6 +3,7 @@ import { NgbModal, NgbActiveModal } from '@ng-bootstrap/ng-bootstrap';
import { ApiService } from '../../shared/services/api.service';
import { GlobalService } from '../../shared/services/global.service';
import { ModalService } from '../../shared/services/modal.service';
import { WalletInfo } from '../../shared/classes/wallet-info';
import { TransactionInfo } from '../../shared/classes/transaction-info';
......@@ -19,7 +20,7 @@ import { TransactionDetailsComponent } from '../transaction-details/transaction-
})
export class HistoryComponent {
constructor(private apiService: ApiService, private globalService: GlobalService, private modalService: NgbModal) {}
constructor(private apiService: ApiService, private globalService: GlobalService, private modalService: NgbModal, private genericModalService: ModalService) {}
public transactions: TransactionInfo[];
public coinUnit: string;
......@@ -58,14 +59,14 @@ export class HistoryComponent {
console.log(error);
if (error.status === 0) {
this.cancelSubscriptions();
alert("Something went wrong while connecting to the API. Please restart the application.");
this.genericModalService.openModal(null, null);
} 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);
this.genericModalService.openModal(null, error.json().errors[0].description);
} else {
this.cancelSubscriptions();
this.startSubscriptions();
......
......@@ -2,6 +2,7 @@ import { Component, OnInit } from '@angular/core';
import { ApiService } from '../../shared/services/api.service';
import { GlobalService } from '../../shared/services/global.service';
import { ModalService } from '../../shared/services/modal.service';
import { WalletInfo } from '../../shared/classes/wallet-info';
......@@ -14,7 +15,7 @@ import { NgbModal, NgbActiveModal } from '@ng-bootstrap/ng-bootstrap';
})
export class ReceiveComponent {
constructor(private apiService: ApiService, private globalService: GlobalService, public activeModal: NgbActiveModal) {}
constructor(private apiService: ApiService, private globalService: GlobalService, public activeModal: NgbActiveModal, private genericModalService: ModalService) {}
public address: any = "";
public copied: boolean = false;
......@@ -40,13 +41,13 @@ export class ReceiveComponent {
error => {
console.log(error);
if (error.status === 0) {
alert("Something went wrong while connecting to the API. Please restart the application.");
this.genericModalService.openModal(null, null);
} else if (error.status >= 400) {
if (!error.json().errors[0]) {
console.log(error);
}
else {
alert(error.json().errors[0].description);
this.genericModalService.openModal(null, error.json().errors[0].description);
}
}
}
......
......@@ -9,8 +9,8 @@
<form [formGroup]="sendForm" (ngSubmit)="send()">
<!--<div class="form-group has-danger clearfix">-->
<div class="form-group clearfix">
<label class="float-left" for="yourAddress">Amount</label>
<!--<span class="float-right"><a href="#">max</a></span>-->
<label class="float-left" for="Amount">Amount</label>
<!-- <span class="float-right btn-link" (click)="getMaxBalance()">max</span> -->
<input type="text" class="form-control form-control-danger" formControlName="amount" id="Amount" placeholder="0.00 {{ coinUnit }}">
<div *ngIf="formErrors.amount" class="form-control-feedback">{{ formErrors.amount }}</div>
</div>
......@@ -20,36 +20,34 @@
<input type="text" class="form-control form-control-success" formControlName="address" id="destinationAddress" placeholder="Please enter the destination address here.">
<div *ngIf="formErrors.address" class="form-control-feedback">{{ formErrors.address }}</div>
</div>
<!-- <div class="form-group">
<label for="Fees">Fees</label>
<div class="col feeSlider text-center">
<input class="form-control" id="dataSlider" type="text"
data-provide="slider"
data-slider-ticks="[1, 2, 3]"
data-slider-ticks-labels='["Low", "Medium", "High"]'
data-slider-min="1"
data-slider-max="3"
data-slider-step="1"
data-slider-value="2"
data-slider-tooltip="hide">
</div>
<p class="text-muted text-center">
<em>A higher fee helps expedite your transaction.
<br>You are sending <strong>1 BTC</strong> with an included <strong>Medium</strong> fee of <strong>0.0001</strong>.</em>
</p>
</div> -->
<div class="form-group clearfix">
<label for="feeSlider">Fee</label>
<input class="form-control col text-center" formControlName="fee" type="range" min="1" max="3" value="2">
<label>Transaction Fee</label>
<!-- fee buttons -->
<div class="radioButtons" ngbRadioGroup name="feeButtons" formControlName="fee">
<label ngbButtonLabel class="btn btn-outline-danger">
<input ngbButton type="radio" value="low">Low/Slow
</label>
<label ngbButtonLabel class="btn btn-outline-warning">
<input ngbButton type="radio" value="medium">Medium
</label>
<label ngbButtonLabel class="btn btn-outline-success">
<input ngbButton type="radio" value="high">High/Fast
</label>
</div>
<!-- /fee buttons -->
</div>
<div class="form-group clearfix">
<div class="form-group clearfix">
<label for="walletPassword">Wallet Password</label>
<input type="password" class="form-control form-control-success" formControlName="password" id="walletPassword" placeholder="Please enter your wallet password.">
<div *ngIf="formErrors.password" class="form-control-feedback">{{formErrors.password}}</div>
</div>
<button type="button" class="btn btn-link" (click)="buildTransaction()" [disabled]="!sendForm.valid">Estimate Fee</button>
<label *ngIf="estimatedFee">Estimated Fee: </label>
<label *ngIf="estimatedFee">{{ estimatedFee | coinNotation }} {{ coinUnit }}</label>
<div class="form-group clearfix">
<button type="button" class="btn btn-link" (click)="buildTransaction()" [disabled]="!sendForm.valid">Estimate Fee</button>
<div *ngIf="estimatedFee">
<label>Estimated Fee: </label>
<label>{{ estimatedFee | coinNotation }} {{ coinUnit }}</label>
</div>
</div>
</form>
<!-- /form-->
</div>
......
import { Component, OnInit } from '@angular/core';
import { FormGroup, FormControl, Validators, FormBuilder } from '@angular/forms';
import { ApiService } from '../../shared/services/api.service';
import { GlobalService } from '../../shared/services/global.service';
import { FormGroup, FormControl, Validators, FormBuilder } from '@angular/forms';
import { ModalService } from '../../shared/services/modal.service';
import { NgbModal, NgbActiveModal } from '@ng-bootstrap/ng-bootstrap';
......@@ -17,7 +19,7 @@ import { SendConfirmationComponent } from './send-confirmation/send-confirmation
})
export class SendComponent implements OnInit {
constructor(private apiService: ApiService, private globalService: GlobalService, private modalService: NgbModal, public activeModal: NgbActiveModal, private fb: FormBuilder) {
constructor(private apiService: ApiService, private globalService: GlobalService, private modalService: NgbModal, private genericModalService: ModalService, public activeModal: NgbActiveModal, private fb: FormBuilder) {
this.buildSendForm();
}
......@@ -38,7 +40,7 @@ export class SendComponent implements OnInit {
this.sendForm = this.fb.group({
"address": ["", Validators.required],
"amount": ["", Validators.compose([Validators.required, Validators.pattern(/^[0-9]+(\.[0-9]{0,8})?$/)])],
"fee": [2, Validators.required],
"fee": ["medium", Validators.required],
"password": ["", Validators.required]
});
......@@ -86,15 +88,51 @@ export class SendComponent implements OnInit {
}
};
public getMaxBalance() {
let data = {
walletName: this.globalService.getWalletName(),
feeType: this.sendForm.get("fee").value
}
let balanceResponse;
this.apiService
.getMaximumBalance(data)
.subscribe(
response => {
if (response.status >= 200 && response.status < 400){
balanceResponse = response.json();
console.log(balanceResponse);
}
},
error => {
console.log(error);
if (error.status === 0) {
this.genericModalService.openModal(null, "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 {
this.genericModalService.openModal(null, error.json().errors[0].description);
}
}
},
() => {
this.sendForm.patchValue({amount: balanceResponse.maxSpendableAmount});
this.estimatedFee = balanceResponse.fee;
}
)
};
public buildTransaction() {
this.transaction = new TransactionBuilding(
this.globalService.getWalletName(),
this.globalService.getCoinType(),
"account 0",
this.sendForm.get("password").value,
this.sendForm.get("address").value,
this.sendForm.get("amount").value,
this.getFeeType(),
this.sendForm.get("fee").value,
true
);
......@@ -109,13 +147,13 @@ export class SendComponent implements OnInit {
error => {
console.log(error);
if (error.status === 0) {
alert("Something went wrong while connecting to the API. Please restart the application.");
this.genericModalService.openModal(null, null);
} else if (error.status >= 400) {
if (!error.json().errors[0]) {
console.log(error);
}
else {
alert(error.json().errors[0].description);
this.genericModalService.openModal(null, error.json().errors[0].description);
}
}
},
......@@ -149,13 +187,13 @@ export class SendComponent implements OnInit {
console.log(error);
this.isSending = false;
if (error.status === 0) {
alert("Something went wrong while connecting to the API. Please restart the application.");
this.genericModalService.openModal(null, null);
} else if (error.status >= 400) {
if (!error.json().errors[0]) {
console.log(error);
}
else {
alert(error.json().errors[0].description);
this.genericModalService.openModal(null, error.json().errors[0].description);
}
}
},
......@@ -164,19 +202,6 @@ export class SendComponent implements OnInit {
;
}
private getFeeType(){
let feeValue = this.sendForm.get("fee").value;
switch(feeValue){
case 1:
return "low";
case 2:
return "medium";
case 3:
return "high";
}
}
private openConfirmationModal() {
const modalRef = this.modalService.open(SendConfirmationComponent);
modalRef.componentInstance.transaction = this.transaction;
......
import { Component, OnInit, OnDestroy } from '@angular/core';
import { Observable } from 'rxjs/Rx';
import { Subscription } from 'rxjs/Subscription';
import { ApiService } from '../../shared/services/api.service';
import { GlobalService } from '../../shared/services/global.service';
import { WalletInfo } from '../../shared/classes/wallet-info';
import { ModalService } from '../../shared/services/modal.service';
import { Observable } from 'rxjs/Rx';
import { Subscription } from 'rxjs/Subscription';
import { WalletInfo } from '../../shared/classes/wallet-info';
@Component({
selector: 'status-bar',
......@@ -22,7 +24,7 @@ export class StatusBarComponent implements OnInit {
private percentSyncedNumber: number = 0;
public percentSynced: string;
constructor(private apiService: ApiService, private globalService: GlobalService) { }
constructor(private apiService: ApiService, private globalService: GlobalService, private genericModalService: ModalService) { }
ngOnInit() {
this.startSubscriptions();
......@@ -61,14 +63,14 @@ export class StatusBarComponent implements OnInit {
console.log(error);
if (error.status === 0) {
this.cancelSubscriptions();
alert("Something went wrong while connecting to the API. Please restart the application.");
this.genericModalService.openModal(null, null);
} 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);
this.genericModalService.openModal(null, error.json().errors[0].description);
} else {
this.cancelSubscriptions();
this.startSubscriptions();
......
......@@ -8,28 +8,28 @@
<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.transactionType }}</li>
<li class="list-inline-item col-8 blockText text-capitalize">{{ transaction.transactionType }}</li>
</ul>
<ul class="list-inline row">
<li class="list-inline-item col blockLabel">Amount</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 + transaction.transactionFee | coinNotation }} {{ coinUnit }}</li>
<li *ngIf="transaction.transactionType == 'received'" class="list-inline-item col-8 blockText text-success">{{ transaction.transactionAmount | coinNotation }} {{ coinUnit }}</li>
<li *ngIf="transaction.transactionType == 'sent'" class="list-inline-item col-8 blockText text-danger">-{{ transaction.transactionAmount + transaction.transactionFee | coinNotation }} {{ coinUnit }}</li>
</ul>
<!-- <ul class="list-inline row" *ngIf="transaction.transactionType == 'sent'">
<li class="list-inline-item col blockLabel">Fee</li>
<li *ngIf="transaction.transactionType == 'sent'" class="list-inline-item col-9 blockText text-danger">{{ transaction.transactionFee | coinNotation }} {{ coinUnit }}</li>
<li *ngIf="transaction.transactionType == 'sent'" class="list-inline-item col-8 blockText text-danger">{{ transaction.transactionFee | coinNotation }} {{ coinUnit }}</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>
<li class="list-inline-item col-8 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.transactionConfirmedInBlock }}</li>
<li class="list-inline-item col-8 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>
<li class="list-inline-item col-8 blockText">{{ confirmations }}</li>
</ul>
<ul class="list-inline row">
<li class="list-inline-item col blockLabel mb-3">Transaction ID</li>
......
......@@ -2,10 +2,12 @@ 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';
import { ModalService } from '../../shared/services/modal.service';
import { WalletInfo } from '../../shared/classes/wallet-info';
import { TransactionInfo } from '../../shared/classes/transaction-info';
@Component({
selector: 'transaction-details',
......@@ -15,7 +17,7 @@ import { GlobalService } from '../../shared/services/global.service';
export class TransactionDetailsComponent implements OnInit, OnDestroy {
@Input() transaction: TransactionInfo;
constructor(private apiService: ApiService, private globalService: GlobalService, public activeModal: NgbActiveModal) {}
constructor(private apiService: ApiService, private globalService: GlobalService, private genericModalService: ModalService, public activeModal: NgbActiveModal) {}
public copied: boolean = false;
public coinUnit: string;
......@@ -50,14 +52,14 @@ export class TransactionDetailsComponent implements OnInit, OnDestroy {
error => {
console.log(error);
if (error.status === 0) {
alert("Something went wrong while connecting to the API. Please restart the application.");
this.genericModalService.openModal(null, null);
} 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);
this.genericModalService.openModal(null, error.json().errors[0].description);
} else {
this.cancelSubscriptions();
this.startSubscriptions();
......
import { CommonModule } from '@angular/common';
import { NgModule } from '@angular/core';
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
import { NgbDropdownModule } from '@ng-bootstrap/ng-bootstrap';
import { NgbModule } from '@ng-bootstrap/ng-bootstrap';
import { ClipboardModule } from 'ngx-clipboard';
import { WalletComponent } from './wallet.component';
......@@ -21,7 +21,7 @@ import { TransactionDetailsComponent } from './transaction-details/transaction-d
ClipboardModule,
FormsModule,
SharedModule.forRoot(),
NgbDropdownModule,
NgbModule,
ReactiveFormsModule,
WalletRoutingModule
],
......
......@@ -30,7 +30,7 @@
&.disabled,
&:disabled {
cursor: $cursor-disabled;
opacity: 1;
opacity: 0;
@include box-shadow(none);
}
......
......@@ -15,8 +15,8 @@ a, button {
}
button {
&:disabled {
background: #EFEFEF !important;
border-color: #EFEFEF !important;
background: lighten($gray,20%) !important;
border-color: lighten($gray,20%) !important;
&:hover {cursor: not-allowed !important;}
}
}
......@@ -136,6 +136,14 @@ em {
h5 {
font-size: .85em;
color: $gray-dark;
margin-bottom: 0;
&.walletName {
color: $black;
font-size: 1em;
font-weight: bolder;
margin-bottom: 1.5em;
}
}
p {margin-bottom: 0 !important;}
.lead {
......@@ -143,12 +151,13 @@ em {
font-size: 1.85em;
font-weight: 500;
margin-bottom: 0;
.h2 {
font-size: 2em;
font-weight: 600;
}
small {
font-size: .75em;
font-size: .5em;
padding-left: .5em;
font-weight: 400;
}
......@@ -248,26 +257,34 @@ em {
}
}
#modalSend {
label {
label {font-size: .825em;}
.float-right {a {text-decoration: underline; &:hover {text-decoration: none;}}}
// Fee Buttons
.radioButtons {
.btn {
border-radius: 50px;
}
}
p {
color: $blue;
text-transform: uppercase;
font-size: .825em;
font-style: italic;
}
.btn-link {padding: 0 !important;}
.btn-primary {
&:disabled {opacity: 1 !important;}
}
.float-right {a {text-decoration: underline; &:hover {text-decoration: none;}}}
}
#modalReceive {
.modal-body {padding: 0 3em;}
label {
color: $blue;
text-transform: uppercase;
font-size: .825em;
}
label {font-size: .825em;}
}
#modalDetail, #modalCheck, #modalSettings {
.blockLabel {
color: $blue;
text-transform: uppercase;
font-size: .825em;
line-height: 2em;
}
.blockText {
color: $darkgray;
......
......@@ -51,7 +51,7 @@
background-color: $dropdown-bg;
background-clip: padding-box;
border: $dropdown-border-width solid $dropdown-border-color;
@include border-radius($border-radius);
border-radius: 50px;
@include box-shadow($dropdown-box-shadow);
}
......
......@@ -5,7 +5,7 @@
@include border-radius($border-radius-lg);
@include media-breakpoint-up(sm) {
padding: ($jumbotron-padding * 2) $jumbotron-padding;
padding: $jumbotron-padding $jumbotron-padding;
}
}
......
......@@ -91,7 +91,7 @@
.modal-title {
text-align: center;
line-height: $modal-title-line-height;
margin-bottom: 2em;
margin-bottom: 1em;
color: $blue;
font-size: 1em;
}
......
......@@ -798,8 +798,8 @@ $badge-pill-border-radius: 10rem !default;
// Padding applied to the modal body
$modal-inner-padding: 3em !default;
$modal-dialog-margin: 30px !default;
$modal-dialog-sm-up-margin-y: 30px !default;
$modal-dialog-margin: 20px !default;
$modal-dialog-sm-up-margin-y: 20px !default;
$modal-title-line-height: $line-height-base !default;
......
......@@ -17,8 +17,8 @@ a:hover, button:hover {
}
button:disabled {
background: #EFEFEF !important;
border-color: #EFEFEF !important;
background: #d3d7de !important;
border-color: #d3d7de !important;
}
button:disabled:hover {
......@@ -161,6 +161,14 @@ em.display-4 {
.jumbotron h5 {
font-size: .85em;
color: #878685;
margin-bottom: 0;
}
.jumbotron h5.walletName {
color: #444;
font-size: 1em;
font-weight: bolder;
margin-bottom: 1.5em;
}
.jumbotron p {
......@@ -180,7 +188,7 @@ em.display-4 {
}
.jumbotron .lead small {
font-size: .75em;
font-size: .5em;
padding-left: .5em;
font-weight: 400;
}
......@@ -292,8 +300,6 @@ em.display-4 {
}
#modalSend label {
color: #7385A0;
text-transform: uppercase;
font-size: .825em;
}
......@@ -305,13 +311,29 @@ em.display-4 {
text-decoration: none;
}
#modalSend .radioButtons .btn {
border-radius: 50px;
}
#modalSend p {
color: #7385A0;
font-size: .825em;
font-style: italic;
}
#modalSend .btn-link {
padding: 0 !important;
}
#modalSend .btn-primary:disabled {
opacity: 1 !important;
}
#modalReceive .modal-body {
padding: 0 3em;
}
#modalReceive label {
color: #7385A0;
text-transform: uppercase;
font-size: .825em;
}
......@@ -319,6 +341,7 @@ em.display-4 {
color: #7385A0;
text-transform: uppercase;
font-size: .825em;
line-height: 2em;
}
#modalDetail .blockText, #modalCheck .blockText, #modalSettings .blockText {
......@@ -3251,7 +3274,7 @@ select.form-control-lg:not([size]):not([multiple]), .input-group-lg > select.for
.btn.disabled, .btn:disabled {
cursor: not-allowed;
opacity: 1;
opacity: 0;
}
.btn:active, .btn.active {
......@@ -3779,7 +3802,7 @@ tbody.collapse.show {
background-color: #fff;
background-clip: padding-box;
border: 1px solid rgba(68, 68, 68, 0.15);
border-radius: 0.25rem;
border-radius: 50px;
}
.dropdown-divider {
......@@ -5300,7 +5323,7 @@ a.badge:focus, a.badge:hover {
@media (min-width: 576px) {
.jumbotron {
padding: 3.5rem 1.75rem;
padding: 1.75rem 1.75rem;
}
}
......@@ -5752,7 +5775,7 @@ button.close {
.modal-dialog {
position: relative;
width: auto;
margin: 30px;
margin: 20px;
}
.modalBg {
......@@ -5797,7 +5820,7 @@ button.close {
.modal-title {
text-align: center;
line-height: 1.5;
margin-bottom: 2em;
margin-bottom: 1em;
color: #7385A0;
font-size: 1em;
}
......@@ -5834,7 +5857,7 @@ button.close {
@media (min-width: 576px) {
.modal-dialog {
max-width: 500px;
margin: 30px auto;
margin: 20px auto;
}
.modal-sm {
max-width: 360px;
......
This source diff could not be displayed because it is too large. You can view the blob instead.
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