Add next block visualization to main dashboard, expand widgets
This commit is contained in:
		
							parent
							
								
									e86d0dc868
								
							
						
					
					
						commit
						29e4a581e7
					
				| @ -16,23 +16,22 @@ | |||||||
|     </ng-container> |     </ng-container> | ||||||
|     <div class="col"> |     <div class="col"> | ||||||
|       <div class="card graph-card"> |       <div class="card graph-card"> | ||||||
|         <div class="card-body pl-0"> |         <div class="card-body pl-lg-3 pr-lg-3 pl-2 pr-2"> | ||||||
|  |           <ng-template [ngIf]="(network$ | async) !== 'liquid'" [ngIfElse]="liquidPegs"> | ||||||
|  |             <a class="title-link" href="" [routerLink]="['/mempool-block/0' | relativeUrl]"> | ||||||
|  |               <h5 class="card-title d-inline" i18n="dashboard.mempool-goggles">Mempool Goggles</h5> | ||||||
|  |               <span> </span> | ||||||
|  |               <fa-icon [icon]="['fas', 'external-link-alt']" [fixedWidth]="true" style="vertical-align: text-top; font-size: 13px; color: #4a68b9"></fa-icon> | ||||||
|  |             </a> | ||||||
|  |             <div class="mempool-block-wrapper"> | ||||||
|  |               <app-mempool-block-overview [index]="0"></app-mempool-block-overview> | ||||||
|  |             </div> | ||||||
|  |           </ng-template> | ||||||
|  |           <ng-template #liquidPegs> | ||||||
|             <div style="padding-left: 1.25rem;"> |             <div style="padding-left: 1.25rem;"> | ||||||
|               <ng-container *ngTemplateOutlet="stateService.network === 'liquid' ? lbtcPegs : mempoolTable; context: { $implicit: mempoolInfoData }"></ng-container> |               <ng-container *ngTemplateOutlet="stateService.network === 'liquid' ? lbtcPegs : mempoolTable; context: { $implicit: mempoolInfoData }"></ng-container> | ||||||
|               <hr> |               <hr> | ||||||
|             </div> |             </div> | ||||||
|           <ng-template [ngIf]="(network$ | async) !== 'liquid'" [ngIfElse]="liquidPegs"> |  | ||||||
|             <ng-container *ngIf="{ value: (mempoolStats$ | async) } as mempoolStats"> |  | ||||||
|               <div class="mempool-graph"> |  | ||||||
|                 <app-mempool-graph |  | ||||||
|                 [template]="'widget'" |  | ||||||
|                 [data]="mempoolStats.value?.mempool" |  | ||||||
|                 [windowPreferenceOverride]="'2h'" |  | ||||||
|                 ></app-mempool-graph> |  | ||||||
|               </div> |  | ||||||
|             </ng-container> |  | ||||||
|           </ng-template> |  | ||||||
|           <ng-template #liquidPegs> |  | ||||||
|             <app-lbtc-pegs-graph [data]="fullHistory$ | async"></app-lbtc-pegs-graph> |             <app-lbtc-pegs-graph [data]="fullHistory$ | async"></app-lbtc-pegs-graph> | ||||||
|           </ng-template> |           </ng-template> | ||||||
|         </div> |         </div> | ||||||
| @ -41,9 +40,21 @@ | |||||||
|     <div class="col"> |     <div class="col"> | ||||||
|       <div class="card graph-card"> |       <div class="card graph-card"> | ||||||
|         <div class="card-body"> |         <div class="card-body"> | ||||||
|           <ng-container *ngTemplateOutlet="stateService.network === 'liquid' ? mempoolTable : txPerSecond; context: { $implicit: mempoolInfoData }"></ng-container> |           <ng-container *ngIf="stateService.network !== 'liquid'"> | ||||||
|  |             <h5 class="card-title" i18n="dashboard.incoming-transactions">Incoming Transactions</h5> | ||||||
|  |             <div class="mempool-graph" *ngIf="{ value: (mempoolStats$ | async) } as mempoolStats"> | ||||||
|  |               <app-incoming-transactions-graph | ||||||
|  |                 [height]="incomingGraphHeight" | ||||||
|  |                 [left]="50" | ||||||
|  |                 [right]="20" | ||||||
|  |                 [data]="mempoolStats.value?.weightPerSecond" | ||||||
|  |                 [windowPreferenceOverride]="'2h'" | ||||||
|  |                 ></app-incoming-transactions-graph> | ||||||
|  |             </div> | ||||||
|  |           </ng-container> | ||||||
|  |           <ng-container *ngTemplateOutlet="mempoolTable; context: { $implicit: mempoolInfoData }"></ng-container> | ||||||
|  |           <div class="mempool-graph" *ngIf="stateService.network === 'liquid'"> | ||||||
|             <hr> |             <hr> | ||||||
|           <div class="mempool-graph" *ngIf="stateService.network === 'liquid'; else mempoolGraph"> |  | ||||||
|             <table class="table table-borderless table-striped" *ngIf="(featuredAssets$ | async) as featuredAssets else loadingAssetsTable"> |             <table class="table table-borderless table-striped" *ngIf="(featuredAssets$ | async) as featuredAssets else loadingAssetsTable"> | ||||||
|               <tbody> |               <tbody> | ||||||
|                 <tr *ngFor="let group of featuredAssets"> |                 <tr *ngFor="let group of featuredAssets"> | ||||||
| @ -60,15 +71,6 @@ | |||||||
|               </tbody> |               </tbody> | ||||||
|             </table> |             </table> | ||||||
|           </div> |           </div> | ||||||
|           <ng-template #mempoolGraph> |  | ||||||
|             <div class="mempool-graph" *ngIf="{ value: (mempoolStats$ | async) } as mempoolStats"> |  | ||||||
|               <app-incoming-transactions-graph |  | ||||||
|                 [left]="50" |  | ||||||
|                 [data]="mempoolStats.value?.weightPerSecond" |  | ||||||
|                 [windowPreferenceOverride]="'2h'" |  | ||||||
|                 ></app-incoming-transactions-graph> |  | ||||||
|             </div> |  | ||||||
|           </ng-template> |  | ||||||
|         </div> |         </div> | ||||||
|       </div> |       </div> | ||||||
|     </div> |     </div> | ||||||
| @ -284,19 +286,3 @@ | |||||||
|     </div> |     </div> | ||||||
|   </div> |   </div> | ||||||
| </ng-template> | </ng-template> | ||||||
| 
 |  | ||||||
| <ng-template #txPerSecond let-mempoolInfoData> |  | ||||||
|   <h5 class="card-title" i18n="dashboard.incoming-transactions">Incoming Transactions</h5> |  | ||||||
|   <ng-template [ngIf]="(isLoadingWebSocket$ | async) === false && mempoolInfoData.value" [ngIfElse]="loadingTransactions"> |  | ||||||
|     <span *ngIf="(mempoolLoadingStatus$ | async) !== 100; else inSync"> |  | ||||||
|        <span class="badge badge-pill badge-warning"><ng-container i18n="dashboard.backend-is-synchronizing">Backend is synchronizing</ng-container> ({{ mempoolLoadingStatus$ | async }}%)</span> |  | ||||||
|     </span> |  | ||||||
|     <ng-template #inSync> |  | ||||||
|       <div class="progress inc-tx-progress-bar"> |  | ||||||
|         <div class="progress-bar {{ mempoolInfoData.value.progressColor }}" role="progressbar" [ngStyle]="{'width': mempoolInfoData.value.progressWidth}"> </div> |  | ||||||
|         <div *only-vsize class="progress-text">‎{{ mempoolInfoData.value.vBytesPerSecond | ceil | number }} <ng-container i18n="shared.vbytes-per-second|vB/s">vB/s</ng-container></div> |  | ||||||
|         <div *only-weight class="progress-text">‎{{ mempoolInfoData.value.vBytesPerSecond * 4 | ceil | number }} <ng-container i18n="shared.weight-per-second|WU/s">WU/s</ng-container></div> |  | ||||||
|       </div> |  | ||||||
|     </ng-template> |  | ||||||
|   </ng-template> |  | ||||||
| </ng-template> |  | ||||||
|  | |||||||
| @ -44,8 +44,11 @@ | |||||||
| 
 | 
 | ||||||
| .graph-card { | .graph-card { | ||||||
|   height: 100%; |   height: 100%; | ||||||
|  |   @media (min-width: 768px) { | ||||||
|  |     height: 415px; | ||||||
|  |   } | ||||||
|   @media (min-width: 992px) { |   @media (min-width: 992px) { | ||||||
|     height: 385px; |     height: 500px; | ||||||
|   } |   } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| @ -258,6 +261,12 @@ | |||||||
| 
 | 
 | ||||||
| .mempool-graph { | .mempool-graph { | ||||||
|   height: 255px; |   height: 255px; | ||||||
|  |   @media (min-width: 768px) { | ||||||
|  |     height: 285px; | ||||||
|  |   } | ||||||
|  |   @media (min-width: 992px) { | ||||||
|  |     height: 370px; | ||||||
|  |   } | ||||||
| } | } | ||||||
| .loadingGraphs{ | .loadingGraphs{ | ||||||
|   height: 250px; |   height: 250px; | ||||||
| @ -364,3 +373,18 @@ | |||||||
|   text-decoration: none; |   text-decoration: none; | ||||||
|   color: inherit; |   color: inherit; | ||||||
| } | } | ||||||
|  | 
 | ||||||
|  | .mempool-block-wrapper { | ||||||
|  |   max-height: 430px; | ||||||
|  |   max-width: 430px; | ||||||
|  |   margin: auto; | ||||||
|  | 
 | ||||||
|  |   @media (min-width: 768px) { | ||||||
|  |     max-height: 344px; | ||||||
|  |     max-width: 344px; | ||||||
|  |   } | ||||||
|  |   @media (min-width: 992px) { | ||||||
|  |     max-height: 430px; | ||||||
|  |     max-width: 430px; | ||||||
|  |   } | ||||||
|  | } | ||||||
| @ -1,4 +1,4 @@ | |||||||
| import { AfterViewInit, ChangeDetectionStrategy, Component, OnDestroy, OnInit } from '@angular/core'; | import { AfterViewInit, ChangeDetectionStrategy, Component, HostListener, OnDestroy, OnInit } from '@angular/core'; | ||||||
| import { combineLatest, EMPTY, merge, Observable, of, Subject, Subscription, timer } from 'rxjs'; | import { combineLatest, EMPTY, merge, Observable, of, Subject, Subscription, timer } from 'rxjs'; | ||||||
| import { catchError, delayWhen, filter, map, scan, share, shareReplay, startWith, switchMap, takeUntil, tap, throttleTime } from 'rxjs/operators'; | import { catchError, delayWhen, filter, map, scan, share, shareReplay, startWith, switchMap, takeUntil, tap, throttleTime } from 'rxjs/operators'; | ||||||
| import { AuditStatus, BlockExtended, CurrentPegs, OptimizedMempoolStats } from '../interfaces/node-api.interface'; | import { AuditStatus, BlockExtended, CurrentPegs, OptimizedMempoolStats } from '../interfaces/node-api.interface'; | ||||||
| @ -54,8 +54,10 @@ export class DashboardComponent implements OnInit, OnDestroy, AfterViewInit { | |||||||
|   currentReserves$: Observable<CurrentPegs>; |   currentReserves$: Observable<CurrentPegs>; | ||||||
|   fullHistory$: Observable<any>; |   fullHistory$: Observable<any>; | ||||||
|   isLoad: boolean = true; |   isLoad: boolean = true; | ||||||
|  |   mempoolInfoSubscription: Subscription; | ||||||
|   currencySubscription: Subscription; |   currencySubscription: Subscription; | ||||||
|   currency: string; |   currency: string; | ||||||
|  |   incomingGraphHeight: number = 300; | ||||||
|   private lastPegBlockUpdate: number = 0; |   private lastPegBlockUpdate: number = 0; | ||||||
|   private lastPegAmount: string = ''; |   private lastPegAmount: string = ''; | ||||||
|   private lastReservesBlockUpdate: number = 0; |   private lastReservesBlockUpdate: number = 0; | ||||||
| @ -74,6 +76,7 @@ export class DashboardComponent implements OnInit, OnDestroy, AfterViewInit { | |||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   ngOnDestroy(): void { |   ngOnDestroy(): void { | ||||||
|  |     this.mempoolInfoSubscription.unsubscribe(); | ||||||
|     this.currencySubscription.unsubscribe(); |     this.currencySubscription.unsubscribe(); | ||||||
|     this.websocketService.stopTrackRbfSummary(); |     this.websocketService.stopTrackRbfSummary(); | ||||||
|     this.destroy$.next(1); |     this.destroy$.next(1); | ||||||
| @ -81,6 +84,7 @@ export class DashboardComponent implements OnInit, OnDestroy, AfterViewInit { | |||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   ngOnInit(): void { |   ngOnInit(): void { | ||||||
|  |     this.onResize(); | ||||||
|     this.isLoadingWebSocket$ = this.stateService.isLoadingWebSocket$; |     this.isLoadingWebSocket$ = this.stateService.isLoadingWebSocket$; | ||||||
|     this.seoService.resetTitle(); |     this.seoService.resetTitle(); | ||||||
|     this.seoService.resetDescription(); |     this.seoService.resetDescription(); | ||||||
| @ -95,8 +99,7 @@ export class DashboardComponent implements OnInit, OnDestroy, AfterViewInit { | |||||||
|     this.mempoolInfoData$ = combineLatest([ |     this.mempoolInfoData$ = combineLatest([ | ||||||
|       this.stateService.mempoolInfo$, |       this.stateService.mempoolInfo$, | ||||||
|       this.stateService.vbytesPerSecond$ |       this.stateService.vbytesPerSecond$ | ||||||
|     ]) |     ]).pipe( | ||||||
|       .pipe( |  | ||||||
|       map(([mempoolInfo, vbytesPerSecond]) => { |       map(([mempoolInfo, vbytesPerSecond]) => { | ||||||
|         const percent = Math.round((Math.min(vbytesPerSecond, this.vBytesPerSecondLimit) / this.vBytesPerSecondLimit) * 100); |         const percent = Math.round((Math.min(vbytesPerSecond, this.vBytesPerSecondLimit) / this.vBytesPerSecondLimit) * 100); | ||||||
| 
 | 
 | ||||||
| @ -126,6 +129,8 @@ export class DashboardComponent implements OnInit, OnDestroy, AfterViewInit { | |||||||
|       }) |       }) | ||||||
|     ); |     ); | ||||||
| 
 | 
 | ||||||
|  |     this.mempoolInfoSubscription = this.mempoolInfoData$.subscribe(); | ||||||
|  | 
 | ||||||
|     this.mempoolBlocksData$ = this.stateService.mempoolBlocks$ |     this.mempoolBlocksData$ = this.stateService.mempoolBlocks$ | ||||||
|       .pipe( |       .pipe( | ||||||
|         map((mempoolBlocks) => { |         map((mempoolBlocks) => { | ||||||
| @ -347,4 +352,15 @@ export class DashboardComponent implements OnInit, OnDestroy, AfterViewInit { | |||||||
|   trackByBlock(index: number, block: BlockExtended) { |   trackByBlock(index: number, block: BlockExtended) { | ||||||
|     return block.height; |     return block.height; | ||||||
|   } |   } | ||||||
|  | 
 | ||||||
|  |   @HostListener('window:resize', ['$event']) | ||||||
|  |   onResize(): void { | ||||||
|  |     if (window.innerWidth >= 992) { | ||||||
|  |       this.incomingGraphHeight = 300; | ||||||
|  |     } else if (window.innerWidth >= 768) { | ||||||
|  |       this.incomingGraphHeight = 215; | ||||||
|  |     } else { | ||||||
|  |       this.incomingGraphHeight = 180; | ||||||
|  |     } | ||||||
|  |   } | ||||||
| } | } | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user