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,93 +1,42 @@
|
|||||||
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);
|
<Tooltip title={"Auto save enabled"} arrow placement="right">
|
||||||
|
<div
|
||||||
return (
|
style={{
|
||||||
<div>
|
position: "relative",
|
||||||
{value === true ? (
|
width: "2rem",
|
||||||
<Tooltip title={"Auto save enabled"} arrow placement="right">
|
height: "2rem",
|
||||||
<IconButton
|
margin: "1rem",
|
||||||
style={{
|
}}
|
||||||
width: "40px",
|
>
|
||||||
height: "40px",
|
{loading && (
|
||||||
position: "absolute",
|
<FontAwesomeIcon
|
||||||
}}
|
style={{ position: "absolute" }}
|
||||||
>
|
icon={faCircleNotch}
|
||||||
{loading && (
|
spin={true}
|
||||||
<FontAwesomeIcon
|
size="2x"
|
||||||
style={{ position: "absolute" }}
|
color="grey"
|
||||||
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>
|
|
||||||
) : (
|
|
||||||
<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>
|
|
||||||
)}
|
)}
|
||||||
|
<FontAwesomeIcon
|
||||||
|
style={{
|
||||||
|
position: "absolute",
|
||||||
|
left: "50%",
|
||||||
|
top: "50%",
|
||||||
|
transform: "translate(-50%,-50%)",
|
||||||
|
}}
|
||||||
|
icon={faSave}
|
||||||
|
color={loading ? "grey" : "green"}
|
||||||
|
size={loading ? "1x" : "lg"}
|
||||||
|
/>
|
||||||
</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>
|
||||||
<ListItemText primary={item.text} />
|
{item.text === "CodeEditor" ? (
|
||||||
|
<Badge badgeContent={"Experimental"} color="primary">
|
||||||
|
<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