esp8266-react-framework/interface/src/forms/ManageUsersForm.js

254 lines
7.9 KiB
JavaScript
Raw Normal View History

import React, { Fragment } from 'react';
2019-05-21 22:34:48 +00:00
import PropTypes from 'prop-types';
2019-05-25 08:45:49 +00:00
import { ValidatorForm } from 'react-material-ui-form-validator';
2019-05-21 22:34:48 +00:00
import { withStyles } from '@material-ui/core/styles';
import Button from '@material-ui/core/Button';
import LinearProgress from '@material-ui/core/LinearProgress';
import Typography from '@material-ui/core/Typography';
import Table from '@material-ui/core/Table';
import TableBody from '@material-ui/core/TableBody';
import TableCell from '@material-ui/core/TableCell';
import TableFooter from '@material-ui/core/TableFooter';
2019-05-21 22:34:48 +00:00
import TableHead from '@material-ui/core/TableHead';
import TableRow from '@material-ui/core/TableRow';
import Box from '@material-ui/core/Box';
2019-05-21 22:34:48 +00:00
import EditIcon from '@material-ui/icons/Edit';
import DeleteIcon from '@material-ui/icons/Delete';
2019-05-25 08:45:49 +00:00
import CloseIcon from '@material-ui/icons/Close';
import CheckIcon from '@material-ui/icons/Check';
import IconButton from '@material-ui/core/IconButton';
import SectionContent from '../components/SectionContent';
import UserForm from './UserForm';
2019-05-25 08:45:49 +00:00
import { withAuthenticationContext } from '../authentication/Context';
2019-05-21 22:34:48 +00:00
const styles = theme => ({
loadingSettings: {
margin: theme.spacing.unit,
},
loadingSettingsDetails: {
margin: theme.spacing.unit * 4,
textAlign: "center"
},
button: {
marginRight: theme.spacing.unit * 2,
marginTop: theme.spacing.unit * 2,
},
table: {
'& td, & th': { padding: theme.spacing.unit }
},
actions: {
2019-05-25 08:45:49 +00:00
whiteSpace: "nowrap"
}
2019-05-21 22:34:48 +00:00
});
function compareUsers(a, b) {
if (a.username < b.username) {
return -1;
}
if (a.username > b.username) {
return 1;
}
return 0;
}
2019-05-21 22:34:48 +00:00
class ManageUsersForm extends React.Component {
constructor(props) {
super(props);
this.state = {};
}
createUser = () => {
this.setState({
creating: true,
user: {
username: "",
password: "",
2019-05-25 08:45:49 +00:00
admin: true
}
});
};
uniqueUsername = username => {
return !this.props.userData.users.find(u => u.username === username);
}
2019-05-25 08:45:49 +00:00
noAdminConfigured = () => {
return !this.props.userData.users.find(u => u.admin);
}
removeUser = user => {
const { userData } = this.props;
const users = userData.users.filter(u => u.username !== user.username);
this.props.setData({ ...userData, users });
}
startEditingUser = user => {
this.setState({
creating: false,
user
});
};
cancelEditingUser = () => {
this.setState({
user: undefined
});
}
doneEditingUser = () => {
const { user } = this.state;
const { userData } = this.props;
const users = userData.users.filter(u => u.username !== user.username);
users.push(user);
this.props.setData({ ...userData, users });
this.setState({
user: undefined
});
};
handleUserValueChange = name => event => {
const { user } = this.state;
2019-05-25 08:45:49 +00:00
this.setState({
user: {
...user, [name]: event.target.value
}
});
};
2019-05-25 08:45:49 +00:00
handleUserCheckboxChange = name => event => {
const { user } = this.state;
this.setState({
user: {
...user, [name]: event.target.checked
}
});
}
onSubmit = () => {
this.props.onSubmit();
this.props.authenticationContext.refresh();
2019-05-25 08:45:49 +00:00
}
2019-05-21 22:34:48 +00:00
render() {
2019-05-25 08:45:49 +00:00
const { classes, userData, userDataFetched, errorMessage, onReset } = this.props;
const { user, creating } = this.state;
2019-05-21 22:34:48 +00:00
return (
<SectionContent title="Manage Users">
2019-05-21 22:34:48 +00:00
{
!userDataFetched ?
2019-05-21 22:34:48 +00:00
<div className={classes.loadingSettings}>
<LinearProgress className={classes.loadingSettingsDetails} />
<Typography variant="h4" className={classes.loadingSettingsDetails}>
Loading...
</Typography>
</div>
:
userData ?
<Fragment>
2019-05-25 08:45:49 +00:00
<ValidatorForm onSubmit={this.onSubmit}>
<Table className={classes.table}>
<TableHead>
<TableRow>
<TableCell>Username</TableCell>
2019-05-25 08:45:49 +00:00
<TableCell align="center">Admin?</TableCell>
2019-05-25 17:01:50 +00:00
<TableCell />
</TableRow>
</TableHead>
<TableBody>
2019-05-25 08:45:49 +00:00
{userData.users.sort(compareUsers).map(user => (
<TableRow key={user.username}>
<TableCell component="th" scope="row">
{user.username}
</TableCell>
<TableCell align="center">
{
2019-05-25 08:45:49 +00:00
user.admin ? <CheckIcon /> : <CloseIcon />
}
</TableCell>
<TableCell align="center">
<IconButton aria-label="Delete" onClick={() => this.removeUser(user)}>
<DeleteIcon />
</IconButton>
<IconButton aria-label="Edit" onClick={() => this.startEditingUser(user)}>
<EditIcon />
</IconButton>
</TableCell>
</TableRow>
))}
</TableBody>
<TableFooter>
<TableRow>
<TableCell colSpan={2} />
2019-05-21 22:34:48 +00:00
<TableCell align="center">
<Button variant="contained" color="secondary" className={classes.button} onClick={this.createUser}>
Add User
</Button>
2019-05-21 22:34:48 +00:00
</TableCell>
</TableRow>
</TableFooter>
</Table>
{
this.noAdminConfigured() &&
<Typography component="div" variant="body1">
<Box bgcolor="error.main" color="error.contrastText" p={2} m={1}>
You must have at least one admin user configured.
</Box>
</Typography>
}
2019-05-25 08:45:49 +00:00
<Button variant="contained" color="primary" className={classes.button} type="submit" disabled={this.noAdminConfigured()}>
Save
</Button>
<Button variant="contained" color="secondary" className={classes.button} onClick={onReset}>
Reset
</Button>
</ValidatorForm>
{
user &&
<UserForm
user={user}
creating={creating}
onDoneEditing={this.doneEditingUser}
onCancelEditing={this.cancelEditingUser}
handleValueChange={this.handleUserValueChange}
handleCheckboxChange={this.handleUserCheckboxChange}
uniqueUsername={this.uniqueUsername}
/>
}
</Fragment>
2019-05-21 22:34:48 +00:00
:
<SectionContent title="Manage Users">
2019-05-21 22:34:48 +00:00
<Typography variant="h4" className={classes.loadingSettingsDetails}>
{errorMessage}
</Typography>
<Button variant="contained" color="secondary" className={classes.button} onClick={onReset}>
Reset
</Button>
</SectionContent>
2019-05-21 22:34:48 +00:00
}
</SectionContent>
2019-05-21 22:34:48 +00:00
);
}
2019-05-21 22:34:48 +00:00
}
ManageUsersForm.propTypes = {
2019-05-26 15:19:16 +00:00
authenticationContext: PropTypes.object.isRequired,
2019-05-21 22:34:48 +00:00
classes: PropTypes.object.isRequired,
userData: PropTypes.object,
userDataFetched: PropTypes.bool.isRequired,
2019-05-21 22:34:48 +00:00
errorMessage: PropTypes.string,
onSubmit: PropTypes.func.isRequired,
onReset: PropTypes.func.isRequired,
setData: PropTypes.func.isRequired,
handleValueChange: PropTypes.func.isRequired
2019-05-21 22:34:48 +00:00
};
2019-05-25 08:45:49 +00:00
export default withAuthenticationContext(withStyles(styles)(ManageUsersForm));