WIP - User Management Interface

This commit is contained in:
Rick Watson 2019-05-21 23:34:48 +01:00
parent 5c6ba73e1f
commit 096dc55604
6 changed files with 195 additions and 0 deletions

View File

@ -14,6 +14,7 @@ import NTPConfiguration from './containers/NTPConfiguration';
import OTAConfiguration from './containers/OTAConfiguration';
import APConfiguration from './containers/APConfiguration';
import SignInPage from './containers/SignInPage';
import UserConfiguration from './containers/UserConfiguration';
class AppRouting extends Component {
@ -30,6 +31,7 @@ class AppRouting extends Component {
<AuthenticatedRoute exact path="/ap-configuration" component={APConfiguration} />
<AuthenticatedRoute exact path="/ntp-configuration" component={NTPConfiguration} />
<AuthenticatedRoute exact path="/ota-configuration" component={OTAConfiguration} />
<AuthenticatedRoute exact path="/user-configuration" component={UserConfiguration} />
<Redirect to="/" />
</Switch>
</AuthenticationWrapper>

View File

@ -22,6 +22,7 @@ import SystemUpdateIcon from '@material-ui/icons/SystemUpdate';
import AccessTimeIcon from '@material-ui/icons/AccessTime';
import AccountCircleIcon from '@material-ui/icons/AccountCircle';
import SettingsInputAntennaIcon from '@material-ui/icons/SettingsInputAntenna';
import PeopleIcon from '@material-ui/icons/People';
import { APP_NAME } from '../constants/App';
import { withAuthenticationContext } from '../authentication/Context.js';
@ -131,6 +132,12 @@ class MenuAppBar extends React.Component {
</ListItemIcon>
<ListItemText primary="OTA Configuration" />
</ListItem>
<ListItem button component={Link} to='/user-configuration'>
<ListItemIcon>
<PeopleIcon />
</ListItemIcon>
<ListItemText primary="User Configuration" />
</ListItem>
<Divider />
<ListItem button onClick={authenticationContext.signOut}>
<ListItemIcon>

View File

@ -11,3 +11,4 @@ export const WIFI_STATUS_ENDPOINT = ENDPOINT_ROOT + "wifiStatus";
export const OTA_SETTINGS_ENDPOINT = ENDPOINT_ROOT + "otaSettings";
export const SIGN_IN_ENDPOINT = ENDPOINT_ROOT + "signIn";
export const VERIFY_AUTHORIZATION_ENDPOINT = ENDPOINT_ROOT + "verifyAuthorization";
export const USERS_ENDPOINT = ENDPOINT_ROOT + "users";

View File

@ -0,0 +1,33 @@
import React, { Component } from 'react';
import { USERS_ENDPOINT } from '../constants/Endpoints';
import {restComponent} from '../components/RestComponent';
import SectionContent from '../components/SectionContent';
import ManageUsersForm from '../forms/ManageUsersForm';
class ManageUsers extends Component {
componentDidMount() {
this.props.loadData();
}
render() {
const { data, fetched, errorMessage } = this.props;
return (
<SectionContent title="Manage Users">
<ManageUsersForm
users={data}
usersFetched={fetched}
errorMessage={errorMessage}
onSubmit={this.props.saveData}
onReset={this.props.loadData}
handleValueChange={this.props.handleValueChange}
handleCheckboxChange={this.props.handleCheckboxChange}
/>
</SectionContent>
)
}
}
export default restComponent(USERS_ENDPOINT, ManageUsers);

View File

@ -0,0 +1,15 @@
import React, { Component } from 'react';
import MenuAppBar from '../components/MenuAppBar';
import ManageUsers from './ManageUsers';
class UserConfiguration extends Component {
render() {
return (
<MenuAppBar sectionTitle="User Configuration">
<ManageUsers />
</MenuAppBar>
)
}
}
export default UserConfiguration

View File

@ -0,0 +1,137 @@
import React from 'react';
import PropTypes from 'prop-types';
import { ValidatorForm } from 'react-material-ui-form-validator';
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 TableHead from '@material-ui/core/TableHead';
import TableRow from '@material-ui/core/TableRow';
import IconButton from '@material-ui/core/IconButton';
import EditIcon from '@material-ui/icons/Edit';
import DeleteIcon from '@material-ui/icons/Delete';
import Chip from '@material-ui/core/Chip';
const styles = theme => ({
loadingSettings: {
margin: theme.spacing.unit,
},
loadingSettingsDetails: {
margin: theme.spacing.unit * 4,
textAlign: "center"
},
switchControl: {
width: "100%",
marginTop: theme.spacing.unit * 2,
marginBottom: theme.spacing.unit
},
textField: {
width: "100%"
},
button: {
marginRight: theme.spacing.unit * 2,
marginTop: theme.spacing.unit * 2,
},
chip: {
margin: theme.spacing.unit,
},
table: {
'& td, & th': {padding: theme.spacing.unit}
}
});
class ManageUsersForm extends React.Component {
render() {
const { classes, users, usersFetched, errorMessage, onSubmit, onReset } = this.props;
return (
<div>
{
!usersFetched ?
<div className={classes.loadingSettings}>
<LinearProgress className={classes.loadingSettingsDetails} />
<Typography variant="h4" className={classes.loadingSettingsDetails}>
Loading...
</Typography>
</div>
: users ?
<ValidatorForm onSubmit={onSubmit}>
<Table className={classes.table}>
<TableHead>
<TableRow>
<TableCell>Username</TableCell>
<TableCell>Password</TableCell>
<TableCell align="center">Role(s)</TableCell>
<TableCell align="center">Action</TableCell>
</TableRow>
</TableHead>
<TableBody>
{users.users.map(user => (
<TableRow key={user.username}>
<TableCell component="th" scope="row">
{user.username}
</TableCell>
<TableCell>{user.password}</TableCell>
<TableCell align="center">
<Chip label={user.role} className={classes.chip} />
</TableCell>
<TableCell align="center">
<IconButton aria-label="Delete">
<DeleteIcon />
</IconButton>
<IconButton aria-label="Edit">
<EditIcon />
</IconButton>
</TableCell>
</TableRow>
))}
</TableBody>
</Table>
<Button variant="contained" color="primary" className={classes.button} type="submit">
Save
</Button>
<Button variant="contained" color="secondary" className={classes.button} onClick={onReset}>
Reset
</Button>
</ValidatorForm>
:
<div className={classes.loadingSettings}>
<Typography variant="h4" className={classes.loadingSettingsDetails}>
{errorMessage}
</Typography>
<Button variant="contained" color="secondary" className={classes.button} onClick={onReset}>
Reset
</Button>
</div>
}
</div>
);
}
}
ManageUsersForm.propTypes = {
classes: PropTypes.object.isRequired,
users: PropTypes.object,
usersFetched: PropTypes.bool.isRequired,
errorMessage: PropTypes.string,
onSubmit: PropTypes.func.isRequired,
onReset: PropTypes.func.isRequired,
handleValueChange: PropTypes.func.isRequired,
handleCheckboxChange: PropTypes.func.isRequired,
};
export default withStyles(styles)(ManageUsersForm);