WIP refacto typed input
This commit is contained in:
parent
529633e9b2
commit
cd143e475a
@ -16,12 +16,124 @@
|
|||||||
|
|
||||||
import React, { Component, PropTypes } from 'react';
|
import React, { Component, PropTypes } from 'react';
|
||||||
import { MenuItem } from 'material-ui';
|
import { MenuItem } from 'material-ui';
|
||||||
|
import { range } from 'lodash';
|
||||||
|
|
||||||
import { AddressSelect, Form, Input, InputAddressSelect, Select } from '../../../ui';
|
import { AddressSelect, Form, Input, InputAddressSelect, Select } from '../../../ui';
|
||||||
import { validateAbi } from '../../../util/validation';
|
import { validateAbi } from '../../../util/validation';
|
||||||
|
|
||||||
import styles from '../deployContract.css';
|
import styles from '../deployContract.css';
|
||||||
|
|
||||||
|
class TypedInput extends Component {
|
||||||
|
|
||||||
|
static propTypes = {
|
||||||
|
onChange: PropTypes.func.isRequired,
|
||||||
|
accounts: PropTypes.object.isRequired,
|
||||||
|
type: PropTypes.string.isRequired,
|
||||||
|
|
||||||
|
error: PropTypes.any,
|
||||||
|
value: PropTypes.any,
|
||||||
|
label: PropTypes.string
|
||||||
|
};
|
||||||
|
|
||||||
|
render () {
|
||||||
|
const { type } = this.props;
|
||||||
|
|
||||||
|
const arrayRegex = /^(.+)\[(\d*)\]$/;
|
||||||
|
|
||||||
|
if (arrayRegex.test(type)) {
|
||||||
|
const matches = arrayRegex.exec(type);
|
||||||
|
return this.renderArray(matches[1], matches[2] || Infinity);
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (type) {
|
||||||
|
case 'address':
|
||||||
|
return this.renderAddress();
|
||||||
|
|
||||||
|
case 'bool':
|
||||||
|
return this.renderBoolean();
|
||||||
|
|
||||||
|
default:
|
||||||
|
return this.renderDefault();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
renderArray (type, max) {
|
||||||
|
const { label, value, error } = this.props;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
renderDefault () {
|
||||||
|
const { label, value, error } = this.props;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Input
|
||||||
|
label={ label }
|
||||||
|
value={ value }
|
||||||
|
error={ error }
|
||||||
|
onSubmit={ this.onSubmit }
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
renderAddress () {
|
||||||
|
const { accounts, label, value, error } = this.props;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<InputAddressSelect
|
||||||
|
accounts={ accounts }
|
||||||
|
label={ label }
|
||||||
|
value={ value }
|
||||||
|
error={ error }
|
||||||
|
onChange={ this.onChange }
|
||||||
|
editing
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
renderBoolean () {
|
||||||
|
const { label, value, error } = this.props;
|
||||||
|
|
||||||
|
const boolitems = ['false', 'true'].map((bool) => {
|
||||||
|
return (
|
||||||
|
<MenuItem
|
||||||
|
key={ bool }
|
||||||
|
value={ bool }
|
||||||
|
label={ bool }
|
||||||
|
>
|
||||||
|
{ bool }
|
||||||
|
</MenuItem>
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Select
|
||||||
|
label={ label }
|
||||||
|
value={ value ? 'true' : 'false' }
|
||||||
|
error={ error }
|
||||||
|
onChange={ this.onChangeBool }
|
||||||
|
>
|
||||||
|
{ boolitems }
|
||||||
|
</Select>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
onChangeBool = (event, _index, value) => {
|
||||||
|
this.props.onChange(value === 'true');
|
||||||
|
}
|
||||||
|
|
||||||
|
onChange = (event, value) => {
|
||||||
|
this.props.onChange(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
onSubmit = (value) => {
|
||||||
|
this.props.onChange(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
export default class DetailsStep extends Component {
|
export default class DetailsStep extends Component {
|
||||||
static contextTypes = {
|
static contextTypes = {
|
||||||
api: PropTypes.object.isRequired
|
api: PropTypes.object.isRequired
|
||||||
@ -98,59 +210,22 @@ export default class DetailsStep extends Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return inputs.map((input, index) => {
|
return inputs.map((input, index) => {
|
||||||
const onChange = (event, value) => this.onParamChange(index, value);
|
const onChange = (value) => this.onParamChange(index, value);
|
||||||
const onChangeBool = (event, _index, value) => this.onParamChange(index, value === 'true');
|
|
||||||
const onSubmit = (value) => this.onParamChange(index, value);
|
|
||||||
const label = `${input.name}: ${input.type}`;
|
|
||||||
let inputBox = null;
|
|
||||||
|
|
||||||
switch (input.type) {
|
const label = `${input.name ? `${input.name}: ` : ''}${input.type}`;
|
||||||
case 'address':
|
const value = params[index];
|
||||||
inputBox = (
|
const error = paramsError[index];
|
||||||
<InputAddressSelect
|
|
||||||
accounts={ accounts }
|
|
||||||
editing
|
|
||||||
label={ label }
|
|
||||||
value={ params[index] }
|
|
||||||
error={ paramsError[index] }
|
|
||||||
onChange={ onChange } />
|
|
||||||
);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 'bool':
|
|
||||||
const boolitems = ['false', 'true'].map((bool) => {
|
|
||||||
return (
|
|
||||||
<MenuItem
|
|
||||||
key={ bool }
|
|
||||||
value={ bool }
|
|
||||||
label={ bool }>{ bool }</MenuItem>
|
|
||||||
);
|
|
||||||
});
|
|
||||||
inputBox = (
|
|
||||||
<Select
|
|
||||||
label={ label }
|
|
||||||
value={ params[index] ? 'true' : 'false' }
|
|
||||||
error={ paramsError[index] }
|
|
||||||
onChange={ onChangeBool }>
|
|
||||||
{ boolitems }
|
|
||||||
</Select>
|
|
||||||
);
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
inputBox = (
|
|
||||||
<Input
|
|
||||||
label={ label }
|
|
||||||
value={ params[index] }
|
|
||||||
error={ paramsError[index] }
|
|
||||||
onSubmit={ onSubmit } />
|
|
||||||
);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div key={ index } className={ styles.funcparams }>
|
<div key={ index } className={ styles.funcparams }>
|
||||||
{ inputBox }
|
<TypedInput
|
||||||
|
label={ label }
|
||||||
|
value={ value }
|
||||||
|
error={ error }
|
||||||
|
accounts={ accounts }
|
||||||
|
onChange={ onChange }
|
||||||
|
type={ input.type }
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
@ -181,7 +256,9 @@ export default class DetailsStep extends Component {
|
|||||||
const { abiError, abiParsed } = validateAbi(abi, api);
|
const { abiError, abiParsed } = validateAbi(abi, api);
|
||||||
|
|
||||||
if (!abiError) {
|
if (!abiError) {
|
||||||
const { inputs } = abiParsed.find((method) => method.type === 'constructor') || { inputs: [] };
|
const { inputs } = abiParsed
|
||||||
|
.find((method) => method.type === 'constructor') || { inputs: [] };
|
||||||
|
|
||||||
const params = [];
|
const params = [];
|
||||||
|
|
||||||
inputs.forEach((input) => {
|
inputs.forEach((input) => {
|
||||||
@ -228,3 +305,104 @@ export default class DetailsStep extends Component {
|
|||||||
onCodeChange(code);
|
onCodeChange(code);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const ARRAY_TYPE = 'ARRAY_TYPE';
|
||||||
|
const ADDRESS_TYPE = 'ADDRESS_TYPE';
|
||||||
|
const STRING_TYPE = 'STRING_TYPE';
|
||||||
|
const BOOL_TYPE = 'BOOL_TYPE';
|
||||||
|
const BYTES_TYPE = 'BYTES_TYPE';
|
||||||
|
const UINT_TYPE = 'UINT_TYPE';
|
||||||
|
const INT_TYPE = 'INT_TYPE';
|
||||||
|
|
||||||
|
function parseAbiType (type) {
|
||||||
|
if (type === 'string') {
|
||||||
|
return {
|
||||||
|
type: STRING_TYPE,
|
||||||
|
default: ''
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
if (type === 'bool') {
|
||||||
|
return {
|
||||||
|
type: BOOL_TYPE,
|
||||||
|
default: false
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
if (type === 'address') {
|
||||||
|
return {
|
||||||
|
type: ADDRESS_TYPE,
|
||||||
|
default: '0x'
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
const arrayRegex = /^(.+)\[(\d*)\]$/;
|
||||||
|
|
||||||
|
if (arrayRegex.test(type)) {
|
||||||
|
const matches = arrayRegex.exec(type);
|
||||||
|
|
||||||
|
const subtype = parseAbiType(matches[1]);
|
||||||
|
const M = parseInt(matches[2]) || Infinity;
|
||||||
|
const defaultValue = M === Infinity
|
||||||
|
? []
|
||||||
|
: range(M).map(() => subtype.default);
|
||||||
|
|
||||||
|
return {
|
||||||
|
type: ARRAY_TYPE,
|
||||||
|
subtype: subtype,
|
||||||
|
length: M,
|
||||||
|
default: defaultValue
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
const lengthRegex = /^([a-z]+)(\d{1,3})$/;
|
||||||
|
|
||||||
|
if (lengthRegex.test(type)) {
|
||||||
|
const subtype = parseAbiType(matches[1]);
|
||||||
|
const length = parseInt(matches[2]) || Infinity;
|
||||||
|
|
||||||
|
return {
|
||||||
|
...subtype,
|
||||||
|
length
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
if (type === 'bytes') {
|
||||||
|
return {
|
||||||
|
type: BYTES_TYPE,
|
||||||
|
default: '0x'
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
if (type === 'uint') {
|
||||||
|
return {
|
||||||
|
type: UINT_TYPE,
|
||||||
|
default: 0,
|
||||||
|
length: 256
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
if (type === 'int') {
|
||||||
|
return {
|
||||||
|
type: INT_TYPE,
|
||||||
|
default: 0,
|
||||||
|
length: 256
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
if (type === 'ufixed') {
|
||||||
|
return {
|
||||||
|
type: UFIXED_TYPE,
|
||||||
|
default: 0,
|
||||||
|
length: 256
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
if (type === 'fixed') {
|
||||||
|
return {
|
||||||
|
type: FIXED_TYPE,
|
||||||
|
default: 0,
|
||||||
|
length: 256
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user