From 8a65b12cffb0302da7bf8ad09d968cc2ef7c414c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 19 Oct 2023 10:30:42 +0000 Subject: [PATCH 01/14] Bump @babel/traverse from 7.22.6 to 7.23.2 in /frontend Bumps [@babel/traverse](https://github.com/babel/babel/tree/HEAD/packages/babel-traverse) from 7.22.6 to 7.23.2. - [Release notes](https://github.com/babel/babel/releases) - [Changelog](https://github.com/babel/babel/blob/main/CHANGELOG.md) - [Commits](https://github.com/babel/babel/commits/v7.23.2/packages/babel-traverse) --- updated-dependencies: - dependency-name: "@babel/traverse" dependency-type: indirect ... Signed-off-by: dependabot[bot] --- frontend/package-lock.json | 102 ++++++++++++++++++++++++------------- 1 file changed, 66 insertions(+), 36 deletions(-) diff --git a/frontend/package-lock.json b/frontend/package-lock.json index e54eb2e..3d59b10 100644 --- a/frontend/package-lock.json +++ b/frontend/package-lock.json @@ -936,12 +936,13 @@ "dev": true }, "node_modules/@babel/code-frame": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.22.5.tgz", - "integrity": "sha512-Xmwn266vad+6DAqEB2A6V/CcZVp62BbwVmcOJc2RPuwih1kw02TjQvWVWlcKGbBPd+8/0V5DEkOcizRGYsspYQ==", + "version": "7.22.13", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.22.13.tgz", + "integrity": "sha512-XktuhWlJ5g+3TJXc5upd9Ks1HutSArik6jf2eAjYFyIOf4ej3RN+184cZbzDvbPnuTJIUhPKKJE3cIsYTiAT3w==", "dev": true, "dependencies": { - "@babel/highlight": "^7.22.5" + "@babel/highlight": "^7.22.13", + "chalk": "^2.4.2" }, "engines": { "node": ">=6.9.0" @@ -1122,22 +1123,36 @@ } }, "node_modules/@babel/helper-environment-visitor": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.22.5.tgz", - "integrity": "sha512-XGmhECfVA/5sAt+H+xpSg0mfrHq6FzNr9Oxh7PSEBBRUb/mL7Kz3NICXb194rCqAEdxkhPT1a88teizAFyvk8Q==", + "version": "7.22.20", + "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.22.20.tgz", + "integrity": "sha512-zfedSIzFhat/gFhWfHtgWvlec0nqB9YEIVrpuwjruLlXfUSnA8cJB0miHKwqDnQ7d32aKo2xt88/xZptwxbfhA==", "dev": true, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-function-name": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.22.5.tgz", - "integrity": "sha512-wtHSq6jMRE3uF2otvfuD3DIvVhOsSNshQl0Qrd7qC9oQJzHvOL4qQXlQn2916+CXGywIjpGuIkoyZRRxHPiNQQ==", + "version": "7.23.0", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.23.0.tgz", + "integrity": "sha512-OErEqsrxjZTJciZ4Oo+eoZqeW9UIiOcuYKRJA4ZAgV9myA+pOXhhmpfNCKjEH/auVfEYVFJ6y1Tc4r0eIApqiw==", "dev": true, "dependencies": { - "@babel/template": "^7.22.5", - "@babel/types": "^7.22.5" + "@babel/template": "^7.22.15", + "@babel/types": "^7.23.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-function-name/node_modules/@babel/template": { + "version": "7.22.15", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.22.15.tgz", + "integrity": "sha512-QPErUVm4uyJa60rkI73qneDacvdvzxshT3kksGqlGWYdOTIUOwJ7RDUL8sGqslY1uXWSL6xMFKEXDS3ox2uF0w==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.22.13", + "@babel/parser": "^7.22.15", + "@babel/types": "^7.22.15" }, "engines": { "node": ">=6.9.0" @@ -1300,9 +1315,9 @@ } }, "node_modules/@babel/helper-validator-identifier": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.5.tgz", - "integrity": "sha512-aJXu+6lErq8ltp+JhkJUfk1MTGyuA4v7f3pA+BJ5HLfNC6nAQ0Cpi9uOquUj8Hehg0aUiHzWQbOVJGao6ztBAQ==", + "version": "7.22.20", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.20.tgz", + "integrity": "sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A==", "dev": true, "engines": { "node": ">=6.9.0" @@ -1347,13 +1362,13 @@ } }, "node_modules/@babel/highlight": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.22.5.tgz", - "integrity": "sha512-BSKlD1hgnedS5XRnGOljZawtag7H1yPfQp0tdNJCHoH6AZ+Pcm9VvkrK59/Yy593Ypg0zMxH2BxD1VPYUQ7UIw==", + "version": "7.22.20", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.22.20.tgz", + "integrity": "sha512-dkdMCN3py0+ksCgYmGG8jKeGA/8Tk+gJwSYYlFGxG5lmhfKNoAy004YpLxpS1W2J8m/EK2Ew+yOs9pVRwO89mg==", "dev": true, "dependencies": { - "@babel/helper-validator-identifier": "^7.22.5", - "chalk": "^2.0.0", + "@babel/helper-validator-identifier": "^7.22.20", + "chalk": "^2.4.2", "js-tokens": "^4.0.0" }, "engines": { @@ -1361,9 +1376,9 @@ } }, "node_modules/@babel/parser": { - "version": "7.22.6", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.22.6.tgz", - "integrity": "sha512-EIQu22vNkceq3LbjAq7knDf/UmtI2qbcNI8GRBlijez6TpQLvSodJPYfydQmNA5buwkxxxa/PVI44jjYZ+/cLw==", + "version": "7.23.0", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.23.0.tgz", + "integrity": "sha512-vvPKKdMemU85V9WE/l5wZEmImpCtLqbnTvqDS2U1fJ96KrxoW7KrXhNsNCblQlg8Ck4b85yxdTyelsMUgFUXiw==", "dev": true, "bin": { "parser": "bin/babel-parser.js" @@ -2650,19 +2665,19 @@ } }, "node_modules/@babel/traverse": { - "version": "7.22.6", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.22.6.tgz", - "integrity": "sha512-53CijMvKlLIDlOTrdWiHileRddlIiwUIyCKqYa7lYnnPldXCG5dUSN38uT0cA6i7rHWNKJLH0VU/Kxdr1GzB3w==", + "version": "7.23.2", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.23.2.tgz", + "integrity": "sha512-azpe59SQ48qG6nu2CzcMLbxUudtN+dOM9kDbUqGq3HXUJRlo7i8fvPoxQUzYgLZ4cMVmuZgm8vvBpNeRhd6XSw==", "dev": true, "dependencies": { - "@babel/code-frame": "^7.22.5", - "@babel/generator": "^7.22.5", - "@babel/helper-environment-visitor": "^7.22.5", - "@babel/helper-function-name": "^7.22.5", + "@babel/code-frame": "^7.22.13", + "@babel/generator": "^7.23.0", + "@babel/helper-environment-visitor": "^7.22.20", + "@babel/helper-function-name": "^7.23.0", "@babel/helper-hoist-variables": "^7.22.5", "@babel/helper-split-export-declaration": "^7.22.6", - "@babel/parser": "^7.22.6", - "@babel/types": "^7.22.5", + "@babel/parser": "^7.23.0", + "@babel/types": "^7.23.0", "debug": "^4.1.0", "globals": "^11.1.0" }, @@ -2670,6 +2685,21 @@ "node": ">=6.9.0" } }, + "node_modules/@babel/traverse/node_modules/@babel/generator": { + "version": "7.23.0", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.23.0.tgz", + "integrity": "sha512-lN85QRR+5IbYrMWM6Y4pE/noaQtg4pNiqeNGX60eqOfo6gtEj6uw/JagelB8vVztSd7R6M5n1+PQkDbHbBRU4g==", + "dev": true, + "dependencies": { + "@babel/types": "^7.23.0", + "@jridgewell/gen-mapping": "^0.3.2", + "@jridgewell/trace-mapping": "^0.3.17", + "jsesc": "^2.5.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, "node_modules/@babel/traverse/node_modules/@babel/helper-split-export-declaration": { "version": "7.22.6", "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.22.6.tgz", @@ -2683,13 +2713,13 @@ } }, "node_modules/@babel/types": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.22.5.tgz", - "integrity": "sha512-zo3MIHGOkPOfoRXitsgHLjEXmlDaD/5KU1Uzuc9GNiZPhSqVxVRtxuPaSBZDsYZ9qV88AjtMtWW7ww98loJ9KA==", + "version": "7.23.0", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.23.0.tgz", + "integrity": "sha512-0oIyUfKoI3mSqMvsxBdclDwxXKXAUA8v/apZbc+iSyARYou1o8ZGDxbUYyLFoW2arqS2jDGqJuZvv1d/io1axg==", "dev": true, "dependencies": { "@babel/helper-string-parser": "^7.22.5", - "@babel/helper-validator-identifier": "^7.22.5", + "@babel/helper-validator-identifier": "^7.22.20", "to-fast-properties": "^2.0.0" }, "engines": { From 20c03aea4a9d683b2b2eeb3b84958f17b7f9e340 Mon Sep 17 00:00:00 2001 From: Yamaguchi Date: Fri, 27 Oct 2023 13:56:14 +0900 Subject: [PATCH 02/14] Add routing GET /block/height/:height --- backend/actions/block_detail.js | 34 ++++++++++++++++++++++++++ frontend/src/app/app-routing.module.ts | 5 ++++ frontend/src/app/backend.service.ts | 4 +++ frontend/src/app/block/block.page.ts | 27 ++++++++++++++++++++ 4 files changed, 70 insertions(+) diff --git a/backend/actions/block_detail.js b/backend/actions/block_detail.js index 709a1b4..50a403d 100644 --- a/backend/actions/block_detail.js +++ b/backend/actions/block_detail.js @@ -12,6 +12,40 @@ app.use((req, res, next) => { next(); }); +app.get('/api/block/height/:height', async (req, res) => { + const height = req.params.height; + + try { + const blockHash = await rest.block.height(height); + const block = await rest.block.get(blockHash); + const status = await rest.block.status(blockHash); + if (!block || !status) { + res.status(404).send('Block not found.'); + return; + } + const tip = await rest.block.tip.height(); + res.json({ + blockHash: block.id, + confirmations: tip - block.height, + ntx: block.tx_count, + height: block.height, + timestamp: block.time, + proof: block.signature, + sizeBytes: block.size, + version: block.features, + merkleRoot: block.merkle_root, + immutableMerkleRoot: block.im_merkle_root, + previousBlock: block.previousblockhash, + nextBlock: status.next_best + }); + } catch (err) { + logger.error( + `Error retrieving information for block - height = ${height}. Error Message - ${err.message}` + ); + res.status(503).send('Service Temporary Unavailable'); + } +}); + app.get('/api/block/:blockHash', async (req, res) => { const blockHash = req.params.blockHash; diff --git a/frontend/src/app/app-routing.module.ts b/frontend/src/app/app-routing.module.ts index 0dacd31..6a290fd 100644 --- a/frontend/src/app/app-routing.module.ts +++ b/frontend/src/app/app-routing.module.ts @@ -13,6 +13,11 @@ const routes: Routes = [ loadChildren: () => import('./blocks/blocks.module').then(m => m.BlocksPageModule) }, + { + path: 'block/height/:height', + loadChildren: () => + import('./block/block.module').then(m => m.BlockPageModule) + }, { path: 'block/:hash', loadChildren: () => diff --git a/frontend/src/app/backend.service.ts b/frontend/src/app/backend.service.ts index c4a1332..9aeb72b 100644 --- a/frontend/src/app/backend.service.ts +++ b/frontend/src/app/backend.service.ts @@ -30,6 +30,10 @@ export class BackendService { return this.http.get(`${this.backendUrl}/api/block/${blockHash}`); } + getBlockByHeight(height: number): Observable { + return this.http.get(`${this.backendUrl}/api/block/height/${height}`); + } + getRawBlock(blockHash: string): Observable { return this.http.get(`${this.backendUrl}/api/block/${blockHash}/raw`); } diff --git a/frontend/src/app/block/block.page.ts b/frontend/src/app/block/block.page.ts index 28b690b..0bc71fb 100644 --- a/frontend/src/app/block/block.page.ts +++ b/frontend/src/app/block/block.page.ts @@ -13,6 +13,7 @@ import { AppConst } from '../app.const'; }) export class BlockPage implements OnInit { blockHash: string; + height: number; block: any = {}; blockTxns: any = {}; openTxns = false; @@ -37,10 +38,19 @@ export class BlockPage implements OnInit { ngOnInit() { this.blockHash = this.activatedRoute.snapshot.paramMap.get('hash'); + this.height = Number(this.activatedRoute.snapshot.paramMap.get('height')); this.getBlockInfo(); } getBlockInfo() { + if (this.blockHash != null) { + this.getBlockInfoByHash(); + } else if (this.height != null) { + this.getBlockInfoByHeight(); + } + } + + getBlockInfoByHash() { this.backendService.getBlock(this.blockHash).subscribe( data => { this.block = data || {}; @@ -56,6 +66,23 @@ export class BlockPage implements OnInit { ); } + getBlockInfoByHeight() { + this.backendService.getBlockByHeight(this.height).subscribe( + data => { + this.block = data || {}; + this.blockHash = this.block.blockHash; + this.calculatePagination(); + }, + err => { + console.log(err); + this.hasError = true; + this.statusCode = err.status; + this.statusMsg = err.statusText; + this.detailMsg = err.error; + } + ); + } + goToBlocks() { this.navCtrl.navigateBack('/blocks'); } From ed4e5287676ab422f516e6057d515e78fa14c2f2 Mon Sep 17 00:00:00 2001 From: Yamaguchi Date: Fri, 27 Oct 2023 19:29:21 +0900 Subject: [PATCH 03/14] Add query parameter for paging blocks --- frontend/src/app/blocks/blocks.page.ts | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/frontend/src/app/blocks/blocks.page.ts b/frontend/src/app/blocks/blocks.page.ts index ef26217..9491c8e 100644 --- a/frontend/src/app/blocks/blocks.page.ts +++ b/frontend/src/app/blocks/blocks.page.ts @@ -4,6 +4,7 @@ import { NavController } from '@ionic/angular'; import { BackendService } from '../backend.service'; import { AppConst } from '../app.const'; +import { ActivatedRoute } from '@angular/router'; @Component({ selector: 'app-blocks', @@ -26,10 +27,14 @@ export class BlocksPage implements OnInit { constructor( private httpClient: HttpClient, private navCtrl: NavController, - private backendService: BackendService + private backendService: BackendService, + private activatedRoute: ActivatedRoute ) {} ngOnInit() { + this.activatedRoute.queryParamMap.subscribe(params => { + this.page = Math.max(Number(params.get('page')), 1); + }); this.getBlockLists(); } From 7fcadcb0a89428c5c62fec664d41238e45c48480 Mon Sep 17 00:00:00 2001 From: Yamaguchi Date: Fri, 27 Oct 2023 19:45:21 +0900 Subject: [PATCH 04/14] Fix CI failure --- frontend/src/app/blocks/blocks.page.spec.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/frontend/src/app/blocks/blocks.page.spec.ts b/frontend/src/app/blocks/blocks.page.spec.ts index c1d74a5..144608d 100644 --- a/frontend/src/app/blocks/blocks.page.spec.ts +++ b/frontend/src/app/blocks/blocks.page.spec.ts @@ -2,6 +2,7 @@ import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing'; import { IonicModule } from '@ionic/angular'; import { BlocksPage } from './blocks.page'; +import { RouterTestingModule } from '@angular/router/testing'; import { HttpClientTestingModule } from '@angular/common/http/testing'; import { NgxPaginationModule } from 'ngx-pagination'; @@ -15,7 +16,8 @@ describe('BlocksPage', () => { imports: [ IonicModule.forRoot(), HttpClientTestingModule, - NgxPaginationModule + NgxPaginationModule, + RouterTestingModule ] }).compileComponents(); From 194fc811d4552610134c4d3333e505413cc90449 Mon Sep 17 00:00:00 2001 From: Yamaguchi Date: Sat, 28 Oct 2023 02:57:56 +0900 Subject: [PATCH 05/14] Add button to switch visibility of detail of transaction inputs/outputs --- .../src/app/transaction/transaction.page.html | 174 ++++++++++++------ .../src/app/transaction/transaction.page.scss | 7 + .../src/app/transaction/transaction.page.ts | 5 + 3 files changed, 125 insertions(+), 61 deletions(-) diff --git a/frontend/src/app/transaction/transaction.page.html b/frontend/src/app/transaction/transaction.page.html index f322c4c..3b6aad9 100644 --- a/frontend/src/app/transaction/transaction.page.html +++ b/frontend/src/app/transaction/transaction.page.html @@ -51,7 +51,33 @@ - +
+ + + + + + + Show Detail + Hide Detail + + + + +
@@ -96,6 +122,38 @@ >{{ vin.txid }}:{{ vin.vout }} + + + + script sig asm + + + {{ vin.scriptsig_asm }} + + + script sig hex + + + {{ vin.scriptsig }} + + +
@@ -123,71 +181,65 @@ class="with-border {{'#output_' + i == this.scrollTarget ? 'highlight' : ''}}" id="output_{{i}}" > - #{{ i }} - {{ vout.scriptpubkey_uncolored_address }} - - {{vout.value | asTpc }} - COIN - - TPC + + + #{{ i }} + {{ vout.scriptpubkey_uncolored_address }} + + {{vout.value | asTpc }} + COIN + + TPC + + + + + + script pubkey asm + + + {{ vout.scriptpubkey_asm }} + + + script pubkey hex + + + {{ vout.scriptpubkey }} + + + - - - Input Scripts:

-
-
-
- - {{ vin.scriptsig_asm }} - -
-
-
-
- - - - - Output Scripts:

-
- - {{ vout.scriptpubkey_asm }} - -
-
-
- Date: Sat, 28 Oct 2023 21:57:30 +0900 Subject: [PATCH 06/14] Add Copy button for script pubkey and script sig --- frontend/src/app/app.helper.ts | 17 +++ .../src/app/transaction/transaction.page.html | 101 +++++++++++------- .../src/app/transaction/transaction.page.scss | 9 ++ .../src/app/transaction/transaction.page.ts | 14 ++- frontend/src/global.scss | 6 ++ 5 files changed, 107 insertions(+), 40 deletions(-) create mode 100644 frontend/src/app/app.helper.ts diff --git a/frontend/src/app/app.helper.ts b/frontend/src/app/app.helper.ts new file mode 100644 index 0000000..11774e7 --- /dev/null +++ b/frontend/src/app/app.helper.ts @@ -0,0 +1,17 @@ +import { Component, Injectable } from '@angular/core'; +import { ToastController } from '@ionic/angular'; + +export default class Helper { + @Injectable() + static async copy(toastController: ToastController, text: string) { + navigator.clipboard.writeText(text); + const toast = await toastController.create({ + message: 'Copied', + color: 'dark', + position: 'middle', + duration: 1000, + animated: true + }); + toast.present(); + } +} diff --git a/frontend/src/app/transaction/transaction.page.html b/frontend/src/app/transaction/transaction.page.html index 3b6aad9..300b4e7 100644 --- a/frontend/src/app/transaction/transaction.page.html +++ b/frontend/src/app/transaction/transaction.page.html @@ -122,35 +122,47 @@ >{{ vin.txid }}:{{ vin.vout }} - + - script sig asm - - {{ vin.scriptsig_asm }} + + + {{ vin.scriptsig_asm }} + + + + - script sig hex - - {{ vin.scriptsig }} + + + {{ vin.scriptsig }} + + + + @@ -203,35 +215,48 @@ TPC - + - script pubkey asm - - {{ vout.scriptpubkey_asm }} + + + {{ vout.scriptpubkey_asm }} + + + + - script pubkey hex - - {{ vout.scriptpubkey }} + + + {{ vout.scriptpubkey }} + + + + diff --git a/frontend/src/app/transaction/transaction.page.scss b/frontend/src/app/transaction/transaction.page.scss index 04ede8d..af05006 100644 --- a/frontend/src/app/transaction/transaction.page.scss +++ b/frontend/src/app/transaction/transaction.page.scss @@ -17,6 +17,15 @@ ion-content { margin-bottom: 16px; } +.text-script { + color: var(--ion-color-primary) !important; + + > ion-col { + display: inline-flex; + align-items: center; + } +} + #block-header-text { @media (max-width: 539px) { font-size: 16px; diff --git a/frontend/src/app/transaction/transaction.page.ts b/frontend/src/app/transaction/transaction.page.ts index a98fb1e..16d081a 100644 --- a/frontend/src/app/transaction/transaction.page.ts +++ b/frontend/src/app/transaction/transaction.page.ts @@ -1,10 +1,15 @@ import { AfterViewChecked, Component, OnInit } from '@angular/core'; import { ActivatedRoute } from '@angular/router'; import { HttpClient } from '@angular/common/http'; -import { ModalController, NavController } from '@ionic/angular'; +import { + ModalController, + NavController, + ToastController +} from '@ionic/angular'; import { TransactionRawdataPage } from '../transaction-rawdata/transaction-rawdata.page'; import { BackendService } from '../backend.service'; +import Helper from '../app.helper'; @Component({ selector: 'app-transaction', @@ -31,7 +36,8 @@ export class TransactionPage implements OnInit, AfterViewChecked { private httpClient: HttpClient, private modalCtrl: ModalController, private navCtrl: NavController, - private backendService: BackendService + private backendService: BackendService, + private toastController: ToastController ) {} ngOnInit() { @@ -42,6 +48,10 @@ export class TransactionPage implements OnInit, AfterViewChecked { this.scrollToOutput(); } + async copy(text: string) { + Helper.copy(this.toastController, text); + } + getTransactionInfo() { this.resetError(); this.backendService.getTransaction(this.txid).subscribe( diff --git a/frontend/src/global.scss b/frontend/src/global.scss index 7e9319e..f0bb7a3 100644 --- a/frontend/src/global.scss +++ b/frontend/src/global.scss @@ -87,3 +87,9 @@ a { .block { padding: 5px 5px; } + +ion-toast { + --max-width: 100px; + font-weight: bold; + text-align: center !important; +} From 7744e0965303edef8b739906b2e1febfaf87f54a Mon Sep 17 00:00:00 2001 From: Yamaguchi Date: Sat, 28 Oct 2023 21:59:05 +0900 Subject: [PATCH 07/14] Use Helper function to copy to clipboard --- frontend/src/app/address/address.page.ts | 23 +++------------- frontend/src/app/app.helper.ts | 1 - .../app/block-rawdata/block-rawdata.page.html | 8 ------ .../block-rawdata/block-rawdata.page.spec.ts | 5 ++-- .../app/block-rawdata/block-rawdata.page.ts | 26 ++++--------------- .../transaction-rawdata.page.html | 8 ------ .../transaction-rawdata.page.ts | 26 ++++--------------- 7 files changed, 17 insertions(+), 80 deletions(-) diff --git a/frontend/src/app/address/address.page.ts b/frontend/src/app/address/address.page.ts index 836fad9..daaf2fa 100644 --- a/frontend/src/app/address/address.page.ts +++ b/frontend/src/app/address/address.page.ts @@ -1,9 +1,10 @@ import { Component, OnInit } from '@angular/core'; import { ActivatedRoute } from '@angular/router'; -import { NavController } from '@ionic/angular'; +import { NavController, ToastController } from '@ionic/angular'; import { BackendService } from '../backend.service'; import { AppConst } from '../app.const'; +import Helper from '../app.helper'; @Component({ selector: 'app-address', @@ -34,6 +35,7 @@ export class AddressPage implements OnInit { constructor( private activatedRoute: ActivatedRoute, private navCtrl: NavController, + private toastController: ToastController, private backendService: BackendService ) {} @@ -56,24 +58,7 @@ export class AddressPage implements OnInit { } copyAddress() { - const textArea = document.createElement('textarea'); - textArea.value = this.address; - - document.body.appendChild(textArea); - textArea.focus(); - textArea.select(); - - try { - document.execCommand('copy'); - this.copied = true; - setTimeout(() => { - this.copied = false; - }, 800); - } catch (err) { - console.error('Fallback: Oops, unable to copy', err); - } - - document.body.removeChild(textArea); + Helper.copy(this.toastController, this.address); } onNextPage() { diff --git a/frontend/src/app/app.helper.ts b/frontend/src/app/app.helper.ts index 11774e7..4c36735 100644 --- a/frontend/src/app/app.helper.ts +++ b/frontend/src/app/app.helper.ts @@ -2,7 +2,6 @@ import { Component, Injectable } from '@angular/core'; import { ToastController } from '@ionic/angular'; export default class Helper { - @Injectable() static async copy(toastController: ToastController, text: string) { navigator.clipboard.writeText(text); const toast = await toastController.create({ diff --git a/frontend/src/app/block-rawdata/block-rawdata.page.html b/frontend/src/app/block-rawdata/block-rawdata.page.html index e7e2dc3..8dffd8a 100644 --- a/frontend/src/app/block-rawdata/block-rawdata.page.html +++ b/frontend/src/app/block-rawdata/block-rawdata.page.html @@ -12,16 +12,8 @@ Copy Raw Data - Copied !

{{ blockRawData }}

-
- - - Copy Raw Data
- Copied ! -
diff --git a/frontend/src/app/block-rawdata/block-rawdata.page.spec.ts b/frontend/src/app/block-rawdata/block-rawdata.page.spec.ts index babd116..dbefe24 100644 --- a/frontend/src/app/block-rawdata/block-rawdata.page.spec.ts +++ b/frontend/src/app/block-rawdata/block-rawdata.page.spec.ts @@ -1,5 +1,5 @@ import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing'; -import { IonicModule } from '@ionic/angular'; +import { IonicModule, NavParams } from '@ionic/angular'; import { BlockRawdataPage } from './block-rawdata.page'; import { HttpClientTestingModule } from '@angular/common/http/testing'; @@ -11,7 +11,8 @@ describe('BlockRawdataPage', () => { beforeEach(waitForAsync(() => { TestBed.configureTestingModule({ declarations: [BlockRawdataPage], - imports: [IonicModule.forRoot(), HttpClientTestingModule] + imports: [IonicModule.forRoot(), HttpClientTestingModule], + providers: [NavParams] }).compileComponents(); fixture = TestBed.createComponent(BlockRawdataPage); diff --git a/frontend/src/app/block-rawdata/block-rawdata.page.ts b/frontend/src/app/block-rawdata/block-rawdata.page.ts index 8f574ee..c43a03b 100644 --- a/frontend/src/app/block-rawdata/block-rawdata.page.ts +++ b/frontend/src/app/block-rawdata/block-rawdata.page.ts @@ -1,24 +1,25 @@ import { Component, OnInit, Input } from '@angular/core'; -import { NavParams, ModalController } from '@ionic/angular'; +import { NavParams, ModalController, ToastController } from '@ionic/angular'; import { HttpClient } from '@angular/common/http'; import { BackendService } from '../backend.service'; +import Helper from '../app.helper'; @Component({ selector: 'app-block-rawdata', templateUrl: './block-rawdata.page.html', styleUrls: ['./block-rawdata.page.scss'], - providers: [BackendService, NavParams] + providers: [BackendService] }) export class BlockRawdataPage implements OnInit { @Input() blockHash: string; blockRawData = ''; - copied = false; constructor( private navParams: NavParams, private httpClient: HttpClient, private modalCtrl: ModalController, + private toastController: ToastController, private backendService: BackendService ) {} @@ -40,24 +41,7 @@ export class BlockRawdataPage implements OnInit { } copyBlockRawData() { - const textArea = document.createElement('textarea'); - textArea.value = this.blockRawData; - - document.body.appendChild(textArea); - textArea.focus(); - textArea.select(); - - try { - document.execCommand('copy'); - this.copied = true; - setTimeout(() => { - this.copied = false; - }, 800); - } catch (err) { - console.error('Fallback: Oops, unable to copy', err); - } - - document.body.removeChild(textArea); + Helper.copy(this.toastController, this.blockRawData); } dismiss() { diff --git a/frontend/src/app/transaction-rawdata/transaction-rawdata.page.html b/frontend/src/app/transaction-rawdata/transaction-rawdata.page.html index fc4915d..aaefda9 100644 --- a/frontend/src/app/transaction-rawdata/transaction-rawdata.page.html +++ b/frontend/src/app/transaction-rawdata/transaction-rawdata.page.html @@ -12,16 +12,8 @@ Copy Raw Data - Copied !

{{ txRawData }}

-
- - - Copy Raw Data
- Copied ! -
diff --git a/frontend/src/app/transaction-rawdata/transaction-rawdata.page.ts b/frontend/src/app/transaction-rawdata/transaction-rawdata.page.ts index eaab893..07ca51a 100644 --- a/frontend/src/app/transaction-rawdata/transaction-rawdata.page.ts +++ b/frontend/src/app/transaction-rawdata/transaction-rawdata.page.ts @@ -1,8 +1,9 @@ import { Component, OnInit, Input } from '@angular/core'; -import { NavParams, ModalController } from '@ionic/angular'; +import { NavParams, ModalController, ToastController } from '@ionic/angular'; import { HttpClient } from '@angular/common/http'; import { BackendService } from '../backend.service'; +import Helper from '../app.helper'; @Component({ selector: 'app-transaction-rawdata', @@ -13,12 +14,12 @@ import { BackendService } from '../backend.service'; export class TransactionRawdataPage implements OnInit { @Input() txid: string; txRawData = ''; - copied = false; constructor( private navParams: NavParams, private httpClient: HttpClient, private modalCtrl: ModalController, + private toastController: ToastController, private backendService: BackendService ) {} @@ -39,25 +40,8 @@ export class TransactionRawdataPage implements OnInit { ); } - copyTxRawData() { - const textArea = document.createElement('textarea'); - textArea.value = this.txRawData; - - document.body.appendChild(textArea); - textArea.focus(); - textArea.select(); - - try { - document.execCommand('copy'); - this.copied = true; - setTimeout(() => { - this.copied = false; - }, 800); - } catch (err) { - console.error('Fallback: Oops, unable to copy', err); - } - - document.body.removeChild(textArea); + async copyTxRawData() { + Helper.copy(this.toastController, this.txRawData); } dismiss() { From e9bce22491b9569d755882b1cb0e84da979c5240 Mon Sep 17 00:00:00 2001 From: Yamaguchi Date: Wed, 8 Nov 2023 17:53:27 +0900 Subject: [PATCH 08/14] Change query parameter when changing page --- frontend/src/app/blocks/blocks.page.ts | 3 +++ 1 file changed, 3 insertions(+) diff --git a/frontend/src/app/blocks/blocks.page.ts b/frontend/src/app/blocks/blocks.page.ts index 9491c8e..911942d 100644 --- a/frontend/src/app/blocks/blocks.page.ts +++ b/frontend/src/app/blocks/blocks.page.ts @@ -68,6 +68,9 @@ export class BlocksPage implements OnInit { onPageChange(pageNumber: number) { this.page = pageNumber; + this.navCtrl.navigateForward('/blocks', { + queryParams: { page: this.page } + }); this.getBlockLists(); } From af92e5d01f8b54b5bfebc25bc0d63b8e7fdb5d6c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sat, 11 Nov 2023 13:36:24 +0000 Subject: [PATCH 09/14] Bump axios from 1.4.0 to 1.6.1 in /frontend Bumps [axios](https://github.com/axios/axios) from 1.4.0 to 1.6.1. - [Release notes](https://github.com/axios/axios/releases) - [Changelog](https://github.com/axios/axios/blob/v1.x/CHANGELOG.md) - [Commits](https://github.com/axios/axios/compare/v1.4.0...v1.6.1) --- updated-dependencies: - dependency-name: axios dependency-type: indirect ... Signed-off-by: dependabot[bot] --- frontend/package-lock.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/frontend/package-lock.json b/frontend/package-lock.json index e54eb2e..5a94af0 100644 --- a/frontend/package-lock.json +++ b/frontend/package-lock.json @@ -5445,9 +5445,9 @@ "dev": true }, "node_modules/axios": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/axios/-/axios-1.4.0.tgz", - "integrity": "sha512-S4XCWMEmzvo64T9GfvQDOXgYRDJ/wsSZc7Jvdgx5u1sd0JwsuPLqb3SYmusag+edF6ziyMensPVqLTSc1PiSEA==", + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.6.1.tgz", + "integrity": "sha512-vfBmhDpKafglh0EldBEbVuoe7DyAavGSLWhuSm5ZSEKQnHhBf0xAAwybbNH1IkrJNGnS/VG4I5yxig1pCEXE4g==", "dev": true, "dependencies": { "follow-redirects": "^1.15.0", From d3c72c7666b0e8fe323af6de4f443e481262944b Mon Sep 17 00:00:00 2001 From: Yamaguchi Date: Mon, 18 Mar 2024 03:55:43 +0900 Subject: [PATCH 10/14] Implement color list page --- backend/actions/color_list.js | 27 +++++++ backend/libs/rest.js | 14 ++++ backend/server.js | 1 + frontend/src/app/app-routing.module.ts | 5 ++ frontend/src/app/app.component.ts | 4 ++ frontend/src/app/backend.service.ts | 10 +++ .../src/app/colors/colors-routing.module.ts | 17 +++++ frontend/src/app/colors/colors.module.ts | 23 ++++++ frontend/src/app/colors/colors.page.html | 51 ++++++++++++++ frontend/src/app/colors/colors.page.scss | 37 ++++++++++ frontend/src/app/colors/colors.page.spec.ts | 30 ++++++++ frontend/src/app/colors/colors.page.ts | 70 +++++++++++++++++++ 12 files changed, 289 insertions(+) create mode 100644 backend/actions/color_list.js create mode 100644 frontend/src/app/colors/colors-routing.module.ts create mode 100644 frontend/src/app/colors/colors.module.ts create mode 100644 frontend/src/app/colors/colors.page.html create mode 100644 frontend/src/app/colors/colors.page.scss create mode 100644 frontend/src/app/colors/colors.page.spec.ts create mode 100644 frontend/src/app/colors/colors.page.ts diff --git a/backend/actions/color_list.js b/backend/actions/color_list.js new file mode 100644 index 0000000..36e01a5 --- /dev/null +++ b/backend/actions/color_list.js @@ -0,0 +1,27 @@ +const app = require('../app.js'); +const rest = require('../libs/rest'); +const logger = require('../libs/logger'); + +app.use((req, res, next) => { + res.header('Access-Control-Allow-Origin', '*'); + res.header( + 'Access-Control-Allow-Headers', + 'Origin, X-Requested-With, Content-Type, Accept' + ); + next(); +}); + +app.get('/api/colors', async (req, res) => { + const lastSeenColorId = req.query.lastSeenColorId; + + try { + const colors = await rest.color.list(lastSeenColorId); + console.log(colors); + res.json({ colors: colors }); + } catch (err) { + logger.error( + `Error retrieving colors. Error Message - ${err.message}` + ); + res.status(500).send(`Error Retrieving Blocks`); + } +}); diff --git a/backend/libs/rest.js b/backend/libs/rest.js index ea01683..368cd08 100644 --- a/backend/libs/rest.js +++ b/backend/libs/rest.js @@ -148,6 +148,20 @@ const block = { }; const color = { + list: async lastSeenColorId => { + let url; + if (lastSeenColorId) { + url = `${baseUrl}/colors/${lastSeenColorId}`; + } else { + url = `${baseUrl}/colors`; + } + const response = await fetch(url, { agent: agentSelector }); + if (response.ok) { + return response.json(); + } else { + throw new Error(`failed to fetch API ${url}`); + } + }, get: async colorId => { const url = `${baseUrl}/color/${colorId}`; const response = await fetch(url, { agent: agentSelector }); diff --git a/backend/server.js b/backend/server.js index ff47fe7..b00a75e 100644 --- a/backend/server.js +++ b/backend/server.js @@ -2,6 +2,7 @@ const app = require('./app.js'); require('./actions/block_detail.js'); require('./actions/block_list.js'); require('./actions/color_detail.js'); +require('./actions/color_list.js'); require('./actions/transaction_detail.js'); require('./actions/transaction_list.js'); require('./actions/address_detail.js'); diff --git a/frontend/src/app/app-routing.module.ts b/frontend/src/app/app-routing.module.ts index 6a290fd..1e09857 100644 --- a/frontend/src/app/app-routing.module.ts +++ b/frontend/src/app/app-routing.module.ts @@ -30,6 +30,11 @@ const routes: Routes = [ m => m.BlockRawdataPageModule ) }, + { + path: 'colors', + loadChildren: () => + import('./colors/colors.module').then(m => m.ColorsPageModule) + }, { path: 'color/:colorId', loadChildren: () => diff --git a/frontend/src/app/app.component.ts b/frontend/src/app/app.component.ts index 336a16f..c2f4572 100644 --- a/frontend/src/app/app.component.ts +++ b/frontend/src/app/app.component.ts @@ -21,6 +21,10 @@ export class AppComponent implements OnInit { title: 'Txns', url: '/tx/recent' }, + { + title: 'Colors', + url: '/colors' + }, { title: 'Tracking Validation', url: '/material_tracking_validation' diff --git a/frontend/src/app/backend.service.ts b/frontend/src/app/backend.service.ts index 9aeb72b..ce7a469 100644 --- a/frontend/src/app/backend.service.ts +++ b/frontend/src/app/backend.service.ts @@ -80,6 +80,16 @@ export class BackendService { return this.http.get(`${this.backendUrl}/api/tx/${query}/get`); } + getColors(lastSeenColorId?: string): Observable { + return this.http.get(`${this.backendUrl}/api/colors`, { + params: new HttpParams({ + fromObject: { + lastSeenColorId: (lastSeenColorId || '').toString() + } + }) + }); + } + getColor(colorId: string, lastSeenTxid?: string): Observable { return this.http.get(`${this.backendUrl}/api/color/${colorId}`, { params: new HttpParams({ diff --git a/frontend/src/app/colors/colors-routing.module.ts b/frontend/src/app/colors/colors-routing.module.ts new file mode 100644 index 0000000..cfec1b9 --- /dev/null +++ b/frontend/src/app/colors/colors-routing.module.ts @@ -0,0 +1,17 @@ +import { NgModule } from '@angular/core'; +import { Routes, RouterModule } from '@angular/router'; + +import { ColorsPage } from './colors.page'; + +const routes: Routes = [ + { + path: '', + component: ColorsPage + } +]; + +@NgModule({ + imports: [RouterModule.forChild(routes)], + exports: [RouterModule] +}) +export class ColorsPageRoutingModule {} diff --git a/frontend/src/app/colors/colors.module.ts b/frontend/src/app/colors/colors.module.ts new file mode 100644 index 0000000..2398feb --- /dev/null +++ b/frontend/src/app/colors/colors.module.ts @@ -0,0 +1,23 @@ +import { NgModule } from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { FormsModule } from '@angular/forms'; + +import { IonicModule } from '@ionic/angular'; + +import { ColorsPageRoutingModule } from './colors-routing.module'; + +import { ColorsPage } from './colors.page'; +import { SharedPipeModule } from '../modules/sharePipe.module'; +import { NgxPaginationModule } from 'ngx-pagination'; +@NgModule({ + imports: [ + CommonModule, + FormsModule, + IonicModule, + ColorsPageRoutingModule, + NgxPaginationModule, + SharedPipeModule + ], + declarations: [ColorsPage] +}) +export class ColorsPageModule {} diff --git a/frontend/src/app/colors/colors.page.html b/frontend/src/app/colors/colors.page.html new file mode 100644 index 0000000..df11dd3 --- /dev/null +++ b/frontend/src/app/colors/colors.page.html @@ -0,0 +1,51 @@ + +
+
+ + +

Colors

+
+
+ + COLOR ID + LATEST USED BLOCK + + + {{ color[0] }} + {{ color[1] }} + +
+
+ + + + Load More + + + +
+

+
{{ statusCode }}
+
{{ statusMsg }}
+

+
+

{{ detailMsg }}

+
+
+
diff --git a/frontend/src/app/colors/colors.page.scss b/frontend/src/app/colors/colors.page.scss new file mode 100644 index 0000000..9e27b98 --- /dev/null +++ b/frontend/src/app/colors/colors.page.scss @@ -0,0 +1,37 @@ +ion-content { + --background: var( + --ion-item-background, + var(--ion-background-color, #e5e5e5) + ) !important; +} + +#color-header-text { + @media (max-width: 539px) { + font-size: 16px; + margin: 17px 10px 10px; + } + + @media (min-width: 540px) { + font-size: 36px; + margin: 0px 10px 20px; + } + + font-weight: 500; +} + +.table-header { + background-color: #f6f6f6; + font-size: 14px; + color: #aaaaaa; +} + +.table-border-bottom { + border-bottom: 1px solid #f6f6f6; + padding: 10px 10px; +} + +.ellipsis { + text-overflow: ellipsis; + white-space: nowrap; + overflow: hidden; +} diff --git a/frontend/src/app/colors/colors.page.spec.ts b/frontend/src/app/colors/colors.page.spec.ts new file mode 100644 index 0000000..1a9b969 --- /dev/null +++ b/frontend/src/app/colors/colors.page.spec.ts @@ -0,0 +1,30 @@ +import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing'; +import { IonicModule } from '@ionic/angular'; + +import { ColorsPage } from './colors.page'; +import { RouterTestingModule } from '@angular/router/testing'; +import { HttpClientTestingModule } from '@angular/common/http/testing'; + +describe('ColorsPage', () => { + let component: ColorsPage; + let fixture: ComponentFixture; + + beforeEach(waitForAsync(() => { + TestBed.configureTestingModule({ + declarations: [ColorsPage], + imports: [ + IonicModule.forRoot(), + RouterTestingModule, + HttpClientTestingModule + ] + }).compileComponents(); + + fixture = TestBed.createComponent(ColorsPage); + component = fixture.componentInstance; + fixture.detectChanges(); + })); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/frontend/src/app/colors/colors.page.ts b/frontend/src/app/colors/colors.page.ts new file mode 100644 index 0000000..bdb19a8 --- /dev/null +++ b/frontend/src/app/colors/colors.page.ts @@ -0,0 +1,70 @@ +import { Component, OnInit } from '@angular/core'; +import { ActivatedRoute } from '@angular/router'; +import { HttpClient } from '@angular/common/http'; +import { ModalController, NavController } from '@ionic/angular'; +import { BackendService } from '../backend.service'; +import { AppConst } from '../app.const'; + +@Component({ + selector: 'app-color', + templateUrl: './colors.page.html', + styleUrls: ['./colors.page.scss'], + providers: [BackendService] +}) +export class ColorsPage implements OnInit { + lastSeenColorId?: string; + colors = []; + hasError: boolean; + statusCode: string; + statusMsg: string; + detailMsg: string; + + constructor( + private activatedRoute: ActivatedRoute, + private httpClient: HttpClient, + private modalCtrl: ModalController, + private navCtrl: NavController, + private backendService: BackendService + ) {} + + ngOnInit() { + this.lastSeenColorId = this.activatedRoute.snapshot.paramMap.get('lastSeenColorId') || ''; + this.getColorsInfo(); + } + + getColorsInfo() { + this.resetError(); + this.backendService.getColors(this.lastSeenColorId).subscribe( + data => { + this.colors = this.colors.concat(data["colors"]); + this.lastSeenColorId = data["colors"][data["colors"].length - 1][0]; + }, + err => { + console.log(err); + this.hasError = true; + this.statusCode = err.status; + this.statusMsg = err.statusText; + this.detailMsg = err.error; + } + ); + } + + goToColorPage(colorId) { + this.navCtrl.navigateForward(`/color/${colorId}`); + } + + goToBlock(block_height) { + this.navCtrl.navigateForward(`/block/height/${block_height}`); + } + + onNextPage() { + this.getColorsInfo(); + } + + resetError() { + this.hasError = false; + this.statusCode = null; + this.statusMsg = null; + this.detailMsg = null; + } +} From 06d4011a3e81116934bc331bd2afeaf94fc32dc6 Mon Sep 17 00:00:00 2001 From: Yamaguchi Date: Tue, 19 Mar 2024 01:52:32 +0900 Subject: [PATCH 11/14] Fix prettier warnings --- backend/actions/color_list.js | 4 +--- frontend/src/app/colors/colors.page.html | 5 ++++- frontend/src/app/colors/colors.page.ts | 7 ++++--- 3 files changed, 9 insertions(+), 7 deletions(-) diff --git a/backend/actions/color_list.js b/backend/actions/color_list.js index 36e01a5..52910f2 100644 --- a/backend/actions/color_list.js +++ b/backend/actions/color_list.js @@ -19,9 +19,7 @@ app.get('/api/colors', async (req, res) => { console.log(colors); res.json({ colors: colors }); } catch (err) { - logger.error( - `Error retrieving colors. Error Message - ${err.message}` - ); + logger.error(`Error retrieving colors. Error Message - ${err.message}`); res.status(500).send(`Error Retrieving Blocks`); } }); diff --git a/frontend/src/app/colors/colors.page.html b/frontend/src/app/colors/colors.page.html index df11dd3..6f71b7f 100644 --- a/frontend/src/app/colors/colors.page.html +++ b/frontend/src/app/colors/colors.page.html @@ -10,7 +10,10 @@

Colors

COLOR ID LATEST USED BLOCK
- + { - this.colors = this.colors.concat(data["colors"]); - this.lastSeenColorId = data["colors"][data["colors"].length - 1][0]; + this.colors = this.colors.concat(data['colors']); + this.lastSeenColorId = data['colors'][data['colors'].length - 1][0]; }, err => { console.log(err); From f76adc82e1cb7572937ce9e0f0ac23e04f4df2a9 Mon Sep 17 00:00:00 2001 From: Yamaguchi Date: Thu, 21 Mar 2024 13:19:36 +0900 Subject: [PATCH 12/14] Fix spec --- frontend/src/app/app.component.spec.ts | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/frontend/src/app/app.component.spec.ts b/frontend/src/app/app.component.spec.ts index f3ab00f..48e1116 100644 --- a/frontend/src/app/app.component.spec.ts +++ b/frontend/src/app/app.component.spec.ts @@ -51,10 +51,11 @@ describe('AppComponent', () => { await fixture.detectChanges(); const app = fixture.nativeElement; const menuItems = app.querySelectorAll('ion-label'); - expect(menuItems.length).toEqual(3); + expect(menuItems.length).toEqual(4); expect(menuItems[0].textContent).toContain('Blocks'); expect(menuItems[1].textContent).toContain('Txns'); - expect(menuItems[2].textContent).toContain('Tracking Validation'); + expect(menuItems[2].textContent).toContain('Colors'); + expect(menuItems[3].textContent).toContain('Tracking Validation'); }); it('should have urls', async () => { @@ -62,7 +63,7 @@ describe('AppComponent', () => { await fixture.detectChanges(); const app = fixture.nativeElement; const menuItems = app.querySelectorAll('ion-item'); - expect(menuItems.length).toEqual(3); + expect(menuItems.length).toEqual(4); expect(menuItems[0].getAttribute('ng-reflect-router-link')).toEqual( '/blocks' ); @@ -70,6 +71,9 @@ describe('AppComponent', () => { '/tx/recent' ); expect(menuItems[2].getAttribute('ng-reflect-router-link')).toEqual( + '/colors' + ); + expect(menuItems[3].getAttribute('ng-reflect-router-link')).toEqual( '/material_tracking_validation' ); }); From b39465e69bec94001a51f2b59c5c617ea6912783 Mon Sep 17 00:00:00 2001 From: Yamaguchi Date: Tue, 26 Mar 2024 01:51:22 +0900 Subject: [PATCH 13/14] Display amount of the issued coins on colors page --- frontend/src/app/colors/colors.page.html | 24 ++++++++++++++++-------- frontend/src/app/colors/colors.page.ts | 3 ++- 2 files changed, 18 insertions(+), 9 deletions(-) diff --git a/frontend/src/app/colors/colors.page.html b/frontend/src/app/colors/colors.page.html index 6f71b7f..84a9faf 100644 --- a/frontend/src/app/colors/colors.page.html +++ b/frontend/src/app/colors/colors.page.html @@ -7,24 +7,32 @@

Colors

- COLOR ID - LATEST USED BLOCK + COLOR ID + LATEST USED BLOCK + ISSUED {{ color[0] }}{{ color['color_id'] }} {{ color[1] }}{{ color['height'] }} + {{ color['chain_stats']['issued_sum'] + + color['mempool_stats']['issued_sum'] }} diff --git a/frontend/src/app/colors/colors.page.ts b/frontend/src/app/colors/colors.page.ts index be3ffe8..c3606cd 100644 --- a/frontend/src/app/colors/colors.page.ts +++ b/frontend/src/app/colors/colors.page.ts @@ -38,7 +38,8 @@ export class ColorsPage implements OnInit { this.backendService.getColors(this.lastSeenColorId).subscribe( data => { this.colors = this.colors.concat(data['colors']); - this.lastSeenColorId = data['colors'][data['colors'].length - 1][0]; + this.lastSeenColorId = + data['colors'][data['colors'].length - 1]['color_id']; }, err => { console.log(err); From 2dcbca1bebee0d7904f17fde270a98e398fd2f9d Mon Sep 17 00:00:00 2001 From: Yamaguchi Date: Mon, 1 Apr 2024 02:13:22 +0900 Subject: [PATCH 14/14] Update frontend/src/app/colors/colors.page.html Co-authored-by: shigeyuki azuchi --- frontend/src/app/colors/colors.page.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frontend/src/app/colors/colors.page.html b/frontend/src/app/colors/colors.page.html index 84a9faf..3e83a54 100644 --- a/frontend/src/app/colors/colors.page.html +++ b/frontend/src/app/colors/colors.page.html @@ -9,7 +9,7 @@

Colors

COLOR ID LATEST USED BLOCK - ISSUED + TOTAL SUPPLY