Fork of the excellent esp8266-react - https://github.com/rjwats/esp8266-react
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

190 lines
5.8 KiB

  1. import React, { Fragment } from 'react';
  2. import { ValidatorForm } from 'react-material-ui-form-validator';
  3. import { Table, TableBody, TableCell, TableHead, TableFooter, TableRow } from '@material-ui/core';
  4. import { Box, Button, Typography, } from '@material-ui/core';
  5. import EditIcon from '@material-ui/icons/Edit';
  6. import DeleteIcon from '@material-ui/icons/Delete';
  7. import CloseIcon from '@material-ui/icons/Close';
  8. import CheckIcon from '@material-ui/icons/Check';
  9. import IconButton from '@material-ui/core/IconButton';
  10. import SaveIcon from '@material-ui/icons/Save';
  11. import PersonAddIcon from '@material-ui/icons/PersonAdd';
  12. import { withAuthenticatedContext, AuthenticatedContextProps } from '../authentication';
  13. import { RestFormProps, FormActions, FormButton } from '../components';
  14. import UserForm from './UserForm';
  15. import { SecuritySettings, User } from './types';
  16. function compareUsers(a: User, b: User) {
  17. if (a.username < b.username) {
  18. return -1;
  19. }
  20. if (a.username > b.username) {
  21. return 1;
  22. }
  23. return 0;
  24. }
  25. type ManageUsersFormProps = RestFormProps<SecuritySettings> & AuthenticatedContextProps;
  26. type ManageUsersFormState = {
  27. creating: boolean;
  28. user?: User;
  29. }
  30. class ManageUsersForm extends React.Component<ManageUsersFormProps, ManageUsersFormState> {
  31. state: ManageUsersFormState = {
  32. creating: false
  33. };
  34. createUser = () => {
  35. this.setState({
  36. creating: true,
  37. user: {
  38. username: "",
  39. password: "",
  40. admin: true
  41. }
  42. });
  43. };
  44. uniqueUsername = (username: string) => {
  45. return !this.props.data.users.find(u => u.username === username);
  46. }
  47. noAdminConfigured = () => {
  48. return !this.props.data.users.find(u => u.admin);
  49. }
  50. removeUser = (user: User) => {
  51. const { data } = this.props;
  52. const users = data.users.filter(u => u.username !== user.username);
  53. this.props.setData({ ...data, users });
  54. }
  55. startEditingUser = (user: User) => {
  56. this.setState({
  57. creating: false,
  58. user
  59. });
  60. };
  61. cancelEditingUser = () => {
  62. this.setState({
  63. user: undefined
  64. });
  65. }
  66. doneEditingUser = () => {
  67. const { user } = this.state;
  68. if (user) {
  69. const { data } = this.props;
  70. const users = data.users.filter(u => u.username !== user.username);
  71. users.push(user);
  72. this.props.setData({ ...data, users });
  73. this.setState({
  74. user: undefined
  75. });
  76. }
  77. };
  78. handleUserValueChange = (name: keyof User) => (event: React.ChangeEvent<HTMLInputElement>) => {
  79. this.setState({ user: { ...this.state.user!, [name]: event.target.value } });
  80. };
  81. handleUserCheckboxChange = (name: keyof User) => (event: React.ChangeEvent<HTMLInputElement>) => {
  82. this.setState({ user: { ...this.state.user!, [name]: event.target.checked } });
  83. }
  84. onSubmit = () => {
  85. this.props.saveData();
  86. this.props.authenticatedContext.refresh();
  87. }
  88. render() {
  89. const { data, loadData } = this.props;
  90. const { user, creating } = this.state;
  91. return (
  92. <Fragment>
  93. <ValidatorForm onSubmit={this.onSubmit}>
  94. <Table size="small">
  95. <TableHead>
  96. <TableRow>
  97. <TableCell>Username</TableCell>
  98. <TableCell align="center">Admin?</TableCell>
  99. <TableCell />
  100. </TableRow>
  101. </TableHead>
  102. <TableBody>
  103. {data.users.sort(compareUsers).map(user => (
  104. <TableRow key={user.username}>
  105. <TableCell component="th" scope="row">
  106. {user.username}
  107. </TableCell>
  108. <TableCell align="center">
  109. {
  110. user.admin ? <CheckIcon /> : <CloseIcon />
  111. }
  112. </TableCell>
  113. <TableCell align="center">
  114. <IconButton size="small" aria-label="Delete" onClick={() => this.removeUser(user)}>
  115. <DeleteIcon />
  116. </IconButton>
  117. <IconButton size="small" aria-label="Edit" onClick={() => this.startEditingUser(user)}>
  118. <EditIcon />
  119. </IconButton>
  120. </TableCell>
  121. </TableRow>
  122. ))}
  123. </TableBody>
  124. <TableFooter>
  125. <TableRow>
  126. <TableCell colSpan={2} />
  127. <TableCell align="center">
  128. <Button startIcon={<PersonAddIcon />} variant="contained" color="secondary" onClick={this.createUser}>
  129. Add User
  130. </Button>
  131. </TableCell>
  132. </TableRow>
  133. </TableFooter>
  134. </Table>
  135. {
  136. this.noAdminConfigured() &&
  137. <Typography component="div" variant="body1">
  138. <Box bgcolor="error.main" color="error.contrastText" p={2} mt={2} mb={2}>
  139. You must have at least one admin user configured.
  140. </Box>
  141. </Typography>
  142. }
  143. <FormActions>
  144. <FormButton startIcon={<SaveIcon />} variant="contained" color="primary" type="submit" disabled={this.noAdminConfigured()}>
  145. Save
  146. </FormButton>
  147. <FormButton variant="contained" color="secondary" onClick={loadData}>
  148. Reset
  149. </FormButton>
  150. </FormActions>
  151. </ValidatorForm>
  152. {
  153. user &&
  154. <UserForm
  155. user={user}
  156. creating={creating}
  157. onDoneEditing={this.doneEditingUser}
  158. onCancelEditing={this.cancelEditingUser}
  159. handleValueChange={this.handleUserValueChange}
  160. handleCheckboxChange={this.handleUserCheckboxChange}
  161. uniqueUsername={this.uniqueUsername}
  162. />
  163. }
  164. </Fragment>
  165. );
  166. }
  167. }
  168. export default withAuthenticatedContext(ManageUsersForm);