165 lines
9.8 KiB
HTML
165 lines
9.8 KiB
HTML
<app-indexing-progress *ngIf="!widget"></app-indexing-progress>
|
|
|
|
<div [class]="widget === false ? 'full-container' : ''">
|
|
|
|
<div *ngIf="widget">
|
|
<div class="pool-distribution" *ngIf="(miningStatsObservable$ | async) as miningStats; else loadingReward">
|
|
<div class="item">
|
|
<h5 class="card-title d-inline-block" i18n="mining.miners-luck" i18n-ngbTooltip="mining.miners-luck-1w"
|
|
ngbTooltip="Pools luck (1 week)" placement="bottom" #minersluck [disableTooltip]="!isEllipsisActive(minersluck)">Pools luck</h5>
|
|
<p class="card-text" i18n-ngbTooltip="mining.pools-luck-desc"
|
|
ngbTooltip="The overall luck of all mining pools over the past week. A luck bigger than 100% means the average block time for the current epoch is less than 10 minutes." placement="bottom">
|
|
{{ miningStats['minersLuck'] }}%
|
|
</p>
|
|
</div>
|
|
<div class="item">
|
|
<h5 class="card-title d-inline-block" i18n="mining.miners-count" i18n-ngbTooltip="mining.miners-count-1w"
|
|
ngbTooltip="Pools count (1w)" placement="bottom" #poolscount [disableTooltip]="!isEllipsisActive(poolscount)">Pools count</h5>
|
|
<p class="card-text" i18n-ngbTooltip="mining.pools-count-desc"
|
|
ngbTooltip="How many unique pools found at least one block over the past week." placement="bottom">
|
|
{{ miningStats.pools.length }}
|
|
</p>
|
|
</div>
|
|
<div class="item">
|
|
<h5 class="card-title d-inline-block" i18n="master-page.blocks" i18n-ngbTooltip="master-page.blocks"
|
|
ngbTooltip="Blocks (1w)" placement="bottom" #blockscount [disableTooltip]="!isEllipsisActive(blockscount)">Blocks (1w)</h5>
|
|
<p class="card-text" i18n-ngbTooltip="mining.blocks-count-desc"
|
|
ngbTooltip="The number of blocks found over the past week." placement="bottom">
|
|
{{ miningStats.blockCount }}
|
|
</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="card-header" *ngIf="!widget">
|
|
<div class="d-flex d-md-table-cell align-items-baseline">
|
|
<span i18n="mining.pools">Pools Ranking</span>
|
|
<button class="btn p-0 pl-2" style="margin: 0 0 4px 0px" (click)="onSaveChart()">
|
|
<fa-icon [icon]="['fas', 'download']" [fixedWidth]="true"></fa-icon>
|
|
</button>
|
|
</div>
|
|
<form [formGroup]="radioGroupForm" class="formRadioGroup"
|
|
*ngIf="!widget && (miningStatsObservable$ | async) as stats">
|
|
<div class="btn-group btn-group-toggle" name="radioBasic" [class]="{'disabled': isLoading}">
|
|
<label class="btn btn-primary btn-sm" *ngIf="stats.totalBlockCount >= 144" [class.active]="radioGroupForm.get('dateSpan').value === '24h'">
|
|
<input type="radio" [value]="'24h'" fragment="24h" [routerLink]="['/graphs/mining/pools' | relativeUrl]" [attr.data-cy]="'24h'" formControlName="dateSpan"> 24h
|
|
</label>
|
|
<label class="btn btn-primary btn-sm" *ngIf="stats.totalBlockCount >= 432" [class.active]="radioGroupForm.get('dateSpan').value === '3d'">
|
|
<input type="radio" [value]="'3d'" fragment="3d" [routerLink]="['/graphs/mining/pools' | relativeUrl]" [attr.data-cy]="'3d'" formControlName="dateSpan"> 3D
|
|
</label>
|
|
<label class="btn btn-primary btn-sm" *ngIf="stats.totalBlockCount >= 1008" [class.active]="radioGroupForm.get('dateSpan').value === '1w'">
|
|
<input type="radio" [value]="'1w'" fragment="1w" [routerLink]="['/graphs/mining/pools' | relativeUrl]" [attr.data-cy]="'1w'" formControlName="dateSpan"> 1W
|
|
</label>
|
|
<label class="btn btn-primary btn-sm" *ngIf="stats.totalBlockCount >= 4320" [class.active]="radioGroupForm.get('dateSpan').value === '1m'">
|
|
<input type="radio" [value]="'1m'" fragment="1m" [routerLink]="['/graphs/mining/pools' | relativeUrl]" [attr.data-cy]="'1m'" formControlName="dateSpan"> 1M
|
|
</label>
|
|
<label class="btn btn-primary btn-sm" *ngIf="stats.totalBlockCount >= 12960" [class.active]="radioGroupForm.get('dateSpan').value === '3m'">
|
|
<input type="radio" [value]="'3m'" fragment="3m" [routerLink]="['/graphs/mining/pools' | relativeUrl]" [attr.data-cy]="'3m'" formControlName="dateSpan"> 3M
|
|
</label>
|
|
<label class="btn btn-primary btn-sm" *ngIf="stats.totalBlockCount >= 25920" [class.active]="radioGroupForm.get('dateSpan').value === '6m'">
|
|
<input type="radio" [value]="'6m'" fragment="6m" [routerLink]="['/graphs/mining/pools' | relativeUrl]" [attr.data-cy]="'6m'" formControlName="dateSpan"> 6M
|
|
</label>
|
|
<label class="btn btn-primary btn-sm" *ngIf="stats.totalBlockCount >= 52560" [class.active]="radioGroupForm.get('dateSpan').value === '1y'">
|
|
<input type="radio" [value]="'1y'" fragment="1y" [routerLink]="['/graphs/mining/pools' | relativeUrl]" [attr.data-cy]="'1y'" formControlName="dateSpan"> 1Y
|
|
</label>
|
|
<label class="btn btn-primary btn-sm" *ngIf="stats.totalBlockCount >= 105120" [class.active]="radioGroupForm.get('dateSpan').value === '2y'">
|
|
<input type="radio" [value]="'2y'" fragment="2y" [routerLink]="['/graphs/mining/pools' | relativeUrl]" [attr.data-cy]="'2y'" formControlName="dateSpan"> 2Y
|
|
</label>
|
|
<label class="btn btn-primary btn-sm" *ngIf="stats.totalBlockCount >= 157680" [class.active]="radioGroupForm.get('dateSpan').value === '3y'">
|
|
<input type="radio" [value]="'3y'" fragment="3y" [routerLink]="['/graphs/mining/pools' | relativeUrl]" [attr.data-cy]="'3y'" formControlName="dateSpan"> 3Y
|
|
</label>
|
|
<label class="btn btn-primary btn-sm" [class.active]="radioGroupForm.get('dateSpan').value === 'all'">
|
|
<input type="radio" [value]="'all'" fragment="all" [routerLink]="['/graphs/mining/pools' | relativeUrl]" [attr.data-cy]="'all'" formControlName="dateSpan"><span i18n>All</span>
|
|
</label>
|
|
</div>
|
|
</form>
|
|
</div>
|
|
|
|
<div [class]="!widget ? 'bottom-padding' : 'pb-0'" class="container pb-lg-0">
|
|
<div [class]="widget ? 'chart-widget' : 'chart'" echarts [initOpts]="chartInitOptions" [options]="chartOptions"
|
|
(chartInit)="onChartInit($event)">
|
|
</div>
|
|
|
|
<div class="text-center loadingGraphs" *ngIf="isLoading">
|
|
<div class="spinner-border text-light"></div>
|
|
</div>
|
|
|
|
<table *ngIf="widget === false" class="table table-borderless text-center pools-table">
|
|
<thead>
|
|
<tr>
|
|
<th class="d-none d-md-table-cell" i18n="mining.rank">Rank</th>
|
|
<th class=""></th>
|
|
<th class="" i18n="mining.pool-name">Pool</th>
|
|
<th class="" *ngIf="this.miningWindowPreference === '24h'" i18n="mining.hashrate">Hashrate</th>
|
|
<th class="" i18n="master-page.blocks">Blocks</th>
|
|
<th *ngIf="auditAvailable" class="health text-right widget" i18n="latest-blocks.avg_health"
|
|
i18n-ngbTooltip="latest-blocks.avg_health" ngbTooltip="Avg Health" placement="bottom" #health [disableTooltip]="!isEllipsisActive(health)">Avg Health</th>
|
|
<th class="d-none d-md-table-cell" i18n="mining.empty-blocks">Empty blocks</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody [attr.data-cy]="'pools-table'" *ngIf="(miningStatsObservable$ | async) as miningStats">
|
|
<tr *ngFor="let pool of miningStats.pools">
|
|
<td class="d-none d-md-table-cell">{{ pool.rank }}</td>
|
|
<td class="text-right">
|
|
<img width="25" height="25" src="{{ pool.logo }}" [alt]="pool.name + ' mining pool logo'" onError="this.src = '/resources/mining-pools/default.svg'">
|
|
</td>
|
|
<td class=""><a [routerLink]="[('/mining/pool/' + pool.slug) | relativeUrl]">{{ pool.name }}</a></td>
|
|
<td class="" *ngIf="this.miningWindowPreference === '24h'">{{ pool.lastEstimatedHashrate }} {{
|
|
miningStats.miningUnits.hashrateUnit }}</td>
|
|
<td class="d-flex justify-content-center">
|
|
{{ pool.blockCount }}<span class="d-none d-md-table-cell"> ({{ pool.share }}%)</span>
|
|
</td>
|
|
<td *ngIf="auditAvailable" class="health text-right" [ngClass]="{'widget': widget, 'legacy': !indexingAvailable}">
|
|
<a
|
|
class="health-badge badge"
|
|
[class.badge-success]="pool.avgMatchRate >= 99"
|
|
[class.badge-warning]="pool.avgMatchRate >= 75 && pool.avgMatchRate < 99"
|
|
[class.badge-danger]="pool.avgMatchRate < 75"
|
|
*ngIf="pool.avgMatchRate != null; else nullHealth"
|
|
>{{ pool.avgMatchRate }}%</a>
|
|
<ng-template #nullHealth>
|
|
<span class="health-badge badge badge-secondary" i18n="unknown">Unknown</span>
|
|
</ng-template>
|
|
</td>
|
|
<td class="d-none d-md-table-cell">{{ pool.emptyBlocks }} ({{ pool.emptyBlockRatio }}%)</td>
|
|
</tr>
|
|
<tr style="border-top: 1px solid #555">
|
|
<td class="d-none d-md-table-cell"></td>
|
|
<td class="text-right"></td>
|
|
<td class=""><b i18n="mining.all-miners">All miners</b></td>
|
|
<td class="" *ngIf="this.miningWindowPreference === '24h'"><b>{{ miningStats.lastEstimatedHashrate}} {{
|
|
miningStats.miningUnits.hashrateUnit }}</b></td>
|
|
<td class=""><b>{{ miningStats.blockCount }}</b></td>
|
|
<td class="d-none d-md-table-cell"><b>{{ miningStats.totalEmptyBlock }} ({{ miningStats.totalEmptyBlockRatio
|
|
}}%)</b></td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
|
|
</div>
|
|
|
|
|
|
<ng-template #loadingReward>
|
|
<div class="pool-distribution">
|
|
<div class="item">
|
|
<h5 class="card-title" i18n="mining.miners-luck">Pools Luck (1w)</h5>
|
|
<p class="card-text">
|
|
<span class="skeleton-loader skeleton-loader-big"></span>
|
|
</p>
|
|
</div>
|
|
<div class="item">
|
|
<h5 class="card-title" i18n="master-page.blocks">Blocks (1w)</h5>
|
|
<p class="card-text">
|
|
<span class="skeleton-loader skeleton-loader-big"></span>
|
|
</p>
|
|
</div>
|
|
<div class="item">
|
|
<h5 class="card-title" i18n="mining.miners-count">Pools Count (1w)</h5>
|
|
<p class="card-text">
|
|
<span class="skeleton-loader skeleton-loader-big"></span>
|
|
</p>
|
|
</div>
|
|
</div>
|
|
</ng-template>
|