mirror of https://github.com/embarklabs/embark.git
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.
This commit is contained in:
parent
5a502b379a
commit
745edafee4
|
@ -2,10 +2,11 @@ import React from 'react';
|
||||||
import {Row, Col, Card, CardHeader, CardBody} from 'reactstrap';
|
import {Row, Col, Card, CardHeader, CardBody} from 'reactstrap';
|
||||||
import {Link} from 'react-router-dom';
|
import {Link} from 'react-router-dom';
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
|
import Pagination from './Pagination';
|
||||||
|
|
||||||
import CardTitleIdenticon from './CardTitleIdenticon';
|
import CardTitleIdenticon from './CardTitleIdenticon';
|
||||||
|
|
||||||
const Accounts = ({accounts}) => (
|
const Accounts = ({accounts, changePage, currentPage, numberOfPages}) => (
|
||||||
<Row>
|
<Row>
|
||||||
<Col>
|
<Col>
|
||||||
<Card>
|
<Card>
|
||||||
|
@ -13,6 +14,7 @@ const Accounts = ({accounts}) => (
|
||||||
<h2>Accounts</h2>
|
<h2>Accounts</h2>
|
||||||
</CardHeader>
|
</CardHeader>
|
||||||
<CardBody>
|
<CardBody>
|
||||||
|
{!accounts.length && "No accounts to display"}
|
||||||
{accounts.map(account => (
|
{accounts.map(account => (
|
||||||
<div className="explorer-row border-top" key={account.address}>
|
<div className="explorer-row border-top" key={account.address}>
|
||||||
<CardTitleIdenticon id={account.address}>Account
|
<CardTitleIdenticon id={account.address}>Account
|
||||||
|
@ -34,6 +36,7 @@ const Accounts = ({accounts}) => (
|
||||||
</Row>
|
</Row>
|
||||||
</div>
|
</div>
|
||||||
))}
|
))}
|
||||||
|
{numberOfPages > 1 && <Pagination changePage={changePage} currentPage={currentPage} numberOfPages={numberOfPages}/>}
|
||||||
</CardBody>
|
</CardBody>
|
||||||
</Card>
|
</Card>
|
||||||
</Col>
|
</Col>
|
||||||
|
@ -41,7 +44,10 @@ const Accounts = ({accounts}) => (
|
||||||
);
|
);
|
||||||
|
|
||||||
Accounts.propTypes = {
|
Accounts.propTypes = {
|
||||||
accounts: PropTypes.arrayOf(PropTypes.object)
|
accounts: PropTypes.arrayOf(PropTypes.object),
|
||||||
|
changePage: PropTypes.func,
|
||||||
|
currentPage: PropTypes.number,
|
||||||
|
numberOfPages: PropTypes.number
|
||||||
};
|
};
|
||||||
|
|
||||||
export default Accounts;
|
export default Accounts;
|
||||||
|
|
|
@ -17,7 +17,7 @@ const ExplorerDashboardLayout = () => (
|
||||||
<div className="explorer-overview">
|
<div className="explorer-overview">
|
||||||
<Row>
|
<Row>
|
||||||
<Col>
|
<Col>
|
||||||
<AccountsContainer overridePageHead={false} />
|
<AccountsContainer numAccountsToDisplay={2} overridePageHead={false} />
|
||||||
</Col>
|
</Col>
|
||||||
</Row>
|
</Row>
|
||||||
<Row>
|
<Row>
|
||||||
|
|
|
@ -1,37 +1,105 @@
|
||||||
import React, {Component} from 'react';
|
import React, {Component} from 'react';
|
||||||
import {connect} from 'react-redux';
|
import {connect} from 'react-redux';
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
|
import {accounts as accountsAction,
|
||||||
import {accounts as accountsAction} from '../actions';
|
initBlockHeader,
|
||||||
|
stopBlockHeader} from '../actions';
|
||||||
import Accounts from '../components/Accounts';
|
import Accounts from '../components/Accounts';
|
||||||
import DataWrapper from "../components/DataWrapper";
|
|
||||||
import {getAccounts} from "../reducers/selectors";
|
import {getAccounts} from "../reducers/selectors";
|
||||||
import PageHead from "../components/PageHead";
|
import PageHead from "../components/PageHead";
|
||||||
|
|
||||||
|
const MAX_ACCOUNTS = 10;
|
||||||
|
|
||||||
class AccountsContainer extends Component {
|
class AccountsContainer extends Component {
|
||||||
|
constructor(props) {
|
||||||
|
super(props);
|
||||||
|
|
||||||
|
this.numAccountsToDisplay = this.props.numAccountsToDisplay || MAX_ACCOUNTS;
|
||||||
|
this.state = {currentPage: 1};
|
||||||
|
}
|
||||||
|
|
||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
this.props.fetchAccounts();
|
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() {
|
render() {
|
||||||
|
this.resetNums();
|
||||||
return (
|
return (
|
||||||
<React.Fragment>
|
<React.Fragment>
|
||||||
<PageHead title="Accounts" enabled={this.props.overridePageHead} description="Summary view of the accounts configured for Embark" />
|
<PageHead
|
||||||
<DataWrapper shouldRender={this.props.accounts.length > 0} {...this.props} render={({accounts}) => (
|
title="Accounts"
|
||||||
<Accounts accounts={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>
|
</React.Fragment>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function mapStateToProps(state) {
|
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 = {
|
AccountsContainer.propTypes = {
|
||||||
accounts: PropTypes.arrayOf(PropTypes.object),
|
accounts: PropTypes.arrayOf(PropTypes.object),
|
||||||
fetchAccounts: PropTypes.func,
|
fetchAccounts: PropTypes.func,
|
||||||
|
numAccountsToDisplay: PropTypes.number,
|
||||||
|
initBlockHeader: PropTypes.func,
|
||||||
|
stopBlockHeader: PropTypes.func,
|
||||||
error: PropTypes.string,
|
error: PropTypes.string,
|
||||||
loading: PropTypes.bool,
|
loading: PropTypes.bool,
|
||||||
overridePageHead: PropTypes.bool
|
overridePageHead: PropTypes.bool
|
||||||
|
@ -40,6 +108,8 @@ AccountsContainer.propTypes = {
|
||||||
export default connect(
|
export default connect(
|
||||||
mapStateToProps,
|
mapStateToProps,
|
||||||
{
|
{
|
||||||
fetchAccounts: accountsAction.request
|
fetchAccounts: accountsAction.request,
|
||||||
|
initBlockHeader,
|
||||||
|
stopBlockHeader
|
||||||
},
|
},
|
||||||
)(AccountsContainer);
|
)(AccountsContainer);
|
||||||
|
|
|
@ -41,6 +41,9 @@ const entitiesDefaultState = {
|
||||||
};
|
};
|
||||||
|
|
||||||
const sorter = {
|
const sorter = {
|
||||||
|
accounts: function(a, b) {
|
||||||
|
return a.index - b.index;
|
||||||
|
},
|
||||||
blocks: function(a, b) {
|
blocks: function(a, b) {
|
||||||
return b.number - a.number;
|
return b.number - a.number;
|
||||||
},
|
},
|
||||||
|
|
|
@ -420,6 +420,7 @@ export function *initBlockHeader() {
|
||||||
channel.close();
|
channel.close();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
yield put({type: actions.ACCOUNTS[actions.REQUEST]});
|
||||||
yield put({type: actions.BLOCKS[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.BLOCKS_FULL[actions.REQUEST], txObjects: true, txReceipts: true});
|
||||||
yield put({type: actions.TRANSACTIONS[actions.REQUEST]});
|
yield put({type: actions.TRANSACTIONS[actions.REQUEST]});
|
||||||
|
|
Loading…
Reference in New Issue