Align contract event log l&f with transactions (#2812)
* Event into own component, align with transactions * Pass value & type through from event log params * Reformat display columns
This commit is contained in:
parent
8d0cff3599
commit
7eacf07629
@ -150,7 +150,9 @@ export default class Contract {
|
|||||||
log.event = event.name;
|
log.event = event.name;
|
||||||
|
|
||||||
decoded.params.forEach((param) => {
|
decoded.params.forEach((param) => {
|
||||||
log.params[param.name] = param.token.value;
|
const { type, value } = param.token;
|
||||||
|
|
||||||
|
log.params[param.name] = { type, value };
|
||||||
});
|
});
|
||||||
|
|
||||||
return log;
|
return log;
|
||||||
|
@ -110,6 +110,10 @@ export default class Events extends Component {
|
|||||||
|
|
||||||
logToEvent = (log) => {
|
logToEvent = (log) => {
|
||||||
log.key = api.util.sha3(JSON.stringify(log));
|
log.key = api.util.sha3(JSON.stringify(log));
|
||||||
|
log.params = Object.keys(log.params).reduce((params, name) => {
|
||||||
|
params[name] = log.params[name].value;
|
||||||
|
return params;
|
||||||
|
}, {});
|
||||||
|
|
||||||
return log;
|
return log;
|
||||||
}
|
}
|
||||||
|
@ -114,6 +114,10 @@ export default class Events extends Component {
|
|||||||
|
|
||||||
logToEvent = (log) => {
|
logToEvent = (log) => {
|
||||||
log.key = api.util.sha3(JSON.stringify(log));
|
log.key = api.util.sha3(JSON.stringify(log));
|
||||||
|
log.params = Object.keys(log.params).reduce((params, name) => {
|
||||||
|
params[name] = log.params[name].value;
|
||||||
|
return params;
|
||||||
|
}, {});
|
||||||
|
|
||||||
return log;
|
return log;
|
||||||
}
|
}
|
||||||
@ -139,7 +143,6 @@ export default class Events extends Component {
|
|||||||
.concat(pendingEvents)
|
.concat(pendingEvents)
|
||||||
.filter((log) => !minedNew.find((event) => event.transactionHash === log.transactionHash));
|
.filter((log) => !minedNew.find((event) => event.transactionHash === log.transactionHash));
|
||||||
const events = [].concat(pendingNew).concat(minedNew);
|
const events = [].concat(pendingNew).concat(minedNew);
|
||||||
console.log('*** events', events.map((event) => event.address));
|
|
||||||
this.setState({ loading: false, events, minedEvents: minedNew, pendingEvents: pendingNew });
|
this.setState({ loading: false, events, minedEvents: minedNew, pendingEvents: pendingNew });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -106,7 +106,10 @@ export default class Events extends Component {
|
|||||||
logIndex,
|
logIndex,
|
||||||
transactionHash,
|
transactionHash,
|
||||||
transactionIndex,
|
transactionIndex,
|
||||||
params,
|
params: Object.keys(params).reduce((data, name) => {
|
||||||
|
data[name] = params[name].value;
|
||||||
|
return data;
|
||||||
|
}, {}),
|
||||||
key
|
key
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
@ -48,9 +48,9 @@ const renderEvent = (classNames, verb) => (e, accounts, contacts) => {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<tr key={ e.key } className={ classes }>
|
<tr key={ e.key } className={ classes }>
|
||||||
<td>{ renderAddress(e.parameters.owner, accounts, contacts) }</td>
|
<td>{ renderAddress(e.parameters.owner.value, accounts, contacts) }</td>
|
||||||
<td><abbr title={ e.transaction }>{ verb }</abbr></td>
|
<td><abbr title={ e.transaction }>{ verb }</abbr></td>
|
||||||
<td><code>{ renderHash(bytesToHex(e.parameters.name)) }</code></td>
|
<td><code>{ renderHash(bytesToHex(e.parameters.name.value)) }</code></td>
|
||||||
<td>{ renderStatus(e.timestamp, e.state === 'pending') }</td>
|
<td>{ renderStatus(e.timestamp, e.state === 'pending') }</td>
|
||||||
</tr>
|
</tr>
|
||||||
);
|
);
|
||||||
@ -64,10 +64,10 @@ const renderDataChanged = (e, accounts, contacts) => {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<tr key={ e.key } className={ classNames }>
|
<tr key={ e.key } className={ classNames }>
|
||||||
<td>{ renderAddress(e.parameters.owner, accounts, contacts) }</td>
|
<td>{ renderAddress(e.parameters.owner.value, accounts, contacts) }</td>
|
||||||
<td><abbr title={ e.transaction }>updated</abbr></td>
|
<td><abbr title={ e.transaction }>updated</abbr></td>
|
||||||
<td>
|
<td>
|
||||||
key <code>{ new Buffer(e.parameters.plainKey).toString('utf8') }</code> of <code>{ renderHash(bytesToHex(e.parameters.name)) }</code>
|
key <code>{ new Buffer(e.parameters.plainKey.value).toString('utf8') }</code> of <code>{ renderHash(bytesToHex(e.parameters.name.value)) }</code>
|
||||||
</td>
|
</td>
|
||||||
<td>{ renderStatus(e.timestamp, e.state === 'pending') }</td>
|
<td>{ renderStatus(e.timestamp, e.state === 'pending') }</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
@ -30,7 +30,10 @@ const logToEvent = (log) => {
|
|||||||
logIndex,
|
logIndex,
|
||||||
transactionHash,
|
transactionHash,
|
||||||
transactionIndex,
|
transactionIndex,
|
||||||
params,
|
params: Object.keys(params).reduce((data, name) => {
|
||||||
|
data[name] = params[name].value;
|
||||||
|
return data;
|
||||||
|
}, {}),
|
||||||
key
|
key
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
@ -148,27 +148,27 @@ export const subscribeEvents = () => (dispatch, getState) => {
|
|||||||
return dispatch(setTokenData(params.id.toNumber(), {
|
return dispatch(setTokenData(params.id.toNumber(), {
|
||||||
tla: '...',
|
tla: '...',
|
||||||
base: -1,
|
base: -1,
|
||||||
address: params.addr,
|
address: params.addr.value,
|
||||||
name: params.name,
|
name: params.name.value,
|
||||||
isPending: true
|
isPending: true
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (event === 'Registered' && type === 'mined') {
|
if (event === 'Registered' && type === 'mined') {
|
||||||
return dispatch(loadToken(params.id.toNumber()));
|
return dispatch(loadToken(params.id.value.toNumber()));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (event === 'Unregistered' && type === 'pending') {
|
if (event === 'Unregistered' && type === 'pending') {
|
||||||
return dispatch(setTokenPending(params.id.toNumber(), true));
|
return dispatch(setTokenPending(params.id.value.toNumber(), true));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (event === 'Unregistered' && type === 'mined') {
|
if (event === 'Unregistered' && type === 'mined') {
|
||||||
return dispatch(deleteToken(params.id.toNumber()));
|
return dispatch(deleteToken(params.id.value.toNumber()));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (event === 'MetaChanged' && type === 'pending') {
|
if (event === 'MetaChanged' && type === 'pending') {
|
||||||
return dispatch(setTokenData(
|
return dispatch(setTokenData(
|
||||||
params.id.toNumber(),
|
params.id.value.toNumber(),
|
||||||
{ metaPending: true, metaMined: false }
|
{ metaPending: true, metaMined: false }
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
@ -176,13 +176,13 @@ export const subscribeEvents = () => (dispatch, getState) => {
|
|||||||
if (event === 'MetaChanged' && type === 'mined') {
|
if (event === 'MetaChanged' && type === 'mined') {
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
dispatch(setTokenData(
|
dispatch(setTokenData(
|
||||||
params.id.toNumber(),
|
params.id.value.toNumber(),
|
||||||
{ metaPending: false, metaMined: false }
|
{ metaPending: false, metaMined: false }
|
||||||
));
|
));
|
||||||
}, 5000);
|
}, 5000);
|
||||||
|
|
||||||
return dispatch(setTokenData(
|
return dispatch(setTokenData(
|
||||||
params.id.toNumber(),
|
params.id.value.toNumber(),
|
||||||
{ metaPending: false, metaMined: true }
|
{ metaPending: false, metaMined: true }
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
183
js/src/views/Contract/Events/Event/event.js
Normal file
183
js/src/views/Contract/Events/Event/event.js
Normal file
@ -0,0 +1,183 @@
|
|||||||
|
// 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 BigNumber from 'bignumber.js';
|
||||||
|
import moment from 'moment';
|
||||||
|
import React, { Component, PropTypes } from 'react';
|
||||||
|
import { connect } from 'react-redux';
|
||||||
|
import { bindActionCreators } from 'redux';
|
||||||
|
|
||||||
|
import { fetchBlock, fetchTransaction } from '../../../../redux/providers/blockchainActions';
|
||||||
|
import { IdentityIcon, IdentityName, Input, InputAddress } from '../../../../ui';
|
||||||
|
|
||||||
|
import styles from '../../contract.css';
|
||||||
|
|
||||||
|
class Event extends Component {
|
||||||
|
static contextTypes = {
|
||||||
|
api: PropTypes.object.isRequired
|
||||||
|
}
|
||||||
|
|
||||||
|
static propTypes = {
|
||||||
|
event: PropTypes.object.isRequired,
|
||||||
|
blocks: PropTypes.object,
|
||||||
|
transactions: PropTypes.object,
|
||||||
|
isTest: PropTypes.bool,
|
||||||
|
fetchBlock: PropTypes.func.isRequired,
|
||||||
|
fetchTransaction: PropTypes.func.isRequired
|
||||||
|
}
|
||||||
|
|
||||||
|
componentDidMount () {
|
||||||
|
this.retrieveTransaction();
|
||||||
|
}
|
||||||
|
|
||||||
|
render () {
|
||||||
|
const { event, blocks, transactions, isTest } = this.props;
|
||||||
|
|
||||||
|
const block = blocks[event.blockNumber.toString()];
|
||||||
|
const transaction = transactions[event.transactionHash] || {};
|
||||||
|
const classes = `${styles.event} ${styles[event.state]}`;
|
||||||
|
const url = `https://${isTest ? 'testnet.' : ''}etherscan.io/tx/${event.transactionHash}`;
|
||||||
|
const keys = Object.keys(event.params).join(', ');
|
||||||
|
const values = Object.keys(event.params).map((name, index) => {
|
||||||
|
const param = event.params[name];
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className={ styles.eventValue } key={ `${event.key}_val_${index}` }>
|
||||||
|
{ this.renderParam(name, param) }
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
return (
|
||||||
|
<tr className={ classes }>
|
||||||
|
<td className={ styles.timestamp }>
|
||||||
|
<div>{ event.state === 'pending' ? 'pending' : this.formatBlockTimestamp(block) }</div>
|
||||||
|
<div>{ this.formatNumber(transaction.blockNumber) }</div>
|
||||||
|
</td>
|
||||||
|
<td className={ styles.txhash }>
|
||||||
|
{ this.renderAddressName(transaction.from) }
|
||||||
|
</td>
|
||||||
|
<td className={ styles.txhash }>
|
||||||
|
<div className={ styles.eventType }>
|
||||||
|
{ event.type }({ keys })
|
||||||
|
</div>
|
||||||
|
<a href={ url } target='_blank'>{ this.formatHash(event.transactionHash) }</a>
|
||||||
|
</td>
|
||||||
|
<td className={ styles.eventDetails }>
|
||||||
|
<div className={ styles.eventParams }>
|
||||||
|
{ values }
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
formatHash (hash) {
|
||||||
|
if (!hash || hash.length <= 16) {
|
||||||
|
return hash;
|
||||||
|
}
|
||||||
|
|
||||||
|
return `${hash.substr(2, 6)}...${hash.slice(-6)}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
renderAddressName (address, withName = true) {
|
||||||
|
return (
|
||||||
|
<span className={ styles.eventAddress }>
|
||||||
|
<IdentityIcon center inline address={ address } className={ styles.eventIdentityicon } />
|
||||||
|
{ withName ? <IdentityName address={ address } /> : address }
|
||||||
|
</span>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
renderParam (name, param) {
|
||||||
|
const { api } = this.context;
|
||||||
|
|
||||||
|
switch (param.type) {
|
||||||
|
case 'address':
|
||||||
|
return (
|
||||||
|
<InputAddress
|
||||||
|
disabled
|
||||||
|
text
|
||||||
|
className={ styles.input }
|
||||||
|
value={ param.value }
|
||||||
|
label={ name } />
|
||||||
|
);
|
||||||
|
|
||||||
|
default:
|
||||||
|
let value;
|
||||||
|
if (api.util.isInstanceOf(param.value, BigNumber)) {
|
||||||
|
value = param.value.toFormat(0);
|
||||||
|
} else if (api.util.isArray(param.value)) {
|
||||||
|
value = api.util.bytesToHex(param.value);
|
||||||
|
} else {
|
||||||
|
value = param.value.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Input
|
||||||
|
disabled
|
||||||
|
className={ styles.input }
|
||||||
|
value={ value }
|
||||||
|
label={ name } />
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
formatBlockTimestamp (block) {
|
||||||
|
if (!block) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return moment(block.timestamp).fromNow();
|
||||||
|
}
|
||||||
|
|
||||||
|
formatNumber (number) {
|
||||||
|
if (!number) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return new BigNumber(number).toFormat();
|
||||||
|
}
|
||||||
|
|
||||||
|
retrieveTransaction () {
|
||||||
|
const { event, fetchBlock, fetchTransaction } = this.props;
|
||||||
|
|
||||||
|
fetchBlock(event.blockNumber);
|
||||||
|
fetchTransaction(event.transactionHash);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function mapStateToProps (state) {
|
||||||
|
const { isTest } = state.nodeStatus;
|
||||||
|
const { blocks, transactions } = state.blockchain;
|
||||||
|
|
||||||
|
return {
|
||||||
|
isTest,
|
||||||
|
blocks,
|
||||||
|
transactions
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
function mapDispatchToProps (dispatch) {
|
||||||
|
return bindActionCreators({
|
||||||
|
fetchBlock, fetchTransaction
|
||||||
|
}, dispatch);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default connect(
|
||||||
|
mapStateToProps,
|
||||||
|
mapDispatchToProps
|
||||||
|
)(Event);
|
17
js/src/views/Contract/Events/Event/index.js
Normal file
17
js/src/views/Contract/Events/Event/index.js
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
// 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 './event';
|
@ -14,11 +14,11 @@
|
|||||||
// You should have received a copy of the GNU General Public License
|
// You should have received a copy of the GNU General Public License
|
||||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
import BigNumber from 'bignumber.js';
|
|
||||||
import React, { Component, PropTypes } from 'react';
|
import React, { Component, PropTypes } from 'react';
|
||||||
|
|
||||||
import { Container, ContainerTitle } from '../../../ui';
|
import { Container, ContainerTitle } from '../../../ui';
|
||||||
|
|
||||||
|
import Event from './Event';
|
||||||
import styles from '../contract.css';
|
import styles from '../contract.css';
|
||||||
|
|
||||||
export default class Events extends Component {
|
export default class Events extends Component {
|
||||||
@ -27,106 +27,23 @@ export default class Events extends Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static propTypes = {
|
static propTypes = {
|
||||||
events: PropTypes.array,
|
events: PropTypes.array
|
||||||
isTest: PropTypes.bool
|
|
||||||
}
|
|
||||||
|
|
||||||
state = {
|
|
||||||
transactions: {}
|
|
||||||
}
|
|
||||||
|
|
||||||
componentDidMount () {
|
|
||||||
this.componentWillReceiveProps(this.props);
|
|
||||||
}
|
|
||||||
|
|
||||||
componentWillReceiveProps (newProps) {
|
|
||||||
this.retrieveTransactions(newProps.events);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
render () {
|
render () {
|
||||||
const { events, isTest } = this.props;
|
const { events } = this.props;
|
||||||
const { transactions } = this.state;
|
|
||||||
|
|
||||||
if (!events || !events.length) {
|
if (!events || !events.length) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
const rows = events.map((event) => {
|
|
||||||
const transaction = transactions[event.transactionHash] || {};
|
|
||||||
const classes = `${styles.event} ${styles[event.state]}`;
|
|
||||||
const url = `https://${isTest ? 'testnet.' : ''}etherscan.io/tx/${event.transactionHash}`;
|
|
||||||
const keys = Object.keys(event.params).map((key, index) => {
|
|
||||||
return <div className={ styles.key } key={ `${event.key}_key_${index}` }>{ key }</div>;
|
|
||||||
});
|
|
||||||
const values = Object.values(event.params).map((value, index) => {
|
|
||||||
return (
|
|
||||||
<div className={ styles.value } key={ `${event.key}_val_${index}` }>
|
|
||||||
{ this.renderValue(value) }
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
return (
|
|
||||||
<tr className={ classes } key={ event.key }>
|
|
||||||
<td>{ event.state === 'pending' ? 'pending' : event.blockNumber.toFormat(0) }</td>
|
|
||||||
<td className={ styles.txhash }>
|
|
||||||
<div>{ transaction.from }</div>
|
|
||||||
<a href={ url } target='_blank'>{ event.transactionHash }</a>
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
<div>{ event.type } =></div>
|
|
||||||
{ keys }
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
<div> </div>
|
|
||||||
{ values }
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Container>
|
<Container>
|
||||||
<ContainerTitle title='events' />
|
<ContainerTitle title='events' />
|
||||||
<table className={ styles.events }>
|
<table className={ styles.events }>
|
||||||
<tbody>{ rows }</tbody>
|
<tbody>{ events.map((event) => <Event event={ event } key={ event.key } />) }</tbody>
|
||||||
</table>
|
</table>
|
||||||
</Container>
|
</Container>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
renderValue (value) {
|
|
||||||
const { api } = this.context;
|
|
||||||
|
|
||||||
if (api.util.isInstanceOf(value, BigNumber)) {
|
|
||||||
return value.toFormat(0);
|
|
||||||
} else if (api.util.isArray(value)) {
|
|
||||||
return api.util.bytesToHex(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
return value.toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
retrieveTransactions (events) {
|
|
||||||
const { api } = this.context;
|
|
||||||
const { transactions } = this.state;
|
|
||||||
const hashes = {};
|
|
||||||
|
|
||||||
events.forEach((event) => {
|
|
||||||
if (!hashes[event.transactionHash] && !transactions[event.transactionHash]) {
|
|
||||||
hashes[event.transactionHash] = true;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
Promise
|
|
||||||
.all(Object.keys(hashes).map((hash) => api.eth.getTransactionByHash(hash)))
|
|
||||||
.then((newTransactions) => {
|
|
||||||
this.setState({
|
|
||||||
transactions: newTransactions.reduce((store, transaction) => {
|
|
||||||
transactions[transaction.hash] = transaction;
|
|
||||||
return transactions;
|
|
||||||
}, transactions)
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -24,9 +24,12 @@
|
|||||||
border-spacing: 0;
|
border-spacing: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.event {
|
.events tr {
|
||||||
|
line-height: 32px;
|
||||||
vertical-align: top;
|
vertical-align: top;
|
||||||
line-height: 26px;
|
}
|
||||||
|
|
||||||
|
.event {
|
||||||
}
|
}
|
||||||
|
|
||||||
.event td {
|
.event td {
|
||||||
@ -43,9 +46,6 @@
|
|||||||
color: #aaa;
|
color: #aaa;
|
||||||
}
|
}
|
||||||
|
|
||||||
.value {
|
|
||||||
}
|
|
||||||
|
|
||||||
.event td div {
|
.event td div {
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
}
|
}
|
||||||
@ -56,3 +56,35 @@
|
|||||||
.pending {
|
.pending {
|
||||||
opacity: 0.5;
|
opacity: 0.5;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.timestamp {
|
||||||
|
padding-top: 1.5em;
|
||||||
|
text-align: right;
|
||||||
|
line-height: 1.5em;
|
||||||
|
opacity: 0.5;
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
.eventDetails {
|
||||||
|
}
|
||||||
|
|
||||||
|
.eventType {
|
||||||
|
}
|
||||||
|
|
||||||
|
.eventParams {
|
||||||
|
padding-left: 2em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.eventValue {
|
||||||
|
margin-top: -16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.eventAddress {
|
||||||
|
display: inline-block;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
.eventIdentityicon {
|
||||||
|
margin-bottom: -10px;
|
||||||
|
margin-right: 0.5em;
|
||||||
|
}
|
||||||
|
@ -116,7 +116,6 @@ class Contract extends Component {
|
|||||||
contract={ contract }
|
contract={ contract }
|
||||||
values={ queryValues } />
|
values={ queryValues } />
|
||||||
<Events
|
<Events
|
||||||
isTest={ isTest }
|
|
||||||
events={ allEvents } />
|
events={ allEvents } />
|
||||||
</Page>
|
</Page>
|
||||||
</div>
|
</div>
|
||||||
|
Loading…
Reference in New Issue
Block a user