Commit 5348e6f7 authored by Paul Herbert's avatar Paul Herbert

2100 - Breeze ICO updates: functionality complete, first-cut

parent b1355d6a
......@@ -58,7 +58,6 @@
"core-js": "2.5.3",
"electron-context-menu": "0.9.1",
"enhanced-resolve": "3.4.1",
"ng2-datepicker": "^3.1.0",
"ngx-bootstrap": "2.0.0-beta.11",
"ngx-clipboard": "9.0.0",
"rxjs": "5.5.5",
......
......@@ -17,6 +17,7 @@ import { GenericModalComponent } from './shared/components/generic-modal/generic
import { ApiService } from './shared/services/api.service';
import { GlobalService } from './shared/services/global.service';
import { ModalService } from './shared/services/modal.service';
import { NavigationService } from './shared/services/navigation.service';
import { SendComponent } from './wallet/send/send.component';
import { SendConfirmationComponent } from './wallet/send/send-confirmation/send-confirmation.component';
......@@ -55,7 +56,7 @@ import { LogoutConfirmationComponent } from './wallet/logout-confirmation/logout
TransactionDetailsComponent,
LogoutConfirmationComponent
],
providers: [ ApiService, GlobalService, ModalService, Title ],
providers: [ NavigationService, ApiService, GlobalService, ModalService, Title ],
bootstrap: [ AppComponent ]
})
......
import { Injectable } from '@angular/core';
import { Router, Event, NavigationEnd } from '@angular/router';
import { filter } from 'rxjs/operator/filter';
import { map } from 'rxjs/operator/map';
import { ReplaySubject } from 'rxJs/ReplaySubject';
export enum Page {
Bitcoin, Stratis
}
@Injectable()
export class NavigationService {
private readonly navBase = '/wallet';
constructor(router: Router) {
const navigation$ = router.events.filter(x => x instanceof NavigationEnd)
.map(x => <NavigationEnd>x)
.map(x => x.url);
navigation$.filter(x => x === this.navBase).subscribe(_ => this.pageSubject.next(Page.Bitcoin));
navigation$.filter(x => x === `${this.navBase}/stratis-wallet`).subscribe(_ => this.pageSubject.next(Page.Stratis));
}
public pageSubject = new ReplaySubject(1);
}
<div class="mainDiv">
<form [formGroup]='icoFormGroup'>
<div style="margin-top:15px">
<div style="margin-top:20px">
<div>
<label style="font-size:14px;margin-bottom:0px">Extended Public Key</label>
......@@ -12,40 +12,32 @@
</ng-template>
</div>
<div style="margin-top:30px">
<label style="font-size:14px;margin-bottom:1px">Generate Addresses</label>
<div style="display:flex; flex-direction:row">
<div class="input-group" style="height:35px; margin-bottom:1px; width:240px">
<input formControlName="addressCountControl" type="text" class="form-control" placeholder="Number to generate..." style="border-radius: 0px">
<span class="input-group-btn">
<div>
<button *ngIf="!addressCountControl.invalid && addressCount" (click)="generateAddresses()" class="btn btn-default" type="button">Go</button>
<button *ngIf="addressCountControl.invalid || !addressCount" style="color: gray; outline:none" class="btn btn-default" type="button">Go</button>
</div>
</span>
<div style="display: flex; flex-direction: row; margin-top:30px">
<div style="width:275px">
<label style="font-size:14px;margin-bottom:1px">Generate Addresses</label>
<div style="display:flex; flex-direction:row; height:34px">
<input formControlName="addressCountControl" type="text" class="form-control" placeholder="Number to generate..." style="border-radius: 0px; width: 163px">
<button *ngIf="!addressCountControl.invalid && addressCount" [disabled]="addressCountControl.invalid || !addressCount" (click)="generateAddresses()"
class="btn btn-darkgray btn-sm" type="button" style="margin-left: 5px">Go</button>
<img style="width:16px; height:16px; margin-left:6px; margin-top:8px" *ngIf="showAddressesTick" src="../../../assets/images/Tick_Mark-16.png"
/>
<app-feedback *ngIf="!generateAddressesLoadingState.success" style="margin-left:5px; width:115px" [loading]="generateAddressesLoadingState.loading"
[errored]="generateAddressesLoadingState.errored" [erroredText]="'Failed'"></app-feedback>
</div>
<img style="width:16px; height:16px; margin-left:6px" *ngIf="showAddressesTick" src="../../../assets/images/Tick_Mark-16.png"
/>
<app-feedback *ngIf="!generateAddressesLoadingState.success" style="margin-left:5px; width:115px" [loading]="generateAddressesLoadingState.loading"
[errored]="generateAddressesLoadingState.errored" [erroredText]="'Failed to generate'"></app-feedback>
</div>
</div>
<div style="margin-top:30px">
<label style="font-size:14px;margin-bottom:1px">Resync</label>
<div style="display:flex; flex-direction:row">
<div class="input-group" style="height:35px; margin-bottom:1px; width:240px">
<ng-datepicker style="width:163px" [(ngModel)]="resyncDate" [options]="resyncDateOptions" formControlName="datePickerControl"></ng-datepicker>
<span class="input-group-btn">
<div>
<button style="height: 35px" (click)="resync()" class="btn btn-default" type="button">Go</button>
</div>
</span>
<div style="margin-left: 30px">
<label style="font-size:14px;margin-bottom:1px">Resync</label>
<div style="display:flex; flex-direction:row">
<ngb-datepicker [(ngModel)]="resyncDate" [outsideDays]="hidden" [minDate]="minResyncDate" [maxDate]="maxResyncDate" style="outline:none; border:none"
formControlName="datePickerControl"></ngb-datepicker>
<button [disabled]="!resyncDate" style="margin-left: 5px; align-self:flex-start; height:34px" (click)="resync()" class="btn btn-darkgray btn-sm"
type="button">Go</button>
<img style="width:16px; height:16px; margin-left:6px; margin-top:8px" *ngIf="showResyncTick" src="../../../assets/images/Tick_Mark-16.png"
/>
<app-feedback *ngIf="!resyncLoadingState.success" style="margin-left:5px; width:65px" [loading]="resyncLoadingState.loading"
[errored]="resyncLoadingState.errored" [erroredText]="'Failed'"></app-feedback>
</div>
<img style="width:16px; height:16px; margin-left:6px" *ngIf="showResyncTick" src="../../../assets/images/Tick_Mark-16.png"
/>
<app-feedback *ngIf="!resyncLoadingState.success" style="margin-left:5px; width:115px" [loading]="resyncLoadingState.loading"
[errored]="resyncLoadingState.errored" [erroredText]="'Failed to sync'"></app-feedback>
</div>
</div>
......
import { Component, OnInit, OnDestroy, Input } from '@angular/core';
import { Subscription } from 'rxJs/Subscription';
import { FormGroup, Validators, FormBuilder } from '@angular/forms';
import { DatepickerOptions } from 'ng2-datepicker';
import { NgbDateStruct } from '@ng-bootstrap/ng-bootstrap';
import { AdvancedService } from './advanced.service';
import { LoadingState } from './loadingState';
......@@ -23,23 +23,23 @@ export class AdvancedComponent implements OnInit, OnDestroy {
public icoFormGroup: FormGroup;
public extPubKey = "";
public resyncDate = new Date();
public resyncDate: NgbDateStruct;
public extPubKeyLoadingState = new LoadingState();
public generateAddressesLoadingState = new LoadingState();
public resyncDateOptions: DatepickerOptions;
public resyncLoadingState = new LoadingState();
public maxResyncDate: NgbDateStruct;
public minResyncDate: NgbDateStruct;
public get datePickerControl() { return this.icoFormGroup.get('datePickerControl'); }
public get addressCountControl() { return this.icoFormGroup.get('addressCountControl'); }
public get showAddressesTick() {
return this.generateAddressesLoadingState.success && this.addresses.length && (Number(this.addressCount)===this.addresses.length);
}
public get showAddressesTick() { return this.generateAddressesLoadingState.success &&
this.addresses.length && (Number(this.addressCount)===this.addresses.length); }
public get showResyncTick(): boolean { return this.resyncLoadingState.success && this.resyncActioned; }
ngOnInit() {
this.registerFormControls();
this.setResyncDateOptions();
this.loadExtPubKey();
this.setResyncDates();
}
public generateAddresses() {
......@@ -58,11 +58,18 @@ export class AdvancedComponent implements OnInit, OnDestroy {
this.resyncSubs.unsubscribe();
}
this.resyncLoadingState.loading = this.resyncActioned = true;
this.resyncSubs = this.advancedService.resyncFromDate(this.resyncDate)
const date = new Date(this.resyncDate.year, this.resyncDate.month-1, this.resyncDate.day);
this.resyncSubs = this.advancedService.resyncFromDate(date)
.subscribe(_ => this.onResync(),
_ => this.resyncLoadingState.errored = true);
}
private setResyncDates() {
const now = new Date();
this.maxResyncDate = {year: now.getFullYear(), month: now.getMonth()+1, day: now.getDate()}
this.minResyncDate = {year: now.getFullYear(), month: 1, day: 1}
}
private loadExtPubKey() {
this.extPubKeyLoadingState.loading = true;
this.extPubKeySubs = this.advancedService.getExtPubKey()
......@@ -99,15 +106,6 @@ export class AdvancedComponent implements OnInit, OnDestroy {
});
}
private setResyncDateOptions() {
const today = new Date();
this.resyncDateOptions = {
minDate: new Date(today.getFullYear(),0),
maxDate: today,
displayFormat: 'MMMM D[,] YYYY'
};
}
ngOnDestroy() {
if (this.extPubKeySubs) {
this.extPubKeySubs.unsubscribe();
......
import { Injectable } from '@angular/core';
import { Observable } from 'rxjs/Observable';
import { HttpClient } from '@angular/common/http';
import { HttpClient, HttpHeaders } from '@angular/common/http';
import 'rxjs/add/observable/empty';
import { GlobalService } from '../../shared/services/global.service';
import { NavigationService, Page } from '../../shared/services/navigation.service';
class dateRequest {
constructor(public date: Date){}
}
@Injectable()
export class AdvancedService {
private readonly accountName = 'account 0';
private urlPrefix = '';
private readonly walletName;
private readonly urlPrefix = 'http://localhost:37221/api/Wallet/';
private readonly accountName = 'account 0';
private headers = new HttpHeaders({'Content-Type': 'application/json'});
constructor(private httpClient: HttpClient, private globalService: GlobalService) {
constructor(private httpClient: HttpClient, private globalService: GlobalService, navigationService: NavigationService) {
this.walletName = this.globalService.getWalletName();
navigationService.pageSubject.subscribe(x =>
this.urlPrefix = `http://localhost:3722${Page.Bitcoin ? 0 : 1}/api/Wallet/`);
}
public getExtPubKey(): Observable<string> {
......@@ -26,7 +35,10 @@ export class AdvancedService {
}
public resyncFromDate(date: Date): Observable<any> {
return Observable.empty<any>();
date = new Date(date.getFullYear(), date.getMonth(), date.getDate()); //<- Strip any time values
const url = `${this.urlPrefix}syncfromdate`;
const data = JSON.stringify(new dateRequest(date));
return this.httpClient.post(url, data, {headers: this.headers}).map((x: Response) => x);
}
private processAddresses(response: any): string[] {
......
<div>
<div class="progress" *ngIf="loading">
<div class="progress-bar progress-bar-striped progress-bar-animated"
role="progressbar" aria-valuenow="100" aria-valuemin="0" aria-valuemax="100" style="width: 100%">
Working...
<div class="progress" *ngIf="loading">
<div class="progress-bar progress-bar-striped progress-bar-animated" role="progressbar" aria-valuenow="100"
aria-valuemin="0" aria-valuemax="100" style="width: 100%">
<label style="font-size:10px">Working...</label>
</div>
</div>
<div class="alert alert-danger" role="alert" *ngIf="errored">
{{erroredText}}
<label>{{erroredText}}</label>
</div>
</div>
</div>
\ No newline at end of file
......@@ -95,8 +95,9 @@ export class DashboardComponent implements OnInit {
.subscribe(
response => {
if (response.status >= 200 && response.status < 400) {
if (response.json().transactionsHistory.length > 0) {
historyResponse = response.json().transactionsHistory;
const json = response.json();
if (json.transactionsHistory) {
historyResponse = json.transactionsHistory;
this.getTransactionInfo(historyResponse);
}
}
......
......@@ -6,6 +6,7 @@ import { Router } from '@angular/router';
import { ApiService } from '../../shared/services/api.service';
import { GlobalService } from '../../shared/services/global.service';
import { ModalService } from '../../shared/services/modal.service';
import { NavigationService } from '../../shared/services/navigation.service';
import { WalletInfo } from '../../shared/classes/wallet-info';
......@@ -16,7 +17,9 @@ import { WalletInfo } from '../../shared/classes/wallet-info';
})
export class SidebarComponent implements OnInit {
constructor(private globalService: GlobalService, private apiService: ApiService, private router: Router, private modalService: NgbModal, private genericModalService: ModalService) { }
constructor(private globalService: GlobalService, private apiService: ApiService,
private router: Router, private modalService: NgbModal, private genericModalService: ModalService,
private navigationService: NavigationService) { }
public bitcoinActive: boolean;
public stratisActive: boolean;
......
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