diff --git a/src/actions/tutorialBuilderActions.js b/src/actions/tutorialBuilderActions.js index 48d4bc2..6509a6b 100644 --- a/src/actions/tutorialBuilderActions.js +++ b/src/actions/tutorialBuilderActions.js @@ -220,6 +220,7 @@ export const progress = (inProgress) => (dispatch) => { }; export const resetTutorial = () => (dispatch, getState) => { + dispatch(jsonString('')); dispatch(tutorialTitle('')); dispatch(tutorialId('')); var steps = [ diff --git a/src/components/Snackbar.js b/src/components/Snackbar.js new file mode 100644 index 0000000..e3763d1 --- /dev/null +++ b/src/components/Snackbar.js @@ -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 ( + + + + + } + message={this.props.message} + /> + + ); + }; +} + + +export default withStyles(styles, {withTheme: true})(Snackbar); diff --git a/src/components/Tutorial/Builder/Builder.js b/src/components/Tutorial/Builder/Builder.js index 58fbae3..462ad6e 100644 --- a/src/components/Tutorial/Builder/Builder.js +++ b/src/components/Tutorial/Builder/Builder.js @@ -12,6 +12,7 @@ import Id from './Id'; import Textfield from './Textfield'; import Step from './Step'; import Dialog from '../../Dialog'; +import Snackbar from '../../Snackbar'; import { withStyles } from '@material-ui/core/styles'; import Button from '@material-ui/core/Button'; @@ -34,14 +35,21 @@ class Builder extends Component { open: false, title: '', content: '', - string: false + string: false, + snackbar: false, + message: '' }; this.inputRef = React.createRef(); } + componentWillUnmount(){ + this.reset(); + } + submit = () => { var isError = this.props.checkError(); if(isError){ + this.setState({ snackbar: true, message: `Die Angaben für das Tutorial sind nicht vollständig.`, type: 'error'}); window.scrollTo(0, 0); } else{ @@ -57,6 +65,7 @@ class Builder extends Component { reset = () => { this.props.resetTutorial(); + this.setState({ snackbar: true, message: `Das Tutorial wurde erfolgreich zurückgesetzt.`, type: 'success'}); window.scrollTo(0, 0); } @@ -86,6 +95,7 @@ class Builder extends Component { result.steps = [{}]; } 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){ console.log(err); this.props.progress(false); @@ -105,6 +115,10 @@ class Builder extends Component { this.setState({ open: !this.state }); } + toggleSnackbar = () => { + this.setState({ snackbar: !this.state, message: '', type: null }); + } + render() { return ( @@ -169,6 +183,13 @@ class Builder extends Component { : null} + + ); }; diff --git a/src/components/Tutorial/Builder/Step.js b/src/components/Tutorial/Builder/Step.js index ac5bde6..24c75ac 100644 --- a/src/components/Tutorial/Builder/Step.js +++ b/src/components/Tutorial/Builder/Step.js @@ -3,6 +3,8 @@ import PropTypes from 'prop-types'; import { connect } from 'react-redux'; import { addStep, removeStep, changeStepIndex } from '../../../actions/tutorialBuilderActions'; +import clsx from 'clsx'; + import Textfield from './Textfield'; import StepType from './StepType'; import BlocklyExample from './BlocklyExample'; @@ -27,6 +29,14 @@ const styles = (theme) => ({ backgroundColor: theme.palette.primary.main, 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 { this.props.removeStep(index)} > diff --git a/src/components/WorkspaceFunc.js b/src/components/WorkspaceFunc.js index 3d413b3..62380f5 100644 --- a/src/components/WorkspaceFunc.js +++ b/src/components/WorkspaceFunc.js @@ -13,6 +13,7 @@ import { initialXml } from './Blockly/initialXml.js'; import Compile from './Compile'; import SolutionCheck from './Tutorial/SolutionCheck'; import Dialog from './Dialog'; +import Snackbar from './Snackbar'; import withWidth, { isWidthDown } from '@material-ui/core/withWidth'; import { withStyles } from '@material-ui/core/styles'; @@ -59,7 +60,9 @@ class WorkspaceFunc extends Component { open: false, file: 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 }); } + toggleSnackbar = () => { + this.setState({ snackbar: !this.state, message: '' }); + } + saveXmlFile = () => { var code = this.props.xml; this.toggleDialog(); @@ -121,6 +128,7 @@ class WorkspaceFunc extends Component { var extensionPosition = xmlFile.name.lastIndexOf('.'); 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){ 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 = () => { const workspace = Blockly.getMainWorkspace(); Blockly.Events.disable(); // https://groups.google.com/forum/#!topic/blockly/m7e3g0TC75Y @@ -142,6 +156,7 @@ class WorkspaceFunc extends Component { if(!this.props.solutionCheck){ this.props.workspaceName(null); } + this.setState({ snackbar: true, message: 'Das Projekt wurde erfolgreich zurückgesetzt.' }); } render() { @@ -204,11 +219,18 @@ class WorkspaceFunc extends Component { {this.state.file ?
- +
: null} + + ); };