Skip to content
Permalink
Browse files

feat(@cockpit/explorer): implement pagination for accounts explorer

Display two accounts per page in the explorer overview. Display ten accounts
per page in the accounts explorer page.

Sort accounts by their api-supplied index numbers with the lowest index coming
first.

Change the `initBlockHeader` saga so that it triggers a re-fetch of accounts
and therefore the "Tx Count" numbers of displayed accounts will reflect
increased counts.
  • Loading branch information
michaelsbradleyjr authored and iurimatias committed Apr 1, 2019
1 parent 5a502b3 commit 745edafee41883e4bc1033e75122758d8a311ce3
@@ -2,17 +2,19 @@ import React from 'react';
import {Row, Col, Card, CardHeader, CardBody} from 'reactstrap';
import {Link} from 'react-router-dom';
import PropTypes from 'prop-types';
import Pagination from './Pagination';

import CardTitleIdenticon from './CardTitleIdenticon';

const Accounts = ({accounts}) => (
const Accounts = ({accounts, changePage, currentPage, numberOfPages}) => (
<Row>
<Col>
<Card>
<CardHeader>
<h2>Accounts</h2>
</CardHeader>
<CardBody>
{!accounts.length && "No accounts to display"}
{accounts.map(account => (
<div className="explorer-row border-top" key={account.address}>
<CardTitleIdenticon id={account.address}>Account&nbsp;
@@ -34,14 +36,18 @@ const Accounts = ({accounts}) => (
</Row>
</div>
))}
{numberOfPages > 1 && <Pagination changePage={changePage} currentPage={currentPage} numberOfPages={numberOfPages}/>}
</CardBody>
</Card>
</Col>
</Row>
);

Accounts.propTypes = {
accounts: PropTypes.arrayOf(PropTypes.object)
accounts: PropTypes.arrayOf(PropTypes.object),
changePage: PropTypes.func,
currentPage: PropTypes.number,
numberOfPages: PropTypes.number
};

export default Accounts;
@@ -17,7 +17,7 @@ const ExplorerDashboardLayout = () => (
<div className="explorer-overview">
<Row>
<Col>
<AccountsContainer overridePageHead={false} />
<AccountsContainer numAccountsToDisplay={2} overridePageHead={false} />
</Col>
</Row>
<Row>
@@ -1,37 +1,105 @@
import React, {Component} from 'react';
import {connect} from 'react-redux';
import PropTypes from 'prop-types';

import {accounts as accountsAction} from '../actions';
import {accounts as accountsAction,
initBlockHeader,
stopBlockHeader} from '../actions';
import Accounts from '../components/Accounts';
import DataWrapper from "../components/DataWrapper";
import {getAccounts} from "../reducers/selectors";
import PageHead from "../components/PageHead";

const MAX_ACCOUNTS = 10;

class AccountsContainer extends Component {
constructor(props) {
super(props);

this.numAccountsToDisplay = this.props.numAccountsToDisplay || MAX_ACCOUNTS;
this.state = {currentPage: 1};
}

componentDidMount() {
this.props.fetchAccounts();
this.props.initBlockHeader();
}

componentWillUnmount() {
this.props.stopBlockHeader();
}

get numberOfAccounts() {
if (this._numberOfAccounts === undefined) {
this._numberOfAccounts = this.props.accounts.length;
}
return this._numberOfAccounts;
}

get numberOfPages() {
if (this._numberOfPages === undefined) {
this._numberOfPages = Math.ceil(
this.numberOfAccounts / this.numAccountsToDisplay
);
}
return this._numberOfPages;
}

resetNums() {
this._numberOfAccounts = undefined;
this._numberOfPages = undefined;
}

changePage(newPage) {
if (newPage <= 0) {
newPage = 1;
} else if (newPage > this.numberOfPages) {
newPage = this.numberOfPages;
}
this.setState({ currentPage: newPage });
this.props.fetchAccounts();
}

get currentAccounts() {
return this.props.accounts
.filter((account) => {
const index = (
(account.index + 1) -
(this.numAccountsToDisplay * (this.state.currentPage - 1))
);
return index <= this.numAccountsToDisplay && index > 0;
});
}

render() {
this.resetNums();
return (
<React.Fragment>
<PageHead title="Accounts" enabled={this.props.overridePageHead} description="Summary view of the accounts configured for Embark" />
<DataWrapper shouldRender={this.props.accounts.length > 0} {...this.props} render={({accounts}) => (
<Accounts accounts={accounts} />
)} />
<PageHead
title="Accounts"
enabled={this.props.overridePageHead}
description="Summary view of the accounts configured for Embark" />
<Accounts accounts={this.currentAccounts}
numberOfPages={this.numberOfPages}
changePage={(newPage) => this.changePage(newPage)}
currentPage={this.state.currentPage} />
</React.Fragment>
);
}
}

function mapStateToProps(state) {
return {accounts: getAccounts(state), error: state.errorMessage, loading: state.loading};
return {
accounts: getAccounts(state),
error: state.errorMessage,
loading: state.loading
};
}

AccountsContainer.propTypes = {
accounts: PropTypes.arrayOf(PropTypes.object),
fetchAccounts: PropTypes.func,
numAccountsToDisplay: PropTypes.number,
initBlockHeader: PropTypes.func,
stopBlockHeader: PropTypes.func,
error: PropTypes.string,
loading: PropTypes.bool,
overridePageHead: PropTypes.bool
@@ -40,6 +108,8 @@ AccountsContainer.propTypes = {
export default connect(
mapStateToProps,
{
fetchAccounts: accountsAction.request
fetchAccounts: accountsAction.request,
initBlockHeader,
stopBlockHeader
},
)(AccountsContainer);
@@ -41,6 +41,9 @@ const entitiesDefaultState = {
};

const sorter = {
accounts: function(a, b) {
return a.index - b.index;
},
blocks: function(a, b) {
return b.number - a.number;
},
@@ -420,6 +420,7 @@ export function *initBlockHeader() {
channel.close();
return;
}
yield put({type: actions.ACCOUNTS[actions.REQUEST]});
yield put({type: actions.BLOCKS[actions.REQUEST]});
yield put({type: actions.BLOCKS_FULL[actions.REQUEST], txObjects: true, txReceipts: true});
yield put({type: actions.TRANSACTIONS[actions.REQUEST]});

0 comments on commit 745edaf

Please sign in to comment.
You can’t perform that action at this time.