/ embark-ui / src / components / ContractTransactions.js
ContractTransactions.js
  1  import PropTypes from "prop-types";
  2  import React from 'react';
  3  import {Row, Col, Table, FormGroup, Label, Input, Form} from 'reactstrap';
  4  
  5  const TX_STATES = {Success: '0x1', Fail: '0x0', Any: ''};
  6  const EVENT = 'event';
  7  const FUNCTION = 'function';
  8  const CONSTRUCTOR = 'constructor';
  9  const PURE = 'pure';
 10  const VIEW = 'view';
 11  
 12  class ContractTransactions extends React.Component {
 13    constructor(props) {
 14      super(props);
 15      this.state = {method: '', event: '', status: TX_STATES['Any']};
 16    }
 17  
 18    getMethods() {
 19      if (!this.props.contract.abiDefinition) {
 20        return [];
 21      }
 22  
 23      return this.props.contract.abiDefinition.filter(method => (
 24        method.name !== CONSTRUCTOR && method.mutability !== VIEW && method.mutability !== PURE && method.constant !== true && method.type === FUNCTION
 25      ));
 26    }
 27  
 28    getEvents() {
 29      if (!this.props.contract.abiDefinition) {
 30        return [];
 31      }
 32      return this.props.contract.abiDefinition.filter(method => method.type === EVENT);
 33    }
 34  
 35    updateState(key, value) {
 36      this.setState({[key]: value});
 37    }
 38  
 39    dataToDisplay() {
 40      return this.props.contractLogs.map(contractLog => {
 41        const events = this.props.contractEvents
 42          .filter(contractEvent => contractEvent.transactionHash === contractLog.transactionHash)
 43          .map(contractEvent => contractEvent.event);
 44        contractLog.events = events;
 45        return contractLog;
 46      }).filter(contractLog => {
 47        if (this.state.status && contractLog.status !== this.state.status) {
 48          return false;
 49        }
 50  
 51        if (this.state.method || this.state.event) {
 52          return this.state.method === contractLog.functionName || contractLog.events.includes(this.state.event);
 53        }
 54  
 55        return true;
 56      });
 57    }
 58  
 59    render() {
 60      return (
 61        <React.Fragment>
 62          <Form>
 63            <Row>
 64              <Col md={6}>
 65                <FormGroup>
 66                  <Label htmlFor="functions">Functions</Label>
 67                  <Input type="select" name="functions" id="functions" onChange={(event) => this.updateState('method', event.target.value)} value={this.state.method}>
 68                    <option value=""></option>
 69                    {this.getMethods().map((method, index) => <option value={method.name} key={index}>{method.name}</option>)}
 70                  </Input>
 71                </FormGroup>
 72              </Col>
 73              <Col md={6}>
 74                <FormGroup>
 75                  <Label htmlFor="events">Events</Label>
 76                  <Input type="select" name="events" id="events" onChange={(event) => this.updateState('eveny', event.target.value)} value={this.state.event}>
 77                    <option value=""/>
 78                    {this.getEvents().map((event, index) => <option value={event.name} key={index}>{event.name}</option>)}
 79                  </Input>
 80                </FormGroup>
 81              </Col>
 82              <Col>
 83                <FormGroup row>
 84                  <Col md="3">
 85                    <Label>Tx Status</Label>
 86                  </Col>
 87                  <Col md="9">
 88                    {Object.keys(TX_STATES).map(key => (
 89                      <FormGroup key={key} check inline>
 90                        <Input className="form-check-input"
 91                              type="radio"
 92                              id={key}
 93                              name={key}
 94                              value={TX_STATES[key]}
 95                              onChange={(event) => this.updateState('status', event.target.value)}
 96                              checked={TX_STATES[key] === this.state.status} />
 97                        <Label check className="form-check-label" htmlFor={key}>{key}</Label>
 98                      </FormGroup>
 99                    ))}
100                  </Col>
101                </FormGroup>
102              </Col>
103            </Row>
104          </Form>
105          <Row>
106            <Col className="overflow-auto">
107              <Table>
108                <thead>
109                  <tr>
110                    <th>Call</th>
111                    <th>Events</th>
112                    <th>Gas Used</th>
113                    <th>Block number</th>
114                    <th>Status</th>
115                    <th>Transaction hash</th>
116                  </tr>
117                </thead>
118                <tbody>
119                  {
120                    this.dataToDisplay().map((log, index) => {
121                      return (
122                        <tr key={'log-' + index}>
123                          <td>{`${log.name}.${log.functionName}(${log.paramString})`}</td>
124                          <td>{log.events.join(', ')}</td>
125                          <td>{log.gasUsed}</td>
126                          <td>{log.blockNumber}</td>
127                          <td>{log.status}</td>
128                          <td>{log.transactionHash}</td>
129                        </tr>
130                      );
131                    })
132                  }
133                </tbody>
134              </Table>
135            </Col>
136          </Row>
137        </React.Fragment>
138      );
139    }
140  }
141  
142  ContractTransactions.propTypes = {
143    contractLogs: PropTypes.array,
144    contractEvents: PropTypes.array,
145    contract: PropTypes.object.isRequired
146  };
147  
148  export default ContractTransactions;
149