fix eslint on EVERYTHING

This commit is contained in:
Jonathan Rainville 2018-08-02 15:17:40 -04:00 committed by Pascal Precht
parent 0b6cb01a80
commit 4e7a0389bb
No known key found for this signature in database
GPG Key ID: 0EE28D8D6FD85D7D
29 changed files with 911 additions and 814 deletions

1
.eslintignore Normal file
View File

@ -0,0 +1 @@
lib/modules/webserver/backend/assets/*

View File

@ -67,7 +67,7 @@
],
"dot-notation": "off",
"eol-last": "error",
"eqeqeq": "off",
"eqeqeq": "error",
"for-direction": "error",
"func-call-spacing": "error",
"func-name-matching": "error",

View File

@ -31,7 +31,7 @@ class Dashboard {
plugin.registerAPICall(
'ws',
'/embark-api/dashboard',
(ws, req) => {
(ws, _req) => {
let dashboardState = {contractsState: [], environment: "", status: "", availableServices: []};
// TODO: doesn't feel quite right, should be refactored into a shared

View File

@ -3,7 +3,7 @@ import {NavLink, Route, Switch, withRouter} from 'react-router-dom';
import {
Page,
Grid,
List,
List
} from "tabler-react";
import AccountsContainer from '../containers/AccountsContainer';

View File

@ -20,7 +20,8 @@ const Transactions = ({transactions}) => (
{content: "From"},
{content: "To"},
{content: "Type"},
{content: "Hash"}]}
{content: "Hash"}
]}
bodyItems={
transactions.map((transaction) => {
return ([

View File

@ -11,7 +11,7 @@ class Scaffolding {
}
generate(contractName, contractConfiguration){
if(this.framework == 'react'){
if(this.framework === 'react'){
this.embark.plugins.loadInternalPlugin('scaffolding-react', this.options);
}
@ -19,7 +19,7 @@ class Scaffolding {
let build = null;
dappGenerators.forEach((plugin) => {
plugin.dappGenerators.forEach((d) => {
if(d.framework == this.framework){
if(d.framework === this.framework){
build = d.cb;
}
});

View File

@ -416,7 +416,7 @@ class ContractsManager {
let orderedDependencies;
try {
orderedDependencies = toposort(converted_dependencies.filter((x) => x[0] != x[1])).reverse();
orderedDependencies = toposort(converted_dependencies.filter((x) => x[0] !== x[1])).reverse();
} catch(e) {
this.logger.error((__("Error: ") + e.message).red);
this.logger.error(__("there are two or more contracts that depend on each other in a cyclic manner").bold.red);
@ -425,13 +425,11 @@ class ContractsManager {
//process.exit(0);
}
let newList = contractList.sort(function (a, b) {
return contractList.sort(function (a, b) {
let order_a = orderedDependencies.indexOf(a.className);
let order_b = orderedDependencies.indexOf(b.className);
return order_a - order_b;
});
return newList;
}
// TODO: should be built contracts

View File

@ -58,7 +58,7 @@ class GraphGenerator {
for (let i = 0; i < contract.abiDefinition.length; i++) {
let abiDef = contract.abiDefinition[i];
if (abiDef.type == 'event' && options.skipEvents) continue;
if (abiDef.type === 'event' && options.skipEvents) continue;
if (['constructor', 'fallback'].indexOf(abiDef.type) > -1 && options.skipFunctions) continue;
switch(abiDef.type){
@ -68,14 +68,14 @@ class GraphGenerator {
case 'constructor':
contractLabel += "«constructor»(";
abiDef.inputs.forEach(function(elem, index){
contractLabel += (index == 0 ? "" : ", ") + elem.type;
contractLabel += (index === 0 ? "" : ", ") + elem.type;
});
contractLabel += ")\\l";
break;
case 'event':
contractLabel += "«event»" + abiDef.name + "(";
abiDef.inputs.forEach(function(elem, index){
contractLabel += (index == 0 ? "" : ", ") + elem.type;
contractLabel += (index === 0 ? "" : ", ") + elem.type;
});
contractLabel += ")\\l";
break;
@ -84,7 +84,7 @@ class GraphGenerator {
}
let fHashes = contract.functionHashes;
if (fHashes != {} && fHashes != undefined && !options.skipFunctions){
if (fHashes !== {} && fHashes !== undefined && !options.skipFunctions){
for (let method in contract.functionHashes){
contractLabel += method + '\\l';
}

View File

@ -17,7 +17,7 @@ class Npm {
}
_isInstalling(packageName, version){
return typeof this._installing[packageName + version] != 'undefined';
return typeof this._installing[packageName + version] !== 'undefined';
}
getPackageVersion(packageName, version, callback) {

View File

@ -6,7 +6,7 @@ i18n.setOrDetectLocale('en');
class NpmTimer{
constructor(options){
this._logger = (options.logger && typeof options.logger.info == 'function') ? options.logger : console;
this._logger = (options.logger && typeof options.logger.info === 'function') ? options.logger : console;
this._packageName = options.packageName;
this._version = options.version;
this._showSpinner = options.showSpinner || false;
@ -24,7 +24,7 @@ class NpmTimer{
}
get observer(){
if(typeof this._observer == 'undefined'){
if(typeof this._observer === 'undefined'){
this._observer = new PerformanceObserver((items) => {
let entry;
let strDuration;

View File

@ -14,7 +14,7 @@ class ContractFuzzer {
generateFuzz(iterations, contract) {
const self = this;
let fuzzMap = {};
contract.abiDefinition.filter((x) => x.inputs && x.inputs.length != 0 && x.type != "event").forEach((abiMethod) => {
contract.abiDefinition.filter((x) => x.inputs && x.inputs.length !== 0 && x.type !== "event").forEach((abiMethod) => {
let name = abiMethod.type === "constructor" ? "constructor" : abiMethod.name;
let inputTypes = abiMethod.inputs.map(input => input.type);
fuzzMap[name] = {};
@ -48,7 +48,7 @@ class ContractFuzzer {
let length = arraySize === undefined || arraySize === null || arraySize === '' ? Math.floor((Math.random() * 256) + 1) : arraySize;
return self.generateArrayOfType(length, type);
}
case kind == "bool":
case kind === "bool":
return self.generateRandomBool();
case kind == "uint" || kind == "int":
return self.generateRandomInt(size || 256);

View File

@ -23,7 +23,7 @@ class GasEstimator {
// already provided for us
gasMap['constructor'] = contract.gasEstimates.creation.totalCost.toString();
return gasCb(null, name, abiMethod.type);
} else if (abiMethod.type == "fallback") {
} else if (abiMethod.type === "fallback") {
gasMap['fallback'] = contract.gasEstimates.external[""].toString();
return gasCb(null, name, abiMethod.type);
} else if (

View File

@ -7,7 +7,7 @@ Handlebars.registerHelper('capitalize', function(word) {
});
Handlebars.registerHelper('ifview', function(stateMutability, options) {
let result = stateMutability == 'view' || stateMutability == 'pure' || stateMutability == 'constant';
let result = stateMutability === 'view' || stateMutability === 'pure' || stateMutability === 'constant';
if (result) {
return options.fn(this);
}
@ -15,7 +15,7 @@ Handlebars.registerHelper('ifview', function(stateMutability, options) {
});
Handlebars.registerHelper('ifeq', function(elem, value, options){
if (elem == value) {
if (elem === value) {
return options.fn(this);
}
return options.inverse(this);
@ -34,8 +34,8 @@ Handlebars.registerHelper('emptyname', function(name, index) {
Handlebars.registerHelper('methodname', function(abiDefinition, functionName, inputs){
let funCount = abiDefinition.filter(x => x.name == functionName).length;
if(funCount == 1){
let funCount = abiDefinition.filter(x => x.name === functionName).length;
if(funCount === 1){
return '.' + functionName;
}
return new Handlebars.SafeString(`['${functionName}(${inputs !== null ? inputs.map(input => input.type).join(',') : ''})']`);
@ -73,7 +73,7 @@ class ScaffoldingReact {
});
}
async build(contract){
build(contract){
this._buildHTML(contract);
const filename = contract.className.toLowerCase();
@ -82,7 +82,7 @@ class ScaffoldingReact {
{
'title': contract.className,
'contractName': contract.className,
'functions': contract.abiDefinition.filter(x => x.type == 'function')
'functions': contract.abiDefinition.filter(x => x.type === 'function')
});
// Update config

View File

@ -22,7 +22,6 @@ class Solidity {
}
let self = this;
let input = {};
let solcW;
let originalFilepath = {};
async.waterfall([

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -1,3 +1,7 @@
import React from 'react';
import ContractContext from './contract-context';
import CardAlert from './card-alert';
class AccountList extends React.Component {
constructor(props) {
super(props);
@ -12,7 +16,7 @@ class AccountList extends React.Component {
}
async handleClick(e, updateAccountsCallback){
handleClick(e, updateAccountsCallback) {
e.preventDefault();
try {
@ -21,7 +25,7 @@ class AccountList extends React.Component {
this.setState({
error: true,
errorMessage: e.name + ': ' + e.message
})
});
}
}
@ -57,7 +61,8 @@ class AccountList extends React.Component {
</code>
</div>
<div className="col-md-1">
<button className="btn btn-primary ml-auto" onClick={event => this.handleClick(event, context.updateAccounts)}>&#9166;</button>
<button className="btn btn-primary ml-auto"
onClick={event => this.handleClick(event, context.updateAccounts)}>&#9166;</button>
</div>
</div>
<div className="card-footer">
@ -73,3 +78,5 @@ class AccountList extends React.Component {
</ContractContext.Consumer>;
}
}
export default AccountList;

View File

@ -1,13 +1,15 @@
import React from 'react';
import PropTypes from 'prop-types';
class CardAlert extends React.Component {
render() {
return this.props.show ?
<div className="card-alert alert alert-danger mb-0">
{this.props.message}
</div>
:
'';
return this.props.show ? <div className="card-alert alert alert-danger mb-0">{this.props.message}</div> : '';
}
}
CardAlert.propTypes = {
show: PropTypes.bool,
message: PropTypes.string
};
export default CardAlert;

View File

@ -1,7 +1,12 @@
import React from 'react';
const ContractContext = React.createContext({
accounts: [],
instances: [],
updateAccounts: () => {},
updateInstances: (_instance) => {}
updateAccounts: () => {
},
updateInstances: (_instance) => {
}
});
export default ContractContext;

View File

@ -1,3 +1,14 @@
/*global web3*/
import React from 'react';
import ContractContext from './contract-context';
import MenuItem from './menu-item';
import AccountList from './account-list';
import FunctionArea from './function-area';
import Tab from './tab';
import InstanceSelector from './instance-selector';
import SourceArea from './source-area';
import PropTypes from 'prop-types';
class ContractUI extends React.Component {
constructor(props) {
super(props);
@ -16,7 +27,7 @@ class ContractUI extends React.Component {
selectedTab: 'deploy'
};
if(props.contract.options.address != null){
if (props.contract.options.address !== null) {
this.state.instances = [props.contract.options.address];
this.state.selectedInstance = props.contract.options.address;
}
@ -54,7 +65,7 @@ class ContractUI extends React.Component {
this.props.contract.options.address = _instance;
this.setState({
selectedInstance: _instance
})
});
}
render() {
@ -65,9 +76,12 @@ class ContractUI extends React.Component {
<h3 className="page-title mb-5">{this.props.name}</h3>
<div>
<div className="list-group list-group-transparent mb-0">
<MenuItem icon="fe-file-plus" click={this.handleMenuClick} selectedTab={this.state.selectedTab} target="deploy" text="Deployment / Utils" />
<MenuItem icon="fe-list" click={this.handleMenuClick} selectedTab={this.state.selectedTab} target="functions" text="Functions" />
<MenuItem icon="fe-file-text" click={this.handleMenuClick} selectedTab={this.state.selectedTab} target="contract" text="Source Code" />
<MenuItem icon="fe-file-plus" click={this.handleMenuClick} selectedTab={this.state.selectedTab}
target="deploy" text="Deployment / Utils"/>
<MenuItem icon="fe-list" click={this.handleMenuClick} selectedTab={this.state.selectedTab}
target="functions" text="Functions"/>
<MenuItem icon="fe-file-text" click={this.handleMenuClick} selectedTab={this.state.selectedTab}
target="contract" text="Source Code"/>
</div>
</div>
</div>
@ -77,28 +91,29 @@ class ContractUI extends React.Component {
<div className="card">
<div className="card-body">
<ul>
<li>Open your browser's console: <code>Tools &gt; Developer Tools</code></li>
<li>Remix: <a href="https://remix.ethereum.org" target="_blank">http://remix.ethereum.org</a></li>
<li>Open your browser&apos;s console: <code>Tools &gt; Developer Tools</code></li>
<li>Remix: <a href="https://remix.ethereum.org" target="_blank" rel="noopener noreferrer">http://remix.ethereum.org</a></li>
</ul>
</div>
</div>
<AccountList accountUpdate={this.updateAccounts}/>
<h5>Deploy</h5>
{
this.props.definition.code == "" ? <p>Interface or set to not deploy</p>: ""
this.props.definition.code === "" ? <p>Interface or set to not deploy</p> : ""
}
<FunctionArea definition={this.props.definition} contractName={this.props.name} contract={this.props.contract} type="constructor" />
<FunctionArea definition={this.props.definition} contractName={this.props.name}
contract={this.props.contract} type="constructor"/>
</Tab>
<Tab id="functions" selectedTab={this.state.selectedTab}>
<h4 className="mb-5">Functions</h4>
{
this.props.definition.code != "" ?
<InstanceSelector selectedInstance={this.state.selectedInstance} instanceUpdate={this.handleInstanceSelection} />
: ""
{(this.props.definition.code !== "") && <InstanceSelector selectedInstance={this.state.selectedInstance}
instanceUpdate={this.handleInstanceSelection}/>
}
<FunctionArea definition={this.props.definition} contractName={this.props.name} contract={this.props.contract} type="function" />
<FunctionArea definition={this.props.definition} contractName={this.props.name} contract={this.props.contract} type="fallback" />
<FunctionArea definition={this.props.definition} contractName={this.props.name}
contract={this.props.contract} type="function"/>
<FunctionArea definition={this.props.definition} contractName={this.props.name}
contract={this.props.contract} type="fallback"/>
</Tab>
<Tab id="contract" selectedTab={this.state.selectedTab}>
@ -106,28 +121,21 @@ class ContractUI extends React.Component {
<SourceArea definition={this.props.definition} source={this.props.source}/>
</Tab>
</div>
</div>,
</div>
,
</ContractContext.Provider>
)
);
}
}
ContractUI.propTypes = {
definition: PropTypes.object,
source: PropTypes.string,
contract: PropTypes.object,
name: PropTypes.string
};
export default ContractUI;

View File

@ -1,3 +1,7 @@
import React from 'react';
import FunctionForm from './function-form';
import PropTypes from 'prop-types';
class FunctionArea extends React.Component {
constructor(props) {
super(props);
@ -12,9 +16,21 @@ class FunctionArea extends React.Component {
return <React.Fragment>
{
this.props.contract.options.jsonInterface
.filter(item => item.type == type)
.map((item, i) => <FunctionForm definition={this.props.definition} key={i} contract={contract} contractName={contractName} abi={item} instanceUpdate={this.props.instanceUpdate} />)
.filter(item => item.type === type)
.map((item, i) => <FunctionForm definition={this.props.definition} key={i} contract={contract}
contractName={contractName} abi={item}
instanceUpdate={this.props.instanceUpdate}/>)
}
</React.Fragment>;
}
}
FunctionArea.propTypes = {
type: PropTypes.string,
contract: PropTypes.object,
contractName: PropTypes.string,
definition: PropTypes.object,
instanceUpdate: PropTypes.func
};
export default FunctionArea;

View File

@ -1,3 +1,8 @@
import React from 'react';
import CardAlert from './card-alert';
import Function from './function';
import PropTypes from 'prop-types';
class FunctionForm extends React.Component {
constructor(props) {
super(props);
@ -18,28 +23,107 @@ class FunctionForm extends React.Component {
this.child.current.copyCommand(e);
}
_getFunctionParamFields(elem){
if(this.props.abi.type == 'fallback') return '';
_getFunctionParamFields(_elem) {
if (this.props.abi.type === 'fallback') return '';
return '(' + this.props.abi.inputs
.map((input, i) => <input type="text" data-var-type={input.type} data-type="inputParam" data-name={input.name} placeholder={input.name} title={input.type + ' ' + input.name} size={input.name.length} />)
.map((input, i) => <input type="text" data-var-type={input.type} data-type="inputParam" data-name={input.name}
placeholder={input.name} title={input.type + ' ' + input.name}
size={input.name.length}
key={'input' + i}/>)
.join(', ') + ')';
}
_getMethodType(elem){
return (this.props.abi.constant == true || this.props.abi.stateMutability == 'view' || this.props.abi.stateMutability == 'pure') ? 'call' : 'send';
_getMethodType(_elem) {
return (this.props.abi.constant === true || this.props.abi.stateMutability === 'view' || this.props.abi.stateMutability === 'pure') ? 'call' : 'send';
}
renderContent(receipt, contract) {
if (receipt === null && (this.state.error || this.state.message === null)) {
return '';
}
let messagesList;
if (this.props.abi.outputs.filter(x => x.name !== "").length > 0) {
messagesList = Object.keys(this.state.message).map((key, index) => {
if (isNaN(key)) {
return <li key={index}>{key}: {this.state.message[key]}</li>;
} else {
return '';
}
});
} else {
messagesList = Object.keys(this.state.message).map((key, index) => {
return <li key={index}>{key}: {this.state.message[key]}</li>;
});
}
let message;
if (this.state.message !== null && typeof this.state.message === 'object') {
message = <ul>
{messagesList}
</ul>;
} else if (typeof this.state.message === "boolean") {
message = (this.state.message ? 'true' : 'false');
} else {
message = this.state.message;
}
return (<div className="card-footer">
{receipt && <ul>
<li>Status: {receipt.status}</li>
<li>Transaction Hash: {receipt.transactionHash}</li>
{
receipt.events && <li>Events:
<ul>
{
Object.keys(receipt.events).map(function(ev, index) {
if (!isNaN(ev)) return null;
const eventAbi = contract.options.jsonInterface.filter(x => x.name === ev)[0];
let props = [];
for (let prop in receipt.events[ev].returnValues) {
if (isNaN(prop)) {
let input = eventAbi.inputs.filter(x => x.name === prop)[0];
props.push(prop + ': ' +
(input.type.indexOf('int') === -1 ? '"' : '') +
receipt.events[ev].returnValues[prop] +
(input.type.indexOf('int') === -1 ? '"' : ''));
}
}
return <li key={index}>{ev}({props.join(', ')})</li>;
})
}
</ul>
</li>
}
</ul>
}
{
!this.state.error && this.state.message && <React.Fragment>
{message}
</React.Fragment>}
</div>);
}
render() {
const functionName = this.props.abi.name;
const isDuplicated = this.props.contract.options.jsonInterface.filter(x => x.name == functionName).length > 1;
const isDuplicated = this.props.contract.options.jsonInterface.filter(x => x.name === functionName).length > 1;
const contract = this.props.contract;
const receipt = this.state.receipt;
let title;
if (this.props.abi.type === 'function') {
title = this.props.abi.name;
} else if (this.props.abi.type === 'fallback') {
title = '(fallback)';
} else {
title = this.props.abi.name;
}
return <div className="card function">
<div className="card-header">
<h3 className="card-title">{this.props.abi.type == 'function' ? this.props.abi.name : (this.props.abi.type == 'fallback' ? '(fallback)' : this.props.abi.name)}</h3>
<h3
className="card-title">{title}</h3>
<div className="card-options">
<a href="#" onClick={this.handleCopyClick} title="Copy to clipboard"><i className="fe fe-copy"></i></a>
</div>
@ -48,81 +132,11 @@ class FunctionForm extends React.Component {
<CardAlert show={this.state.error} message={this.state.message}/>
<div className="card-body row">
<Function ref={this.child} definition={this.props.definition} contract={this.props.contract} contractName={this.props.contractName} duplicated={isDuplicated} abi={this.props.abi} resultHandler={this.showResults} />
<Function ref={this.child} definition={this.props.definition} contract={this.props.contract}
contractName={this.props.contractName} duplicated={isDuplicated} abi={this.props.abi}
resultHandler={this.showResults}/>
</div>
{
receipt != null || !this.state.error && this.state.message != null
?
<div className="card-footer">
{ receipt != null ?
<ul>
<li>Status: {receipt.status}</li>
<li>Transaction Hash: {receipt.transactionHash}</li>
{
receipt.events != null ?
<li>Events:
<ul>
{
Object.keys(receipt.events).map(function(ev, index) {
if(!isNaN(ev)) return null;
const eventAbi = contract.options.jsonInterface.filter(x => x.name == ev)[0];
let props = [];
for(let prop in receipt.events[ev].returnValues){
if(isNaN(prop)){
let input = eventAbi.inputs.filter(x => x.name == prop)[0];
props.push(prop + ': '
+ (input.type.indexOf('int') == -1 ? '"' : '')
+ receipt.events[ev].returnValues[prop]
+ (input.type.indexOf('int') == -1 ? '"' : ''));
}
}
return <li key={index}>{ev}({props.join(', ')})</li>;
})
}
</ul>
</li>
: ''
}
</ul>
: ""
}
{
!this.state.error && this.state.message != null
?
<React.Fragment>{
(this.state.message !== null && typeof this.state.message === 'object')
?
(
<ul>
{
this.props.abi.outputs.filter(x => x.name !== "").length > 0
?
Object.keys(this.state.message).map((key, index) => {
if(isNaN(key)){
return <li key={index}>{key}: {this.state.message[key]}</li>
} else {
return '';
}
})
:
Object.keys(this.state.message).map((key, index) => {
return <li key={index}>{key}: {this.state.message[key]}</li>
})
}
</ul>
)
:
(typeof this.state.message === "boolean" ?
(this.state.message ? 'true' : 'false')
:
this.state.message)
}</React.Fragment>
: '' }
</div>
: ''
}
{this.renderContent(receipt, contract)}
</div>;
}
@ -131,6 +145,15 @@ class FunctionForm extends React.Component {
error: _error,
message: _message,
receipt: _receipt
})
});
}
}
FunctionForm.propTypes = {
abi: PropTypes.object,
contract: PropTypes.object,
definition: PropTypes.object,
contractName: PropTypes.string
};
export default FunctionForm;

View File

@ -1,3 +1,8 @@
/*global web3*/
import React from 'react';
import ContractContext from './contract-context';
import PropTypes from 'prop-types';
class Function extends React.Component {
constructor(props) {
@ -24,15 +29,12 @@ class Function extends React.Component {
copyCommand(e) {
e.preventDefault();
let fields = this.state.fields;
let functionLabel = this._getFunctionLabel();
let functionParams = this._getFunctionParamString();
let methodParams = this._getMethodString();
if(this.props.abi.type == "constructor")
functionParams = `{arguments: [${functionParams}]}`;
if (this.props.abi.type === "constructor") functionParams = `{arguments: [${functionParams}]}`;
const command = `await ${functionLabel}(${functionParams})${this.props.abi.type != 'fallback' ? '.' + this._getMethodType() : ''}${methodParams}`;
const command = `await ${functionLabel}(${functionParams})${this.props.abi.type !== 'fallback' ? '.' + this._getMethodType() : ''}${methodParams}`;
var dummy = document.createElement("input");
document.body.appendChild(dummy);
@ -43,7 +45,6 @@ class Function extends React.Component {
}
async handleClick(e, instanceUpdateCallback) {
e.preventDefault();
@ -54,12 +55,11 @@ class Function extends React.Component {
let executionParams = {
from: this.state.methodFields.from,
gasLimit: this.state.methodFields.gasLimit
}
};
if(this.props.abi.payable)
executionParams.value = this.state.methodFields.value;
if (this.props.abi.payable) executionParams.value = this.state.methodFields.value;
if(this.props.abi.type == 'fallback'){
if (this.props.abi.type === 'fallback') {
executionParams.data = this.state.methodFields.data;
executionParams.to = this.props.contract.options.address;
}
@ -69,15 +69,14 @@ class Function extends React.Component {
let functionLabel = this._getFunctionLabel();
let functionParams = this._getFunctionParamString();
let methodParams = this._getMethodString();
if(this.props.abi.type == "constructor")
functionParams = `{arguments: [${functionParams}]}`;
if (this.props.abi.type === "constructor") functionParams = `{arguments: [${functionParams}]}`;
console.log(`%cawait ${functionLabel}(${functionParams})${this.props.abi.type != 'fallback' ? '.' + this._getMethodType() : ''}${methodParams}`, 'font-weight: bold');
console.log(`%cawait ${functionLabel}(${functionParams})${this.props.abi.type !== 'fallback' ? '.' + this._getMethodType() : ''}${methodParams}`, 'font-weight: bold');
let _receipt;
try {
if(this.props.abi.type == 'constructor'){
if (this.props.abi.type === 'constructor') {
let contractInstance = await this.props.contract.deploy({arguments: Object.keys(fields).map(val => fields[val])}).send(executionParams);
instanceUpdateCallback(contractInstance.options.address);
this.setState({onRequest: false});
@ -85,18 +84,15 @@ class Function extends React.Component {
this.props.resultHandler(false, 'New instance: ' + contractInstance.options.address);
} else {
if(this.props.abi.type == 'fallback')
_receipt = await web3.eth.sendTransaction(executionParams);
else
_receipt = await this.props.contract
if (this.props.abi.type === 'fallback') _receipt = await web3.eth.sendTransaction(executionParams);
else _receipt = await this.props.contract
.methods[this.props.abi.name + '(' + this.props.abi.inputs.map(input => input.type).join(',') + ')']
.apply(null, Object.keys(fields).map(val => {
let input = this.props.abi.inputs.filter(x => x.name == val)[0];
return input.type.indexOf('bool') == -1 ? fields[val] : (fields[val].toLowerCase() === 'true')
}))
[this._getMethodType()](executionParams)
let input = this.props.abi.inputs.filter(x => x.name === val)[0];
return input.type.indexOf('bool') === -1 ? fields[val] : (fields[val].toLowerCase() === 'true');
}))[this._getMethodType()](executionParams);
if(this._getMethodType() == 'call'){
if (this._getMethodType() === 'call') {
this.props.resultHandler(false, _receipt, null);
} else {
this.props.resultHandler(false, null, _receipt);
@ -107,10 +103,10 @@ class Function extends React.Component {
}
} catch (e) {
console.error('%s: %s', e.name, e.message);
} catch (err) {
console.error('%s: %s', err.name, err.message);
this.setState({onRequest: false});
this.props.resultHandler(true, e.name + ": " + e.message, _receipt);
this.props.resultHandler(true, err.name + ": " + err.message, _receipt);
}
}
@ -124,34 +120,31 @@ class Function extends React.Component {
let newState = this.state;
newState.methodFields[e.target.getAttribute('data-param')] = e.target.value;
if(e.target.getAttribute('data-param') == 'from'){
if (e.target.getAttribute('data-param') === 'from') {
newState.selectedAccount = e.target.options[e.target.selectedIndex].text;
}
this.setState(newState);
}
_getFunctionLabel() {
if(this.props.abi.type == 'function')
if(!this.props.duplicated)
return `${this.props.contractName}.methods.${this.props.abi.name}`;
if (this.props.abi.type === 'function') if (!this.props.duplicated) return `${this.props.contractName}.methods.${this.props.abi.name}`;
else {
return `${this.props.contractName}.methods['${this.props.abi.name + '(' + (this.props.abi.inputs != null ? this.props.abi.inputs.map(input => input.type).join(',') : '') + ')'}']`;
return `${this.props.contractName}.methods['${this.props.abi.name + '(' + (this.props.abi.inputs !== null ? this.props.abi.inputs.map(input => input.type).join(',') : '') + ')'}']`;
}
else if(this.props.abi.type == 'fallback'){
else if (this.props.abi.type === 'fallback') {
return `web3.eth.sendTransaction`;
}
else
return `${this.props.contractName}.deploy`;
else return `${this.props.contractName}.deploy`;
}
_getMethodType() {
return (this.props.abi.constant == true || this.props.abi.stateMutability == 'view' || this.props.abi.stateMutability == 'pure') ? 'call' : 'send';
return (this.props.abi.constant === true || this.props.abi.stateMutability === 'view' || this.props.abi.stateMutability === 'pure') ? 'call' : 'send';
}
_getMethodFields(accounts) {
let methodParams;
return <React.Fragment>
from: <select data-param="from" disabled={accounts.length == 0} value={this.state.from} onChange={this.handleMethodFieldChange}>
from: <select data-param="from" disabled={accounts.length === 0} value={this.state.from}
onChange={this.handleMethodFieldChange}>
<option>-</option>
{
accounts.map(function(item, i) {
@ -159,27 +152,22 @@ class Function extends React.Component {
})
}
</select>
{
this.props.abi.payable ?
{this.props.abi.payable &&
<span>, value:
<input type="text" data-param="value" value={this.state.methodFields.value} size="6" onChange={this.handleMethodFieldChange} />
<input type="text" data-param="value" value={this.state.methodFields.value} size="6"
onChange={this.handleMethodFieldChange}/>
</span>
: ''
}
{
this._getMethodType() == 'send' ?
{this._getMethodType() === 'send' &&
<span>, gasLimit:
<input type="text" data-param="gasLimit" value={this.state.methodFields.gasLimit} size="6" onChange={this.handleMethodFieldChange} />
</span>
: ''
}
{
this._getMethodType() == 'send' && this.props.abi.type == 'fallback' ?
<input type="text" data-param="gasLimit" value={this.state.methodFields.gasLimit} size="6"
onChange={this.handleMethodFieldChange}/>
</span>}
{this._getMethodType() === 'send' && this.props.abi.type === 'fallback' &&
<span>, data:
<input type="text" data-param="data" value={this.state.methodFields.data} size="6" onChange={this.handleMethodFieldChange} />
</span>
: ''
}
<input type="text" data-param="data" value={this.state.methodFields.data} size="6"
onChange={this.handleMethodFieldChange}/>
</span>}
</React.Fragment>;
}
@ -188,32 +176,35 @@ class Function extends React.Component {
return <React.Fragment>
{
this.props.abi.inputs
.map((input, i) => <input key={i} type="text" data-var-type={input.type} data-type="inputParam" data-name={input.name} placeholder={input.name} title={input.type + ' ' + input.name} size={input.name.length} value={this.state.fields[input.name] || ''} onChange={this.handleParameterChange} />)
.map((input, i) => <input key={i} type="text" data-var-type={input.type} data-type="inputParam"
data-name={input.name} placeholder={input.name}
title={input.type + ' ' + input.name} size={input.name.length}
value={this.state.fields[input.name] || ''} onChange={this.handleParameterChange}/>)
.reduce((accu, elem) => {
return accu === null ? [elem] : [...accu, ', ', elem]
return accu === null ? [elem] : [...accu, ', ', elem];
}, null)
}
</React.Fragment>;
}
_getFunctionParamString() {
if(this.props.abi.type == 'fallback') return '';
if (this.props.abi.type === 'fallback') return '';
return this.props.abi.inputs
.map((input, i) => (input.type.indexOf('int') == -1 && input.type.indexOf('bool') == -1 ? '"' : '') + (this.state.fields[input.name] || (input.type.indexOf('int') == -1 ? '' : '0')) + (input.type.indexOf('int') == -1 ? '"' : ''))
.map((input, _i) => (input.type.indexOf('int') === -1 && input.type.indexOf('bool') === -1 ? '"' : '') + (this.state.fields[input.name] || (input.type.indexOf('int') === -1 ? '' : '0')) + (input.type.indexOf('int') === -1 ? '"' : ''))
.join(', ');
}
_getMethodString(elem){
_getMethodString(_elem) {
let methodParams = "({";
methodParams += `from: ` + (this.state.selectedAccount || '"0x00"');
if(this._getMethodType() == 'send'){
methodParams += ', gasLimit: ' + (this.state.methodFields.gasLimit || 0)
if (this._getMethodType() === 'send') {
methodParams += ', gasLimit: ' + (this.state.methodFields.gasLimit || 0);
if (this.props.abi.payable) {
methodParams += ', value: ' + (this.state.methodFields.value || 0)
methodParams += ', value: ' + (this.state.methodFields.value || 0);
}
if(this.props.abi.type == 'fallback'){
methodParams += ', data: "' + (this.state.methodFields.data || '"0x00"' ) + '", to: "' + (this.state.methodFields.to || '"0x00"') + '"'
if (this.props.abi.type === 'fallback') {
methodParams += ', data: "' + (this.state.methodFields.data || '"0x00"') + '", to: "' + (this.state.methodFields.to || '"0x00"') + '"';
}
}
return methodParams + "})";
@ -228,45 +219,53 @@ class Function extends React.Component {
disabled = true;
}
if(this.props.definition.code == ""){
if (this.props.definition.code === "") {
btnClass += "btn-secondary";
disabled = true;
} else {
btnClass += "btn-primary";
}
let requestResult;
if (this.state.onRequest) {
requestResult = <img src="../assets/images/loading.gif" className="loading" alt=""/>;
} else {
requestResult = this.props.definition.code === "" ? <React.Fragment>_</React.Fragment>: <React.Fragment>&#9166;</React.Fragment>;
}
return <ContractContext.Consumer>
{(context) => (
<React.Fragment>
<div className="col-md-11">
<code>
await {this._getFunctionLabel()}
{ this.props.abi.type != 'fallback' ? '(' : '' }
{ this.props.abi.type != 'fallback' ? this._getFunctionParamFields() : '' }
{ this.props.abi.type != 'fallback' ? ')' : '' }
{ this.props.abi.type != 'fallback' ? '.' + this._getMethodType() : '' }
{this.props.abi.type !== 'fallback' ? '(' : ''}
{this.props.abi.type !== 'fallback' ? this._getFunctionParamFields() : ''}
{this.props.abi.type !== 'fallback' ? ')' : ''}
{this.props.abi.type !== 'fallback' ? '.' + this._getMethodType() : ''}
({this._getMethodFields(context.accounts)})
</code>
</div>
<div className="col-md-1">
<button className={btnClass} title={this.props.definition.code == "" ? "Can't execute function" : "Execute function"} onClick={event => this.handleClick(event, context.updateInstances)} disabled={disabled}>
{ this.state.onRequest ?
<img src="../assets/images/loading.gif" className="loading" alt="" />
:
(
this.props.definition.code == ""
?
<React.Fragment>_</React.Fragment>
:
<React.Fragment>&#9166;</React.Fragment>
)
}
<button className={btnClass}
title={this.props.definition.code === "" ? "Can't execute function" : "Execute function"}
onClick={event => this.handleClick(event, context.updateInstances)} disabled={disabled}>
{requestResult}
</button>
</div>
</React.Fragment>
)}
</ContractContext.Consumer>;
}
}
Function.propTypes = {
definition: PropTypes.object,
abi: PropTypes.object,
contract: PropTypes.object,
resultHandler: PropTypes.func,
duplicated: PropTypes.bool,
contractName: PropTypes.string
};
export default Function;

View File

@ -1,3 +1,7 @@
import React from 'react';
import ContractContext from './contract-context';
import PropTypes from 'prop-types';
class InstanceSelector extends React.Component {
constructor(props) {
@ -32,13 +36,13 @@ class InstanceSelector extends React.Component {
e.preventDefault();
let instance;
if(this.state.selectedInstance == "custom"){
if (this.state.selectedInstance === "custom") {
instance = this.state.customInstance;
} else {
instance = this.state.selectedInstance;
}
if(!/^0x[0-9a-f]{40}$/i.test(instance)){
if (!(/^0x[0-9a-f]{40}$/i).test(instance)) {
this.setState({error: true, errorMessage: 'Not a valid Ethereum address.'});
console.log(this.state.errorMessage);
return;
@ -52,54 +56,47 @@ class InstanceSelector extends React.Component {
showInstances: false,
showCustomAddressField: false,
selectedInstance: instance,
customInstance: this.state.selectedInstance == "custom" ? this.state.customInstance : ""
})
customInstance: this.state.selectedInstance === "custom" ? this.state.customInstance : ""
});
}
handleChange(e) {
this.setState({
showCustomAddressField: e.target.value == "custom",
showCustomAddressField: e.target.value === "custom",
selectedInstance: e.target.value
});
}
render() {
let showInstance;
if (!this.state.showInstances) {
showInstance = <a href="#" className="btn btn-primary btn-sm" onClick={this.handleShowInstances}>Change</a>;
} else {
showInstance = <a href="#" className="btn btn-secondary btn-sm" onClick={this.handleShowInstances}>Cancel</a>;
}
return <ContractContext.Consumer>
{(context) => (<div className="contractSelection">
<div className="card">
<div className="card-header">
<h3 className="card-title">
Instance Selected: <b>{this.props.selectedInstance != null ? this.props.selectedInstance : 'none'}</b>
Instance Selected: <b>{this.props.selectedInstance !== null ? this.props.selectedInstance : 'none'}</b>
</h3>
<div className="card-options">
{
!this.state.showInstances
?
<a href="#" className="btn btn-primary btn-sm" onClick={this.handleShowInstances}>Change</a>
:
<a href="#" className="btn btn-secondary btn-sm" onClick={this.handleShowInstances}>Cancel</a>
}
{showInstance}
</div>
</div>
{
this.state.showInstances ?
<React.Fragment>
this.state.showInstances && <React.Fragment>
{
this.state.error
?
<div className="card-alert alert alert-danger mb-0">
this.state.error && <div className="card-alert alert alert-danger mb-0">
{this.state.errorMessage}
</div>
:
''
}
<div className="card-body">
<div className="form-group control-group error">
<select className="form-control" id="contracts" value={this.state.selectedInstance} onChange={this.handleChange}>
<select className="form-control" id="contracts" value={this.state.selectedInstance}
onChange={this.handleChange}>
<option value="custom">Specific contract address</option>
{
context.instances.map(function(item, i) {
@ -108,9 +105,9 @@ class InstanceSelector extends React.Component {
}
</select>
{
this.state.showCustomAddressField ?
<input type="text" className="form-control" id="specificAddress" onChange={this.handleTextChange} placeholder="0x" />
: ''
this.state.showCustomAddressField &&
<input type="text" className="form-control" id="specificAddress"
onChange={this.handleTextChange} placeholder="0x"/>
}
</div>
</div>
@ -118,13 +115,17 @@ class InstanceSelector extends React.Component {
<button className="btn btn-primary" onClick={this.handleClick}>Change</button>
</div>
</React.Fragment>
:
''
}
</div>
</div>
)}
</ContractContext.Consumer>;
}
}
InstanceSelector.propTypes = {
instanceUpdate: PropTypes.func,
selectedInstance: PropTypes.string
};
export default InstanceSelector;

View File

@ -1,9 +1,12 @@
import React from 'react';
import PropTypes from 'prop-types';
class MenuItem extends React.Component {
render() {
let classNames = "list-group-item list-group-item-action d-flex align-items-center ";
let icon = "fe " + this.props.icon;
if(this.props.target == this.props.selectedTab){
if (this.props.target === this.props.selectedTab) {
classNames += "active";
}
@ -12,3 +15,13 @@ class MenuItem extends React.Component {
</a>;
}
}
MenuItem.propTypes = {
icon: PropTypes.string,
target: PropTypes.string,
selectedTab: PropTypes.string,
text: PropTypes.string,
click: PropTypes.func
};
export default MenuItem;

View File

@ -1,3 +1,7 @@
/*global hljs*/
import React from 'react';
import PropTypes from 'prop-types';
class SourceArea extends React.Component {
constructor(props) {
super(props);
@ -25,3 +29,10 @@ class SourceArea extends React.Component {
</div>;
}
}
SourceArea.propTypes = {
definition: PropTypes.object,
source: PropTypes.string
};
export default SourceArea;

View File

@ -1,13 +1,20 @@
import React from 'react';
import PropTypes from 'prop-types';
class Tab extends React.Component {
render() {
return (
this.props.selectedTab == this.props.id
?
<div id={this.props.id}>
this.props.selectedTab === this.props.id && <div id={this.props.id}>
{this.props.children}
</div>
:
''
);
}
}
Tab.propTypes = {
selectedTab: PropTypes.string,
id: PropTypes.string,
children: PropTypes.element
};
export default Tab;

View File

@ -1,3 +1,7 @@
/*global Web3*/
import React from 'react';
import ReactDOM from 'react-dom';
import ContractUI from './components/contract-ui';
const contractName = location.search.replace(/\?/, '');
@ -31,7 +35,8 @@ fetch("/embark/console", {
window[contractDefinition.className] = contractObj;
ReactDOM.render(
<ContractUI name={contractDefinition.className} definition={contractDefinition} contract={contractObj} source={contractSource} />,
<ContractUI name={contractDefinition.className} definition={contractDefinition} contract={contractObj}
source={contractSource}/>,
document.getElementById('contracts-area')
);
})
@ -42,7 +47,8 @@ fetch("/embark/console", {
ReactDOM.render(
<div>
<h1 className="h2 mb-3">Error rendering the UI</h1>
<p className="h4 text-muted font-weight-normal mb-7">UI for "{contractName}" cannot be generated</p>
<p className="h4 text-muted font-weight-normal mb-7">UI for &quot;&lbrace;contractName&rbrace;&quot; cannot be
generated</p>
</div>,
document.getElementById('contracts-area')
);