Added loading entities

Moved functionality out of FiddleDeployButton component

Added loading entities (WIP) to separate loading messages
This commit is contained in:
emizzle 2018-08-20 22:52:30 +10:00 committed by Pascal Precht
parent bf46b91166
commit 4d195657dd
No known key found for this signature in database
GPG Key ID: 0EE28D8D6FD85D7D
8 changed files with 73 additions and 53 deletions

View File

@ -8,6 +8,7 @@
"classnames": "^2.2.6",
"connected-react-router": "^4.3.0",
"history": "^4.7.2",
"lodash": "^4.17.10",
"prop-types": "^15.6.2",
"react": "^16.4.1",
"react-ace": "^6.1.4",

View File

@ -170,14 +170,14 @@ export const ensRecords = {
export const FIDDLE = createRequestTypes('FIDDLE');
export const fiddle = {
request: (codeToCompile) => action(FIDDLE[REQUEST], {codeToCompile}),
request: (codeToCompile) => action(FIDDLE[REQUEST], {codeToCompile, loading: 'Compiling...'}),
success: (fiddle) => action(FIDDLE[SUCCESS], {fiddles: [fiddle]}),
failure: (error) => action(FIDDLE[FAILURE], {error})
};
export const FIDDLE_DEPLOY = createRequestTypes('FIDDLE_DEPLOY');
export const fiddleDeploy = {
request: (compiledCode) => action(FIDDLE_DEPLOY[REQUEST], {compiledCode}),
request: (compiledCode) => action(FIDDLE_DEPLOY[REQUEST], {compiledCode, loading: 'Deploying...'}),
success: () => action(FIDDLE_DEPLOY[SUCCESS]),
failure: (error) => action(FIDDLE_DEPLOY[FAILURE], {error})
};

View File

@ -1,47 +1,29 @@
import React, {Component} from 'react';
import PropTypes from 'prop-types';
import {Button} from 'tabler-react';
import {fiddleDeploy as fiddleDeployAction} from '../actions';
import {connect} from 'react-redux';
import {getFiddle} from '../reducers/selectors';
class FiddleDeployButton extends Component{
handleClick(){
this.props.postFiddleDeploy(this.props.fiddle);
}
render (){
return (
<Button
color="success"
onClick={(e) => this.handleClick(e)}>
color="dark"
size="sm"
icon="upload-cloud"
onClick={(e) => this.props.onDeployClick(e)}>
Deploy
</Button>
);
}
}
function mapStateToProps(state) {
return {
fiddle: getFiddle(state),
error: state.errorMessage,
loading: state.loading,
compiledContract: state.compiledContract
};
}
FiddleDeployButton.propTypes = {
fiddle: PropTypes.object,
postFiddleDeploy: PropTypes.func,
onDeployClick: PropTypes.func,
loading: PropTypes.bool,
compiledContract: PropTypes.object,
error: PropTypes.string
};
export default connect(
mapStateToProps,
{
postFiddleDeploy: fiddleDeployAction.request
},
)(FiddleDeployButton);
export default FiddleDeployButton;

View File

@ -1,6 +1,6 @@
/* eslint {jsx-a11y/anchor-has-content:"off"} */
import React, {Component} from 'react';
import {Card, List, Badge, Icon} from 'tabler-react';
import {Card, List, Badge, Icon, Dimmer} from 'tabler-react';
import PropTypes from 'prop-types';
import classNames from 'classnames';
@ -24,7 +24,7 @@ class FiddleResults extends Component {
this.setState(updatedState);
}
_getFormatted(errors, errorType){
_getFormatted(errors, errorType, loading){
const color = (errorType === "error" ? "danger" : errorType);
const isFullscreen = Boolean(this.state[errorType + 'sFullscreen']);
const classes = classNames({
@ -46,15 +46,17 @@ class FiddleResults extends Component {
</Card.Options>
</Card.Header>
<Card.Body>
<List.Group>
{errors.map(error => { return error.node; })}
</List.Group>
<Dimmer active={loading ? "active" : ""} loader>
<List.Group>
{errors.map(error => { return error.node; })}
</List.Group>
</Dimmer>
</Card.Body>
</Card>;
}
render() {
const {warnings, errors, fatal} = this.props;
const {warnings, errors, fatal, isLoading} = this.props;
let renderings = [];
if(fatal){
@ -80,13 +82,13 @@ class FiddleResults extends Component {
if (errors.length) renderings.push(
<React.Fragment key="errors">
<a id="errors" aria-hidden="true"/>
{this._getFormatted(errors, "error")}
{this._getFormatted(errors, "error", isLoading)}
</React.Fragment>
);
if (warnings.length) renderings.push(
<React.Fragment key="warnings">
<a id="warnings" aria-hidden="true"/>
{this._getFormatted(warnings, "warning")}
{this._getFormatted(warnings, "warning", isLoading)}
</React.Fragment>
);
}
@ -102,7 +104,8 @@ class FiddleResults extends Component {
FiddleResults.propTypes = {
errors: PropTypes.array,
warnings: PropTypes.array,
fatal: PropTypes.string
fatal: PropTypes.string,
isLoading: PropTypes.bool
};
export default FiddleResults;

View File

@ -6,7 +6,7 @@ import FiddleDeployButton from './FiddleDeployButton';
class FiddleResultsSummary extends Component{
render(){
const {warnings, errors, isFetching, hasResult, fatal} = this.props;
const {warnings, errors, isLoading, loadingMessage, hasResult, fatal} = this.props;
let renderings = [];
if(fatal) {
renderings.push(
@ -15,9 +15,9 @@ class FiddleResultsSummary extends Component{
</React.Fragment>
);
}
else if(isFetching){
else if(isLoading){
renderings.push(
<React.Fragment key="compiling"><div className="loader"></div><span className="loader-text">Compiling...</span></React.Fragment>
<React.Fragment key="loading"><div className="loader"></div><span className="loader-text">{loadingMessage}</span></React.Fragment>
);
}
else {
@ -25,7 +25,7 @@ class FiddleResultsSummary extends Component{
renderings.push(
<React.Fragment key="success">
<Badge className="badge-link" color="success">Compiled</Badge>
<FiddleDeployButton />
<FiddleDeployButton onDeployClick={this.props.onDeployClick} />
</React.Fragment>
);
}
@ -41,9 +41,9 @@ class FiddleResultsSummary extends Component{
);
}
return (
<div className={"compilation-summary " + ((hasResult || isFetching) ? "visible" : "")}>
<div className={"compilation-summary " + ((hasResult || isLoading) ? "visible" : "")}>
{renderings}
{!(hasResult || isFetching) ? "&nbsp;" : ""}
{!(hasResult || isLoading) ? "&nbsp;" : ""}
</div>
);
}
@ -52,9 +52,11 @@ class FiddleResultsSummary extends Component{
FiddleResultsSummary.propTypes = {
errors: PropTypes.array,
warnings: PropTypes.array,
isFetching: PropTypes.bool,
isLoading: PropTypes.bool,
loadingMessage: PropTypes.string,
hasResult: PropTypes.bool,
fatal: PropTypes.string
fatal: PropTypes.string,
onDeployClick: PropTypes.func
};
export default FiddleResultsSummary;

View File

@ -3,7 +3,7 @@
import React, {Component} from 'react';
import {connect} from 'react-redux';
import PropTypes from 'prop-types';
import {fiddle as fiddleAction} from '../actions';
import {fiddle as fiddleAction, fiddleDeploy as fiddleDeployAction} from '../actions';
import Fiddle from '../components/Fiddle';
import FiddleResults from '../components/FiddleResults';
import FiddleResultsSummary from '../components/FiddleResultsSummary';
@ -74,8 +74,12 @@ class FiddleContainer extends Component {
scrollToComponent(this.ace);
}
_onDeployClick(){
this.props.postFiddleDeploy(this.props.fiddle);
}
render() {
const {fiddle, loading, error} = this.props;
const {fiddle, loading, loadingMessage, error} = this.props;
let renderings = [];
let warnings = [];
let errors = [];
@ -87,10 +91,12 @@ class FiddleContainer extends Component {
<React.Fragment key="fiddle">
<FiddleResultsSummary
errors={errors}
warnings={warnings}
isFetching={loading}
warnings={warnings}
isLoading={loading}
loadingMessage={loadingMessage}
hasResult={Boolean(fiddle)}
fatal={error}
onDeployClick={this._onDeployClick}
/>
<Fiddle
value={this.state.value}
@ -113,6 +119,7 @@ class FiddleContainer extends Component {
errors={errors}
warnings={warnings}
fatal={error}
isLoading={loading}
/>);
}
@ -126,9 +133,11 @@ class FiddleContainer extends Component {
}
}
function mapStateToProps(state) {
const fiddle = getFiddle(state);
return {
fiddle: getFiddle(state),
error: state.errorMessage,
fiddle: fiddle.data,
error: fiddle.error,
loadingMessage: fiddle.loading,
loading: state.loading
};
}
@ -136,13 +145,16 @@ function mapStateToProps(state) {
FiddleContainer.propTypes = {
fiddle: PropTypes.object,
error: PropTypes.string,
loading: PropTypes.bool,
loadingMessage: PropTypes.string,
postFiddle: PropTypes.func,
loading: PropTypes.bool
postFiddleDeploy: PropTypes.func
};
export default connect(
mapStateToProps,
{
postFiddle: fiddleAction.request
postFiddle: fiddleAction.request,
postFiddleDeploy: fiddleDeployAction.request
},
)(FiddleContainer);

View File

@ -114,6 +114,19 @@ function errorEntities(state = {}, action) {
return {...state, ...newState};
}
function loadingEntities(state = {}, action) {
if (!action.type.endsWith(REQUEST)) {
return state;
}
let newState = {};
for (let name of Object.keys(entitiesDefaultState)) {
if (action[name] && action[name].length > 0) {
newState[name] = action[name][0].loading || "Loading...";
}
}
return {...state, ...newState};
}
function loading(_state = false, action) {
return action.type.endsWith(REQUEST);
}
@ -122,7 +135,8 @@ const rootReducer = combineReducers({
entities,
loading,
errorMessage,
errorEntities
errorEntities,
loadingEntities
});
export default rootReducer;

View File

@ -1,3 +1,5 @@
import _ from 'lodash';
export function getAccounts(state) {
return state.entities.accounts;
}
@ -103,7 +105,11 @@ export function getMessages(state) {
}
export function getFiddle(state) {
return state.entities.fiddles[state.entities.fiddles.length - 1];
return {
data: _.last(state.entities.fiddles),
error: _.last(state.errorEntities.fiddles),
loading: _.last(state.loadingEntities)
};
}
export function getEnsRecords(state) {