Assets page pagination.
This commit is contained in:
parent
b1c8166936
commit
097e2ba0ea
@ -37,6 +37,21 @@
|
|||||||
"^/testnet/api": ""
|
"^/testnet/api": ""
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"/liquid/api/v1/ws": {
|
||||||
|
"target": "http://localhost:8999/",
|
||||||
|
"secure": false,
|
||||||
|
"ws": true,
|
||||||
|
"pathRewrite": {
|
||||||
|
"^/liquid/api": "/api/v1/ws"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"/liquid/api": {
|
||||||
|
"target": "http://localhost:50001/",
|
||||||
|
"secure": false,
|
||||||
|
"pathRewrite": {
|
||||||
|
"^/liquid/api": ""
|
||||||
|
}
|
||||||
|
},
|
||||||
"/bisq/api": {
|
"/bisq/api": {
|
||||||
"target": "http://localhost:8999/",
|
"target": "http://localhost:8999/",
|
||||||
"secure": false,
|
"secure": false,
|
||||||
|
@ -13,7 +13,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
|
|
||||||
<ng-template [ngIf]="!isLoading && !error">
|
<ng-container *ngIf="(assets$ | async) as filteredAssets; else isLoading">
|
||||||
<table class="table table-borderless table-striped">
|
<table class="table table-borderless table-striped">
|
||||||
<thead>
|
<thead>
|
||||||
<th class="td-name">Name</th>
|
<th class="td-name">Name</th>
|
||||||
@ -37,9 +37,9 @@
|
|||||||
|
|
||||||
<ngb-pagination [collectionSize]="assets.length" [rotate]="true" [pageSize]="itemsPerPage" [(page)]="page" (pageChange)="pageChange(page)" [maxSize]="5" [boundaryLinks]="true"></ngb-pagination>
|
<ngb-pagination [collectionSize]="assets.length" [rotate]="true" [pageSize]="itemsPerPage" [(page)]="page" (pageChange)="pageChange(page)" [maxSize]="5" [boundaryLinks]="true"></ngb-pagination>
|
||||||
|
|
||||||
</ng-template>
|
</ng-container>
|
||||||
|
|
||||||
<ng-template [ngIf]="isLoading && !error">
|
<ng-template #isLoading>
|
||||||
|
|
||||||
<table class="table table-borderless table-striped">
|
<table class="table table-borderless table-striped">
|
||||||
<thead>
|
<thead>
|
||||||
|
@ -1,22 +1,25 @@
|
|||||||
import { Component, OnInit } from '@angular/core';
|
import { Component, OnInit, ChangeDetectionStrategy, ChangeDetectorRef } from '@angular/core';
|
||||||
import { AssetsService } from '../services/assets.service';
|
import { AssetsService } from '../services/assets.service';
|
||||||
import { environment } from 'src/environments/environment';
|
import { environment } from 'src/environments/environment';
|
||||||
import { FormGroup, FormBuilder, Validators } from '@angular/forms';
|
import { FormGroup, FormBuilder, Validators } from '@angular/forms';
|
||||||
import { distinctUntilChanged } from 'rxjs/operators';
|
import { distinctUntilChanged, map, filter, mergeMap, tap, take } from 'rxjs/operators';
|
||||||
|
import { ActivatedRoute, Router } from '@angular/router';
|
||||||
|
import { merge, combineLatest, Observable } from 'rxjs';
|
||||||
|
import { AssetExtended } from '../interfaces/electrs.interface';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-assets',
|
selector: 'app-assets',
|
||||||
templateUrl: './assets.component.html',
|
templateUrl: './assets.component.html',
|
||||||
styleUrls: ['./assets.component.scss']
|
styleUrls: ['./assets.component.scss'],
|
||||||
|
changeDetection: ChangeDetectionStrategy.OnPush
|
||||||
})
|
})
|
||||||
export class AssetsComponent implements OnInit {
|
export class AssetsComponent implements OnInit {
|
||||||
nativeAssetId = environment.nativeAssetId;
|
nativeAssetId = environment.nativeAssetId;
|
||||||
assets: any[];
|
assets: AssetExtended[];
|
||||||
assetsCache: any[];
|
assetsCache: AssetExtended[];
|
||||||
filteredAssets: any[];
|
|
||||||
searchForm: FormGroup;
|
searchForm: FormGroup;
|
||||||
|
assets$: Observable<AssetExtended[]>;
|
||||||
|
|
||||||
isLoading = true;
|
|
||||||
error: any;
|
error: any;
|
||||||
|
|
||||||
page = 1;
|
page = 1;
|
||||||
@ -27,6 +30,9 @@ export class AssetsComponent implements OnInit {
|
|||||||
constructor(
|
constructor(
|
||||||
private assetsService: AssetsService,
|
private assetsService: AssetsService,
|
||||||
private formBuilder: FormBuilder,
|
private formBuilder: FormBuilder,
|
||||||
|
private route: ActivatedRoute,
|
||||||
|
private router: Router,
|
||||||
|
private cd: ChangeDetectorRef,
|
||||||
) { }
|
) { }
|
||||||
|
|
||||||
ngOnInit() {
|
ngOnInit() {
|
||||||
@ -36,30 +42,15 @@ export class AssetsComponent implements OnInit {
|
|||||||
searchText: [{ value: '', disabled: true }, Validators.required]
|
searchText: [{ value: '', disabled: true }, Validators.required]
|
||||||
});
|
});
|
||||||
|
|
||||||
this.searchForm.get('searchText').valueChanges
|
this.assets$ = combineLatest([
|
||||||
|
this.assetsService.getAssetsJson$,
|
||||||
|
this.route.queryParams
|
||||||
|
])
|
||||||
.pipe(
|
.pipe(
|
||||||
distinctUntilChanged(),
|
take(1),
|
||||||
)
|
mergeMap(([assets, qp]) => {
|
||||||
.subscribe((searchText) => {
|
|
||||||
this.page = 1;
|
|
||||||
if (searchText.length ) {
|
|
||||||
this.filteredAssets = this.assetsCache.filter((asset) => asset.name.toLowerCase().indexOf(searchText.toLowerCase()) > -1
|
|
||||||
|| asset.ticker.toLowerCase().indexOf(searchText.toLowerCase()) > -1);
|
|
||||||
this.assets = this.filteredAssets;
|
|
||||||
this.filteredAssets = this.filteredAssets.slice(0, this.itemsPerPage);
|
|
||||||
} else {
|
|
||||||
this.assets = this.assetsCache;
|
|
||||||
this.filteredAssets = this.assets.slice(0, this.itemsPerPage);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
this.getAssets();
|
|
||||||
}
|
|
||||||
|
|
||||||
getAssets() {
|
|
||||||
this.assetsService.getAssetsJson$
|
|
||||||
.subscribe((assets) => {
|
|
||||||
this.assets = Object.values(assets);
|
this.assets = Object.values(assets);
|
||||||
|
// @ts-ignore
|
||||||
this.assets.push({
|
this.assets.push({
|
||||||
name: 'Liquid Bitcoin',
|
name: 'Liquid Bitcoin',
|
||||||
ticker: 'L-BTC',
|
ticker: 'L-BTC',
|
||||||
@ -68,19 +59,93 @@ export class AssetsComponent implements OnInit {
|
|||||||
this.assets = this.assets.sort((a: any, b: any) => a.name.localeCompare(b.name));
|
this.assets = this.assets.sort((a: any, b: any) => a.name.localeCompare(b.name));
|
||||||
this.assetsCache = this.assets;
|
this.assetsCache = this.assets;
|
||||||
this.searchForm.get('searchText').enable();
|
this.searchForm.get('searchText').enable();
|
||||||
this.filteredAssets = this.assets.slice(0, this.itemsPerPage);
|
|
||||||
this.isLoading = false;
|
if (qp.search) {
|
||||||
},
|
this.searchForm.get('searchText').setValue(qp.search, { emitEvent: false });
|
||||||
(error) => {
|
}
|
||||||
console.log(error);
|
|
||||||
this.error = error;
|
return merge(
|
||||||
this.isLoading = false;
|
this.searchForm.get('searchText').valueChanges
|
||||||
});
|
.pipe(
|
||||||
|
distinctUntilChanged(),
|
||||||
|
tap((text) => {
|
||||||
|
this.page = 1;
|
||||||
|
this.searchTextChanged(text);
|
||||||
|
})
|
||||||
|
),
|
||||||
|
this.route.queryParams
|
||||||
|
.pipe(
|
||||||
|
filter((queryParams) => {
|
||||||
|
const newPage = parseInt(queryParams.page, 10);
|
||||||
|
if (newPage !== this.page || queryParams.search !== this.searchForm.get('searchText').value) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}),
|
||||||
|
map((queryParams) => {
|
||||||
|
if (queryParams.page) {
|
||||||
|
const newPage = parseInt(queryParams.page, 10);
|
||||||
|
this.page = newPage;
|
||||||
|
} else {
|
||||||
|
this.page = 1;
|
||||||
|
}
|
||||||
|
this.cd.markForCheck();
|
||||||
|
if (this.searchForm.get('searchText').value !== (queryParams.search || '')) {
|
||||||
|
this.searchTextChanged(queryParams.search);
|
||||||
|
}
|
||||||
|
if (queryParams.search) {
|
||||||
|
this.searchForm.get('searchText').setValue(queryParams.search, { emitEvent: false });
|
||||||
|
return queryParams.search;
|
||||||
|
}
|
||||||
|
return '';
|
||||||
|
})
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}),
|
||||||
|
map((searchText) => {
|
||||||
|
const start = (this.page - 1) * this.itemsPerPage;
|
||||||
|
if (searchText.length ) {
|
||||||
|
const filteredAssets = this.assetsCache.filter((asset) => asset.name.toLowerCase().indexOf(searchText.toLowerCase()) > -1
|
||||||
|
|| asset.ticker.toLowerCase().indexOf(searchText.toLowerCase()) > -1);
|
||||||
|
this.assets = filteredAssets;
|
||||||
|
return filteredAssets.slice(start, this.itemsPerPage + start);
|
||||||
|
} else {
|
||||||
|
this.assets = this.assetsCache;
|
||||||
|
return this.assets.slice(start, this.itemsPerPage + start);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
pageChange(page: number) {
|
pageChange(page: number) {
|
||||||
const start = (page - 1) * this.itemsPerPage;
|
const queryParams = { page: page, search: this.searchForm.get('searchText').value };
|
||||||
this.filteredAssets = this.assets.slice(start, this.itemsPerPage + start);
|
if (queryParams.search === '') {
|
||||||
|
queryParams.search = null;
|
||||||
|
}
|
||||||
|
if (queryParams.page === 1) {
|
||||||
|
queryParams.page = null;
|
||||||
|
}
|
||||||
|
this.page = -1;
|
||||||
|
this.router.navigate([], {
|
||||||
|
relativeTo: this.route,
|
||||||
|
queryParams: queryParams,
|
||||||
|
queryParamsHandling: 'merge',
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
searchTextChanged(text: string) {
|
||||||
|
const queryParams = { search: text, page: 1 };
|
||||||
|
if (queryParams.search === '') {
|
||||||
|
queryParams.search = null;
|
||||||
|
}
|
||||||
|
if (queryParams.page === 1) {
|
||||||
|
queryParams.page = null;
|
||||||
|
}
|
||||||
|
this.router.navigate([], {
|
||||||
|
relativeTo: this.route,
|
||||||
|
queryParams: queryParams,
|
||||||
|
queryParamsHandling: 'merge',
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
trackByAsset(index: number, asset: any) {
|
trackByAsset(index: number, asset: any) {
|
||||||
|
@ -24,7 +24,6 @@ export class BisqTransactionsComponent implements OnInit {
|
|||||||
loadingItems: number[];
|
loadingItems: number[];
|
||||||
radioGroupForm: FormGroup;
|
radioGroupForm: FormGroup;
|
||||||
types: string[] = [];
|
types: string[] = [];
|
||||||
pageSubject$ = new Subject<any>();
|
|
||||||
|
|
||||||
txTypeOptions: IMultiSelectOption[] = [
|
txTypeOptions: IMultiSelectOption[] = [
|
||||||
{ id: 1, name: 'Asset listing fee' },
|
{ id: 1, name: 'Asset listing fee' },
|
||||||
@ -126,40 +125,21 @@ export class BisqTransactionsComponent implements OnInit {
|
|||||||
this.cd.markForCheck();
|
this.cd.markForCheck();
|
||||||
})
|
})
|
||||||
),
|
),
|
||||||
this.pageSubject$,
|
|
||||||
)
|
)
|
||||||
.pipe(
|
.pipe(
|
||||||
switchMap(() => this.bisqApiService.listTransactions$((this.page - 1) * this.itemsPerPage, this.itemsPerPage, this.types)),
|
switchMap(() => this.bisqApiService.listTransactions$((this.page - 1) * this.itemsPerPage, this.itemsPerPage, this.types)),
|
||||||
map((response) => [response.body, parseInt(response.headers.get('x-total-count'), 10)])
|
map((response) => [response.body, parseInt(response.headers.get('x-total-count'), 10)])
|
||||||
);
|
);
|
||||||
|
|
||||||
this.radioGroupForm.valueChanges
|
|
||||||
.subscribe((data) => {
|
|
||||||
const types: string[] = [];
|
|
||||||
for (const i in data) {
|
|
||||||
if (data[i]) {
|
|
||||||
types.push(i);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
this.types = types;
|
|
||||||
if (this.page !== 1) {
|
|
||||||
this.pageChange(1, true);
|
|
||||||
}
|
|
||||||
return 1;
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pageChange(page: number, noTrigger?: boolean) {
|
pageChange(page: number) {
|
||||||
this.page = page;
|
|
||||||
this.router.navigate([], {
|
this.router.navigate([], {
|
||||||
relativeTo: this.route,
|
relativeTo: this.route,
|
||||||
queryParams: { page: page },
|
queryParams: { page: page },
|
||||||
queryParamsHandling: 'merge',
|
queryParamsHandling: 'merge',
|
||||||
});
|
});
|
||||||
|
// trigger queryParams change
|
||||||
if (!noTrigger) {
|
this.page = -1;
|
||||||
this.pageSubject$.next();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
typesChanged(types: number[]) {
|
typesChanged(types: number[]) {
|
||||||
|
@ -137,6 +137,19 @@ export interface Asset {
|
|||||||
mempool_stats: AssetStats;
|
mempool_stats: AssetStats;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface AssetExtended extends Asset {
|
||||||
|
name: string;
|
||||||
|
ticker: string;
|
||||||
|
precision: number;
|
||||||
|
entity: Entity;
|
||||||
|
version: number;
|
||||||
|
issuer_pubkey: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface Entity {
|
||||||
|
domain: string;
|
||||||
|
}
|
||||||
|
|
||||||
interface IssuanceTxin {
|
interface IssuanceTxin {
|
||||||
txid: string;
|
txid: string;
|
||||||
vin: number;
|
vin: number;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user