diff --git a/frontend/src/components/nodes/ValidatingLabel.tsx b/frontend/src/components/nodes/ValidatingLabel.tsx index 6c0e0ae52..a0e387aa4 100644 --- a/frontend/src/components/nodes/ValidatingLabel.tsx +++ b/frontend/src/components/nodes/ValidatingLabel.tsx @@ -45,6 +45,10 @@ class ValidatingLabel extends React.PureComponent { background-color: #dc3545; color: #ffffff; } + .validating-label.inactive { + background-color: #e5e5e6; + color: #72727a; + } `} diff --git a/frontend/src/components/nodes/ValidatorCollapsedRow.tsx b/frontend/src/components/nodes/ValidatorCollapsedRow.tsx index a9f57e048..b81fb14b1 100644 --- a/frontend/src/components/nodes/ValidatorCollapsedRow.tsx +++ b/frontend/src/components/nodes/ValidatorCollapsedRow.tsx @@ -1,18 +1,15 @@ -import React, { PureComponent } from "react"; - -import { Badge, Row, Col } from "react-bootstrap"; - -import { DatabaseConsumer } from "../../context/DatabaseProvider"; +import React, { Component } from "react"; import { TableCollapseRow } from "../utils/Table"; -import Term from "../utils/Term"; -import Timer from "../utils/Timer"; + +import ValidatorMetadataRow from "./ValidatorMetadataRow"; +import ValidatorTelemetryRow from "./ValidatorTelemetryRow"; interface Props { isRowActive: boolean; producedBlocks?: number; expectedBlocks?: number; - validatorsLatestBlock?: number; + latestProducedValidatorBlock?: number; lastSeen?: number; agentName?: string; agentVersion?: string; @@ -24,13 +21,13 @@ interface Props { poolDescription?: string; } -class ValidatorCollapsedRow extends PureComponent { +class ValidatorCollapsedRow extends Component { render() { const { isRowActive, producedBlocks, expectedBlocks, - validatorsLatestBlock, + latestProducedValidatorBlock, lastSeen, agentName, agentVersion, @@ -42,284 +39,31 @@ class ValidatorCollapsedRow extends PureComponent { poolDescription, } = this.props; - const poolDetailsAvailable = - Boolean(poolWebsite) || - Boolean(poolEmail) || - Boolean(poolTwitter) || - Boolean(poolDiscord) || - Boolean(poolDescription); - return ( - - {({ latestBlockHeight }) => ( - <> - - - {producedBlocks && expectedBlocks && ( - - {producedBlocks && expectedBlocks && ( - - - - - - - - - {producedBlocks && expectedBlocks ? ( - <> - {( - (producedBlocks / expectedBlocks) * - 100 - ).toFixed(3)} - %   - - ({producedBlocks}/{expectedBlocks}) - - - ) : null} - - - - )} - {validatorsLatestBlock && ( - - - - - - - - 1000 - ? "text-danger" - : Math.abs( - validatorsLatestBlock - - latestBlockHeight.toNumber() - ) > 50 - ? "text-warning" - : "" - } validator-nodes-text`} - md={3} - > - {` ${validatorsLatestBlock}`} - - - - )} - {lastSeen && ( - - - - - - - - - {lastSeen ? : "..."} - - - - )} - {agentName && ( - - - - - { - "NEAR Protocol could have multiple implementations, so agent is the name of that implementation, where 'near-rs' is " - } - - {"the official implementation"} - - {"."} - - } - /> - - - - - {agentName ? ( - - {agentName} - - ) : ( - "..." - )} - - - - )} - {agentVersion && agentBuild && ( - - - - {"Node Agent Version / Build"} - - - - - {agentVersion && agentBuild ? ( - - {`v${agentVersion} / ${agentBuild}`} - - ) : ( - "..." - )} - - - - )} - - )} + + + - - {poolDetailsAvailable ? ( - <> - {poolWebsite && ( - - - - Web - - - - - - {poolWebsite} - - - - - )} - {poolEmail && ( - - - - Email - - - - - {poolEmail} - - - - )} - {poolTwitter && ( - - - - Twitter - - - - - - {poolTwitter} - - - - - )} - {poolDiscord && ( - - - - Discord - - - - - - {poolDiscord} - - - - - )} - {poolDescription && ( - - - - Description - - - - - {poolDescription} - - - - )} - - ) : ( - -

- If you are node owner feel free to fill all{" "} - - data - {" "} - to promote your own node! -

- - )} -
- -
- - )} -
+ + + ); } } diff --git a/frontend/src/components/nodes/ValidatorMainRow.tsx b/frontend/src/components/nodes/ValidatorMainRow.tsx index c2ebedcec..62782b114 100644 --- a/frontend/src/components/nodes/ValidatorMainRow.tsx +++ b/frontend/src/components/nodes/ValidatorMainRow.tsx @@ -22,9 +22,9 @@ interface Props { validatorFee: string | null; validatorDelegators: number | string | null; stake: string; - stakeProposed?: string; + proposedStakePerNextEpoch?: string; cumulativeStake: number; - persntStake: number; + totalStakeInPersnt: number; handleClick: React.MouseEventHandler; } @@ -41,22 +41,26 @@ class ValidatorMainRow extends PureComponent { validatorFee, validatorDelegators, stake, - stakeProposed, + proposedStakePerNextEpoch, cumulativeStake, - persntStake, + totalStakeInPersnt, handleClick, } = this.props; const stakeProposedAmount = - stakeProposed && - (new BN(stake).gt(new BN(stakeProposed)) + proposedStakePerNextEpoch && + (new BN(stake).gt(new BN(proposedStakePerNextEpoch)) ? { - value: new BN(stake).sub(new BN(stakeProposed)).toString(), + value: new BN(stake) + .sub(new BN(proposedStakePerNextEpoch)) + .toString(), increace: false, } - : new BN(stake).lt(new BN(stakeProposed)) + : new BN(stake).lt(new BN(proposedStakePerNextEpoch)) ? { - value: new BN(stakeProposed).sub(new BN(stake)).toString(), + value: new BN(proposedStakePerNextEpoch) + .sub(new BN(stake)) + .toString(), increace: true, } : "same"); @@ -110,9 +114,6 @@ class ValidatorMainRow extends PureComponent { ).toString()} tooltipKey="nodes" > - {/* {translate( - "component.nodes.ValidatorRow.state.pending.title" - )} */} Proposal ) : validatorStatus === "new" ? ( @@ -151,7 +152,15 @@ class ValidatorMainRow extends PureComponent { "component.nodes.ValidatorRow.state.active.title" )} - ) : null} + ) : ( + + Inactive + + )} @@ -213,7 +222,7 @@ class ValidatorMainRow extends PureComponent { diff --git a/frontend/src/components/nodes/ValidatorMetadataRow.tsx b/frontend/src/components/nodes/ValidatorMetadataRow.tsx new file mode 100644 index 000000000..1b9340ffc --- /dev/null +++ b/frontend/src/components/nodes/ValidatorMetadataRow.tsx @@ -0,0 +1,134 @@ +import { PureComponent } from "react"; + +import { Row, Col } from "react-bootstrap"; + +interface Props { + poolWebsite?: string; + poolEmail?: string; + poolTwitter?: string; + poolDiscord?: string; + poolDescription?: string; +} + +class ValidatorMetadataRow extends PureComponent { + render() { + const { + poolWebsite, + poolEmail, + poolTwitter, + poolDiscord, + poolDescription, + } = this.props; + + const poolDetailsAvailable = + Boolean(poolWebsite) || + Boolean(poolEmail) || + Boolean(poolTwitter) || + Boolean(poolDiscord) || + Boolean(poolDescription); + + return ( + + {poolDetailsAvailable ? ( + <> + {poolWebsite && ( + + + Web + + + + + {poolWebsite} + + + + + )} + {poolEmail && ( + + + Email + + + + {poolEmail} + + + + )} + {poolTwitter && ( + + + Twitter + + + + + {poolTwitter} + + + + + )} + {poolDiscord && ( + + + Discord + + + + + {poolDiscord} + + + + + )} + {poolDescription && ( + + + + Description + + + + + {poolDescription} + + + + )} + + ) : ( + +

+ If you are node owner feel free to fill all{" "} + + data + {" "} + to promote your own node! +

+ + )} +
+ ); + } +} + +export default ValidatorMetadataRow; diff --git a/frontend/src/components/nodes/ValidatorRow.tsx b/frontend/src/components/nodes/ValidatorRow.tsx index 4c913ecc0..71a9d6119 100644 --- a/frontend/src/components/nodes/ValidatorRow.tsx +++ b/frontend/src/components/nodes/ValidatorRow.tsx @@ -27,7 +27,7 @@ class ValidatorRow extends React.Component { render() { const { node, index, totalStake } = this.props; - let persntStake = 0; + let totalStakeInPersnt = 0; let cumulativeStake = 0; let validatorFee = typeof node.fee === "undefined" @@ -43,7 +43,7 @@ class ValidatorRow extends React.Component { : node.delegatorsCount; if (node.stake && totalStake) { - persntStake = + totalStakeInPersnt = new BN(node.stake).mul(new BN(10000)).div(totalStake).toNumber() / 100; } @@ -70,9 +70,9 @@ class ValidatorRow extends React.Component { validatorFee={validatorFee} validatorDelegators={validatorDelegators} stake={node.stake} - stakeProposed={node.stakeProposed} + proposedStakePerNextEpoch={node.stakeProposed} cumulativeStake={cumulativeStake} - persntStake={persntStake} + totalStakeInPersnt={totalStakeInPersnt} handleClick={this.handleClick} /> @@ -80,7 +80,7 @@ class ValidatorRow extends React.Component { isRowActive={this.state.activeRow} producedBlocks={node.num_produced_blocks} expectedBlocks={node.num_expected_blocks} - validatorsLatestBlock={node.nodeInfo?.lastHeight} + latestProducedValidatorBlock={node.nodeInfo?.lastHeight} lastSeen={node.nodeInfo?.lastSeen} agentName={node.nodeInfo?.agentName} agentVersion={node.nodeInfo?.agentVersion} diff --git a/frontend/src/components/nodes/ValidatorTelemetryRow.tsx b/frontend/src/components/nodes/ValidatorTelemetryRow.tsx new file mode 100644 index 000000000..385d7cccf --- /dev/null +++ b/frontend/src/components/nodes/ValidatorTelemetryRow.tsx @@ -0,0 +1,188 @@ +import { PureComponent } from "react"; + +import { Badge, Row, Col } from "react-bootstrap"; +import { DatabaseConsumer } from "../../context/DatabaseProvider"; +import Term from "../utils/Term"; +import Timer from "../utils/Timer"; + +interface Props { + producedBlocks?: number; + expectedBlocks?: number; + latestProducedValidatorBlock?: number; + lastSeen?: number; + agentName?: string; + agentVersion?: string; + agentBuild?: string; +} + +class ValidatorTelemetryRow extends PureComponent { + render() { + const { + producedBlocks, + expectedBlocks, + latestProducedValidatorBlock, + lastSeen, + agentName, + agentVersion, + agentBuild, + } = this.props; + + const isTelemetryAvailable = + Boolean(producedBlocks) || + Boolean(expectedBlocks) || + Boolean(latestProducedValidatorBlock) || + Boolean(lastSeen) || + Boolean(agentName) || + Boolean(agentVersion) || + Boolean(agentBuild); + + if (isTelemetryAvailable) return null; + + return ( + + {({ latestBlockHeight }) => ( + + {producedBlocks && expectedBlocks && ( + + + + + + + + + {producedBlocks && expectedBlocks ? ( + <> + {((producedBlocks / expectedBlocks) * 100).toFixed(3)}% +   + + ({producedBlocks}/{expectedBlocks}) + + + ) : null} + + + + )} + {latestProducedValidatorBlock && ( + + + + + + + + 1000 + ? "text-danger" + : Math.abs( + latestProducedValidatorBlock - + latestBlockHeight.toNumber() + ) > 50 + ? "text-warning" + : "" + } validator-nodes-text`} + md={3} + > + {` ${latestProducedValidatorBlock}`} + + + + )} + {lastSeen && ( + + + + + + + + + {lastSeen ? : "..."} + + + + )} + {agentName && ( + + + + + { + "NEAR Protocol could have multiple implementations, so agent is the name of that implementation, where 'near-rs' is " + } + + {"the official implementation"} + + {"."} + + } + /> + + + + + {agentName ? ( + + {agentName} + + ) : ( + "..." + )} + + + + )} + {agentVersion && agentBuild && ( + + + + {"Node Agent Version / Build"} + + + + + {agentVersion && agentBuild ? ( + + {`v${agentVersion} / ${agentBuild}`} + + ) : ( + "..." + )} + + + + )} + + )} + + ); + } +} + +export default ValidatorTelemetryRow; diff --git a/frontend/src/components/nodes/__test__/__snapshots__/ValidatorRow.test.tsx.snap b/frontend/src/components/nodes/__test__/__snapshots__/ValidatorRow.test.tsx.snap index c8696e72c..b9b967237 100644 --- a/frontend/src/components/nodes/__test__/__snapshots__/ValidatorRow.test.tsx.snap +++ b/frontend/src/components/nodes/__test__/__snapshots__/ValidatorRow.test.tsx.snap @@ -346,7 +346,17 @@ exports[` renders simple Validators row 1`] = ` >
+ > + + Inactive + +