From a6c6a6e9f1a86858c4bd2ba2dce92a1555e847ea Mon Sep 17 00:00:00 2001 From: Vit Stanislav Date: Thu, 13 Jul 2017 10:37:44 +0200 Subject: [PATCH 01/24] Migrate forging component to React --- package.json | 2 + src/actions/forging.js | 11 ++++ src/components/app/index.js | 10 +++- .../forging/circularProgressbar.css | 24 ++++++++ src/components/forging/delegateStats.js | 45 ++++++++++++++ src/components/forging/forgedBlocks.js | 38 ++++++++++++ src/components/forging/forging.css | 20 +++++++ src/components/forging/forgingComponent.js | 47 +++++++++++++++ src/components/forging/forgingStats.js | 60 +++++++++++++++++++ src/components/forging/forgingTitle.js | 34 +++++++++++ src/components/forging/index.js | 32 ++++++++-- src/constants/actions.js | 2 + src/store/reducers/forging.js | 23 +++++++ src/store/reducers/index.js | 1 + 14 files changed, 343 insertions(+), 6 deletions(-) create mode 100644 src/actions/forging.js create mode 100644 src/components/forging/circularProgressbar.css create mode 100644 src/components/forging/delegateStats.js create mode 100644 src/components/forging/forgedBlocks.js create mode 100644 src/components/forging/forging.css create mode 100644 src/components/forging/forgingComponent.js create mode 100644 src/components/forging/forgingStats.js create mode 100644 src/components/forging/forgingTitle.js create mode 100644 src/store/reducers/forging.js diff --git a/package.json b/package.json index 2b68c1513..face2f63f 100644 --- a/package.json +++ b/package.json @@ -35,10 +35,12 @@ "postcss-cssnext": "=2.11.0", "prop-types": "=15.5.10", "react": "=15.6.x", + "react-circular-progressbar": "=0.1.5", "react-dom": "=15.6.x", "react-redux": "=5.0.3", "react-redux-toastr": "=7.0.0", "react-router-dom": "=4.0.0", + "react-timeago": "=3.3.0", "react-toolbox": "=2.0.0-beta.12", "redux": "=3.6.0", "redux-logger": "=3.0.6" diff --git a/src/actions/forging.js b/src/actions/forging.js new file mode 100644 index 000000000..f58e06b08 --- /dev/null +++ b/src/actions/forging.js @@ -0,0 +1,11 @@ +import actionTypes from '../constants/actions'; + +export const updateForgedBlocks = data => ({ + data, + type: actionTypes.forgedBlocksUpdated, +}); + +export const updateForgingStats = data => ({ + data, + type: actionTypes.forgingStatsUpdated, +}); diff --git a/src/components/app/index.js b/src/components/app/index.js index 7e905ab36..9db280909 100644 --- a/src/components/app/index.js +++ b/src/components/app/index.js @@ -28,9 +28,15 @@ const App = (props) => { // temporary, will be deleted with #347 setActivePeer(network); - getAccount(props.store.getState().peers.data, '16313739661670634666L').then((result) => { + getAccount(props.store.getState().peers.data, '537318935439898807L').then((result) => { props.store.dispatch(accountUpdated(Object.assign({}, result, { - passphrase: 'wagon stock borrow episode laundry kitten salute link globe zero feed marble', + passphrase: 'recipe bomb asset salon coil symbol tiger engine assist pact pumpkin visit', + delegate: { + username: 'genesis_17', + rate: 19, + approval: 30, + productivity: 99.2, + }, }))); }); diff --git a/src/components/forging/circularProgressbar.css b/src/components/forging/circularProgressbar.css new file mode 100644 index 000000000..2a3958944 --- /dev/null +++ b/src/components/forging/circularProgressbar.css @@ -0,0 +1,24 @@ +:global .CircularProgressbar { + /* + * This fixes an issue where the CircularProgressbar svg has + * 0 width inside a "display: flex" container, and thus not visible. + * + * If you're not using "display: flex", you can remove this style. + */ + width: 100%; +} + +:global .CircularProgressbar .CircularProgressbar-path { + stroke: rgb(2, 136, 209); + transition: stroke-dashoffset 0.5s ease 0s; +} + +:global .CircularProgressbar .CircularProgressbar-trail { + stroke: #d6d6d6; +} + +:global .CircularProgressbar .CircularProgressbar-text { + font-size: 20px; + dominant-baseline: middle; + text-anchor: middle; +} diff --git a/src/components/forging/delegateStats.js b/src/components/forging/delegateStats.js new file mode 100644 index 000000000..e504afa85 --- /dev/null +++ b/src/components/forging/delegateStats.js @@ -0,0 +1,45 @@ +import React from 'react'; +import { Card, CardText } from 'react-toolbox/lib/card'; +import CircularProgressbar from 'react-circular-progressbar'; +import grid from '../../../node_modules/flexboxgrid/dist/flexboxgrid.css'; +import style from './forging.css'; + +const progressCircleCardObjects = [ + { + key: 'rate', + label: 'Rank', + textForPercentage: pct => (101 - pct), + percentageTransform: pct => (101 - pct), + }, { + key: 'productivity', + label: 'Productivity', + }, { + key: 'approval', + label: 'Approval', + }, +]; + +const identity = x => (x); + +const DelegateStats = props => ( +
+ {progressCircleCardObjects.map(cardObj => ( +
+ + +
+
+
{cardObj.label}
+ +
+
+
+
+
+ ))} +
+); + +export default DelegateStats; diff --git a/src/components/forging/forgedBlocks.js b/src/components/forging/forgedBlocks.js new file mode 100644 index 000000000..5fa7160d3 --- /dev/null +++ b/src/components/forging/forgedBlocks.js @@ -0,0 +1,38 @@ +import React from 'react'; +import { Card, CardTitle } from 'react-toolbox/lib/card'; +import { Table, TableHead, TableRow, TableCell } from 'react-toolbox/lib/table'; +import TimeAgo from 'react-timeago'; +import FormattedNumber from '../formattedNumber'; +import grid from '../../../node_modules/flexboxgrid/dist/flexboxgrid.css'; +import style from './forging.css'; + + +const ForgedBlocks = props => ( + + + Forged Blocks + +
+ + + Block height + Block Id + Timestamp + Total fee + Reward + + {props.forgedBlocks.map((block, idx) => ( + + + {block.id} + + + + + ))} +
+
+
+); + +export default ForgedBlocks; diff --git a/src/components/forging/forging.css b/src/components/forging/forging.css new file mode 100644 index 000000000..e455602da --- /dev/null +++ b/src/components/forging/forging.css @@ -0,0 +1,20 @@ +@import './circularProgressbar.css'; + +.delegateName { + margin: 0; + font-weight: normal; +} + +.grayCard { + background: #f7f8f9; +} + +.forgedBlocksTableWrapper { + margin: 0 -8px; +} + +.circularProgressTitle { + text-align: center; + padding-bottom: 16px; + width: 100%; +} diff --git a/src/components/forging/forgingComponent.js b/src/components/forging/forgingComponent.js new file mode 100644 index 000000000..2e7b992a0 --- /dev/null +++ b/src/components/forging/forgingComponent.js @@ -0,0 +1,47 @@ +import React from 'react'; +import { Card } from 'react-toolbox/lib/card'; +import Waypoint from 'react-waypoint'; +import ForgingTitle from './forgingTitle'; +import DelegateStats from './delegateStats'; +import ForgingStats from './forgingStats'; +import ForgedBlocks from './forgedBlocks'; + +class ForgingComponent extends React.Component { + loadStats(key, startMoment) { + this.props.loadStats( + this.props.peers.data, + key, + startMoment, + this.props.account.publicKey, + ); + } + + render() { + return ( + + {this.props.account && this.props.account.delegate ? +
+ +
+ +
+ +
+ + this.props.loadForgedBlocks( + this.props.peers.data, + 20, + this.props.forgedBlocks.length, + this.props.account.publicKey, + ) } /> +
: + null + } +
+ ); + } +} + +export default ForgingComponent; diff --git a/src/components/forging/forgingStats.js b/src/components/forging/forgingStats.js new file mode 100644 index 000000000..b33c2a339 --- /dev/null +++ b/src/components/forging/forgingStats.js @@ -0,0 +1,60 @@ +import React from 'react'; +import { Card, CardText } from 'react-toolbox/lib/card'; +import moment from 'moment'; +import FormattedNumber from '../formattedNumber'; +import grid from '../../../node_modules/flexboxgrid/dist/flexboxgrid.css'; +import style from './forging.css'; + +const statCardObjects = [ + { + key: 'last24h', + label: 'Last 24 hours', + startMoment: moment().subtract(1, 'days'), + }, { + key: 'last7d', + label: 'Last 7 days', + startMoment: moment().subtract(7, 'days'), + }, { + key: 'last30d', + label: 'Last 30 days', + startMoment: moment().subtract(30, 'days'), + }, { + key: 'last365d', + label: 'Last 365 days', + startMoment: moment().subtract(365, 'days'), + }, +]; + + +class ForgingStats extends React.Component { + + componentDidMount() { + statCardObjects.map(obj => this.props.loadStats(obj.key, obj.startMoment)); + } + + render() { + return ( +
+ {statCardObjects.map(cardObj => ( +
+ + +
+
+ {cardObj.label} + + LSK + +
+
+
+
+
+ ))} +
+ ); + } +} + +export default ForgingStats; diff --git a/src/components/forging/forgingTitle.js b/src/components/forging/forgingTitle.js new file mode 100644 index 000000000..2866d294f --- /dev/null +++ b/src/components/forging/forgingTitle.js @@ -0,0 +1,34 @@ +import React from 'react'; +import { Card, CardText } from 'react-toolbox/lib/card'; +import moment from 'moment'; +import FormattedNumber from '../formattedNumber'; +import grid from '../../../node_modules/flexboxgrid/dist/flexboxgrid.css'; +import style from './forging.css'; + + +class ForgingTitle extends React.Component { + + componentDidMount() { + this.props.loadStats('total', moment('2016-04-24 17:00')); + } + + render() { + return ( + + +
+

+ {this.props.account.delegate.username} +

+ + LSK Earned + +
+
+
+ ); + } +} + +export default ForgingTitle; diff --git a/src/components/forging/index.js b/src/components/forging/index.js index e6a832e56..db0b9e4b5 100644 --- a/src/components/forging/index.js +++ b/src/components/forging/index.js @@ -1,7 +1,31 @@ -import React from 'react'; +import { connect } from 'react-redux'; +import { updateForgedBlocks, updateForgingStats } from '../../actions/forging'; +import ForgingComponent from './forgingComponent'; +import { getForgedBlocks, getForgedStats } from '../../utils/api/forging'; -const Forging = () => ( -

Forging

-); +const mapStateToProps = state => ({ + account: state.account, + peers: state.peers, + statistics: state.forging.statistics, + forgedBlocks: state.forging.forgedBlocks, +}); + +const mapDispatchToProps = dispatch => ({ + loadForgedBlocks: (activePeer, limit = 10, offset = 0, generatorPublicKey) => { + getForgedBlocks(activePeer, limit, offset, generatorPublicKey).then((data) => { + dispatch(updateForgedBlocks(data.blocks)); + }); + }, + loadStats: (activePeer, key, startMoment, generatorPublicKey) => { + getForgedStats(activePeer, startMoment, generatorPublicKey).then((data) => { + dispatch(updateForgingStats({ [key]: data.forged })); + }); + }, +}); + +const Forging = connect( + mapStateToProps, + mapDispatchToProps, +)(ForgingComponent); export default Forging; diff --git a/src/constants/actions.js b/src/constants/actions.js index f43e50fbd..11fdbca0f 100644 --- a/src/constants/actions.js +++ b/src/constants/actions.js @@ -6,6 +6,8 @@ const actionTypes = { activePeerReset: 'ACTIVE_PEER_RESET', dialogDisplayed: 'DIALOG_DISPLAYED', dialogHidden: 'DIALOG_HIDDEN', + forgedBlocksUpdated: 'FORGED_BLOCKS_UPDATED', + forgingStatsUpdated: 'FORGING_STATS_UPDATED', }; export default actionTypes; diff --git a/src/store/reducers/forging.js b/src/store/reducers/forging.js new file mode 100644 index 000000000..70bbd8e25 --- /dev/null +++ b/src/store/reducers/forging.js @@ -0,0 +1,23 @@ +import actionTypes from '../../constants/actions'; + +/** + * + * @param {Array} state + * @param {Object} action + */ +const forging = (state = { forgedBlocks: [], statistics: {} }, action) => { + switch (action.type) { + case actionTypes.forgedBlocksUpdated: + return Object.assign({}, state, { + forgedBlocks: (state.forgedBlocks || []).concat(action.data), + }); + case actionTypes.forgingStatsUpdated: + return Object.assign({}, state, { + statistics: Object.assign({}, state.statistics, action.data), + }); + default: + return state; + } +}; + +export default forging; diff --git a/src/store/reducers/index.js b/src/store/reducers/index.js index 018cf688a..9dca54638 100644 --- a/src/store/reducers/index.js +++ b/src/store/reducers/index.js @@ -1,4 +1,5 @@ export { default as account } from './account'; export { default as peers } from './peers'; export { default as dialog } from './dialog'; +export { default as forging } from './forging'; From 6ceb52388d6b21fd716d3cba559ba79422cf00cf Mon Sep 17 00:00:00 2001 From: Vit Stanislav Date: Tue, 18 Jul 2017 17:45:14 +0200 Subject: [PATCH 02/24] Add unit tests for ForgedBlocks component --- src/components/forging/forgedBlocks.test.js | 52 +++++++++++++++++++++ 1 file changed, 52 insertions(+) create mode 100644 src/components/forging/forgedBlocks.test.js diff --git a/src/components/forging/forgedBlocks.test.js b/src/components/forging/forgedBlocks.test.js new file mode 100644 index 000000000..294fdc6f9 --- /dev/null +++ b/src/components/forging/forgedBlocks.test.js @@ -0,0 +1,52 @@ +import React from 'react'; +import chai, { expect } from 'chai'; +import sinonChai from 'sinon-chai'; +import { mount } from 'enzyme'; +import ForgedBlocks from './forgedBlocks'; + +chai.use(sinonChai); + +describe('', () => { + const forgedBlocks = [{ + id: '16113150790072764126', + timestamp: 36280810, + height: 29394, + totalFee: 0, + reward: 0, + }, + { + id: '13838471839278892195', + version: 0, + timestamp: 36280700, + height: 29383, + totalFee: 0, + reward: 0, + }, + { + id: '5654150596698663763', + version: 0, + timestamp: 36279700, + height: 29283, + totalFee: 0, + reward: 0, + }, + ]; + let wrapper; + + beforeEach(() => { + wrapper = mount(); + }); + + it('should render 1 Table component', () => { + expect(wrapper.find('Table')).to.have.lengthOf(1); + }); + + it('should render TableHead component with 5 TableCell componenets', () => { + expect(wrapper.find('TableHead')).to.have.lengthOf(1); + expect(wrapper.find('TableHead').find('TableCell')).to.have.lengthOf(5); + }); + + it('should render 3 TableRow components', () => { + expect(wrapper.find('TableRow')).to.have.lengthOf(3); + }); +}); From a0bee86ebd1ea595bd55047b2663fdb5001f3edb Mon Sep 17 00:00:00 2001 From: Vit Stanislav Date: Wed, 19 Jul 2017 11:19:03 +0200 Subject: [PATCH 03/24] Fix forging reducers to append and prepend forgedBlocks --- src/store/reducers/forging.js | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/src/store/reducers/forging.js b/src/store/reducers/forging.js index 70bbd8e25..5a24384f2 100644 --- a/src/store/reducers/forging.js +++ b/src/store/reducers/forging.js @@ -6,10 +6,21 @@ import actionTypes from '../../constants/actions'; * @param {Object} action */ const forging = (state = { forgedBlocks: [], statistics: {} }, action) => { + let startTimesamp; + let endTimesamp; + switch (action.type) { case actionTypes.forgedBlocksUpdated: + startTimesamp = state.forgedBlocks.length ? state.forgedBlocks[0].timestamp : 0; + endTimesamp = state.forgedBlocks.length ? + state.forgedBlocks[state.forgedBlocks.length - 1].timestamp : + 0; return Object.assign({}, state, { - forgedBlocks: (state.forgedBlocks || []).concat(action.data), + forgedBlocks: [].concat( + action.data.filter(block => block.timestamp > startTimesamp), + state.forgedBlocks, + action.data.filter(block => block.timestamp < endTimesamp), + ), }); case actionTypes.forgingStatsUpdated: return Object.assign({}, state, { From 6ca8ceb9e725244ffe1d8af12d7b9f44aaac6f60 Mon Sep 17 00:00:00 2001 From: Vit Stanislav Date: Wed, 19 Jul 2017 11:20:09 +0200 Subject: [PATCH 04/24] Add tests for forging reducers --- src/store/reducers/forging.test.js | 86 ++++++++++++++++++++++++++++++ 1 file changed, 86 insertions(+) create mode 100644 src/store/reducers/forging.test.js diff --git a/src/store/reducers/forging.test.js b/src/store/reducers/forging.test.js new file mode 100644 index 000000000..7fa4ca09a --- /dev/null +++ b/src/store/reducers/forging.test.js @@ -0,0 +1,86 @@ +import chai, { expect } from 'chai'; +import sinonChai from 'sinon-chai'; +import forging from './forging'; +import actionTypes from '../../constants/actions'; + + +chai.use(sinonChai); + +describe('Reducer: forging(state, action)', () => { + let state; + const blocks = [{ + id: '16113150790072764126', + timestamp: 36280810, + height: 29394, + totalFee: 0, + reward: 0, + }, + { + id: '13838471839278892195', + version: 0, + timestamp: 36280700, + height: 29383, + totalFee: 0, + reward: 0, + }, + { + id: '5654150596698663763', + version: 0, + timestamp: 36279700, + height: 29283, + totalFee: 0, + reward: 0, + }]; + + it('should set forgedBlocks if action.type = actionTypes.forgedBlocksUpdate and state.forgedBlocks is []', () => { + state = { + statistics: {}, + forgedBlocks: [], + }; + const action = { + type: actionTypes.forgedBlocksUpdated, + data: [blocks[0], blocks[1]], + }; + const changedState = forging(state, action); + expect(changedState.forgedBlocks).to.deep.equal(action.data); + }); + + it('should prepend forgedBlocks with newer blocks if action.type = actionTypes.forgedBlocksUpdated', () => { + state = { + statistics: {}, + forgedBlocks: [blocks[2]], + }; + const action = { + type: actionTypes.forgedBlocksUpdated, + data: [blocks[0], blocks[1]], + }; + const changedState = forging(state, action); + expect(changedState.forgedBlocks).to.deep.equal(blocks); + }); + + it('should append forgedBlocks with older blocks if action.type = actionTypes.forgedBlocksUpdated', () => { + state = { + statistics: {}, + forgedBlocks: [blocks[0]], + }; + const action = { + type: actionTypes.forgedBlocksUpdated, + data: [blocks[1], blocks[2]], + }; + const changedState = forging(state, action); + expect(changedState.forgedBlocks).to.deep.equal(blocks); + }); + + it('should update statistics if action.type = actionTypes.forgingStatsUpdated', () => { + state = { + statistics: { last7d: 1000 }, + }; + const action = { + type: actionTypes.forgingStatsUpdated, + data: { last24h: 100 }, + }; + const changedState = forging(state, action); + expect(changedState.statistics).to.deep.equal({ last7d: 1000, last24h: 100 }); + }); +}); + From 4c6222365961476f881bc770b170db1a6f59d955 Mon Sep 17 00:00:00 2001 From: Vit Stanislav Date: Wed, 19 Jul 2017 11:37:56 +0200 Subject: [PATCH 05/24] Add unit tests for forging actions --- src/actions/forging.test.js | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) create mode 100644 src/actions/forging.test.js diff --git a/src/actions/forging.test.js b/src/actions/forging.test.js new file mode 100644 index 000000000..2cf3e4bcc --- /dev/null +++ b/src/actions/forging.test.js @@ -0,0 +1,27 @@ +import { expect } from 'chai'; +import actionTypes from '../constants/actions'; +import { updateForgedBlocks, updateForgingStats } from './forging'; + +describe('actions', () => { + it('should create an action to update forged blocks', () => { + const data = { + online: true, + }; + + const expectedAction = { + data, + type: actionTypes.forgedBlocksUpdated, + }; + expect(updateForgedBlocks(data)).to.be.deep.equal(expectedAction); + }); + + it('should create an action to update forging stats', () => { + const data = { last7d: 1000 }; + + const expectedAction = { + data, + type: actionTypes.forgingStatsUpdated, + }; + expect(updateForgingStats(data)).to.be.deep.equal(expectedAction); + }); +}); From 2e64149bb8dd72e5d9dc9949cb4cfc51aaef543a Mon Sep 17 00:00:00 2001 From: Vit Stanislav Date: Wed, 19 Jul 2017 15:32:22 +0200 Subject: [PATCH 06/24] Add more unit tests for forging components --- src/components/forging/delegateStats.test.js | 29 +++++++++++ .../forging/forgingComponent.test.js | 42 +++++++++++++++ src/components/forging/forgingStats.test.js | 52 +++++++++++++++++++ src/components/forging/forgingTitle.test.js | 37 +++++++++++++ src/components/forging/index.js | 2 +- src/components/forging/index.test.js | 22 ++++++++ 6 files changed, 183 insertions(+), 1 deletion(-) create mode 100644 src/components/forging/delegateStats.test.js create mode 100644 src/components/forging/forgingComponent.test.js create mode 100644 src/components/forging/forgingStats.test.js create mode 100644 src/components/forging/forgingTitle.test.js create mode 100644 src/components/forging/index.test.js diff --git a/src/components/forging/delegateStats.test.js b/src/components/forging/delegateStats.test.js new file mode 100644 index 000000000..2a189da25 --- /dev/null +++ b/src/components/forging/delegateStats.test.js @@ -0,0 +1,29 @@ +import React from 'react'; +import chai, { expect } from 'chai'; +import sinonChai from 'sinon-chai'; +import { mount } from 'enzyme'; +import DelegateStats from './delegateStats'; + +chai.use(sinonChai); + +describe('', () => { + const delegate = { + username: 'genesis_17', + rate: 19, + approval: 30, + productivity: 99.2, + }; + let wrapper; + + beforeEach(() => { + wrapper = mount(); + }); + + it('should render 3 Card components', () => { + expect(wrapper.find('Card')).to.have.lengthOf(3); + }); + + it('should render 3 CircularProgressbar components', () => { + expect(wrapper.find('svg.CircularProgressbar')).to.have.lengthOf(3); + }); +}); diff --git a/src/components/forging/forgingComponent.test.js b/src/components/forging/forgingComponent.test.js new file mode 100644 index 000000000..e9c85bab0 --- /dev/null +++ b/src/components/forging/forgingComponent.test.js @@ -0,0 +1,42 @@ +import React from 'react'; +import chai, { expect } from 'chai'; +import sinonChai from 'sinon-chai'; +import { mount } from 'enzyme'; +import ForgingComponent from './forgingComponent'; + +chai.use(sinonChai); + + +describe('', () => { + let wrapper; + const props = { + account: { + delegate: {}, + }, + peers: {}, + statistics: {}, + forgedBlocks: [], + loadStats: () => {}, + loadForgedBlocks: () => {}, + }; + + beforeEach(() => { + wrapper = mount(); + }); + + it('should render ', () => { + expect(wrapper.find('ForgingTitle')).to.have.lengthOf(1); + }); + + it('should render ', () => { + expect(wrapper.find('ForgingStats')).to.have.lengthOf(1); + }); + + it('should render ', () => { + expect(wrapper.find('DelegateStats')).to.have.lengthOf(1); + }); + + it('should render ', () => { + expect(wrapper.find('ForgedBlocks')).to.have.lengthOf(1); + }); +}); diff --git a/src/components/forging/forgingStats.test.js b/src/components/forging/forgingStats.test.js new file mode 100644 index 000000000..c323861a0 --- /dev/null +++ b/src/components/forging/forgingStats.test.js @@ -0,0 +1,52 @@ +import React from 'react'; +import chai, { expect } from 'chai'; +import sinonChai from 'sinon-chai'; +import { mount } from 'enzyme'; +import ForgingStats from './forgingStats'; + +chai.use(sinonChai); + + +describe('', () => { + const account = { + delegate: { + username: 'genesis_17', + rate: 19, + approval: 30, + productivity: 99.2, + }, + }; + const statistics = { + last24h: 321317, + last7d: 3213179124, + last30d: 321317912423, + last365d: 32131791242342, + }; + const loadStats = () => {}; + let wrapper; + + beforeEach(() => { + wrapper = mount(); + }); + + it('should render 4 Card components', () => { + expect(wrapper.find('Card')).to.have.lengthOf(4); + }); + + it('should render Card component for Last 24 hours', () => { + expect(wrapper.find('Card').at(0).text().trim()).to.equal('Last 24 hours 0.00321317 LSK'); + }); + + it('should render Card component for Last 7 days', () => { + expect(wrapper.find('Card').at(1).text().trim()).to.equal('Last 7 days 32.13179124 LSK'); + }); + + it('should render Card component for Last 30 days', () => { + expect(wrapper.find('Card').at(2).text().trim()).to.equal('Last 30 days 3,213.17912423 LSK'); + }); + + it('should render Card component for Last 365 days', () => { + expect(wrapper.find('Card').at(3).text().trim()).to.equal('Last 365 days 321,317.91242342 LSK'); + }); +}); diff --git a/src/components/forging/forgingTitle.test.js b/src/components/forging/forgingTitle.test.js new file mode 100644 index 000000000..503e3a45e --- /dev/null +++ b/src/components/forging/forgingTitle.test.js @@ -0,0 +1,37 @@ +import React from 'react'; +import chai, { expect } from 'chai'; +import sinonChai from 'sinon-chai'; +import { mount } from 'enzyme'; +import ForgingTitle from './forgingTitle'; + +chai.use(sinonChai); + + +describe('', () => { + const account = { + delegate: { + username: 'genesis_17', + rate: 19, + approval: 30, + productivity: 99.2, + }, + }; + const statistics = { + total: 132423, + }; + const loadStats = () => {}; + let wrapper; + + beforeEach(() => { + wrapper = mount(); + }); + + it('should render 1 Card component', () => { + expect(wrapper.find('Card')).to.have.lengthOf(1); + }); + + it('should render h2 with delegate name', () => { + expect(wrapper.find('h2').text()).to.equal(account.delegate.username); + }); +}); diff --git a/src/components/forging/index.js b/src/components/forging/index.js index db0b9e4b5..efe62ad6d 100644 --- a/src/components/forging/index.js +++ b/src/components/forging/index.js @@ -11,7 +11,7 @@ const mapStateToProps = state => ({ }); const mapDispatchToProps = dispatch => ({ - loadForgedBlocks: (activePeer, limit = 10, offset = 0, generatorPublicKey) => { + loadForgedBlocks: (activePeer, limit, offset, generatorPublicKey) => { getForgedBlocks(activePeer, limit, offset, generatorPublicKey).then((data) => { dispatch(updateForgedBlocks(data.blocks)); }); diff --git a/src/components/forging/index.test.js b/src/components/forging/index.test.js new file mode 100644 index 000000000..7515ef220 --- /dev/null +++ b/src/components/forging/index.test.js @@ -0,0 +1,22 @@ +import React from 'react'; +import chai, { expect } from 'chai'; +import sinonChai from 'sinon-chai'; +import { mount } from 'enzyme'; +import { Provider } from 'react-redux'; +import Forging from './'; +import store from '../../store'; + +chai.use(sinonChai); + + +describe('', () => { + let wrapper; + + beforeEach(() => { + wrapper = mount(); + }); + + it('should render 1 ', () => { + expect(wrapper.find('ForgingComponent')).to.have.lengthOf(1); + }); +}); From e9f3ef9eb5554cd7799c39b99893a3ec45c0a076 Mon Sep 17 00:00:00 2001 From: Vit Stanislav Date: Fri, 21 Jul 2017 12:27:03 +0200 Subject: [PATCH 07/24] Use instead of react-timeago --- package.json | 1 - src/components/forging/forgedBlocks.js | 4 ++-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/package.json b/package.json index face2f63f..add013e3d 100644 --- a/package.json +++ b/package.json @@ -40,7 +40,6 @@ "react-redux": "=5.0.3", "react-redux-toastr": "=7.0.0", "react-router-dom": "=4.0.0", - "react-timeago": "=3.3.0", "react-toolbox": "=2.0.0-beta.12", "redux": "=3.6.0", "redux-logger": "=3.0.6" diff --git a/src/components/forging/forgedBlocks.js b/src/components/forging/forgedBlocks.js index 5fa7160d3..88e4b6fb1 100644 --- a/src/components/forging/forgedBlocks.js +++ b/src/components/forging/forgedBlocks.js @@ -1,7 +1,7 @@ import React from 'react'; import { Card, CardTitle } from 'react-toolbox/lib/card'; import { Table, TableHead, TableRow, TableCell } from 'react-toolbox/lib/table'; -import TimeAgo from 'react-timeago'; +import { TooltipTime } from '../timestamp'; import FormattedNumber from '../formattedNumber'; import grid from '../../../node_modules/flexboxgrid/dist/flexboxgrid.css'; import style from './forging.css'; @@ -25,7 +25,7 @@ const ForgedBlocks = props => ( {block.id} - + From c06f0b9c145164dd391a4df01fdc21d70788d4aa Mon Sep 17 00:00:00 2001 From: Vit Stanislav Date: Fri, 21 Jul 2017 13:04:56 +0200 Subject: [PATCH 08/24] Use spread operator instead of [].concat --- src/store/reducers/forging.js | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/store/reducers/forging.js b/src/store/reducers/forging.js index 5a24384f2..caa7186b4 100644 --- a/src/store/reducers/forging.js +++ b/src/store/reducers/forging.js @@ -16,11 +16,11 @@ const forging = (state = { forgedBlocks: [], statistics: {} }, action) => { state.forgedBlocks[state.forgedBlocks.length - 1].timestamp : 0; return Object.assign({}, state, { - forgedBlocks: [].concat( - action.data.filter(block => block.timestamp > startTimesamp), - state.forgedBlocks, - action.data.filter(block => block.timestamp < endTimesamp), - ), + forgedBlocks: [ + ...action.data.filter(block => block.timestamp > startTimesamp), + ...state.forgedBlocks, + ...action.data.filter(block => block.timestamp < endTimesamp), + ], }); case actionTypes.forgingStatsUpdated: return Object.assign({}, state, { From dacebdd763d6871e6211c8b920ea39b7ccfd2a32 Mon Sep 17 00:00:00 2001 From: Vit Stanislav Date: Fri, 21 Jul 2017 17:37:48 +0200 Subject: [PATCH 09/24] Load delegate info with account --- src/components/login/loginFormComponent.js | 8 ++++++++ src/utils/api/delegate.js | 4 ++-- src/utils/api/delegate.test.js | 4 ++-- src/utils/api/forging.js | 5 ----- src/utils/api/forging.test.js | 7 ------- 5 files changed, 12 insertions(+), 16 deletions(-) diff --git a/src/components/login/loginFormComponent.js b/src/components/login/loginFormComponent.js index 9ef8015c0..3a4f50053 100644 --- a/src/components/login/loginFormComponent.js +++ b/src/components/login/loginFormComponent.js @@ -6,6 +6,7 @@ import Dropdown from 'react-toolbox/lib/dropdown'; import Button from 'react-toolbox/lib/button'; import Checkbox from 'react-toolbox/lib/checkbox'; import { getAccount } from '../../utils/api/account'; +import { getDelegate } from '../../utils/api/delegate'; import networksRaw from './networks'; if (global._bitcore) delete global._bitcore; @@ -94,6 +95,13 @@ class LoginFormComponent extends React.Component { // redirect to main/transactions getAccount(this.props.peers.data, accountInfo.address).then((result) => { onAccountUpdated(result); + getDelegate(this.props.peers.data, accountInfo.publicKey).then((data) => { + if (data.success) { + onAccountUpdated({ delegate: data.delegate, isDelegate: true }); + } else { + onAccountUpdated({ delegate: {}, isDelegate: false }); + } + }); // redirect to main/transactions this.props.history.push('/main/transactions'); }); diff --git a/src/utils/api/delegate.js b/src/utils/api/delegate.js index e523d0fb5..7d0143475 100644 --- a/src/utils/api/delegate.js +++ b/src/utils/api/delegate.js @@ -7,8 +7,8 @@ export const listAccountDelegates = (activePeer, address) => export const listDelegates = (activePeer, options) => requestToActivePeer(activePeer, `delegates/${options.q ? 'search' : ''}`, options); -export const getDelegate = (activePeer, options) => - requestToActivePeer(activePeer, 'delegates/get', options); +export const getDelegate = (activePeer, publicKey) => + requestToActivePeer(activePeer, 'delegates/get', { publicKey }); export const vote = (activePeer, secret, publicKey, voteList, unvoteList, secondSecret = null) => requestToActivePeer(activePeer, 'accounts/delegates', { diff --git a/src/utils/api/delegate.test.js b/src/utils/api/delegate.test.js index c30281053..1b27deb94 100644 --- a/src/utils/api/delegate.test.js +++ b/src/utils/api/delegate.test.js @@ -61,11 +61,11 @@ describe('Delegate', () => { describe('getDelegate', () => { it('should return requestToActivePeer(activePeer, `delegates/get`, options)', () => { - const options = {}; + const options = { publicKey: '"86499879448d1b0215d59cbf078836e3d7d9d2782d56a2274a568761bff36f19"' }; const mockedPromise = new Promise((resolve) => { resolve(); }); peersMock.expects('requestToActivePeer').withArgs(activePeer, 'delegates/get', options).returns(mockedPromise); - const returnedPromise = getDelegate(activePeer, options); + const returnedPromise = getDelegate(activePeer, options.publicKey); expect(returnedPromise).to.equal(mockedPromise); }); }); diff --git a/src/utils/api/forging.js b/src/utils/api/forging.js index 35af093d4..bcd798d60 100644 --- a/src/utils/api/forging.js +++ b/src/utils/api/forging.js @@ -1,11 +1,6 @@ import moment from 'moment'; import { requestToActivePeer } from './peers'; -export const getDelegate = (activePeer, publicKey) => - requestToActivePeer(activePeer, 'delegates/get', { - publicKey, - }); - export const getForgedBlocks = (activePeer, limit = 10, offset = 0, generatorPublicKey) => requestToActivePeer(activePeer, 'blocks', { limit, diff --git a/src/utils/api/forging.test.js b/src/utils/api/forging.test.js index 5e9b5d301..ff9ea861e 100644 --- a/src/utils/api/forging.test.js +++ b/src/utils/api/forging.test.js @@ -5,13 +5,6 @@ import { getDelegate, getForgedBlocks, getForgedStats } from './forging'; chai.use(sinonChai); describe('Peers', () => { - describe('getDelegate', () => { - it('should return a promise', () => { - const promise = getDelegate(); - expect(typeof promise.then).to.be.equal('function'); - }); - }); - describe('getForgedBlocks', () => { it('should return a promise', () => { const promise = getForgedBlocks(); From e6f344ac3006c6476b574d16f51d3d6f582ba345 Mon Sep 17 00:00:00 2001 From: Vit Stanislav Date: Fri, 21 Jul 2017 17:38:19 +0200 Subject: [PATCH 10/24] Move Page links right below Account --- src/components/app/index.js | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/components/app/index.js b/src/components/app/index.js index c7eef125a..d5af8bfe5 100644 --- a/src/components/app/index.js +++ b/src/components/app/index.js @@ -23,6 +23,9 @@ const App = () => { (
+ Transactions + Voting + Forging @@ -31,10 +34,6 @@ const App = () => {
- Login - Transactions - Voting - Forging ); From c94c0587908a8a79df3b04828eda95b095e1335e Mon Sep 17 00:00:00 2001 From: Vit Stanislav Date: Fri, 21 Jul 2017 17:51:27 +0200 Subject: [PATCH 11/24] Replace FormattedNumber with LiskNumnber in forging --- src/components/forging/forgingStats.js | 4 ++-- src/components/forging/forgingTitle.js | 5 ++--- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/src/components/forging/forgingStats.js b/src/components/forging/forgingStats.js index b33c2a339..ec0cca590 100644 --- a/src/components/forging/forgingStats.js +++ b/src/components/forging/forgingStats.js @@ -1,7 +1,7 @@ import React from 'react'; import { Card, CardText } from 'react-toolbox/lib/card'; import moment from 'moment'; -import FormattedNumber from '../formattedNumber'; +import LiskAmount from '../liskAmount'; import grid from '../../../node_modules/flexboxgrid/dist/flexboxgrid.css'; import style from './forging.css'; @@ -43,7 +43,7 @@ class ForgingStats extends React.Component {
{cardObj.label} - LSK
diff --git a/src/components/forging/forgingTitle.js b/src/components/forging/forgingTitle.js index 2866d294f..43802ef18 100644 --- a/src/components/forging/forgingTitle.js +++ b/src/components/forging/forgingTitle.js @@ -1,7 +1,7 @@ import React from 'react'; import { Card, CardText } from 'react-toolbox/lib/card'; import moment from 'moment'; -import FormattedNumber from '../formattedNumber'; +import LiskAmount from '../liskAmount'; import grid from '../../../node_modules/flexboxgrid/dist/flexboxgrid.css'; import style from './forging.css'; @@ -21,8 +21,7 @@ class ForgingTitle extends React.Component { {this.props.account.delegate.username} - LSK Earned + LSK Earned From d0c4cc1d3de69674e68baddee2324c72a4901ab0 Mon Sep 17 00:00:00 2001 From: Vit Stanislav Date: Fri, 21 Jul 2017 17:51:46 +0200 Subject: [PATCH 12/24] Fix delegate username in account component --- src/components/account/address.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/account/address.js b/src/components/account/address.js index e5fa9a402..4b862f179 100644 --- a/src/components/account/address.js +++ b/src/components/account/address.js @@ -6,7 +6,7 @@ const Address = (props) => { const content = props.isDelegate ? (

- {props.username} + {props.delegate.username}

{props.address} From 8ad94950b205d03d229b7934c017132fb806cea5 Mon Sep 17 00:00:00 2001 From: Vit Stanislav Date: Fri, 21 Jul 2017 17:52:13 +0200 Subject: [PATCH 13/24] Fix forging reducer to work without forgedBlocks --- src/store/reducers/forging.js | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/store/reducers/forging.js b/src/store/reducers/forging.js index caa7186b4..eb026ee75 100644 --- a/src/store/reducers/forging.js +++ b/src/store/reducers/forging.js @@ -11,8 +11,10 @@ const forging = (state = { forgedBlocks: [], statistics: {} }, action) => { switch (action.type) { case actionTypes.forgedBlocksUpdated: - startTimesamp = state.forgedBlocks.length ? state.forgedBlocks[0].timestamp : 0; - endTimesamp = state.forgedBlocks.length ? + startTimesamp = state.forgedBlocks && state.forgedBlocks.length ? + state.forgedBlocks[0].timestamp : + 0; + endTimesamp = state.forgedBlocks && state.forgedBlocks.length ? state.forgedBlocks[state.forgedBlocks.length - 1].timestamp : 0; return Object.assign({}, state, { From 3988ae2e3802504bf0874be6688d606701ca8129 Mon Sep 17 00:00:00 2001 From: Vit Stanislav Date: Fri, 21 Jul 2017 18:05:45 +0200 Subject: [PATCH 14/24] Fix Address delegate test --- src/components/account/address.test.js | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/components/account/address.test.js b/src/components/account/address.test.js index f103ae13f..bf577f452 100644 --- a/src/components/account/address.test.js +++ b/src/components/account/address.test.js @@ -18,7 +18,9 @@ describe('Address', () => { const inputValue = { isDelegate: true, address: '16313739661670634666L', - username: 'lisk-nano', + delegate: { + username: 'lisk-nano', + }, }; const expectedHeaderValue = 'Delegate'; const wrapper = shallow(

); @@ -29,7 +31,9 @@ describe('Address', () => { const inputValue = { isDelegate: true, address: '16313739661670634666L', - username: 'lisk-nano', + delegate: { + username: 'lisk-nano', + }, }; const expectedValue = 'lisk-nano'; const wrapper = shallow(
); From 7a09fabd68901b2de3e69833709f891d2e456cc9 Mon Sep 17 00:00:00 2001 From: Vit Stanislav Date: Fri, 21 Jul 2017 18:06:04 +0200 Subject: [PATCH 15/24] Fix test descriptions --- src/components/forging/forgingComponent.test.js | 10 +++++----- src/components/forging/index.test.js | 4 ++-- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/components/forging/forgingComponent.test.js b/src/components/forging/forgingComponent.test.js index e9c85bab0..80e029b28 100644 --- a/src/components/forging/forgingComponent.test.js +++ b/src/components/forging/forgingComponent.test.js @@ -7,7 +7,7 @@ import ForgingComponent from './forgingComponent'; chai.use(sinonChai); -describe('', () => { +describe('ForgingComponent', () => { let wrapper; const props = { account: { @@ -24,19 +24,19 @@ describe('', () => { wrapper = mount(); }); - it('should render ', () => { + it('should render ForgingTitle', () => { expect(wrapper.find('ForgingTitle')).to.have.lengthOf(1); }); - it('should render ', () => { + it('should render ForgingStats', () => { expect(wrapper.find('ForgingStats')).to.have.lengthOf(1); }); - it('should render ', () => { + it('should render DelegateStats', () => { expect(wrapper.find('DelegateStats')).to.have.lengthOf(1); }); - it('should render ', () => { + it('should render ForgedBlocks', () => { expect(wrapper.find('ForgedBlocks')).to.have.lengthOf(1); }); }); diff --git a/src/components/forging/index.test.js b/src/components/forging/index.test.js index 7515ef220..72babc785 100644 --- a/src/components/forging/index.test.js +++ b/src/components/forging/index.test.js @@ -9,14 +9,14 @@ import store from '../../store'; chai.use(sinonChai); -describe('', () => { +describe('Forging', () => { let wrapper; beforeEach(() => { wrapper = mount(); }); - it('should render 1 ', () => { + it('should render ForgingComponent', () => { expect(wrapper.find('ForgingComponent')).to.have.lengthOf(1); }); }); From d753137532b6719f03643b78391aee0e8ce0c020 Mon Sep 17 00:00:00 2001 From: Vit Stanislav Date: Fri, 21 Jul 2017 18:19:46 +0200 Subject: [PATCH 16/24] Use LiskAmount in forgedBlocks --- src/components/forging/forgedBlocks.js | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/components/forging/forgedBlocks.js b/src/components/forging/forgedBlocks.js index 88e4b6fb1..d43ee5808 100644 --- a/src/components/forging/forgedBlocks.js +++ b/src/components/forging/forgedBlocks.js @@ -2,6 +2,7 @@ import React from 'react'; import { Card, CardTitle } from 'react-toolbox/lib/card'; import { Table, TableHead, TableRow, TableCell } from 'react-toolbox/lib/table'; import { TooltipTime } from '../timestamp'; +import LiskAmount from '../liskAmount'; import FormattedNumber from '../formattedNumber'; import grid from '../../../node_modules/flexboxgrid/dist/flexboxgrid.css'; import style from './forging.css'; @@ -26,8 +27,8 @@ const ForgedBlocks = props => ( {block.id} - - + + ))} From 3eb46c0f2d59cdd17c6e37b6e8ecdb232e67b56d Mon Sep 17 00:00:00 2001 From: Vit Stanislav Date: Fri, 21 Jul 2017 19:55:31 +0200 Subject: [PATCH 17/24] Remove unused import from forging.test.js --- src/utils/api/forging.test.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/utils/api/forging.test.js b/src/utils/api/forging.test.js index 5d905221e..861c3635a 100644 --- a/src/utils/api/forging.test.js +++ b/src/utils/api/forging.test.js @@ -1,6 +1,6 @@ import chai, { expect } from 'chai'; import sinonChai from 'sinon-chai'; -import { getDelegate, getForgedBlocks, getForgedStats } from './forging'; +import { getForgedBlocks, getForgedStats } from './forging'; chai.use(sinonChai); From 27806fa32d94c4a11e941059a071419983532577 Mon Sep 17 00:00:00 2001 From: Vit Stanislav Date: Fri, 21 Jul 2017 22:52:23 +0200 Subject: [PATCH 18/24] Handle non-delegate state of forgingComponent --- src/components/forging/forgingComponent.js | 10 +++++++++- src/components/login/loginFormComponent.js | 8 +++----- 2 files changed, 12 insertions(+), 6 deletions(-) diff --git a/src/components/forging/forgingComponent.js b/src/components/forging/forgingComponent.js index 2e7b992a0..dda1a3c03 100644 --- a/src/components/forging/forgingComponent.js +++ b/src/components/forging/forgingComponent.js @@ -19,7 +19,7 @@ class ForgingComponent extends React.Component { render() { return ( - {this.props.account && this.props.account.delegate ? + {this.props.account && this.props.account.isDelegate ?
@@ -39,6 +39,14 @@ class ForgingComponent extends React.Component {
: null } + {this.props.account && this.props.account.delegate && !this.props.account.isDelegate ? +

+ You need to become a delegate to start forging. + If you already registered to become a delegate, + your registration hasn't been processed, yet. +

: + null + }
); } diff --git a/src/components/login/loginFormComponent.js b/src/components/login/loginFormComponent.js index 3a4f50053..ffb79571b 100644 --- a/src/components/login/loginFormComponent.js +++ b/src/components/login/loginFormComponent.js @@ -96,11 +96,9 @@ class LoginFormComponent extends React.Component { getAccount(this.props.peers.data, accountInfo.address).then((result) => { onAccountUpdated(result); getDelegate(this.props.peers.data, accountInfo.publicKey).then((data) => { - if (data.success) { - onAccountUpdated({ delegate: data.delegate, isDelegate: true }); - } else { - onAccountUpdated({ delegate: {}, isDelegate: false }); - } + onAccountUpdated({ delegate: data.delegate, isDelegate: true }); + }).catch(() => { + onAccountUpdated({ delegate: {}, isDelegate: false }); }); // redirect to main/transactions this.props.history.push('/main/transactions'); From dc3cd2ee647861c81531d28fabd41bb219a7b3ca Mon Sep 17 00:00:00 2001 From: Vit Stanislav Date: Mon, 24 Jul 2017 14:02:49 +0200 Subject: [PATCH 19/24] Fix test describe statements --- src/components/forging/delegateStats.test.js | 2 +- src/components/forging/forgedBlocks.test.js | 2 +- src/components/forging/forgingStats.test.js | 2 +- src/components/forging/forgingTitle.test.js | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/components/forging/delegateStats.test.js b/src/components/forging/delegateStats.test.js index 2a189da25..1ce83b70c 100644 --- a/src/components/forging/delegateStats.test.js +++ b/src/components/forging/delegateStats.test.js @@ -6,7 +6,7 @@ import DelegateStats from './delegateStats'; chai.use(sinonChai); -describe('', () => { +describe('DelegateStats', () => { const delegate = { username: 'genesis_17', rate: 19, diff --git a/src/components/forging/forgedBlocks.test.js b/src/components/forging/forgedBlocks.test.js index 294fdc6f9..3babb2c14 100644 --- a/src/components/forging/forgedBlocks.test.js +++ b/src/components/forging/forgedBlocks.test.js @@ -6,7 +6,7 @@ import ForgedBlocks from './forgedBlocks'; chai.use(sinonChai); -describe('', () => { +describe('ForgedBlocks', () => { const forgedBlocks = [{ id: '16113150790072764126', timestamp: 36280810, diff --git a/src/components/forging/forgingStats.test.js b/src/components/forging/forgingStats.test.js index c323861a0..900922af6 100644 --- a/src/components/forging/forgingStats.test.js +++ b/src/components/forging/forgingStats.test.js @@ -7,7 +7,7 @@ import ForgingStats from './forgingStats'; chai.use(sinonChai); -describe('', () => { +describe('ForgingStats', () => { const account = { delegate: { username: 'genesis_17', diff --git a/src/components/forging/forgingTitle.test.js b/src/components/forging/forgingTitle.test.js index 503e3a45e..5581fb46d 100644 --- a/src/components/forging/forgingTitle.test.js +++ b/src/components/forging/forgingTitle.test.js @@ -7,7 +7,7 @@ import ForgingTitle from './forgingTitle'; chai.use(sinonChai); -describe('', () => { +describe('ForgingTitle', () => { const account = { delegate: { username: 'genesis_17', From 000e534d42254e19363465f3e0b76f1d048ded71 Mon Sep 17 00:00:00 2001 From: Vit Stanislav Date: Mon, 24 Jul 2017 14:08:01 +0200 Subject: [PATCH 20/24] Rename variables in delegateStats --- src/components/forging/delegateStats.js | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/components/forging/delegateStats.js b/src/components/forging/delegateStats.js index e504afa85..1e6a313c5 100644 --- a/src/components/forging/delegateStats.js +++ b/src/components/forging/delegateStats.js @@ -4,12 +4,12 @@ import CircularProgressbar from 'react-circular-progressbar'; import grid from '../../../node_modules/flexboxgrid/dist/flexboxgrid.css'; import style from './forging.css'; -const progressCircleCardObjects = [ +const progressCircleCardList = [ { key: 'rate', label: 'Rank', - textForPercentage: pct => (101 - pct), - percentageTransform: pct => (101 - pct), + textForPercentage: percentage => (101 - percentage), + percentageTransform: percentage => (101 - percentage), }, { key: 'productivity', label: 'Productivity', @@ -23,16 +23,16 @@ const identity = x => (x); const DelegateStats = props => (
- {progressCircleCardObjects.map(cardObj => ( -
+ {progressCircleCardList.map(cardItem => ( +
-
{cardObj.label}
+
{cardItem.label}
+ percentage={(cardItem.percentageTransform || identity)(props.delegate[cardItem.key])} + textForPercentage={cardItem.textForPercentage}/>
From cbfe8d30bbf20f729f20d73bcc00a3d07d701e11 Mon Sep 17 00:00:00 2001 From: Vit Stanislav Date: Mon, 24 Jul 2017 14:10:31 +0200 Subject: [PATCH 21/24] Refactor percentageTransform in delegateStats --- src/components/forging/delegateStats.js | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/components/forging/delegateStats.js b/src/components/forging/delegateStats.js index 1e6a313c5..ad79e8c1c 100644 --- a/src/components/forging/delegateStats.js +++ b/src/components/forging/delegateStats.js @@ -4,6 +4,8 @@ import CircularProgressbar from 'react-circular-progressbar'; import grid from '../../../node_modules/flexboxgrid/dist/flexboxgrid.css'; import style from './forging.css'; +const identity = x => (x); + const progressCircleCardList = [ { key: 'rate', @@ -13,14 +15,14 @@ const progressCircleCardList = [ }, { key: 'productivity', label: 'Productivity', + percentageTransform: identity, }, { key: 'approval', label: 'Approval', + percentageTransform: identity, }, ]; -const identity = x => (x); - const DelegateStats = props => (
{progressCircleCardList.map(cardItem => ( @@ -31,7 +33,7 @@ const DelegateStats = props => (
{cardItem.label}
From 2970c606d30836cf1432addb8989b43fb6df52b2 Mon Sep 17 00:00:00 2001 From: Vit Stanislav Date: Mon, 24 Jul 2017 14:25:47 +0200 Subject: [PATCH 22/24] Move Api calls to the forgingComponent consuming the data --- src/components/forging/forgingComponent.js | 19 ++++++++++++------- src/components/forging/index.js | 13 ++++--------- 2 files changed, 16 insertions(+), 16 deletions(-) diff --git a/src/components/forging/forgingComponent.js b/src/components/forging/forgingComponent.js index dda1a3c03..7ee452b52 100644 --- a/src/components/forging/forgingComponent.js +++ b/src/components/forging/forgingComponent.js @@ -1,6 +1,7 @@ import React from 'react'; import { Card } from 'react-toolbox/lib/card'; import Waypoint from 'react-waypoint'; +import { getForgedBlocks, getForgedStats } from '../../utils/api/forging'; import ForgingTitle from './forgingTitle'; import DelegateStats from './delegateStats'; import ForgingStats from './forgingStats'; @@ -8,12 +9,16 @@ import ForgedBlocks from './forgedBlocks'; class ForgingComponent extends React.Component { loadStats(key, startMoment) { - this.props.loadStats( - this.props.peers.data, - key, - startMoment, - this.props.account.publicKey, - ); + getForgedStats(this.props.peers.data, startMoment, this.props.account.publicKey, + ).then((data) => { + this.props.onForgingStatsUpdate({ [key]: data.forged }); + }); + } + + loadForgedBlocks(activePeer, limit, offset, generatorPublicKey) { + getForgedBlocks(activePeer, limit, offset, generatorPublicKey).then((data) => { + this.props.onForgedBlocksLoaded(data.blocks); + }); } render() { @@ -30,7 +35,7 @@ class ForgingComponent extends React.Component {
- this.props.loadForgedBlocks( + this.loadForgedBlocks( this.props.peers.data, 20, this.props.forgedBlocks.length, diff --git a/src/components/forging/index.js b/src/components/forging/index.js index efe62ad6d..89766e186 100644 --- a/src/components/forging/index.js +++ b/src/components/forging/index.js @@ -1,7 +1,6 @@ import { connect } from 'react-redux'; import { updateForgedBlocks, updateForgingStats } from '../../actions/forging'; import ForgingComponent from './forgingComponent'; -import { getForgedBlocks, getForgedStats } from '../../utils/api/forging'; const mapStateToProps = state => ({ account: state.account, @@ -11,15 +10,11 @@ const mapStateToProps = state => ({ }); const mapDispatchToProps = dispatch => ({ - loadForgedBlocks: (activePeer, limit, offset, generatorPublicKey) => { - getForgedBlocks(activePeer, limit, offset, generatorPublicKey).then((data) => { - dispatch(updateForgedBlocks(data.blocks)); - }); + onForgedBlocksLoaded: (blocks) => { + dispatch(updateForgedBlocks(blocks)); }, - loadStats: (activePeer, key, startMoment, generatorPublicKey) => { - getForgedStats(activePeer, startMoment, generatorPublicKey).then((data) => { - dispatch(updateForgingStats({ [key]: data.forged })); - }); + onForgingStatsUpdate: (stats) => { + dispatch(updateForgingStats(stats)); }, }); From 9c3d5021c0502e6ab9e0fd7151591a188954bd0c Mon Sep 17 00:00:00 2001 From: Vit Stanislav Date: Mon, 24 Jul 2017 14:34:22 +0200 Subject: [PATCH 23/24] Fix forgingComponent unit tests --- src/components/forging/forgingComponent.test.js | 1 + 1 file changed, 1 insertion(+) diff --git a/src/components/forging/forgingComponent.test.js b/src/components/forging/forgingComponent.test.js index 80e029b28..d625dcb79 100644 --- a/src/components/forging/forgingComponent.test.js +++ b/src/components/forging/forgingComponent.test.js @@ -12,6 +12,7 @@ describe('ForgingComponent', () => { const props = { account: { delegate: {}, + isDelegate: true, }, peers: {}, statistics: {}, From 84ec037b608c787441c44acaa9f5ef0453d7f01d Mon Sep 17 00:00:00 2001 From: Vit Stanislav Date: Mon, 24 Jul 2017 14:45:17 +0200 Subject: [PATCH 24/24] Fix delegateStats rank for rank > 101 --- src/components/forging/delegateStats.js | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/components/forging/delegateStats.js b/src/components/forging/delegateStats.js index ad79e8c1c..f9e72401f 100644 --- a/src/components/forging/delegateStats.js +++ b/src/components/forging/delegateStats.js @@ -5,21 +5,24 @@ import grid from '../../../node_modules/flexboxgrid/dist/flexboxgrid.css'; import style from './forging.css'; const identity = x => (x); +const addPercentSign = x => (`${x}%`); const progressCircleCardList = [ { key: 'rate', label: 'Rank', - textForPercentage: percentage => (101 - percentage), - percentageTransform: percentage => (101 - percentage), + percentageTransform: percentage => (Math.max(0, 101 - percentage)), + textForPercentage: identity, }, { key: 'productivity', label: 'Productivity', percentageTransform: identity, + textForPercentage: addPercentSign, }, { key: 'approval', label: 'Approval', percentageTransform: identity, + textForPercentage: addPercentSign, }, ]; @@ -34,7 +37,7 @@ const DelegateStats = props => (
{cardItem.label}
+ textForPercentage={cardItem.textForPercentage.bind(props.delegate[cardItem.key])}/>