mirror of https://github.com/embarklabs/embark.git
feat(@cockpit): implement pagination for contracts
Display five contracts per page in the dashboard. Display ten contracts per page in the contracts explorer and deployment page. Sort contracts by name. In the future we can implement an option to sort by block number and index within a block by calculating and including that information as part of the server-side api response (based on a contract's txhash). Remove unnecessary contract filtering in the components since the containers take care of it. Make use of `listenToContracts` / `stopContracts` in DeploymentContainer.
This commit is contained in:
parent
07b2ecc448
commit
d71352b781
|
@ -1,12 +1,13 @@
|
|||
import PropTypes from "prop-types";
|
||||
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 {formatContractForDisplay} from '../utils/presentation';
|
||||
|
||||
import CardTitleIdenticon from './CardTitleIdenticon';
|
||||
|
||||
const Contracts = ({contracts, title = "Contracts"}) => (
|
||||
const Contracts = ({contracts, changePage, currentPage, numberOfPages, title = "Contracts"}) => (
|
||||
<Row>
|
||||
<Col>
|
||||
<Card>
|
||||
|
@ -14,36 +15,37 @@ const Contracts = ({contracts, title = "Contracts"}) => (
|
|||
<h2>{title}</h2>
|
||||
</CardHeader>
|
||||
<CardBody>
|
||||
{
|
||||
contracts
|
||||
.filter(contract => !contract.silent)
|
||||
.map((contract, key) => {
|
||||
const contractDisplay = formatContractForDisplay(contract);
|
||||
if (!contractDisplay) {
|
||||
return '';
|
||||
}
|
||||
{!contracts.length && "No contracts to display"}
|
||||
{contracts
|
||||
.map((contract, key) => {
|
||||
const contractDisplay = formatContractForDisplay(contract);
|
||||
if (!contractDisplay) {
|
||||
return '';
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="explorer-row border-top" key={`contract-${key}`}>
|
||||
<CardTitleIdenticon id={contract.className}>
|
||||
<Link to={`/explorer/contracts/${contract.className}`}>{contract.className}</Link>
|
||||
</CardTitleIdenticon>
|
||||
<Row>
|
||||
<Col>
|
||||
<strong>Address</strong>
|
||||
<div>{contract.address}</div>
|
||||
</Col>
|
||||
<Col>
|
||||
<strong>State</strong>
|
||||
<div className={contractDisplay.stateColor}>
|
||||
{contractDisplay.state}
|
||||
</div>
|
||||
</Col>
|
||||
</Row>
|
||||
</div>
|
||||
)
|
||||
})
|
||||
}
|
||||
return (
|
||||
<div className="explorer-row border-top" key={`contract-${key}`}>
|
||||
<CardTitleIdenticon id={contract.className}>
|
||||
<Link to={`/explorer/contracts/${contract.className}`}>
|
||||
{contract.className}
|
||||
</Link>
|
||||
</CardTitleIdenticon>
|
||||
<Row>
|
||||
<Col>
|
||||
<strong>Address</strong>
|
||||
<div>{contract.address}</div>
|
||||
</Col>
|
||||
<Col>
|
||||
<strong>State</strong>
|
||||
<div className={contractDisplay.stateColor}>
|
||||
{contractDisplay.state}
|
||||
</div>
|
||||
</Col>
|
||||
</Row>
|
||||
</div>
|
||||
)
|
||||
})}
|
||||
{numberOfPages > 1 && <Pagination changePage={changePage} currentPage={currentPage} numberOfPages={numberOfPages}/>}
|
||||
</CardBody>
|
||||
</Card>
|
||||
</Col>
|
||||
|
@ -52,6 +54,9 @@ const Contracts = ({contracts, title = "Contracts"}) => (
|
|||
|
||||
Contracts.propTypes = {
|
||||
contracts: PropTypes.array,
|
||||
changePage: PropTypes.func,
|
||||
currentPage: PropTypes.number,
|
||||
numberOfPages: PropTypes.number,
|
||||
title: PropTypes.string
|
||||
};
|
||||
|
||||
|
|
|
@ -1,19 +1,18 @@
|
|||
import PropTypes from "prop-types";
|
||||
import React from 'react';
|
||||
import FontAwesomeIcon from 'react-fontawesome';
|
||||
import {
|
||||
Row,
|
||||
Col,
|
||||
FormGroup,
|
||||
Input,
|
||||
Label,
|
||||
UncontrolledTooltip,
|
||||
Button,
|
||||
Card,
|
||||
CardHeader,
|
||||
CardTitle,
|
||||
CardBody
|
||||
} from 'reactstrap';
|
||||
import {Row,
|
||||
Col,
|
||||
FormGroup,
|
||||
Input,
|
||||
Label,
|
||||
UncontrolledTooltip,
|
||||
Button,
|
||||
Card,
|
||||
CardHeader,
|
||||
CardTitle,
|
||||
CardBody} from 'reactstrap';
|
||||
import PropTypes from "prop-types";
|
||||
import Pagination from './Pagination';
|
||||
import classNames from 'classnames';
|
||||
import {DEPLOYMENT_PIPELINES} from '../constants';
|
||||
import Description from './Description';
|
||||
|
@ -326,39 +325,49 @@ class ContractsDeployment extends React.Component {
|
|||
}
|
||||
|
||||
render() {
|
||||
const props = this.props;
|
||||
const {changePage, currentPage, numberOfPages} = props;
|
||||
return (
|
||||
<Row>
|
||||
<Col>
|
||||
<ContractsHeader deploymentPipeline={this.props.deploymentPipeline}
|
||||
updateDeploymentPipeline={this.props.updateDeploymentPipeline}/>
|
||||
{this.props.contracts.filter(contract => (contract.code || contract.deploy) && !contract.silent)
|
||||
.sort((a, b) => a.index - b.index).map((contract, index) => {
|
||||
<React.Fragment>
|
||||
<Row>
|
||||
<Col>
|
||||
<ContractsHeader
|
||||
deploymentPipeline={props.deploymentPipeline}
|
||||
updateDeploymentPipeline={props.updateDeploymentPipeline} />
|
||||
{!props.contracts.length && "No contracts to display"}
|
||||
{props.contracts
|
||||
.map((contract, index) => {
|
||||
contract.deployIndex = index;
|
||||
return (<Contract key={contract.deployIndex}
|
||||
contract={contract}
|
||||
toggleContractOverview={(contract) => this.toggleContractOverview(contract)}
|
||||
{...this.props} />);
|
||||
}
|
||||
)}
|
||||
</Col>
|
||||
{this.isContractOverviewOpen() &&
|
||||
<Col xs={6} md={3}>
|
||||
<Card>
|
||||
<CardBody>
|
||||
<h2>{this.state.currentContractOverview.className} - Overview</h2>
|
||||
<ContractOverviewContainer contract={this.state.currentContractOverview} />
|
||||
</CardBody>
|
||||
</Card>
|
||||
return (
|
||||
<Contract key={contract.deployIndex}
|
||||
contract={contract}
|
||||
toggleContractOverview={(contract) => this.toggleContractOverview(contract)}
|
||||
{...props} />
|
||||
);
|
||||
})}
|
||||
</Col>
|
||||
}
|
||||
</Row>
|
||||
{this.isContractOverviewOpen() &&
|
||||
<Col xs={6} md={3}>
|
||||
<Card>
|
||||
<CardBody>
|
||||
<h2>{this.state.currentContractOverview.className} - Overview</h2>
|
||||
<ContractOverviewContainer contract={this.state.currentContractOverview} />
|
||||
</CardBody>
|
||||
</Card>
|
||||
</Col>
|
||||
}
|
||||
</Row>
|
||||
{numberOfPages > 1 && <Pagination changePage={changePage} currentPage={currentPage} numberOfPages={numberOfPages}/>}
|
||||
</React.Fragment>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
ContractsDeployment.propTypes = {
|
||||
contracts: PropTypes.array,
|
||||
changePage: PropTypes.func,
|
||||
currentPage: PropTypes.number,
|
||||
numberOfPages: PropTypes.number,
|
||||
deploymentPipeline: PropTypes.oneOfType([
|
||||
PropTypes.object,
|
||||
PropTypes.string
|
||||
|
@ -373,4 +382,3 @@ ContractsDeployment.propTypes = {
|
|||
};
|
||||
|
||||
export default ContractsDeployment;
|
||||
|
||||
|
|
|
@ -1,42 +1,49 @@
|
|||
import PropTypes from "prop-types";
|
||||
import React from 'react';
|
||||
import {Table} from "reactstrap";
|
||||
import {Link} from 'react-router-dom';
|
||||
import PropTypes from "prop-types";
|
||||
import Pagination from './Pagination';
|
||||
import {formatContractForDisplay} from '../utils/presentation';
|
||||
|
||||
const ContractsList = ({contracts}) => (
|
||||
<Table hover responsive className="table-outline mb-0 d-none d-sm-table text-nowrap">
|
||||
<thead className="thead-light">
|
||||
<tr>
|
||||
<th>Name</th>
|
||||
<th>Address</th>
|
||||
<th>State</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{
|
||||
contracts
|
||||
.filter(contract => !contract.silent)
|
||||
.map((contract) => {
|
||||
const contractDisplay = formatContractForDisplay(contract);
|
||||
if (!contractDisplay) {
|
||||
return null;
|
||||
}
|
||||
return (
|
||||
<tr key={contract.className} className={contractDisplay.stateColor}>
|
||||
<td><Link to={`/explorer/contracts/${contract.className}`}>{contract.className}</Link></td>
|
||||
<td>{contractDisplay.address}</td>
|
||||
<td>{contractDisplay.state}</td>
|
||||
</tr>
|
||||
);
|
||||
})
|
||||
}
|
||||
</tbody>
|
||||
</Table>
|
||||
const ContractsList = ({contracts, changePage, currentPage, numberOfPages}) => (
|
||||
<React.Fragment>
|
||||
{!contracts.length && "No contracts to display"}
|
||||
<Table hover responsive className="table-outline mb-0 d-none d-sm-table text-nowrap">
|
||||
<thead className="thead-light">
|
||||
<tr>
|
||||
<th>Name</th>
|
||||
<th>Address</th>
|
||||
<th>State</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{
|
||||
contracts
|
||||
.map((contract) => {
|
||||
const contractDisplay = formatContractForDisplay(contract);
|
||||
if (!contractDisplay) {
|
||||
return null;
|
||||
}
|
||||
return (
|
||||
<tr key={contract.className} className={contractDisplay.stateColor}>
|
||||
<td><Link to={`/explorer/contracts/${contract.className}`}>{contract.className}</Link></td>
|
||||
<td>{contractDisplay.address}</td>
|
||||
<td>{contractDisplay.state}</td>
|
||||
</tr>
|
||||
);
|
||||
})
|
||||
}
|
||||
</tbody>
|
||||
</Table>
|
||||
{numberOfPages > 1 && <Pagination changePage={changePage} currentPage={currentPage} numberOfPages={numberOfPages}/>}
|
||||
</React.Fragment>
|
||||
);
|
||||
|
||||
ContractsList.propTypes = {
|
||||
contracts: PropTypes.array,
|
||||
changePage: PropTypes.func,
|
||||
currentPage: PropTypes.number,
|
||||
numberOfPages: PropTypes.number
|
||||
};
|
||||
|
||||
export default ContractsList;
|
||||
|
|
|
@ -1,19 +1,24 @@
|
|||
import React, {Component} from 'react';
|
||||
import {connect} from 'react-redux';
|
||||
import PropTypes from 'prop-types';
|
||||
import {
|
||||
listenToContracts as listenToContractsAction,
|
||||
stopContracts as stopContractsAction,
|
||||
contracts as contractsAction
|
||||
} from "../actions";
|
||||
|
||||
import {contracts as contractsAction,
|
||||
listenToContracts,
|
||||
stopContracts} from "../actions";
|
||||
import Contracts from '../components/Contracts';
|
||||
import ContractsList from '../components/ContractsList';
|
||||
import DataWrapper from "../components/DataWrapper";
|
||||
import PageHead from "../components/PageHead";
|
||||
import {getContracts} from "../reducers/selectors";
|
||||
import PageHead from "../components/PageHead";
|
||||
|
||||
const MAX_CONTRACTS = 10;
|
||||
|
||||
class ContractsContainer extends Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
|
||||
this.numContractsToDisplay = this.props.numContractsToDisplay || MAX_CONTRACTS;
|
||||
this.state = {currentPage: 1};
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
this.props.fetchContracts();
|
||||
this.props.listenToContracts();
|
||||
|
@ -23,14 +28,72 @@ class ContractsContainer extends Component {
|
|||
this.props.stopContracts();
|
||||
}
|
||||
|
||||
get numberOfContracts() {
|
||||
if (this._numberOfContracts === undefined) {
|
||||
this._numberOfContracts = this.props.contracts
|
||||
.filter(contract => !contract.silent)
|
||||
.length;
|
||||
}
|
||||
return this._numberOfContracts;
|
||||
}
|
||||
|
||||
get numberOfPages() {
|
||||
if (this._numberOfPages === undefined) {
|
||||
this._numberOfPages = Math.ceil(
|
||||
this.numberOfContracts / this.numContractsToDisplay
|
||||
);
|
||||
}
|
||||
return this._numberOfPages;
|
||||
}
|
||||
|
||||
resetNums() {
|
||||
this._numberOfContracts = 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.fetchContracts();
|
||||
}
|
||||
|
||||
get currentContracts() {
|
||||
let offset = 0;
|
||||
return this.props.contracts
|
||||
.filter((contract, arrIndex) => {
|
||||
if (contract.silent) {
|
||||
offset++;
|
||||
return false
|
||||
};
|
||||
const index = (
|
||||
(arrIndex + 1 - offset) -
|
||||
(this.numContractsToDisplay * (this.state.currentPage - 1))
|
||||
);
|
||||
return index <= this.numContractsToDisplay && index > 0;
|
||||
});
|
||||
}
|
||||
|
||||
render() {
|
||||
this.resetNums();
|
||||
let ContractsComp;
|
||||
if (this.props.mode === "detail") {
|
||||
ContractsComp = Contracts
|
||||
} else if (this.props.mode === "list") {
|
||||
ContractsComp = ContractsList
|
||||
}
|
||||
return (
|
||||
<React.Fragment>
|
||||
{this.props.updatePageHeader && <PageHead title="Contracts" description="Summary of all deployed contracts" />}
|
||||
<DataWrapper shouldRender={this.props.contracts.length > 0} {...this.props} render={({contracts}) => {
|
||||
if (this.props.mode === "list") return <ContractsList contracts={contracts} />;
|
||||
if (this.props.mode === "detail") return <Contracts contracts={contracts} />;
|
||||
}} />
|
||||
{this.props.updatePageHeader &&
|
||||
<PageHead title="Contracts"
|
||||
description="Summary of all deployed contracts" />}
|
||||
<ContractsComp contracts={this.currentContracts}
|
||||
numberOfPages={this.numberOfPages}
|
||||
changePage={(newPage) => this.changePage(newPage)}
|
||||
currentPage={this.state.currentPage} />
|
||||
</React.Fragment>
|
||||
);
|
||||
}
|
||||
|
@ -40,15 +103,17 @@ function mapStateToProps(state) {
|
|||
return {
|
||||
contracts: getContracts(state),
|
||||
error: state.errorMessage,
|
||||
loading: state.loading};
|
||||
loading: state.loading
|
||||
};
|
||||
}
|
||||
|
||||
ContractsContainer.propTypes = {
|
||||
contracts: PropTypes.array,
|
||||
fetchContracts: PropTypes.func,
|
||||
numContractsToDisplay: PropTypes.number,
|
||||
listenToContracts: PropTypes.func,
|
||||
stopContracts: PropTypes.func,
|
||||
contracts: PropTypes.array,
|
||||
fiddleContracts: PropTypes.array,
|
||||
fetchContracts: PropTypes.func,
|
||||
mode: PropTypes.string,
|
||||
updatePageHeader: PropTypes.bool
|
||||
};
|
||||
|
@ -59,9 +124,9 @@ ContractsContainer.defaultProps = {
|
|||
}
|
||||
|
||||
export default connect(
|
||||
mapStateToProps,{
|
||||
listenToContracts: listenToContractsAction,
|
||||
stopContracts: stopContractsAction,
|
||||
fetchContracts: contractsAction.request
|
||||
mapStateToProps, {
|
||||
fetchContracts: contractsAction.request,
|
||||
listenToContracts,
|
||||
stopContracts,
|
||||
}
|
||||
)(ContractsContainer);
|
||||
|
|
|
@ -1,44 +1,107 @@
|
|||
import React, {Component} from 'react';
|
||||
import {connect} from 'react-redux';
|
||||
import PropTypes from 'prop-types';
|
||||
import {
|
||||
contracts as contractsAction,
|
||||
web3Deploy as web3DeployAction,
|
||||
web3EstimateGas as web3EstimateGasAction,
|
||||
updateDeploymentPipeline} from "../actions";
|
||||
|
||||
import {contracts as contractsAction,
|
||||
listenToContracts,
|
||||
stopContracts,
|
||||
web3Deploy as web3DeployAction,
|
||||
web3EstimateGas as web3EstimateGasAction,
|
||||
updateDeploymentPipeline} from "../actions";
|
||||
import ContractsDeployment from '../components/ContractsDeployment';
|
||||
import DataWrapper from "../components/DataWrapper";
|
||||
import {getContracts,
|
||||
getDeploymentPipeline,
|
||||
getWeb3,
|
||||
getWeb3GasEstimates,
|
||||
getWeb3Deployments,
|
||||
getWeb3ContractsDeployed} from "../reducers/selectors";
|
||||
import PageHead from '../components/PageHead';
|
||||
import {
|
||||
getContracts,
|
||||
getDeploymentPipeline,
|
||||
getWeb3,
|
||||
getWeb3GasEstimates,
|
||||
getWeb3Deployments,
|
||||
getWeb3ContractsDeployed
|
||||
} from "../reducers/selectors";
|
||||
|
||||
const MAX_CONTRACTS = 10;
|
||||
|
||||
class DeploymentContainer extends Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
|
||||
this.numContractsToDisplay = this.props.numContractsToDisplay || MAX_CONTRACTS;
|
||||
this.state = {currentPage: 1};
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
this.props.fetchContracts();
|
||||
this.props.listenToContracts();
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
this.props.stopContracts();
|
||||
}
|
||||
|
||||
get numberOfContracts() {
|
||||
if (this._numberOfContracts === undefined) {
|
||||
this._numberOfContracts = this.props.contracts
|
||||
.filter(contract => (contract.code || contract.deploy) && !contract.silent)
|
||||
.length;
|
||||
}
|
||||
return this._numberOfContracts;
|
||||
}
|
||||
|
||||
get numberOfPages() {
|
||||
if (this._numberOfPages === undefined) {
|
||||
this._numberOfPages = Math.ceil(
|
||||
this.numberOfContracts / this.numContractsToDisplay
|
||||
);
|
||||
}
|
||||
return this._numberOfPages;
|
||||
}
|
||||
|
||||
resetNums() {
|
||||
this._numberOfContracts = 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.fetchContracts();
|
||||
}
|
||||
|
||||
get currentContracts() {
|
||||
let offset = 0;
|
||||
return this.props.contracts
|
||||
.filter((contract, arrIndex) => {
|
||||
if (!(contract.code || contract.deploy) || contract.silent) {
|
||||
offset++;
|
||||
return false
|
||||
};
|
||||
const index = (
|
||||
(arrIndex + 1 - offset) -
|
||||
(this.numContractsToDisplay * (this.state.currentPage - 1))
|
||||
);
|
||||
return index <= this.numContractsToDisplay && index > 0;
|
||||
});
|
||||
}
|
||||
|
||||
render() {
|
||||
this.resetNums();
|
||||
return (
|
||||
<React.Fragment>
|
||||
<PageHead title="Deployment" description="Deploy your contracts using Embark or a web3-enabled browser such as Mist or MetaMask." />
|
||||
<DataWrapper shouldRender={this.props.contracts.length > 0} {...this.props} render={() => (
|
||||
<ContractsDeployment contracts={this.props.contracts}
|
||||
deploymentPipeline={this.props.deploymentPipeline}
|
||||
web3={this.props.web3}
|
||||
web3Deploy={this.props.web3Deploy}
|
||||
web3EstimateGas={this.props.web3EstimateGas}
|
||||
web3Deployments={this.props.web3Deployments}
|
||||
web3GasEstimates={this.props.web3GasEstimates}
|
||||
web3ContractsDeployed={this.props.web3ContractsDeployed}
|
||||
updateDeploymentPipeline={this.props.updateDeploymentPipeline} />
|
||||
)} />
|
||||
<PageHead title="Deployment"
|
||||
description="Deploy your contracts using Embark or a web3-enabled browser such as Mist or MetaMask." />
|
||||
<ContractsDeployment contracts={this.currentContracts}
|
||||
deploymentPipeline={this.props.deploymentPipeline}
|
||||
web3={this.props.web3}
|
||||
web3Deploy={this.props.web3Deploy}
|
||||
web3EstimateGas={this.props.web3EstimateGas}
|
||||
web3Deployments={this.props.web3Deployments}
|
||||
web3GasEstimates={this.props.web3GasEstimates}
|
||||
web3ContractsDeployed={this.props.web3ContractsDeployed}
|
||||
updateDeploymentPipeline={this.props.updateDeploymentPipeline}
|
||||
numberOfPages={this.numberOfPages}
|
||||
changePage={(newPage) => this.changePage(newPage)}
|
||||
currentPage={this.state.currentPage} />
|
||||
</React.Fragment>
|
||||
);
|
||||
}
|
||||
|
@ -59,11 +122,14 @@ function mapStateToProps(state) {
|
|||
|
||||
DeploymentContainer.propTypes = {
|
||||
contracts: PropTypes.array,
|
||||
fetchContracts: PropTypes.func,
|
||||
numContractsToDisplay: PropTypes.number,
|
||||
listenToContracts: PropTypes.func,
|
||||
stopContracts: PropTypes.func,
|
||||
deploymentPipeline: PropTypes.oneOfType([
|
||||
PropTypes.object,
|
||||
PropTypes.string
|
||||
]),
|
||||
fetchContracts: PropTypes.func,
|
||||
updateDeploymentPipeline: PropTypes.func,
|
||||
web3: PropTypes.object,
|
||||
web3Deploy: PropTypes.func,
|
||||
|
@ -75,6 +141,8 @@ DeploymentContainer.propTypes = {
|
|||
export default connect(
|
||||
mapStateToProps, {
|
||||
fetchContracts: contractsAction.request,
|
||||
listenToContracts,
|
||||
stopContracts,
|
||||
web3Deploy: web3DeployAction.request,
|
||||
web3EstimateGas: web3EstimateGasAction.request,
|
||||
updateDeploymentPipeline: updateDeploymentPipeline
|
||||
|
|
|
@ -76,7 +76,7 @@ class HomeContainer extends Component {
|
|||
<CardBody>
|
||||
<CardTitle>Deployed Contracts</CardTitle>
|
||||
<div style={{marginBottom: '1.5rem', overflow: 'auto'}}>
|
||||
<ContractsContainer contracts={contracts} mode="list" updatePageHeader={false} />
|
||||
<ContractsContainer contracts={contracts} mode="list" numContractsToDisplay={5} updatePageHeader={false} />
|
||||
</div>
|
||||
</CardBody>
|
||||
</Card>
|
||||
|
|
|
@ -50,6 +50,14 @@ const sorter = {
|
|||
blocksFull: function(a, b) {
|
||||
return b.number - a.number;
|
||||
},
|
||||
contracts: function (a, b) {
|
||||
const aName = a.className || '';
|
||||
const bName = b.className || '';
|
||||
if (!(aName || bName)) return 0;
|
||||
if (!aName) return 1;
|
||||
if (!bName) return -1;
|
||||
return aName < bName ? -1 : aName > bName ? 1 : 0
|
||||
},
|
||||
transactions: function(a, b) {
|
||||
return ((BN_FACTOR * b.blockNumber) + b.transactionIndex) - ((BN_FACTOR * a.blockNumber) + a.transactionIndex);
|
||||
},
|
||||
|
|
Loading…
Reference in New Issue