Merge branch 'snackbar'
This commit is contained in:
		
						commit
						9e9c523955
					
				| @ -220,6 +220,7 @@ export const progress = (inProgress) => (dispatch) => { | |||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| export const resetTutorial = () => (dispatch, getState) => { | export const resetTutorial = () => (dispatch, getState) => { | ||||||
|  |   dispatch(jsonString('')); | ||||||
|   dispatch(tutorialTitle('')); |   dispatch(tutorialTitle('')); | ||||||
|   dispatch(tutorialId('')); |   dispatch(tutorialId('')); | ||||||
|   var steps = [ |   var steps = [ | ||||||
|  | |||||||
							
								
								
									
										50
									
								
								src/components/Snackbar.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										50
									
								
								src/components/Snackbar.js
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,50 @@ | |||||||
|  | import React, { Component } from 'react'; | ||||||
|  | 
 | ||||||
|  | import { withStyles } from '@material-ui/core/styles'; | ||||||
|  | import IconButton from '@material-ui/core/IconButton'; | ||||||
|  | import MaterialUISnackbar from '@material-ui/core/Snackbar'; | ||||||
|  | import SnackbarContent from '@material-ui/core/SnackbarContent'; | ||||||
|  | 
 | ||||||
|  | import { faTimes } from "@fortawesome/free-solid-svg-icons"; | ||||||
|  | import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; | ||||||
|  | 
 | ||||||
|  | const styles = (theme) => ({ | ||||||
|  |   success: { | ||||||
|  |     backgroundColor: theme.palette.primary.main, | ||||||
|  |     color: theme.palette.primary.contrastText | ||||||
|  |   }, | ||||||
|  |   error: { | ||||||
|  |     backgroundColor: theme.palette.error.dark, | ||||||
|  |     color: theme.palette.error.contrastText | ||||||
|  |   } | ||||||
|  | }); | ||||||
|  | 
 | ||||||
|  | class Snackbar extends Component { | ||||||
|  | 
 | ||||||
|  |   render() { | ||||||
|  |     return ( | ||||||
|  |       <MaterialUISnackbar | ||||||
|  |         anchorOrigin={{vertical: 'bottom', horizontal: 'left' }} | ||||||
|  |         open={this.props.open} | ||||||
|  |         onClose={this.props.onClose} | ||||||
|  |         key={Date.now()+this.props.message} | ||||||
|  |         autoHideDuration={5000} | ||||||
|  |         style={{left: '22px', bottom: '40px', width: '300px', zIndex: '100'}} | ||||||
|  |       > | ||||||
|  |         <SnackbarContent | ||||||
|  |           style={{flexWrap: 'nowrap'}} | ||||||
|  |           className={this.props.type === 'error' ? this.props.classes.error : this.props.classes.success} | ||||||
|  |           action={ | ||||||
|  |             <IconButton onClick={this.props.onClose} style={{color: 'inherit'}}> | ||||||
|  |               <FontAwesomeIcon icon={faTimes} size="xs"/> | ||||||
|  |             </IconButton> | ||||||
|  |           } | ||||||
|  |           message={this.props.message} | ||||||
|  |         /> | ||||||
|  |       </MaterialUISnackbar> | ||||||
|  |     ); | ||||||
|  |   }; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | export default withStyles(styles, {withTheme: true})(Snackbar); | ||||||
| @ -12,6 +12,7 @@ import Id from './Id'; | |||||||
| import Textfield from './Textfield'; | import Textfield from './Textfield'; | ||||||
| import Step from './Step'; | import Step from './Step'; | ||||||
| import Dialog from '../../Dialog'; | import Dialog from '../../Dialog'; | ||||||
|  | import Snackbar from '../../Snackbar'; | ||||||
| 
 | 
 | ||||||
| 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'; | ||||||
| @ -34,14 +35,21 @@ class Builder extends Component { | |||||||
|       open: false, |       open: false, | ||||||
|       title: '', |       title: '', | ||||||
|       content: '', |       content: '', | ||||||
|       string: false |       string: false, | ||||||
|  |       snackbar: false, | ||||||
|  |       message: '' | ||||||
|     }; |     }; | ||||||
|     this.inputRef = React.createRef(); |     this.inputRef = React.createRef(); | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|  |   componentWillUnmount(){ | ||||||
|  |     this.reset(); | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|   submit = () => { |   submit = () => { | ||||||
|     var isError = this.props.checkError(); |     var isError = this.props.checkError(); | ||||||
|     if(isError){ |     if(isError){ | ||||||
|  |       this.setState({ snackbar: true, message: `Die Angaben für das Tutorial sind nicht vollständig.`, type: 'error'}); | ||||||
|       window.scrollTo(0, 0); |       window.scrollTo(0, 0); | ||||||
|     } |     } | ||||||
|     else{ |     else{ | ||||||
| @ -57,6 +65,7 @@ class Builder extends Component { | |||||||
| 
 | 
 | ||||||
|   reset = () => { |   reset = () => { | ||||||
|     this.props.resetTutorial(); |     this.props.resetTutorial(); | ||||||
|  |     this.setState({ snackbar: true, message: `Das Tutorial wurde erfolgreich zurückgesetzt.`, type: 'success'}); | ||||||
|     window.scrollTo(0, 0); |     window.scrollTo(0, 0); | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
| @ -86,6 +95,7 @@ class Builder extends Component { | |||||||
|         result.steps = [{}]; |         result.steps = [{}]; | ||||||
|       } |       } | ||||||
|       this.props.readJSON(result); |       this.props.readJSON(result); | ||||||
|  |       this.setState({ snackbar: true, message: `${isFile ? 'Die übergebene JSON-Datei' : 'Der übergebene JSON-String'} wurde erfolgreich übernommen.`, type: 'success'}); | ||||||
|     } catch(err){ |     } catch(err){ | ||||||
|       console.log(err); |       console.log(err); | ||||||
|       this.props.progress(false); |       this.props.progress(false); | ||||||
| @ -105,6 +115,10 @@ class Builder extends Component { | |||||||
|     this.setState({ open: !this.state }); |     this.setState({ open: !this.state }); | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|  |   toggleSnackbar = () => { | ||||||
|  |     this.setState({ snackbar: !this.state, message: '', type: null }); | ||||||
|  |   } | ||||||
|  | 
 | ||||||
| 
 | 
 | ||||||
|   render() { |   render() { | ||||||
|     return ( |     return ( | ||||||
| @ -169,6 +183,13 @@ class Builder extends Component { | |||||||
|           : null} |           : null} | ||||||
|         </Dialog> |         </Dialog> | ||||||
| 
 | 
 | ||||||
|  |         <Snackbar | ||||||
|  |           open={this.state.snackbar} | ||||||
|  |           onClose={this.toggleSnackbar} | ||||||
|  |           message={this.state.message} | ||||||
|  |           type={this.state.type} | ||||||
|  |         /> | ||||||
|  | 
 | ||||||
|       </div> |       </div> | ||||||
|     ); |     ); | ||||||
|   }; |   }; | ||||||
|  | |||||||
| @ -3,6 +3,8 @@ import PropTypes from 'prop-types'; | |||||||
| import { connect } from 'react-redux'; | import { connect } from 'react-redux'; | ||||||
| import { addStep, removeStep, changeStepIndex } from '../../../actions/tutorialBuilderActions'; | import { addStep, removeStep, changeStepIndex } from '../../../actions/tutorialBuilderActions'; | ||||||
| 
 | 
 | ||||||
|  | import clsx from 'clsx'; | ||||||
|  | 
 | ||||||
| import Textfield from './Textfield'; | import Textfield from './Textfield'; | ||||||
| import StepType from './StepType'; | import StepType from './StepType'; | ||||||
| import BlocklyExample from './BlocklyExample'; | import BlocklyExample from './BlocklyExample'; | ||||||
| @ -27,6 +29,14 @@ const styles = (theme) => ({ | |||||||
|       backgroundColor: theme.palette.primary.main, |       backgroundColor: theme.palette.primary.main, | ||||||
|       color: theme.palette.primary.contrastText, |       color: theme.palette.primary.contrastText, | ||||||
|     } |     } | ||||||
|  |   }, | ||||||
|  |   delete: { | ||||||
|  |     backgroundColor: theme.palette.error.dark, | ||||||
|  |     color: theme.palette.error.contrastText, | ||||||
|  |     '&:hover': { | ||||||
|  |       backgroundColor: theme.palette.error.dark, | ||||||
|  |       color: theme.palette.error.contrastText, | ||||||
|  |     } | ||||||
|   } |   } | ||||||
| }); | }); | ||||||
| 
 | 
 | ||||||
| @ -74,7 +84,7 @@ class Step extends Component { | |||||||
|                 <Tooltip title={`Schritt ${index+1} löschen`} arrow> |                 <Tooltip title={`Schritt ${index+1} löschen`} arrow> | ||||||
|                   <IconButton |                   <IconButton | ||||||
|                     disabled={index === 0} |                     disabled={index === 0} | ||||||
|                     className={this.props.classes.button} |                     className={clsx(this.props.classes.button, this.props.classes.delete)} | ||||||
|                     onClick={() => this.props.removeStep(index)} |                     onClick={() => this.props.removeStep(index)} | ||||||
|                   > |                   > | ||||||
|                     <FontAwesomeIcon icon={faTrash} size="xs"/> |                     <FontAwesomeIcon icon={faTrash} size="xs"/> | ||||||
|  | |||||||
| @ -13,6 +13,7 @@ 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 Dialog from './Dialog'; | ||||||
|  | import Snackbar from './Snackbar'; | ||||||
| 
 | 
 | ||||||
| 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'; | ||||||
| @ -59,7 +60,9 @@ class WorkspaceFunc extends Component { | |||||||
|       open: false, |       open: false, | ||||||
|       file: false, |       file: false, | ||||||
|       saveXml: false, |       saveXml: false, | ||||||
|       name: props.name |       name: props.name, | ||||||
|  |       snackbar: false, | ||||||
|  |       message: '' | ||||||
|     }; |     }; | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
| @ -73,6 +76,10 @@ class WorkspaceFunc extends Component { | |||||||
|     this.setState({ open: !this.state }); |     this.setState({ open: !this.state }); | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|  |   toggleSnackbar = () => { | ||||||
|  |     this.setState({ snackbar: !this.state, message: '' }); | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|   saveXmlFile = () => { |   saveXmlFile = () => { | ||||||
|     var code = this.props.xml; |     var code = this.props.xml; | ||||||
|     this.toggleDialog(); |     this.toggleDialog(); | ||||||
| @ -121,6 +128,7 @@ class WorkspaceFunc extends Component { | |||||||
|               var extensionPosition = xmlFile.name.lastIndexOf('.'); |               var extensionPosition = xmlFile.name.lastIndexOf('.'); | ||||||
|               this.props.workspaceName(xmlFile.name.substr(0, extensionPosition)); |               this.props.workspaceName(xmlFile.name.substr(0, extensionPosition)); | ||||||
|             } |             } | ||||||
|  |             this.setState({ snackbar: true, message: 'Das Projekt aus gegebener XML-Datei wurde erfolgreich eingefügt.' }); | ||||||
|           } |           } | ||||||
|         } catch(err){ |         } catch(err){ | ||||||
|           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, 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.' }); | ||||||
| @ -129,6 +137,12 @@ class WorkspaceFunc extends Component { | |||||||
|     } |     } | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|  |   renameWorkspace = () => { | ||||||
|  |     this.props.workspaceName(this.state.name); | ||||||
|  |     this.toggleDialog(); | ||||||
|  |     this.setState({ snackbar: true, message: `Das Projekt wurde erfolgreich in '${this.state.name}' umbenannt.` }); | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|   resetWorkspace = () => { |   resetWorkspace = () => { | ||||||
|     const workspace = Blockly.getMainWorkspace(); |     const workspace = Blockly.getMainWorkspace(); | ||||||
|     Blockly.Events.disable(); // https://groups.google.com/forum/#!topic/blockly/m7e3g0TC75Y
 |     Blockly.Events.disable(); // https://groups.google.com/forum/#!topic/blockly/m7e3g0TC75Y
 | ||||||
| @ -142,6 +156,7 @@ class WorkspaceFunc extends Component { | |||||||
|     if(!this.props.solutionCheck){ |     if(!this.props.solutionCheck){ | ||||||
|       this.props.workspaceName(null); |       this.props.workspaceName(null); | ||||||
|     } |     } | ||||||
|  |     this.setState({ snackbar: true, message: 'Das Projekt wurde erfolgreich zurückgesetzt.' }); | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   render() { |   render() { | ||||||
| @ -204,11 +219,18 @@ class WorkspaceFunc extends Component { | |||||||
|           {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.renameWorkspace()}}>Eingabe</Button> | ||||||
|             </div> |             </div> | ||||||
|           : null} |           : null} | ||||||
|         </Dialog> |         </Dialog> | ||||||
| 
 | 
 | ||||||
|  |         <Snackbar | ||||||
|  |           open={this.state.snackbar} | ||||||
|  |           onClose={this.toggleSnackbar} | ||||||
|  |           message={this.state.message} | ||||||
|  |           type='success' | ||||||
|  |         /> | ||||||
|  | 
 | ||||||
|       </div> |       </div> | ||||||
|     ); |     ); | ||||||
|   }; |   }; | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user