Merge pull request #3671 from ethcore/jg-signer-decoding

Signer method parameter decoding & destination info
This commit is contained in:
Gav Wood 2016-12-02 22:13:35 -08:00 committed by GitHub
commit be7401c8bf
20 changed files with 66 additions and 737 deletions

View File

@ -44,9 +44,9 @@
} }
.gasDetails { .gasDetails {
padding-top: 1em; padding-top: 0.75em;
font-size: 0.75em; font-size: 0.75em;
line-height: 2em; line-height: 1.5em;
opacity: 0.5; opacity: 0.5;
} }

View File

@ -142,16 +142,17 @@ class MethodDecoding extends Component {
getAscii () { getAscii () {
const { api } = this.context; const { api } = this.context;
const { transaction } = this.props; const { transaction } = this.props;
const ascii = api.util.hex2Ascii(transaction.input || transaction.data);
const ascii = api.util.hex2Ascii(transaction.input);
return { value: ascii, valid: ASCII_INPUT.test(ascii) }; return { value: ascii, valid: ASCII_INPUT.test(ascii) };
} }
renderInputValue () { renderInputValue () {
const { transaction } = this.props; const { transaction } = this.props;
const { expandInput, inputType } = this.state; const { expandInput, inputType } = this.state;
const input = transaction.input || transaction.data;
if (!/^(0x)?([0]*[1-9a-f]+[0]*)+$/.test(transaction.input)) { if (!/^(0x)?([0]*[1-9a-f]+[0]*)+$/.test(input)) {
return null; return null;
} }
@ -162,7 +163,7 @@ class MethodDecoding extends Component {
const text = type === 'ascii' const text = type === 'ascii'
? ascii.value ? ascii.value
: transaction.input; : input;
const expandable = text.length > 50; const expandable = text.length > 50;
const textToShow = expandInput || !expandable const textToShow = expandInput || !expandable
@ -447,11 +448,12 @@ class MethodDecoding extends Component {
const isReceived = transaction.to === address; const isReceived = transaction.to === address;
const contractAddress = isReceived ? transaction.from : transaction.to; const contractAddress = isReceived ? transaction.from : transaction.to;
const input = transaction.input || transaction.data;
const token = (tokens || {})[contractAddress]; const token = (tokens || {})[contractAddress];
this.setState({ token, isReceived, contractAddress }); this.setState({ token, isReceived, contractAddress });
if (!transaction.input || transaction.input === '0x') { if (!input || input === '0x') {
return; return;
} }
@ -470,7 +472,7 @@ class MethodDecoding extends Component {
return; return;
} }
const { signature, paramdata } = api.util.decodeCallData(transaction.input); const { signature, paramdata } = api.util.decodeCallData(input);
this.setState({ methodSignature: signature, methodParams: paramdata }); this.setState({ methodSignature: signature, methodParams: paramdata });
if (!signature || signature === CONTRACT_CREATE || transaction.creates) { if (!signature || signature === CONTRACT_CREATE || transaction.creates) {

View File

@ -19,6 +19,6 @@ $pendingHeight: 190px;
$finishedHeight: 120px; $finishedHeight: 120px;
$embedWidth: 920px; $embedWidth: 920px;
$statusWidth: 260px; $statusWidth: 270px;
$accountPadding: 75px; $accountPadding: 75px;

View File

@ -1,17 +0,0 @@
// Copyright 2015, 2016 Ethcore (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 './requestFinished';

View File

@ -1,87 +0,0 @@
// Copyright 2015, 2016 Ethcore (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 TransactionFinished from '../TransactionFinished';
import SignRequest from '../SignRequest';
export default class RequestFinished extends Component {
static propTypes = {
id: PropTypes.object.isRequired,
result: PropTypes.any.isRequired,
date: PropTypes.instanceOf(Date).isRequired,
payload: PropTypes.oneOfType([
PropTypes.shape({ signTransaction: PropTypes.object.isRequired }),
PropTypes.shape({ sendTransaction: PropTypes.object.isRequired }),
PropTypes.shape({ sign: PropTypes.object.isRequired })
]).isRequired,
msg: PropTypes.string,
status: PropTypes.string,
error: PropTypes.string,
className: PropTypes.string,
isTest: PropTypes.bool.isRequired,
store: PropTypes.object.isRequired
}
render () {
const { payload, id, result, msg, status, error, date, className, isTest, store } = this.props;
if (payload.sign) {
const { sign } = payload;
return (
<SignRequest
className={ className }
isFinished
id={ id }
address={ sign.address }
hash={ sign.hash }
msg={ msg }
status={ status }
error={ error }
isTest={ isTest }
store={ store }
/>
);
}
const transaction = payload.sendTransaction || payload.signTransaction;
if (transaction) {
return (
<TransactionFinished
className={ className }
txHash={ result }
id={ id }
gasPrice={ transaction.gasPrice }
gas={ transaction.gas }
from={ transaction.from }
to={ transaction.to }
value={ transaction.value }
msg={ msg }
date={ date }
status={ status }
error={ error }
isTest={ isTest }
store={ store }
/>
);
}
// Unknown payload
return null;
}
}

View File

@ -74,12 +74,7 @@ export default class RequestPending extends Component {
onReject={ onReject } onReject={ onReject }
isSending={ isSending } isSending={ isSending }
id={ id } id={ id }
gasPrice={ transaction.gasPrice } transaction={ transaction }
gas={ transaction.gas }
data={ transaction.data }
from={ transaction.from }
to={ transaction.to }
value={ transaction.value }
date={ date } date={ date }
isTest={ isTest } isTest={ isTest }
store={ store } store={ store }

View File

@ -1,54 +0,0 @@
/* Copyright 2015, 2016 Ethcore (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 '../../_layout.css';
.container {
display: flex;
padding: 1.5em 0 1em;
& > * {
vertical-align: middle;
min-height: $finishedHeight;
}
}
.statusContainer {
box-sizing: border-box;
float: right;
padding: 0 1em;
flex: 0 0 $statusWidth;
}
.transactionDetails {
width: 100%;
box-sizing: border-box;
}
.isConfirmed {
color: green;
}
.isRejected {
opacity: 0.5;
padding-top: 2em;
}
.txHash {
display: block;
word-break: break-all;
}

View File

@ -1,120 +0,0 @@
// Copyright 2015, 2016 Ethcore (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 { observer } from 'mobx-react';
import { TxHash } from '../../../../ui';
import TransactionMainDetails from '../TransactionMainDetails';
import TxHashLink from '../TxHashLink';
import TransactionSecondaryDetails from '../TransactionSecondaryDetails';
import styles from './TransactionFinished.css';
import * as tUtil from '../util/transaction';
import { capitalize } from '../util/util';
@observer
export default class TransactionFinished extends Component {
static propTypes = {
id: PropTypes.object.isRequired,
from: PropTypes.string.isRequired,
value: PropTypes.object.isRequired, // wei hex
gasPrice: PropTypes.object.isRequired, // wei hex
gas: PropTypes.object.isRequired, // hex
status: PropTypes.string.isRequired, // rejected, confirmed
date: PropTypes.instanceOf(Date).isRequired,
to: PropTypes.string, // undefined if it's a contract
txHash: PropTypes.string, // undefined if transacation is rejected
className: PropTypes.string,
data: PropTypes.string,
isTest: PropTypes.bool.isRequired,
store: PropTypes.object.isRequired
};
componentWillMount () {
const { from, to, gas, gasPrice, value, store } = this.props;
const fee = tUtil.getFee(gas, gasPrice); // BigNumber object
const totalValue = tUtil.getTotalValue(fee, value);
this.setState({ totalValue });
store.fetchBalances([from, to]);
}
render () {
const { className, date, id, from, to, store } = this.props;
const fromBalance = store.balances[from];
const toBalance = store.balances[to];
return (
<div className={ `${styles.container} ${className || ''}` }>
<TransactionMainDetails
{ ...this.props }
{ ...this.state }
fromBalance={ fromBalance }
toBalance={ toBalance }
className={ styles.transactionDetails }
>
<TransactionSecondaryDetails
id={ id }
date={ date }
/>
</TransactionMainDetails>
<div className={ styles.statusContainer }>
{ this.renderStatus() }
</div>
</div>
);
}
renderStatus () {
const { status, txHash } = this.props;
if (status !== 'confirmed') {
return (
<div>
<span className={ styles.isRejected }>{ capitalize(status) }</span>
</div>
);
}
return (
<TxHash
summary
hash={ txHash } />
);
}
renderTxHash () {
const { txHash, isTest } = this.props;
if (!txHash) {
return;
}
return (
<div>
Transaction hash:
<TxHashLink
isTest={ isTest }
txHash={ txHash }
className={ styles.txHash } />
</div>
);
}
}

View File

@ -1,17 +0,0 @@
// Copyright 2015, 2016 Ethcore (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 './TransactionFinished';

View File

@ -30,27 +30,26 @@
text-align: center; text-align: center;
} }
.from, .to { .from {
width: 50%; width: 40%;
vertical-align: top;
img {
display: inline-block;
width: 50px;
height: 50px;
margin: 5px;
}
span {
display: block;
}
} }
.from .account { .method {
padding-right: $accountPadding; width: 60%;
} vertical-align: top;
line-height: 1em;
.to .account {
padding-left: $accountPadding;
}
.from img, .to img {
display: inline-block;
width: 50px;
height: 50px;
margin: 5px;
}
.from span, .to span {
display: block;
} }
.tx { .tx {

View File

@ -16,9 +16,10 @@
import React, { Component, PropTypes } from 'react'; import React, { Component, PropTypes } from 'react';
import ContractIcon from 'material-ui/svg-icons/action/code';
import ReactTooltip from 'react-tooltip'; import ReactTooltip from 'react-tooltip';
import { MethodDecoding } from '../../../../ui';
import * as tUtil from '../util/transaction'; import * as tUtil from '../util/transaction';
import Account from '../Account'; import Account from '../Account';
import styles from './TransactionMainDetails.css'; import styles from './TransactionMainDetails.css';
@ -31,8 +32,7 @@ export default class TransactionMainDetails extends Component {
value: PropTypes.object.isRequired, // wei hex value: PropTypes.object.isRequired, // wei hex
totalValue: PropTypes.object.isRequired, // wei BigNumber totalValue: PropTypes.object.isRequired, // wei BigNumber
isTest: PropTypes.bool.isRequired, isTest: PropTypes.bool.isRequired,
to: PropTypes.string, // undefined if it's a contract transaction: PropTypes.object.isRequired,
toBalance: PropTypes.object, // eth BigNumber - undefined if it's a contract or until it's fetched
children: PropTypes.node children: PropTypes.node
}; };
@ -59,15 +59,7 @@ export default class TransactionMainDetails extends Component {
} }
render () { render () {
const { to } = this.props; const { children, from, fromBalance, transaction, isTest } = this.props;
return to
? this.renderTransfer()
: this.renderContract();
}
renderTransfer () {
const { children, from, fromBalance, to, toBalance, isTest } = this.props;
return ( return (
<div className={ styles.transaction }> <div className={ styles.transaction }>
@ -79,48 +71,11 @@ export default class TransactionMainDetails extends Component {
isTest={ isTest } /> isTest={ isTest } />
</div> </div>
</div> </div>
<div className={ styles.tx }> <div className={ styles.method }>
{ this.renderValue() } <MethodDecoding
<div>&rArr;</div> address={ from }
{ this.renderTotalValue() } transaction={ transaction }
</div> historic={ false } />
<div className={ styles.to }>
<div className={ styles.account }>
<Account
address={ to }
balance={ toBalance }
isTest={ isTest } />
</div>
</div>
{ children }
</div>
);
}
renderContract () {
const { children, from, fromBalance, isTest } = this.props;
return (
<div className={ styles.transaction }>
<div className={ styles.from }>
<div className={ styles.account }>
<Account
address={ from }
balance={ fromBalance }
isTest={ isTest } />
</div>
</div>
<div className={ styles.tx }>
{ this.renderValue() }
<div>&rArr;</div>
{ this.renderTotalValue() }
</div>
<div className={ styles.to }>
<div className={ styles.account }>
<ContractIcon className={ styles.contractIcon } />
<br />
Contract
</div>
</div> </div>
{ children } { children }
</div> </div>

View File

@ -19,9 +19,13 @@
.container { .container {
display: flex; display: flex;
padding: 1.5em 0 1em; padding: 1em 0 1em;
& > * { & > * {
vertical-align: middle; vertical-align: middle;
} }
} }
.container+.container {
padding-top: 2em;
}

View File

@ -19,7 +19,6 @@ import { observer } from 'mobx-react';
import TransactionMainDetails from '../TransactionMainDetails'; import TransactionMainDetails from '../TransactionMainDetails';
import TransactionPendingForm from '../TransactionPendingForm'; import TransactionPendingForm from '../TransactionPendingForm';
import TransactionSecondaryDetails from '../TransactionSecondaryDetails';
import styles from './TransactionPending.css'; import styles from './TransactionPending.css';
@ -29,13 +28,15 @@ import * as tUtil from '../util/transaction';
export default class TransactionPending extends Component { export default class TransactionPending extends Component {
static propTypes = { static propTypes = {
id: PropTypes.object.isRequired, id: PropTypes.object.isRequired,
from: PropTypes.string.isRequired, transaction: PropTypes.shape({
value: PropTypes.object.isRequired, // wei hex from: PropTypes.string.isRequired,
gasPrice: PropTypes.object.isRequired, // wei hex value: PropTypes.object.isRequired, // wei hex
gas: PropTypes.object.isRequired, // hex gasPrice: PropTypes.object.isRequired, // wei hex
gas: PropTypes.object.isRequired, // hex
data: PropTypes.string, // hex
to: PropTypes.string // undefined if it's a contract
}).isRequired,
date: PropTypes.instanceOf(Date).isRequired, date: PropTypes.instanceOf(Date).isRequired,
to: PropTypes.string, // undefined if it's a contract
data: PropTypes.string, // hex
nonce: PropTypes.number, nonce: PropTypes.number,
onConfirm: PropTypes.func.isRequired, onConfirm: PropTypes.func.isRequired,
onReject: PropTypes.func.isRequired, onReject: PropTypes.func.isRequired,
@ -50,7 +51,8 @@ export default class TransactionPending extends Component {
}; };
componentWillMount () { componentWillMount () {
const { gas, gasPrice, value, from, to, store } = this.props; const { transaction, store } = this.props;
const { gas, gasPrice, value, from, to } = transaction;
const fee = tUtil.getFee(gas, gasPrice); // BigNumber object const fee = tUtil.getFee(gas, gasPrice); // BigNumber object
const totalValue = tUtil.getTotalValue(fee, value); const totalValue = tUtil.getTotalValue(fee, value);
@ -62,29 +64,22 @@ export default class TransactionPending extends Component {
} }
render () { render () {
const { className, id, date, data, from, to, store } = this.props; const { className, id, transaction, store } = this.props;
const { totalValue, gasPriceEthmDisplay, gasToDisplay } = this.state; const { from, value } = transaction;
const { totalValue } = this.state;
const fromBalance = store.balances[from]; const fromBalance = store.balances[from];
const toBalance = store.balances[to];
return ( return (
<div className={ `${styles.container} ${className || ''}` }> <div className={ `${styles.container} ${className || ''}` }>
<TransactionMainDetails <TransactionMainDetails
{ ...this.props } id={ id }
{ ...this.state } value={ value }
from={ from }
fromBalance={ fromBalance } fromBalance={ fromBalance }
toBalance={ toBalance }
className={ styles.transactionDetails } className={ styles.transactionDetails }
totalValue={ totalValue }> transaction={ transaction }
<TransactionSecondaryDetails totalValue={ totalValue } />
id={ id }
date={ date }
data={ data }
gasPriceEthmDisplay={ gasPriceEthmDisplay }
gasToDisplay={ gasToDisplay }
/>
</TransactionMainDetails>
<TransactionPendingForm <TransactionPendingForm
address={ from } address={ from }
isSending={ this.props.isSending } isSending={ this.props.isSending }
@ -96,7 +91,8 @@ export default class TransactionPending extends Component {
} }
onConfirm = data => { onConfirm = data => {
const { id, gasPrice } = this.props; const { id, transaction } = this.props;
const { gasPrice } = transaction;
const { password, wallet } = data; const { password, wallet } = data;
this.props.onConfirm({ id, password, wallet, gasPrice }); this.props.onConfirm({ id, password, wallet, gasPrice });

View File

@ -19,7 +19,7 @@
.container { .container {
box-sizing: border-box; box-sizing: border-box;
padding: 1em 1em 0 1em; padding: 1em 0 0 2em;
flex: 0 0 $statusWidth; flex: 0 0 $statusWidth;
} }

View File

@ -1,90 +0,0 @@
/* Copyright 2015, 2016 Ethcore (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/>.
*/
.container {
display: block;
}
.iconsContainer {
display: block;
text-align: center;
font-size: .8em;
opacity: 0.5;
padding: 1em 0 0 0;
}
.iconsContainer > * {
margin-right: 3px;
display: inline-block;
}
.iconsContainer:after {
clear: both;
}
.hasInfoIcon svg,
.miningTime svg,
.gasPrice svg,
.data svg,
.date svg {
width: 16px !important;
height: 16px !important;
position: relative;
bottom: -3px;
margin: 0 0.25rem 0 0.75rem;
}
/* TODO [ToDr] composes was handling weird errors when linking from other app */
.miningTime {
/* composes: hasInfoIcon; */
}
.gasPrice {
/* composes: hasInfoIcon; */
}
.data {
/* composes: hasInfoIcon; */
cursor: pointer;
}
.data.noData {
cursor: text;
}
.dataTooltip {
word-wrap: break-word;
max-width: 400px;
}
.expandedData {
display: block;
padding: 15px;
background: gray;
word-wrap: break-word;
color: #fff;
}
.expandedContainer {
padding: 10px;
border-radius: 4px;
}
.expandedContainer:empty {
padding: 0;
}

View File

@ -1,178 +0,0 @@
// Copyright 2015, 2016 Ethcore (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 ReactTooltip from 'react-tooltip';
import DescriptionIcon from 'material-ui/svg-icons/action/description';
import GasIcon from 'material-ui/svg-icons/maps/local-gas-station';
import TimeIcon from 'material-ui/svg-icons/device/access-time';
import moment from 'moment';
import styles from './TransactionSecondaryDetails.css';
import * as tUtil from '../util/transaction';
export default class TransactionSecondaryDetails extends Component {
static propTypes = {
id: PropTypes.object.isRequired,
date: PropTypes.instanceOf(Date),
data: PropTypes.string, // hex
gasPriceEthmDisplay: PropTypes.string,
gasToDisplay: PropTypes.string,
className: PropTypes.string
};
state = {
isDataExpanded: false
};
render () {
const className = this.props.className || '';
return (
<div className={ `${styles.container} ${className}` }>
<div className={ styles.iconsContainer }>
{ this.renderGasPrice() }
{ this.renderData() }
{ this.renderDate() }
</div>
<div className={ styles.expandedContainer }>
{ this.renderDataExpanded() }
</div>
</div>
);
}
renderGasPrice () {
if (!this.props.gasPriceEthmDisplay && !this.props.gasToDisplay) {
return null;
}
const { id } = this.props;
const { gasPriceEthmDisplay, gasToDisplay } = this.props;
return (
<div
data-tip
data-place='right'
data-for={ 'gasPrice' + id }
data-effect='solid'
>
<span className={ styles.gasPrice }>
<GasIcon />
{ gasPriceEthmDisplay } <small>ETH/MGAS</small>
</span>
{ /* dynamic id required in case there are multple transactions in page */ }
<ReactTooltip id={ 'gasPrice' + id }>
Cost of 1,000,000 units of gas. This transaction will use up to <strong>{ gasToDisplay }</strong> <small>MGAS</small>.
</ReactTooltip>
</div>
);
}
renderData () {
if (!this.props.data) {
return null;
}
const { data, id } = this.props;
let dataToDisplay = this.noData() ? 'no data' : tUtil.getShortData(data);
const noDataClass = this.noData() ? styles.noData : '';
return (
<div
className={ `${styles.data} ${noDataClass}` }
onClick={ this.toggleDataExpanded }
data-tip
data-place='right'
data-for={ 'data' + id }
data-class={ styles.dataTooltip }
data-effect='solid'
>
<DescriptionIcon />
{ dataToDisplay }
{ /* dynamic id required in case there are multple transactions in page */ }
<ReactTooltip id={ 'data' + id }>
<strong>Extra data for the transaction: </strong>
<br />
{ dataToDisplay }.
<br />
{ this.noData() ? '' : <strong>Click to expand.</strong> }
</ReactTooltip>
</div>
);
}
renderDate () {
const { date, id } = this.props;
const dateToDisplay = moment(date).fromNow();
const fullDate = moment(date).format('LL LTS');
return (
<div
className={ styles.date }
data-tip
data-place='right'
data-for={ 'date' + id }
data-class={ styles.dataTooltip }
data-effect='solid'
>
<TimeIcon />
{ dateToDisplay }
{ /* dynamic id required in case there are multple transactions in page */ }
<ReactTooltip id={ 'date' + id }>
<strong>Date of the request: </strong>
<br />
{ fullDate }
</ReactTooltip>
</div>
);
}
renderDataExpanded () {
if (!this.props.data) return null;
const { isDataExpanded } = this.state;
const { data } = this.props;
if (!isDataExpanded) {
return;
}
return (
<div className={ styles.expandedHelper }>
<h3>Transaction's Data</h3>
<code className={ styles.expandedData }>{ data }</code>
</div>
);
}
noData () {
return this.props.data === '0x';
}
toggleDataExpanded = () => {
if (this.noData()) {
return;
}
this.setState({
isDataExpanded: !this.state.isDataExpanded
});
}
}

View File

@ -1 +0,0 @@
export default from './TransactionSecondaryDetails';

View File

@ -1,18 +0,0 @@
// Copyright 2015, 2016 Ethcore (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 RequestFinished from './RequestFinished';
export RequestPending from './RequestPending';

View File

@ -23,7 +23,7 @@ import Store from '../../store';
import * as RequestsActions from '../../../../redux/providers/signerActions'; import * as RequestsActions from '../../../../redux/providers/signerActions';
import { Container } from '../../../../ui'; import { Container } from '../../../../ui';
import { RequestPending } from '../../components'; import RequestPending from '../../components/RequestPending';
import styles from './embedded.css'; import styles from './embedded.css';

View File

@ -24,7 +24,7 @@ import Store from '../../store';
import * as RequestsActions from '../../../../redux/providers/signerActions'; import * as RequestsActions from '../../../../redux/providers/signerActions';
import { Container, Page, TxList } from '../../../../ui'; import { Container, Page, TxList } from '../../../../ui';
import { RequestPending, RequestFinished } from '../../components'; import RequestPending from '../../components/RequestPending';
import styles from './RequestsPage.css'; import styles from './RequestsPage.css';
@ -57,7 +57,6 @@ class RequestsPage extends Component {
<Page> <Page>
<div>{ this.renderPendingRequests() }</div> <div>{ this.renderPendingRequests() }</div>
<div>{ this.renderLocalQueue() }</div> <div>{ this.renderLocalQueue() }</div>
<div>{ this.renderFinishedRequests() }</div>
</Page> </Page>
); );
} }
@ -106,24 +105,6 @@ class RequestsPage extends Component {
); );
} }
renderFinishedRequests () {
const { finished } = this.props.signer;
if (!finished.length) {
return;
}
const items = finished.sort(this._sortRequests).map(this.renderFinished);
return (
<Container title='Finished Requests'>
<div className={ styles.items }>
{ items }
</div>
</Container>
);
}
renderPending = (data) => { renderPending = (data) => {
const { actions, isTest } = this.props; const { actions, isTest } = this.props;
const { payload, id, isSending, date } = data; const { payload, id, isSending, date } = data;
@ -143,27 +124,6 @@ class RequestsPage extends Component {
/> />
); );
} }
renderFinished = (data) => {
const { isTest } = this.props;
const { payload, id, result, msg, status, error, date } = data;
return (
<RequestFinished
className={ styles.request }
result={ result }
key={ id }
id={ id }
msg={ msg }
status={ status }
error={ error }
payload={ payload }
date={ date }
isTest={ isTest }
store={ this.store }
/>
);
}
} }
function mapStateToProps (state) { function mapStateToProps (state) {