Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix forging details in the delegates page - Closes #3440 #3514

Merged
merged 43 commits into from
May 4, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
43 commits
Select commit Hold shift + click to select a range
7dda514
Fix getDelegates WS config
reyraa Apr 29, 2021
2ee7101
Improve names and use correct response transformers
reyraa Apr 29, 2021
6d4eb65
Remove delegate productivity, code clean up
reyraa Apr 29, 2021
6c2eab0
Remove delegate productivity, code cleanup
reyraa Apr 29, 2021
706a80e
Use camelCase
reyraa Apr 29, 2021
a393a67
Add text align global style
reyraa Apr 29, 2021
65239f2
Remove unused titles
reyraa Apr 29, 2021
9c77418
Rename to dataColumns
reyraa Apr 29, 2021
5cd9a53
Create components for each column of data
reyraa Apr 29, 2021
58b7a9c
Use components from dataColumns.js
reyraa Apr 29, 2021
995fe0c
Use functions to define css classes
reyraa Apr 29, 2021
e37b7c4
Code cleanup
reyraa Apr 29, 2021
6375ef5
Use Lisk Service nextForgingTime
reyraa Apr 29, 2021
3252d78
Pass forgers list
reyraa Apr 29, 2021
5f1160b
Rename constant name
reyraa May 3, 2021
367f840
Rename forging actions
reyraa May 3, 2021
eeb866b
Refactor forging actions to use the forging times form the API response
reyraa May 3, 2021
f47ff5b
use new actions in blocks reducer
reyraa May 3, 2021
d91b18b
Remove old forgingTimes and awaitingForgers from the Redux store
reyraa May 3, 2021
7fa911b
Rename MAX_BLOCKS_FORGED to ROUND_LENGTH
reyraa May 3, 2021
e6c08c6
Get statuses and chart info from state.forgers
reyraa May 3, 2021
24c50b1
Remove forgers API call since we read from the Redux store
reyraa May 3, 2021
12342e0
Adapt to the new forgers list structure
reyraa May 3, 2021
16c5777
Update block actions to use the new forging times
reyraa May 3, 2021
74e2987
Pass status through
reyraa May 3, 2021
ce2bad7
Replace old awaitingForgers and forgingTimes with forgers from the Re…
reyraa May 3, 2021
2fcfeb2
Use new actions in block middleware
reyraa May 3, 2021
37f3a55
Update local sort to use nextForgingTime from core API
reyraa May 3, 2021
cba51f2
Use block.forgers in DelegatesMonitor
reyraa May 3, 2021
d37b903
Remove old awaitingForgers and forgingTimes in favor of forgers list
reyraa May 3, 2021
03bbfbc
Rely purely on the API forgersRetrieved
reyraa May 3, 2021
c76d66f
Remove unused actions
reyraa May 3, 2021
63dd4b8
Use mapStateToProps to pass blocks
reyraa May 3, 2021
2f01308
Update mock delegates
reyraa May 3, 2021
565adad
Fix the start time
reyraa May 3, 2021
871e780
Update unit tests, Remove Chai
reyraa May 3, 2021
76f89f3
Reorganize components
reyraa May 3, 2021
265d4ae
Update imports
reyraa May 3, 2021
a8eb8ce
Remove logs
reyraa May 3, 2021
7ab791a
Merge branch 'development' into 3440-fix-forging-details
reyraa May 3, 2021
29a1ddf
Update component props
reyraa May 3, 2021
f876465
Update mock blocks
reyraa May 3, 2021
4a4f275
Don't show the forgers who have forged
reyraa May 3, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion i18n/locales/en/common.json
Original file line number Diff line number Diff line change
Expand Up @@ -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.",
Expand Down
10 changes: 10 additions & 0 deletions src/app/type.css
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
2 changes: 1 addition & 1 deletion src/components/screens/monitor/delegates/delegates.css
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
Expand Down
37 changes: 14 additions & 23 deletions src/components/screens/monitor/delegates/delegates.js
Original file line number Diff line number Diff line change
@@ -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 = ({
Expand All @@ -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) => {
Expand Down Expand Up @@ -109,7 +98,7 @@ const DelegatesMonitor = ({

return (
<div>
<Overview
<DelegatesOverview
delegatesCount={delegatesCount}
transactionsCount={transactionsCount}
registrations={registrations}
Expand All @@ -119,9 +108,11 @@ const DelegatesMonitor = ({
/>
<ForgingDetails
t={t}
chartDelegatesForging={forgingTimes}
forgers={forgers}
forgedInRound={forgedInRound}
startTime={latestBlocks[forgedInRound]?.timestamp}
/>
<Box main isLoading={delegates.isLoading || standByDelegates.isLoading || votes.isLoading}>
<Box main isLoading={standByDelegates.isLoading || votes.isLoading}>
<BoxHeader className="delegates-table">
{tabs.tabs.length === 1
? <h2>{tabs.tabs[0].name}</h2>
Expand All @@ -145,7 +136,7 @@ const DelegatesMonitor = ({
setActiveTab={setActiveTab}
delegates={delegatesWithForgingTimes}
watchList={watchList}
watchedDelegates={watchedDelegatesWithForgingTimes}
watchedDelegates={watchedDelegates}
standByDelegates={standByDelegates}
sanctionedDelegates={sanctionedDelegates}
filters={filters}
Expand All @@ -160,4 +151,4 @@ const DelegatesMonitor = ({
);
};

export default withTranslation()(DelegatesMonitor);
export default DelegatesMonitor;
12 changes: 4 additions & 8 deletions src/components/screens/monitor/delegates/delegates.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -46,16 +46,12 @@ describe('Delegates monitor page', () => {
});
};

const { blocks } = store.getState();

beforeEach(() => {
props = {
t: key => key,
delegates: {
isLoading: true,
data: activeDelegates,
loadData: jest.fn(),
clearData: jest.fn(),
urlSearchParams: {},
},
blocks,
standByDelegates: {
isLoading: true,
data: [],
Expand Down Expand Up @@ -145,6 +141,6 @@ describe('Delegates monitor page', () => {

it('renders the forging status', () => {
wrapper = setup(props);
expect(wrapper.find('a.delegate-row')).toHaveLength(delegatesList.length + 1);
expect(wrapper.find('a.delegate-row')).toHaveLength(blocks.forgers.length);
});
});
145 changes: 145 additions & 0 deletions src/components/screens/monitor/delegates/delegatesTable/dataColumns.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,145 @@
import React from 'react';
import grid from 'flexboxgrid/dist/flexboxgrid.css';

import { formatAmountBasedOnLocale } from '@utils/formattedNumber';
import { fromRawLsk } from '@utils/lsk';
import { truncateAddress } from '@utils/account';
import Tooltip from '@toolbox/tooltip/tooltip';
import Icon from '@toolbox/icon';
import AccountVisual from '@toolbox/accountVisual';
import {
getStatusClass,
getDelegateWeightClass,
getRoundStateClass,
getForgingTimeClass,
} from './tableHeader';
import styles from '../delegates.css';

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',
nonEligible: 'Non-eligible to forge',
};

export const DelegateWeight = ({ value, activeTab }) => {
const formatted = formatAmountBasedOnLocale({
value: fromRawLsk(value),
format: '0a',
});

return (
<span className={getDelegateWeightClass(activeTab)}>
<span>{formatted}</span>
</span>
);
};

export const DelegateDetails = ({
t, watched = false, data, activeTab, removeFromWatchList, addToWatchList,
}) => {
const showEyeIcon = activeTab === 'active' || activeTab === 'standby' || activeTab === 'watched';
return (
<span className={grid['col-xs-5']}>
<div className={styles.delegateColumn}>
<Tooltip
tooltipClassName={styles.tooltipContainer}
className={styles.eyeIconTooltip}
position="bottom right"
size="s"
content={(
<span
className={`
${styles.eyeIcon} ${!showEyeIcon ? 'hidden' : ''} ${watched && showEyeIcon ? styles.watchedDelegate : ''}
`}
onClick={watched ? removeFromWatchList : addToWatchList}
>
<Icon name={watched ? 'eyeActive' : 'eyeInactive'} />
</span>
)}
>
<p className={styles.watchedTooltip}>
{watched ? t('Remove from watched') : t('Add to watched')}
</p>
</Tooltip>

<div className={`${styles.delegateDetails}`}>
<AccountVisual address={data.address} />
<div>
<p className={styles.delegateName}>
{data.username}
</p>
<p className={styles.delegateAddress}>{truncateAddress(data.address)}</p>
</div>
</div>
</div>
</span>
);
};

export const RoundStatus = ({
activeTab, data, t, time,
}) => (
<span className={`${getRoundStateClass(activeTab)} ${styles.noEllipsis} ${styles.statusIconsContainer}`}>
<Tooltip
title={t(roundStatus[data.status])}
position="left"
size="maxContent"
content={(
<Icon
className={styles.statusIcon}
name={icons[data.status]}
/>
)}
footer={(
<p>{data.status === 'missedBlock' ? '-' : time}</p>
)}
>
<p className={styles.statusToolip}>
{data.lastBlock && `Last block forged ${data.lastBlock}`}
</p>
</Tooltip>
{data.isBanned && (
<Tooltip
position="left"
size="maxContent"
content={<Icon className={styles.statusIcon} name="delegateWarning" />}
footer={(
<p>{time}</p>
)}
>
<p>
{t('This delegate will be punished in upcoming rounds')}
</p>
</Tooltip>
)}
</span>
);

export const DelegateStatus = ({ activeTab, data }) => {
const status = data.totalVotesReceived < 1e11 ? 'nonEligible' : data.status;
return (
<span className={getStatusClass(activeTab)}>
<span className={`${styles.delegateStatus} ${styles[status]}`}>{delegateStatus[status]}</span>
</span>
);
};

export const ForgingTime = ({ activeTab, time, status }) => (
<span className={getForgingTimeClass(activeTab)}>
{status === 'missedBlock' ? '-' : time}
</span>
);
Loading