Addressed PR comments
Changed `fiddle` to an entity and removed unneeded fiddle reducer. Added a selector for getting the entity. Changed fiddle saga to `doRequest`. Changed fiddle api call to the `post` method (did not see beofre the rebase). Added `CompilerError` presentation component to handle displaying compiler errors and warnings. Added spaces to css (as requested). Removed extra space after function in solidity compiler (as requested). Removed the compile contract event from the solidity compiler (as requested). Handling of fatal api error in the UI. Changed fiddle action to the one created with `createRequestTypes`. Moved `Fiddle` nav tab before `Documentation`. Changed `FiddleResults` DOM manipulation to be controlled via React state instead.
This commit is contained in:
parent
13e4b4dc0d
commit
eee898527e
|
@ -143,30 +143,17 @@ export function listenToContractLogs() {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
// Fiddle
|
export function initBlockHeader(){
|
||||||
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 {
|
return {
|
||||||
type: COMPILE_CODE_REQUEST,
|
type: INIT_BLOCK_HEADER
|
||||||
codeToCompile
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export const FIDDLE = createRequestTypes('FIDDLE');
|
||||||
export function receiveCodeCompilation(compilationResult){
|
export const fiddle = {
|
||||||
return {
|
request: (codeToCompile) => action(FIDDLE[REQUEST], {codeToCompile}),
|
||||||
type: COMPILE_CODE_SUCCESS,
|
success: (fiddle) => action(FIDDLE[SUCCESS], {fiddle}),
|
||||||
compilationResult
|
failure: (error) => action(FIDDLE[FAILURE], {error})
|
||||||
};
|
};
|
||||||
}
|
|
||||||
|
|
||||||
export function receiveCodeCompilationError(){
|
|
||||||
return {
|
|
||||||
type: COMPILE_CODE_FAILURE
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -96,6 +96,6 @@ export function webSocketBlockHeader() {
|
||||||
return new WebSocket(`${constants.wsEndpoint}/blockchain/blockHeader`);
|
return new WebSocket(`${constants.wsEndpoint}/blockchain/blockHeader`);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function fetchCodeCompilation(codeToCompile) {
|
export function fetchFiddle(payload) {
|
||||||
return axios.post(constants.httpEndpoint + '/contract/compile', {code: codeToCompile});
|
return post('/contract/compile', {code: payload.codeToCompile});
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,27 @@
|
||||||
|
import React from 'react';
|
||||||
|
import PropTypes from 'prop-types';
|
||||||
|
import {Badge} from 'tabler-react';
|
||||||
|
|
||||||
|
const CompilerError = ({key, onClick, errorType, row, errorMessage}) => (
|
||||||
|
<a
|
||||||
|
href="#editor"
|
||||||
|
className="list-group-item list-group-item-action"
|
||||||
|
onClick={onClick}
|
||||||
|
key={key}
|
||||||
|
>
|
||||||
|
<Badge color={errorType === "error" ? "danger" : errorType} className="mr-1" key={key}>
|
||||||
|
Line {row}
|
||||||
|
</Badge>
|
||||||
|
{errorMessage}
|
||||||
|
</a>
|
||||||
|
);
|
||||||
|
|
||||||
|
CompilerError.propTypes = {
|
||||||
|
key: PropTypes.string,
|
||||||
|
onClick: PropTypes.func,
|
||||||
|
errorType: PropTypes.string,
|
||||||
|
row: PropTypes.number,
|
||||||
|
errorMessage: PropTypes.string
|
||||||
|
};
|
||||||
|
|
||||||
|
export default CompilerError;
|
|
@ -1,57 +1,48 @@
|
||||||
/* eslint {jsx-a11y/anchor-has-content:"off"} */
|
/* eslint {jsx-a11y/anchor-has-content:"off"} */
|
||||||
import React, {Component} from 'react';
|
import React, {Component} from 'react';
|
||||||
import {Card, List, Badge} from 'tabler-react';
|
import {Card, List, Badge, Icon} from 'tabler-react';
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
|
import classNames from 'classnames';
|
||||||
|
|
||||||
class FiddleResults extends Component {
|
class FiddleResults extends Component {
|
||||||
|
|
||||||
static _removeClass(elems, className) {
|
constructor(props){
|
||||||
for (let elem of elems) {
|
super(props);
|
||||||
elem.className = elem.className.replace(className, '').replace(' ', ' ');
|
|
||||||
}
|
this.state = {
|
||||||
|
errorsCollapsed: false,
|
||||||
|
warningsCollapsed: false,
|
||||||
|
errorsFullscreen: false,
|
||||||
|
warningsFullscreen: false
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
static _toggleClass(elems, className) {
|
_toggle(e, type){
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
_toggleCollapse(e) {
|
|
||||||
const collapsedClassName = 'card-collapsed';
|
|
||||||
const className = e.currentTarget.parentElement.className.replace('card-options', '').replace(' ', '');
|
const className = e.currentTarget.parentElement.className.replace('card-options', '').replace(' ', '');
|
||||||
const elems = document.getElementsByClassName(className + '-card');
|
const updatedState = {};
|
||||||
FiddleResults._toggleClass(elems, collapsedClassName);
|
updatedState[className + type] = !(this.state[className + type]);
|
||||||
}
|
this.setState(updatedState);
|
||||||
|
|
||||||
_toggleFullscreen(e) {
|
|
||||||
const collapsedClassName = 'card-collapsed';
|
|
||||||
const fullscreenClassName = 'card-fullscreen';
|
|
||||||
const className = e.currentTarget.parentElement.className.replace('card-options', '').replace(' ', '');
|
|
||||||
const elems = document.getElementsByClassName(className + '-card');
|
|
||||||
FiddleResults._toggleClass(elems, fullscreenClassName);
|
|
||||||
FiddleResults._removeClass(elems, collapsedClassName);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
_getFormatted(errors, errorType){
|
_getFormatted(errors, errorType){
|
||||||
const color = (errorType === "error" ? "danger" : errorType);
|
const color = (errorType === "error" ? "danger" : errorType);
|
||||||
|
const isFullscreen = Boolean(this.state[errorType + 'sFullscreen']);
|
||||||
|
const classes = classNames({
|
||||||
|
'card-fullscreen': Boolean(this.state[errorType + 'sFullscreen']),
|
||||||
|
'card-collapsed': Boolean(this.state[errorType + 'sCollapsed']) && !isFullscreen
|
||||||
|
});
|
||||||
return <Card
|
return <Card
|
||||||
isCollapsible={true}
|
isCollapsible={true}
|
||||||
isFullscreenable={true}
|
isFullscreenable={true}
|
||||||
statusColor={color}
|
statusColor={color}
|
||||||
statusSide="true"
|
statusSide="true"
|
||||||
className={errorType + "s-card"}
|
className={errorType + "s-card " + classes}
|
||||||
key={errorType + "s-card"}>
|
key={errorType + "s-card"}>
|
||||||
<Card.Header>
|
<Card.Header>
|
||||||
<Card.Title color={color}>{errorType + "s"} <Badge color={color}>{errors.length}</Badge></Card.Title>
|
<Card.Title color={color}>{errorType + "s"} <Badge color={color}>{errors.length}</Badge></Card.Title>
|
||||||
<Card.Options className={errorType + "s"}>
|
<Card.Options className={errorType + "s"}>
|
||||||
<Card.OptionsItem key="0" type="collapse" icon="chevron-up" onClick={this._toggleCollapse} />
|
<Card.OptionsItem key="0" type="collapse" icon="chevron-up" onClick={(e) => this._toggle(e, 'Collapsed')}/>
|
||||||
<Card.OptionsItem key="1" type="fullscreen" icon="maximize" onClick={this._toggleFullscreen} />
|
<Card.OptionsItem key="1" type="fullscreen" icon="maximize" onClick={(e) => this._toggle(e, 'Fullscreen')} />
|
||||||
</Card.Options>
|
</Card.Options>
|
||||||
</Card.Header>
|
</Card.Header>
|
||||||
<Card.Body>
|
<Card.Body>
|
||||||
|
@ -63,21 +54,42 @@ class FiddleResults extends Component {
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const {warnings, errors} = this.props;
|
const {warnings, errors, fatal} = this.props;
|
||||||
|
|
||||||
let renderings = [];
|
let renderings = [];
|
||||||
if (errors.length) renderings.push(
|
if(fatal){
|
||||||
<React.Fragment key="errors">
|
renderings.push(
|
||||||
<a id="errors" aria-hidden="true"/>
|
<React.Fragment key="fatal">
|
||||||
{this._getFormatted(errors, "error")}
|
<a id="fatal" aria-hidden="true"/>
|
||||||
</React.Fragment>
|
<Card
|
||||||
);
|
statusColor="danger"
|
||||||
if (warnings.length) renderings.push(
|
statusSide="true"
|
||||||
<React.Fragment key="warnings">
|
className="fatal-card"
|
||||||
<a id="warnings" aria-hidden="true"/>
|
key="fatal-card">
|
||||||
{this._getFormatted(warnings, "warning")}
|
<Card.Header>
|
||||||
</React.Fragment>
|
<Card.Title color="danger"><Icon name="slash"/> Failed to compile</Card.Title>
|
||||||
);
|
</Card.Header>
|
||||||
|
<Card.Body>
|
||||||
|
{fatal}
|
||||||
|
</Card.Body>
|
||||||
|
</Card>
|
||||||
|
</React.Fragment>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
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 (
|
return (
|
||||||
<React.Fragment>
|
<React.Fragment>
|
||||||
|
@ -89,7 +101,8 @@ class FiddleResults extends Component {
|
||||||
|
|
||||||
FiddleResults.propTypes = {
|
FiddleResults.propTypes = {
|
||||||
errors: PropTypes.array,
|
errors: PropTypes.array,
|
||||||
warnings: PropTypes.array
|
warnings: PropTypes.array,
|
||||||
|
fatal: PropTypes.string
|
||||||
};
|
};
|
||||||
|
|
||||||
export default FiddleResults;
|
export default FiddleResults;
|
||||||
|
|
|
@ -1,31 +1,39 @@
|
||||||
import React, {Component} from 'react';
|
import React, {Component} from 'react';
|
||||||
import {Badge} from 'tabler-react';
|
import {Badge, Icon} from 'tabler-react';
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
|
|
||||||
class FiddleResultsSummary extends Component{
|
class FiddleResultsSummary extends Component{
|
||||||
|
|
||||||
render(){
|
render(){
|
||||||
const {warnings, errors, isFetching, hasResult} = this.props;
|
const {warnings, errors, isFetching, hasResult, fatal} = this.props;
|
||||||
let renderings = [];
|
let renderings = [];
|
||||||
if(isFetching){
|
if(fatal) {
|
||||||
|
renderings.push(
|
||||||
|
<React.Fragment key="errors">
|
||||||
|
<a className="badge-link" href="#fatal"><Badge color="danger"><Icon name="slash"/></Badge></a>
|
||||||
|
</React.Fragment>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
else if(isFetching){
|
||||||
renderings.push(
|
renderings.push(
|
||||||
<React.Fragment key="compiling"><div className="loader"></div><span className="loader-text">Compiling...</span></React.Fragment>
|
<React.Fragment key="compiling"><div className="loader"></div><span className="loader-text">Compiling...</span></React.Fragment>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
if(hasResult && !errors.length){
|
else {
|
||||||
renderings.push(<Badge key="success" className="badge-link" color="success">Compiled</Badge>);
|
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>
|
||||||
|
);
|
||||||
}
|
}
|
||||||
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 (
|
return (
|
||||||
<div className={"compilation-summary " + ((hasResult || isFetching) ? "visible" : "")}>
|
<div className={"compilation-summary " + ((hasResult || isFetching) ? "visible" : "")}>
|
||||||
{renderings}
|
{renderings}
|
||||||
|
@ -39,7 +47,8 @@ FiddleResultsSummary.propTypes = {
|
||||||
errors: PropTypes.array,
|
errors: PropTypes.array,
|
||||||
warnings: PropTypes.array,
|
warnings: PropTypes.array,
|
||||||
isFetching: PropTypes.bool,
|
isFetching: PropTypes.bool,
|
||||||
hasResult: PropTypes.bool
|
hasResult: PropTypes.bool,
|
||||||
|
fatal: PropTypes.string
|
||||||
};
|
};
|
||||||
|
|
||||||
export default FiddleResultsSummary;
|
export default FiddleResultsSummary;
|
||||||
|
|
|
@ -10,8 +10,8 @@ const navBarItems = [
|
||||||
{value: "Contracts", to: "/embark/contracts", icon: "box", LinkComponent: withRouter(NavLink)},
|
{value: "Contracts", to: "/embark/contracts", icon: "box", LinkComponent: withRouter(NavLink)},
|
||||||
{value: "Explorer", to: "/embark/explorer/accounts", icon: "activity", LinkComponent: withRouter(NavLink)},
|
{value: "Explorer", to: "/embark/explorer/accounts", icon: "activity", LinkComponent: withRouter(NavLink)},
|
||||||
{value: "Processes", to: "/embark/processes", icon: "cpu", LinkComponent: withRouter(NavLink)},
|
{value: "Processes", to: "/embark/processes", icon: "cpu", LinkComponent: withRouter(NavLink)},
|
||||||
{value: "Documentation", to: "/embark/documentation", icon: "file-text", LinkComponent: withRouter(NavLink)},
|
{value: "Fiddle", to: "/embark/fiddle", icon: "codepen", LinkComponent: withRouter(NavLink)},
|
||||||
{value: "Fiddle", to: "/embark/fiddle", icon: "codepen", LinkComponent: withRouter(NavLink)}
|
{value: "Documentation", to: "/embark/documentation", icon: "file-text", LinkComponent: withRouter(NavLink)}
|
||||||
];
|
];
|
||||||
|
|
||||||
const Layout = (props) => (
|
const Layout = (props) => (
|
||||||
|
|
|
@ -3,12 +3,13 @@
|
||||||
import React, {Component} from 'react';
|
import React, {Component} from 'react';
|
||||||
import {connect} from 'react-redux';
|
import {connect} from 'react-redux';
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
import {fetchCodeCompilation} from '../actions';
|
import {fiddle as fiddleAction} from '../actions';
|
||||||
import Fiddle from '../components/Fiddle';
|
import Fiddle from '../components/Fiddle';
|
||||||
import FiddleResults from '../components/FiddleResults';
|
import FiddleResults from '../components/FiddleResults';
|
||||||
import FiddleReultsSummary from '../components/FiddleResultsSummary';
|
import FiddleResultsSummary from '../components/FiddleResultsSummary';
|
||||||
import {Badge} from 'tabler-react';
|
|
||||||
import scrollToComponent from 'react-scroll-to-component';
|
import scrollToComponent from 'react-scroll-to-component';
|
||||||
|
import {getFiddle} from "../reducers/selectors";
|
||||||
|
import CompilerError from "../components/CompilerError";
|
||||||
|
|
||||||
class FiddleContainer extends Component {
|
class FiddleContainer extends Component {
|
||||||
|
|
||||||
|
@ -22,17 +23,11 @@ class FiddleContainer extends Component {
|
||||||
this.editor = null;
|
this.editor = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
componentDidMount() {
|
|
||||||
if (this.state.value) {
|
|
||||||
this.props.fetchCodeCompilation(this.state.value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
_onCodeChange(newValue) {
|
_onCodeChange(newValue) {
|
||||||
this.setState({value: newValue});
|
this.setState({value: newValue});
|
||||||
if (this.compileTimeout) clearTimeout(this.compileTimeout);
|
if (this.compileTimeout) clearTimeout(this.compileTimeout);
|
||||||
this.compileTimeout = setTimeout(() => {
|
this.compileTimeout = setTimeout(() => {
|
||||||
this.props.fetchCodeCompilation(newValue);
|
this.props.fetchFiddle(newValue);
|
||||||
}, 1000);
|
}, 1000);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -51,17 +46,12 @@ class FiddleContainer extends Component {
|
||||||
errors.push({
|
errors.push({
|
||||||
solcError: error,
|
solcError: error,
|
||||||
node:
|
node:
|
||||||
<a
|
<CompilerError
|
||||||
href="#editor"
|
onClick={(e) => { this._onErrorClick(e, annotation); }}
|
||||||
className="list-group-item list-group-item-action"
|
key={index}
|
||||||
onClick={(e) => { this._onErrorClick(e, annotation); }}
|
errorType={errorType}
|
||||||
key={index}
|
row={errorRowCol.row}
|
||||||
>
|
errorMessage={error.formattedMessage}/>,
|
||||||
<Badge color={errorType === "error" ? "danger" : errorType} className="mr-1" key={index}>
|
|
||||||
Line {errorRowCol.row}
|
|
||||||
</Badge>
|
|
||||||
{error.formattedMessage}
|
|
||||||
</a>,
|
|
||||||
annotation: annotation
|
annotation: annotation
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -84,22 +74,22 @@ class FiddleContainer extends Component {
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const {fiddles} = this.props;
|
const {fiddle, loading, error} = this.props;
|
||||||
let renderings = [];
|
let renderings = [];
|
||||||
let warnings = [];
|
let warnings = [];
|
||||||
let errors = [];
|
let errors = [];
|
||||||
if (fiddles.compilationResult) {
|
if (fiddle && fiddle.errors) {
|
||||||
warnings = this._getFormattedErrors(fiddles.compilationResult.errors, "warning");
|
warnings = this._getFormattedErrors(fiddle.errors, "warning");
|
||||||
errors = this._getFormattedErrors(fiddles.compilationResult.errors, "error");
|
errors = this._getFormattedErrors(fiddle.errors, "error");
|
||||||
|
|
||||||
}
|
}
|
||||||
renderings.push(
|
renderings.push(
|
||||||
<React.Fragment key="fiddle">
|
<React.Fragment key="fiddle">
|
||||||
<FiddleReultsSummary
|
<FiddleResultsSummary
|
||||||
errors={errors}
|
errors={errors}
|
||||||
warnings={warnings}
|
warnings={warnings}
|
||||||
isFetching={fiddles.isFetching}
|
isFetching={loading}
|
||||||
hasResult={Boolean(fiddles.compilationResult)}
|
hasResult={Boolean(fiddle)}
|
||||||
|
fatal={error}
|
||||||
/>
|
/>
|
||||||
<Fiddle
|
<Fiddle
|
||||||
value={this.state.value}
|
value={this.state.value}
|
||||||
|
@ -115,12 +105,13 @@ class FiddleContainer extends Component {
|
||||||
/>
|
/>
|
||||||
</React.Fragment>
|
</React.Fragment>
|
||||||
);
|
);
|
||||||
if (fiddles.compilationResult) {
|
if (fiddle || (this.state.value && error)) {
|
||||||
renderings.push(
|
renderings.push(
|
||||||
<FiddleResults
|
<FiddleResults
|
||||||
key="results"
|
key="results"
|
||||||
errors={errors}
|
errors={errors}
|
||||||
warnings={warnings}
|
warnings={warnings}
|
||||||
|
fatal={error}
|
||||||
/>);
|
/>);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -134,19 +125,24 @@ class FiddleContainer extends Component {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
function mapStateToProps(state) {
|
function mapStateToProps(state) {
|
||||||
return {
|
return {
|
||||||
fiddles: state.fiddles
|
fiddle: getFiddle(state),
|
||||||
|
error: state.errorMessage,
|
||||||
|
loading: state.loading
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
FiddleContainer.propTypes = {
|
FiddleContainer.propTypes = {
|
||||||
fiddles: PropTypes.object,
|
fiddle: PropTypes.object,
|
||||||
fetchCodeCompilation: PropTypes.func
|
error: PropTypes.string,
|
||||||
|
fetchFiddle: PropTypes.func,
|
||||||
|
loading: PropTypes.bool
|
||||||
};
|
};
|
||||||
|
|
||||||
export default connect(
|
export default connect(
|
||||||
mapStateToProps,
|
mapStateToProps,
|
||||||
{
|
{
|
||||||
fetchCodeCompilation
|
fetchFiddle: fiddleAction.request
|
||||||
|
//fetchBlock: blockAction.request
|
||||||
},
|
},
|
||||||
)(FiddleContainer);
|
)(FiddleContainer);
|
||||||
|
|
|
@ -21,47 +21,44 @@
|
||||||
color: #8f98a2;
|
color: #8f98a2;
|
||||||
}
|
}
|
||||||
|
|
||||||
.text__new-line {
|
.text__new-line, .card.warnings-card .list-group-item, .card.errors-card .list-group-item {
|
||||||
white-space: pre-line;
|
white-space: pre-line;
|
||||||
}
|
}
|
||||||
.card.card-fullscreen{
|
.card.card-fullscreen{
|
||||||
z-index:6;
|
z-index: 6;
|
||||||
}
|
}
|
||||||
.card.warnings-card, .card.errors-card{
|
.card.warnings-card, .card.errors-card{
|
||||||
text-transform: capitalize;
|
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{
|
.card.warnings-card .card-options a, .card.errors-card .card-options a{
|
||||||
cursor:pointer;
|
cursor:pointer;
|
||||||
}
|
}
|
||||||
.compilation-summary {
|
.compilation-summary {
|
||||||
float:right;
|
float: right;
|
||||||
margin-bottom:3px;
|
margin-bottom: 3px;
|
||||||
line-height:30px;
|
line-height: 30px;
|
||||||
visibility: hidden;
|
visibility: hidden;
|
||||||
}
|
}
|
||||||
.compilation-summary.visible{
|
.compilation-summary.visible{
|
||||||
visibility: visible;
|
visibility: visible;
|
||||||
}
|
}
|
||||||
.compilation-summary .badge-link:not(:last-child){
|
.compilation-summary .badge-link:not(:last-child){
|
||||||
margin-right:5px;
|
margin-right: 5px;
|
||||||
}
|
}
|
||||||
.ace_editor {
|
.ace_editor {
|
||||||
margin-bottom:24px;
|
margin-bottom: 24px;
|
||||||
}
|
}
|
||||||
.loader, .loader:before, .loader:after{
|
.loader, .loader:before, .loader:after{
|
||||||
width:1.2rem;
|
width: 1.2rem;
|
||||||
height:1.2rem;
|
height: 1.2rem;
|
||||||
}
|
}
|
||||||
.loader:before, .loader:after{
|
.loader:before, .loader:after{
|
||||||
margin:-0.6rem 0 0 -0.6rem;
|
margin: -0.6rem 0 0 -0.6rem;
|
||||||
}
|
}
|
||||||
.loader, .loader-text{
|
.loader, .loader-text{
|
||||||
display:inline-block;
|
display: inline-block;
|
||||||
vertical-align: middle;
|
vertical-align: middle;
|
||||||
}
|
}
|
||||||
.loader {
|
.loader {
|
||||||
margin-right:5px;
|
margin-right: 5px;
|
||||||
}
|
}
|
|
@ -1,14 +0,0 @@
|
||||||
import {COMPILE_CODE_REQUEST, COMPILE_CODE_FAILURE, COMPILE_CODE_SUCCESS} from "../actions";
|
|
||||||
|
|
||||||
export default function processes(state = {}, action) {
|
|
||||||
switch (action.type) {
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,6 +1,5 @@
|
||||||
import {combineReducers} from 'redux';
|
import {combineReducers} from 'redux';
|
||||||
import {REQUEST} from "../actions";
|
import {REQUEST} from "../actions";
|
||||||
import fiddleRecuder from './fiddleReducer';
|
|
||||||
|
|
||||||
const BN_FACTOR = 10000;
|
const BN_FACTOR = 10000;
|
||||||
|
|
||||||
|
@ -16,7 +15,8 @@ const entitiesDefaultState = {
|
||||||
commands: [],
|
commands: [],
|
||||||
messages: [],
|
messages: [],
|
||||||
messageChannels: [],
|
messageChannels: [],
|
||||||
messageVersion: null
|
messageVersion: null,
|
||||||
|
fiddle: null
|
||||||
};
|
};
|
||||||
|
|
||||||
const sorter = {
|
const sorter = {
|
||||||
|
@ -97,8 +97,7 @@ function loading(_state = false, action) {
|
||||||
const rootReducer = combineReducers({
|
const rootReducer = combineReducers({
|
||||||
entities,
|
entities,
|
||||||
loading,
|
loading,
|
||||||
errorMessage,
|
errorMessage
|
||||||
fiddles: fiddleRecuder
|
|
||||||
});
|
});
|
||||||
|
|
||||||
export default rootReducer;
|
export default rootReducer;
|
||||||
|
|
|
@ -80,3 +80,7 @@ export function getMessages(state) {
|
||||||
});
|
});
|
||||||
return messages;
|
return messages;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function getFiddle(state){
|
||||||
|
return state.entities.fiddle;
|
||||||
|
}
|
||||||
|
|
|
@ -4,7 +4,8 @@ import {eventChannel} from 'redux-saga';
|
||||||
import {all, call, fork, put, takeEvery, take} from 'redux-saga/effects';
|
import {all, call, fork, put, takeEvery, take} from 'redux-saga/effects';
|
||||||
|
|
||||||
const {account, accounts, block, blocks, transaction, transactions, processes, commands, processLogs,
|
const {account, accounts, block, blocks, transaction, transactions, processes, commands, processLogs,
|
||||||
contracts, contract, contractProfile, messageSend, messageVersion, messageListen, contractLogs} = actions;
|
contracts, contract, contractProfile, messageSend, messageVersion, messageListen, contractLogs,
|
||||||
|
fiddle} = actions;
|
||||||
|
|
||||||
function *doRequest(entity, apiFn, payload) {
|
function *doRequest(entity, apiFn, payload) {
|
||||||
const {response, error} = yield call(apiFn, payload);
|
const {response, error} = yield call(apiFn, payload);
|
||||||
|
@ -28,6 +29,7 @@ export const fetchContractLogs = doRequest.bind(null, contractLogs, api.fetchCon
|
||||||
export const fetchContracts = doRequest.bind(null, contracts, api.fetchContracts);
|
export const fetchContracts = doRequest.bind(null, contracts, api.fetchContracts);
|
||||||
export const fetchContract = doRequest.bind(null, contract, api.fetchContract);
|
export const fetchContract = doRequest.bind(null, contract, api.fetchContract);
|
||||||
export const fetchContractProfile = doRequest.bind(null, contractProfile, api.fetchContractProfile);
|
export const fetchContractProfile = doRequest.bind(null, contractProfile, api.fetchContractProfile);
|
||||||
|
export const fetchFiddle = doRequest.bind(null, fiddle, api.fetchFiddle);
|
||||||
|
|
||||||
export function *watchFetchTransaction() {
|
export function *watchFetchTransaction() {
|
||||||
yield takeEvery(actions.TRANSACTION[actions.REQUEST], fetchTransaction);
|
yield takeEvery(actions.TRANSACTION[actions.REQUEST], fetchTransaction);
|
||||||
|
@ -157,20 +159,8 @@ export function *watchCommunicationVersion() {
|
||||||
yield takeEvery(actions.MESSAGE_VERSION[actions.REQUEST], fetchCommunicationVersion);
|
yield takeEvery(actions.MESSAGE_VERSION[actions.REQUEST], fetchCommunicationVersion);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function *fetchCodeCompilation(action) {
|
export function *watchFetchFiddle() {
|
||||||
try {
|
yield takeEvery(actions.FIDDLE[actions.REQUEST], fetchFiddle);
|
||||||
const compilationResponse = yield call(api.fetchCodeCompilation, action.codeToCompile);
|
|
||||||
if(compilationResponse.status !== 200){
|
|
||||||
yield put(actions.receiveCodeCompilationError(compilationResponse.data));
|
|
||||||
}
|
|
||||||
else yield put(actions.receiveCodeCompilation(compilationResponse.data));
|
|
||||||
} catch (e) {
|
|
||||||
yield put(actions.receiveCodeCompilationError(e));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export function *watchFetchCodeCompilation() {
|
|
||||||
yield takeEvery(actions.COMPILE_CODE_REQUEST, fetchCodeCompilation);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export default function *root() {
|
export default function *root() {
|
||||||
|
@ -194,7 +184,7 @@ export default function *root() {
|
||||||
fork(watchFetchContract),
|
fork(watchFetchContract),
|
||||||
fork(watchFetchTransaction),
|
fork(watchFetchTransaction),
|
||||||
fork(watchFetchContractProfile),
|
fork(watchFetchContractProfile),
|
||||||
fork(watchFetchCodeCompilation)
|
fork(watchFetchFiddle)
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -25,23 +25,26 @@ class Solidity {
|
||||||
'post',
|
'post',
|
||||||
'/embark-api/contract/compile',
|
'/embark-api/contract/compile',
|
||||||
(req, res) => {
|
(req, res) => {
|
||||||
this.events.request("contract:compile", req.body.code, (errors, compilationResult) => {
|
const input = {'fiddler': {content: req.body.code.replace(/\r\n/g, '\n')}};
|
||||||
res.send({errors:errors, compilationResult: compilationResult});
|
this.compile_solidity_code(input, {}, true, (errors, compilationResult) => {
|
||||||
|
const responseData = {errors: errors, compilationResult: compilationResult};
|
||||||
|
this.logger.trace(`POST response /embark-api/contract/compile:\n ${JSON.stringify(responseData)}`);
|
||||||
|
res.send(responseData);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
_compile(jsonObj, returnAllErrors, callback){
|
_compile(jsonObj, returnAllErrors, callback) {
|
||||||
this.solcW.compile(jsonObj, (err, output) => {
|
this.solcW.compile(jsonObj, (err, output) => {
|
||||||
if(err){
|
if (err) {
|
||||||
return callback(err);
|
return callback(err);
|
||||||
}
|
}
|
||||||
if(output.errors && returnAllErrors){
|
if (output.errors && returnAllErrors) {
|
||||||
return callback(output.errors);
|
return callback(output.errors);
|
||||||
}
|
}
|
||||||
if (output.errors) {
|
if (output.errors) {
|
||||||
for (let i=0; i<output.errors.length; i++) {
|
for (let i = 0; i < output.errors.length; i++) {
|
||||||
if (output.errors[i].type === 'Warning') {
|
if (output.errors[i].type === 'Warning') {
|
||||||
this.logger.warn(output.errors[i].formattedMessage);
|
this.logger.warn(output.errors[i].formattedMessage);
|
||||||
}
|
}
|
||||||
|
@ -54,8 +57,7 @@ class Solidity {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
compile_solidity_code(codeInputs, originalFilepaths, returnAllErrors, cb){
|
compile_solidity_code(codeInputs, originalFilepaths, returnAllErrors, cb) {
|
||||||
|
|
||||||
const self = this;
|
const self = this;
|
||||||
|
|
||||||
async.waterfall([
|
async.waterfall([
|
||||||
|
@ -99,7 +101,7 @@ class Solidity {
|
||||||
},
|
},
|
||||||
function compileContracts(callback) {
|
function compileContracts(callback) {
|
||||||
self.logger.info(__("compiling solidity contracts") + "...");
|
self.logger.info(__("compiling solidity contracts") + "...");
|
||||||
let jsonObj = {
|
let jsonObj = {
|
||||||
language: 'Solidity',
|
language: 'Solidity',
|
||||||
sources: codeInputs,
|
sources: codeInputs,
|
||||||
settings: {
|
settings: {
|
||||||
|
@ -203,7 +205,7 @@ class Solidity {
|
||||||
async.waterfall([
|
async.waterfall([
|
||||||
function prepareInput(callback) {
|
function prepareInput(callback) {
|
||||||
async.each(contractFiles,
|
async.each(contractFiles,
|
||||||
function(file, fileCb) {
|
function (file, fileCb) {
|
||||||
let filename = file.filename;
|
let filename = file.filename;
|
||||||
|
|
||||||
for (let directory of self.contractDirectories) {
|
for (let directory of self.contractDirectories) {
|
||||||
|
@ -213,7 +215,7 @@ class Solidity {
|
||||||
|
|
||||||
originalFilepath[filename] = file.filename;
|
originalFilepath[filename] = file.filename;
|
||||||
|
|
||||||
file.content(function(fileContent) {
|
file.content(function (fileContent) {
|
||||||
if (!fileContent) {
|
if (!fileContent) {
|
||||||
self.logger.error(__('Error while loading the content of ') + filename);
|
self.logger.error(__('Error while loading the content of ') + filename);
|
||||||
return fileCb();
|
return fileCb();
|
||||||
|
|
Loading…
Reference in New Issue