update variable names

This commit is contained in:
Mario Pesch 2021-03-29 15:07:39 +02:00
parent 687ac32166
commit 255b1619b8
8 changed files with 932 additions and 688 deletions

View File

@ -1,20 +1,18 @@
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 { onChangeWorkspace, clearStats } from '../../actions/workspaceActions'; import { onChangeWorkspace, clearStats } from "../../actions/workspaceActions";
import BlocklyComponent from './BlocklyComponent'; import BlocklyComponent from "./BlocklyComponent";
import BlocklySvg from './BlocklySvg'; import BlocklySvg from "./BlocklySvg";
import * as Blockly from 'blockly/core'; import * as Blockly from "blockly/core";
import './blocks/index'; import "./blocks/index";
import './generator/index'; import "./generator/index";
import { initialXml } from './initialXml.js';
import { initialXml } from "./initialXml.js";
class BlocklyWindow extends Component { class BlocklyWindow extends Component {
constructor(props) { constructor(props) {
super(props); super(props);
this.simpleWorkspace = React.createRef(); this.simpleWorkspace = React.createRef();
@ -41,6 +39,7 @@ class BlocklyWindow extends Component {
Blockly.Events.disableOrphans(event); Blockly.Events.disableOrphans(event);
} }
}); });
Blockly.svgResize(workspace); Blockly.svgResize(workspace);
} }
@ -64,46 +63,65 @@ class BlocklyWindow extends Component {
// workspace.updateToolbox(toolbox.toolboxDef_); // workspace.updateToolbox(toolbox.toolboxDef_);
} }
Blockly.svgResize(workspace); Blockly.svgResize(workspace);
} }
render() { render() {
return ( return (
<div> <div>
<BlocklyComponent ref={this.simpleWorkspace} <BlocklyComponent
ref={this.simpleWorkspace}
style={this.props.svg ? { height: 0 } : this.props.blocklyCSS} style={this.props.svg ? { height: 0 } : this.props.blocklyCSS}
readOnly={this.props.readOnly !== undefined ? this.props.readOnly : false} readOnly={
trashcan={this.props.trashcan !== undefined ? this.props.trashcan : true} this.props.readOnly !== undefined ? this.props.readOnly : false
}
trashcan={
this.props.trashcan !== undefined ? this.props.trashcan : true
}
renderer={this.props.renderer} renderer={this.props.renderer}
zoom={{ // https://developers.google.com/blockly/guides/configure/web/zoom zoom={{
controls: this.props.zoomControls !== undefined ? this.props.zoomControls : true, // https://developers.google.com/blockly/guides/configure/web/zoom
controls:
this.props.zoomControls !== undefined
? this.props.zoomControls
: true,
wheel: false, wheel: false,
startScale: 1, startScale: 1,
maxScale: 3, maxScale: 3,
minScale: 0.3, minScale: 0.3,
scaleSpeed: 1.2 scaleSpeed: 1.2,
}} }}
grid={this.props.grid !== undefined && !this.props.grid ? {} : grid={
{ // https://developers.google.com/blockly/guides/configure/web/grid this.props.grid !== undefined && !this.props.grid
spacing: 20, ? {}
length: 1, : {
colour: '#4EAF47', // senseBox-green // https://developers.google.com/blockly/guides/configure/web/grid
snap: false spacing: 20,
}} length: 1,
media={'/media/blockly/'} colour: "#4EAF47", // senseBox-green
move={this.props.move !== undefined && !this.props.move ? {} : snap: false,
{ // https://developers.google.com/blockly/guides/configure/web/move }
scrollbars: true, }
drag: true, media={"/media/blockly/"}
wheel: false move={
}} this.props.move !== undefined && !this.props.move
initialXml={this.props.initialXml ? this.props.initialXml : initialXml} ? {}
> : {
</BlocklyComponent > // https://developers.google.com/blockly/guides/configure/web/move
{this.props.svg && this.props.initialXml ? <BlocklySvg initialXml={this.props.initialXml} /> : null} scrollbars: true,
drag: true,
wheel: false,
}
}
initialXml={
this.props.initialXml ? this.props.initialXml : initialXml
}
></BlocklyComponent>
{this.props.svg && this.props.initialXml ? (
<BlocklySvg initialXml={this.props.initialXml} />
) : null}
</div> </div>
); );
}; }
} }
BlocklyWindow.propTypes = { BlocklyWindow.propTypes = {
@ -114,10 +132,12 @@ BlocklyWindow.propTypes = {
workspaceXML: PropTypes.string.isRequired, workspaceXML: PropTypes.string.isRequired,
}; };
const mapStateToProps = state => ({ const mapStateToProps = (state) => ({
renderer: state.general.renderer, renderer: state.general.renderer,
language: state.general.language.Blockly, language: state.general.language.Blockly,
workspaceXML: state.workspace.code.xml, workspaceXML: state.workspace.code.xml,
}); });
export default connect(mapStateToProps, { onChangeWorkspace, clearStats })(BlocklyWindow); export default connect(mapStateToProps, { onChangeWorkspace, clearStats })(
BlocklyWindow
);

View File

@ -1,43 +1,46 @@
import Blockly from 'blockly/core'; import Blockly from "blockly/core";
import { getColour } from '../helpers/colour'; import { getColour } from "../helpers/colour";
import { getCompatibleTypes } from '../helpers/types' import { getCompatibleTypes } from "../helpers/types";
Blockly.Blocks['variables_set_dynamic'] = {
init: function () {
// const type = myVar.type;
this.setColour(getColour().variables);
this.setPreviousStatement(true, null);
this.setNextStatement(true, null);
this.appendValueInput('VALUE')
.appendField('set', 'set')
.appendField('', 'type')
.appendField(new Blockly.FieldVariable('VAR'), 'VAR')
.appendField('to');
},
onchange: function (e) {
let variableID = this.getFieldValue('VAR');
let variable = Blockly.getMainWorkspace().getVariableMap().getVariableById(variableID)
this.getField('type').setValue(variable.type);
this.getInput('VALUE').setCheck(getCompatibleTypes(variable.type));
Blockly.Blocks["variables_set_dynamic"] = {
init: function () {
// const type = myVar.type;
this.setColour(getColour().variables);
this.setPreviousStatement(true, null);
this.setNextStatement(true, null);
this.appendValueInput("VALUE")
.appendField("set", "set")
.appendField("", "type")
.appendField(new Blockly.FieldVariable("VAR"), "VAR")
.appendField("to");
},
onchange: function (e) {
let variableID = this.getFieldValue("VAR");
let variable = Blockly.getMainWorkspace()
.getVariableMap()
.getVariableById(variableID);
if (variable !== null) {
this.getField("type").setValue(variable.type);
this.getInput("VALUE").setCheck(getCompatibleTypes(variable.type));
} }
} },
};
Blockly.Blocks['variables_get_dynamic'] = {
init: function () {
this.setColour(getColour().variables);
this.appendDummyInput()
.appendField('', 'type')
.appendField(new Blockly.FieldVariable('VAR'), 'VAR');
this.setOutput(true);
},
onchange: function (e) {
let variableID = this.getFieldValue('VAR');
let variable = Blockly.getMainWorkspace().getVariableMap().getVariableById(variableID)
this.getField('type').setValue(variable.type);
Blockly.Blocks["variables_get_dynamic"] = {
init: function () {
this.setColour(getColour().variables);
this.appendDummyInput()
.appendField("", "type")
.appendField(new Blockly.FieldVariable("VAR"), "VAR");
this.setOutput(true);
},
onchange: function (e) {
let variableID = this.getFieldValue("VAR");
let variable = Blockly.getMainWorkspace()
.getVariableMap()
.getVariableById(variableID);
if (variable !== null) {
this.getField("type").setValue(variable.type);
} }
} },
};

View File

@ -10,6 +10,16 @@ export const UI = {
toolbox_time: "Zeit", toolbox_time: "Zeit",
toolbox_functions: "Funktionen", toolbox_functions: "Funktionen",
toolbox_variables: "Variablen", toolbox_variables: "Variablen",
variable_NUMBER: "Zahl (int)",
variable_SHORT_NUMBER: "char",
variable_LONG: "große Zahl (long)",
variable_DECIMAL: "Kommazahl (float)",
variables_TEXT: "Text (string)",
variables_ARRAY: "Array (array)",
variables_CHARACTER: "char (char)",
variables_BOOLEAN: "Boolean (boolean)",
variables_NULL: "void (void)",
variables_UNDEF: "undefined",
/** /**
* Tooltips * Tooltips

View File

@ -10,6 +10,16 @@ export const UI = {
toolbox_time: "Time", toolbox_time: "Time",
toolbox_functions: "Functions", toolbox_functions: "Functions",
toolbox_variables: "Variables", toolbox_variables: "Variables",
variable_NUMBER: "Number (int)",
variable_SHORT_NUMBER: "char",
variable_LONG: " Zahl (long)",
variable_DECIMAL: "Decimal (float)",
variables_TEXT: "Text (string)",
variables_ARRAY: "Array (array)",
variables_CHARACTER: "char (char)",
variables_BOOLEAN: "Boolean (boolean)",
variables_NULL: "void (void)",
variables_UNDEF: "undefined",
/** /**
* Tooltips * Tooltips

File diff suppressed because it is too large Load Diff

View File

@ -1,20 +1,20 @@
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 BlocklyWindow from '../Blockly/BlocklyWindow'; import BlocklyWindow from "../Blockly/BlocklyWindow";
import CodeViewer from '../CodeViewer'; import CodeViewer from "../CodeViewer";
import WorkspaceFunc from '../Workspace/WorkspaceFunc'; import WorkspaceFunc from "../Workspace/WorkspaceFunc";
import withWidth, { isWidthDown } from '@material-ui/core/withWidth'; import withWidth, { isWidthDown } from "@material-ui/core/withWidth";
import Grid from '@material-ui/core/Grid'; import Grid from "@material-ui/core/Grid";
import Card from '@material-ui/core/Card'; import Card from "@material-ui/core/Card";
import Typography from '@material-ui/core/Typography'; import Typography from "@material-ui/core/Typography";
import * as Blockly from 'blockly' import * as Blockly from "blockly";
import { initialXml } from "../Blockly/initialXml";
class Assessment extends Component { class Assessment extends Component {
componentDidMount() { componentDidMount() {
this.props.workspaceName(this.props.name); this.props.workspaceName(this.props.name);
} }
@ -28,48 +28,90 @@ class Assessment extends Component {
render() { render() {
var tutorialId = this.props.tutorial._id; var tutorialId = this.props.tutorial._id;
var currentTask = this.props.step; var currentTask = this.props.step;
var status = this.props.status.filter(status => status._id === tutorialId)[0]; var status = this.props.status.filter(
var taskIndex = status.tasks.findIndex(task => task._id === currentTask._id); (status) => status._id === tutorialId
)[0];
var taskIndex = status.tasks.findIndex(
(task) => task._id === currentTask._id
);
var statusTask = status.tasks[taskIndex]; var statusTask = status.tasks[taskIndex];
return ( return (
<div className="assessmentDiv" style={{ width: '100%' }}> <div className="assessmentDiv" style={{ width: "100%" }}>
<Typography variant='h4' style={{ float: 'left', marginBottom: '5px', height: '40px', display: 'table' }}>{currentTask.headline}</Typography> <Typography
<div style={{ float: 'right', height: '40px' }}><WorkspaceFunc assessment /></div> variant="h4"
<Grid container spacing={2} style={{ marginBottom: '5px' }}> style={{
float: "left",
marginBottom: "5px",
height: "40px",
display: "table",
}}
>
{currentTask.headline}
</Typography>
<div style={{ float: "right", height: "40px" }}>
<WorkspaceFunc assessment />
</div>
<Grid container spacing={2} style={{ marginBottom: "5px" }}>
<Grid item xs={12} md={6} lg={8}> <Grid item xs={12} md={6} lg={8}>
<BlocklyWindow <BlocklyWindow
initialXml={statusTask ? statusTask.xml ? statusTask.xml : null : null} initialXml={initialXml}
blockDisabled blockDisabled
blocklyCSS={{ height: '65vH' }} blocklyCSS={{ height: "65vH" }}
/> />
</Grid> </Grid>
<Grid item xs={12} md={6} lg={4} style={isWidthDown('sm', this.props.width) ? { height: 'max-content' } : {}}> <Grid
<Card style={{ height: 'calc(50% - 30px)', padding: '10px', marginBottom: '10px' }}> item
<Typography variant='h5'>{Blockly.Msg.tutorials_assessment_task}</Typography> xs={12}
md={6}
lg={4}
style={
isWidthDown("sm", this.props.width)
? { height: "max-content" }
: {}
}
>
<Card
style={{
height: "calc(50% - 30px)",
padding: "10px",
marginBottom: "10px",
}}
>
<Typography variant="h5">
{Blockly.Msg.tutorials_assessment_task}
</Typography>
<Typography>{currentTask.text}</Typography> <Typography>{currentTask.text}</Typography>
</Card> </Card>
<div style={isWidthDown('sm', this.props.width) ? { height: '500px' } : { height: '50%' }}> <div
style={
isWidthDown("sm", this.props.width)
? { height: "500px" }
: { height: "50%" }
}
>
<CodeViewer /> <CodeViewer />
</div> </div>
</Grid> </Grid>
</Grid> </Grid>
</div> </div>
); );
}; }
} }
Assessment.propTypes = { Assessment.propTypes = {
status: PropTypes.array.isRequired, status: PropTypes.array.isRequired,
change: PropTypes.number.isRequired, change: PropTypes.number.isRequired,
workspaceName: PropTypes.func.isRequired, workspaceName: PropTypes.func.isRequired,
tutorial: PropTypes.object.isRequired tutorial: PropTypes.object.isRequired,
}; };
const mapStateToProps = state => ({ const mapStateToProps = (state) => ({
change: state.tutorial.change, change: state.tutorial.change,
status: state.tutorial.status, status: state.tutorial.status,
tutorial: state.tutorial.tutorials[0] tutorial: state.tutorial.tutorials[0],
}); });
export default connect(mapStateToProps, { workspaceName })(withWidth()(Assessment)); export default connect(mapStateToProps, { workspaceName })(
withWidth()(Assessment)
);

View File

@ -1,57 +1,95 @@
import React, { Component } from 'react'; import React, { Component } from "react";
import Hardware from './Hardware'; import Hardware from "./Hardware";
import Requirement from './Requirement'; import Requirement from "./Requirement";
import BlocklyWindow from '../Blockly/BlocklyWindow'; import BlocklyWindow from "../Blockly/BlocklyWindow";
import Grid from '@material-ui/core/Grid';
import Typography from '@material-ui/core/Typography';
import ReactMarkdown from 'react-markdown'
import Grid from "@material-ui/core/Grid";
import Typography from "@material-ui/core/Typography";
import ReactMarkdown from "react-markdown";
class Instruction extends Component { class Instruction extends Component {
render() { render() {
var step = this.props.step; var step = this.props.step;
var isHardware = step.hardware && step.hardware.length > 0; var isHardware = step.hardware && step.hardware.length > 0;
var areRequirements = step.requirements && step.requirements.length > 0; var areRequirements = step.requirements && step.requirements.length > 0;
return ( return (
<div> <div>
<Typography variant='h4' style={{ marginBottom: '5px' }}>{step.headline}</Typography> <Typography variant="h4" style={{ marginBottom: "5px" }}>
<Typography style={isHardware ? {} : { marginBottom: '5px' }}><ReactMarkdown className={'tutorial'} linkTarget={'_blank'} skipHtml={false}>{step.text}</ReactMarkdown></Typography> {step.headline}
{isHardware ? </Typography>
<Hardware picture={step.hardware} /> : null} <Typography style={isHardware ? {} : { marginBottom: "5px" }}>
{areRequirements > 0 ? <ReactMarkdown
<Requirement requirements={step.requirements} /> : null} className={"tutorial"}
{step.media ? linkTarget={"_blank"}
step.media.picture ? skipHtml={false}
<div style={{ display: 'flex', justifyContent: 'center', marginBottom: '5px' }}> >
<img src={`${process.env.REACT_APP_BLOCKLY_API}/media/${step.media.picture.path}`} alt='' style={{ maxHeight: '40vH', maxWidth: '100%' }} /> {step.text}
</div> </ReactMarkdown>
: step.media.youtube ? </Typography>
/*16:9; width: 800px; height: width/16*9=450px*/ {isHardware ? <Hardware picture={step.hardware} /> : null}
<div style={{ maxWidth: '800px', margin: 'auto' }}> {areRequirements > 0 ? (
<div style={{ position: 'relative', height: 0, paddingBottom: 'calc(100% / 16 * 9)' }}> <Requirement requirements={step.requirements} />
<iframe title={step.media.youtube} style={{ position: 'absolute', top: '0', left: '0', width: '100%', maxWidth: '800px', height: '100%', maxHeight: '450px' }} src={`https://www.youtube.com/embed/${step.media.youtube}`} frameBorder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowFullScreen /> ) : null}
</div> {step.media ? (
</div> step.media.picture ? (
: null <div
: null} style={{
{step.xml ? display: "flex",
<Grid container spacing={2} style={{ marginBottom: '5px' }}> justifyContent: "center",
<Grid item xs={12} style={{display: 'flex', justifyContent: 'center'}}> marginBottom: "5px",
<BlocklyWindow }}
svg >
blockDisabled <img
initialXml={step.xml} src={`${process.env.REACT_APP_BLOCKLY_API}/media/${step.media.picture.path}`}
alt=""
style={{ maxHeight: "40vH", maxWidth: "100%" }}
/> />
</div>
) : step.media.youtube ? (
/*16:9; width: 800px; height: width/16*9=450px*/
<div style={{ maxWidth: "800px", margin: "auto" }}>
<div
style={{
position: "relative",
height: 0,
paddingBottom: "calc(100% / 16 * 9)",
}}
>
<iframe
title={step.media.youtube}
style={{
position: "absolute",
top: "0",
left: "0",
width: "100%",
maxWidth: "800px",
height: "100%",
maxHeight: "450px",
}}
src={`https://www.youtube.com/embed/${step.media.youtube}`}
frameBorder="0"
allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture"
allowFullScreen
/>
</div>
</div>
) : null
) : null}
{step.xml ? (
<Grid container spacing={2} style={{ marginBottom: "5px" }}>
<Grid
item
xs={12}
style={{ display: "flex", justifyContent: "center" }}
>
<BlocklyWindow svg blockDisabled initialXml={step.xml} />
</Grid> </Grid>
</Grid> </Grid>
: null} ) : null}
</div> </div>
); );
}; }
} }
export default Instruction; export default Instruction;

View File

@ -1,76 +1,88 @@
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 { login } from '../../actions/authActions' import { login } from "../../actions/authActions";
import { clearMessages } from '../../actions/messageActions' import { clearMessages } from "../../actions/messageActions";
import { withRouter } from 'react-router-dom'; import { withRouter } from "react-router-dom";
import Snackbar from '../Snackbar'; import Snackbar from "../Snackbar";
import Alert from '../Alert'; import Alert from "../Alert";
import Breadcrumbs from '../Breadcrumbs'; import Breadcrumbs from "../Breadcrumbs";
import Button from '@material-ui/core/Button'; import Button from "@material-ui/core/Button";
import IconButton from '@material-ui/core/IconButton'; import IconButton from "@material-ui/core/IconButton";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { faEye, faEyeSlash } from "@fortawesome/free-solid-svg-icons"; import { faEye, faEyeSlash } from "@fortawesome/free-solid-svg-icons";
import TextField from '@material-ui/core/TextField'; import TextField from "@material-ui/core/TextField";
import Divider from '@material-ui/core/Divider'; import Divider from "@material-ui/core/Divider";
import InputAdornment from '@material-ui/core/InputAdornment'; import InputAdornment from "@material-ui/core/InputAdornment";
import CircularProgress from '@material-ui/core/CircularProgress'; import CircularProgress from "@material-ui/core/CircularProgress";
import Link from '@material-ui/core/Link'; import Link from "@material-ui/core/Link";
import * as Blockly from 'blockly' import * as Blockly from "blockly";
export class Login extends Component { export class Login extends Component {
constructor(props) { constructor(props) {
super(props); super(props);
this.state = { this.state = {
redirect: props.location.state ? props.location.state.from.pathname : null, redirect: props.location.state
email: '', ? props.location.state.from.pathname
password: '', : null,
email: "",
password: "",
snackbar: false, snackbar: false,
type: '', type: "",
key: '', key: "",
message: '', message: "",
showPassword: false showPassword: false,
}; };
} }
componentDidUpdate(props) { componentDidUpdate(props) {
const { message } = this.props; const { message } = this.props;
if (message !== props.message) { if (message !== props.message) {
if (message.id === 'LOGIN_SUCCESS') { if (message.id === "LOGIN_SUCCESS") {
if (this.state.redirect) { if (this.state.redirect) {
this.props.history.push(this.state.redirect); this.props.history.push(this.state.redirect);
} } else {
else {
this.props.history.goBack(); this.props.history.goBack();
} }
} }
// Check for login error // Check for login error
else if (message.id === 'LOGIN_FAIL') { else if (message.id === "LOGIN_FAIL") {
this.setState({ email: '', password: '', snackbar: true, key: Date.now(), message: Blockly.Msg.messages_LOGIN_FAIL, type: 'error' }); this.setState({
email: "",
password: "",
snackbar: true,
key: Date.now(),
message: Blockly.Msg.messages_LOGIN_FAIL,
type: "error",
});
} }
} }
} }
onChange = e => { onChange = (e) => {
this.setState({ [e.target.name]: e.target.value }); this.setState({ [e.target.name]: e.target.value });
}; };
onSubmit = e => { onSubmit = (e) => {
e.preventDefault(); e.preventDefault();
const { email, password } = this.state; const { email, password } = this.state;
if (email !== '' && password !== '') { if (email !== "" && password !== "") {
// create user object // create user object
const user = { const user = {
email, email,
password password,
}; };
this.props.login(user); this.props.login(user);
} else { } else {
this.setState({ snackbar: true, key: Date.now(), message: Blockly.Msg.messages_login_error, type: 'error' }); this.setState({
snackbar: true,
key: Date.now(),
message: Blockly.Msg.messages_login_error,
type: "error",
});
} }
}; };
@ -85,12 +97,25 @@ export class Login extends Component {
render() { render() {
return ( return (
<div> <div>
<Breadcrumbs content={[{ link: '/user/login', title: Blockly.Msg.button_login }]} /> <Breadcrumbs
content={[{ link: "/user/login", title: Blockly.Msg.button_login }]}
/>
<div style={{ maxWidth: '500px', marginLeft: 'auto', marginRight: 'auto' }}> <div
style={{ maxWidth: "500px", marginLeft: "auto", marginRight: "auto" }}
>
<h1>{Blockly.Msg.login_head}</h1> <h1>{Blockly.Msg.login_head}</h1>
<Alert> <Alert>
{Blockly.Msg.login_osem_account_01} <Link color='primary' rel="noreferrer" target="_blank" href={'https://opensensemap.org/'}>openSenseMap</Link> {Blockly.Msg.login_osem_account_02}. {Blockly.Msg.login_osem_account_01}{" "}
<Link
color="primary"
rel="noreferrer"
target="_blank"
href={"https://opensensemap.org/"}
>
openSenseMap
</Link>{" "}
{Blockly.Msg.login_osem_account_02}.
</Alert> </Alert>
<Snackbar <Snackbar
open={this.state.snackbar} open={this.state.snackbar}
@ -99,51 +124,83 @@ export class Login extends Component {
key={this.state.key} key={this.state.key}
/> />
<TextField <TextField
style={{ marginBottom: '10px' }} style={{ marginBottom: "10px" }}
// variant='outlined' // variant='outlined'
type='text' type="text"
label={Blockly.Msg.labels_username} label={Blockly.Msg.labels_username}
name='email' name="email"
value={this.state.email} value={this.state.email}
onChange={this.onChange} onChange={this.onChange}
fullWidth={true} fullWidth={true}
/> />
<TextField <TextField
// variant='outlined' // variant='outlined'
type={this.state.showPassword ? 'text' : 'password'} type={this.state.showPassword ? "text" : "password"}
label={Blockly.Msg.labels_password} label={Blockly.Msg.labels_password}
name='password' name="password"
value={this.state.password} value={this.state.password}
InputProps={{ InputProps={{
endAdornment: endAdornment: (
<InputAdornment <InputAdornment position="end">
position="end"
>
<IconButton <IconButton
onClick={this.handleClickShowPassword} onClick={this.handleClickShowPassword}
onMouseDown={this.handleMouseDownPassword} onMouseDown={this.handleMouseDownPassword}
edge="end" edge="end"
> >
<FontAwesomeIcon size='xs' icon={this.state.showPassword ? faEyeSlash : faEye} /> <FontAwesomeIcon
size="xs"
icon={this.state.showPassword ? faEyeSlash : faEye}
/>
</IconButton> </IconButton>
</InputAdornment> </InputAdornment>
),
}} }}
onChange={this.onChange} onChange={this.onChange}
fullWidth={true} fullWidth={true}
/> />
<p> <p>
<Button color="primary" variant='contained' onClick={this.onSubmit} style={{ width: '100%' }}> <Button
{this.props.progress ? color="primary"
<div style={{ height: '24.5px' }}><CircularProgress color="inherit" size={20} /></div> variant="contained"
: Blockly.Msg.button_login} onClick={this.onSubmit}
style={{ width: "100%" }}
>
{this.props.progress ? (
<div style={{ height: "24.5px" }}>
<CircularProgress color="inherit" size={20} />
</div>
) : (
Blockly.Msg.button_login
)}
</Button> </Button>
</p> </p>
<p style={{ textAlign: 'center', fontSize: '0.8rem' }}> <p style={{ textAlign: "center", fontSize: "0.8rem" }}>
<Link rel="noreferrer" target="_blank" href={'https://opensensemap.org/'} color="primary">{Blockly.Msg.login_lostpassword}</Link> <Link
rel="noreferrer"
target="_blank"
href={"https://opensensemap.org/"}
color="primary"
>
{Blockly.Msg.login_lostpassword}
</Link>
</p> </p>
<Divider variant='fullWidth' /> <Divider variant="fullWidth" />
<p style={{ textAlign: 'center', paddingRight: "34px", paddingLeft: "34px" }}> <p
{Blockly.Msg.login_createaccount}<Link rel="noreferrer" target="_blank" href={'https://opensensemap.org/'}>openSenseMap</Link>. style={{
textAlign: "center",
paddingRight: "34px",
paddingLeft: "34px",
}}
>
{Blockly.Msg.login_createaccount}
<Link
rel="noreferrer"
target="_blank"
href={"https://opensensemap.org/"}
>
openSenseMap
</Link>
.
</p> </p>
</div> </div>
</div> </div>
@ -155,12 +212,14 @@ Login.propTypes = {
message: PropTypes.object.isRequired, message: PropTypes.object.isRequired,
login: PropTypes.func.isRequired, login: PropTypes.func.isRequired,
clearMessages: PropTypes.func.isRequired, clearMessages: PropTypes.func.isRequired,
progress: PropTypes.bool.isRequired progress: PropTypes.bool.isRequired,
}; };
const mapStateToProps = state => ({ const mapStateToProps = (state) => ({
message: state.message, message: state.message,
progress: state.auth.progress progress: state.auth.progress,
}); });
export default connect(mapStateToProps, { login, clearMessages })(withRouter(Login)); export default connect(mapStateToProps, { login, clearMessages })(
withRouter(Login)
);