upload JSON string
This commit is contained in:
@@ -7,13 +7,13 @@ import moment from 'moment';
|
||||
import localization from 'moment/locale/de';
|
||||
import * as Blockly from 'blockly/core';
|
||||
|
||||
import { parseXml } from '../../../helpers/compareXml';
|
||||
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 FormHelperText from '@material-ui/core/FormHelperText';
|
||||
import FormLabel from '@material-ui/core/FormLabel';
|
||||
import Button from '@material-ui/core/Button';
|
||||
import Grid from '@material-ui/core/Grid';
|
||||
|
||||
@@ -79,54 +79,56 @@ class BlocklyExample extends Component {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
render() {
|
||||
moment.locale('de', localization);
|
||||
var initialXml = this.props.value;
|
||||
// check if value is valid xml;
|
||||
try{
|
||||
Blockly.Xml.textToDom(initialXml);
|
||||
}
|
||||
catch(err){
|
||||
initialXml = null;
|
||||
this.props.setError(this.props.index, 'xml');
|
||||
}
|
||||
return (
|
||||
<div style={{marginBottom: '10px'}}>
|
||||
<FormControlLabel
|
||||
style={{margin: 0}}
|
||||
labelPlacement="start"
|
||||
label={this.props.task ? "Musterlösung" : "Blockly Beispiel"}
|
||||
control={
|
||||
<Switch
|
||||
disabled={this.props.task}
|
||||
checked={this.state.checked}
|
||||
onChange={(e) => this.onChange(e.target.checked)}
|
||||
color="primary"
|
||||
/>
|
||||
}
|
||||
/>
|
||||
{!this.props.task ?
|
||||
<FormControlLabel
|
||||
style={{margin: 0}}
|
||||
labelPlacement="end"
|
||||
label={"Blockly Beispiel"}
|
||||
control={
|
||||
<Switch
|
||||
checked={this.state.checked}
|
||||
onChange={(e) => this.onChange(e.target.checked)}
|
||||
color="primary"
|
||||
/>
|
||||
}
|
||||
/>
|
||||
: <FormLabel style={{color: 'black'}}>Musterlösung</FormLabel>}
|
||||
{this.state.checked ? !this.props.value || this.props.error.steps[this.props.index].xml ?
|
||||
<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>
|
||||
<Grid container className={!this.props.value ? this.props.classes.errorBorder : null}>
|
||||
<Grid item xs={12}>
|
||||
<BlocklyWindow initialXml={initialXml}/>
|
||||
{this.state.checked ? (() => {
|
||||
var initialXml = this.props.value;
|
||||
// check if value is valid xml;
|
||||
try{
|
||||
Blockly.Xml.textToDom(initialXml);
|
||||
}
|
||||
catch(err){
|
||||
initialXml = null;
|
||||
this.props.setError(this.props.index, 'xml');
|
||||
}
|
||||
return (
|
||||
<div>
|
||||
<Grid container className={!this.props.value ? this.props.classes.errorBorder : null}>
|
||||
<Grid item xs={12}>
|
||||
<BlocklyWindow initialXml={initialXml}/>
|
||||
</Grid>
|
||||
</Grid>
|
||||
</Grid>
|
||||
<Button
|
||||
className={!this.props.value || this.props.error.steps[this.props.index].xml ? this.props.classes.errorButton : null }
|
||||
style={{marginTop: '5px', height: '40px'}}
|
||||
variant='contained'
|
||||
color='primary'
|
||||
onClick={() => {this.props.changeContent(this.props.index, 'xml', this.props.xml); this.setState({input: moment(Date.now()).format('LTS')})}}
|
||||
>
|
||||
{this.props.task ? 'Musterlösung einreichen' : 'Beispiel einreichen'}
|
||||
</Button>
|
||||
</div>
|
||||
<Button
|
||||
className={!this.props.value || this.props.error.steps[this.props.index].xml ? this.props.classes.errorButton : null }
|
||||
style={{marginTop: '5px', height: '40px'}}
|
||||
variant='contained'
|
||||
color='primary'
|
||||
onClick={() => {this.props.changeContent(this.props.index, 'xml', this.props.xml); this.setState({input: moment(Date.now()).format('LTS')})}}
|
||||
>
|
||||
{this.props.task ? 'Musterlösung einreichen' : 'Beispiel einreichen'}
|
||||
</Button>
|
||||
</div>
|
||||
)})()
|
||||
: null}
|
||||
</div>
|
||||
);
|
||||
|
||||
@@ -1,17 +1,17 @@
|
||||
import React, { Component } from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { connect } from 'react-redux';
|
||||
import { checkError, readJSON, progress, resetTutorial } from '../../../actions/tutorialBuilderActions';
|
||||
import { checkError, readJSON, jsonString, progress, resetTutorial } from '../../../actions/tutorialBuilderActions';
|
||||
|
||||
import { saveAs } from 'file-saver';
|
||||
|
||||
import data from '../../../data/hardware.json';
|
||||
import { detectWhitespacesAndReturnReadableResult } from '../../../helpers/whitespace';
|
||||
|
||||
import Breadcrumbs from '../../Breadcrumbs';
|
||||
import Id from './Id';
|
||||
import Title from './Textfield';
|
||||
import Textfield from './Textfield';
|
||||
import Step from './Step';
|
||||
import Dialog from '../../Dialog';
|
||||
|
||||
import { withStyles } from '@material-ui/core/styles';
|
||||
import Button from '@material-ui/core/Button';
|
||||
@@ -30,6 +30,12 @@ class Builder extends Component {
|
||||
|
||||
constructor(props){
|
||||
super(props);
|
||||
this.state = {
|
||||
open: false,
|
||||
title: '',
|
||||
content: '',
|
||||
string: false
|
||||
};
|
||||
this.inputRef = React.createRef();
|
||||
}
|
||||
|
||||
@@ -57,30 +63,37 @@ class Builder extends Component {
|
||||
uploadJsonFile = (jsonFile) => {
|
||||
this.props.progress(true);
|
||||
if(jsonFile.type !== 'application/json'){
|
||||
alert('falscher Dateityp');
|
||||
this.props.progress(false);
|
||||
this.setState({ open: true, file: false, title: 'Unzulässiger Dateityp', content: 'Die übergebene Datei entsprach nicht dem geforderten Format. Es sind nur JSON-Dateien zulässig.' });
|
||||
this.setState({ open: true, string: false, title: 'Unzulässiger Dateityp', content: 'Die übergebene Datei entspricht nicht dem geforderten Format. Es sind nur JSON-Dateien zulässig.'});
|
||||
}
|
||||
else {
|
||||
var reader = new FileReader();
|
||||
reader.readAsText(jsonFile);
|
||||
reader.onloadend = () => {
|
||||
try {
|
||||
var result = JSON.parse(reader.result);
|
||||
if(!this.checkSteps(result.steps)){
|
||||
result.steps = [{}];
|
||||
}
|
||||
this.props.readJSON(result);
|
||||
} catch(err){
|
||||
console.log(err);
|
||||
this.props.progress(false);
|
||||
alert('ungültige JSON-Datei');
|
||||
this.setState({ open: true, file: false, title: 'Ungültige XML', content: 'Die XML-Datei konnte nicht in Blöcke zerlegt werden. Bitte überprüfe den XML-Code und versuche es erneut.' });
|
||||
}
|
||||
this.readJson(reader.result, true);
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
uploadJsonString = () => {
|
||||
this.setState({ open: true, string: true, title: 'JSON-String einfügen', content: ''});
|
||||
}
|
||||
|
||||
readJson = (jsonString, isFile) => {
|
||||
try {
|
||||
var result = JSON.parse(jsonString);
|
||||
if(!this.checkSteps(result.steps)){
|
||||
result.steps = [{}];
|
||||
}
|
||||
this.props.readJSON(result);
|
||||
} catch(err){
|
||||
console.log(err);
|
||||
this.props.progress(false);
|
||||
this.props.jsonString('');
|
||||
this.setState({ open: true, string: false, title: 'Ungültiges JSON-Format', content: `${isFile ? 'Die übergebene Datei' : 'Der übergebene String'} enthält nicht valides JSON. Bitte überprüfe ${isFile ? 'die JSON-Datei' : 'den JSON-String'} und versuche es erneut.`});
|
||||
}
|
||||
}
|
||||
|
||||
checkSteps = (steps) => {
|
||||
if(!(steps && steps.length > 0)){
|
||||
return false;
|
||||
@@ -88,6 +101,10 @@ class Builder extends Component {
|
||||
return true;
|
||||
}
|
||||
|
||||
toggle = () => {
|
||||
this.setState({ open: !this.state });
|
||||
}
|
||||
|
||||
|
||||
render() {
|
||||
return (
|
||||
@@ -96,6 +113,7 @@ class Builder extends Component {
|
||||
|
||||
<h1>Tutorial-Builder</h1>
|
||||
|
||||
{/*upload JSON*/}
|
||||
<div ref={this.inputRef}>
|
||||
<input
|
||||
style={{display: 'none'}}
|
||||
@@ -107,30 +125,50 @@ class Builder extends Component {
|
||||
<label htmlFor="open-json">
|
||||
<Button component="span" style={{marginRight: '10px', marginBottom: '10px'}} variant='contained' color='primary'>Datei laden</Button>
|
||||
</label>
|
||||
<Button style={{marginRight: '10px', marginBottom: '10px'}} variant='contained' color='primary' onClick={() => this.uploadJsonString()}>String laden</Button>
|
||||
</div>
|
||||
<Divider variant='fullWidth' style={{margin: '10px 0 30px 0'}}/>
|
||||
|
||||
{/*Tutorial-Builder-Form*/}
|
||||
<Id error={this.props.error} value={this.props.id}/>
|
||||
<Title value={this.props.title} property={'title'} label={'Titel'} error={this.props.error}/>
|
||||
<Textfield value={this.props.title} property={'title'} label={'Titel'} error={this.props.error}/>
|
||||
|
||||
{this.props.steps.map((step, i) =>
|
||||
<Step step={step} index={i} />
|
||||
|
||||
)}
|
||||
|
||||
|
||||
{/*submit or reset*/}
|
||||
<Button style={{marginRight: '10px'}} variant='contained' color='primary' onClick={() => this.submit()}>Tutorial-Vorlage erstellen</Button>
|
||||
<Button variant='contained' onClick={() => this.reset()}>Zurücksetzen</Button>
|
||||
|
||||
<Backdrop className={this.props.classes.backdrop} open={this.props.isProgress}>
|
||||
<CircularProgress color="inherit" />
|
||||
</Backdrop>
|
||||
|
||||
<Dialog
|
||||
open={this.state.open}
|
||||
maxWidth={this.state.string ? 'md' : 'sm'}
|
||||
fullWidth={this.state.string}
|
||||
title={this.state.title}
|
||||
content={this.state.content}
|
||||
onClose={this.toggle}
|
||||
onClick={this.toggle}
|
||||
button={'Schließen'}
|
||||
actions={
|
||||
this.state.string ?
|
||||
<div>
|
||||
<Button disabled={this.props.error.json || this.props.json === ''} variant='contained' onClick={() => {this.toggle(); this.props.progress(true); this.readJson(this.props.json, false);}} color="primary">Bestätigen</Button>
|
||||
<Button onClick={() => {this.toggle(); this.props.jsonString('');}} color="primary">Abbrechen</Button>
|
||||
</div>
|
||||
: null
|
||||
}
|
||||
>
|
||||
{this.state.string ?
|
||||
<Textfield value={this.props.json} property={'json'} label={'JSON'} multiline error={this.props.error}/>
|
||||
: null}
|
||||
</Dialog>
|
||||
|
||||
</div>
|
||||
/*<div style={{borderRadius: '25px', background: 'yellow', textAlign: 'center'}}>
|
||||
<Typography variant='h4'>Tutorial-Builder</Typography>
|
||||
</div>
|
||||
*/
|
||||
);
|
||||
};
|
||||
}
|
||||
@@ -138,12 +176,14 @@ class Builder extends Component {
|
||||
Builder.propTypes = {
|
||||
checkError: PropTypes.func.isRequired,
|
||||
readJSON: PropTypes.func.isRequired,
|
||||
jsonString: PropTypes.func.isRequired,
|
||||
progress: PropTypes.func.isRequired,
|
||||
resetTutorial: PropTypes.func.isRequired,
|
||||
title: PropTypes.string.isRequired,
|
||||
steps: PropTypes.array.isRequired,
|
||||
change: PropTypes.number.isRequired,
|
||||
error: PropTypes.object.isRequired,
|
||||
json: PropTypes.string.isRequired,
|
||||
isProgress: PropTypes.bool.isRequired
|
||||
};
|
||||
|
||||
@@ -153,7 +193,8 @@ const mapStateToProps = state => ({
|
||||
steps: state.builder.steps,
|
||||
change: state.builder.change,
|
||||
error: state.builder.error,
|
||||
json: state.builder.json,
|
||||
isProgress: state.builder.progress
|
||||
});
|
||||
|
||||
export default connect(mapStateToProps, { checkError, readJSON, progress, resetTutorial })(withStyles(styles, {withTheme: true})(Builder));
|
||||
export default connect(mapStateToProps, { checkError, readJSON, jsonString, progress, resetTutorial })(withStyles(styles, {withTheme: true})(Builder));
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import React, { Component } from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { connect } from 'react-redux';
|
||||
import { tutorialTitle, changeContent, setError, deleteError } from '../../../actions/tutorialBuilderActions';
|
||||
import { tutorialTitle, jsonString, changeContent, setError, deleteError } from '../../../actions/tutorialBuilderActions';
|
||||
|
||||
import { withStyles } from '@material-ui/core/styles';
|
||||
import OutlinedInput from '@material-ui/core/OutlinedInput';
|
||||
@@ -25,6 +25,9 @@ class Textfield extends Component {
|
||||
if(this.props.property === 'title'){
|
||||
this.props.tutorialTitle(value);
|
||||
}
|
||||
else if(this.props.property === 'json'){
|
||||
this.props.jsonString(value);
|
||||
}
|
||||
else {
|
||||
this.props.changeContent(this.props.index, this.props.property, value);
|
||||
}
|
||||
@@ -55,7 +58,9 @@ class Textfield extends Component {
|
||||
{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>
|
||||
: this.props.error[this.props.property] ?
|
||||
this.props.property === 'title' ? <FormHelperText className={this.props.classes.errorColor}>Gib einen Titel für das Tutorial ein.</FormHelperText>
|
||||
: <FormHelperText className={this.props.classes.errorColor}>Gib einen JSON-String ein und bestätige diesen mit einem Klick auf den entsprechenden Button</FormHelperText>
|
||||
: null}
|
||||
</FormControl>
|
||||
);
|
||||
@@ -64,6 +69,7 @@ class Textfield extends Component {
|
||||
|
||||
Textfield.propTypes = {
|
||||
tutorialTitle: PropTypes.func.isRequired,
|
||||
jsonString: PropTypes.func.isRequired,
|
||||
changeContent: PropTypes.func.isRequired,
|
||||
error: PropTypes.object.isRequired,
|
||||
change: PropTypes.number.isRequired
|
||||
@@ -74,4 +80,4 @@ const mapStateToProps = state => ({
|
||||
change: state.builder.change
|
||||
});
|
||||
|
||||
export default connect(mapStateToProps, { tutorialTitle, changeContent, setError, deleteError })(withStyles(styles, { withTheme: true })(Textfield));
|
||||
export default connect(mapStateToProps, { tutorialTitle, jsonString, changeContent, setError, deleteError })(withStyles(styles, { withTheme: true })(Textfield));
|
||||
|
||||
Reference in New Issue
Block a user