From 097e2ba0ead1fd6fdecbb4ec565eefeda12ede0b Mon Sep 17 00:00:00 2001 From: softsimon Date: Thu, 13 Aug 2020 00:46:44 +0700 Subject: [PATCH] Assets page pagination. --- frontend/proxy.conf.json | 15 ++ frontend/src/app/assets/assets.component.html | 6 +- frontend/src/app/assets/assets.component.ts | 145 +++++++++++++----- .../bisq-transactions.component.ts | 26 +--- .../src/app/interfaces/electrs.interface.ts | 13 ++ 5 files changed, 139 insertions(+), 66 deletions(-) diff --git a/frontend/proxy.conf.json b/frontend/proxy.conf.json index bb8672574..4e6c6e197 100644 --- a/frontend/proxy.conf.json +++ b/frontend/proxy.conf.json @@ -37,6 +37,21 @@ "^/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": { "target": "http://localhost:8999/", "secure": false, diff --git a/frontend/src/app/assets/assets.component.html b/frontend/src/app/assets/assets.component.html index e2c97c400..7414ea3c7 100644 --- a/frontend/src/app/assets/assets.component.html +++ b/frontend/src/app/assets/assets.component.html @@ -13,7 +13,7 @@ - + @@ -37,9 +37,9 @@ - + - +
Name
diff --git a/frontend/src/app/assets/assets.component.ts b/frontend/src/app/assets/assets.component.ts index 3e003945d..873d626e3 100644 --- a/frontend/src/app/assets/assets.component.ts +++ b/frontend/src/app/assets/assets.component.ts @@ -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 { environment } from 'src/environments/environment'; 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({ selector: 'app-assets', templateUrl: './assets.component.html', - styleUrls: ['./assets.component.scss'] + styleUrls: ['./assets.component.scss'], + changeDetection: ChangeDetectionStrategy.OnPush }) export class AssetsComponent implements OnInit { nativeAssetId = environment.nativeAssetId; - assets: any[]; - assetsCache: any[]; - filteredAssets: any[]; + assets: AssetExtended[]; + assetsCache: AssetExtended[]; searchForm: FormGroup; + assets$: Observable; - isLoading = true; error: any; page = 1; @@ -27,6 +30,9 @@ export class AssetsComponent implements OnInit { constructor( private assetsService: AssetsService, private formBuilder: FormBuilder, + private route: ActivatedRoute, + private router: Router, + private cd: ChangeDetectorRef, ) { } ngOnInit() { @@ -36,30 +42,15 @@ export class AssetsComponent implements OnInit { searchText: [{ value: '', disabled: true }, Validators.required] }); - this.searchForm.get('searchText').valueChanges - .pipe( - distinctUntilChanged(), - ) - .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$ = combineLatest([ + this.assetsService.getAssetsJson$, + this.route.queryParams + ]) + .pipe( + take(1), + mergeMap(([assets, qp]) => { this.assets = Object.values(assets); + // @ts-ignore this.assets.push({ name: 'Liquid Bitcoin', 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.assetsCache = this.assets; this.searchForm.get('searchText').enable(); - this.filteredAssets = this.assets.slice(0, this.itemsPerPage); - this.isLoading = false; - }, - (error) => { - console.log(error); - this.error = error; - this.isLoading = false; - }); + + if (qp.search) { + this.searchForm.get('searchText').setValue(qp.search, { emitEvent: false }); + } + + return merge( + 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) { - const start = (page - 1) * this.itemsPerPage; - this.filteredAssets = this.assets.slice(start, this.itemsPerPage + start); + const queryParams = { page: page, search: this.searchForm.get('searchText').value }; + 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) { diff --git a/frontend/src/app/bisq/bisq-transactions/bisq-transactions.component.ts b/frontend/src/app/bisq/bisq-transactions/bisq-transactions.component.ts index b911d5910..fd3b15c92 100644 --- a/frontend/src/app/bisq/bisq-transactions/bisq-transactions.component.ts +++ b/frontend/src/app/bisq/bisq-transactions/bisq-transactions.component.ts @@ -24,7 +24,6 @@ export class BisqTransactionsComponent implements OnInit { loadingItems: number[]; radioGroupForm: FormGroup; types: string[] = []; - pageSubject$ = new Subject(); txTypeOptions: IMultiSelectOption[] = [ { id: 1, name: 'Asset listing fee' }, @@ -126,40 +125,21 @@ export class BisqTransactionsComponent implements OnInit { this.cd.markForCheck(); }) ), - this.pageSubject$, ) .pipe( 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)]) ); - - 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) { - this.page = page; + pageChange(page: number) { this.router.navigate([], { relativeTo: this.route, queryParams: { page: page }, queryParamsHandling: 'merge', }); - - if (!noTrigger) { - this.pageSubject$.next(); - } + // trigger queryParams change + this.page = -1; } typesChanged(types: number[]) { diff --git a/frontend/src/app/interfaces/electrs.interface.ts b/frontend/src/app/interfaces/electrs.interface.ts index 2ad52ec8f..b435e3d9e 100644 --- a/frontend/src/app/interfaces/electrs.interface.ts +++ b/frontend/src/app/interfaces/electrs.interface.ts @@ -137,6 +137,19 @@ export interface Asset { 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 { txid: string; vin: number;