Bisq: Feature to filter transaction types.
This commit is contained in:
parent
24182a6fb3
commit
7f71781916
@ -39,8 +39,12 @@ class Bisq {
|
|||||||
return this.transactionIndex[txId];
|
return this.transactionIndex[txId];
|
||||||
}
|
}
|
||||||
|
|
||||||
getTransactions(start: number, length: number): [BisqTransaction[], number] {
|
getTransactions(start: number, length: number, types: string[]): [BisqTransaction[], number] {
|
||||||
return [this.transactions.slice(start, length + start), this.transactions.length];
|
let transactions = this.transactions;
|
||||||
|
if (types.length) {
|
||||||
|
transactions = transactions.filter((tx) => types.indexOf(tx.txType) > -1);
|
||||||
|
}
|
||||||
|
return [transactions.slice(start, length + start), transactions.length];
|
||||||
}
|
}
|
||||||
|
|
||||||
getBlock(hash: string): BisqBlock | undefined {
|
getBlock(hash: string): BisqBlock | undefined {
|
||||||
|
@ -108,9 +108,21 @@ class Routes {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public getBisqTransactions(req: Request, res: Response) {
|
public getBisqTransactions(req: Request, res: Response) {
|
||||||
|
const types: string[] = [];
|
||||||
|
if (req.query.types && !Array.isArray(req.query.types)) {
|
||||||
|
res.status(500).send('Types is not an array');
|
||||||
|
return;
|
||||||
|
} else {
|
||||||
|
for (const _type in req.query.types) {
|
||||||
|
if (typeof req.query.types[_type] === 'string') {
|
||||||
|
types.push(req.query.types[_type].toString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const index = parseInt(req.params.index, 10) || 0;
|
const index = parseInt(req.params.index, 10) || 0;
|
||||||
const length = parseInt(req.params.length, 10) > 100 ? 100 : parseInt(req.params.length, 10) || 25;
|
const length = parseInt(req.params.length, 10) > 100 ? 100 : parseInt(req.params.length, 10) || 25;
|
||||||
const [transactions, count] = bisq.getTransactions(index, length);
|
const [transactions, count] = bisq.getTransactions(index, length, types);
|
||||||
res.header('X-Total-Count', count.toString());
|
res.header('X-Total-Count', count.toString());
|
||||||
res.json(transactions);
|
res.json(transactions);
|
||||||
}
|
}
|
||||||
|
@ -1,9 +1,7 @@
|
|||||||
import { BrowserModule } from '@angular/platform-browser';
|
import { BrowserModule } from '@angular/platform-browser';
|
||||||
import { NgModule } from '@angular/core';
|
import { NgModule } from '@angular/core';
|
||||||
import { HttpClientModule } from '@angular/common/http';
|
import { HttpClientModule } from '@angular/common/http';
|
||||||
import { ReactiveFormsModule } from '@angular/forms';
|
|
||||||
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
|
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
|
||||||
import { NgbButtonsModule, NgbPaginationModule, NgbDropdownModule } from '@ng-bootstrap/ng-bootstrap';
|
|
||||||
import { InfiniteScrollModule } from 'ngx-infinite-scroll';
|
import { InfiniteScrollModule } from 'ngx-infinite-scroll';
|
||||||
|
|
||||||
import { AppRoutingModule } from './app-routing.module';
|
import { AppRoutingModule } from './app-routing.module';
|
||||||
@ -76,11 +74,7 @@ import { SharedModule } from './shared/shared.module';
|
|||||||
BrowserModule,
|
BrowserModule,
|
||||||
AppRoutingModule,
|
AppRoutingModule,
|
||||||
HttpClientModule,
|
HttpClientModule,
|
||||||
ReactiveFormsModule,
|
|
||||||
BrowserAnimationsModule,
|
BrowserAnimationsModule,
|
||||||
NgbButtonsModule,
|
|
||||||
NgbPaginationModule,
|
|
||||||
NgbDropdownModule,
|
|
||||||
InfiniteScrollModule,
|
InfiniteScrollModule,
|
||||||
SharedModule,
|
SharedModule,
|
||||||
],
|
],
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import { Injectable } from '@angular/core';
|
import { Injectable } from '@angular/core';
|
||||||
import { HttpClient, HttpResponse } from '@angular/common/http';
|
import { HttpClient, HttpResponse, HttpParams } from '@angular/common/http';
|
||||||
import { Observable } from 'rxjs';
|
import { Observable } from 'rxjs';
|
||||||
import { BisqTransaction, BisqBlock, BisqStats } from './bisq.interfaces';
|
import { BisqTransaction, BisqBlock, BisqStats } from './bisq.interfaces';
|
||||||
|
|
||||||
@ -23,8 +23,12 @@ export class BisqApiService {
|
|||||||
return this.httpClient.get<BisqTransaction>(API_BASE_URL + '/tx/' + txId);
|
return this.httpClient.get<BisqTransaction>(API_BASE_URL + '/tx/' + txId);
|
||||||
}
|
}
|
||||||
|
|
||||||
listTransactions$(start: number, length: number): Observable<HttpResponse<BisqTransaction[]>> {
|
listTransactions$(start: number, length: number, types: string[]): Observable<HttpResponse<BisqTransaction[]>> {
|
||||||
return this.httpClient.get<BisqTransaction[]>(API_BASE_URL + `/txs/${start}/${length}`, { observe: 'response' });
|
let params = new HttpParams();
|
||||||
|
types.forEach((t: string) => {
|
||||||
|
params = params.append('types[]', t);
|
||||||
|
});
|
||||||
|
return this.httpClient.get<BisqTransaction[]>(API_BASE_URL + `/txs/${start}/${length}`, { params, observe: 'response' });
|
||||||
}
|
}
|
||||||
|
|
||||||
getBlock$(hash: string): Observable<BisqBlock> {
|
getBlock$(hash: string): Observable<BisqBlock> {
|
||||||
|
@ -1,5 +1,61 @@
|
|||||||
<div class="container-xl">
|
<div class="container-xl">
|
||||||
<h1 style="float: left;">Transactions</h1>
|
<h1 style="float: left;">Transactions</h1>
|
||||||
|
|
||||||
|
<div ngbDropdown class="d-block float-right">
|
||||||
|
<button class="btn btn-primary" id="dropdownForm1" ngbDropdownToggle>Filter</button>
|
||||||
|
<div ngbDropdownMenu aria-labelledby="dropdownForm1">
|
||||||
|
<form [formGroup]="radioGroupForm">
|
||||||
|
<label>
|
||||||
|
<input type="checkbox" formControlName="GENESIS"> Genesis
|
||||||
|
</label>
|
||||||
|
<br>
|
||||||
|
<label>
|
||||||
|
<input type="checkbox" formControlName="TRANSFER_BSQ"> Transfer BSQ
|
||||||
|
</label>
|
||||||
|
<br>
|
||||||
|
<label>
|
||||||
|
<input type="checkbox" formControlName="PAY_TRADE_FEE"> Pay trade fee
|
||||||
|
</label>
|
||||||
|
<br>
|
||||||
|
<label>
|
||||||
|
<input type="checkbox" formControlName="PROPOSAL"> Proposal
|
||||||
|
</label>
|
||||||
|
<br>
|
||||||
|
<label>
|
||||||
|
<input type="checkbox" formControlName="COMPENSATION_REQUEST"> Compensation request
|
||||||
|
</label>
|
||||||
|
<br>
|
||||||
|
<label>
|
||||||
|
<input type="checkbox" formControlName="REIMBURSEMENT_REQUEST"> Reimbursement request
|
||||||
|
</label>
|
||||||
|
<br>
|
||||||
|
<label>
|
||||||
|
<input type="checkbox" formControlName="BLIND_VOTE"> Blind vote
|
||||||
|
</label>
|
||||||
|
<br>
|
||||||
|
<label>
|
||||||
|
<input type="checkbox" formControlName="VOTE_REVEAL"> Vote reveal
|
||||||
|
</label>
|
||||||
|
<br>
|
||||||
|
<label>
|
||||||
|
<input type="checkbox" formControlName="LOCKUP"> Lockup
|
||||||
|
</label>
|
||||||
|
<br>
|
||||||
|
<label>
|
||||||
|
<input type="checkbox" formControlName="UNLOCK"> Unlock
|
||||||
|
</label>
|
||||||
|
<br>
|
||||||
|
<label>
|
||||||
|
<input type="checkbox" formControlName="ASSET_LISTING_FEE"> Asset listing fee
|
||||||
|
</label>
|
||||||
|
<br>
|
||||||
|
<label>
|
||||||
|
<input type="checkbox" formControlName="PROOF_OF_BURN"> Proof of burn
|
||||||
|
</label>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<br>
|
<br>
|
||||||
|
|
||||||
<div class="clearfix"></div>
|
<div class="clearfix"></div>
|
||||||
|
@ -0,0 +1,4 @@
|
|||||||
|
label {
|
||||||
|
padding: 0.25rem 1rem;
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
@ -1,9 +1,10 @@
|
|||||||
import { Component, OnInit } from '@angular/core';
|
import { Component, OnInit } from '@angular/core';
|
||||||
import { BisqTransaction, BisqOutput } from '../bisq.interfaces';
|
import { BisqTransaction, BisqOutput } from '../bisq.interfaces';
|
||||||
import { Subject } from 'rxjs';
|
import { Subject, merge } from 'rxjs';
|
||||||
import { switchMap, tap } from 'rxjs/operators';
|
import { switchMap, tap, map } from 'rxjs/operators';
|
||||||
import { BisqApiService } from '../bisq-api.service';
|
import { BisqApiService } from '../bisq-api.service';
|
||||||
import { SeoService } from 'src/app/services/seo.service';
|
import { SeoService } from 'src/app/services/seo.service';
|
||||||
|
import { FormGroup, FormBuilder } from '@angular/forms';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-bisq-transactions',
|
selector: 'app-bisq-transactions',
|
||||||
@ -20,6 +21,8 @@ export class BisqTransactionsComponent implements OnInit {
|
|||||||
isLoading = true;
|
isLoading = true;
|
||||||
loadingItems: number[];
|
loadingItems: number[];
|
||||||
pageSubject$ = new Subject<number>();
|
pageSubject$ = new Subject<number>();
|
||||||
|
radioGroupForm: FormGroup;
|
||||||
|
types: string[] = [];
|
||||||
|
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
paginationSize: 'sm' | 'lg' = 'md';
|
paginationSize: 'sm' | 'lg' = 'md';
|
||||||
@ -28,11 +31,29 @@ export class BisqTransactionsComponent implements OnInit {
|
|||||||
constructor(
|
constructor(
|
||||||
private bisqApiService: BisqApiService,
|
private bisqApiService: BisqApiService,
|
||||||
private seoService: SeoService,
|
private seoService: SeoService,
|
||||||
|
private formBuilder: FormBuilder,
|
||||||
) { }
|
) { }
|
||||||
|
|
||||||
ngOnInit(): void {
|
ngOnInit(): void {
|
||||||
this.seoService.setTitle('Transactions', true);
|
this.seoService.setTitle('Transactions', true);
|
||||||
|
|
||||||
|
this.radioGroupForm = this.formBuilder.group({
|
||||||
|
UNVERIFIED: false,
|
||||||
|
INVALID: false,
|
||||||
|
GENESIS: false,
|
||||||
|
TRANSFER_BSQ: false,
|
||||||
|
PAY_TRADE_FEE: false,
|
||||||
|
PROPOSAL: false,
|
||||||
|
COMPENSATION_REQUEST: false,
|
||||||
|
REIMBURSEMENT_REQUEST: false,
|
||||||
|
BLIND_VOTE: false,
|
||||||
|
VOTE_REVEAL: false,
|
||||||
|
LOCKUP: false,
|
||||||
|
UNLOCK: false,
|
||||||
|
ASSET_LISTING_FEE: false,
|
||||||
|
PROOF_OF_BURN: false,
|
||||||
|
});
|
||||||
|
|
||||||
this.itemsPerPage = Math.max(Math.round(this.contentSpace / this.fiveItemsPxSize) * 5, 10);
|
this.itemsPerPage = Math.max(Math.round(this.contentSpace / this.fiveItemsPxSize) * 5, 10);
|
||||||
this.loadingItems = Array(this.itemsPerPage);
|
this.loadingItems = Array(this.itemsPerPage);
|
||||||
|
|
||||||
@ -41,10 +62,25 @@ export class BisqTransactionsComponent implements OnInit {
|
|||||||
this.paginationMaxSize = 3;
|
this.paginationMaxSize = 3;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.pageSubject$
|
merge(
|
||||||
|
this.pageSubject$,
|
||||||
|
this.radioGroupForm.valueChanges
|
||||||
|
.pipe(
|
||||||
|
map((data) => {
|
||||||
|
const types: string[] = [];
|
||||||
|
for (const i in data) {
|
||||||
|
if (data[i]) {
|
||||||
|
types.push(i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.types = types;
|
||||||
|
return 1;
|
||||||
|
})
|
||||||
|
)
|
||||||
|
)
|
||||||
.pipe(
|
.pipe(
|
||||||
tap(() => this.isLoading = true),
|
tap(() => this.isLoading = true),
|
||||||
switchMap((page) => this.bisqApiService.listTransactions$((page - 1) * this.itemsPerPage, this.itemsPerPage))
|
switchMap((page) => this.bisqApiService.listTransactions$((page - 1) * this.itemsPerPage, this.itemsPerPage, this.types))
|
||||||
)
|
)
|
||||||
.subscribe((response) => {
|
.subscribe((response) => {
|
||||||
this.isLoading = false;
|
this.isLoading = false;
|
||||||
|
@ -12,9 +12,11 @@ import { TimeSinceComponent } from '../components/time-since/time-since.componen
|
|||||||
import { ClipboardComponent } from '../components/clipboard/clipboard.component';
|
import { ClipboardComponent } from '../components/clipboard/clipboard.component';
|
||||||
import { QrcodeComponent } from '../components/qrcode/qrcode.component';
|
import { QrcodeComponent } from '../components/qrcode/qrcode.component';
|
||||||
import { FiatComponent } from '../fiat/fiat.component';
|
import { FiatComponent } from '../fiat/fiat.component';
|
||||||
import { NgbNavModule, NgbTooltipModule } from '@ng-bootstrap/ng-bootstrap';
|
import { NgbNavModule, NgbTooltipModule, NgbButtonsModule, NgbPaginationModule, NgbDropdownModule } from '@ng-bootstrap/ng-bootstrap';
|
||||||
import { TxFeaturesComponent } from '../components/tx-features/tx-features.component';
|
import { TxFeaturesComponent } from '../components/tx-features/tx-features.component';
|
||||||
import { TxFeeRatingComponent } from '../components/tx-fee-rating/tx-fee-rating.component';
|
import { TxFeeRatingComponent } from '../components/tx-fee-rating/tx-fee-rating.component';
|
||||||
|
import { ReactiveFormsModule } from '@angular/forms';
|
||||||
|
import { AngularMultiSelectModule } from 'angular2-multiselect-dropdown';
|
||||||
|
|
||||||
@NgModule({
|
@NgModule({
|
||||||
declarations: [
|
declarations: [
|
||||||
@ -35,8 +37,12 @@ import { TxFeeRatingComponent } from '../components/tx-fee-rating/tx-fee-rating.
|
|||||||
],
|
],
|
||||||
imports: [
|
imports: [
|
||||||
CommonModule,
|
CommonModule,
|
||||||
|
ReactiveFormsModule,
|
||||||
NgbNavModule,
|
NgbNavModule,
|
||||||
NgbTooltipModule,
|
NgbTooltipModule,
|
||||||
|
NgbButtonsModule,
|
||||||
|
NgbPaginationModule,
|
||||||
|
NgbDropdownModule,
|
||||||
],
|
],
|
||||||
providers: [
|
providers: [
|
||||||
VbytesPipe,
|
VbytesPipe,
|
||||||
@ -44,7 +50,11 @@ import { TxFeeRatingComponent } from '../components/tx-fee-rating/tx-fee-rating.
|
|||||||
exports: [
|
exports: [
|
||||||
NgbNavModule,
|
NgbNavModule,
|
||||||
CommonModule,
|
CommonModule,
|
||||||
|
ReactiveFormsModule,
|
||||||
NgbTooltipModule,
|
NgbTooltipModule,
|
||||||
|
NgbButtonsModule,
|
||||||
|
NgbPaginationModule,
|
||||||
|
NgbDropdownModule,
|
||||||
TimeSinceComponent,
|
TimeSinceComponent,
|
||||||
ClipboardComponent,
|
ClipboardComponent,
|
||||||
QrcodeComponent,
|
QrcodeComponent,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user