mirror of
https://github.com/embarklabs/embark.git
synced 2025-01-11 14:24:24 +00:00
Merge pull request #1041 from embark-framework/feature/debug-button
feat: add debug button to transaction and contract log
This commit is contained in:
commit
13f7a3ff41
@ -7,14 +7,23 @@ import {
|
||||
Button
|
||||
} from "reactstrap";
|
||||
import ReactJson from 'react-json-view';
|
||||
import DebugButton from './DebugButton';
|
||||
|
||||
class ContractDebugger extends Component {
|
||||
handleChange(e) {
|
||||
this.setState({txHash: e.target.value});
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.state = {txHash: ''};
|
||||
}
|
||||
|
||||
debug(_e) {
|
||||
this.props.startDebug(this.state.txHash);
|
||||
componentDidMount() {
|
||||
if (this.props.debuggerTransactionHash) {
|
||||
this.setState({txHash: this.props.debuggerTransactionHash});
|
||||
this.props.startDebug(this.props.debuggerTransactionHash);
|
||||
}
|
||||
}
|
||||
|
||||
handleChange(e) {
|
||||
this.setState({txHash: e.target.value});
|
||||
}
|
||||
|
||||
debugJumpBack(_e) {
|
||||
@ -46,8 +55,8 @@ class ContractDebugger extends Component {
|
||||
<div>
|
||||
<Row>
|
||||
<Col>
|
||||
<Input name="txHash" id="txHash" onChange={(e) => this.handleChange(e)}/>
|
||||
<Button color="primary" onClick={(e) => this.debug(e)}>Debug Tx</Button>
|
||||
<Input name="txHash" id="txHash" value={this.state.txHash} onChange={(e) => this.handleChange(e)}/>
|
||||
<DebugButton forceDebuggable transaction={{hash: this.state.txHash}} />
|
||||
</Col>
|
||||
</Row>
|
||||
<Row>
|
||||
@ -74,7 +83,7 @@ class ContractDebugger extends Component {
|
||||
}
|
||||
|
||||
ContractDebugger.propTypes = {
|
||||
contract: PropTypes.object.isRequired,
|
||||
debuggerTransactionHash: PropTypes.string,
|
||||
startDebug: PropTypes.func,
|
||||
debugJumpBack: PropTypes.func,
|
||||
debugJumpForward: PropTypes.func,
|
||||
|
@ -7,7 +7,6 @@ import classnames from 'classnames';
|
||||
import ContractDetail from '../components/ContractDetail';
|
||||
import ContractTransactionsContainer from '../containers/ContractTransactionsContainer';
|
||||
import ContractOverviewContainer from '../containers/ContractOverviewContainer';
|
||||
import ContractDebuggerContainer from '../containers/ContractDebuggerContainer';
|
||||
|
||||
class ContractLayout extends React.Component {
|
||||
constructor(props) {
|
||||
@ -57,14 +56,6 @@ class ContractLayout extends React.Component {
|
||||
<FontAwesomeIcon className="mr-2" name="list-alt" />Transactions
|
||||
</NavLink>
|
||||
</NavItem>
|
||||
<NavItem>
|
||||
<NavLink
|
||||
className={classnames({ active: this.state.activeTab === '4' })}
|
||||
onClick={() => { this.toggle('4'); }}
|
||||
>
|
||||
<FontAwesomeIcon className="mr-2" name="bug" />Debugger
|
||||
</NavLink>
|
||||
</NavItem>
|
||||
</Nav>
|
||||
<TabContent activeTab={this.state.activeTab}>
|
||||
<TabPane tabId="1">
|
||||
@ -76,9 +67,6 @@ class ContractLayout extends React.Component {
|
||||
<TabPane tabId="3">
|
||||
<ContractTransactionsContainer contract={this.props.contract} />
|
||||
</TabPane>
|
||||
<TabPane tabId="4">
|
||||
<ContractDebuggerContainer contract={this.props.contract} />
|
||||
</TabPane>
|
||||
</TabContent>
|
||||
</CardBody>
|
||||
</Card>
|
||||
|
@ -2,6 +2,8 @@ import PropTypes from "prop-types";
|
||||
import React from 'react';
|
||||
import {Row, Col, Table, FormGroup, Label, Input, Form} from 'reactstrap';
|
||||
|
||||
import DebugButton from './DebugButton'
|
||||
|
||||
const TX_STATES = {Success: '0x1', Fail: '0x0', Any: ''};
|
||||
const EVENT = 'event';
|
||||
const FUNCTION = 'function';
|
||||
@ -107,6 +109,7 @@ class ContractTransactions extends React.Component {
|
||||
<Table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th></th>
|
||||
<th>Call</th>
|
||||
<th>Events</th>
|
||||
<th>Gas Used</th>
|
||||
@ -120,6 +123,7 @@ class ContractTransactions extends React.Component {
|
||||
this.dataToDisplay().map((log, index) => {
|
||||
return (
|
||||
<tr key={'log-' + index}>
|
||||
<td><DebugButton forceDebuggable transaction={{hash: log.transactionHash}}/></td>
|
||||
<td>{`${log.name}.${log.functionName}(${log.paramString})`}</td>
|
||||
<td>{log.events.join(', ')}</td>
|
||||
<td>{log.gasUsed}</td>
|
||||
|
42
embark-ui/src/components/DebugButton.js
Normal file
42
embark-ui/src/components/DebugButton.js
Normal file
@ -0,0 +1,42 @@
|
||||
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import {Button} from "reactstrap";
|
||||
import FontAwesome from 'react-fontawesome';
|
||||
import {withRouter} from "react-router-dom";
|
||||
|
||||
class DebugButton extends React.Component {
|
||||
onClick() {
|
||||
this.props.history.push(`/embark/editor?debuggerTransactionHash=${this.props.transaction.hash}`);
|
||||
}
|
||||
|
||||
isDebuggable() {
|
||||
return this.props.forceDebuggable ||
|
||||
(this.props.contracts && this.props.contracts.find(contract => contract.address === this.props.transaction.to));
|
||||
}
|
||||
|
||||
render() {
|
||||
if (!this.isDebuggable()) {
|
||||
return <React.Fragment />
|
||||
}
|
||||
return (
|
||||
<Button color="primary" onClick={() => this.onClick()}>
|
||||
<FontAwesome className="mr-2" name="bug"/>
|
||||
Debug
|
||||
</Button>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
DebugButton.defaultProps = {
|
||||
forceDebuggable: false
|
||||
}
|
||||
|
||||
DebugButton.propTypes = {
|
||||
forceDebuggable: PropTypes.bool,
|
||||
history: PropTypes.object,
|
||||
transaction: PropTypes.object,
|
||||
contracts: PropTypes.arrayOf(PropTypes.object)
|
||||
};
|
||||
|
||||
export default withRouter(DebugButton);
|
@ -123,13 +123,14 @@ class TextEditor extends React.Component {
|
||||
}
|
||||
|
||||
componentDidUpdate(prevProps) {
|
||||
if (this.props.currentFile.content !== prevProps.currentFile.content) {
|
||||
const isNewContent = this.props.currentFile.content !== prevProps.currentFile.content;
|
||||
if (isNewContent) {
|
||||
editor.setValue(this.props.currentFile.content || '');
|
||||
}
|
||||
|
||||
this.updateMarkers();
|
||||
const expectedDecorationsLength = this.props.debuggerLine ? this.props.breakpoints.length + 1 : this.props.breakpoints.length;
|
||||
if (expectedDecorationsLength !== this.state.decorations.length || this.props.debuggerLine !== prevProps.debuggerLine) {
|
||||
if (expectedDecorationsLength !== this.state.decorations.length || this.props.debuggerLine !== prevProps.debuggerLine || isNewContent) {
|
||||
this.updateDecorations();
|
||||
}
|
||||
|
||||
|
@ -22,6 +22,10 @@ class TextEditorToolbar extends Component {
|
||||
return tab === TextEditorToolbarTabs.Browser;
|
||||
}
|
||||
|
||||
isDebuggerTab(tab) {
|
||||
return tab === TextEditorToolbarTabs.Debugger;
|
||||
}
|
||||
|
||||
renderTab(tab) {
|
||||
return (
|
||||
<NavLink key={tab.label} className={classnames('btn', { active: this.isActiveTab(tab)})} onClick={() => this.props.openAsideTab(tab)}>
|
||||
@ -45,7 +49,8 @@ class TextEditorToolbar extends Component {
|
||||
</li>
|
||||
<li className="breadcrumb-menu">
|
||||
<Nav className="btn-group">
|
||||
{this.props.isContract && Object.values(TextEditorToolbarTabs).map(tab => !this.isBrowserTab(tab) && this.renderTab(tab))}
|
||||
{this.props.isContract && Object.values(TextEditorToolbarTabs).map(tab => !this.isBrowserTab(tab) && !this.isDebuggerTab(tab) && this.renderTab(tab))}
|
||||
{this.renderTab(TextEditorToolbarTabs.Debugger)}
|
||||
{this.renderTab(TextEditorToolbarTabs.Browser)}
|
||||
</Nav>
|
||||
</li>
|
||||
|
@ -3,17 +3,23 @@ import {Link} from 'react-router-dom';
|
||||
import {Row, Col, Card, CardHeader, CardBody} from 'reactstrap';
|
||||
import PropTypes from 'prop-types';
|
||||
|
||||
import DebugButton from './DebugButton';
|
||||
import Description from './Description';
|
||||
import CardTitleIdenticon from './CardTitleIdenticon';
|
||||
import {utils} from 'web3';
|
||||
|
||||
|
||||
const Transaction = ({transaction}) => (
|
||||
const Transaction = ({transaction, contracts}) => (
|
||||
<Row>
|
||||
<Col>
|
||||
<Card>
|
||||
<CardHeader>
|
||||
<CardTitleIdenticon id={transaction.hash}>Transaction {transaction.hash}</CardTitleIdenticon>
|
||||
<CardTitleIdenticon id={transaction.hash}>
|
||||
Transaction {transaction.hash}
|
||||
<div className="float-right">
|
||||
<DebugButton contracts={contracts} transaction={transaction} />
|
||||
</div>
|
||||
</CardTitleIdenticon>
|
||||
</CardHeader>
|
||||
<CardBody>
|
||||
<dl className="row">
|
||||
@ -33,6 +39,7 @@ const Transaction = ({transaction}) => (
|
||||
);
|
||||
|
||||
Transaction.propTypes = {
|
||||
contracts: PropTypes.arrayOf(PropTypes.object),
|
||||
transaction: PropTypes.object
|
||||
};
|
||||
|
||||
|
@ -3,10 +3,11 @@ import {Link} from "react-router-dom";
|
||||
import {Row, Col, Card, CardHeader, CardBody} from 'reactstrap';
|
||||
import PropTypes from 'prop-types';
|
||||
|
||||
import DebugButton from './DebugButton';
|
||||
import CardTitleIdenticon from './CardTitleIdenticon';
|
||||
import Pagination from "./Pagination";
|
||||
|
||||
const Transactions = ({transactions, changePage, currentPage, numberOfPages}) => (
|
||||
const Transactions = ({transactions, contracts, changePage, currentPage, numberOfPages}) => (
|
||||
<Row>
|
||||
<Col>
|
||||
<Card>
|
||||
@ -21,6 +22,11 @@ const Transactions = ({transactions, changePage, currentPage, numberOfPages}) =>
|
||||
{transaction.hash}
|
||||
</Link>
|
||||
</CardTitleIdenticon>
|
||||
<Row>
|
||||
<Col>
|
||||
<DebugButton transaction={transaction} contracts={contracts} />
|
||||
</Col>
|
||||
</Row>
|
||||
<Row>
|
||||
<Col md={6}>
|
||||
<strong>Block number</strong>
|
||||
@ -50,6 +56,7 @@ const Transactions = ({transactions, changePage, currentPage, numberOfPages}) =>
|
||||
|
||||
Transactions.propTypes = {
|
||||
transactions: PropTypes.arrayOf(PropTypes.object),
|
||||
contracts: PropTypes.arrayOf(PropTypes.object),
|
||||
changePage: PropTypes.func,
|
||||
currentPage: PropTypes.number,
|
||||
numberOfPages: PropTypes.number
|
||||
|
@ -1,42 +1,43 @@
|
||||
import React, {Component} from 'react';
|
||||
import {connect} from 'react-redux';
|
||||
import PropTypes from 'prop-types';
|
||||
import {startDebug, debugJumpBack, debugJumpForward, debugStepOverForward, debugStepOverBackward, debugStepIntoForward, debugStepIntoBackward} from '../actions';
|
||||
|
||||
import {
|
||||
startDebug,
|
||||
debugJumpBack,
|
||||
debugJumpForward,
|
||||
debugStepOverForward,
|
||||
debugStepOverBackward,
|
||||
debugStepIntoForward,
|
||||
debugStepIntoBackward
|
||||
} from '../actions';
|
||||
import ContractDebugger from '../components/ContractDebugger';
|
||||
import DataWrapper from "../components/DataWrapper";
|
||||
import {getContractLogsByContract, debuggerInfo} from "../reducers/selectors";
|
||||
import {getDebuggerInfo} from "../reducers/selectors";
|
||||
|
||||
|
||||
class ContractDebuggerContainer extends Component {
|
||||
render() {
|
||||
return (
|
||||
<DataWrapper shouldRender={this.props.contractLogs !== undefined } {...this.props} render={() => (
|
||||
<ContractDebugger contract={this.props.contract} startDebug={this.props.startDebug}
|
||||
debugJumpBack={this.props.debugJumpBack} debugJumpForward={this.props.debugJumpForward}
|
||||
<ContractDebugger debuggerTransactionHash={this.props.debuggerTransactionHash}
|
||||
startDebug={this.props.startDebug}
|
||||
debugJumpBack={this.props.debugJumpBack}
|
||||
debugJumpForward={this.props.debugJumpForward}
|
||||
debugStepOverForward={this.props.debugStepOverForward}
|
||||
debugStepOverBackward={this.props.debugStepOverBackward}
|
||||
debugStepIntoForward={this.props.debugStepIntoForward}
|
||||
debugStepIntoBackward={this.props.debugStepIntoBackward}
|
||||
debuggerInfo={this.props.debuggerInfo}
|
||||
/>
|
||||
)} />
|
||||
debuggerInfo={this.props.debuggerInfo}/>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
function mapStateToProps(state, props) {
|
||||
return {
|
||||
contractLogs: getContractLogsByContract(state, props.contract.className),
|
||||
debuggerInfo: debuggerInfo(state)
|
||||
debuggerInfo: getDebuggerInfo(state)
|
||||
};
|
||||
}
|
||||
|
||||
ContractDebuggerContainer.propTypes = {
|
||||
contractLogs: PropTypes.array,
|
||||
fetchContractLogs: PropTypes.func,
|
||||
listenToContractLogs: PropTypes.func,
|
||||
match: PropTypes.object,
|
||||
contract: PropTypes.object,
|
||||
debuggerTransactionHash: PropTypes.string,
|
||||
startDebug: PropTypes.func,
|
||||
debugJumpBack: PropTypes.func,
|
||||
debugJumpForward: PropTypes.func,
|
||||
|
@ -1,13 +1,20 @@
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import {connect} from 'react-redux';
|
||||
import {withRouter} from "react-router-dom";
|
||||
import {Row, Col} from 'reactstrap';
|
||||
import TextEditorAsideContainer from './TextEditorAsideContainer';
|
||||
import TextEditorContainer from './TextEditorContainer';
|
||||
import FileExplorerContainer from './FileExplorerContainer';
|
||||
import TextEditorToolbarContainer from './TextEditorToolbarContainer';
|
||||
import {fetchEditorTabs as fetchEditorTabsAction} from '../actions';
|
||||
import {getCurrentFile} from '../reducers/selectors';
|
||||
import {
|
||||
fetchEditorTabs as fetchEditorTabsAction,
|
||||
contracts as contractsAction,
|
||||
file as fileAction,
|
||||
transaction as transactionAction
|
||||
} from '../actions';
|
||||
import {getCurrentFile, getContracts, getTransaction} from '../reducers/selectors';
|
||||
import {getDebuggerTransactionHash} from '../utils/utils';
|
||||
import classnames from 'classnames';
|
||||
import Resizable from 're-resizable';
|
||||
import {OPERATIONS} from '../constants';
|
||||
@ -24,16 +31,21 @@ class EditorContainer extends React.Component {
|
||||
this.windowWidth = window.innerWidth;
|
||||
|
||||
this.state = {
|
||||
currentAsideTab: {}, showHiddenFiles: false, currentFile: this.props.currentFile,
|
||||
currentAsideTab: {},
|
||||
showHiddenFiles: false,
|
||||
currentFile: this.props.currentFile,
|
||||
editorHeight: this.DEFAULT_HEIGHT,
|
||||
editorWidth: ((this.windowWidth < this.SMALL_SIZE) ? this.DEFAULT_EDITOR_WIDTH_SMALL : this.DEFAULT_EDITOR_WIDTH) + '%',
|
||||
asideHeight: '100%', asideWidth: '25%',
|
||||
asideHeight: '100%',
|
||||
asideWidth: '25%',
|
||||
isSmallSize: (this.windowWidth < this.SMALL_SIZE)
|
||||
};
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
this.props.fetchEditorTabs();
|
||||
this.props.fetchContracts();
|
||||
this.props.fetchTransaction(this.props.debuggerTransactionHash);
|
||||
window.addEventListener("resize", this.updateDimensions.bind(this));
|
||||
}
|
||||
|
||||
@ -56,6 +68,14 @@ class EditorContainer extends React.Component {
|
||||
if (this.props.currentFile.path !== prevProps.currentFile.path) {
|
||||
this.setState({currentFile: this.props.currentFile});
|
||||
}
|
||||
|
||||
if(this.props.contracts && this.props.transaction !== prevProps.transaction) {
|
||||
const debuggingContract = this.props.contracts.find(contract => contract.address === this.props.transaction.to)
|
||||
if (debuggingContract) {
|
||||
this.setState({currentAsideTab: 'debugger'})
|
||||
this.props.fetchFile({path: debuggingContract.path});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
isContract() {
|
||||
@ -129,6 +149,7 @@ class EditorContainer extends React.Component {
|
||||
const aside = (
|
||||
<div className="editor-aside">
|
||||
<TextEditorAsideContainer currentAsideTab={this.state.currentAsideTab}
|
||||
debuggerTransactionHash={this.props.debuggerTransactionHash}
|
||||
currentFile={this.props.currentFile}/>
|
||||
</div>
|
||||
);
|
||||
@ -188,21 +209,36 @@ class EditorContainer extends React.Component {
|
||||
}
|
||||
}
|
||||
|
||||
function mapStateToProps(state, _props) {
|
||||
function mapStateToProps(state, props) {
|
||||
const currentFile = getCurrentFile(state);
|
||||
const debuggerTransactionHash = getDebuggerTransactionHash(props.location);
|
||||
|
||||
return {
|
||||
currentFile
|
||||
currentFile,
|
||||
debuggerTransactionHash,
|
||||
transaction: getTransaction(state, debuggerTransactionHash),
|
||||
contracts: getContracts(state)
|
||||
};
|
||||
}
|
||||
|
||||
EditorContainer.propTypes = {
|
||||
debuggerTransactionHash: PropTypes.string,
|
||||
contracts: PropTypes.array,
|
||||
transaction: PropTypes.object,
|
||||
fetchContracts: PropTypes.func,
|
||||
fetchFile: PropTypes.func,
|
||||
fetchTransaction: PropTypes.func,
|
||||
currentFile: PropTypes.object,
|
||||
fetchEditorTabs: PropTypes.func
|
||||
};
|
||||
|
||||
export default connect(
|
||||
export default withRouter(connect(
|
||||
mapStateToProps,
|
||||
{fetchEditorTabs: fetchEditorTabsAction.request}
|
||||
)(EditorContainer);
|
||||
{
|
||||
fetchEditorTabs: fetchEditorTabsAction.request,
|
||||
fetchTransaction: transactionAction.request,
|
||||
fetchFile: fileAction.request,
|
||||
fetchContracts: contractsAction.request
|
||||
},
|
||||
)(EditorContainer));
|
||||
|
||||
|
@ -4,7 +4,6 @@ import PropTypes from 'prop-types';
|
||||
import {Card, CardBody} from 'reactstrap';
|
||||
|
||||
import Preview from '../components/Preview';
|
||||
import {contracts as contractsAction} from '../actions';
|
||||
import {getContractsByPath} from "../reducers/selectors";
|
||||
import ContractDetail from '../components/ContractDetail';
|
||||
import ContractTransactionsContainer from './ContractTransactionsContainer';
|
||||
@ -13,19 +12,8 @@ import ContractDebuggerContainer from '../containers/ContractDebuggerContainer';
|
||||
import { TextEditorToolbarTabs } from '../components/TextEditorToolbar';
|
||||
|
||||
class TextEditorAsideContainer extends Component {
|
||||
componentDidMount() {
|
||||
this.props.fetchContracts();
|
||||
}
|
||||
|
||||
renderContent(contract, index) {
|
||||
switch (this.props.currentAsideTab.label) {
|
||||
case TextEditorToolbarTabs.Debugger.label:
|
||||
return (
|
||||
<React.Fragment>
|
||||
<h2>{contract.className} - Debugger</h2>
|
||||
<ContractDebuggerContainer key={index} contract={contract}/>
|
||||
</React.Fragment>
|
||||
);
|
||||
switch (this.props.currentAsideTab) {
|
||||
case TextEditorToolbarTabs.Details.label:
|
||||
return (
|
||||
<React.Fragment>
|
||||
@ -56,15 +44,21 @@ class TextEditorAsideContainer extends Component {
|
||||
if (this.props.currentAsideTab.label === TextEditorToolbarTabs.Browser.label) {
|
||||
return <Preview/>;
|
||||
}
|
||||
return this.props.contracts.map((contract, index) => {
|
||||
if (this.props.currentAsideTab.label === TextEditorToolbarTabs.Debugger.label) {
|
||||
return (
|
||||
<React.Fragment>
|
||||
<h2>Debugger</h2>
|
||||
<ContractDebuggerContainer debuggerTransactionHash={this.props.debuggerTransactionHash}/>
|
||||
</React.Fragment>
|
||||
);
|
||||
}
|
||||
return this.props.contracts.map((contract, index) => (
|
||||
<Card key={'contract-' + index} className="editor-aside-card rounded-0 border-top-0">
|
||||
<CardBody>
|
||||
{this.renderContent(contract, index)}
|
||||
</CardBody>
|
||||
</Card>
|
||||
);
|
||||
});
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
@ -76,15 +70,12 @@ function mapStateToProps(state, props) {
|
||||
|
||||
TextEditorAsideContainer.propTypes = {
|
||||
currentFile: PropTypes.object,
|
||||
currentAsideTab: PropTypes.object,
|
||||
contract: PropTypes.array,
|
||||
fetchContracts: PropTypes.func,
|
||||
debuggerTransactionHash: PropTypes.string,
|
||||
currentAsideTab: PropTypes.string,
|
||||
contracts: PropTypes.array
|
||||
};
|
||||
|
||||
export default connect(
|
||||
mapStateToProps,
|
||||
{
|
||||
fetchContracts: contractsAction.request
|
||||
}
|
||||
{}
|
||||
)(TextEditorAsideContainer);
|
||||
|
@ -3,20 +3,21 @@ import {connect} from 'react-redux';
|
||||
import PropTypes from 'prop-types';
|
||||
import {withRouter} from 'react-router-dom';
|
||||
|
||||
import {transaction as transactionAction} from '../actions';
|
||||
import {transaction as transactionAction, contracts as contractsAction} from '../actions';
|
||||
import Transaction from '../components/Transaction';
|
||||
import DataWrapper from "../components/DataWrapper";
|
||||
import {getTransaction} from "../reducers/selectors";
|
||||
import {getTransaction, getContracts} from "../reducers/selectors";
|
||||
|
||||
class TransactionContainer extends Component {
|
||||
componentDidMount() {
|
||||
this.props.fetchContracts();
|
||||
this.props.fetchTransaction(this.props.match.params.hash);
|
||||
}
|
||||
|
||||
render() {
|
||||
return (
|
||||
<DataWrapper shouldRender={this.props.transaction !== undefined } {...this.props} render={({transaction}) => (
|
||||
<Transaction transaction={transaction} />
|
||||
<Transaction contracts={this.props.contracts} transaction={transaction} />
|
||||
)} />
|
||||
);
|
||||
}
|
||||
@ -25,6 +26,7 @@ class TransactionContainer extends Component {
|
||||
function mapStateToProps(state, props) {
|
||||
return {
|
||||
transaction: getTransaction(state, props.match.params.hash),
|
||||
contracts: getContracts(state),
|
||||
error: state.errorMessage,
|
||||
loading: state.loading
|
||||
};
|
||||
@ -33,7 +35,8 @@ function mapStateToProps(state, props) {
|
||||
TransactionContainer.propTypes = {
|
||||
match: PropTypes.object,
|
||||
transaction: PropTypes.object,
|
||||
transactions: PropTypes.arrayOf(PropTypes.object),
|
||||
contracts: PropTypes.arrayOf(PropTypes.object),
|
||||
fetchContracts: PropTypes.func,
|
||||
fetchTransaction: PropTypes.func,
|
||||
error: PropTypes.string
|
||||
};
|
||||
@ -41,6 +44,7 @@ TransactionContainer.propTypes = {
|
||||
export default withRouter(connect(
|
||||
mapStateToProps,
|
||||
{
|
||||
fetchContracts: contractsAction.request,
|
||||
fetchTransaction: transactionAction.request
|
||||
}
|
||||
)(TransactionContainer));
|
||||
|
@ -2,10 +2,10 @@ import React, {Component} from 'react';
|
||||
import {connect} from 'react-redux';
|
||||
import PropTypes from 'prop-types';
|
||||
|
||||
import {transactions as transactionsAction, initBlockHeader, stopBlockHeader} from '../actions';
|
||||
import {transactions as transactionsAction, initBlockHeader, stopBlockHeader, contracts as contractsAction} from '../actions';
|
||||
import Transactions from '../components/Transactions';
|
||||
import DataWrapper from "../components/DataWrapper";
|
||||
import {getTransactions} from "../reducers/selectors";
|
||||
import {getTransactions, getContracts} from "../reducers/selectors";
|
||||
|
||||
const MAX_TXS = 10; // TODO use same constant as API
|
||||
|
||||
@ -20,6 +20,7 @@ class TransactionsContainer extends Component {
|
||||
|
||||
componentDidMount() {
|
||||
this.props.fetchTransactions();
|
||||
this.props.fetchContracts();
|
||||
this.props.initBlockHeader();
|
||||
}
|
||||
|
||||
@ -59,7 +60,9 @@ class TransactionsContainer extends Component {
|
||||
return (
|
||||
<React.Fragment>
|
||||
<DataWrapper shouldRender={this.currentTxs.length > 0} {...this.props} render={() => (
|
||||
<Transactions transactions={this.currentTxs} numberOfPages={this.getNumberOfPages()}
|
||||
<Transactions transactions={this.currentTxs}
|
||||
contracts={this.props.contracts}
|
||||
numberOfPages={this.getNumberOfPages()}
|
||||
changePage={(newPage) => this.changePage(newPage)}
|
||||
currentPage={this.state.currentPage || this.getNumberOfPages()} />
|
||||
)} />
|
||||
@ -69,12 +72,19 @@ class TransactionsContainer extends Component {
|
||||
}
|
||||
|
||||
function mapStateToProps(state) {
|
||||
return {transactions: getTransactions(state), error: state.errorMessage, loading: state.loading};
|
||||
return {
|
||||
transactions: getTransactions(state),
|
||||
contracts: getContracts(state),
|
||||
error: state.errorMessage,
|
||||
loading: state.loading
|
||||
};
|
||||
}
|
||||
|
||||
TransactionsContainer.propTypes = {
|
||||
transactions: PropTypes.arrayOf(PropTypes.object),
|
||||
contracts: PropTypes.arrayOf(PropTypes.object),
|
||||
fetchTransactions: PropTypes.func,
|
||||
fetchContracts: PropTypes.func,
|
||||
initBlockHeader: PropTypes.func,
|
||||
stopBlockHeader: PropTypes.func,
|
||||
error: PropTypes.string,
|
||||
@ -85,6 +95,7 @@ export default connect(
|
||||
mapStateToProps,
|
||||
{
|
||||
fetchTransactions: transactionsAction.request,
|
||||
fetchContracts: contractsAction.request,
|
||||
initBlockHeader,
|
||||
stopBlockHeader
|
||||
},
|
||||
|
@ -225,7 +225,7 @@ export function getWeb3Deployments(state) {
|
||||
return state.web3.deployments;
|
||||
}
|
||||
|
||||
export function debuggerInfo(state) {
|
||||
export function getDebuggerInfo(state) {
|
||||
return state.debuggerInfo;
|
||||
}
|
||||
|
||||
|
@ -25,6 +25,10 @@ export function getQueryToken(location) {
|
||||
return qs.parse(location.search, {ignoreQueryPrefix: true}).token;
|
||||
}
|
||||
|
||||
export function getDebuggerTransactionHash(location) {
|
||||
return qs.parse(location.search, {ignoreQueryPrefix: true}).debuggerTransactionHash;
|
||||
}
|
||||
|
||||
export function stripQueryToken(location) {
|
||||
const _location = Object.assign({}, location);
|
||||
_location.search = _location.search.replace(
|
||||
|
@ -607,12 +607,8 @@ class BlockchainConnector {
|
||||
return this.web3.eth.net.getId();
|
||||
}
|
||||
|
||||
//TODO: fix me, why is this gasPrice??
|
||||
getTransaction(hash, cb) {
|
||||
const self = this;
|
||||
this.onReady(() => {
|
||||
self.web3.eth.getGasPrice(cb);
|
||||
});
|
||||
return this.web3.eth.getTransaction(hash, cb);
|
||||
}
|
||||
|
||||
ContractObject(params) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user