error validation
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
import React, { Component } from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { connect } from 'react-redux';
|
||||
import { changeContent, deleteProperty } from '../../../actions/tutorialBuilderActions';
|
||||
import { changeContent, deleteProperty, setError, deleteError } from '../../../actions/tutorialBuilderActions';
|
||||
|
||||
import moment from 'moment';
|
||||
import localization from 'moment/locale/de';
|
||||
@@ -11,7 +11,7 @@ import BlocklyWindow from '../../Blockly/BlocklyWindow';
|
||||
import { withStyles } from '@material-ui/core/styles';
|
||||
import Switch from '@material-ui/core/Switch';
|
||||
import FormControlLabel from '@material-ui/core/FormControlLabel';
|
||||
import FormLabel from '@material-ui/core/FormLabel';
|
||||
import FormHelperText from '@material-ui/core/FormHelperText';
|
||||
import Button from '@material-ui/core/Button';
|
||||
import Grid from '@material-ui/core/Grid';
|
||||
|
||||
@@ -42,9 +42,29 @@ class BlocklyExample extends Component {
|
||||
};
|
||||
}
|
||||
|
||||
componentDidUpdate(props){
|
||||
componentDidMount(){
|
||||
if(this.props.task){
|
||||
this.props.setError(this.props.index, 'xml');
|
||||
}
|
||||
}
|
||||
|
||||
componentDidUpdate(props, state){
|
||||
if(props.task !== this.props.task || props.value !== this.props.value){
|
||||
this.setState({checked: this.props.task ? this.props.task : this.props.value ? true : false});
|
||||
this.setState({checked: this.props.task ? this.props.task : this.props.value ? true : false},
|
||||
() => this.isError()
|
||||
);
|
||||
}
|
||||
if(state.checked !== this.state.checked){
|
||||
this.isError();
|
||||
}
|
||||
}
|
||||
|
||||
isError = () => {
|
||||
if(this.state.checked && !this.props.value){
|
||||
this.props.setError(this.props.index, 'xml');
|
||||
}
|
||||
else {
|
||||
this.props.deleteError(this.props.index, 'xml');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -75,8 +95,8 @@ class BlocklyExample extends Component {
|
||||
}
|
||||
/>
|
||||
{this.state.checked ? !this.props.value ?
|
||||
<FormLabel className={this.props.classes.errorColor}>Es ist noch keine Eingabe gemacht worden.</FormLabel>
|
||||
: <FormLabel>Die letzte Einreichung erfolgte um {this.state.input} Uhr.</FormLabel>
|
||||
<FormHelperText style={{lineHeight: 'initial', marginBottom: '10px'}} className={this.props.classes.errorColor}>Reiche deine Blöcke ein, indem du auf den rot gefärbten Button klickst.</FormHelperText>
|
||||
: <FormHelperText style={{lineHeight: 'initial', marginBottom: '10px'}}>Die letzte Einreichung erfolgte um {this.state.input} Uhr.</FormHelperText>
|
||||
: null}
|
||||
{this.state.checked ?
|
||||
<div>
|
||||
@@ -104,6 +124,8 @@ class BlocklyExample extends Component {
|
||||
BlocklyExample.propTypes = {
|
||||
changeContent: PropTypes.func.isRequired,
|
||||
deleteProperty: PropTypes.func.isRequired,
|
||||
setError: PropTypes.func.isRequired,
|
||||
deleteError: PropTypes.func.isRequired,
|
||||
xml: PropTypes.string.isRequired
|
||||
};
|
||||
|
||||
@@ -112,4 +134,4 @@ const mapStateToProps = state => ({
|
||||
});
|
||||
|
||||
|
||||
export default connect(mapStateToProps, { changeContent, deleteProperty })(withStyles(styles, {withTheme: true})(BlocklyExample));
|
||||
export default connect(mapStateToProps, { changeContent, deleteProperty, setError, deleteError })(withStyles(styles, {withTheme: true})(BlocklyExample));
|
||||
|
||||
@@ -1,21 +1,14 @@
|
||||
import React, { Component } from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { connect } from 'react-redux';
|
||||
import { checkError } from '../../../actions/tutorialBuilderActions';
|
||||
|
||||
import Breadcrumbs from '../../Breadcrumbs';
|
||||
import Id from './Id';
|
||||
import Title from './Textfield';
|
||||
import Step from './Step';
|
||||
|
||||
import Typography from '@material-ui/core/Typography';
|
||||
import Button from '@material-ui/core/Button';
|
||||
import TextField from '@material-ui/core/TextField';
|
||||
import OutlinedInput from '@material-ui/core/OutlinedInput';
|
||||
import InputLabel from '@material-ui/core/InputLabel';
|
||||
import FormControl from '@material-ui/core/FormControl';
|
||||
|
||||
import { faPlus, faMinus } from "@fortawesome/free-solid-svg-icons";
|
||||
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
||||
|
||||
class Builder extends Component {
|
||||
|
||||
@@ -27,8 +20,8 @@ class Builder extends Component {
|
||||
|
||||
<h1>Tutorial-Builder</h1>
|
||||
|
||||
<Id />
|
||||
<Title value={this.props.title} property={'title'} label={'Titel'}/>
|
||||
<Id error={this.props.error} value={this.props.id}/>
|
||||
<Title value={this.props.title} property={'title'} label={'Titel'} error={this.props.error}/>
|
||||
|
||||
{this.props.steps.map((step, i) =>
|
||||
<Step step={step} index={i} />
|
||||
@@ -36,7 +29,7 @@ class Builder extends Component {
|
||||
)}
|
||||
|
||||
|
||||
<Button variant='contained' color='primary' onClick={() => {alert('hi')}}>Submit</Button>
|
||||
<Button variant='contained' color='primary' onClick={() => {var error = this.props.checkError(); alert(error);}}>Tutorial-Vorlage erstellen</Button>
|
||||
|
||||
|
||||
</div>
|
||||
@@ -49,15 +42,19 @@ class Builder extends Component {
|
||||
}
|
||||
|
||||
Builder.propTypes = {
|
||||
checkError: PropTypes.func.isRequired,
|
||||
title: PropTypes.string.isRequired,
|
||||
steps: PropTypes.array.isRequired,
|
||||
change: PropTypes.number.isRequired
|
||||
change: PropTypes.number.isRequired,
|
||||
error: PropTypes.object.isRequired
|
||||
};
|
||||
|
||||
const mapStateToProps = state => ({
|
||||
title: state.builder.title,
|
||||
id: state.builder.id,
|
||||
steps: state.builder.steps,
|
||||
change: state.builder.change
|
||||
change: state.builder.change,
|
||||
error: state.builder.error
|
||||
});
|
||||
|
||||
export default connect(mapStateToProps, null)(Builder);
|
||||
export default connect(mapStateToProps, { checkError })(Builder);
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import React, { Component } from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { connect } from 'react-redux';
|
||||
import { changeContent } from '../../../actions/tutorialBuilderActions';
|
||||
import { changeContent, setError, deleteError } from '../../../actions/tutorialBuilderActions';
|
||||
|
||||
import hardware from '../../../data/hardware.json';
|
||||
|
||||
@@ -11,6 +11,7 @@ import withWidth, { isWidthDown } from '@material-ui/core/withWidth';
|
||||
import GridList from '@material-ui/core/GridList';
|
||||
import GridListTile from '@material-ui/core/GridListTile';
|
||||
import GridListTileBar from '@material-ui/core/GridListTileBar';
|
||||
import FormHelperText from '@material-ui/core/FormHelperText';
|
||||
|
||||
const styles = theme => ({
|
||||
multiGridListTile: {
|
||||
@@ -31,6 +32,11 @@ const styles = theme => ({
|
||||
width: 'calc(100% - 4px)',
|
||||
height: 'calc(100% - 4px)',
|
||||
border: `2px solid ${theme.palette.primary.main}`
|
||||
},
|
||||
errorColor: {
|
||||
color: theme.palette.error.dark,
|
||||
lineHeight: 'initial',
|
||||
marginBottom: '10px'
|
||||
}
|
||||
});
|
||||
|
||||
@@ -43,13 +49,22 @@ class Requirements extends Component {
|
||||
}
|
||||
else {
|
||||
hardwareArray.push(hardware);
|
||||
if(this.props.error.steps[this.props.index].hardware){
|
||||
this.props.deleteError(this.props.index, 'hardware');
|
||||
}
|
||||
}
|
||||
this.props.changeContent(this.props.index, 'hardware', hardwareArray);
|
||||
if(hardwareArray.length === 0){
|
||||
this.props.setError(this.props.index, 'hardware');
|
||||
}
|
||||
}
|
||||
|
||||
render() {
|
||||
var cols = isWidthDown('md', this.props.width) ? isWidthDown('sm', this.props.width) ? isWidthDown('xs', this.props.width) ? 2 : 3 : 4 : 6;
|
||||
return (
|
||||
<div>
|
||||
<FormHelperText style={this.props.error.steps[this.props.index].hardware ? {lineHeight: 'initial', marginTop: '5px'} : {marginTop: '5px', lineHeight: 'initial', marginBottom: '10px'}}>Beachte, dass die Reihenfolge des Auswählens maßgebend ist.</FormHelperText>
|
||||
{this.props.error.steps[this.props.index].hardware ? <FormHelperText className={this.props.classes.errorColor}>Wähle mindestens eine Hardware aus.</FormHelperText> : null}
|
||||
<GridList cellHeight={100} cols={cols} spacing={10}>
|
||||
{hardware.map((picture,i) => (
|
||||
<GridListTile key={i} onClick={() => this.onChange(picture.id)} classes={{tile: this.props.value.filter(value => value === picture.id).length > 0 ? this.props.classes.active : this.props.classes.border}}>
|
||||
@@ -67,16 +82,20 @@ class Requirements extends Component {
|
||||
</GridListTile>
|
||||
))}
|
||||
</GridList>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
}
|
||||
|
||||
Requirements.propTypes = {
|
||||
changeContent: PropTypes.func.isRequired
|
||||
changeContent: PropTypes.func.isRequired,
|
||||
setError: PropTypes.func.isRequired,
|
||||
deleteError: PropTypes.func.isRequired,
|
||||
change: PropTypes.number.isRequired
|
||||
};
|
||||
|
||||
const mapStateToProps = state => ({
|
||||
change: state.builder.change
|
||||
});
|
||||
|
||||
export default connect(mapStateToProps, { changeContent })(withStyles(styles, { withTheme: true })(withWidth()(Requirements)));
|
||||
export default connect(mapStateToProps, { changeContent, setError, deleteError })(withStyles(styles, { withTheme: true })(withWidth()(Requirements)));
|
||||
|
||||
@@ -1,5 +1,9 @@
|
||||
import React, { Component } from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { connect } from 'react-redux';
|
||||
import { tutorialId, setError, deleteError } from '../../../actions/tutorialBuilderActions';
|
||||
|
||||
import { withStyles } from '@material-ui/core/styles';
|
||||
import Button from '@material-ui/core/Button';
|
||||
import OutlinedInput from '@material-ui/core/OutlinedInput';
|
||||
import InputLabel from '@material-ui/core/InputLabel';
|
||||
@@ -9,29 +13,40 @@ import FormHelperText from '@material-ui/core/FormHelperText';
|
||||
import { faPlus, faMinus } from "@fortawesome/free-solid-svg-icons";
|
||||
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
||||
|
||||
class Id extends Component {
|
||||
|
||||
state = {
|
||||
id: 0,
|
||||
error: false
|
||||
const styles = theme => ({
|
||||
errorColor: {
|
||||
color: theme.palette.error.dark
|
||||
}
|
||||
});
|
||||
|
||||
class Id extends Component {
|
||||
|
||||
handleChange = (e) => {
|
||||
var value = parseInt(e.target.value);
|
||||
if(Number.isInteger(value)){
|
||||
this.setState({id: value, error: false});
|
||||
if(Number.isInteger(value) && value > 0){
|
||||
this.props.tutorialId(value);
|
||||
if(this.props.error.id){
|
||||
this.props.deleteError(undefined, 'id');
|
||||
}
|
||||
}
|
||||
else {
|
||||
this.setState({id: e.target.value, error: true});
|
||||
this.props.tutorialId(value);
|
||||
this.props.setError(undefined,'id');
|
||||
}
|
||||
};
|
||||
|
||||
handleCounter = (step) => {
|
||||
if(!this.state.id){
|
||||
this.setState({id: 0+step});
|
||||
if(this.props.value+step < 1){
|
||||
this.props.setError(undefined,'id');
|
||||
}
|
||||
else if(this.props.error.id){
|
||||
this.props.deleteError(undefined, 'id');
|
||||
}
|
||||
if(!this.props.value){
|
||||
this.props.tutorialId(0+step);
|
||||
}
|
||||
else {
|
||||
this.setState({id: this.state.id+step});
|
||||
this.props.tutorialId(this.props.value+step);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -41,8 +56,8 @@ class Id extends Component {
|
||||
<InputLabel htmlFor="id">ID</InputLabel>
|
||||
<OutlinedInput
|
||||
style={{borderRadius: '25px', padding: '0 0 0 10px', width: '200px'}}
|
||||
error={this.state.error}
|
||||
value={this.state.id}
|
||||
error={this.props.error.id}
|
||||
value={this.props.value}
|
||||
name='id'
|
||||
label='ID'
|
||||
id='id'
|
||||
@@ -53,6 +68,7 @@ class Id extends Component {
|
||||
endAdornment={
|
||||
<div style={{display: 'flex'}}>
|
||||
<Button
|
||||
disabled={this.props.value === 1 || !this.props.value}
|
||||
onClick={() => this.handleCounter(-1)}
|
||||
variant='contained'
|
||||
color='primary'
|
||||
@@ -71,10 +87,20 @@ class Id extends Component {
|
||||
</div>
|
||||
}
|
||||
/>
|
||||
{this.state.error ? <FormHelperText style={{color: 'red'}}>Es muss eine positive ganzzahlige Zahl sein.</FormHelperText> : null}
|
||||
{this.props.error.id ? <FormHelperText className={this.props.classes.errorColor}>Gib eine positive ganzzahlige Zahl ein.</FormHelperText> : null}
|
||||
</FormControl>
|
||||
);
|
||||
};
|
||||
}
|
||||
|
||||
export default Id;
|
||||
Id.propTypes = {
|
||||
tutorialId: PropTypes.func.isRequired,
|
||||
setError: PropTypes.func.isRequired,
|
||||
deleteError: PropTypes.func.isRequired
|
||||
};
|
||||
|
||||
const mapStateToProps = state => ({
|
||||
change: state.builder.change
|
||||
});
|
||||
|
||||
export default connect(mapStateToProps, { tutorialId, setError, deleteError })(withStyles(styles, { withTheme: true })(Id));
|
||||
|
||||
@@ -9,6 +9,7 @@ import FormGroup from '@material-ui/core/FormGroup';
|
||||
import Checkbox from '@material-ui/core/Checkbox';
|
||||
import FormControlLabel from '@material-ui/core/FormControlLabel';
|
||||
import FormLabel from '@material-ui/core/FormLabel';
|
||||
import FormHelperText from '@material-ui/core/FormHelperText';
|
||||
import FormControl from '@material-ui/core/FormControl';
|
||||
|
||||
class Requirements extends Component {
|
||||
@@ -29,7 +30,7 @@ class Requirements extends Component {
|
||||
return (
|
||||
<FormControl style={{marginBottom: '10px'}}>
|
||||
<FormLabel style={{color: 'black'}}>Voraussetzungen</FormLabel>
|
||||
<FormLabel style={{marginTop: '5px'}}>Beachte, dass die Reihenfolge des Anhakens maßgebend ist.</FormLabel>
|
||||
<FormHelperText style={{marginTop: '5px'}}>Beachte, dass die Reihenfolge des Anhakens maßgebend ist.</FormHelperText>
|
||||
<FormGroup>
|
||||
{tutorials.map((tutorial, i) =>
|
||||
<FormControlLabel
|
||||
|
||||
@@ -13,9 +13,6 @@ import { withStyles } from '@material-ui/core/styles';
|
||||
import Typography from '@material-ui/core/Typography';
|
||||
import IconButton from '@material-ui/core/IconButton';
|
||||
import Tooltip from '@material-ui/core/Tooltip';
|
||||
import OutlinedInput from '@material-ui/core/OutlinedInput';
|
||||
import InputLabel from '@material-ui/core/InputLabel';
|
||||
import FormControl from '@material-ui/core/FormControl';
|
||||
|
||||
import { faPlus, faAngleDoubleUp, faAngleDoubleDown, faTrash } from "@fortawesome/free-solid-svg-icons";
|
||||
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
||||
@@ -88,15 +85,15 @@ class Step extends Component {
|
||||
</div>
|
||||
<div style={{width: '100%', marginLeft: '54px'}}>
|
||||
<StepType value={this.props.step.type} index={index} />
|
||||
<Textfield value={this.props.step.headline} property={'headline'} label={'Überschrift'} index={index}/>
|
||||
<Textfield value={this.props.step.text} property={'text'} label={this.props.step.type === 'task' ? 'Aufgabenstellung' : 'Instruktionen'} index={index} multiline/>
|
||||
<Textfield value={this.props.step.headline} property={'headline'} label={'Überschrift'} index={index} error={this.props.error} errorText={`Gib eine Überschrift für die ${this.props.step.type === 'task' ? 'Aufgabe' : 'Anleitung'} ein.`} />
|
||||
<Textfield value={this.props.step.text} property={'text'} label={this.props.step.type === 'task' ? 'Aufgabenstellung' : 'Instruktionen'} index={index} multiline error={this.props.error} errorText={`Gib Instruktionen für die ${this.props.step.type === 'task' ? 'Aufgabe' : 'Anleitung'} ein.`}/>
|
||||
{index === 0 ?
|
||||
<div>
|
||||
<Requirements value={this.props.step.requirements} index={index}/>
|
||||
<Hardware value={this.props.step.hardware} index={index} />
|
||||
<Hardware value={this.props.step.hardware} index={index} error={this.props.error}/>
|
||||
</div>
|
||||
: null}
|
||||
<BlocklyExample value={this.props.step.xml} index={index} task={this.props.step.type === 'task'}/>
|
||||
<BlocklyExample value={this.props.step.xml} index={index} task={this.props.step.type === 'task'} />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -109,12 +106,14 @@ Step.propTypes = {
|
||||
removeStep: PropTypes.func.isRequired,
|
||||
changeStepIndex: PropTypes.func.isRequired,
|
||||
steps: PropTypes.array.isRequired,
|
||||
change: PropTypes.number.isRequired
|
||||
change: PropTypes.number.isRequired,
|
||||
error: PropTypes.object.isRequired,
|
||||
};
|
||||
|
||||
const mapStateToProps = state => ({
|
||||
steps: state.builder.steps,
|
||||
change: state.builder.change
|
||||
change: state.builder.change,
|
||||
error: state.builder.error
|
||||
});
|
||||
|
||||
export default connect(mapStateToProps, { addStep, removeStep, changeStepIndex })(withStyles(styles, {withTheme: true})(Step));
|
||||
|
||||
@@ -1,45 +1,62 @@
|
||||
import React, { Component } from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { connect } from 'react-redux';
|
||||
import { tutorialTitle, changeContent } from '../../../actions/tutorialBuilderActions';
|
||||
import { tutorialTitle, changeContent, setError, deleteError } from '../../../actions/tutorialBuilderActions';
|
||||
|
||||
import Button from '@material-ui/core/Button';
|
||||
import { withStyles } from '@material-ui/core/styles';
|
||||
import OutlinedInput from '@material-ui/core/OutlinedInput';
|
||||
import InputLabel from '@material-ui/core/InputLabel';
|
||||
import FormControl from '@material-ui/core/FormControl';
|
||||
import FormHelperText from '@material-ui/core/FormHelperText';
|
||||
|
||||
const styles = theme => ({
|
||||
multiline: {
|
||||
padding: '18.5px 14px 18.5px 24px'
|
||||
},
|
||||
errorColor: {
|
||||
color: theme.palette.error.dark
|
||||
}
|
||||
});
|
||||
|
||||
class Textfield extends Component {
|
||||
|
||||
// handleChange = (e) => {
|
||||
// var value = e.target.value;
|
||||
// if(value.replace(/\s/g,'') !== ''){
|
||||
// this.setState({[e.target.name]: value, error: false});
|
||||
// }
|
||||
// else {
|
||||
// this.setState({[e.target.name]: value, error: true});
|
||||
// }
|
||||
// };
|
||||
handleChange = (e) => {
|
||||
var value = e.target.value;
|
||||
if(this.props.property === 'title'){
|
||||
this.props.tutorialTitle(value);
|
||||
}
|
||||
else {
|
||||
this.props.changeContent(this.props.index, this.props.property, value);
|
||||
}
|
||||
if(value.replace(/\s/g,'') === ''){
|
||||
this.props.setError(this.props.index, this.props.property);
|
||||
}
|
||||
else{
|
||||
this.props.deleteError(this.props.index, this.props.property);
|
||||
}
|
||||
};
|
||||
|
||||
render() {
|
||||
return (
|
||||
<FormControl variant="outlined" fullWidth style={{marginBottom: '10px'}}>
|
||||
<InputLabel htmlFor={this.props.property}>{this.props.label}</InputLabel>
|
||||
<OutlinedInput
|
||||
style={this.props.multiline ? {borderRadius: '25px', padding: '18.5px 14px 18.5px 24px'} : {borderRadius: '25px', padding: '0 0 0 10px'}}
|
||||
/* error={this.state.error}*/
|
||||
style={{borderRadius: '25px'}}
|
||||
classes={{multiline: this.props.classes.multiline}}
|
||||
error={this.props.index !== undefined ? this.props.error.steps[this.props.index][this.props.property] : this.props.error[this.props.property]}
|
||||
value={this.props.value}
|
||||
label={this.props.label}
|
||||
id={this.props.property}
|
||||
multiline={this.props.multiline}
|
||||
rows={2}
|
||||
rowsMax={10}
|
||||
onChange={(e) => {this.props.property === 'title' ?
|
||||
this.props.tutorialTitle(e.target.value)
|
||||
: this.props.changeContent(this.props.index, this.props.property, e.target.value)
|
||||
}}
|
||||
onChange={(e) => this.handleChange(e)}
|
||||
/>
|
||||
{/* {this.state.error ? <FormHelperText style={{color: 'red'}}>Gib einen Titel für das Tutorial ein.</FormHelperText> : null}*/}
|
||||
{this.props.index !== undefined ?
|
||||
this.props.error.steps[this.props.index][this.props.property] ? <FormHelperText className={this.props.classes.errorColor}>{this.props.errorText}</FormHelperText>
|
||||
: null
|
||||
: this.props.error[this.props.property] ? <FormHelperText className={this.props.classes.errorColor}>Gib einen Titel für das Tutorial ein.</FormHelperText>
|
||||
: null}
|
||||
</FormControl>
|
||||
);
|
||||
};
|
||||
@@ -47,7 +64,14 @@ class Textfield extends Component {
|
||||
|
||||
Textfield.propTypes = {
|
||||
tutorialTitle: PropTypes.func.isRequired,
|
||||
changeContent: PropTypes.func.isRequired
|
||||
changeContent: PropTypes.func.isRequired,
|
||||
error: PropTypes.object.isRequired,
|
||||
change: PropTypes.number.isRequired
|
||||
};
|
||||
|
||||
export default connect(null, { tutorialTitle, changeContent })(Textfield);
|
||||
const mapStateToProps = state => ({
|
||||
error: state.builder.error,
|
||||
change: state.builder.change
|
||||
});
|
||||
|
||||
export default connect(mapStateToProps, { tutorialTitle, changeContent, setError, deleteError })(withStyles(styles, { withTheme: true })(Textfield));
|
||||
|
||||
Reference in New Issue
Block a user