Handling errors and UI reorganization / features

- UI shows error screen if contract doesn't exist or fails fetching data
- Menu shows selected state and icons can be specified
- Component created for card alerts
This commit is contained in:
Richard Ramos 2018-04-19 09:59:48 -04:00 committed by Iuri Matias
parent e8dbf2be26
commit d40f73bdd1
8 changed files with 50 additions and 28 deletions

View File

@ -33,15 +33,7 @@ class AccountList extends React.Component {
<div className="card-header">
<h3 className="card-title">Get Accounts</h3>
</div>
{
this.state.error
?
<div className="card-alert alert alert-danger mb-0">
{this.state.errorMessage}
</div>
:
''
}
<CardAlert show={this.state.error} message={this.state.errorMessage} />
<div className="card-body row">
<div className="col-md-11">
<code>

View File

@ -0,0 +1,13 @@
class CardAlert extends React.Component {
render(){
return this.props.show ?
<div className="card-alert alert alert-danger mb-0">
{this.props.message}
</div>
:
'';
}
}

View File

@ -27,7 +27,6 @@ class ContractUI extends React.Component {
}
handleMenuClick(e){
console.log(e.target);
e.preventDefault();
this.setState({
selectedTab: e.target.getAttribute('data-target')
@ -66,9 +65,9 @@ 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 click={this.handleMenuClick} target="deploy" text="Deployment / Utils" />
<MenuItem click={this.handleMenuClick} target="functions" text="Functions" />
<MenuItem click={this.handleMenuClick} 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>

View File

@ -39,15 +39,10 @@ class FunctionForm extends React.Component {
:
""
}
{
this.state.error
?
<div className="card-alert alert alert-danger mb-0">
{this.state.message}
</div>
:
''
}
<CardAlert show={this.state.error} message={this.state.message} />
<div className="card-body row">
<Function contract={this.props.contract} contractName={this.props.contractName} duplicated={isDuplicated} abi={this.props.abi} resultHandler={this.showResults} />
</div>

View File

@ -162,7 +162,7 @@ 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 + 2} 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]
}, null)

View File

@ -1,7 +1,14 @@
class MenuItem extends React.Component {
render(){
return <a href="#" onClick={this.props.click} data-target={this.props.target} className="list-group-item list-group-item-action d-flex align-items-center">
<span className="icon mr-3"><i className="fe fe-file"></i></span>{this.props.text}
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){
classNames += "active";
}
return <a href="#" onClick={this.props.click} data-target={this.props.target} className={classNames}>
<span className="icon mr-3"><i className={icon}></i></span>{this.props.text}
</a>;
}
}

View File

@ -54,6 +54,7 @@
<script src="./components/source-area.js" type="text/babel"></script>
<script src="./components/tab.js" type="text/babel"></script>
<script src="./components/menu-item.js" type="text/babel"></script>
<script src="./components/card-alert.js" type="text/babel"></script>
<script src="./view.js" type="text/babel"></script>
@ -172,10 +173,11 @@
</div>
<div class="page-content">
<div class="container">
<div id="contracts-area"></div>
</div>
</div>
</div>

View File

@ -25,8 +25,8 @@ fetch("/embark/console", {
window.web3 = web3;
let contractObj = new web3.eth.Contract(contractDefinition.abiDefinition);
contractObj.options.data = "0x" + contractDefinition.code;
contractObj.options.address = contractDefinition.deployedAddress;
contractObj.options.data = "0x" + contractDefinition.code;
contractObj.options.address = contractDefinition.deployedAddress;
window[contractDefinition.className] = contractObj;
@ -34,4 +34,18 @@ fetch("/embark/console", {
<ContractUI name={contractDefinition.className} definition={contractDefinition} contract={contractObj} source={contractSource} />,
document.getElementById('contracts-area')
);
})
.catch(function(err) {
console.log('%cError while rendering UI', 'font-weight: bold');
console.error(err);
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>
</div>,
document.getElementById('contracts-area')
);
});