upload JSON string
This commit is contained in:
		
							parent
							
								
									3ba35751ea
								
							
						
					
					
						commit
						fc1b898c80
					
				| @ -1,4 +1,4 @@ | |||||||
| import { PROGRESS, BUILDER_CHANGE, BUILDER_ERROR, BUILDER_TITLE, BUILDER_ID, BUILDER_ADD_STEP, BUILDER_DELETE_STEP, BUILDER_CHANGE_STEP, BUILDER_CHANGE_ORDER, BUILDER_DELETE_PROPERTY } from './types'; | import { PROGRESS, JSON_STRING, BUILDER_CHANGE, BUILDER_ERROR, BUILDER_TITLE, BUILDER_ID, BUILDER_ADD_STEP, BUILDER_DELETE_STEP, BUILDER_CHANGE_STEP, BUILDER_CHANGE_ORDER, BUILDER_DELETE_PROPERTY } from './types'; | ||||||
| 
 | 
 | ||||||
| import data from '../data/hardware.json'; | import data from '../data/hardware.json'; | ||||||
| 
 | 
 | ||||||
| @ -8,6 +8,13 @@ export const changeTutorialBuilder = () => (dispatch) => { | |||||||
|   }); |   }); | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
|  | export const jsonString = (json) => (dispatch) => { | ||||||
|  |   dispatch({ | ||||||
|  |     type: JSON_STRING, | ||||||
|  |     payload: json | ||||||
|  |   }); | ||||||
|  | }; | ||||||
|  | 
 | ||||||
| export const tutorialTitle = (title) => (dispatch) => { | export const tutorialTitle = (title) => (dispatch) => { | ||||||
|   dispatch({ |   dispatch({ | ||||||
|     type: BUILDER_TITLE, |     type: BUILDER_TITLE, | ||||||
|  | |||||||
| @ -14,6 +14,7 @@ export const TUTORIAL_CHANGE = 'TUTORIAL_CHANGE'; | |||||||
| export const TUTORIAL_XML = 'TUTORIAL_XML'; | export const TUTORIAL_XML = 'TUTORIAL_XML'; | ||||||
| export const TUTORIAL_ID = 'TUTORIAL_ID'; | export const TUTORIAL_ID = 'TUTORIAL_ID'; | ||||||
| export const TUTORIAL_STEP = 'TUTORIAL_STEP'; | export const TUTORIAL_STEP = 'TUTORIAL_STEP'; | ||||||
|  | export const JSON_STRING = 'JSON_STRING'; | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| export const BUILDER_CHANGE = 'BUILDER_CHANGE'; | export const BUILDER_CHANGE = 'BUILDER_CHANGE'; | ||||||
|  | |||||||
| @ -5,14 +5,12 @@ import { workspaceName } from '../actions/workspaceActions'; | |||||||
| 
 | 
 | ||||||
| import { detectWhitespacesAndReturnReadableResult } from '../helpers/whitespace'; | import { detectWhitespacesAndReturnReadableResult } from '../helpers/whitespace'; | ||||||
| 
 | 
 | ||||||
|  | import Dialog from './Dialog'; | ||||||
|  | 
 | ||||||
| import { withStyles } from '@material-ui/core/styles'; | import { withStyles } from '@material-ui/core/styles'; | ||||||
| import Button from '@material-ui/core/Button'; | import Button from '@material-ui/core/Button'; | ||||||
| import Backdrop from '@material-ui/core/Backdrop'; | import Backdrop from '@material-ui/core/Backdrop'; | ||||||
| import CircularProgress from '@material-ui/core/CircularProgress'; | import CircularProgress from '@material-ui/core/CircularProgress'; | ||||||
| import DialogTitle from '@material-ui/core/DialogTitle'; |  | ||||||
| import DialogContent from '@material-ui/core/DialogContent'; |  | ||||||
| import DialogActions from '@material-ui/core/DialogActions'; |  | ||||||
| import Dialog from '@material-ui/core/Dialog'; |  | ||||||
| import IconButton from '@material-ui/core/IconButton'; | import IconButton from '@material-ui/core/IconButton'; | ||||||
| import Tooltip from '@material-ui/core/Tooltip'; | import Tooltip from '@material-ui/core/Tooltip'; | ||||||
| import TextField from '@material-ui/core/TextField'; | import TextField from '@material-ui/core/TextField'; | ||||||
| @ -129,22 +127,20 @@ class Compile extends Component { | |||||||
|         <Backdrop className={this.props.classes.backdrop} open={this.state.progress}> |         <Backdrop className={this.props.classes.backdrop} open={this.state.progress}> | ||||||
|           <CircularProgress color="inherit" /> |           <CircularProgress color="inherit" /> | ||||||
|         </Backdrop> |         </Backdrop> | ||||||
|         <Dialog onClose={this.toggleDialog} open={this.state.open}> |         <Dialog | ||||||
|           <DialogTitle>{this.state.title}</DialogTitle> |           open={this.state.open} | ||||||
|           <DialogContent dividers> |           title={this.state.title} | ||||||
|             {this.state.content} |           content={this.state.content} | ||||||
|  |           onClose={this.toggleDialog} | ||||||
|  |           onClick={this.state.file ? () => {this.toggleDialog(); this.setState({name: this.props.name})} : this.toggleDialog} | ||||||
|  |           button={this.state.file ? 'Abbrechen' : 'Schließen'} | ||||||
|  |         > | ||||||
|           {this.state.file ? |           {this.state.file ? | ||||||
|             <div style={{marginTop: '10px'}}> |             <div style={{marginTop: '10px'}}> | ||||||
|               <TextField autoFocus placeholder='Dateiname' value={this.state.name} onChange={this.setFileName} style={{marginRight: '10px'}}/> |               <TextField autoFocus placeholder='Dateiname' value={this.state.name} onChange={this.setFileName} style={{marginRight: '10px'}}/> | ||||||
|               <Button disabled={!this.state.name} variant='contained' color='primary' onClick={() => this.download()}>Eingabe</Button> |               <Button disabled={!this.state.name} variant='contained' color='primary' onClick={() => this.download()}>Eingabe</Button> | ||||||
|             </div> |             </div> | ||||||
|           : null} |           : null} | ||||||
|           </DialogContent> |  | ||||||
|           <DialogActions> |  | ||||||
|             <Button onClick={this.state.file ? () => {this.toggleDialog(); this.setState({name: this.props.name})} : this.toggleDialog} color="primary"> |  | ||||||
|               {this.state.file ? 'Abbrechen' : 'Schließen'} |  | ||||||
|             </Button> |  | ||||||
|           </DialogActions> |  | ||||||
|         </Dialog> |         </Dialog> | ||||||
|       </div> |       </div> | ||||||
|     ); |     ); | ||||||
|  | |||||||
							
								
								
									
										38
									
								
								src/components/Dialog.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										38
									
								
								src/components/Dialog.js
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,38 @@ | |||||||
|  | import React, { Component } from 'react'; | ||||||
|  | 
 | ||||||
|  | import Button from '@material-ui/core/Button'; | ||||||
|  | import DialogTitle from '@material-ui/core/DialogTitle'; | ||||||
|  | import DialogContent from '@material-ui/core/DialogContent'; | ||||||
|  | import DialogActions from '@material-ui/core/DialogActions'; | ||||||
|  | import MaterialUIDialog from '@material-ui/core/Dialog'; | ||||||
|  | 
 | ||||||
|  | class Dialog extends Component { | ||||||
|  | 
 | ||||||
|  |   render() { | ||||||
|  |     return ( | ||||||
|  |       <MaterialUIDialog | ||||||
|  |         onClose={this.props.onClose} | ||||||
|  |         open={this.props.open} | ||||||
|  |         style={this.props.style} | ||||||
|  |         maxWidth={this.props.maxWidth} | ||||||
|  |         fullWidth={this.props.fullWidth} | ||||||
|  |       > | ||||||
|  |         <DialogTitle>{this.props.title}</DialogTitle> | ||||||
|  |         <DialogContent dividers> | ||||||
|  |           {this.props.content} | ||||||
|  |           {this.props.children} | ||||||
|  |         </DialogContent> | ||||||
|  |         <DialogActions> | ||||||
|  |           {this.props.actions ? this.props.actions : | ||||||
|  |             <Button onClick={this.props.onClick} color="primary"> | ||||||
|  |               {this.props.button} | ||||||
|  |             </Button> | ||||||
|  |           } | ||||||
|  |         </DialogActions> | ||||||
|  |       </MaterialUIDialog> | ||||||
|  |     ); | ||||||
|  |   }; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | export default Dialog; | ||||||
| @ -7,13 +7,13 @@ import moment from 'moment'; | |||||||
| import localization from 'moment/locale/de'; | import localization from 'moment/locale/de'; | ||||||
| import * as Blockly from 'blockly/core'; | import * as Blockly from 'blockly/core'; | ||||||
| 
 | 
 | ||||||
| import { parseXml } from '../../../helpers/compareXml'; |  | ||||||
| import BlocklyWindow from '../../Blockly/BlocklyWindow'; | import BlocklyWindow from '../../Blockly/BlocklyWindow'; | ||||||
| 
 | 
 | ||||||
| import { withStyles } from '@material-ui/core/styles'; | import { withStyles } from '@material-ui/core/styles'; | ||||||
| import Switch from '@material-ui/core/Switch'; | import Switch from '@material-ui/core/Switch'; | ||||||
| import FormControlLabel from '@material-ui/core/FormControlLabel'; | import FormControlLabel from '@material-ui/core/FormControlLabel'; | ||||||
| import FormHelperText from '@material-ui/core/FormHelperText'; | import FormHelperText from '@material-ui/core/FormHelperText'; | ||||||
|  | import FormLabel from '@material-ui/core/FormLabel'; | ||||||
| import Button from '@material-ui/core/Button'; | import Button from '@material-ui/core/Button'; | ||||||
| import Grid from '@material-ui/core/Grid'; | import Grid from '@material-ui/core/Grid'; | ||||||
| 
 | 
 | ||||||
| @ -79,9 +79,29 @@ class BlocklyExample extends Component { | |||||||
|     } |     } | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
| 
 |  | ||||||
|   render() { |   render() { | ||||||
|     moment.locale('de', localization); |     moment.locale('de', localization); | ||||||
|  |     return ( | ||||||
|  |       <div style={{marginBottom: '10px'}}> | ||||||
|  |         {!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 ? (() => { | ||||||
|           var initialXml = this.props.value; |           var initialXml = this.props.value; | ||||||
|           // check if value is valid xml;
 |           // check if value is valid xml;
 | ||||||
|           try{ |           try{ | ||||||
| @ -92,25 +112,6 @@ class BlocklyExample extends Component { | |||||||
|             this.props.setError(this.props.index, 'xml'); |             this.props.setError(this.props.index, 'xml'); | ||||||
|           } |           } | ||||||
|           return ( |           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.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> |             <div> | ||||||
|               <Grid container className={!this.props.value ? this.props.classes.errorBorder : null}> |               <Grid container className={!this.props.value ? this.props.classes.errorBorder : null}> | ||||||
|                 <Grid item xs={12}> |                 <Grid item xs={12}> | ||||||
| @ -127,6 +128,7 @@ class BlocklyExample extends Component { | |||||||
|                 {this.props.task ? 'Musterlösung einreichen' : 'Beispiel einreichen'} |                 {this.props.task ? 'Musterlösung einreichen' : 'Beispiel einreichen'} | ||||||
|               </Button> |               </Button> | ||||||
|             </div> |             </div> | ||||||
|  |           )})() | ||||||
|         : null} |         : null} | ||||||
|       </div> |       </div> | ||||||
|     ); |     ); | ||||||
|  | |||||||
| @ -1,17 +1,17 @@ | |||||||
| import React, { Component } from 'react'; | import React, { Component } from 'react'; | ||||||
| import PropTypes from 'prop-types'; | import PropTypes from 'prop-types'; | ||||||
| import { connect } from 'react-redux'; | 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 { saveAs } from 'file-saver'; | ||||||
| 
 | 
 | ||||||
| import data from '../../../data/hardware.json'; |  | ||||||
| import { detectWhitespacesAndReturnReadableResult } from '../../../helpers/whitespace'; | import { detectWhitespacesAndReturnReadableResult } from '../../../helpers/whitespace'; | ||||||
| 
 | 
 | ||||||
| import Breadcrumbs from '../../Breadcrumbs'; | import Breadcrumbs from '../../Breadcrumbs'; | ||||||
| import Id from './Id'; | import Id from './Id'; | ||||||
| import Title from './Textfield'; | import Textfield from './Textfield'; | ||||||
| import Step from './Step'; | import Step from './Step'; | ||||||
|  | import Dialog from '../../Dialog'; | ||||||
| 
 | 
 | ||||||
| import { withStyles } from '@material-ui/core/styles'; | import { withStyles } from '@material-ui/core/styles'; | ||||||
| import Button from '@material-ui/core/Button'; | import Button from '@material-ui/core/Button'; | ||||||
| @ -30,6 +30,12 @@ class Builder extends Component { | |||||||
| 
 | 
 | ||||||
|   constructor(props){ |   constructor(props){ | ||||||
|     super(props); |     super(props); | ||||||
|  |     this.state = { | ||||||
|  |       open: false, | ||||||
|  |       title: '', | ||||||
|  |       content: '', | ||||||
|  |       string: false | ||||||
|  |     }; | ||||||
|     this.inputRef = React.createRef(); |     this.inputRef = React.createRef(); | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
| @ -57,16 +63,25 @@ class Builder extends Component { | |||||||
|   uploadJsonFile = (jsonFile) => { |   uploadJsonFile = (jsonFile) => { | ||||||
|     this.props.progress(true); |     this.props.progress(true); | ||||||
|     if(jsonFile.type !== 'application/json'){ |     if(jsonFile.type !== 'application/json'){ | ||||||
|       alert('falscher Dateityp'); |  | ||||||
|       this.props.progress(false); |       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 { |     else { | ||||||
|       var reader = new FileReader(); |       var reader = new FileReader(); | ||||||
|       reader.readAsText(jsonFile); |       reader.readAsText(jsonFile); | ||||||
|       reader.onloadend = () => { |       reader.onloadend = () => { | ||||||
|  |         this.readJson(reader.result, true); | ||||||
|  |       }; | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   uploadJsonString = () => { | ||||||
|  |     this.setState({ open: true, string: true, title: 'JSON-String einfügen', content: ''}); | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   readJson = (jsonString, isFile) => { | ||||||
|     try { |     try { | ||||||
|           var result = JSON.parse(reader.result); |       var result = JSON.parse(jsonString); | ||||||
|       if(!this.checkSteps(result.steps)){ |       if(!this.checkSteps(result.steps)){ | ||||||
|         result.steps = [{}]; |         result.steps = [{}]; | ||||||
|       } |       } | ||||||
| @ -74,10 +89,8 @@ class Builder extends Component { | |||||||
|     } catch(err){ |     } catch(err){ | ||||||
|       console.log(err); |       console.log(err); | ||||||
|       this.props.progress(false); |       this.props.progress(false); | ||||||
|           alert('ungültige JSON-Datei'); |       this.props.jsonString(''); | ||||||
|           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.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.`}); | ||||||
|         } |  | ||||||
|       }; |  | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
| @ -88,6 +101,10 @@ class Builder extends Component { | |||||||
|     return true; |     return true; | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|  |   toggle = () => { | ||||||
|  |     this.setState({ open: !this.state }); | ||||||
|  |   } | ||||||
|  | 
 | ||||||
| 
 | 
 | ||||||
|   render() { |   render() { | ||||||
|     return ( |     return ( | ||||||
| @ -96,6 +113,7 @@ class Builder extends Component { | |||||||
| 
 | 
 | ||||||
|         <h1>Tutorial-Builder</h1> |         <h1>Tutorial-Builder</h1> | ||||||
| 
 | 
 | ||||||
|  |         {/*upload JSON*/} | ||||||
|         <div ref={this.inputRef}> |         <div ref={this.inputRef}> | ||||||
|           <input |           <input | ||||||
|             style={{display: 'none'}} |             style={{display: 'none'}} | ||||||
| @ -107,30 +125,50 @@ class Builder extends Component { | |||||||
|           <label htmlFor="open-json"> |           <label htmlFor="open-json"> | ||||||
|             <Button component="span" style={{marginRight: '10px', marginBottom: '10px'}} variant='contained' color='primary'>Datei laden</Button> |             <Button component="span" style={{marginRight: '10px', marginBottom: '10px'}} variant='contained' color='primary'>Datei laden</Button> | ||||||
|           </label> |           </label> | ||||||
|  |           <Button style={{marginRight: '10px', marginBottom: '10px'}} variant='contained' color='primary' onClick={() => this.uploadJsonString()}>String laden</Button> | ||||||
|         </div> |         </div> | ||||||
|         <Divider variant='fullWidth' style={{margin: '10px 0 30px 0'}}/> |         <Divider variant='fullWidth' style={{margin: '10px 0 30px 0'}}/> | ||||||
| 
 | 
 | ||||||
|  |         {/*Tutorial-Builder-Form*/} | ||||||
|         <Id error={this.props.error} value={this.props.id}/> |         <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) => |         {this.props.steps.map((step, i) => | ||||||
|           <Step step={step} index={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 style={{marginRight: '10px'}} variant='contained' color='primary' onClick={() => this.submit()}>Tutorial-Vorlage erstellen</Button> | ||||||
|         <Button variant='contained' onClick={() => this.reset()}>Zurücksetzen</Button> |         <Button variant='contained' onClick={() => this.reset()}>Zurücksetzen</Button> | ||||||
|  | 
 | ||||||
|         <Backdrop className={this.props.classes.backdrop} open={this.props.isProgress}> |         <Backdrop className={this.props.classes.backdrop} open={this.props.isProgress}> | ||||||
|           <CircularProgress color="inherit" /> |           <CircularProgress color="inherit" /> | ||||||
|         </Backdrop> |         </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> | ||||||
|       /*<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 = { | Builder.propTypes = { | ||||||
|   checkError: PropTypes.func.isRequired, |   checkError: PropTypes.func.isRequired, | ||||||
|   readJSON: PropTypes.func.isRequired, |   readJSON: PropTypes.func.isRequired, | ||||||
|  |   jsonString: PropTypes.func.isRequired, | ||||||
|   progress: PropTypes.func.isRequired, |   progress: PropTypes.func.isRequired, | ||||||
|   resetTutorial: PropTypes.func.isRequired, |   resetTutorial: PropTypes.func.isRequired, | ||||||
|   title: PropTypes.string.isRequired, |   title: PropTypes.string.isRequired, | ||||||
|   steps: PropTypes.array.isRequired, |   steps: PropTypes.array.isRequired, | ||||||
|   change: PropTypes.number.isRequired, |   change: PropTypes.number.isRequired, | ||||||
|   error: PropTypes.object.isRequired, |   error: PropTypes.object.isRequired, | ||||||
|  |   json: PropTypes.string.isRequired, | ||||||
|   isProgress: PropTypes.bool.isRequired |   isProgress: PropTypes.bool.isRequired | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| @ -153,7 +193,8 @@ const mapStateToProps = state => ({ | |||||||
|   steps: state.builder.steps, |   steps: state.builder.steps, | ||||||
|   change: state.builder.change, |   change: state.builder.change, | ||||||
|   error: state.builder.error, |   error: state.builder.error, | ||||||
|  |   json: state.builder.json, | ||||||
|   isProgress: state.builder.progress |   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 React, { Component } from 'react'; | ||||||
| import PropTypes from 'prop-types'; | import PropTypes from 'prop-types'; | ||||||
| import { connect } from 'react-redux'; | 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 { withStyles } from '@material-ui/core/styles'; | ||||||
| import OutlinedInput from '@material-ui/core/OutlinedInput'; | import OutlinedInput from '@material-ui/core/OutlinedInput'; | ||||||
| @ -25,6 +25,9 @@ class Textfield extends Component { | |||||||
|     if(this.props.property === 'title'){ |     if(this.props.property === 'title'){ | ||||||
|       this.props.tutorialTitle(value); |       this.props.tutorialTitle(value); | ||||||
|     } |     } | ||||||
|  |     else if(this.props.property === 'json'){ | ||||||
|  |       this.props.jsonString(value); | ||||||
|  |     } | ||||||
|     else { |     else { | ||||||
|       this.props.changeContent(this.props.index, this.props.property, value); |       this.props.changeContent(this.props.index, this.props.property, value); | ||||||
|     } |     } | ||||||
| @ -55,7 +58,9 @@ class Textfield extends Component { | |||||||
|         {this.props.index !== undefined ? |         {this.props.index !== undefined ? | ||||||
|           this.props.error.steps[this.props.index][this.props.property] ? <FormHelperText className={this.props.classes.errorColor}>{this.props.errorText}</FormHelperText> |           this.props.error.steps[this.props.index][this.props.property] ? <FormHelperText className={this.props.classes.errorColor}>{this.props.errorText}</FormHelperText> | ||||||
|         : null |         : 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} |         : null} | ||||||
|       </FormControl> |       </FormControl> | ||||||
|     ); |     ); | ||||||
| @ -64,6 +69,7 @@ class Textfield extends Component { | |||||||
| 
 | 
 | ||||||
| Textfield.propTypes = { | Textfield.propTypes = { | ||||||
|   tutorialTitle: PropTypes.func.isRequired, |   tutorialTitle: PropTypes.func.isRequired, | ||||||
|  |   jsonString: PropTypes.func.isRequired, | ||||||
|   changeContent: PropTypes.func.isRequired, |   changeContent: PropTypes.func.isRequired, | ||||||
|   error: PropTypes.object.isRequired, |   error: PropTypes.object.isRequired, | ||||||
|   change: PropTypes.number.isRequired |   change: PropTypes.number.isRequired | ||||||
| @ -74,4 +80,4 @@ const mapStateToProps = state => ({ | |||||||
|   change: state.builder.change |   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)); | ||||||
|  | |||||||
| @ -1,18 +1,15 @@ | |||||||
| import React, { Component } from 'react'; | import React, { Component } from 'react'; | ||||||
| 
 | 
 | ||||||
|  | import Dialog from '../Dialog'; | ||||||
|  | 
 | ||||||
| import { fade } from '@material-ui/core/styles/colorManipulator'; | import { fade } from '@material-ui/core/styles/colorManipulator'; | ||||||
| import { withStyles } from '@material-ui/core/styles'; | import { withStyles } from '@material-ui/core/styles'; | ||||||
| import withWidth, { isWidthDown } from '@material-ui/core/withWidth'; | import withWidth, { isWidthDown } from '@material-ui/core/withWidth'; | ||||||
| import Typography from '@material-ui/core/Typography'; | import Typography from '@material-ui/core/Typography'; | ||||||
| import IconButton from '@material-ui/core/IconButton'; | import IconButton from '@material-ui/core/IconButton'; | ||||||
| import Button from '@material-ui/core/Button'; |  | ||||||
| import GridList from '@material-ui/core/GridList'; | import GridList from '@material-ui/core/GridList'; | ||||||
| import GridListTile from '@material-ui/core/GridListTile'; | import GridListTile from '@material-ui/core/GridListTile'; | ||||||
| import GridListTileBar from '@material-ui/core/GridListTileBar'; | import GridListTileBar from '@material-ui/core/GridListTileBar'; | ||||||
| import Dialog from '@material-ui/core/Dialog'; |  | ||||||
| import DialogActions from '@material-ui/core/DialogActions'; |  | ||||||
| import DialogContent from '@material-ui/core/DialogContent'; |  | ||||||
| import DialogTitle from '@material-ui/core/DialogTitle'; |  | ||||||
| 
 | 
 | ||||||
| import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; | import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; | ||||||
| import { faExpandAlt } from "@fortawesome/free-solid-svg-icons"; | import { faExpandAlt } from "@fortawesome/free-solid-svg-icons"; | ||||||
| @ -84,20 +81,16 @@ class Hardware extends Component { | |||||||
| 
 | 
 | ||||||
|         <Dialog |         <Dialog | ||||||
|           style={{zIndex: 1500}} |           style={{zIndex: 1500}} | ||||||
|           fullWidth={true} |  | ||||||
|           open={this.state.open} |           open={this.state.open} | ||||||
|  |           title={`Hardware: ${this.state.title}`} | ||||||
|  |           content={this.state.content} | ||||||
|           onClose={this.handleClose} |           onClose={this.handleClose} | ||||||
|  |           onClick={this.handleClose} | ||||||
|  |           button={'Schließen'} | ||||||
|         > |         > | ||||||
|           <DialogTitle style={{padding: "10px 24px"}}>Hardware: {this.state.title}</DialogTitle> |  | ||||||
|           <DialogContent style={{padding: "0px"}}> |  | ||||||
|           <img src={this.state.url} width="100%" alt={this.state.title}/> |           <img src={this.state.url} width="100%" alt={this.state.title}/> | ||||||
|           </DialogContent> |  | ||||||
|           <DialogActions style={{padding: "10px 24px"}}> |  | ||||||
|             <Button onClick={this.handleClose} color="primary"> |  | ||||||
|               Schließen |  | ||||||
|             </Button> |  | ||||||
|           </DialogActions> |  | ||||||
|         </Dialog> |         </Dialog> | ||||||
|  | 
 | ||||||
|       </div> |       </div> | ||||||
|     ); |     ); | ||||||
|   }; |   }; | ||||||
|  | |||||||
| @ -6,6 +6,7 @@ import { tutorialCheck, tutorialStep } from '../../actions/tutorialActions'; | |||||||
| import { withRouter } from 'react-router-dom'; | import { withRouter } from 'react-router-dom'; | ||||||
| 
 | 
 | ||||||
| import Compile from '../Compile'; | import Compile from '../Compile'; | ||||||
|  | import Dialog from '../Dialog'; | ||||||
| 
 | 
 | ||||||
| import tutorials from './tutorials.json'; | import tutorials from './tutorials.json'; | ||||||
| import { checkXml } from '../../helpers/compareXml'; | import { checkXml } from '../../helpers/compareXml'; | ||||||
| @ -14,10 +15,7 @@ import { withStyles } from '@material-ui/core/styles'; | |||||||
| import IconButton from '@material-ui/core/IconButton'; | import IconButton from '@material-ui/core/IconButton'; | ||||||
| import Tooltip from '@material-ui/core/Tooltip'; | import Tooltip from '@material-ui/core/Tooltip'; | ||||||
| import Button from '@material-ui/core/Button'; | import Button from '@material-ui/core/Button'; | ||||||
| import DialogTitle from '@material-ui/core/DialogTitle'; | 
 | ||||||
| import DialogContent from '@material-ui/core/DialogContent'; |  | ||||||
| import DialogActions from '@material-ui/core/DialogActions'; |  | ||||||
| import Dialog from '@material-ui/core/Dialog'; |  | ||||||
| import { faPlay } from "@fortawesome/free-solid-svg-icons"; | import { faPlay } from "@fortawesome/free-solid-svg-icons"; | ||||||
| import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; | import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; | ||||||
| 
 | 
 | ||||||
| @ -69,10 +67,18 @@ class SolutionCheck extends Component { | |||||||
|             <FontAwesomeIcon icon={faPlay} size="xs"/> |             <FontAwesomeIcon icon={faPlay} size="xs"/> | ||||||
|           </IconButton> |           </IconButton> | ||||||
|         </Tooltip> |         </Tooltip> | ||||||
|         <Dialog fullWidth maxWidth={'sm'} onClose={this.toggleDialog} open={this.state.open} style={{zIndex: 9999999}}> |          | ||||||
|           <DialogTitle>{this.state.msg.type === 'error' ? 'Fehler' : 'Erfolg'}</DialogTitle> |         <Dialog | ||||||
|           <DialogContent dividers> |           style={{zIndex: 9999999}} | ||||||
|             {this.state.msg.text} |           fullWidth | ||||||
|  |           maxWidth={'sm'} | ||||||
|  |           open={this.state.open} | ||||||
|  |           title={this.state.msg.type === 'error' ? 'Fehler' : 'Erfolg'} | ||||||
|  |           content={this.state.msg.text} | ||||||
|  |           onClose={this.toggleDialog} | ||||||
|  |           onClick={this.toggleDialog} | ||||||
|  |           button={'Schließen'} | ||||||
|  |         > | ||||||
|           {this.state.msg.type === 'success' ? |           {this.state.msg.type === 'success' ? | ||||||
|             <div style={{marginTop: '20px', display: 'flex'}}> |             <div style={{marginTop: '20px', display: 'flex'}}> | ||||||
|               <Compile /> |               <Compile /> | ||||||
| @ -97,13 +103,8 @@ class SolutionCheck extends Component { | |||||||
|               } |               } | ||||||
|             </div> |             </div> | ||||||
|           : null} |           : null} | ||||||
|           </DialogContent> |  | ||||||
|           <DialogActions> |  | ||||||
|             <Button onClick={this.toggleDialog} color="primary"> |  | ||||||
|               Schließen |  | ||||||
|             </Button> |  | ||||||
|           </DialogActions> |  | ||||||
|         </Dialog> |         </Dialog> | ||||||
|  | 
 | ||||||
|       </div> |       </div> | ||||||
|     ); |     ); | ||||||
|   }; |   }; | ||||||
|  | |||||||
| @ -12,14 +12,11 @@ import { initialXml } from './Blockly/initialXml.js'; | |||||||
| 
 | 
 | ||||||
| import Compile from './Compile'; | import Compile from './Compile'; | ||||||
| import SolutionCheck from './Tutorial/SolutionCheck'; | import SolutionCheck from './Tutorial/SolutionCheck'; | ||||||
|  | import Dialog from './Dialog'; | ||||||
| 
 | 
 | ||||||
| import withWidth, { isWidthDown } from '@material-ui/core/withWidth'; | import withWidth, { isWidthDown } from '@material-ui/core/withWidth'; | ||||||
| import { withStyles } from '@material-ui/core/styles'; | import { withStyles } from '@material-ui/core/styles'; | ||||||
| import Button from '@material-ui/core/Button'; | import Button from '@material-ui/core/Button'; | ||||||
| import DialogTitle from '@material-ui/core/DialogTitle'; |  | ||||||
| import DialogContent from '@material-ui/core/DialogContent'; |  | ||||||
| import DialogActions from '@material-ui/core/DialogActions'; |  | ||||||
| import Dialog from '@material-ui/core/Dialog'; |  | ||||||
| import IconButton from '@material-ui/core/IconButton'; | import IconButton from '@material-ui/core/IconButton'; | ||||||
| import Tooltip from '@material-ui/core/Tooltip'; | import Tooltip from '@material-ui/core/Tooltip'; | ||||||
| import TextField from '@material-ui/core/TextField'; | import TextField from '@material-ui/core/TextField'; | ||||||
| @ -195,23 +192,23 @@ class WorkspaceFunc extends Component { | |||||||
|             <FontAwesomeIcon icon={faShare} size="xs" flip='horizontal'/> |             <FontAwesomeIcon icon={faShare} size="xs" flip='horizontal'/> | ||||||
|           </IconButton> |           </IconButton> | ||||||
|         </Tooltip> |         </Tooltip> | ||||||
|         <Dialog onClose={this.toggleDialog} open={this.state.open}> | 
 | ||||||
|           <DialogTitle>{this.state.title}</DialogTitle> |         <Dialog | ||||||
|           <DialogContent dividers> |           open={this.state.open} | ||||||
|             {this.state.content} |           title={this.state.title} | ||||||
|  |           content={this.state.content} | ||||||
|  |           onClose={this.toggleDialog} | ||||||
|  |           onClick={this.state.file ? () => {this.toggleDialog(); this.setState({name: this.props.name})} : this.toggleDialog} | ||||||
|  |           button={this.state.file ? 'Abbrechen' : 'Schließen'} | ||||||
|  |         > | ||||||
|           {this.state.file ? |           {this.state.file ? | ||||||
|             <div style={{marginTop: '10px'}}> |             <div style={{marginTop: '10px'}}> | ||||||
|               <TextField autoFocus placeholder={this.state.saveXml ?'Dateiname' : 'Projektname'} value={this.state.name} onChange={this.setFileName} style={{marginRight: '10px'}}/> |               <TextField autoFocus placeholder={this.state.saveXml ?'Dateiname' : 'Projektname'} value={this.state.name} onChange={this.setFileName} style={{marginRight: '10px'}}/> | ||||||
|               <Button disabled={!this.state.name} variant='contained' color='primary' onClick={() => {this.state.saveXml ? this.saveXmlFile() : this.props.workspaceName(this.state.name); this.toggleDialog();}}>Eingabe</Button> |               <Button disabled={!this.state.name} variant='contained' color='primary' onClick={() => {this.state.saveXml ? this.saveXmlFile() : this.props.workspaceName(this.state.name); this.toggleDialog();}}>Eingabe</Button> | ||||||
|             </div> |             </div> | ||||||
|           : null} |           : null} | ||||||
|           </DialogContent> |  | ||||||
|           <DialogActions> |  | ||||||
|             <Button onClick={this.state.file ? () => {this.toggleDialog(); this.setState({name: this.props.name})} : this.toggleDialog} color="primary"> |  | ||||||
|               {this.state.file ? 'Abbrechen' : 'Schließen'} |  | ||||||
|             </Button> |  | ||||||
|           </DialogActions> |  | ||||||
|         </Dialog> |         </Dialog> | ||||||
|  | 
 | ||||||
|       </div> |       </div> | ||||||
|     ); |     ); | ||||||
|   }; |   }; | ||||||
|  | |||||||
| @ -1,8 +1,9 @@ | |||||||
| import { PROGRESS, BUILDER_CHANGE, BUILDER_ERROR, BUILDER_TITLE, BUILDER_ID, BUILDER_ADD_STEP, BUILDER_DELETE_STEP, BUILDER_CHANGE_STEP,BUILDER_CHANGE_ORDER, BUILDER_DELETE_PROPERTY } from '../actions/types'; | import { PROGRESS, JSON_STRING, BUILDER_CHANGE, BUILDER_ERROR, BUILDER_TITLE, BUILDER_ID, BUILDER_ADD_STEP, BUILDER_DELETE_STEP, BUILDER_CHANGE_STEP,BUILDER_CHANGE_ORDER, BUILDER_DELETE_PROPERTY } from '../actions/types'; | ||||||
| 
 | 
 | ||||||
| const initialState = { | const initialState = { | ||||||
|   change: 0, |   change: 0, | ||||||
|   progress: false, |   progress: false, | ||||||
|  |   json: '', | ||||||
|   title: '', |   title: '', | ||||||
|   id: '', |   id: '', | ||||||
|   steps: [ |   steps: [ | ||||||
| @ -56,6 +57,11 @@ export default function(state = initialState, action){ | |||||||
|         ...state, |         ...state, | ||||||
|         progress: action.payload |         progress: action.payload | ||||||
|       } |       } | ||||||
|  |     case JSON_STRING: | ||||||
|  |       return { | ||||||
|  |         ...state, | ||||||
|  |         json: action.payload | ||||||
|  |       } | ||||||
|     default: |     default: | ||||||
|       return state; |       return state; | ||||||
|   } |   } | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user