Annotations, click to error, UI improvements
Compiler annotations added to editor gutter for errors and warnings Clicking an error now scrolls editor to offending line and scrolls page to the top of the editor Added Compiling… loader.
This commit is contained in:
parent
70f5a09d47
commit
8caa478968
|
@ -2039,11 +2039,47 @@
|
|||
"resolved": "https://registry.npmjs.org/compare-versions/-/compare-versions-3.3.0.tgz",
|
||||
"integrity": "sha512-MAAAIOdi2s4Gl6rZ76PNcUa9IOYB+5ICdT41o5uMRf09aEu/F9RK+qhe8RjXNPwcTjGV7KU7h2P/fljThFVqyQ=="
|
||||
},
|
||||
"component-clone": {
|
||||
"version": "0.2.2",
|
||||
"resolved": "https://registry.npmjs.org/component-clone/-/component-clone-0.2.2.tgz",
|
||||
"integrity": "sha1-x/WXmCKID62M+wliuikYbQYe4E8=",
|
||||
"requires": {
|
||||
"component-type": "*"
|
||||
}
|
||||
},
|
||||
"component-emitter": {
|
||||
"version": "1.2.1",
|
||||
"resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.2.1.tgz",
|
||||
"integrity": "sha1-E3kY1teCg/ffemt8WmPhQOaUJeY="
|
||||
},
|
||||
"component-raf": {
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/component-raf/-/component-raf-1.2.0.tgz",
|
||||
"integrity": "sha1-srxy1D8bAU/eeks8RHx2S8c8y6o="
|
||||
},
|
||||
"component-tween": {
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/component-tween/-/component-tween-1.2.0.tgz",
|
||||
"integrity": "sha1-zDnOXbqwW1KCX0HRlHY4oLAbK4o=",
|
||||
"requires": {
|
||||
"component-clone": "0.2.2",
|
||||
"component-emitter": "1.2.0",
|
||||
"component-type": "1.1.0",
|
||||
"ease-component": "1.0.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"component-emitter": {
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.2.0.tgz",
|
||||
"integrity": "sha1-zNETqGOI0GSC0D3j/H35hSa6jv4="
|
||||
}
|
||||
}
|
||||
},
|
||||
"component-type": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/component-type/-/component-type-1.1.0.tgz",
|
||||
"integrity": "sha1-lbZmqtU+XI0fK+E1xFtdSZGXwMU="
|
||||
},
|
||||
"compressible": {
|
||||
"version": "2.0.14",
|
||||
"resolved": "https://registry.npmjs.org/compressible/-/compressible-2.0.14.tgz",
|
||||
|
@ -2835,6 +2871,11 @@
|
|||
"resolved": "https://registry.npmjs.org/duplexer3/-/duplexer3-0.1.4.tgz",
|
||||
"integrity": "sha1-7gHdHKwO08vH/b6jfcCo8c4ALOI="
|
||||
},
|
||||
"ease-component": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/ease-component/-/ease-component-1.0.0.tgz",
|
||||
"integrity": "sha1-s3VybbC1sEWVt3RAOW/sfapdd8k="
|
||||
},
|
||||
"ecc-jsbn": {
|
||||
"version": "0.1.2",
|
||||
"resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz",
|
||||
|
@ -9033,6 +9074,14 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
"react-scroll-to-component": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/react-scroll-to-component/-/react-scroll-to-component-1.0.2.tgz",
|
||||
"integrity": "sha1-8mDck2xipT53J4bXgy/giE4ZU1Q=",
|
||||
"requires": {
|
||||
"scroll-to": "0.0.2"
|
||||
}
|
||||
},
|
||||
"react-text-mask": {
|
||||
"version": "5.4.3",
|
||||
"resolved": "https://registry.npmjs.org/react-text-mask/-/react-text-mask-5.4.3.tgz",
|
||||
|
@ -9554,6 +9603,15 @@
|
|||
"ajv": "^5.0.0"
|
||||
}
|
||||
},
|
||||
"scroll-to": {
|
||||
"version": "0.0.2",
|
||||
"resolved": "https://registry.npmjs.org/scroll-to/-/scroll-to-0.0.2.tgz",
|
||||
"integrity": "sha1-k205ipEzZgokkhRcLACB38sHKPM=",
|
||||
"requires": {
|
||||
"component-raf": "1.2.0",
|
||||
"component-tween": "1.2.0"
|
||||
}
|
||||
},
|
||||
"select-hose": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/select-hose/-/select-hose-2.0.0.tgz",
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
"react-redux": "^5.0.7",
|
||||
"react-router-dom": "^4.3.1",
|
||||
"react-scripts": "1.1.4",
|
||||
"react-scroll-to-component": "^1.0.2",
|
||||
"redux": "^4.0.0",
|
||||
"redux-saga": "^0.16.0",
|
||||
"tabler-react": "^1.18.0"
|
||||
|
|
|
@ -1,5 +0,0 @@
|
|||
self.MonacoEnvironment = {
|
||||
baseUrl: 'https://cdnjs.cloudflare.com/ajax/libs/monaco-editor/0.13.1/min/'
|
||||
};
|
||||
|
||||
importScripts('https://cdnjs.cloudflare.com/ajax/libs/monaco-editor/0.13.1/min/vs/base/worker/workerMain.js'); // eslint-disable-line
|
|
@ -144,13 +144,13 @@ export function listenToContractLogs() {
|
|||
}
|
||||
|
||||
// Fiddle
|
||||
export const FETCH_COMPILE_CODE = 'FETCH_COMPILE_CODE';
|
||||
export const RECEIVE_COMPILE_CODE = 'RECEIVE_COMPILE_CODE';
|
||||
export const RECEIVE_COMPILE_CODE_ERROR = 'RECEIVE_COMPILE_CODE_ERROR';
|
||||
export const COMPILE_CODE_REQUEST = 'COMPILE_CODE_REQUEST';
|
||||
export const COMPILE_CODE_SUCCESS = 'COMPILE_CODE_SUCCESS';
|
||||
export const COMPILE_CODE_FAILURE = 'COMPILE_CODE_FAILURE';
|
||||
|
||||
export function fetchCodeCompilation(codeToCompile){
|
||||
return {
|
||||
type: FETCH_COMPILE_CODE,
|
||||
type: COMPILE_CODE_REQUEST,
|
||||
codeToCompile
|
||||
};
|
||||
}
|
||||
|
@ -158,14 +158,14 @@ export function fetchCodeCompilation(codeToCompile){
|
|||
|
||||
export function receiveCodeCompilation(compilationResult){
|
||||
return {
|
||||
type: RECEIVE_COMPILE_CODE,
|
||||
type: COMPILE_CODE_SUCCESS,
|
||||
compilationResult
|
||||
};
|
||||
}
|
||||
|
||||
export function receiveCodeCompilationError(){
|
||||
return {
|
||||
type: RECEIVE_COMPILE_CODE_ERROR
|
||||
type: COMPILE_CODE_FAILURE
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -5,28 +5,49 @@ import 'brace/theme/tomorrow_night_blue';
|
|||
import 'ace-mode-solidity/build/remix-ide/mode-solidity';
|
||||
import PropTypes from 'prop-types';
|
||||
|
||||
const Fiddle = ({onCodeChange, value}) => {
|
||||
class Fiddle extends React.Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
|
||||
return (
|
||||
<React.Fragment>
|
||||
<h1>Fiddle</h1>
|
||||
<p>Play around with contract code and deploy against your running node.</p>
|
||||
<AceEditor
|
||||
mode="solidity"
|
||||
theme="tomorrow_night_blue"
|
||||
name="blah1"
|
||||
height="60em"
|
||||
width="100%"
|
||||
onChange={onCodeChange}
|
||||
value={value}
|
||||
/>
|
||||
</React.Fragment>
|
||||
);
|
||||
};
|
||||
this.ace = null;
|
||||
}
|
||||
|
||||
render() {
|
||||
const {onCodeChange, value, errors, warnings} = this.props;
|
||||
const annotations = errors.map((error) => { return error.annotation; }).concat(warnings.map(warning => { return warning.annotation; }));
|
||||
return (
|
||||
<React.Fragment>
|
||||
|
||||
<AceEditor
|
||||
mode="solidity"
|
||||
theme="tomorrow_night_blue"
|
||||
name="fiddle"
|
||||
height="60em"
|
||||
width="100%"
|
||||
onChange={onCodeChange}
|
||||
value={value}
|
||||
showGutter={true}
|
||||
annotations={annotations}
|
||||
ref={(ace) => { this.ace = ace; }}
|
||||
setOptions={{
|
||||
useWorker: false
|
||||
}}
|
||||
editorProps={{
|
||||
$blockScrolling: Infinity,
|
||||
enableLiveAutocompletion:true,
|
||||
highlightSelectedWord: true
|
||||
}}
|
||||
/>
|
||||
</React.Fragment>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Fiddle.propTypes = {
|
||||
onCodeChange: PropTypes.func,
|
||||
value: PropTypes.string
|
||||
value: PropTypes.string,
|
||||
errors: PropTypes.array,
|
||||
warnings: PropTypes.array
|
||||
};
|
||||
|
||||
export default Fiddle;
|
||||
|
|
|
@ -1,41 +1,35 @@
|
|||
/* eslint {jsx-a11y/anchor-has-content:"off"} */
|
||||
import React, {Component} from 'react';
|
||||
import {Card, List, Badge} from 'tabler-react';
|
||||
import PropTypes from 'prop-types';
|
||||
|
||||
class FiddleResults extends Component{
|
||||
class FiddleResults extends Component {
|
||||
|
||||
constructor(props){
|
||||
super(props);
|
||||
this.state = {
|
||||
errors: props.compilationResult.errors
|
||||
};
|
||||
static _removeClass(elems, className) {
|
||||
for (let elem of elems) {
|
||||
elem.className = elem.className.replace(className, '').replace(' ', ' ');
|
||||
}
|
||||
}
|
||||
|
||||
static _removeClass(elems, className){
|
||||
for(let elem of elems) {
|
||||
elem.className = elem.className.replace(className, '').replace(' ', ' ');
|
||||
static _toggleClass(elems, className) {
|
||||
for (let elem of elems) {
|
||||
if (elem.className.indexOf(className) > -1) {
|
||||
FiddleResults._removeClass([elem], className);
|
||||
}
|
||||
}
|
||||
|
||||
static _toggleClass(elems, className){
|
||||
for(let elem of elems) {
|
||||
if(elem.className.indexOf(className) > -1){
|
||||
FiddleResults._removeClass([elem], className);
|
||||
}
|
||||
else{
|
||||
elem.className = (elem.className.length > 0 ? elem.className + ' ' : '') + className;
|
||||
}
|
||||
else {
|
||||
elem.className = (elem.className.length > 0 ? elem.className + ' ' : '') + className;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
toggleCollapse(e) {
|
||||
_toggleCollapse(e) {
|
||||
const collapsedClassName = 'card-collapsed';
|
||||
const className = e.currentTarget.parentElement.className.replace('card-options', '').replace(' ', '');
|
||||
const elems = document.getElementsByClassName(className + '-card');
|
||||
FiddleResults._toggleClass(elems, collapsedClassName);
|
||||
}
|
||||
|
||||
toggleFullscreen(e) {
|
||||
|
||||
_toggleFullscreen(e) {
|
||||
const collapsedClassName = 'card-collapsed';
|
||||
const fullscreenClassName = 'card-fullscreen';
|
||||
const className = e.currentTarget.parentElement.className.replace('card-options', '').replace(' ', '');
|
||||
|
@ -44,91 +38,58 @@ class FiddleResults extends Component{
|
|||
FiddleResults._removeClass(elems, collapsedClassName);
|
||||
}
|
||||
|
||||
render(){
|
||||
const warningObjs = this.props.compilationResult.errors.filter(error => {
|
||||
return error.severity === 'warning';
|
||||
});
|
||||
const errorObjs = this.props.compilationResult.errors.filter(error => {
|
||||
return error.severity === 'error';
|
||||
});
|
||||
const warnings = warningObjs.map((warning, index) => {
|
||||
return (
|
||||
<List.GroupItem key={index} action>
|
||||
<Badge color="warning" className="mr-1" key={index}>
|
||||
Lines {warning.sourceLocation.start}-{warning.sourceLocation.end}
|
||||
</Badge>
|
||||
{warning.formattedMessage}
|
||||
</List.GroupItem>
|
||||
);
|
||||
});
|
||||
const errors = errorObjs.map((error, index) => {
|
||||
return (
|
||||
<List.GroupItem key={index} action>
|
||||
<Badge color="danger" className="mr-1" key={index}>
|
||||
Lines {error.sourceLocation.start}-{error.sourceLocation.end}
|
||||
</Badge>
|
||||
{error.formattedMessage}
|
||||
</List.GroupItem>
|
||||
);
|
||||
});
|
||||
const errorsCard = <Card
|
||||
_getFormatted(errors, errorType){
|
||||
const color = (errorType === "error" ? "danger" : errorType);
|
||||
return <Card
|
||||
isCollapsible={true}
|
||||
isFullscreenable={true}
|
||||
statusColor="red"
|
||||
statusColor={color}
|
||||
statusSide="true"
|
||||
className="errors-card"
|
||||
key="errors">
|
||||
className={errorType + "s-card"}
|
||||
key={errorType + "s-card"}>
|
||||
<Card.Header>
|
||||
<Card.Title color="red">Errors <Badge color="danger" className="mr-1">{errors.length}</Badge></Card.Title>
|
||||
<Card.Options className="errors">
|
||||
<Card.OptionsItem key="0" type="collapse" icon="chevron-up" onClick={this.toggleCollapse}/>
|
||||
<Card.OptionsItem key="1" type="fullscreen" icon="maximize" onClick={this.toggleFullscreen}/>
|
||||
<Card.Title color={color}>{errorType + "s"} <Badge color={color}>{errors.length}</Badge></Card.Title>
|
||||
<Card.Options className={errorType + "s"}>
|
||||
<Card.OptionsItem key="0" type="collapse" icon="chevron-up" onClick={this._toggleCollapse} />
|
||||
<Card.OptionsItem key="1" type="fullscreen" icon="maximize" onClick={this._toggleFullscreen} />
|
||||
</Card.Options>
|
||||
</Card.Header>
|
||||
<Card.Body>
|
||||
<List.Group>
|
||||
{errors}
|
||||
</List.Group>
|
||||
</Card.Body>
|
||||
</Card>;
|
||||
const warningsCard = <Card
|
||||
isCollapsible={true}
|
||||
isFullscreenable={true}
|
||||
statusColor="warning"
|
||||
statusSide="true"
|
||||
className="warnings-card"
|
||||
key="warnings">
|
||||
<Card.Header>
|
||||
<Card.Title color="warning">Warnings <Badge color="warning" className="mr-1">{warnings.length}</Badge></Card.Title>
|
||||
<Card.Options className="warnings">
|
||||
<Card.OptionsItem key="0" type="collapse" icon="chevron-up" onClick={this.toggleCollapse}/>
|
||||
<Card.OptionsItem key="1" type="fullscreen" icon="maximize" onClick={this.toggleFullscreen}/>
|
||||
</Card.Options>
|
||||
</Card.Header>
|
||||
<Card.Body>
|
||||
<List.Group>
|
||||
{warnings}
|
||||
{errors.map(error => { return error.node; })}
|
||||
</List.Group>
|
||||
</Card.Body>
|
||||
</Card>;
|
||||
}
|
||||
|
||||
render() {
|
||||
const {warnings, errors} = this.props;
|
||||
|
||||
let renderings = [];
|
||||
if(!this.state.errors){
|
||||
return 'Compilation successful (add green tick mark)';
|
||||
}
|
||||
if(errors.length) renderings.push(errorsCard);
|
||||
if(warnings.length) renderings.push(warningsCard);
|
||||
|
||||
if (errors.length) renderings.push(
|
||||
<React.Fragment key="errors">
|
||||
<a id="errors" aria-hidden="true"/>
|
||||
{this._getFormatted(errors, "error")}
|
||||
</React.Fragment>
|
||||
);
|
||||
if (warnings.length) renderings.push(
|
||||
<React.Fragment key="warnings">
|
||||
<a id="warnings" aria-hidden="true"/>
|
||||
{this._getFormatted(warnings, "warning")}
|
||||
</React.Fragment>
|
||||
);
|
||||
|
||||
return (
|
||||
<React.Fragment>
|
||||
{renderings}
|
||||
{renderings}
|
||||
</React.Fragment>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
FiddleResults.propTypes = {
|
||||
compilationResult: PropTypes.object
|
||||
errors: PropTypes.array,
|
||||
warnings: PropTypes.array
|
||||
};
|
||||
|
||||
export default FiddleResults;
|
||||
|
|
|
@ -0,0 +1,45 @@
|
|||
import React, {Component} from 'react';
|
||||
import {Badge} from 'tabler-react';
|
||||
import PropTypes from 'prop-types';
|
||||
|
||||
class FiddleResultsSummary extends Component{
|
||||
|
||||
render(){
|
||||
const {warnings, errors, isFetching, hasResult} = this.props;
|
||||
let renderings = [];
|
||||
if(isFetching){
|
||||
renderings.push(
|
||||
<React.Fragment key="compiling"><div className="loader"></div><span className="loader-text">Compiling...</span></React.Fragment>
|
||||
);
|
||||
}
|
||||
if(hasResult && !errors.length){
|
||||
renderings.push(<Badge key="success" className="badge-link" color="success">Compiled</Badge>);
|
||||
}
|
||||
if(errors.length) renderings.push(
|
||||
<React.Fragment key="errors">
|
||||
<a className="badge-link" href="#errors"><Badge color="danger">{errors.length} error{errors.length > 1 ? "s" : ""}</Badge></a>
|
||||
</React.Fragment>
|
||||
);
|
||||
if(warnings.length) renderings.push(
|
||||
<React.Fragment key="warnings">
|
||||
<a className="badge-link" href="#warnings"><Badge color="warning">{warnings.length} warning{warnings.length > 1 ? "s" : ""}</Badge></a>
|
||||
</React.Fragment>
|
||||
);
|
||||
|
||||
return (
|
||||
<div className={"compilation-summary " + ((hasResult || isFetching) ? "visible" : "")}>
|
||||
{renderings}
|
||||
{!(hasResult || isFetching) ? " " : ""}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
FiddleResultsSummary.propTypes = {
|
||||
errors: PropTypes.array,
|
||||
warnings: PropTypes.array,
|
||||
isFetching: PropTypes.bool,
|
||||
hasResult: PropTypes.bool
|
||||
};
|
||||
|
||||
export default FiddleResultsSummary;
|
|
@ -6,43 +6,129 @@ import PropTypes from 'prop-types';
|
|||
import {fetchCodeCompilation} from '../actions';
|
||||
import Fiddle from '../components/Fiddle';
|
||||
import FiddleResults from '../components/FiddleResults';
|
||||
import FiddleReultsSummary from '../components/FiddleResultsSummary';
|
||||
import {Badge} from 'tabler-react';
|
||||
import scrollToComponent from 'react-scroll-to-component';
|
||||
|
||||
class FiddleContainer extends Component {
|
||||
|
||||
constructor(props){
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.state = {
|
||||
this.state = {
|
||||
value: ''
|
||||
};
|
||||
this.compileTimeout = null;
|
||||
this.ace = null;
|
||||
this.editor = null;
|
||||
}
|
||||
|
||||
componentDidMount(){
|
||||
if(this.state.value){
|
||||
componentDidMount() {
|
||||
if (this.state.value) {
|
||||
this.props.fetchCodeCompilation(this.state.value);
|
||||
}
|
||||
}
|
||||
|
||||
onCodeChange(newValue) {
|
||||
_onCodeChange(newValue) {
|
||||
this.setState({value: newValue});
|
||||
if(this.compileTimeout) clearTimeout(this.compileTimeout);
|
||||
if (this.compileTimeout) clearTimeout(this.compileTimeout);
|
||||
this.compileTimeout = setTimeout(() => {
|
||||
this.props.fetchCodeCompilation(newValue);
|
||||
}, 1000);
|
||||
|
||||
|
||||
}
|
||||
|
||||
_getFormattedErrors(errors, errorType){
|
||||
return errors.reduce(
|
||||
(errors, error, index) => {
|
||||
if (error.severity === errorType) {
|
||||
const errorRowCol = this._getRowCol(error.formattedMessage);
|
||||
const annotation = Object.assign({}, {
|
||||
row: errorRowCol.row - 1, // must be 0 based
|
||||
column: errorRowCol.col - 1, // must be 0 based
|
||||
text: error.formattedMessage, // text to show in tooltip
|
||||
type: error.severity // "error"|"warning"|"info"
|
||||
});
|
||||
errors.push({
|
||||
solcError: error,
|
||||
node:
|
||||
<a
|
||||
href="#editor"
|
||||
className="list-group-item list-group-item-action"
|
||||
onClick={(e) => { this._onErrorClick(e, annotation); }}
|
||||
key={index}
|
||||
//ref={(item) => { this.refCallback(item, annotation); }}
|
||||
>
|
||||
<Badge color={errorType === "error" ? "danger" : errorType} className="mr-1" key={index}>
|
||||
Line {errorRowCol.row}
|
||||
</Badge>
|
||||
{error.formattedMessage}
|
||||
</a>,
|
||||
annotation: annotation
|
||||
});
|
||||
}
|
||||
return errors;
|
||||
}, []);
|
||||
}
|
||||
|
||||
_getRowCol(errorMessage){
|
||||
const errorSplit = errorMessage.split(':');
|
||||
if(errorSplit.length >= 3){
|
||||
return {row: errorSplit[1], col: errorSplit[2]};
|
||||
}
|
||||
return {row: 0, col: 0};
|
||||
}
|
||||
|
||||
_onErrorClick(e, annotation){
|
||||
e.preventDefault();
|
||||
this.editor.gotoLine(annotation.row + 1);
|
||||
scrollToComponent(this.ace);
|
||||
}
|
||||
|
||||
render() {
|
||||
const {fiddles} = this.props;
|
||||
|
||||
let renderings = [<Fiddle key="0" value={this.state.value} onCodeChange={(n) => this.onCodeChange(n)} />];
|
||||
if(fiddles.compilationResult) {
|
||||
renderings.push(<FiddleResults key="1" compilationResult={fiddles.compilationResult}/>);
|
||||
let renderings = [];
|
||||
let warnings = [];
|
||||
let errors = [];
|
||||
if (fiddles.compilationResult) {
|
||||
warnings = this._getFormattedErrors(fiddles.compilationResult.errors, "warning");
|
||||
errors = this._getFormattedErrors(fiddles.compilationResult.errors, "error");
|
||||
|
||||
}
|
||||
else renderings.push('Nothing to compile');
|
||||
|
||||
renderings.push(
|
||||
<React.Fragment key="fiddle">
|
||||
<FiddleReultsSummary
|
||||
errors={errors}
|
||||
warnings={warnings}
|
||||
isFetching={fiddles.isFetching}
|
||||
hasResult={Boolean(fiddles.compilationResult)}
|
||||
/>
|
||||
<Fiddle
|
||||
value={this.state.value}
|
||||
onCodeChange={(n) => this._onCodeChange(n)}
|
||||
errors={errors}
|
||||
warnings={warnings}
|
||||
ref={(fiddle) => {
|
||||
if(fiddle) {
|
||||
this.editor = fiddle.ace.editor;
|
||||
this.ace = fiddle.ace;
|
||||
}
|
||||
}}
|
||||
/>
|
||||
</React.Fragment>
|
||||
);
|
||||
if (fiddles.compilationResult) {
|
||||
renderings.push(
|
||||
<FiddleResults
|
||||
key="results"
|
||||
errors={errors}
|
||||
warnings={warnings}
|
||||
/>);
|
||||
}
|
||||
|
||||
return (
|
||||
<React.Fragment>
|
||||
<React.Fragment>
|
||||
<h1>Fiddle</h1>
|
||||
<p>Play around with contract code and deploy against your running node.</p>
|
||||
{renderings}
|
||||
</React.Fragment>
|
||||
);
|
||||
|
|
|
@ -25,5 +25,43 @@
|
|||
white-space: pre-line;
|
||||
}
|
||||
.card.card-fullscreen{
|
||||
z-index:4;
|
||||
z-index:6;
|
||||
}
|
||||
.card.warnings-card, .card.errors-card{
|
||||
text-transform: capitalize;
|
||||
}
|
||||
.card.warnings-card .list-group-item, .card.errors-card .list-group-item{
|
||||
white-space: pre-line;
|
||||
}
|
||||
.card.warnings-card .card-options a, .card.errors-card .card-options a{
|
||||
cursor:pointer;
|
||||
}
|
||||
.compilation-summary {
|
||||
float:right;
|
||||
margin-bottom:3px;
|
||||
line-height:30px;
|
||||
visibility: hidden;
|
||||
}
|
||||
.compilation-summary.visible{
|
||||
visibility: visible;
|
||||
}
|
||||
.compilation-summary .badge-link:not(:last-child){
|
||||
margin-right:5px;
|
||||
}
|
||||
.ace_editor {
|
||||
margin-bottom:24px;
|
||||
}
|
||||
.loader, .loader:before, .loader:after{
|
||||
width:1.2rem;
|
||||
height:1.2rem;
|
||||
}
|
||||
.loader:before, .loader:after{
|
||||
margin:-0.6rem 0 0 -0.6rem;
|
||||
}
|
||||
.loader, .loader-text{
|
||||
display:inline-block;
|
||||
vertical-align: middle;
|
||||
}
|
||||
.loader {
|
||||
margin-right:5px;
|
||||
}
|
|
@ -1,11 +1,13 @@
|
|||
import {RECEIVE_COMPILE_CODE, RECEIVE_COMPILE_CODE_ERROR} from "../actions";
|
||||
import {COMPILE_CODE_REQUEST, COMPILE_CODE_FAILURE, COMPILE_CODE_SUCCESS} from "../actions";
|
||||
|
||||
export default function processes(state = {}, action) {
|
||||
switch (action.type) {
|
||||
case RECEIVE_COMPILE_CODE:
|
||||
return Object.assign({}, state, {compilationResult: action.compilationResult});
|
||||
case RECEIVE_COMPILE_CODE_ERROR:
|
||||
return Object.assign({}, state, {error: true});
|
||||
case COMPILE_CODE_REQUEST:
|
||||
return {...state, isFetching: true, compilationResult: action.compilationResult};
|
||||
case COMPILE_CODE_SUCCESS:
|
||||
return {...state, isFetching: false, compilationResult: action.compilationResult};
|
||||
case COMPILE_CODE_FAILURE:
|
||||
return {...state, isFetching: false, error: true};
|
||||
default:
|
||||
return state;
|
||||
}
|
||||
|
|
|
@ -170,7 +170,7 @@ export function *fetchCodeCompilation(action) {
|
|||
}
|
||||
|
||||
export function *watchFetchCodeCompilation() {
|
||||
yield takeEvery(actions.FETCH_COMPILE_CODE, fetchCodeCompilation);
|
||||
yield takeEvery(actions.COMPILE_CODE_REQUEST, fetchCodeCompilation);
|
||||
}
|
||||
|
||||
export default function *root() {
|
||||
|
|
|
@ -25,10 +25,7 @@ class Solidity {
|
|||
'post',
|
||||
'/embark-api/contract/compile',
|
||||
(req, res) => {
|
||||
console.log('=====> POST contract/compile, req = ' + JSON.stringify(req.body));
|
||||
this.events.request("contract:compile", req.body.code, (errors, compilationResult) => {
|
||||
console.log('=====> POST contract/compile, errors = ' + JSON.stringify(errors));
|
||||
console.log('=====> POST contract/compile, compilationResult = ' + JSON.stringify(compilationResult));
|
||||
res.send({errors:errors, compilationResult: compilationResult});
|
||||
});
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue