Display contract block creation (#4069)

* Add contract block creation to metadata

* Display mined block for contract on Contracts view

* Better use of Summary for Accounts

* Add sorted by mined block for contracts

* Proper Block Number sort // display in contract page

* PR Grumble

* Linting issues
This commit is contained in:
Nicolas Gotchac
2017-01-09 09:38:27 +01:00
committed by Jaco Greeff
parent 71e6e24a1f
commit cf0a20f08b
13 changed files with 161 additions and 99 deletions

View File

@@ -57,7 +57,7 @@ class List extends Component {
}
renderAccounts () {
const { accounts, balances, empty, link, handleAddSearchToken } = this.props;
const { accounts, balances, empty } = this.props;
if (empty) {
return (
@@ -80,20 +80,29 @@ class List extends Component {
return (
<div
className={ styles.item }
key={ address }>
<Summary
link={ link }
account={ account }
balance={ balance }
owners={ owners }
handleAddSearchToken={ handleAddSearchToken }
showCertifications
/>
key={ address }
>
{ this.renderSummary(account, balance, owners) }
</div>
);
});
}
renderSummary (account, balance, owners) {
const { handleAddSearchToken, link } = this.props;
return (
<Summary
account={ account }
balance={ balance }
handleAddSearchToken={ handleAddSearchToken }
link={ link }
owners={ owners }
showCertifications
/>
);
}
getAddresses () {
const filteredAddresses = this.getFilteredAddresses();
return this.sortAddresses(filteredAddresses);
@@ -122,7 +131,15 @@ class List extends Component {
});
}
compareAccounts (accountA, accountB, key) {
compareAccounts (accountA, accountB, key, _reverse = null) {
if (key && key.split(':')[1] === '-1') {
return this.compareAccounts(accountA, accountB, key.split(':')[0], true);
}
if (key === 'timestamp' && _reverse === null) {
return this.compareAccounts(accountA, accountB, key, true);
}
if (key === 'name') {
return accountA.name.localeCompare(accountB.name);
}
@@ -177,7 +194,9 @@ class List extends Component {
return tagsA.localeCompare(tagsB);
}
const reverse = key === 'timestamp' ? -1 : 1;
const reverse = _reverse
? -1
: 1;
const metaA = accountA.meta[key];
const metaB = accountB.meta[key];

View File

@@ -19,6 +19,7 @@ import React, { Component, PropTypes } from 'react';
import { Link } from 'react-router';
import { isEqual } from 'lodash';
import ReactTooltip from 'react-tooltip';
import { FormattedMessage } from 'react-intl';
import { Balance, Container, ContainerTitle, IdentityIcon, IdentityName, Tags, Input } from '~/ui';
import Certifications from '~/ui/Certifications';
@@ -107,14 +108,22 @@ export default class Summary extends Component {
/>
);
const description = this.getDescription(account.meta);
return (
<Container>
<Tags tags={ tags } handleAddSearchToken={ handleAddSearchToken } />
<IdentityIcon
address={ address } />
<ContainerTitle
title={ this.renderLink() }
byline={ addressComponent } />
<div className={ styles.heading }>
<IdentityIcon
address={ address }
/>
<ContainerTitle
byline={ addressComponent }
className={ styles.main }
description={ description }
title={ this.renderLink() }
/>
</div>
{ this.renderOwners() }
{ this.renderBalance() }
@@ -123,6 +132,26 @@ export default class Summary extends Component {
);
}
getDescription (meta = {}) {
const { blockNumber } = meta;
if (!blockNumber) {
return null;
}
const formattedBlockNumber = (new BigNumber(blockNumber)).toFormat();
return (
<FormattedMessage
id='accounts.summary.minedBlock'
defaultMessage='Mined at block #{blockNumber}'
values={ {
blockNumber: formattedBlockNumber
} }
/>
);
}
renderOwners () {
const { owners } = this.props;
const ownersValid = (owners || []).filter((owner) => owner.address && new BigNumber(owner.address).gt(0));

View File

@@ -56,3 +56,12 @@
}
}
}
.heading {
display: flex;
flex-direction: row;
.main {
flex: 1;
}
}

View File

@@ -45,6 +45,11 @@
}
}
.blockNumber {
color: rgba(255, 255, 255, 0.25);
margin-top: 1.5em;
}
.origin {
text-align: left;
padding-left: 32px;

View File

@@ -17,6 +17,9 @@
import React, { Component, PropTypes } from 'react';
import { connect } from 'react-redux';
import { bindActionCreators } from 'redux';
import { FormattedMessage } from 'react-intl';
import BigNumber from 'bignumber.js';
import ActionDelete from 'material-ui/svg-icons/action/delete';
import AvPlayArrow from 'material-ui/svg-icons/av/play-arrow';
import ContentCreate from 'material-ui/svg-icons/content/create';
@@ -136,7 +139,9 @@ class Contract extends Component {
account={ account }
balance={ balance }
isContract
/>
>
{ this.renderBlockNumber(account.meta) }
</Header>
<Queries
accountsInfo={ accountsInfo }
@@ -156,6 +161,28 @@ class Contract extends Component {
);
}
renderBlockNumber (meta = {}) {
const { blockNumber } = meta;
if (!blockNumber) {
return null;
}
const formattedBlockNumber = (new BigNumber(blockNumber)).toFormat();
return (
<div className={ styles.blockNumber }>
<FormattedMessage
id='contract.minedBlock'
defaultMessage='Mined at block #{blockNumber}'
values={ {
blockNumber: formattedBlockNumber
} }
/>
</div>
);
}
renderDetails (contract) {
const { showDetailsDialog } = this.state;

View File

@@ -1,17 +0,0 @@
// Copyright 2015, 2016 Parity Technologies (UK) Ltd.
// This file is part of Parity.
// Parity is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// Parity is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
export default from './summary';

View File

@@ -1,52 +0,0 @@
// Copyright 2015, 2016 Parity Technologies (UK) Ltd.
// This file is part of Parity.
// Parity is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// Parity is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
import React, { Component, PropTypes } from 'react';
import { Link } from 'react-router';
import { Container, ContainerTitle, IdentityIcon, IdentityName } from '~/ui';
export default class Summary extends Component {
static contextTypes = {
api: React.PropTypes.object.isRequired
}
static propTypes = {
contract: PropTypes.object.isRequired,
children: PropTypes.node
}
render () {
const contract = this.props.contract;
if (!contract) {
return null;
}
const viewLink = `/app/${contract.address}`;
return (
<Container>
<IdentityIcon
address={ contract.address } />
<ContainerTitle
title={ <Link to={ viewLink }>{ <IdentityName address={ contract.address } unknown /> }</Link> }
byline={ contract.address } />
{ this.props.children }
</Container>
);
}
}

View File

@@ -45,7 +45,7 @@ class Contracts extends Component {
state = {
addContract: false,
deployContract: false,
sortOrder: 'timestamp',
sortOrder: 'blockNumber',
searchValues: [],
searchTokens: []
}
@@ -92,7 +92,8 @@ class Contracts extends Component {
empty={ !hasContracts }
order={ sortOrder }
orderFallback='name'
handleAddSearchToken={ this.onAddSearchToken } />
handleAddSearchToken={ this.onAddSearchToken }
/>
</Page>
</div>
);
@@ -109,7 +110,8 @@ class Contracts extends Component {
id='sortContracts'
order={ this.state.sortOrder }
metas={ [
{ key: 'timestamp', label: 'date' }
{ key: 'timestamp', label: 'date' },
{ key: 'blockNumber:-1', label: 'mined block' }
] }
showDefault={ false }
onChange={ onChange } />