import React, { Component } from 'react'; import PropTypes from 'prop-types'; import { connect } from 'react-redux'; import { checkError, readJSON, jsonString, progress, resetTutorial } from '../../../actions/tutorialBuilderActions'; import { saveAs } from 'file-saver'; import { detectWhitespacesAndReturnReadableResult } from '../../../helpers/whitespace'; import Breadcrumbs from '../../Breadcrumbs'; 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'; import Backdrop from '@material-ui/core/Backdrop'; import CircularProgress from '@material-ui/core/CircularProgress'; import Divider from '@material-ui/core/Divider'; import FormHelperText from '@material-ui/core/FormHelperText'; const styles = (theme) => ({ backdrop: { zIndex: theme.zIndex.drawer + 1, color: '#fff', }, errorColor: { color: theme.palette.error.dark } }); class Builder extends Component { constructor(props) { super(props); this.state = { open: false, title: '', content: '', string: false, snackbar: false, key: '', message: '' }; this.inputRef = React.createRef(); } componentWillUnmount() { this.reset(); } submit = () => { if (this.props.id === null) { var randomID = Date.now(); } else { randomID = this.props.id; } var isError = this.props.checkError(); if (isError) { this.setState({ snackbar: true, key: Date.now(), message: `Die Angaben für das Tutorial sind nicht vollständig.`, type: 'error' }); window.scrollTo(0, 0); } else { // export steps without attribute 'url' var steps = this.props.steps.map(step => { if (step.url) { delete step.url; } return step; }); var tutorial = { id: randomID, title: this.props.title, steps: steps } var blob = new Blob([JSON.stringify(tutorial)], { type: 'text/json' }); saveAs(blob, `${detectWhitespacesAndReturnReadableResult(tutorial.title)}.json`); } } reset = () => { this.props.resetTutorial(); this.setState({ snackbar: true, key: Date.now(), message: `Das Tutorial wurde erfolgreich zurückgesetzt.`, type: 'success' }); window.scrollTo(0, 0); } uploadJsonFile = (jsonFile) => { this.props.progress(true); if (jsonFile.type !== 'application/json') { this.props.progress(false); 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 = () => { 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); this.setState({ snackbar: true, key: Date.now(), message: `${isFile ? 'Die übergebene JSON-Datei' : 'Der übergebene JSON-String'} wurde erfolgreich übernommen.`, type: 'success' }); } catch (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; } return true; } toggle = () => { this.setState({ open: !this.state }); } render() { return (