parent
							
								
									748c29c260
								
							
						
					
					
						commit
						9f7ba27d69
					
				| @ -26,8 +26,8 @@ const CodeEditor = (props) => { | |||||||
|   const [resetDialog, setResetDialog] = useState(false); |   const [resetDialog, setResetDialog] = useState(false); | ||||||
|   const [blocklyCode, setBlocklyCode] = useState(""); |   const [blocklyCode, setBlocklyCode] = useState(""); | ||||||
|   const [defaultValue, setDefaultValue] = useState( |   const [defaultValue, setDefaultValue] = useState( | ||||||
|     sessionStorage.getItem("ArduinoCode") |     localStorage.getItem("ArduinoCode") | ||||||
|       ? sessionStorage.getItem("ArduinoCode") |       ? localStorage.getItem("ArduinoCode") | ||||||
|       : ` |       : ` | ||||||
| #include <senseBoxIO.h> //needs to be always included
 | #include <senseBoxIO.h> //needs to be always included
 | ||||||
| 
 | 
 | ||||||
| @ -129,7 +129,7 @@ void loop() { | |||||||
|   }; |   }; | ||||||
| 
 | 
 | ||||||
|   const saveValue = () => { |   const saveValue = () => { | ||||||
|     sessionStorage.setItem("ArduinoCode", value); |     localStorage.setItem("ArduinoCode", value); | ||||||
|     setAutoSave(true); |     setAutoSave(true); | ||||||
|     setTimeout(() => setAutoSave(false), 1000); |     setTimeout(() => setAutoSave(false), 1000); | ||||||
|   }; |   }; | ||||||
|  | |||||||
| @ -1,27 +1,18 @@ | |||||||
| import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; | import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; | ||||||
| import { useSelector } from "react-redux"; | import { useSelector } from "react-redux"; | ||||||
| import { | import { faCircleNotch, faSave } from "@fortawesome/free-solid-svg-icons"; | ||||||
|   faCircleNotch, |  | ||||||
|   faSave, |  | ||||||
|   faSpinner, |  | ||||||
| } from "@fortawesome/free-solid-svg-icons"; |  | ||||||
| import Tooltip from "@material-ui/core/Tooltip"; | import Tooltip from "@material-ui/core/Tooltip"; | ||||||
| import { IconButton } from "@material-ui/core"; |  | ||||||
| import PropTypes from "prop-types"; | import PropTypes from "prop-types"; | ||||||
| import React from "react"; | import React from "react"; | ||||||
| 
 | 
 | ||||||
| const SaveIcon = ({ loading }) => { | const SaveIcon = ({ loading }) => ( | ||||||
|   const value = useSelector((state) => state.general.autoSave); |  | ||||||
| 
 |  | ||||||
|   return ( |  | ||||||
|     <div> |  | ||||||
|       {value === true ? ( |  | ||||||
|   <Tooltip title={"Auto save enabled"} arrow placement="right"> |   <Tooltip title={"Auto save enabled"} arrow placement="right"> | ||||||
|           <IconButton |     <div | ||||||
|       style={{ |       style={{ | ||||||
|               width: "40px", |         position: "relative", | ||||||
|               height: "40px", |         width: "2rem", | ||||||
|               position: "absolute", |         height: "2rem", | ||||||
|  |         margin: "1rem", | ||||||
|       }} |       }} | ||||||
|     > |     > | ||||||
|       {loading && ( |       {loading && ( | ||||||
| @ -30,7 +21,7 @@ const SaveIcon = ({ loading }) => { | |||||||
|           icon={faCircleNotch} |           icon={faCircleNotch} | ||||||
|           spin={true} |           spin={true} | ||||||
|           size="2x" |           size="2x" | ||||||
|                 color="#4EAF47" |           color="grey" | ||||||
|         /> |         /> | ||||||
|       )} |       )} | ||||||
|       <FontAwesomeIcon |       <FontAwesomeIcon | ||||||
| @ -41,53 +32,11 @@ const SaveIcon = ({ loading }) => { | |||||||
|           transform: "translate(-50%,-50%)", |           transform: "translate(-50%,-50%)", | ||||||
|         }} |         }} | ||||||
|         icon={faSave} |         icon={faSave} | ||||||
|               color={loading ? "gray" : "#4EAF47"} |         color={loading ? "grey" : "green"} | ||||||
|               size={loading ? "1x" : "md"} |         size={loading ? "1x" : "lg"} | ||||||
|       /> |       /> | ||||||
|           </IconButton> |  | ||||||
|         </Tooltip> |  | ||||||
|       ) : ( |  | ||||||
|         <Tooltip title={"Auto save disabled"} arrow placement="right"> |  | ||||||
|           <IconButton |  | ||||||
|             style={{ |  | ||||||
|               width: "40px", |  | ||||||
|               height: "40px", |  | ||||||
|               position: "absolute", |  | ||||||
|             }} |  | ||||||
|             onClick={() => { |  | ||||||
|               this.propTypes.setAutoSave(true); |  | ||||||
|             }} |  | ||||||
|           > |  | ||||||
|             {loading && ( |  | ||||||
|               <FontAwesomeIcon |  | ||||||
|                 style={{ position: "absolute" }} |  | ||||||
|                 icon={faCircleNotch} |  | ||||||
|                 spin={true} |  | ||||||
|                 size="2x" |  | ||||||
|                 color="#4EAF47" |  | ||||||
|               /> |  | ||||||
|             )} |  | ||||||
|             <FontAwesomeIcon |  | ||||||
|               style={{ |  | ||||||
|                 position: "absolute", |  | ||||||
|                 left: "50%", |  | ||||||
|                 top: "50%", |  | ||||||
|                 transform: "translate(-50%,-50%)", |  | ||||||
|               }} |  | ||||||
|               icon={faSave} |  | ||||||
|               color={loading ? "gray" : "#4EAF47"} |  | ||||||
|               size={loading ? "1x" : "md"} |  | ||||||
|             /> |  | ||||||
|           </IconButton> |  | ||||||
|         </Tooltip> |  | ||||||
|       )} |  | ||||||
|     </div> |     </div> | ||||||
|   ); |   </Tooltip> | ||||||
| }; | ); | ||||||
| 
 |  | ||||||
| SaveIcon.propTypes = { |  | ||||||
|   setAutoSave: PropTypes.func.isRequired, |  | ||||||
|   autoSave: PropTypes.bool.isRequired, |  | ||||||
| }; |  | ||||||
| 
 | 
 | ||||||
| export default SaveIcon; | export default SaveIcon; | ||||||
|  | |||||||
| @ -1,30 +1,30 @@ | |||||||
| 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 Prism from "prismjs"; | import Prism from "prismjs"; | ||||||
| import "prismjs/themes/prism.css"; | import "prismjs/themes/prism.css"; | ||||||
| import "prismjs/plugins/line-numbers/prism-line-numbers"; | import "prismjs/plugins/line-numbers/prism-line-numbers"; | ||||||
| import "prismjs/plugins/line-numbers/prism-line-numbers.css"; | import "prismjs/plugins/line-numbers/prism-line-numbers.css"; | ||||||
| 
 | import withWidth from "@material-ui/core/withWidth"; | ||||||
| import withWidth from '@material-ui/core/withWidth'; | import { withStyles } from "@material-ui/core/styles"; | ||||||
| import { withStyles } from '@material-ui/core/styles'; | import MuiAccordion from "@material-ui/core/Accordion"; | ||||||
| import MuiAccordion from '@material-ui/core/Accordion'; | import MuiAccordionSummary from "@material-ui/core/AccordionSummary"; | ||||||
| import MuiAccordionSummary from '@material-ui/core/AccordionSummary'; | import MuiAccordionDetails from "@material-ui/core/AccordionDetails"; | ||||||
| import MuiAccordionDetails from '@material-ui/core/AccordionDetails'; | import { Card, Switch } from "@material-ui/core"; | ||||||
| import { Card } from '@material-ui/core'; | import * as Blockly from "blockly"; | ||||||
| import * as Blockly from 'blockly' | import { default as MonacoEditor } from "@monaco-editor/react"; | ||||||
| 
 | import { DiffEditor as MonacoDiffEditor } from "@monaco-editor/react"; | ||||||
| 
 | 
 | ||||||
| const Accordion = withStyles((theme) => ({ | const Accordion = withStyles((theme) => ({ | ||||||
|   root: { |   root: { | ||||||
|     border: `1px solid ${theme.palette.secondary.main}`, |     border: `1px solid ${theme.palette.secondary.main}`, | ||||||
|     boxShadow: 'none', |     boxShadow: "none", | ||||||
|     '&:before': { |     "&:before": { | ||||||
|       display: 'none', |       display: "none", | ||||||
|     }, |     }, | ||||||
|     '&$expanded': { |     "&$expanded": { | ||||||
|       margin: 'auto', |       margin: "auto", | ||||||
|     }, |     }, | ||||||
|   }, |   }, | ||||||
|   expanded: {}, |   expanded: {}, | ||||||
| @ -34,15 +34,15 @@ const AccordionSummary = withStyles((theme) => ({ | |||||||
|   root: { |   root: { | ||||||
|     backgroundColor: theme.palette.secondary.main, |     backgroundColor: theme.palette.secondary.main, | ||||||
|     borderBottom: `1px solid white`, |     borderBottom: `1px solid white`, | ||||||
|     marginBottom: '-1px', |     marginBottom: "-1px", | ||||||
|     minHeight: '50px', |     minHeight: "50px", | ||||||
|     '&$expanded': { |     "&$expanded": { | ||||||
|       minHeight: '50px', |       minHeight: "50px", | ||||||
|     }, |     }, | ||||||
|   }, |   }, | ||||||
|   content: { |   content: { | ||||||
|     '&$expanded': { |     "&$expanded": { | ||||||
|       margin: '12px 0', |       margin: "12px 0", | ||||||
|     }, |     }, | ||||||
|   }, |   }, | ||||||
|   expanded: {}, |   expanded: {}, | ||||||
| @ -54,40 +54,60 @@ const AccordionDetails = withStyles((theme) => ({ | |||||||
|   }, |   }, | ||||||
| }))(MuiAccordionDetails); | }))(MuiAccordionDetails); | ||||||
| 
 | 
 | ||||||
| 
 |  | ||||||
| class CodeViewer extends Component { | class CodeViewer extends Component { | ||||||
| 
 |  | ||||||
|   constructor(props) { |   constructor(props) { | ||||||
|     super(props); |     super(props); | ||||||
|     this.state = { |     this.state = { | ||||||
|  |       code: this.props.arduino, | ||||||
|  |       changed: false, | ||||||
|       expanded: true, |       expanded: true, | ||||||
|       componentHeight: null |       componentHeight: null, | ||||||
|     }; |     }; | ||||||
|     this.myDiv = React.createRef(); |     this.myDiv = React.createRef(); | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   componentDidMount() { |   componentDidMount() { | ||||||
|     Prism.highlightAll(); |     this.setState({ componentHeight: this.myDiv.current.offsetHeight + "px" }); | ||||||
|     this.setState({ componentHeight: this.myDiv.current.offsetHeight + 'px' }); |  | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   componentDidUpdate(props, state) { |   componentDidUpdate(prevProps, prevState) { | ||||||
|     if (this.myDiv.current && this.myDiv.current.offsetHeight + 'px' !== this.state.componentHeight) { |     // if (this.props.arduino !== prevProps.arduino) {
 | ||||||
|       this.setState({ componentHeight: this.myDiv.current.offsetHeight + 'px' }); |     //   this.setState({ changed: true });
 | ||||||
|  | 
 | ||||||
|  |     //   console.log(`code changed: ${this.state.changed}`);
 | ||||||
|  |     //   if (this.state.changed && prevState.code !== this.props.arduino) {
 | ||||||
|  |     //     this.setState({ code: this.props.arduino });
 | ||||||
|  |     //     this.setState({ changed: false });
 | ||||||
|  |     //   }
 | ||||||
|  | 
 | ||||||
|  |     // if (this.state.code !== prevState.code && this.state.changed) {
 | ||||||
|  |     //   this.setState({ changed: false });
 | ||||||
|  |     // }
 | ||||||
|  | 
 | ||||||
|  |     // if (this.props.arduino !== this.state.code) {
 | ||||||
|  |     //   this.setState({ changed: true });
 | ||||||
|  |     //   //this.setState({ code: this.props.arduino });
 | ||||||
|  |     // }
 | ||||||
|  | 
 | ||||||
|  |     if ( | ||||||
|  |       this.myDiv.current && | ||||||
|  |       this.myDiv.current.offsetHeight + "px" !== this.state.componentHeight | ||||||
|  |     ) { | ||||||
|  |       this.setState({ | ||||||
|  |         componentHeight: this.myDiv.current.offsetHeight + "px", | ||||||
|  |       }); | ||||||
|     } |     } | ||||||
|     Prism.highlightAll(); |  | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   onChange = () => { |   onChange = () => { | ||||||
|     this.setState({ expanded: !this.state.expanded }); |     this.setState({ expanded: !this.state.expanded }); | ||||||
| 
 |   }; | ||||||
|   } |  | ||||||
| 
 | 
 | ||||||
|   render() { |   render() { | ||||||
|     var curlyBrackets = '{ }'; |     var curlyBrackets = "{ }"; | ||||||
|     var unequal = '<>'; |     var unequal = "<>"; | ||||||
|     return ( |     return ( | ||||||
|       <Card style={{ height: '100%', maxHeight: '60vH' }} ref={this.myDiv}> |       <Card style={{ height: "100%", maxHeight: "60vH" }} ref={this.myDiv}> | ||||||
|         <Accordion |         <Accordion | ||||||
|           square={true} |           square={true} | ||||||
|           style={{ margin: 0 }} |           style={{ margin: 0 }} | ||||||
| @ -95,15 +115,32 @@ class CodeViewer extends Component { | |||||||
|           onChange={this.onChange} |           onChange={this.onChange} | ||||||
|         > |         > | ||||||
|           <AccordionSummary> |           <AccordionSummary> | ||||||
|             <b style={{ fontSize: '20px', marginRight: '5px', width: '35px' }}>{curlyBrackets}</b> |             <b style={{ fontSize: "20px", marginRight: "5px", width: "35px" }}> | ||||||
|             <div style={{ margin: 'auto 5px 2px 0px' }}>{Blockly.Msg.codeviewer_arduino}</div> |               {curlyBrackets} | ||||||
|  |             </b> | ||||||
|  |             <div style={{ margin: "auto 5px 2px 0px" }}> | ||||||
|  |               {Blockly.Msg.codeviewer_arduino} | ||||||
|  |             </div> | ||||||
|           </AccordionSummary> |           </AccordionSummary> | ||||||
|           <AccordionDetails style={{ padding: 0, height: `calc(${this.state.componentHeight} - 50px - 50px)`, backgroundColor: 'white' }}> |           <AccordionDetails | ||||||
|             <pre className="line-numbers" style={{ paddingBottom: 0, width: '100%', overflow: 'auto', scrollbarWidth: 'thin', height: 'calc(100% - 30px)', margin: '15px 0', paddingTop: 0, whiteSpace: 'pre-wrap', backgroundColor: 'white' }}> |             style={{ | ||||||
|               <code className="language-clike"> |               padding: 0, | ||||||
|                 {this.props.arduino} |               height: `calc(${this.state.componentHeight} - 50px - 50px)`, | ||||||
|               </code> |               backgroundColor: "white", | ||||||
|             </pre> |             }} | ||||||
|  |           > | ||||||
|  |             <MonacoEditor | ||||||
|  |               height="80vh" | ||||||
|  |               defaultLanguage="cpp" | ||||||
|  |               value={this.props.arduino} | ||||||
|  |               // modified={this.props.arduino}
 | ||||||
|  |               // original={this.state.code}
 | ||||||
|  |               options={{ | ||||||
|  |                 readOnly: true, | ||||||
|  | 
 | ||||||
|  |                 fontSize: "12px", | ||||||
|  |               }} | ||||||
|  |             /> | ||||||
|           </AccordionDetails> |           </AccordionDetails> | ||||||
|         </Accordion> |         </Accordion> | ||||||
|         <Accordion |         <Accordion | ||||||
| @ -113,32 +150,43 @@ class CodeViewer extends Component { | |||||||
|           onChange={this.onChange} |           onChange={this.onChange} | ||||||
|         > |         > | ||||||
|           <AccordionSummary> |           <AccordionSummary> | ||||||
|             <b style={{ fontSize: '20px', marginRight: '5px', width: '35px' }}>{unequal}</b> |             <b style={{ fontSize: "20px", marginRight: "5px", width: "35px" }}> | ||||||
|             <div style={{ margin: 'auto 5px 2px 0px' }}>{Blockly.Msg.codeviewer_xml}</div> |               {unequal} | ||||||
|  |             </b> | ||||||
|  |             <div style={{ margin: "auto 5px 2px 0px" }}> | ||||||
|  |               {Blockly.Msg.codeviewer_xml} | ||||||
|  |             </div> | ||||||
|           </AccordionSummary> |           </AccordionSummary> | ||||||
|           <AccordionDetails style={{ padding: 0, height: `calc(${this.state.componentHeight} - 50px - 50px)`, backgroundColor: 'white' }}> |           <AccordionDetails | ||||||
|             <pre className="line-numbers" style={{ paddingBottom: 0, width: '100%', overflow: 'auto', scrollbarWidth: 'thin', height: 'calc(100% - 30px)', margin: '15px 0', paddingTop: 0, whiteSpace: 'pre-wrap', backgroundColor: 'white' }}> |             style={{ | ||||||
|               <code className="language-xml"> |               padding: 0, | ||||||
|                 {`${this.props.xml}`} |               height: `calc(${this.state.componentHeight} - 50px - 50px)`, | ||||||
|               </code> |               backgroundColor: "white", | ||||||
|             </pre> |             }} | ||||||
|  |           > | ||||||
|  |             <MonacoEditor | ||||||
|  |               height="80vh" | ||||||
|  |               defaultLanguage="xml" | ||||||
|  |               value={this.props.xml} | ||||||
|  |               readOnly={true} | ||||||
|  |             /> | ||||||
|           </AccordionDetails> |           </AccordionDetails> | ||||||
|         </Accordion> |         </Accordion> | ||||||
|       </Card> |       </Card> | ||||||
|     ); |     ); | ||||||
|   }; |   } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| CodeViewer.propTypes = { | CodeViewer.propTypes = { | ||||||
|   arduino: PropTypes.string.isRequired, |   arduino: PropTypes.string.isRequired, | ||||||
|   xml: PropTypes.string.isRequired, |   xml: PropTypes.string.isRequired, | ||||||
|   tooltip: PropTypes.string.isRequired |   tooltip: PropTypes.string.isRequired, | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| const mapStateToProps = state => ({ | const mapStateToProps = (state) => ({ | ||||||
|   arduino: state.workspace.code.arduino, |   arduino: state.workspace.code.arduino, | ||||||
|   xml: state.workspace.code.xml, |   xml: state.workspace.code.xml, | ||||||
|   tooltip: state.workspace.code.tooltip |   tooltip: state.workspace.code.tooltip, | ||||||
| }); | }); | ||||||
| 
 | 
 | ||||||
| export default connect(mapStateToProps, null)(withWidth()(CodeViewer)); | export default connect(mapStateToProps, null)(withWidth()(CodeViewer)); | ||||||
|  | |||||||
| @ -22,8 +22,7 @@ import { faCode } from "@fortawesome/free-solid-svg-icons"; | |||||||
| import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; | import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; | ||||||
| import TooltipViewer from "./TooltipViewer"; | import TooltipViewer from "./TooltipViewer"; | ||||||
| import Dialog from "./Dialog"; | import Dialog from "./Dialog"; | ||||||
| import AutoSave from "./Workspace/AutoSave"; | // import Autosave from "./Workspace/AutoSave";
 | ||||||
| 
 |  | ||||||
| const styles = (theme) => ({ | const styles = (theme) => ({ | ||||||
|   codeOn: { |   codeOn: { | ||||||
|     backgroundColor: theme.palette.primary.main, |     backgroundColor: theme.palette.primary.main, | ||||||
| @ -55,7 +54,7 @@ class Home extends Component { | |||||||
|       key: "", |       key: "", | ||||||
|       message: "", |       message: "", | ||||||
|       open: true, |       open: true, | ||||||
|       initialXml: sessionStorage.getItem("autoSaveXML"), |       initialXml: localStorage.getItem("autoSaveXML"), | ||||||
|     }; |     }; | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
| @ -116,7 +115,6 @@ class Home extends Component { | |||||||
|   render() { |   render() { | ||||||
|     return ( |     return ( | ||||||
|       <div> |       <div> | ||||||
|         <AutoSave /> |  | ||||||
|         {this.props.statistics ? ( |         {this.props.statistics ? ( | ||||||
|           <div style={{ float: "left", height: "40px", position: "relative" }}> |           <div style={{ float: "left", height: "40px", position: "relative" }}> | ||||||
|             <WorkspaceStats /> |             <WorkspaceStats /> | ||||||
| @ -127,6 +125,7 @@ class Home extends Component { | |||||||
|           className="workspaceFunc" |           className="workspaceFunc" | ||||||
|           style={{ float: "right", height: "40px", marginBottom: "20px" }} |           style={{ float: "right", height: "40px", marginBottom: "20px" }} | ||||||
|         > |         > | ||||||
|  |           {/* <Autosave /> */} | ||||||
|           <WorkspaceFunc |           <WorkspaceFunc | ||||||
|             project={this.props.project} |             project={this.props.project} | ||||||
|             projectType={this.props.projectType} |             projectType={this.props.projectType} | ||||||
|  | |||||||
| @ -21,6 +21,7 @@ import ListItemIcon from "@material-ui/core/ListItemIcon"; | |||||||
| import ListItemText from "@material-ui/core/ListItemText"; | import ListItemText from "@material-ui/core/ListItemText"; | ||||||
| import LinearProgress from "@material-ui/core/LinearProgress"; | import LinearProgress from "@material-ui/core/LinearProgress"; | ||||||
| import Tour from "reactour"; | import Tour from "reactour"; | ||||||
|  | import { Badge } from "@material-ui/core"; | ||||||
| import { home, assessment } from "./Tour"; | import { home, assessment } from "./Tour"; | ||||||
| import { | import { | ||||||
|   faBars, |   faBars, | ||||||
| @ -259,7 +260,13 @@ class Navbar extends Component { | |||||||
|                       <ListItemIcon> |                       <ListItemIcon> | ||||||
|                         <FontAwesomeIcon icon={item.icon} /> |                         <FontAwesomeIcon icon={item.icon} /> | ||||||
|                       </ListItemIcon> |                       </ListItemIcon> | ||||||
|  |                       {item.text === "CodeEditor" ? ( | ||||||
|  |                         <Badge badgeContent={"Experimental"} color="primary"> | ||||||
|                           <ListItemText primary={item.text} /> |                           <ListItemText primary={item.text} /> | ||||||
|  |                         </Badge> | ||||||
|  |                       ) : ( | ||||||
|  |                         <ListItemText primary={item.text} /> | ||||||
|  |                       )} | ||||||
|                     </ListItem> |                     </ListItem> | ||||||
|                   </Link> |                   </Link> | ||||||
|                 ); |                 ); | ||||||
|  | |||||||
| @ -32,7 +32,7 @@ class AutoSave extends Component { | |||||||
| 
 | 
 | ||||||
|   saveValue = () => { |   saveValue = () => { | ||||||
|     this.setState({ ...this.state, saved: true }); |     this.setState({ ...this.state, saved: true }); | ||||||
|     sessionStorage.setItem("autoSaveXML", this.props.xml); |     localStorage.setItem("autoSaveXML", this.props.xml); | ||||||
|     setTimeout(() => this.setState({ ...this.state, saved: false }), 1000); |     setTimeout(() => this.setState({ ...this.state, saved: false }), 1000); | ||||||
|   }; |   }; | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -13,7 +13,7 @@ import ShareProject from "./ShareProject"; | |||||||
| import ResetWorkspace from "./ResetWorkspace"; | import ResetWorkspace from "./ResetWorkspace"; | ||||||
| import DeleteProject from "./DeleteProject"; | import DeleteProject from "./DeleteProject"; | ||||||
| import CopyCode from "./CopyCode"; | import CopyCode from "./CopyCode"; | ||||||
| 
 | import AutoSave from "./AutoSave"; | ||||||
| class WorkspaceFunc extends Component { | class WorkspaceFunc extends Component { | ||||||
|   componentDidUpdate() { |   componentDidUpdate() { | ||||||
|     console.log(this.props.autosave); |     console.log(this.props.autosave); | ||||||
| @ -21,7 +21,10 @@ class WorkspaceFunc extends Component { | |||||||
| 
 | 
 | ||||||
|   render() { |   render() { | ||||||
|     return ( |     return ( | ||||||
|       <div style={{ width: "max-content", display: "flex" }}> |       <div | ||||||
|  |         style={{ width: "max-content", display: "flex", alignItems: "center" }} | ||||||
|  |       > | ||||||
|  |         {!this.props.assessment & !this.props.multiple ? <AutoSave /> : null} | ||||||
|         {!this.props.assessment ? ( |         {!this.props.assessment ? ( | ||||||
|           <WorkspaceName |           <WorkspaceName | ||||||
|             style={{ marginRight: "5px" }} |             style={{ marginRight: "5px" }} | ||||||
|  | |||||||
| @ -1,51 +1,50 @@ | |||||||
| 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 { workspaceName } from '../../actions/workspaceActions'; | import { workspaceName } from "../../actions/workspaceActions"; | ||||||
| import { setDescription, updateProject } from '../../actions/projectActions'; | import { setDescription, updateProject } from "../../actions/projectActions"; | ||||||
| 
 | 
 | ||||||
| import Snackbar from '../Snackbar'; | import Snackbar from "../Snackbar"; | ||||||
| import Dialog from '../Dialog'; | 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 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"; | ||||||
| import Typography from '@material-ui/core/Typography'; | import Typography from "@material-ui/core/Typography"; | ||||||
| 
 | 
 | ||||||
| import { faPen } from "@fortawesome/free-solid-svg-icons"; | import { faPen } from "@fortawesome/free-solid-svg-icons"; | ||||||
| import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; | import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; | ||||||
| import * as Blockly from 'blockly/core' | import * as Blockly from "blockly/core"; | ||||||
| 
 | 
 | ||||||
| const styles = (theme) => ({ | const styles = (theme) => ({ | ||||||
|   workspaceName: { |   workspaceName: { | ||||||
|  |     minHeight: "40px", | ||||||
|     backgroundColor: theme.palette.secondary.main, |     backgroundColor: theme.palette.secondary.main, | ||||||
|     borderRadius: '25px', |     borderRadius: "25px", | ||||||
|     display: 'inline-flex', |     display: "inline-flex", | ||||||
|     cursor: 'pointer', |     cursor: "pointer", | ||||||
|     '&:hover': { |     "&:hover": { | ||||||
|       color: theme.palette.primary.main, |       color: theme.palette.primary.main, | ||||||
|     } |     }, | ||||||
|   } |   }, | ||||||
| }); | }); | ||||||
| 
 | 
 | ||||||
| 
 |  | ||||||
| class WorkspaceName extends Component { | class WorkspaceName extends Component { | ||||||
| 
 |  | ||||||
|   constructor(props) { |   constructor(props) { | ||||||
|     super(props); |     super(props); | ||||||
|     this.inputRef = React.createRef(); |     this.inputRef = React.createRef(); | ||||||
|     this.state = { |     this.state = { | ||||||
|       title: '', |       title: "", | ||||||
|       content: '', |       content: "", | ||||||
|       open: false, |       open: false, | ||||||
|       name: props.name, |       name: props.name, | ||||||
|       description: props.description, |       description: props.description, | ||||||
|       snackbar: false, |       snackbar: false, | ||||||
|       type: '', |       type: "", | ||||||
|       key: '', |       key: "", | ||||||
|       message: '' |       message: "", | ||||||
|     }; |     }; | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
| @ -59,47 +58,100 @@ class WorkspaceName extends Component { | |||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   toggleDialog = () => { |   toggleDialog = () => { | ||||||
|     this.setState({ open: !this.state, title: '', content: '' }); |     this.setState({ open: !this.state, title: "", content: "" }); | ||||||
|   } |   }; | ||||||
| 
 | 
 | ||||||
|   setFileName = (e) => { |   setFileName = (e) => { | ||||||
|     this.setState({ name: e.target.value }); |     this.setState({ name: e.target.value }); | ||||||
|   } |   }; | ||||||
| 
 | 
 | ||||||
|   setDescription = (e) => { |   setDescription = (e) => { | ||||||
|     this.setState({ description: e.target.value }); |     this.setState({ description: e.target.value }); | ||||||
|   } |   }; | ||||||
| 
 | 
 | ||||||
|   renameWorkspace = () => { |   renameWorkspace = () => { | ||||||
|     this.props.workspaceName(this.state.name); |     this.props.workspaceName(this.state.name); | ||||||
|     this.toggleDialog(); |     this.toggleDialog(); | ||||||
|     if (this.props.projectType === 'project' || this.props.projectType === 'gallery' || this.state.projectType === 'gallery') { |     if ( | ||||||
|       if (this.props.projectType === 'gallery' || this.state.projectType === 'gallery') { |       this.props.projectType === "project" || | ||||||
|  |       this.props.projectType === "gallery" || | ||||||
|  |       this.state.projectType === "gallery" | ||||||
|  |     ) { | ||||||
|  |       if ( | ||||||
|  |         this.props.projectType === "gallery" || | ||||||
|  |         this.state.projectType === "gallery" | ||||||
|  |       ) { | ||||||
|         this.props.setDescription(this.state.description); |         this.props.setDescription(this.state.description); | ||||||
|       } |       } | ||||||
|       if (this.state.projectType === 'gallery') { |       if (this.state.projectType === "gallery") { | ||||||
|         this.saveGallery(); |         this.saveGallery(); | ||||||
|       } else { |       } else { | ||||||
|         this.props.updateProject(this.props.projectType, this.props.project._id); |         this.props.updateProject( | ||||||
|  |           this.props.projectType, | ||||||
|  |           this.props.project._id | ||||||
|  |         ); | ||||||
|       } |       } | ||||||
|     } else { |     } else { | ||||||
|       this.setState({ snackbar: true, type: 'success', key: Date.now(), message: `${Blockly.Msg.messages_rename_success_01} ${this.state.name} ${Blockly.Msg.messages_rename_success_02}` }); |       this.setState({ | ||||||
|     } |         snackbar: true, | ||||||
|  |         type: "success", | ||||||
|  |         key: Date.now(), | ||||||
|  |         message: `${Blockly.Msg.messages_rename_success_01} ${this.state.name} ${Blockly.Msg.messages_rename_success_02}`, | ||||||
|  |       }); | ||||||
|     } |     } | ||||||
|  |   }; | ||||||
| 
 | 
 | ||||||
|   render() { |   render() { | ||||||
|     return ( |     return ( | ||||||
|       <div style={this.props.style}> |       <div style={this.props.style}> | ||||||
|         <Tooltip title={`${Blockly.Msg.tooltip_project_title} ${this.props.name ? `: ${this.props.name}` : ''}`} arrow style={{ height: '100%' }}> |         <Tooltip | ||||||
|  |           title={`${Blockly.Msg.tooltip_project_title} ${ | ||||||
|  |             this.props.name ? `: ${this.props.name}` : "" | ||||||
|  |           }`}
 | ||||||
|  |           arrow | ||||||
|  |           style={{ height: "100%" }} | ||||||
|  |         > | ||||||
|           <div |           <div | ||||||
|             className={this.props.classes.workspaceName} |             className={this.props.classes.workspaceName} | ||||||
|             onClick={() => { if (this.props.multiple) { this.props.workspaceName(this.props.project.title); if (this.props.projectType === 'gallery') { this.props.setDescription(this.props.project.description); } } this.setState({ open: true, title: this.props.projectType === 'gallery' ? 'Projektdaten ändern' : this.props.projectType === 'project' ? 'Projekt umbenennen' : 'Projekt benennen', content: this.props.projectType === 'gallery' ? 'Bitte gib einen Titel und eine Beschreibung für das Galerie-Projekt ein und bestätige die Angaben mit einem Klick auf \'Eingabe\'.' : 'Bitte gib einen Namen für das Projekt ein und bestätige diesen mit einem Klick auf \'Eingabe\'.' }) }} |             onClick={() => { | ||||||
|  |               if (this.props.multiple) { | ||||||
|  |                 this.props.workspaceName(this.props.project.title); | ||||||
|  |                 if (this.props.projectType === "gallery") { | ||||||
|  |                   this.props.setDescription(this.props.project.description); | ||||||
|  |                 } | ||||||
|  |               } | ||||||
|  |               this.setState({ | ||||||
|  |                 open: true, | ||||||
|  |                 title: | ||||||
|  |                   this.props.projectType === "gallery" | ||||||
|  |                     ? "Projektdaten ändern" | ||||||
|  |                     : this.props.projectType === "project" | ||||||
|  |                     ? "Projekt umbenennen" | ||||||
|  |                     : "Projekt benennen", | ||||||
|  |                 content: | ||||||
|  |                   this.props.projectType === "gallery" | ||||||
|  |                     ? "Bitte gib einen Titel und eine Beschreibung für das Galerie-Projekt ein und bestätige die Angaben mit einem Klick auf 'Eingabe'." | ||||||
|  |                     : "Bitte gib einen Namen für das Projekt ein und bestätige diesen mit einem Klick auf 'Eingabe'.", | ||||||
|  |               }); | ||||||
|  |             }} | ||||||
|           > |           > | ||||||
|             {this.props.name && !isWidthDown(this.props.projectType === 'project' || this.props.projectType === 'gallery' ? 'xl' : 'xs', this.props.width) ? |             {this.props.name && | ||||||
|               <Typography style={{ margin: 'auto -3px auto 12px' }}>{this.props.name}</Typography> |             !isWidthDown( | ||||||
|               : null} |               this.props.projectType === "project" || | ||||||
|             <div style={{ width: '40px', display: 'flex' }}> |                 this.props.projectType === "gallery" | ||||||
|               <FontAwesomeIcon icon={faPen} style={{ height: '18px', width: '18px', margin: 'auto' }} /> |                 ? "xl" | ||||||
|  |                 : "xs", | ||||||
|  |               this.props.width | ||||||
|  |             ) ? ( | ||||||
|  |               <Typography style={{ margin: "auto -3px auto 12px" }}> | ||||||
|  |                 {this.props.name} | ||||||
|  |               </Typography> | ||||||
|  |             ) : null} | ||||||
|  |             <div style={{ width: "40px", display: "flex" }}> | ||||||
|  |               <FontAwesomeIcon | ||||||
|  |                 icon={faPen} | ||||||
|  |                 style={{ height: "18px", width: "18px", margin: "auto" }} | ||||||
|  |               /> | ||||||
|             </div> |             </div> | ||||||
|           </div> |           </div> | ||||||
|         </Tooltip> |         </Tooltip> | ||||||
| @ -114,23 +166,69 @@ class WorkspaceName extends Component { | |||||||
|           open={this.state.open} |           open={this.state.open} | ||||||
|           title={this.state.title} |           title={this.state.title} | ||||||
|           content={this.state.content} |           content={this.state.content} | ||||||
|           onClose={() => { this.toggleDialog(); this.setState({ name: this.props.name, description: this.props.description }); }} |           onClose={() => { | ||||||
|           onClick={() => { this.toggleDialog(); this.setState({ name: this.props.name, description: this.props.description }); }} |             this.toggleDialog(); | ||||||
|           button={'Abbrechen'} |             this.setState({ | ||||||
|  |               name: this.props.name, | ||||||
|  |               description: this.props.description, | ||||||
|  |             }); | ||||||
|  |           }} | ||||||
|  |           onClick={() => { | ||||||
|  |             this.toggleDialog(); | ||||||
|  |             this.setState({ | ||||||
|  |               name: this.props.name, | ||||||
|  |               description: this.props.description, | ||||||
|  |             }); | ||||||
|  |           }} | ||||||
|  |           button={"Abbrechen"} | ||||||
|         > |         > | ||||||
|           <div style={{ marginTop: '10px' }}> |           <div style={{ marginTop: "10px" }}> | ||||||
|             {this.props.projectType === 'gallery' || this.state.projectType === 'gallery' ? |             {this.props.projectType === "gallery" || | ||||||
|  |             this.state.projectType === "gallery" ? ( | ||||||
|               <div> |               <div> | ||||||
|                 <TextField autoFocus placeholder={this.state.saveXml ? 'Dateiname' : 'Projekttitel'} value={this.state.name} onChange={this.setFileName} style={{ marginBottom: '10px' }} /> |                 <TextField | ||||||
|                 <TextField fullWidth multiline placeholder={'Projektbeschreibung'} value={this.state.description} onChange={this.setDescription} style={{ marginBottom: '10px' }} /> |                   autoFocus | ||||||
|  |                   placeholder={ | ||||||
|  |                     this.state.saveXml ? "Dateiname" : "Projekttitel" | ||||||
|  |                   } | ||||||
|  |                   value={this.state.name} | ||||||
|  |                   onChange={this.setFileName} | ||||||
|  |                   style={{ marginBottom: "10px" }} | ||||||
|  |                 /> | ||||||
|  |                 <TextField | ||||||
|  |                   fullWidth | ||||||
|  |                   multiline | ||||||
|  |                   placeholder={"Projektbeschreibung"} | ||||||
|  |                   value={this.state.description} | ||||||
|  |                   onChange={this.setDescription} | ||||||
|  |                   style={{ marginBottom: "10px" }} | ||||||
|  |                 /> | ||||||
|               </div> |               </div> | ||||||
|               : <TextField autoFocus placeholder={this.state.saveXml ? 'Dateiname' : 'Projekttitel'} value={this.state.name} onChange={this.setFileName} style={{ marginRight: '10px' }} />} |             ) : ( | ||||||
|             <Button disabled={!this.state.name} variant='contained' color='primary' onClick={() => { this.renameWorkspace(); this.toggleDialog(); }}>Eingabe</Button> |               <TextField | ||||||
|  |                 autoFocus | ||||||
|  |                 placeholder={this.state.saveXml ? "Dateiname" : "Projekttitel"} | ||||||
|  |                 value={this.state.name} | ||||||
|  |                 onChange={this.setFileName} | ||||||
|  |                 style={{ marginRight: "10px" }} | ||||||
|  |               /> | ||||||
|  |             )} | ||||||
|  |             <Button | ||||||
|  |               disabled={!this.state.name} | ||||||
|  |               variant="contained" | ||||||
|  |               color="primary" | ||||||
|  |               onClick={() => { | ||||||
|  |                 this.renameWorkspace(); | ||||||
|  |                 this.toggleDialog(); | ||||||
|  |               }} | ||||||
|  |             > | ||||||
|  |               Eingabe | ||||||
|  |             </Button> | ||||||
|           </div> |           </div> | ||||||
|         </Dialog> |         </Dialog> | ||||||
|       </div> |       </div> | ||||||
|     ); |     ); | ||||||
|   }; |   } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| WorkspaceName.propTypes = { | WorkspaceName.propTypes = { | ||||||
| @ -142,10 +240,14 @@ WorkspaceName.propTypes = { | |||||||
|   message: PropTypes.object.isRequired, |   message: PropTypes.object.isRequired, | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| const mapStateToProps = state => ({ | const mapStateToProps = (state) => ({ | ||||||
|   name: state.workspace.name, |   name: state.workspace.name, | ||||||
|   description: state.project.description, |   description: state.project.description, | ||||||
|   message: state.message, |   message: state.message, | ||||||
| }); | }); | ||||||
| 
 | 
 | ||||||
| export default connect(mapStateToProps, { workspaceName, setDescription, updateProject })(withStyles(styles, { withTheme: true })(withWidth()(WorkspaceName))); | export default connect(mapStateToProps, { | ||||||
|  |   workspaceName, | ||||||
|  |   setDescription, | ||||||
|  |   updateProject, | ||||||
|  | })(withStyles(styles, { withTheme: true })(withWidth()(WorkspaceName))); | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user