diff --git a/CHANGELOG.md b/CHANGELOG.md index 092f85424a..ce3bac95da 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -26,6 +26,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Fixed +- **Frontend**: Fixed a bug where user could reach a non-existent page + with a non-existent block height on the scan state page + ([#1966](https://github.com/o1-labs/mina-rust/pull/1966)) - **Frontend**: Fixed a bug where text was overlapping in the view. ([#1957](https://github.com/o1-labs/mina-rust/pull/1957)) - **CI**: fix version regex in build verification workflows to accept diff --git a/frontend/src/app/features/snarks/scan-state/scan-state-toolbar/scan-state-toolbar.component.html b/frontend/src/app/features/snarks/scan-state/scan-state-toolbar/scan-state-toolbar.component.html index 4588be19ed..24caf15b19 100644 --- a/frontend/src/app/features/snarks/scan-state/scan-state-toolbar/scan-state-toolbar.component.html +++ b/frontend/src/app/features/snarks/scan-state/scan-state-toolbar/scan-state-toolbar.component.html @@ -39,7 +39,9 @@ class="h-sm w-sm fx-row-full-cent" [tooltip]="'Next block'" [showDelay]="500" - [disabled]="block?.trees.length === 0" + [disabled]=" + block?.trees.length === 0 || block?.height >= maxBlockHeight + " (click)="clearForm(); getHeight(block?.height + 1)" > navigate_next diff --git a/frontend/src/app/features/snarks/scan-state/scan-state-toolbar/scan-state-toolbar.component.ts b/frontend/src/app/features/snarks/scan-state/scan-state-toolbar/scan-state-toolbar.component.ts index 8bb3bd9492..8d0e191570 100644 --- a/frontend/src/app/features/snarks/scan-state/scan-state-toolbar/scan-state-toolbar.component.ts +++ b/frontend/src/app/features/snarks/scan-state/scan-state-toolbar/scan-state-toolbar.component.ts @@ -35,6 +35,8 @@ import { import { FormBuilder, FormGroup } from '@angular/forms'; import { untilDestroyed } from '@ngneat/until-destroy'; import { NumberInput } from '@angular/cdk/coercion'; +import { AppSelectors } from '@app/app.state'; +import { AppNodeDetails } from '@shared/types/app/app-node-details.type'; @Component({ selector: 'mina-scan-state-toolbar', @@ -54,6 +56,7 @@ export class ScanStateToolbarComponent openSidePanel: boolean; treeView: boolean; highlightSnarkPool: boolean; + maxBlockHeight: number; private inputRef: ElementRef; private gotHeightFromForm: boolean; @@ -76,6 +79,7 @@ export class ScanStateToolbarComponent this.listenToSidePanelChange(); this.listenToTreeViewChange(); this.listenToHighlightSnarkPoolChange(); + this.listenToActiveNodeDetailsChanges(); } getHeight(height: NumberInput): void { @@ -196,4 +200,11 @@ export class ScanStateToolbarComponent toggleHighlightSnarkPool(): void { this.dispatch(ScanStateHighlightSnarkPool); } + + private listenToActiveNodeDetailsChanges(): void { + this.select(AppSelectors.activeNodeDetails, (details: AppNodeDetails) => { + this.maxBlockHeight = details?.blockHeight; + this.detect(); + }); + } } diff --git a/frontend/src/app/features/snarks/scan-state/scan-state.service.ts b/frontend/src/app/features/snarks/scan-state/scan-state.service.ts index 7b974a6b43..62b1a08c64 100644 --- a/frontend/src/app/features/snarks/scan-state/scan-state.service.ts +++ b/frontend/src/app/features/snarks/scan-state/scan-state.service.ts @@ -10,7 +10,7 @@ import { tap, } from 'rxjs'; import { ScanStateBlock } from '@shared/types/snarks/scan-state/scan-state-block.type'; -import { HttpClient } from '@angular/common/http'; +import { HttpClient, HttpErrorResponse } from '@angular/common/http'; import { ScanStateLeaf, ScanStateLeafStatus, @@ -32,7 +32,7 @@ export class ScanStateService { ) {} getScanState(heightOrHash?: string | number): Observable { - const url = this.rust.URL + '/scan-state/summary/' + (heightOrHash ?? ''); + const url = `${this.rust.URL}/scan-state/summary/${heightOrHash ?? ''}`; return this.http.get(url).pipe( switchMap((response: any[]) => { @@ -84,8 +84,22 @@ export class ScanStateService { map(() => response), ); }), - map((response: any) => this.mapScanState(response)), + catchError((err: HttpErrorResponse) => { + const response = err.error; + if (response === 'target block not found') { + return of({ + hash: '', + height: 0, + globalSlot: 0, + transactions: [], + completedWorks: [], + workingSnarkers: [], + trees: [], + }); + } + throw new Error(response); + }), ); }