From cf0a20f08baf534d139fd84aa5b7c09faaae44b7 Mon Sep 17 00:00:00 2001 From: Nicolas Gotchac Date: Mon, 9 Jan 2017 09:38:27 +0100 Subject: [PATCH] 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 --- js/src/api/contract/contract.js | 5 ++ .../modals/DeployContract/deployContract.js | 14 +++-- js/src/ui/Balance/balance.css | 2 +- js/src/ui/Container/Title/title.css | 7 ++- js/src/ui/Container/Title/title.js | 30 +++++++++-- js/src/views/Accounts/List/list.js | 43 ++++++++++----- js/src/views/Accounts/Summary/summary.js | 39 ++++++++++++-- js/src/views/Accounts/accounts.css | 9 ++++ js/src/views/Contract/contract.css | 5 ++ js/src/views/Contract/contract.js | 29 ++++++++++- js/src/views/Contracts/Summary/index.js | 17 ------ js/src/views/Contracts/Summary/summary.js | 52 ------------------- js/src/views/Contracts/contracts.js | 8 +-- 13 files changed, 161 insertions(+), 99 deletions(-) delete mode 100644 js/src/views/Contracts/Summary/index.js delete mode 100644 js/src/views/Contracts/Summary/summary.js diff --git a/js/src/api/contract/contract.js b/js/src/api/contract/contract.js index 70853749d..9c3b02b72 100644 --- a/js/src/api/contract/contract.js +++ b/js/src/api/contract/contract.js @@ -75,6 +75,10 @@ export default class Contract { return this._functions; } + get receipt () { + return this._receipt; + } + get instance () { this._instance.address = this._address; return this._instance; @@ -139,6 +143,7 @@ export default class Contract { } setState({ state: 'hasReceipt', receipt }); + this._receipt = receipt; this._address = receipt.contractAddress; return this._address; }); diff --git a/js/src/modals/DeployContract/deployContract.js b/js/src/modals/DeployContract/deployContract.js index 6b09986ad..1bda0dddf 100644 --- a/js/src/modals/DeployContract/deployContract.js +++ b/js/src/modals/DeployContract/deployContract.js @@ -455,10 +455,15 @@ class DeployContract extends Component { this.setState({ step: 'DEPLOYMENT' }); - api - .newContract(abiParsed) + const contract = api.newContract(abiParsed); + + contract .deploy(options, params, this.onDeploymentState) .then((address) => { + const blockNumber = contract._receipt + ? contract.receipt.blockNumber.toNumber() + : null; + return Promise.all([ api.parity.setAccountName(address, name), api.parity.setAccountMeta(address, { @@ -466,8 +471,9 @@ class DeployContract extends Component { contract: true, timestamp: Date.now(), deleted: false, - source, - description + blockNumber, + description, + source }) ]) .then(() => { diff --git a/js/src/ui/Balance/balance.css b/js/src/ui/Balance/balance.css index a27904832..9fe7cc8ac 100644 --- a/js/src/ui/Balance/balance.css +++ b/js/src/ui/Balance/balance.css @@ -23,7 +23,7 @@ .empty { line-height: 24px; - margin: 0.75em 0.5em 0 0; + margin: 0 0.5em 0 0; opacity: 0.25; } diff --git a/js/src/ui/Container/Title/title.css b/js/src/ui/Container/Title/title.css index 341c25a7f..9b636c034 100644 --- a/js/src/ui/Container/Title/title.css +++ b/js/src/ui/Container/Title/title.css @@ -14,7 +14,7 @@ /* You should have received a copy of the GNU General Public License /* along with Parity. If not, see . */ -.byline { +.byline, .description { overflow: hidden; position: relative; line-height: 1.2em; @@ -31,6 +31,11 @@ } } +.description { + font-size: 0.75em; + margin: 0.5em 0 0; +} + .title { text-transform: uppercase; margin: 0; diff --git a/js/src/ui/Container/Title/title.js b/js/src/ui/Container/Title/title.js index de25b818c..ccd3f9d0e 100644 --- a/js/src/ui/Container/Title/title.js +++ b/js/src/ui/Container/Title/title.js @@ -22,13 +22,14 @@ import styles from './title.css'; export default class Title extends Component { static propTypes = { + byline: nodeOrStringProptype(), className: PropTypes.string, - title: nodeOrStringProptype(), - byline: nodeOrStringProptype() + description: nodeOrStringProptype(), + title: nodeOrStringProptype() } render () { - const { className, title, byline } = this.props; + const { byline, className, title } = this.props; const byLine = typeof byline === 'string' ? ( @@ -46,6 +47,29 @@ export default class Title extends Component {
{ byLine }
+ { this.renderDescription() } + + ); + } + + renderDescription () { + const { description } = this.props; + + if (!description) { + return null; + } + + const desc = typeof description === 'string' + ? ( + + { description } + + ) + : description; + + return ( +
+ { desc }
); } diff --git a/js/src/views/Accounts/List/list.js b/js/src/views/Accounts/List/list.js index 19245f4a2..ce7a2ae99 100644 --- a/js/src/views/Accounts/List/list.js +++ b/js/src/views/Accounts/List/list.js @@ -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 (
- + key={ address } + > + { this.renderSummary(account, balance, owners) }
); }); } + renderSummary (account, balance, owners) { + const { handleAddSearchToken, link } = this.props; + + return ( + + ); + } + 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]; diff --git a/js/src/views/Accounts/Summary/summary.js b/js/src/views/Accounts/Summary/summary.js index 8658077a5..20924dc4a 100644 --- a/js/src/views/Accounts/Summary/summary.js +++ b/js/src/views/Accounts/Summary/summary.js @@ -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 ( - - +
+ + +
{ 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 ( + + ); + } + renderOwners () { const { owners } = this.props; const ownersValid = (owners || []).filter((owner) => owner.address && new BigNumber(owner.address).gt(0)); diff --git a/js/src/views/Accounts/accounts.css b/js/src/views/Accounts/accounts.css index 2a7cdcec9..25dfdcab4 100644 --- a/js/src/views/Accounts/accounts.css +++ b/js/src/views/Accounts/accounts.css @@ -56,3 +56,12 @@ } } } + +.heading { + display: flex; + flex-direction: row; + + .main { + flex: 1; + } +} diff --git a/js/src/views/Contract/contract.css b/js/src/views/Contract/contract.css index e3fa38f6c..924818ebd 100644 --- a/js/src/views/Contract/contract.css +++ b/js/src/views/Contract/contract.css @@ -45,6 +45,11 @@ } } +.blockNumber { + color: rgba(255, 255, 255, 0.25); + margin-top: 1.5em; +} + .origin { text-align: left; padding-left: 32px; diff --git a/js/src/views/Contract/contract.js b/js/src/views/Contract/contract.js index d06c22b92..fc299f7cb 100644 --- a/js/src/views/Contract/contract.js +++ b/js/src/views/Contract/contract.js @@ -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) } + + + + ); + } + renderDetails (contract) { const { showDetailsDialog } = this.state; diff --git a/js/src/views/Contracts/Summary/index.js b/js/src/views/Contracts/Summary/index.js deleted file mode 100644 index 980ecff9a..000000000 --- a/js/src/views/Contracts/Summary/index.js +++ /dev/null @@ -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 . - -export default from './summary'; diff --git a/js/src/views/Contracts/Summary/summary.js b/js/src/views/Contracts/Summary/summary.js deleted file mode 100644 index 36e88f039..000000000 --- a/js/src/views/Contracts/Summary/summary.js +++ /dev/null @@ -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 . - -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 ( - - - { } } - byline={ contract.address } /> - { this.props.children } - - ); - } -} diff --git a/js/src/views/Contracts/contracts.js b/js/src/views/Contracts/contracts.js index cc292275a..532c2ffb4 100644 --- a/js/src/views/Contracts/contracts.js +++ b/js/src/views/Contracts/contracts.js @@ -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 } + /> ); @@ -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 } />