diff --git a/i18n/locales/en/common.json b/i18n/locales/en/common.json index 90dc77ba85..1007e86328 100644 --- a/i18n/locales/en/common.json +++ b/i18n/locales/en/common.json @@ -316,7 +316,6 @@ "Peers": "Peers", "Pending": "Pending", "Pending...": "Pending...", - "Percentage of successfully forged blocks in relation to all blocks (forged and missed).": "Percentage of successfully forged blocks in relation to all blocks (forged and missed).", "Perfect! Almost done": "Perfect! Almost done", "Performance": "Performance", "Personalize each transaction with a custom message. Look up its value in a fiat currency of your choice.": "Personalize each transaction with a custom message. Look up its value in a fiat currency of your choice.", diff --git a/src/app/type.css b/src/app/type.css index 1ac5908bf1..2ce1407b84 100644 --- a/src/app/type.css +++ b/src/app/type.css @@ -149,6 +149,16 @@ small { text-align: center; } +:global .text-left { + text-align: left; + justify-content: flex-start; +} + +:global .text-right { + text-align: right; + justify-content: flex-end; +} + input, textarea, select { diff --git a/src/components/screens/monitor/delegates/delegates.css b/src/components/screens/monitor/delegates/delegates.css index d215e476cb..b6a26c474a 100644 --- a/src/components/screens/monitor/delegates/delegates.css +++ b/src/components/screens/monitor/delegates/delegates.css @@ -227,7 +227,7 @@ background-color: var(--color-yellow-transparent); } - &.non-eligible { + &.nonEligible { color: var(--color-blue-gray); background-color: var(--color-blue-manatee-transparent); } diff --git a/src/components/screens/monitor/delegates/delegates.js b/src/components/screens/monitor/delegates/delegates.js index ec9d6c7d95..c62a7982a3 100644 --- a/src/components/screens/monitor/delegates/delegates.js +++ b/src/components/screens/monitor/delegates/delegates.js @@ -1,17 +1,16 @@ import React, { useState, useEffect } from 'react'; -import { useSelector } from 'react-redux'; -import { withTranslation } from 'react-i18next'; import { Input } from '@toolbox/inputs'; import Box from '@toolbox/box'; import BoxHeader from '@toolbox/box/header'; import BoxContent from '@toolbox/box/content'; import BoxTabs from '@toolbox/tabs'; +import { ROUND_LENGTH } from '@constants'; import styles from './delegates.css'; -import Overview from './overview'; +import DelegatesOverview from './overview/delegatesOverview'; +import ForgingDetails from './overview/forgingDetails'; import LatestVotes from './latestVotes'; import DelegatesTable from './delegatesTable'; -import ForgingDetails from './forgingDetails'; // eslint-disable-next-line max-statements const DelegatesMonitor = ({ @@ -25,25 +24,15 @@ const DelegatesMonitor = ({ standByDelegates, networkStatus, applyFilters, - delegates, filters, + blocks, votes, t, }) => { const [activeTab, setActiveTab] = useState('active'); - const { forgingTimes, total } = useSelector(state => state.blocks); - const delegatesWithForgingTimes = { - ...delegates, - data: delegates.data.map( - data => ({ ...data, forgingTime: forgingTimes[data.publicKey] }), - ), - }; - const watchedDelegatesWithForgingTimes = { - ...watchedDelegates, - data: watchedDelegates.data.map( - data => ({ ...data, forgingTime: forgingTimes[data.publicKey] }), - ), - }; + const { total, forgers, latestBlocks } = blocks; + const delegatesWithForgingTimes = { data: forgers }; + const forgedInRound = latestBlocks.length ? latestBlocks[0].height % ROUND_LENGTH : 0; useEffect(() => { const addressList = votes.data && votes.data.reduce((acc, data) => { @@ -109,7 +98,7 @@ const DelegatesMonitor = ({ return (
+ {watched ? t('Remove from watched') : t('Add to watched')} +
++ {data.username} +
+{truncateAddress(data.address)}
+{data.status === 'missedBlock' ? '-' : time}
+ )} + > ++ {data.lastBlock && `Last block forged ${data.lastBlock}`} +
+ + {data.isBanned && ( +{time}
+ )} + > ++ {t('This delegate will be punished in upcoming rounds')} +
+ + )} + +); + +export const DelegateStatus = ({ activeTab, data }) => { + const status = data.totalVotesReceived < 1e11 ? 'nonEligible' : data.status; + return ( + + {delegateStatus[status]} + + ); +}; + +export const ForgingTime = ({ activeTab, time, status }) => ( + + {status === 'missedBlock' ? '-' : time} + +); diff --git a/src/components/screens/monitor/delegates/delegatesTable/delegateRow.js b/src/components/screens/monitor/delegates/delegatesTable/delegateRow.js index fe340b025c..81faca8bfe 100644 --- a/src/components/screens/monitor/delegates/delegatesTable/delegateRow.js +++ b/src/components/screens/monitor/delegates/delegatesTable/delegateRow.js @@ -1,156 +1,35 @@ -/* eslint-disable no-nested-ternary */ import React from 'react'; import { Link } from 'react-router-dom'; -import grid from 'flexboxgrid/dist/flexboxgrid.css'; import { useDispatch } from 'react-redux'; import { routes } from '@constants'; -import { formatAmountBasedOnLocale } from '@utils/formattedNumber'; -import { truncateAddress } from '@utils/account'; import { addedToWatchList, removedFromWatchList } from '@actions'; -import Tooltip from '@toolbox/tooltip/tooltip'; -import Icon from '@toolbox/icon'; -import AccountVisual from '@toolbox/accountVisual'; import styles from '../delegates.css'; -import DelegateWeight from './delegateWeight'; +import { + DelegateWeight, + DelegateDetails, + RoundStatus, + DelegateStatus, + ForgingTime, +} from './dataColumns'; -const roundStatus = { - forging: 'Forging', - awaitingSlot: 'Awaiting slot', - missedBlock: 'Missed block', -}; - -const icons = { - forging: 'delegateForged', - awaitingSlot: 'delegateAwaiting', - missedBlock: 'delegateMissed', -}; - -const delegateStatus = { - active: 'Active', - standby: 'Standby', - banned: 'Banned', - punished: 'Punished', - 'non-eligible': 'Non-eligible to forge', -}; - -const getForgingTime = (data) => { - if (!data || data.time === undefined) return '-'; - if (data.time === 0) return 'now'; - const { time } = data; - const absTime = Math.abs(time); +const getForgingTime = (time) => { + if (!time) return '-'; + const diff = time - Math.floor((new Date()).getTime() / 1000); + if (Math.abs(diff) < 9) return 'now'; + const absTime = Math.abs(diff); const minutes = absTime / 60 >= 1 ? `${Math.floor(absTime / 60)}m ` : ''; const seconds = absTime % 60 >= 1 ? `${absTime % 60}s` : ''; - if (data.time > 0) { + if (diff > 0) { return `in ${minutes}${seconds}`; } return `${minutes}${seconds} ago`; }; -// eslint-disable-next-line complexity -const DelegateDetails = ({ - t, watched = false, data, activeTab, removeFromWatchList, addToWatchList, -}) => { - const showEyeIcon = activeTab === 'active' || activeTab === 'standby' || activeTab === 'watched'; - return ( -- {watched ? t('Remove from watched') : t('Add to watched')} -
-- {data.username} -
-{truncateAddress(data.address)}
-{formattedForgingTime}
- )} - > -- {data.lastBlock && `Last block forged ${data.lastBlock}`} -
- - {data.isBanned && ( -{formattedForgingTime}
- )} - > -- {t('This delegate will be punished in upcoming rounds')} -
- - )} - > -); - -const DelegateStatus = ({ activeTab, data }) => { - const status = data.totalVotesReceived < 100000000000 ? 'non-eligible' : data.status; - return ( - - {delegateStatus[status]} - - ); -}; - -// eslint-disable-next-line complexity const DelegateRow = ({ data, className, t, activeTab, watchList, setActiveTab, }) => { - const formattedForgingTime = data.forgingTime && getForgingTime(data.forgingTime); + const formattedForgingTime = getForgingTime(data.nextForgingTime); const dispatch = useDispatch(); const isWatched = watchList.find(address => address === data.address); @@ -175,56 +54,22 @@ const DelegateRow = ({ className={`${className} delegate-row ${styles.tableRow}`} to={`${routes.account.path}?address=${data.address}`} > - -{`${forgedInRound} / `} - {` ${MAX_BLOCKS_FORGED}`} + {` ${ROUND_LENGTH}`}