mirror of
https://github.com/mempool/mempool.git
synced 2024-12-28 01:04:28 +01:00
Merge pull request #1596 from mempool/nymkappa/feature/indexing-progress
Create indexing progress sticky notification
This commit is contained in:
commit
61a054b40f
@ -221,9 +221,10 @@ class Blocks {
|
|||||||
const lastBlockToIndex = Math.max(0, currentBlockHeight - indexingBlockAmount + 1);
|
const lastBlockToIndex = Math.max(0, currentBlockHeight - indexingBlockAmount + 1);
|
||||||
|
|
||||||
logger.debug(`Indexing blocks from #${currentBlockHeight} to #${lastBlockToIndex}`);
|
logger.debug(`Indexing blocks from #${currentBlockHeight} to #${lastBlockToIndex}`);
|
||||||
|
loadingIndicators.setProgress('block-indexing', 0);
|
||||||
|
|
||||||
const chunkSize = 10000;
|
const chunkSize = 10000;
|
||||||
let totaIndexed = await blocksRepository.$blockCount(null, null);
|
let totalIndexed = await blocksRepository.$blockCountBetweenHeight(currentBlockHeight, lastBlockToIndex);
|
||||||
let indexedThisRun = 0;
|
let indexedThisRun = 0;
|
||||||
let newlyIndexed = 0;
|
let newlyIndexed = 0;
|
||||||
const startedAt = new Date().getTime() / 1000;
|
const startedAt = new Date().getTime() / 1000;
|
||||||
@ -246,16 +247,17 @@ class Blocks {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
++indexedThisRun;
|
++indexedThisRun;
|
||||||
++totaIndexed;
|
++totalIndexed;
|
||||||
const elapsedSeconds = Math.max(1, Math.round((new Date().getTime() / 1000) - timer));
|
const elapsedSeconds = Math.max(1, Math.round((new Date().getTime() / 1000) - timer));
|
||||||
if (elapsedSeconds > 5 || blockHeight === lastBlockToIndex) {
|
if (elapsedSeconds > 5 || blockHeight === lastBlockToIndex) {
|
||||||
const runningFor = Math.max(1, Math.round((new Date().getTime() / 1000) - startedAt));
|
const runningFor = Math.max(1, Math.round((new Date().getTime() / 1000) - startedAt));
|
||||||
const blockPerSeconds = Math.max(1, Math.round(indexedThisRun / elapsedSeconds));
|
const blockPerSeconds = Math.max(1, Math.round(indexedThisRun / elapsedSeconds));
|
||||||
const progress = Math.round(totaIndexed / indexingBlockAmount * 100);
|
const progress = Math.round(totalIndexed / indexingBlockAmount * 10000) / 100;
|
||||||
const timeLeft = Math.round((indexingBlockAmount - totaIndexed) / blockPerSeconds);
|
const timeLeft = Math.round((indexingBlockAmount - totalIndexed) / blockPerSeconds);
|
||||||
logger.debug(`Indexing block #${blockHeight} | ~${blockPerSeconds} blocks/sec | total: ${totaIndexed}/${indexingBlockAmount} (${progress}%) | elapsed: ${runningFor} seconds | left: ~${timeLeft} seconds`);
|
logger.debug(`Indexing block #${blockHeight} | ~${blockPerSeconds.toFixed(2)} blocks/sec | total: ${totalIndexed}/${indexingBlockAmount} (${progress}%) | elapsed: ${runningFor} seconds | left: ~${timeLeft} seconds`);
|
||||||
timer = new Date().getTime() / 1000;
|
timer = new Date().getTime() / 1000;
|
||||||
indexedThisRun = 0;
|
indexedThisRun = 0;
|
||||||
|
loadingIndicators.setProgress('block-indexing', progress, false);
|
||||||
}
|
}
|
||||||
const blockHash = await bitcoinApi.$getBlockHash(blockHeight);
|
const blockHash = await bitcoinApi.$getBlockHash(blockHeight);
|
||||||
const block = BitcoinApi.convertBlock(await bitcoinClient.getBlock(blockHash));
|
const block = BitcoinApi.convertBlock(await bitcoinClient.getBlock(blockHash));
|
||||||
@ -269,9 +271,11 @@ class Blocks {
|
|||||||
currentBlockHeight -= chunkSize;
|
currentBlockHeight -= chunkSize;
|
||||||
}
|
}
|
||||||
logger.info(`Indexed ${newlyIndexed} blocks`);
|
logger.info(`Indexed ${newlyIndexed} blocks`);
|
||||||
|
loadingIndicators.setProgress('block-indexing', 100);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
logger.err('Block indexing failed. Trying again later. Reason: ' + (e instanceof Error ? e.message : e));
|
logger.err('Block indexing failed. Trying again later. Reason: ' + (e instanceof Error ? e.message : e));
|
||||||
this.blockIndexingStarted = false;
|
this.blockIndexingStarted = false;
|
||||||
|
loadingIndicators.setProgress('block-indexing', 100);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -12,8 +12,8 @@ class LoadingIndicators {
|
|||||||
this.progressChangedCallback = fn;
|
this.progressChangedCallback = fn;
|
||||||
}
|
}
|
||||||
|
|
||||||
public setProgress(name: string, progressPercent: number) {
|
public setProgress(name: string, progressPercent: number, rounded: boolean = true) {
|
||||||
const newProgress = Math.round(progressPercent);
|
const newProgress = rounded === true ? Math.round(progressPercent) : progressPercent;
|
||||||
if (newProgress >= 100) {
|
if (newProgress >= 100) {
|
||||||
delete this.loadingIndicators[name];
|
delete this.loadingIndicators[name];
|
||||||
} else {
|
} else {
|
||||||
|
@ -6,6 +6,7 @@ import bitcoinClient from './bitcoin/bitcoin-client';
|
|||||||
import logger from '../logger';
|
import logger from '../logger';
|
||||||
import blocks from './blocks';
|
import blocks from './blocks';
|
||||||
import { Common } from './common';
|
import { Common } from './common';
|
||||||
|
import loadingIndicators from './loading-indicators';
|
||||||
|
|
||||||
class Mining {
|
class Mining {
|
||||||
hashrateIndexingStarted = false;
|
hashrateIndexingStarted = false;
|
||||||
@ -131,7 +132,7 @@ class Mining {
|
|||||||
* [INDEXING] Generate weekly mining pool hashrate history
|
* [INDEXING] Generate weekly mining pool hashrate history
|
||||||
*/
|
*/
|
||||||
public async $generatePoolHashrateHistory(): Promise<void> {
|
public async $generatePoolHashrateHistory(): Promise<void> {
|
||||||
if (!blocks.blockIndexingCompleted || this.weeklyHashrateIndexingStarted) {
|
if (!blocks.blockIndexingCompleted || this.hashrateIndexingStarted || this.weeklyHashrateIndexingStarted) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -167,7 +168,10 @@ class Mining {
|
|||||||
let indexedThisRun = 0;
|
let indexedThisRun = 0;
|
||||||
let totalIndexed = 0;
|
let totalIndexed = 0;
|
||||||
let newlyIndexed = 0;
|
let newlyIndexed = 0;
|
||||||
let startedAt = new Date().getTime();
|
const startedAt = new Date().getTime() / 1000;
|
||||||
|
let timer = new Date().getTime() / 1000;
|
||||||
|
|
||||||
|
loadingIndicators.setProgress('weekly-hashrate-indexing', 0);
|
||||||
|
|
||||||
while (toTimestamp > genesisTimestamp) {
|
while (toTimestamp > genesisTimestamp) {
|
||||||
const fromTimestamp = toTimestamp - 604800000;
|
const fromTimestamp = toTimestamp - 604800000;
|
||||||
@ -214,14 +218,17 @@ class Mining {
|
|||||||
await HashratesRepository.$saveHashrates(hashrates);
|
await HashratesRepository.$saveHashrates(hashrates);
|
||||||
hashrates.length = 0;
|
hashrates.length = 0;
|
||||||
|
|
||||||
const elapsedSeconds = Math.max(1, Math.round((new Date().getTime()) - startedAt)) / 1000;
|
const elapsedSeconds = Math.max(1, Math.round((new Date().getTime() / 1000) - timer));
|
||||||
if (elapsedSeconds > 1) {
|
if (elapsedSeconds > 1) {
|
||||||
const weeksPerSeconds = (indexedThisRun / elapsedSeconds).toFixed(2);
|
const runningFor = Math.max(1, Math.round((new Date().getTime() / 1000) - startedAt));
|
||||||
|
const weeksPerSeconds = Math.max(1, Math.round(indexedThisRun / elapsedSeconds));
|
||||||
|
const progress = Math.round(totalIndexed / totalWeekIndexed * 10000) / 100;
|
||||||
|
const timeLeft = Math.round((totalWeekIndexed - totalIndexed) / weeksPerSeconds);
|
||||||
const formattedDate = new Date(fromTimestamp).toUTCString();
|
const formattedDate = new Date(fromTimestamp).toUTCString();
|
||||||
const weeksLeft = Math.round(totalWeekIndexed - totalIndexed);
|
logger.debug(`Getting weekly pool hashrate for ${formattedDate} | ~${weeksPerSeconds.toFixed(2)} weeks/sec | total: ~${totalIndexed}/${Math.round(totalWeekIndexed)} (${progress}%) | elapsed: ${runningFor} seconds | left: ~${timeLeft} seconds`);
|
||||||
logger.debug(`Getting weekly pool hashrate for ${formattedDate} | ~${weeksPerSeconds} weeks/sec | ~${weeksLeft} weeks left to index`);
|
timer = new Date().getTime() / 1000;
|
||||||
startedAt = new Date().getTime();
|
|
||||||
indexedThisRun = 0;
|
indexedThisRun = 0;
|
||||||
|
loadingIndicators.setProgress('weekly-hashrate-indexing', progress, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
toTimestamp -= 604800000;
|
toTimestamp -= 604800000;
|
||||||
@ -233,7 +240,9 @@ class Mining {
|
|||||||
if (newlyIndexed > 0) {
|
if (newlyIndexed > 0) {
|
||||||
logger.info(`Indexed ${newlyIndexed} pools weekly hashrate`);
|
logger.info(`Indexed ${newlyIndexed} pools weekly hashrate`);
|
||||||
}
|
}
|
||||||
|
loadingIndicators.setProgress('weekly-hashrate-indexing', 100);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
|
loadingIndicators.setProgress('weekly-hashrate-indexing', 100);
|
||||||
this.weeklyHashrateIndexingStarted = false;
|
this.weeklyHashrateIndexingStarted = false;
|
||||||
throw e;
|
throw e;
|
||||||
}
|
}
|
||||||
@ -273,7 +282,10 @@ class Mining {
|
|||||||
let indexedThisRun = 0;
|
let indexedThisRun = 0;
|
||||||
let totalIndexed = 0;
|
let totalIndexed = 0;
|
||||||
let newlyIndexed = 0;
|
let newlyIndexed = 0;
|
||||||
let startedAt = new Date().getTime();
|
const startedAt = new Date().getTime() / 1000;
|
||||||
|
let timer = new Date().getTime() / 1000;
|
||||||
|
|
||||||
|
loadingIndicators.setProgress('daily-hashrate-indexing', 0);
|
||||||
|
|
||||||
while (toTimestamp > genesisTimestamp) {
|
while (toTimestamp > genesisTimestamp) {
|
||||||
const fromTimestamp = toTimestamp - 86400000;
|
const fromTimestamp = toTimestamp - 86400000;
|
||||||
@ -312,15 +324,17 @@ class Mining {
|
|||||||
hashrates.length = 0;
|
hashrates.length = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
const elapsedSeconds = Math.max(1, Math.round(new Date().getTime() - startedAt)) / 1000;
|
const elapsedSeconds = Math.max(1, Math.round((new Date().getTime() / 1000) - timer));
|
||||||
if (elapsedSeconds > 1) {
|
if (elapsedSeconds > 1) {
|
||||||
const daysPerSeconds = (indexedThisRun / elapsedSeconds).toFixed(2);
|
const runningFor = Math.max(1, Math.round((new Date().getTime() / 1000) - startedAt));
|
||||||
|
const daysPerSeconds = Math.max(1, Math.round(indexedThisRun / elapsedSeconds));
|
||||||
|
const progress = Math.round(totalIndexed / totalDayIndexed * 10000) / 100;
|
||||||
|
const timeLeft = Math.round((totalDayIndexed - totalIndexed) / daysPerSeconds);
|
||||||
const formattedDate = new Date(fromTimestamp).toUTCString();
|
const formattedDate = new Date(fromTimestamp).toUTCString();
|
||||||
const daysLeft = Math.round(totalDayIndexed - totalIndexed);
|
logger.debug(`Getting network daily hashrate for ${formattedDate} | ~${daysPerSeconds.toFixed(2)} days/sec | total: ~${totalIndexed}/${Math.round(totalDayIndexed)} (${progress}%) | elapsed: ${runningFor} seconds | left: ~${timeLeft} seconds`);
|
||||||
logger.debug(`Getting network daily hashrate for ${formattedDate} | ~${daysPerSeconds} days/sec | ` +
|
timer = new Date().getTime() / 1000;
|
||||||
`~${daysLeft} days left to index`);
|
|
||||||
startedAt = new Date().getTime();
|
|
||||||
indexedThisRun = 0;
|
indexedThisRun = 0;
|
||||||
|
loadingIndicators.setProgress('daily-hashrate-indexing', progress);
|
||||||
}
|
}
|
||||||
|
|
||||||
toTimestamp -= 86400000;
|
toTimestamp -= 86400000;
|
||||||
@ -346,7 +360,9 @@ class Mining {
|
|||||||
if (newlyIndexed > 0) {
|
if (newlyIndexed > 0) {
|
||||||
logger.info(`Indexed ${newlyIndexed} day of network hashrate`);
|
logger.info(`Indexed ${newlyIndexed} day of network hashrate`);
|
||||||
}
|
}
|
||||||
|
loadingIndicators.setProgress('daily-hashrate-indexing', 100);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
|
loadingIndicators.setProgress('daily-hashrate-indexing', 100);
|
||||||
this.hashrateIndexingStarted = false;
|
this.hashrateIndexingStarted = false;
|
||||||
throw e;
|
throw e;
|
||||||
}
|
}
|
||||||
|
@ -188,6 +188,24 @@ class BlocksRepository {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get blocks count for a period
|
||||||
|
*/
|
||||||
|
public async $blockCountBetweenHeight(startHeight: number, endHeight: number): Promise<number> {
|
||||||
|
const params: any[] = [];
|
||||||
|
let query = `SELECT count(height) as blockCount
|
||||||
|
FROM blocks
|
||||||
|
WHERE height <= ${startHeight} AND height >= ${endHeight}`;
|
||||||
|
|
||||||
|
try {
|
||||||
|
const [rows] = await DB.query(query, params);
|
||||||
|
return <number>rows[0].blockCount;
|
||||||
|
} catch (e) {
|
||||||
|
logger.err(`Cannot count blocks for this pool (using offset). Reason: ` + (e instanceof Error ? e.message : e));
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the oldest indexed block
|
* Get the oldest indexed block
|
||||||
*/
|
*/
|
||||||
|
@ -76,6 +76,8 @@ import { DataCyDirective } from './data-cy.directive';
|
|||||||
import { BlockFeesGraphComponent } from './components/block-fees-graph/block-fees-graph.component';
|
import { BlockFeesGraphComponent } from './components/block-fees-graph/block-fees-graph.component';
|
||||||
import { BlockRewardsGraphComponent } from './components/block-rewards-graph/block-rewards-graph.component';
|
import { BlockRewardsGraphComponent } from './components/block-rewards-graph/block-rewards-graph.component';
|
||||||
import { BlockFeeRatesGraphComponent } from './components/block-fee-rates-graph/block-fee-rates-graph.component';
|
import { BlockFeeRatesGraphComponent } from './components/block-fee-rates-graph/block-fee-rates-graph.component';
|
||||||
|
import { LoadingIndicatorComponent } from './components/loading-indicator/loading-indicator.component';
|
||||||
|
import { IndexingProgressComponent } from './components/indexing-progress/indexing-progress.component';
|
||||||
|
|
||||||
@NgModule({
|
@NgModule({
|
||||||
declarations: [
|
declarations: [
|
||||||
@ -132,6 +134,8 @@ import { BlockFeeRatesGraphComponent } from './components/block-fee-rates-graph/
|
|||||||
BlockFeesGraphComponent,
|
BlockFeesGraphComponent,
|
||||||
BlockRewardsGraphComponent,
|
BlockRewardsGraphComponent,
|
||||||
BlockFeeRatesGraphComponent,
|
BlockFeeRatesGraphComponent,
|
||||||
|
LoadingIndicatorComponent,
|
||||||
|
IndexingProgressComponent,
|
||||||
],
|
],
|
||||||
imports: [
|
imports: [
|
||||||
BrowserModule.withServerTransition({ appId: 'serverApp' }),
|
BrowserModule.withServerTransition({ appId: 'serverApp' }),
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
<app-indexing-progress></app-indexing-progress>
|
||||||
|
|
||||||
<div class="full-container">
|
<div class="full-container">
|
||||||
<div class="card-header mb-0 mb-md-4">
|
<div class="card-header mb-0 mb-md-4">
|
||||||
<span i18n="mining.block-fee-rates">Block fee rates</span>
|
<span i18n="mining.block-fee-rates">Block fee rates</span>
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
<app-indexing-progress></app-indexing-progress>
|
||||||
|
|
||||||
<div class="full-container">
|
<div class="full-container">
|
||||||
<div class="card-header mb-0 mb-md-4">
|
<div class="card-header mb-0 mb-md-4">
|
||||||
<span i18n="mining.block-fees">Block fees</span>
|
<span i18n="mining.block-fees">Block fees</span>
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
<app-indexing-progress></app-indexing-progress>
|
||||||
|
|
||||||
<div class="full-container">
|
<div class="full-container">
|
||||||
|
|
||||||
<div class="card-header mb-0 mb-md-4">
|
<div class="card-header mb-0 mb-md-4">
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
<app-indexing-progress *ngIf="!widget"></app-indexing-progress>
|
||||||
|
|
||||||
<div class="container-xl" [class]="widget ? 'widget' : 'full-height'">
|
<div class="container-xl" [class]="widget ? 'widget' : 'full-height'">
|
||||||
<h1 *ngIf="!widget" class="float-left" i18n="latest-blocks.blocks">Blocks</h1>
|
<h1 *ngIf="!widget" class="float-left" i18n="latest-blocks.blocks">Blocks</h1>
|
||||||
|
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
<app-indexing-progress *ngIf="!widget"></app-indexing-progress>
|
||||||
|
|
||||||
<div [class]="widget === false ? 'full-container' : ''">
|
<div [class]="widget === false ? 'full-container' : ''">
|
||||||
|
|
||||||
<div *ngIf="widget">
|
<div *ngIf="widget">
|
||||||
|
@ -136,16 +136,12 @@ export class HashrateChartComponent implements OnInit {
|
|||||||
prepareChartOptions(data) {
|
prepareChartOptions(data) {
|
||||||
let title: object;
|
let title: object;
|
||||||
if (data.hashrates.length === 0) {
|
if (data.hashrates.length === 0) {
|
||||||
const lastBlock = new Date(data.timestamp * 1000);
|
|
||||||
const dd = String(lastBlock.getDate()).padStart(2, '0');
|
|
||||||
const mm = String(lastBlock.getMonth() + 1).padStart(2, '0'); // January is 0!
|
|
||||||
const yyyy = lastBlock.getFullYear();
|
|
||||||
title = {
|
title = {
|
||||||
textStyle: {
|
textStyle: {
|
||||||
color: 'grey',
|
color: 'grey',
|
||||||
fontSize: 15
|
fontSize: 15
|
||||||
},
|
},
|
||||||
text: `Indexing in progess - ${yyyy}-${mm}-${dd}`,
|
text: `Indexing in progess`,
|
||||||
left: 'center',
|
left: 'center',
|
||||||
top: 'center'
|
top: 'center'
|
||||||
};
|
};
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
<app-indexing-progress></app-indexing-progress>
|
||||||
|
|
||||||
<div class="full-container">
|
<div class="full-container">
|
||||||
|
|
||||||
<div class="card-header mb-0 mb-md-4">
|
<div class="card-header mb-0 mb-md-4">
|
||||||
|
@ -150,16 +150,12 @@ export class HashrateChartPoolsComponent implements OnInit {
|
|||||||
prepareChartOptions(data) {
|
prepareChartOptions(data) {
|
||||||
let title: object;
|
let title: object;
|
||||||
if (data.series.length === 0) {
|
if (data.series.length === 0) {
|
||||||
const lastBlock = new Date(data.timestamp * 1000);
|
|
||||||
const dd = String(lastBlock.getDate()).padStart(2, '0');
|
|
||||||
const mm = String(lastBlock.getMonth() + 1).padStart(2, '0'); // January is 0!
|
|
||||||
const yyyy = lastBlock.getFullYear();
|
|
||||||
title = {
|
title = {
|
||||||
textStyle: {
|
textStyle: {
|
||||||
color: 'grey',
|
color: 'grey',
|
||||||
fontSize: 15
|
fontSize: 15
|
||||||
},
|
},
|
||||||
text: `Indexing in progess - ${yyyy}-${mm}-${dd}`,
|
text: `Indexing in progess`,
|
||||||
left: 'center',
|
left: 'center',
|
||||||
top: 'center',
|
top: 'center',
|
||||||
};
|
};
|
||||||
|
@ -0,0 +1,3 @@
|
|||||||
|
<app-loading-indicator [name]="'block-indexing'" i18n-label label="Indexing blocks"></app-loading-indicator>
|
||||||
|
<app-loading-indicator [name]="'daily-hashrate-indexing'" i18n-label label="Indexing network hashrate"></app-loading-indicator>
|
||||||
|
<app-loading-indicator [name]="'weekly-hashrate-indexing'" i18n-label label="Indexing pools hashrate"></app-loading-indicator>
|
@ -0,0 +1,14 @@
|
|||||||
|
import { ChangeDetectionStrategy, Component, OnInit } from '@angular/core';
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'app-indexing-progress',
|
||||||
|
templateUrl: './indexing-progress.component.html',
|
||||||
|
changeDetection: ChangeDetectionStrategy.OnPush
|
||||||
|
})
|
||||||
|
export class IndexingProgressComponent implements OnInit {
|
||||||
|
constructor(
|
||||||
|
) {}
|
||||||
|
|
||||||
|
ngOnInit() {
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,3 @@
|
|||||||
|
<div *ngIf="this.indexingProgress$ | async as progress" class="sticky-loading">
|
||||||
|
<span *ngIf="progress >= 0" class="mr-auto badge badge-pill badge-warning">{{ this.label }} ({{ progress }}%)</span>
|
||||||
|
</div>
|
@ -0,0 +1,18 @@
|
|||||||
|
.sticky-loading {
|
||||||
|
position: absolute;
|
||||||
|
right: 10px;
|
||||||
|
z-index: 100;
|
||||||
|
font-size: 14px;
|
||||||
|
@media (width >= 992px) {
|
||||||
|
left: 32px;
|
||||||
|
top: 55px;
|
||||||
|
}
|
||||||
|
@media (576px <= width < 992px ) {
|
||||||
|
left: 18px;
|
||||||
|
top: 55px;
|
||||||
|
}
|
||||||
|
@media (width <= 575px) {
|
||||||
|
left: 18px;
|
||||||
|
top: 100px;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,30 @@
|
|||||||
|
import { ChangeDetectionStrategy, Component, Input, OnInit } from '@angular/core';
|
||||||
|
import { Observable } from 'rxjs';
|
||||||
|
import { map } from 'rxjs/operators';
|
||||||
|
import { StateService } from 'src/app/services/state.service';
|
||||||
|
import { WebsocketService } from 'src/app/services/websocket.service';
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'app-loading-indicator',
|
||||||
|
templateUrl: './loading-indicator.component.html',
|
||||||
|
styleUrls: ['./loading-indicator.component.scss'],
|
||||||
|
changeDetection: ChangeDetectionStrategy.OnPush
|
||||||
|
})
|
||||||
|
export class LoadingIndicatorComponent implements OnInit {
|
||||||
|
@Input() name: string;
|
||||||
|
@Input() label: string;
|
||||||
|
|
||||||
|
public indexingProgress$: Observable<number>;
|
||||||
|
|
||||||
|
constructor(
|
||||||
|
private stateService: StateService,
|
||||||
|
private websocketService: WebsocketService
|
||||||
|
) {}
|
||||||
|
|
||||||
|
ngOnInit() {
|
||||||
|
this.indexingProgress$ = this.stateService.loadingIndicators$
|
||||||
|
.pipe(
|
||||||
|
map((indicators) => indicators[this.name] ?? -1)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
@ -1,3 +1,5 @@
|
|||||||
|
<app-indexing-progress></app-indexing-progress>
|
||||||
|
|
||||||
<div class="container-xl dashboard-container">
|
<div class="container-xl dashboard-container">
|
||||||
|
|
||||||
<div class="row row-cols-1 row-cols-md-2">
|
<div class="row row-cols-1 row-cols-md-2">
|
||||||
|
@ -1,8 +1,5 @@
|
|||||||
import { ChangeDetectionStrategy, Component, OnInit } from '@angular/core';
|
import { ChangeDetectionStrategy, Component, OnInit } from '@angular/core';
|
||||||
import { map } from 'rxjs/operators';
|
|
||||||
import { SeoService } from 'src/app/services/seo.service';
|
import { SeoService } from 'src/app/services/seo.service';
|
||||||
import { StateService } from 'src/app/services/state.service';
|
|
||||||
import { Observable } from 'rxjs';
|
|
||||||
import { WebsocketService } from 'src/app/services/websocket.service';
|
import { WebsocketService } from 'src/app/services/websocket.service';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
@ -12,8 +9,6 @@ import { WebsocketService } from 'src/app/services/websocket.service';
|
|||||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||||
})
|
})
|
||||||
export class MiningDashboardComponent implements OnInit {
|
export class MiningDashboardComponent implements OnInit {
|
||||||
private blocks = [];
|
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
private seoService: SeoService,
|
private seoService: SeoService,
|
||||||
private websocketService: WebsocketService,
|
private websocketService: WebsocketService,
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
<app-indexing-progress *ngIf="!widget"></app-indexing-progress>
|
||||||
|
|
||||||
<div [class]="widget === false ? 'full-container' : ''">
|
<div [class]="widget === false ? 'full-container' : ''">
|
||||||
|
|
||||||
<div *ngIf="widget">
|
<div *ngIf="widget">
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
<app-indexing-progress></app-indexing-progress>
|
||||||
|
|
||||||
<div class="container-xl">
|
<div class="container-xl">
|
||||||
|
|
||||||
<!-- Pool overview -->
|
<!-- Pool overview -->
|
||||||
|
@ -111,7 +111,7 @@ export class PoolComponent implements OnInit {
|
|||||||
color: 'grey',
|
color: 'grey',
|
||||||
fontSize: 15
|
fontSize: 15
|
||||||
},
|
},
|
||||||
text: `No data`,
|
text: `Indexing in progress`,
|
||||||
left: 'center',
|
left: 'center',
|
||||||
top: 'center'
|
top: 'center'
|
||||||
};
|
};
|
||||||
@ -164,14 +164,14 @@ export class PoolComponent implements OnInit {
|
|||||||
`;
|
`;
|
||||||
}.bind(this)
|
}.bind(this)
|
||||||
},
|
},
|
||||||
xAxis: {
|
xAxis: data.length === 0 ? undefined : {
|
||||||
type: 'time',
|
type: 'time',
|
||||||
splitNumber: (this.isMobile()) ? 5 : 10,
|
splitNumber: (this.isMobile()) ? 5 : 10,
|
||||||
axisLabel: {
|
axisLabel: {
|
||||||
hideOverlap: true,
|
hideOverlap: true,
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
yAxis: [
|
yAxis: data.length === 0 ? undefined : [
|
||||||
{
|
{
|
||||||
min: (value) => {
|
min: (value) => {
|
||||||
return value.min * 0.9;
|
return value.min * 0.9;
|
||||||
@ -190,7 +190,7 @@ export class PoolComponent implements OnInit {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
series: [
|
series: data.length === 0 ? undefined : [
|
||||||
{
|
{
|
||||||
zlevel: 0,
|
zlevel: 0,
|
||||||
name: 'Hashrate',
|
name: 'Hashrate',
|
||||||
|
Loading…
Reference in New Issue
Block a user