reduce use of ternaries in form code
This commit is contained in:
parent
df06e58fb0
commit
ff85c2e661
@ -52,10 +52,11 @@ export const restComponent = (endpointUrl, FormComponent) => {
|
|||||||
})
|
})
|
||||||
.then(json => { this.setState({ data: json, fetched: true }) })
|
.then(json => { this.setState({ data: json, fetched: true }) })
|
||||||
.catch(error => {
|
.catch(error => {
|
||||||
this.props.enqueueSnackbar("Problem fetching: " + error.message, {
|
const errorMessage = error.message || "Unknown error";
|
||||||
|
this.props.enqueueSnackbar("Problem fetching: " + errorMessage, {
|
||||||
variant: 'error',
|
variant: 'error',
|
||||||
});
|
});
|
||||||
this.setState({ data: null, fetched: true, errorMessage: error.message });
|
this.setState({ data: null, fetched: true, errorMessage });
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -80,10 +81,11 @@ export const restComponent = (endpointUrl, FormComponent) => {
|
|||||||
});
|
});
|
||||||
this.setState({ data: json, fetched: true });
|
this.setState({ data: json, fetched: true });
|
||||||
}).catch(error => {
|
}).catch(error => {
|
||||||
this.props.enqueueSnackbar("Problem saving: " + error.message, {
|
const errorMessage = error.message || "Unknown error";
|
||||||
|
this.props.enqueueSnackbar("Problem saving: " + errorMessage, {
|
||||||
variant: 'error',
|
variant: 'error',
|
||||||
});
|
});
|
||||||
this.setState({ data: null, fetched: true, errorMessage: error.message });
|
this.setState({ data: null, fetched: true, errorMessage });
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,7 +1,8 @@
|
|||||||
import React, { Component } from 'react';
|
import React, { Component } from 'react';
|
||||||
|
|
||||||
import { AP_SETTINGS_ENDPOINT } from '../constants/Endpoints';
|
import { AP_SETTINGS_ENDPOINT } from '../constants/Endpoints';
|
||||||
import { restComponent } from '../components/RestComponent';
|
import { restComponent } from '../components/RestComponent';
|
||||||
|
import LoadingNotification from '../components/LoadingNotification';
|
||||||
import SectionContent from '../components/SectionContent';
|
import SectionContent from '../components/SectionContent';
|
||||||
import APSettingsForm from '../forms/APSettingsForm';
|
import APSettingsForm from '../forms/APSettingsForm';
|
||||||
|
|
||||||
@ -12,17 +13,20 @@ class APSettings extends Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const { data, fetched, errorMessage } = this.props;
|
const { fetched, errorMessage, data, saveData, loadData, handleValueChange } = this.props;
|
||||||
return (
|
return (
|
||||||
<SectionContent title="AP Settings">
|
<SectionContent title="AP Settings">
|
||||||
<APSettingsForm
|
<LoadingNotification
|
||||||
apSettings={data}
|
onReset={loadData}
|
||||||
apSettingsFetched={fetched}
|
fetched={fetched}
|
||||||
errorMessage={errorMessage}
|
errorMessage={errorMessage}>
|
||||||
onSubmit={this.props.saveData}
|
<APSettingsForm
|
||||||
onReset={this.props.loadData}
|
apSettings={data}
|
||||||
handleValueChange={this.props.handleValueChange}
|
onSubmit={saveData}
|
||||||
/>
|
onReset={loadData}
|
||||||
|
handleValueChange={handleValueChange}
|
||||||
|
/>
|
||||||
|
</LoadingNotification>
|
||||||
</SectionContent>
|
</SectionContent>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -2,8 +2,6 @@ import React, { Component, Fragment } from 'react';
|
|||||||
|
|
||||||
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 LinearProgress from '@material-ui/core/LinearProgress';
|
|
||||||
import Typography from '@material-ui/core/Typography';
|
|
||||||
import List from '@material-ui/core/List';
|
import List from '@material-ui/core/List';
|
||||||
import ListItem from '@material-ui/core/ListItem';
|
import ListItem from '@material-ui/core/ListItem';
|
||||||
import ListItemText from '@material-ui/core/ListItemText';
|
import ListItemText from '@material-ui/core/ListItemText';
|
||||||
@ -15,6 +13,7 @@ import DeviceHubIcon from '@material-ui/icons/DeviceHub';
|
|||||||
import ComputerIcon from '@material-ui/icons/Computer';
|
import ComputerIcon from '@material-ui/icons/Computer';
|
||||||
|
|
||||||
import { restComponent } from '../components/RestComponent';
|
import { restComponent } from '../components/RestComponent';
|
||||||
|
import LoadingNotification from '../components/LoadingNotification';
|
||||||
import SectionContent from '../components/SectionContent'
|
import SectionContent from '../components/SectionContent'
|
||||||
|
|
||||||
import * as Highlight from '../constants/Highlight';
|
import * as Highlight from '../constants/Highlight';
|
||||||
@ -27,10 +26,6 @@ const styles = theme => ({
|
|||||||
["apStatus_" + Highlight.IDLE]: {
|
["apStatus_" + Highlight.IDLE]: {
|
||||||
backgroundColor: theme.palette.highlight_idle
|
backgroundColor: theme.palette.highlight_idle
|
||||||
},
|
},
|
||||||
fetching: {
|
|
||||||
margin: theme.spacing(4),
|
|
||||||
textAlign: "center"
|
|
||||||
},
|
|
||||||
button: {
|
button: {
|
||||||
marginRight: theme.spacing(2),
|
marginRight: theme.spacing(2),
|
||||||
marginTop: theme.spacing(2),
|
marginTop: theme.spacing(2),
|
||||||
@ -106,30 +101,15 @@ class APStatus extends Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const { data, fetched, errorMessage, classes } = this.props;
|
const { fetched, errorMessage, data, loadData, classes } = this.props;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<SectionContent title="AP Status">
|
<SectionContent title="AP Status">
|
||||||
{
|
<LoadingNotification
|
||||||
!fetched ?
|
onReset={loadData}
|
||||||
<div>
|
fetched={fetched}
|
||||||
<LinearProgress className={classes.fetching} />
|
errorMessage={errorMessage}>
|
||||||
<Typography variant="h4" className={classes.fetching}>
|
{this.renderAPStatus(data, classes)}
|
||||||
Loading...
|
</LoadingNotification>
|
||||||
</Typography>
|
|
||||||
</div>
|
|
||||||
:
|
|
||||||
data ? this.renderAPStatus(data, classes)
|
|
||||||
:
|
|
||||||
<div>
|
|
||||||
<Typography variant="h4" className={classes.fetching}>
|
|
||||||
{errorMessage}
|
|
||||||
</Typography>
|
|
||||||
<Button variant="contained" color="secondary" className={classes.button} onClick={this.props.loadData}>
|
|
||||||
Refresh
|
|
||||||
</Button>
|
|
||||||
</div>
|
|
||||||
}
|
|
||||||
</SectionContent>
|
</SectionContent>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -2,8 +2,9 @@ import React, { Component } from 'react';
|
|||||||
|
|
||||||
import { SECURITY_SETTINGS_ENDPOINT } from '../constants/Endpoints';
|
import { SECURITY_SETTINGS_ENDPOINT } from '../constants/Endpoints';
|
||||||
import { restComponent } from '../components/RestComponent';
|
import { restComponent } from '../components/RestComponent';
|
||||||
import ManageUsersForm from '../forms/ManageUsersForm';
|
import LoadingNotification from '../components/LoadingNotification';
|
||||||
import SectionContent from '../components/SectionContent';
|
import SectionContent from '../components/SectionContent';
|
||||||
|
import ManageUsersForm from '../forms/ManageUsersForm';
|
||||||
|
|
||||||
class ManageUsers extends Component {
|
class ManageUsers extends Component {
|
||||||
|
|
||||||
@ -12,18 +13,21 @@ class ManageUsers extends Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const { data, fetched, errorMessage } = this.props;
|
const { fetched, errorMessage, data, saveData, loadData, setData, handleValueChange } = this.props;
|
||||||
return (
|
return (
|
||||||
<SectionContent title="Manage Users" titleGutter>
|
<SectionContent title="Manage Users" titleGutter>
|
||||||
<ManageUsersForm
|
<LoadingNotification
|
||||||
userData={data}
|
onReset={loadData}
|
||||||
userDataFetched={fetched}
|
fetched={fetched}
|
||||||
errorMessage={errorMessage}
|
errorMessage={errorMessage}>
|
||||||
onSubmit={this.props.saveData}
|
<ManageUsersForm
|
||||||
onReset={this.props.loadData}
|
userData={data}
|
||||||
setData={this.props.setData}
|
onSubmit={saveData}
|
||||||
handleValueChange={this.props.handleValueChange}
|
onReset={loadData}
|
||||||
/>
|
setData={setData}
|
||||||
|
handleValueChange={handleValueChange}
|
||||||
|
/>
|
||||||
|
</LoadingNotification>
|
||||||
</SectionContent>
|
</SectionContent>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -1,28 +1,32 @@
|
|||||||
import React, { Component } from 'react';
|
import React, { Component } from 'react';
|
||||||
|
|
||||||
import { NTP_SETTINGS_ENDPOINT } from '../constants/Endpoints';
|
import { NTP_SETTINGS_ENDPOINT } from '../constants/Endpoints';
|
||||||
import {restComponent} from '../components/RestComponent';
|
import { restComponent } from '../components/RestComponent';
|
||||||
|
import LoadingNotification from '../components/LoadingNotification';
|
||||||
import SectionContent from '../components/SectionContent';
|
import SectionContent from '../components/SectionContent';
|
||||||
import NTPSettingsForm from '../forms/NTPSettingsForm';
|
import NTPSettingsForm from '../forms/NTPSettingsForm';
|
||||||
|
|
||||||
class NTPSettings extends Component {
|
class NTPSettings extends Component {
|
||||||
|
|
||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
this.props.loadData();
|
this.props.loadData();
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const { data, fetched, errorMessage } = this.props;
|
const { fetched, errorMessage, data, saveData, loadData, handleValueChange } = this.props;
|
||||||
return (
|
return (
|
||||||
<SectionContent title="NTP Settings">
|
<SectionContent title="NTP Settings">
|
||||||
<NTPSettingsForm
|
<LoadingNotification
|
||||||
ntpSettings={data}
|
onReset={loadData}
|
||||||
ntpSettingsFetched={fetched}
|
fetched={fetched}
|
||||||
errorMessage={errorMessage}
|
errorMessage={errorMessage}>
|
||||||
onSubmit={this.props.saveData}
|
<NTPSettingsForm
|
||||||
onReset={this.props.loadData}
|
ntpSettings={data}
|
||||||
handleValueChange={this.props.handleValueChange}
|
onSubmit={saveData}
|
||||||
/>
|
onReset={loadData}
|
||||||
|
handleValueChange={handleValueChange}
|
||||||
|
/>
|
||||||
|
</LoadingNotification>
|
||||||
</SectionContent>
|
</SectionContent>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -2,8 +2,6 @@ import React, { Component, Fragment } from 'react';
|
|||||||
|
|
||||||
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 LinearProgress from '@material-ui/core/LinearProgress';
|
|
||||||
import Typography from '@material-ui/core/Typography';
|
|
||||||
import List from '@material-ui/core/List';
|
import List from '@material-ui/core/List';
|
||||||
import ListItem from '@material-ui/core/ListItem';
|
import ListItem from '@material-ui/core/ListItem';
|
||||||
import ListItemAvatar from '@material-ui/core/ListItemAvatar';
|
import ListItemAvatar from '@material-ui/core/ListItemAvatar';
|
||||||
@ -22,6 +20,7 @@ import * as Highlight from '../constants/Highlight';
|
|||||||
import { unixTimeToTimeAndDate } from '../constants/TimeFormat';
|
import { unixTimeToTimeAndDate } from '../constants/TimeFormat';
|
||||||
import { NTP_STATUS_ENDPOINT } from '../constants/Endpoints';
|
import { NTP_STATUS_ENDPOINT } from '../constants/Endpoints';
|
||||||
import { restComponent } from '../components/RestComponent';
|
import { restComponent } from '../components/RestComponent';
|
||||||
|
import LoadingNotification from '../components/LoadingNotification';
|
||||||
import SectionContent from '../components/SectionContent';
|
import SectionContent from '../components/SectionContent';
|
||||||
|
|
||||||
import moment from 'moment';
|
import moment from 'moment';
|
||||||
@ -36,10 +35,6 @@ const styles = theme => ({
|
|||||||
["ntpStatus_" + Highlight.WARN]: {
|
["ntpStatus_" + Highlight.WARN]: {
|
||||||
backgroundColor: theme.palette.highlight_warn
|
backgroundColor: theme.palette.highlight_warn
|
||||||
},
|
},
|
||||||
fetching: {
|
|
||||||
margin: theme.spacing(4),
|
|
||||||
textAlign: "center"
|
|
||||||
},
|
|
||||||
button: {
|
button: {
|
||||||
marginRight: theme.spacing(2),
|
marginRight: theme.spacing(2),
|
||||||
marginTop: theme.spacing(2),
|
marginTop: theme.spacing(2),
|
||||||
@ -131,32 +126,17 @@ class NTPStatus extends Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const { data, fetched, errorMessage, classes } = this.props;
|
const { data, fetched, errorMessage, loadData, classes } = this.props;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<SectionContent title="NTP Status">
|
<SectionContent title="NTP Status">
|
||||||
{
|
<LoadingNotification
|
||||||
!fetched ?
|
onReset={loadData}
|
||||||
<div>
|
fetched={fetched}
|
||||||
<LinearProgress className={classes.fetching} />
|
errorMessage={errorMessage}>
|
||||||
<Typography variant="h4" className={classes.fetching}>
|
{this.renderNTPStatus(data, classes)}
|
||||||
Loading...
|
</LoadingNotification>
|
||||||
</Typography>
|
|
||||||
</div>
|
|
||||||
:
|
|
||||||
data ? this.renderNTPStatus(data, classes)
|
|
||||||
:
|
|
||||||
<div>
|
|
||||||
<Typography variant="h4" className={classes.fetching}>
|
|
||||||
{errorMessage}
|
|
||||||
</Typography>
|
|
||||||
<Button variant="contained" color="secondary" className={classes.button} onClick={this.props.loadData}>
|
|
||||||
Refresh
|
|
||||||
</Button>
|
|
||||||
</div>
|
|
||||||
}
|
|
||||||
</SectionContent>
|
</SectionContent>
|
||||||
)
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,29 +1,33 @@
|
|||||||
import React, { Component } from 'react';
|
import React, { Component } from 'react';
|
||||||
|
|
||||||
import { OTA_SETTINGS_ENDPOINT } from '../constants/Endpoints';
|
import { OTA_SETTINGS_ENDPOINT } from '../constants/Endpoints';
|
||||||
import {restComponent} from '../components/RestComponent';
|
import { restComponent } from '../components/RestComponent';
|
||||||
|
import LoadingNotification from '../components/LoadingNotification';
|
||||||
import SectionContent from '../components/SectionContent';
|
import SectionContent from '../components/SectionContent';
|
||||||
import OTASettingsForm from '../forms/OTASettingsForm';
|
import OTASettingsForm from '../forms/OTASettingsForm';
|
||||||
|
|
||||||
class OTASettings extends Component {
|
class OTASettings extends Component {
|
||||||
|
|
||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
this.props.loadData();
|
this.props.loadData();
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const { data, fetched, errorMessage } = this.props;
|
const { fetched, errorMessage, data, saveData, loadData, handleValueChange, handleCheckboxChange } = this.props;
|
||||||
return (
|
return (
|
||||||
<SectionContent title="OTA Settings">
|
<SectionContent title="OTA Settings">
|
||||||
<OTASettingsForm
|
<LoadingNotification
|
||||||
otaSettings={data}
|
onReset={loadData}
|
||||||
otaSettingsFetched={fetched}
|
fetched={fetched}
|
||||||
errorMessage={errorMessage}
|
errorMessage={errorMessage}>
|
||||||
onSubmit={this.props.saveData}
|
<OTASettingsForm
|
||||||
onReset={this.props.loadData}
|
otaSettings={data}
|
||||||
handleValueChange={this.props.handleValueChange}
|
onSubmit={saveData}
|
||||||
handleCheckboxChange={this.props.handleCheckboxChange}
|
onReset={loadData}
|
||||||
/>
|
handleValueChange={handleValueChange}
|
||||||
|
handleCheckboxChange={handleCheckboxChange}
|
||||||
|
/>
|
||||||
|
</LoadingNotification>
|
||||||
</SectionContent>
|
</SectionContent>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -2,6 +2,7 @@ import React, { Component } from 'react';
|
|||||||
|
|
||||||
import { SECURITY_SETTINGS_ENDPOINT } from '../constants/Endpoints';
|
import { SECURITY_SETTINGS_ENDPOINT } from '../constants/Endpoints';
|
||||||
import { restComponent } from '../components/RestComponent';
|
import { restComponent } from '../components/RestComponent';
|
||||||
|
import LoadingNotification from '../components/LoadingNotification';
|
||||||
import SecuritySettingsForm from '../forms/SecuritySettingsForm';
|
import SecuritySettingsForm from '../forms/SecuritySettingsForm';
|
||||||
import SectionContent from '../components/SectionContent';
|
import SectionContent from '../components/SectionContent';
|
||||||
|
|
||||||
@ -15,14 +16,17 @@ class SecuritySettings extends Component {
|
|||||||
const { data, fetched, errorMessage, saveData, loadData, handleValueChange } = this.props;
|
const { data, fetched, errorMessage, saveData, loadData, handleValueChange } = this.props;
|
||||||
return (
|
return (
|
||||||
<SectionContent title="Security Settings">
|
<SectionContent title="Security Settings">
|
||||||
<SecuritySettingsForm
|
<LoadingNotification
|
||||||
securitySettings={data}
|
|
||||||
securitySettingsFetched={fetched}
|
|
||||||
errorMessage={errorMessage}
|
|
||||||
onSubmit={saveData}
|
|
||||||
onReset={loadData}
|
onReset={loadData}
|
||||||
handleValueChange={handleValueChange}
|
fetched={fetched}
|
||||||
/>
|
errorMessage={errorMessage}>
|
||||||
|
<SecuritySettingsForm
|
||||||
|
securitySettings={data}
|
||||||
|
onSubmit={saveData}
|
||||||
|
onReset={loadData}
|
||||||
|
handleValueChange={handleValueChange}
|
||||||
|
/>
|
||||||
|
</LoadingNotification>
|
||||||
</SectionContent>
|
</SectionContent>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -2,8 +2,6 @@ import React, { Component, Fragment } from 'react';
|
|||||||
|
|
||||||
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 LinearProgress from '@material-ui/core/LinearProgress';
|
|
||||||
import Typography from '@material-ui/core/Typography';
|
|
||||||
import List from '@material-ui/core/List';
|
import List from '@material-ui/core/List';
|
||||||
import ListItem from '@material-ui/core/ListItem';
|
import ListItem from '@material-ui/core/ListItem';
|
||||||
import ListItemAvatar from '@material-ui/core/ListItemAvatar';
|
import ListItemAvatar from '@material-ui/core/ListItemAvatar';
|
||||||
@ -16,16 +14,12 @@ import ShowChartIcon from '@material-ui/icons/ShowChart';
|
|||||||
import SdStorageIcon from '@material-ui/icons/SdStorage';
|
import SdStorageIcon from '@material-ui/icons/SdStorage';
|
||||||
import DataUsageIcon from '@material-ui/icons/DataUsage';
|
import DataUsageIcon from '@material-ui/icons/DataUsage';
|
||||||
|
|
||||||
|
|
||||||
import { SYSTEM_STATUS_ENDPOINT } from '../constants/Endpoints';
|
import { SYSTEM_STATUS_ENDPOINT } from '../constants/Endpoints';
|
||||||
import { restComponent } from '../components/RestComponent';
|
import { restComponent } from '../components/RestComponent';
|
||||||
|
import LoadingNotification from '../components/LoadingNotification';
|
||||||
import SectionContent from '../components/SectionContent';
|
import SectionContent from '../components/SectionContent';
|
||||||
|
|
||||||
const styles = theme => ({
|
const styles = theme => ({
|
||||||
fetching: {
|
|
||||||
margin: theme.spacing(4),
|
|
||||||
textAlign: "center"
|
|
||||||
},
|
|
||||||
button: {
|
button: {
|
||||||
marginRight: theme.spacing(2),
|
marginRight: theme.spacing(2),
|
||||||
marginTop: theme.spacing(2),
|
marginTop: theme.spacing(2),
|
||||||
@ -85,7 +79,7 @@ class SystemStatus extends Component {
|
|||||||
</ListItemAvatar>
|
</ListItemAvatar>
|
||||||
<ListItemText primary="Flash Chip Size" secondary={data.flash_chip_size + ' bytes'} />
|
<ListItemText primary="Flash Chip Size" secondary={data.flash_chip_size + ' bytes'} />
|
||||||
</ListItem>
|
</ListItem>
|
||||||
<Divider variant="inset" component="li" />
|
<Divider variant="inset" component="li" />
|
||||||
</Fragment>
|
</Fragment>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -104,29 +98,15 @@ class SystemStatus extends Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const { data, fetched, errorMessage, classes } = this.props;
|
const { data, fetched, errorMessage, loadData, classes } = this.props;
|
||||||
return (
|
return (
|
||||||
<SectionContent title="System Status">
|
<SectionContent title="System Status">
|
||||||
{
|
<LoadingNotification
|
||||||
!fetched ?
|
onReset={loadData}
|
||||||
<div>
|
fetched={fetched}
|
||||||
<LinearProgress className={classes.fetching} />
|
errorMessage={errorMessage}>
|
||||||
<Typography variant="h4" className={classes.fetching}>
|
{this.renderNTPStatus(data, classes)}
|
||||||
Loading...
|
</LoadingNotification>
|
||||||
</Typography>
|
|
||||||
</div>
|
|
||||||
:
|
|
||||||
data ? this.renderNTPStatus(data, classes)
|
|
||||||
:
|
|
||||||
<div>
|
|
||||||
<Typography variant="h4" className={classes.fetching}>
|
|
||||||
{errorMessage}
|
|
||||||
</Typography>
|
|
||||||
<Button variant="contained" color="secondary" className={classes.button} onClick={this.props.loadData}>
|
|
||||||
Refresh
|
|
||||||
</Button>
|
|
||||||
</div>
|
|
||||||
}
|
|
||||||
</SectionContent>
|
</SectionContent>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
import React, { Component } from 'react';
|
import React, { Component } from 'react';
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
|
import { withSnackbar } from 'notistack';
|
||||||
|
|
||||||
import { SCAN_NETWORKS_ENDPOINT, LIST_NETWORKS_ENDPOINT } from '../constants/Endpoints';
|
import { SCAN_NETWORKS_ENDPOINT, LIST_NETWORKS_ENDPOINT } from '../constants/Endpoints';
|
||||||
import SectionContent from '../components/SectionContent';
|
import SectionContent from '../components/SectionContent';
|
||||||
import WiFiNetworkSelector from '../forms/WiFiNetworkSelector';
|
import WiFiNetworkSelector from '../forms/WiFiNetworkSelector';
|
||||||
import { withSnackbar } from 'notistack';
|
|
||||||
import { redirectingAuthorizedFetch } from '../authentication/Authentication';
|
import { redirectingAuthorizedFetch } from '../authentication/Authentication';
|
||||||
|
|
||||||
const NUM_POLLS = 10
|
const NUM_POLLS = 10
|
||||||
|
@ -1,8 +1,9 @@
|
|||||||
import React, { Component } from 'react';
|
import React, { Component } from 'react';
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
|
|
||||||
import { WIFI_SETTINGS_ENDPOINT } from '../constants/Endpoints';
|
import { WIFI_SETTINGS_ENDPOINT } from '../constants/Endpoints';
|
||||||
import { restComponent } from '../components/RestComponent';
|
import { restComponent } from '../components/RestComponent';
|
||||||
|
import LoadingNotification from '../components/LoadingNotification';
|
||||||
import SectionContent from '../components/SectionContent';
|
import SectionContent from '../components/SectionContent';
|
||||||
import WiFiSettingsForm from '../forms/WiFiSettingsForm';
|
import WiFiSettingsForm from '../forms/WiFiSettingsForm';
|
||||||
|
|
||||||
@ -18,10 +19,10 @@ class WiFiSettings extends Component {
|
|||||||
const { selectedNetwork } = this.props;
|
const { selectedNetwork } = this.props;
|
||||||
if (selectedNetwork) {
|
if (selectedNetwork) {
|
||||||
var wifiSettings = {
|
var wifiSettings = {
|
||||||
ssid:selectedNetwork.ssid,
|
ssid: selectedNetwork.ssid,
|
||||||
password:"",
|
password: "",
|
||||||
hostname:"esp8266-react",
|
hostname: "esp8266-react",
|
||||||
static_ip_config:false,
|
static_ip_config: false,
|
||||||
}
|
}
|
||||||
this.props.setData(wifiSettings);
|
this.props.setData(wifiSettings);
|
||||||
} else {
|
} else {
|
||||||
@ -35,20 +36,23 @@ class WiFiSettings extends Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const { data, fetched, errorMessage, selectedNetwork } = this.props;
|
const { data, fetched, errorMessage, saveData, loadData, handleValueChange, handleCheckboxChange, selectedNetwork, deselectNetwork } = this.props;
|
||||||
return (
|
return (
|
||||||
<SectionContent title="WiFi Settings">
|
<SectionContent title="WiFi Settings">
|
||||||
<WiFiSettingsForm
|
<LoadingNotification
|
||||||
wifiSettings={data}
|
onReset={loadData}
|
||||||
wifiSettingsFetched={fetched}
|
fetched={fetched}
|
||||||
errorMessage={errorMessage}
|
errorMessage={errorMessage}>
|
||||||
selectedNetwork={selectedNetwork}
|
<WiFiSettingsForm
|
||||||
deselectNetwork={this.props.deselectNetwork}
|
wifiSettings={data}
|
||||||
onSubmit={this.props.saveData}
|
selectedNetwork={selectedNetwork}
|
||||||
onReset={this.deselectNetworkAndLoadData}
|
deselectNetwork={deselectNetwork}
|
||||||
handleValueChange={this.props.handleValueChange}
|
onSubmit={saveData}
|
||||||
handleCheckboxChange={this.props.handleCheckboxChange}
|
onReset={this.deselectNetworkAndLoadData}
|
||||||
/>
|
handleValueChange={handleValueChange}
|
||||||
|
handleCheckboxChange={handleCheckboxChange}
|
||||||
|
/>
|
||||||
|
</LoadingNotification>
|
||||||
</SectionContent>
|
</SectionContent>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -2,14 +2,10 @@ import React, { Component, Fragment } from 'react';
|
|||||||
|
|
||||||
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 LinearProgress from '@material-ui/core/LinearProgress';
|
|
||||||
import Typography from '@material-ui/core/Typography';
|
|
||||||
|
|
||||||
import List from '@material-ui/core/List';
|
import List from '@material-ui/core/List';
|
||||||
import ListItem from '@material-ui/core/ListItem';
|
import ListItem from '@material-ui/core/ListItem';
|
||||||
import ListItemText from '@material-ui/core/ListItemText';
|
import ListItemText from '@material-ui/core/ListItemText';
|
||||||
import ListItemAvatar from '@material-ui/core/ListItemAvatar';
|
import ListItemAvatar from '@material-ui/core/ListItemAvatar';
|
||||||
|
|
||||||
import Avatar from '@material-ui/core/Avatar';
|
import Avatar from '@material-ui/core/Avatar';
|
||||||
import Divider from '@material-ui/core/Divider';
|
import Divider from '@material-ui/core/Divider';
|
||||||
import WifiIcon from '@material-ui/icons/Wifi';
|
import WifiIcon from '@material-ui/icons/Wifi';
|
||||||
@ -23,6 +19,7 @@ import { WIFI_STATUS_ENDPOINT } from '../constants/Endpoints';
|
|||||||
import { isConnected, connectionStatus, connectionStatusHighlight } from '../constants/WiFiConnectionStatus';
|
import { isConnected, connectionStatus, connectionStatusHighlight } from '../constants/WiFiConnectionStatus';
|
||||||
import * as Highlight from '../constants/Highlight';
|
import * as Highlight from '../constants/Highlight';
|
||||||
import { restComponent } from '../components/RestComponent';
|
import { restComponent } from '../components/RestComponent';
|
||||||
|
import LoadingNotification from '../components/LoadingNotification';
|
||||||
|
|
||||||
const styles = theme => ({
|
const styles = theme => ({
|
||||||
["wifiStatus_" + Highlight.IDLE]: {
|
["wifiStatus_" + Highlight.IDLE]: {
|
||||||
@ -37,10 +34,6 @@ const styles = theme => ({
|
|||||||
["wifiStatus_" + Highlight.WARN]: {
|
["wifiStatus_" + Highlight.WARN]: {
|
||||||
backgroundColor: theme.palette.highlight_warn
|
backgroundColor: theme.palette.highlight_warn
|
||||||
},
|
},
|
||||||
fetching: {
|
|
||||||
margin: theme.spacing(4),
|
|
||||||
textAlign: "center"
|
|
||||||
},
|
|
||||||
button: {
|
button: {
|
||||||
marginRight: theme.spacing(2),
|
marginRight: theme.spacing(2),
|
||||||
marginTop: theme.spacing(2),
|
marginTop: theme.spacing(2),
|
||||||
@ -145,32 +138,19 @@ class WiFiStatus extends Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const { data, fetched, errorMessage, classes } = this.props;
|
const { data, fetched, errorMessage, loadData, classes } = this.props;
|
||||||
return (
|
return (
|
||||||
<SectionContent title="WiFi Status">
|
<SectionContent title="WiFi Status">
|
||||||
{
|
<LoadingNotification
|
||||||
!fetched ?
|
onReset={loadData}
|
||||||
<div>
|
fetched={fetched}
|
||||||
<LinearProgress className={classes.fetching} />
|
errorMessage={errorMessage}>
|
||||||
<Typography variant="h4" className={classes.fetching}>
|
{this.renderWiFiStatus(data, classes)}
|
||||||
Loading...
|
</LoadingNotification>
|
||||||
</Typography>
|
|
||||||
</div>
|
|
||||||
:
|
|
||||||
data ? this.renderWiFiStatus(data, classes)
|
|
||||||
:
|
|
||||||
<div>
|
|
||||||
<Typography variant="h4" className={classes.fetching}>
|
|
||||||
{errorMessage}
|
|
||||||
</Typography>
|
|
||||||
<Button variant="contained" color="secondary" className={classes.button} onClick={this.props.loadData}>
|
|
||||||
Refresh
|
|
||||||
</Button>
|
|
||||||
</div>
|
|
||||||
}
|
|
||||||
</SectionContent>
|
</SectionContent>
|
||||||
)
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export default restComponent(WIFI_STATUS_ENDPOINT, withStyles(styles)(WiFiStatus));
|
export default restComponent(WIFI_STATUS_ENDPOINT, withStyles(styles)(WiFiStatus));
|
||||||
|
@ -1,29 +1,19 @@
|
|||||||
import React, { Fragment } from 'react';
|
import React, { Fragment } from 'react';
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
|
import { TextValidator, ValidatorForm, SelectValidator } from 'react-material-ui-form-validator';
|
||||||
|
|
||||||
|
import { isAPEnabled } from '../constants/WiFiAPModes';
|
||||||
|
import PasswordValidator from '../components/PasswordValidator';
|
||||||
|
|
||||||
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 LinearProgress from '@material-ui/core/LinearProgress';
|
|
||||||
import Typography from '@material-ui/core/Typography';
|
|
||||||
import MenuItem from '@material-ui/core/MenuItem';
|
import MenuItem from '@material-ui/core/MenuItem';
|
||||||
|
|
||||||
import { TextValidator, ValidatorForm, SelectValidator } from 'react-material-ui-form-validator';
|
|
||||||
|
|
||||||
import {isAPEnabled} from '../constants/WiFiAPModes';
|
|
||||||
import PasswordValidator from '../components/PasswordValidator';
|
|
||||||
|
|
||||||
const styles = theme => ({
|
const styles = theme => ({
|
||||||
loadingSettings: {
|
|
||||||
margin: theme.spacing(0.5),
|
|
||||||
},
|
|
||||||
loadingSettingsDetails: {
|
|
||||||
margin: theme.spacing(4),
|
|
||||||
textAlign: "center"
|
|
||||||
},
|
|
||||||
textField: {
|
textField: {
|
||||||
width: "100%"
|
width: "100%"
|
||||||
},
|
},
|
||||||
selectField:{
|
selectField: {
|
||||||
width: "100%",
|
width: "100%",
|
||||||
marginTop: theme.spacing(2),
|
marginTop: theme.spacing(2),
|
||||||
marginBottom: theme.spacing(0.5)
|
marginBottom: theme.spacing(0.5)
|
||||||
@ -37,86 +27,54 @@ const styles = theme => ({
|
|||||||
class APSettingsForm extends React.Component {
|
class APSettingsForm extends React.Component {
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const { classes, apSettingsFetched, apSettings, errorMessage, handleValueChange, onSubmit, onReset } = this.props;
|
const { classes, apSettings, handleValueChange, onSubmit, onReset } = this.props;
|
||||||
return (
|
return (
|
||||||
<div>
|
<ValidatorForm onSubmit={onSubmit} ref="APSettingsForm">
|
||||||
|
<SelectValidator name="provision_mode" label="Provide Access Point..." value={apSettings.provision_mode} className={classes.selectField}
|
||||||
|
onChange={handleValueChange('provision_mode')}>
|
||||||
|
<MenuItem value={0}>Always</MenuItem>
|
||||||
|
<MenuItem value={1}>When WiFi Disconnected</MenuItem>
|
||||||
|
<MenuItem value={2}>Never</MenuItem>
|
||||||
|
</SelectValidator>
|
||||||
{
|
{
|
||||||
!apSettingsFetched ?
|
isAPEnabled(apSettings.provision_mode) &&
|
||||||
|
<Fragment>
|
||||||
<div className={classes.loadingSettings}>
|
<TextValidator
|
||||||
<LinearProgress className={classes.loadingSettingsDetails}/>
|
validators={['required', 'matchRegexp:^.{1,32}$']}
|
||||||
<Typography variant="h4" className={classes.loadingSettingsDetails}>
|
errorMessages={['Access Point SSID is required', 'Access Point SSID must be 32 characters or less']}
|
||||||
Loading...
|
name="ssid"
|
||||||
</Typography>
|
label="Access Point SSID"
|
||||||
</div>
|
className={classes.textField}
|
||||||
|
value={apSettings.ssid}
|
||||||
: apSettings ?
|
onChange={handleValueChange('ssid')}
|
||||||
|
margin="normal"
|
||||||
<ValidatorForm onSubmit={onSubmit} ref="APSettingsForm">
|
/>
|
||||||
|
<PasswordValidator
|
||||||
<SelectValidator name="provision_mode" label="Provide Access Point..." value={apSettings.provision_mode} className={classes.selectField}
|
validators={['required', 'matchRegexp:^.{1,64}$']}
|
||||||
onChange={handleValueChange('provision_mode')}>
|
errorMessages={['Access Point Password is required', 'Access Point Password must be 64 characters or less']}
|
||||||
<MenuItem value={0}>Always</MenuItem>
|
name="password"
|
||||||
<MenuItem value={1}>When WiFi Disconnected</MenuItem>
|
label="Access Point Password"
|
||||||
<MenuItem value={2}>Never</MenuItem>
|
className={classes.textField}
|
||||||
</SelectValidator>
|
value={apSettings.password}
|
||||||
|
onChange={handleValueChange('password')}
|
||||||
{
|
margin="normal"
|
||||||
isAPEnabled(apSettings.provision_mode) &&
|
/>
|
||||||
<Fragment>
|
</Fragment>
|
||||||
<TextValidator
|
}
|
||||||
validators={['required', 'matchRegexp:^.{1,32}$']}
|
<Button variant="contained" color="primary" className={classes.button} type="submit">
|
||||||
errorMessages={['Access Point SSID is required', 'Access Point SSID must be 32 characters or less']}
|
Save
|
||||||
name="ssid"
|
</Button>
|
||||||
label="Access Point SSID"
|
<Button variant="contained" color="secondary" className={classes.button} onClick={onReset}>
|
||||||
className={classes.textField}
|
Reset
|
||||||
value={apSettings.ssid}
|
</Button>
|
||||||
onChange={handleValueChange('ssid')}
|
</ValidatorForm>
|
||||||
margin="normal"
|
|
||||||
/>
|
|
||||||
<PasswordValidator
|
|
||||||
validators={['required', 'matchRegexp:^.{1,64}$']}
|
|
||||||
errorMessages={['Access Point Password is required', 'Access Point Password must be 64 characters or less']}
|
|
||||||
name="password"
|
|
||||||
label="Access Point Password"
|
|
||||||
className={classes.textField}
|
|
||||||
value={apSettings.password}
|
|
||||||
onChange={handleValueChange('password')}
|
|
||||||
margin="normal"
|
|
||||||
/>
|
|
||||||
</Fragment>
|
|
||||||
}
|
|
||||||
|
|
||||||
<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>
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
APSettingsForm.propTypes = {
|
APSettingsForm.propTypes = {
|
||||||
classes: PropTypes.object.isRequired,
|
classes: PropTypes.object.isRequired,
|
||||||
apSettingsFetched: PropTypes.bool.isRequired,
|
|
||||||
apSettings: PropTypes.object,
|
apSettings: PropTypes.object,
|
||||||
errorMessage: PropTypes.string,
|
|
||||||
onSubmit: PropTypes.func.isRequired,
|
onSubmit: PropTypes.func.isRequired,
|
||||||
onReset: PropTypes.func.isRequired,
|
onReset: PropTypes.func.isRequired,
|
||||||
handleValueChange: PropTypes.func.isRequired
|
handleValueChange: PropTypes.func.isRequired
|
||||||
|
@ -5,7 +5,6 @@ import { ValidatorForm } from 'react-material-ui-form-validator';
|
|||||||
|
|
||||||
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 LinearProgress from '@material-ui/core/LinearProgress';
|
|
||||||
import Typography from '@material-ui/core/Typography';
|
import Typography from '@material-ui/core/Typography';
|
||||||
import Table from '@material-ui/core/Table';
|
import Table from '@material-ui/core/Table';
|
||||||
import TableBody from '@material-ui/core/TableBody';
|
import TableBody from '@material-ui/core/TableBody';
|
||||||
@ -14,7 +13,6 @@ import TableFooter from '@material-ui/core/TableFooter';
|
|||||||
import TableHead from '@material-ui/core/TableHead';
|
import TableHead from '@material-ui/core/TableHead';
|
||||||
import TableRow from '@material-ui/core/TableRow';
|
import TableRow from '@material-ui/core/TableRow';
|
||||||
import Box from '@material-ui/core/Box';
|
import Box from '@material-ui/core/Box';
|
||||||
|
|
||||||
import EditIcon from '@material-ui/icons/Edit';
|
import EditIcon from '@material-ui/icons/Edit';
|
||||||
import DeleteIcon from '@material-ui/icons/Delete';
|
import DeleteIcon from '@material-ui/icons/Delete';
|
||||||
import CloseIcon from '@material-ui/icons/Close';
|
import CloseIcon from '@material-ui/icons/Close';
|
||||||
@ -25,22 +23,12 @@ import UserForm from './UserForm';
|
|||||||
import { withAuthenticationContext } from '../authentication/Context';
|
import { withAuthenticationContext } from '../authentication/Context';
|
||||||
|
|
||||||
const styles = theme => ({
|
const styles = theme => ({
|
||||||
loadingSettings: {
|
|
||||||
margin: theme.spacing(0.5),
|
|
||||||
},
|
|
||||||
loadingSettingsDetails: {
|
|
||||||
margin: theme.spacing(4),
|
|
||||||
textAlign: "center"
|
|
||||||
},
|
|
||||||
button: {
|
button: {
|
||||||
marginRight: theme.spacing(2),
|
marginRight: theme.spacing(2),
|
||||||
marginTop: theme.spacing(2),
|
marginTop: theme.spacing(2),
|
||||||
},
|
},
|
||||||
table: {
|
table: {
|
||||||
'& td, & th': { padding: theme.spacing(0.5) }
|
'& td, & th': { padding: theme.spacing(0.5) }
|
||||||
},
|
|
||||||
actions: {
|
|
||||||
whiteSpace: "nowrap"
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -134,98 +122,80 @@ class ManageUsersForm extends React.Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const { classes, userData, userDataFetched, errorMessage, onReset } = this.props;
|
const { classes, userData, onReset } = this.props;
|
||||||
const { user, creating } = this.state;
|
const { user, creating } = this.state;
|
||||||
return (
|
return (
|
||||||
!userDataFetched ?
|
<Fragment>
|
||||||
<div className={classes.loadingSettings}>
|
<ValidatorForm onSubmit={this.onSubmit}>
|
||||||
<LinearProgress className={classes.loadingSettingsDetails} />
|
<Table className={classes.table}>
|
||||||
<Typography variant="h4" className={classes.loadingSettingsDetails}>
|
<TableHead>
|
||||||
Loading...
|
<TableRow>
|
||||||
</Typography>
|
<TableCell>Username</TableCell>
|
||||||
</div>
|
<TableCell align="center">Admin?</TableCell>
|
||||||
:
|
<TableCell />
|
||||||
userData ?
|
</TableRow>
|
||||||
<Fragment>
|
</TableHead>
|
||||||
<ValidatorForm onSubmit={this.onSubmit}>
|
<TableBody>
|
||||||
<Table className={classes.table}>
|
{userData.users.sort(compareUsers).map(user => (
|
||||||
<TableHead>
|
<TableRow key={user.username}>
|
||||||
<TableRow>
|
<TableCell component="th" scope="row">
|
||||||
<TableCell>Username</TableCell>
|
{user.username}
|
||||||
<TableCell align="center">Admin?</TableCell>
|
</TableCell>
|
||||||
<TableCell />
|
<TableCell align="center">
|
||||||
</TableRow>
|
{
|
||||||
</TableHead>
|
user.admin ? <CheckIcon /> : <CloseIcon />
|
||||||
<TableBody>
|
}
|
||||||
{userData.users.sort(compareUsers).map(user => (
|
</TableCell>
|
||||||
<TableRow key={user.username}>
|
<TableCell align="center">
|
||||||
<TableCell component="th" scope="row">
|
<IconButton aria-label="Delete" onClick={() => this.removeUser(user)}>
|
||||||
{user.username}
|
<DeleteIcon />
|
||||||
</TableCell>
|
</IconButton>
|
||||||
<TableCell align="center">
|
<IconButton aria-label="Edit" onClick={() => this.startEditingUser(user)}>
|
||||||
{
|
<EditIcon />
|
||||||
user.admin ? <CheckIcon /> : <CloseIcon />
|
</IconButton>
|
||||||
}
|
</TableCell>
|
||||||
</TableCell>
|
</TableRow>
|
||||||
<TableCell align="center">
|
))}
|
||||||
<IconButton aria-label="Delete" onClick={() => this.removeUser(user)}>
|
</TableBody>
|
||||||
<DeleteIcon />
|
<TableFooter>
|
||||||
</IconButton>
|
<TableRow>
|
||||||
<IconButton aria-label="Edit" onClick={() => this.startEditingUser(user)}>
|
<TableCell colSpan={2} />
|
||||||
<EditIcon />
|
<TableCell align="center">
|
||||||
</IconButton>
|
<Button variant="contained" color="secondary" onClick={this.createUser}>
|
||||||
</TableCell>
|
Add User
|
||||||
</TableRow>
|
</Button>
|
||||||
))}
|
</TableCell>
|
||||||
</TableBody>
|
</TableRow>
|
||||||
<TableFooter>
|
</TableFooter>
|
||||||
<TableRow>
|
</Table>
|
||||||
<TableCell colSpan={2} />
|
{
|
||||||
<TableCell align="center">
|
this.noAdminConfigured() &&
|
||||||
<Button variant="contained" color="secondary" onClick={this.createUser}>
|
<Typography component="div" variant="body1">
|
||||||
Add User
|
<Box bgcolor="error.main" color="error.contrastText" p={2} mt={2} mb={2}>
|
||||||
</Button>
|
You must have at least one admin user configured.
|
||||||
</TableCell>
|
</Box>
|
||||||
</TableRow>
|
|
||||||
</TableFooter>
|
|
||||||
</Table>
|
|
||||||
{
|
|
||||||
this.noAdminConfigured() &&
|
|
||||||
<Typography component="div" variant="body1">
|
|
||||||
<Box bgcolor="error.main" color="error.contrastText" p={2} mt={2} mb={2}>
|
|
||||||
You must have at least one admin user configured.
|
|
||||||
</Box>
|
|
||||||
</Typography>
|
|
||||||
}
|
|
||||||
<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>
|
|
||||||
:
|
|
||||||
<div className={classes.loadingSettings}>
|
|
||||||
<Typography variant="h4" className={classes.loadingSettingsDetails}>
|
|
||||||
{errorMessage}
|
|
||||||
</Typography>
|
</Typography>
|
||||||
<Button variant="contained" color="secondary" className={classes.button} onClick={onReset}>
|
}
|
||||||
Reset
|
<Button variant="contained" color="primary" className={classes.button} type="submit" disabled={this.noAdminConfigured()}>
|
||||||
</Button>
|
Save
|
||||||
</div>
|
</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>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -234,8 +204,6 @@ class ManageUsersForm extends React.Component {
|
|||||||
ManageUsersForm.propTypes = {
|
ManageUsersForm.propTypes = {
|
||||||
classes: PropTypes.object.isRequired,
|
classes: PropTypes.object.isRequired,
|
||||||
userData: PropTypes.object,
|
userData: PropTypes.object,
|
||||||
userDataFetched: PropTypes.bool.isRequired,
|
|
||||||
errorMessage: PropTypes.string,
|
|
||||||
onSubmit: PropTypes.func.isRequired,
|
onSubmit: PropTypes.func.isRequired,
|
||||||
onReset: PropTypes.func.isRequired,
|
onReset: PropTypes.func.isRequired,
|
||||||
setData: PropTypes.func.isRequired,
|
setData: PropTypes.func.isRequired,
|
||||||
|
@ -1,24 +1,15 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
|
import { TextValidator, ValidatorForm } from 'react-material-ui-form-validator';
|
||||||
|
|
||||||
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 LinearProgress from '@material-ui/core/LinearProgress';
|
|
||||||
import { TextValidator, ValidatorForm } from 'react-material-ui-form-validator';
|
|
||||||
import Typography from '@material-ui/core/Typography';
|
|
||||||
|
|
||||||
import isIP from '../validators/isIP';
|
import isIP from '../validators/isIP';
|
||||||
import isHostname from '../validators/isHostname';
|
import isHostname from '../validators/isHostname';
|
||||||
import or from '../validators/or';
|
import or from '../validators/or';
|
||||||
|
|
||||||
const styles = theme => ({
|
const styles = theme => ({
|
||||||
loadingSettings: {
|
|
||||||
margin: theme.spacing(0.5),
|
|
||||||
},
|
|
||||||
loadingSettingsDetails: {
|
|
||||||
margin: theme.spacing(4),
|
|
||||||
textAlign: "center"
|
|
||||||
},
|
|
||||||
textField: {
|
textField: {
|
||||||
width: "100%"
|
width: "100%"
|
||||||
},
|
},
|
||||||
@ -35,76 +26,44 @@ class NTPSettingsForm extends React.Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const { classes, ntpSettingsFetched, ntpSettings, errorMessage, handleValueChange, onSubmit, onReset } = this.props;
|
const { classes, ntpSettings, handleValueChange, onSubmit, onReset } = this.props;
|
||||||
return (
|
return (
|
||||||
<div>
|
<ValidatorForm onSubmit={onSubmit}>
|
||||||
{
|
<TextValidator
|
||||||
!ntpSettingsFetched ?
|
validators={['required', 'isIPOrHostname']}
|
||||||
|
errorMessages={['Server is required', "Not a valid IP address or hostname"]}
|
||||||
<div className={classes.loadingSettings}>
|
name="server"
|
||||||
<LinearProgress className={classes.loadingSettingsDetails}/>
|
label="Server"
|
||||||
<Typography variant="h4" className={classes.loadingSettingsDetails}>
|
className={classes.textField}
|
||||||
Loading...
|
value={ntpSettings.server}
|
||||||
</Typography>
|
onChange={handleValueChange('server')}
|
||||||
</div>
|
margin="normal"
|
||||||
|
/>
|
||||||
: ntpSettings ?
|
<TextValidator
|
||||||
|
validators={['required', 'isNumber', 'minNumber:60', 'maxNumber:86400']}
|
||||||
<ValidatorForm onSubmit={onSubmit}>
|
errorMessages={['Interval is required', 'Interval must be a number', 'Must be at least 60 seconds', "Must not be more than 86400 seconds (24 hours)"]}
|
||||||
|
name="interval"
|
||||||
<TextValidator
|
label="Interval (Seconds)"
|
||||||
validators={['required', 'isIPOrHostname']}
|
className={classes.textField}
|
||||||
errorMessages={['Server is required', "Not a valid IP address or hostname"]}
|
value={ntpSettings.interval}
|
||||||
name="server"
|
type="number"
|
||||||
label="Server"
|
onChange={handleValueChange('interval')}
|
||||||
className={classes.textField}
|
margin="normal"
|
||||||
value={ntpSettings.server}
|
/>
|
||||||
onChange={handleValueChange('server')}
|
<Button variant="contained" color="primary" className={classes.button} type="submit">
|
||||||
margin="normal"
|
Save
|
||||||
/>
|
</Button>
|
||||||
|
<Button variant="contained" color="secondary" className={classes.button} onClick={onReset}>
|
||||||
<TextValidator
|
Reset
|
||||||
validators={['required','isNumber','minNumber:60','maxNumber:86400']}
|
</Button>
|
||||||
errorMessages={['Interval is required','Interval must be a number','Must be at least 60 seconds',"Must not be more than 86400 seconds (24 hours)"]}
|
</ValidatorForm>
|
||||||
name="interval"
|
|
||||||
label="Interval (Seconds)"
|
|
||||||
className={classes.textField}
|
|
||||||
value={ntpSettings.interval}
|
|
||||||
type="number"
|
|
||||||
onChange={handleValueChange('interval')}
|
|
||||||
margin="normal"
|
|
||||||
/>
|
|
||||||
|
|
||||||
<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>
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
NTPSettingsForm.propTypes = {
|
NTPSettingsForm.propTypes = {
|
||||||
classes: PropTypes.object.isRequired,
|
classes: PropTypes.object.isRequired,
|
||||||
ntpSettingsFetched: PropTypes.bool.isRequired,
|
|
||||||
ntpSettings: PropTypes.object,
|
ntpSettings: PropTypes.object,
|
||||||
errorMessage: PropTypes.string,
|
|
||||||
onSubmit: PropTypes.func.isRequired,
|
onSubmit: PropTypes.func.isRequired,
|
||||||
onReset: PropTypes.func.isRequired,
|
onReset: PropTypes.func.isRequired,
|
||||||
handleValueChange: PropTypes.func.isRequired,
|
handleValueChange: PropTypes.func.isRequired,
|
||||||
|
@ -4,9 +4,7 @@ import PropTypes from 'prop-types';
|
|||||||
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 Switch from '@material-ui/core/Switch';
|
import Switch from '@material-ui/core/Switch';
|
||||||
import LinearProgress from '@material-ui/core/LinearProgress';
|
|
||||||
import { TextValidator, ValidatorForm } from 'react-material-ui-form-validator';
|
import { TextValidator, ValidatorForm } from 'react-material-ui-form-validator';
|
||||||
import Typography from '@material-ui/core/Typography';
|
|
||||||
import FormControlLabel from '@material-ui/core/FormControlLabel';
|
import FormControlLabel from '@material-ui/core/FormControlLabel';
|
||||||
|
|
||||||
import isIP from '../validators/isIP';
|
import isIP from '../validators/isIP';
|
||||||
@ -15,13 +13,6 @@ import or from '../validators/or';
|
|||||||
import PasswordValidator from '../components/PasswordValidator';
|
import PasswordValidator from '../components/PasswordValidator';
|
||||||
|
|
||||||
const styles = theme => ({
|
const styles = theme => ({
|
||||||
loadingSettings: {
|
|
||||||
margin: theme.spacing(0.5),
|
|
||||||
},
|
|
||||||
loadingSettingsDetails: {
|
|
||||||
margin: theme.spacing(4),
|
|
||||||
textAlign: "center"
|
|
||||||
},
|
|
||||||
switchControl: {
|
switchControl: {
|
||||||
width: "100%",
|
width: "100%",
|
||||||
marginTop: theme.spacing(2),
|
marginTop: theme.spacing(2),
|
||||||
@ -43,88 +34,55 @@ class OTASettingsForm extends React.Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const { classes, otaSettingsFetched, otaSettings, errorMessage, handleValueChange, handleCheckboxChange, onSubmit, onReset } = this.props;
|
const { classes, otaSettings, handleValueChange, handleCheckboxChange, onSubmit, onReset } = this.props;
|
||||||
return (
|
return (
|
||||||
<div>
|
<ValidatorForm onSubmit={onSubmit}>
|
||||||
{
|
<FormControlLabel className={classes.switchControl}
|
||||||
!otaSettingsFetched ?
|
control={
|
||||||
|
<Switch
|
||||||
<div className={classes.loadingSettings}>
|
checked={otaSettings.enabled}
|
||||||
<LinearProgress className={classes.loadingSettingsDetails}/>
|
onChange={handleCheckboxChange('enabled')}
|
||||||
<Typography variant="h4" className={classes.loadingSettingsDetails}>
|
value="enabled"
|
||||||
Loading...
|
color="primary"
|
||||||
</Typography>
|
/>
|
||||||
</div>
|
}
|
||||||
|
label="Enable OTA Updates?"
|
||||||
: otaSettings ?
|
/>
|
||||||
|
<TextValidator
|
||||||
<ValidatorForm onSubmit={onSubmit}>
|
validators={['required', 'isNumber', 'minNumber:1025', 'maxNumber:65535']}
|
||||||
|
errorMessages={['Port is required', "Must be a number", "Must be greater than 1024 ", "Max value is 65535"]}
|
||||||
<FormControlLabel className={classes.switchControl}
|
name="port"
|
||||||
control={
|
label="Port"
|
||||||
<Switch
|
className={classes.textField}
|
||||||
checked={otaSettings.enabled}
|
value={otaSettings.port}
|
||||||
onChange={handleCheckboxChange('enabled')}
|
type="number"
|
||||||
value="enabled"
|
onChange={handleValueChange('port')}
|
||||||
color="primary"
|
margin="normal"
|
||||||
/>
|
/>
|
||||||
}
|
<PasswordValidator
|
||||||
label="Enable OTA Updates?"
|
validators={['required', 'matchRegexp:^.{1,64}$']}
|
||||||
/>
|
errorMessages={['OTA Password is required', 'OTA Point Password must be 64 characters or less']}
|
||||||
|
name="password"
|
||||||
<TextValidator
|
label="Password"
|
||||||
validators={['required', 'isNumber', 'minNumber:1025', 'maxNumber:65535']}
|
className={classes.textField}
|
||||||
errorMessages={['Port is required', "Must be a number", "Must be greater than 1024 ", "Max value is 65535"]}
|
value={otaSettings.password}
|
||||||
name="port"
|
onChange={handleValueChange('password')}
|
||||||
label="Port"
|
margin="normal"
|
||||||
className={classes.textField}
|
/>
|
||||||
value={otaSettings.port}
|
<Button variant="contained" color="primary" className={classes.button} type="submit">
|
||||||
type="number"
|
Save
|
||||||
onChange={handleValueChange('port')}
|
</Button>
|
||||||
margin="normal"
|
<Button variant="contained" color="secondary" className={classes.button} onClick={onReset}>
|
||||||
/>
|
Reset
|
||||||
|
</Button>
|
||||||
<PasswordValidator
|
</ValidatorForm>
|
||||||
validators={['required', 'matchRegexp:^.{1,64}$']}
|
|
||||||
errorMessages={['OTA Password is required', 'OTA Point Password must be 64 characters or less']}
|
|
||||||
name="password"
|
|
||||||
label="Password"
|
|
||||||
className={classes.textField}
|
|
||||||
value={otaSettings.password}
|
|
||||||
onChange={handleValueChange('password')}
|
|
||||||
margin="normal"
|
|
||||||
/>
|
|
||||||
|
|
||||||
<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>
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
OTASettingsForm.propTypes = {
|
OTASettingsForm.propTypes = {
|
||||||
classes: PropTypes.object.isRequired,
|
classes: PropTypes.object.isRequired,
|
||||||
otaSettingsFetched: PropTypes.bool.isRequired,
|
|
||||||
otaSettings: PropTypes.object,
|
otaSettings: PropTypes.object,
|
||||||
errorMessage: PropTypes.string,
|
|
||||||
onSubmit: PropTypes.func.isRequired,
|
onSubmit: PropTypes.func.isRequired,
|
||||||
onReset: PropTypes.func.isRequired,
|
onReset: PropTypes.func.isRequired,
|
||||||
handleValueChange: PropTypes.func.isRequired,
|
handleValueChange: PropTypes.func.isRequired,
|
||||||
|
@ -4,7 +4,6 @@ import { ValidatorForm } from 'react-material-ui-form-validator';
|
|||||||
|
|
||||||
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 LinearProgress from '@material-ui/core/LinearProgress';
|
|
||||||
import Typography from '@material-ui/core/Typography';
|
import Typography from '@material-ui/core/Typography';
|
||||||
import Box from '@material-ui/core/Box';
|
import Box from '@material-ui/core/Box';
|
||||||
|
|
||||||
@ -12,13 +11,6 @@ import PasswordValidator from '../components/PasswordValidator';
|
|||||||
import { withAuthenticationContext } from '../authentication/Context';
|
import { withAuthenticationContext } from '../authentication/Context';
|
||||||
|
|
||||||
const styles = theme => ({
|
const styles = theme => ({
|
||||||
loadingSettings: {
|
|
||||||
margin: theme.spacing(0.5),
|
|
||||||
},
|
|
||||||
loadingSettingsDetails: {
|
|
||||||
margin: theme.spacing(4),
|
|
||||||
textAlign: "center"
|
|
||||||
},
|
|
||||||
textField: {
|
textField: {
|
||||||
width: "100%"
|
width: "100%"
|
||||||
},
|
},
|
||||||
@ -36,58 +28,38 @@ class SecuritySettingsForm extends React.Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const { classes, securitySettingsFetched, securitySettings, errorMessage, handleValueChange, onReset } = this.props;
|
const { classes, securitySettings, handleValueChange, onReset } = this.props;
|
||||||
return (
|
return (
|
||||||
!securitySettingsFetched ?
|
<ValidatorForm onSubmit={this.onSubmit} ref="SecuritySettingsForm">
|
||||||
<div className={classes.loadingSettings}>
|
<PasswordValidator
|
||||||
<LinearProgress className={classes.loadingSettingsDetails} />
|
validators={['required', 'matchRegexp:^.{1,64}$']}
|
||||||
<Typography variant="h4" className={classes.loadingSettingsDetails}>
|
errorMessages={['JWT Secret Required', 'JWT Secret must be 64 characters or less']}
|
||||||
Loading...
|
name="jwt_secret"
|
||||||
</Typography>
|
label="JWT Secret"
|
||||||
</div>
|
className={classes.textField}
|
||||||
:
|
value={securitySettings.jwt_secret}
|
||||||
securitySettings ?
|
onChange={handleValueChange('jwt_secret')}
|
||||||
<ValidatorForm onSubmit={this.onSubmit} ref="SecuritySettingsForm">
|
margin="normal"
|
||||||
<PasswordValidator
|
/>
|
||||||
validators={['required', 'matchRegexp:^.{1,64}$']}
|
<Typography component="div" variant="body1">
|
||||||
errorMessages={['JWT Secret Required', 'JWT Secret must be 64 characters or less']}
|
<Box bgcolor="primary.main" color="primary.contrastText" p={2} mt={2} mb={2}>
|
||||||
name="jwt_secret"
|
If you modify the JWT Secret, all users will be logged out.
|
||||||
label="JWT Secret"
|
</Box>
|
||||||
className={classes.textField}
|
</Typography>
|
||||||
value={securitySettings.jwt_secret}
|
<Button variant="contained" color="primary" className={classes.button} type="submit">
|
||||||
onChange={handleValueChange('jwt_secret')}
|
Save
|
||||||
margin="normal"
|
</Button>
|
||||||
/>
|
<Button variant="contained" color="secondary" className={classes.button} onClick={onReset}>
|
||||||
<Typography component="div" variant="body1">
|
Reset
|
||||||
<Box bgcolor="primary.main" color="primary.contrastText" p={2} mt={2} mb={2}>
|
</Button>
|
||||||
If you modify the JWT Secret, all users will be logged out.
|
</ValidatorForm>
|
||||||
</Box>
|
|
||||||
</Typography>
|
|
||||||
<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>
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
SecuritySettingsForm.propTypes = {
|
SecuritySettingsForm.propTypes = {
|
||||||
classes: PropTypes.object.isRequired,
|
classes: PropTypes.object.isRequired,
|
||||||
securitySettingsFetched: PropTypes.bool.isRequired,
|
|
||||||
securitySettings: PropTypes.object,
|
securitySettings: PropTypes.object,
|
||||||
errorMessage: PropTypes.string,
|
|
||||||
onSubmit: PropTypes.func.isRequired,
|
onSubmit: PropTypes.func.isRequired,
|
||||||
onReset: PropTypes.func.isRequired,
|
onReset: PropTypes.func.isRequired,
|
||||||
handleValueChange: PropTypes.func.isRequired,
|
handleValueChange: PropTypes.func.isRequired,
|
||||||
|
@ -3,10 +3,8 @@ import PropTypes from 'prop-types';
|
|||||||
|
|
||||||
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 LinearProgress from '@material-ui/core/LinearProgress';
|
|
||||||
import Checkbox from '@material-ui/core/Checkbox';
|
import Checkbox from '@material-ui/core/Checkbox';
|
||||||
import FormControlLabel from '@material-ui/core/FormControlLabel';
|
import FormControlLabel from '@material-ui/core/FormControlLabel';
|
||||||
import Typography from '@material-ui/core/Typography';
|
|
||||||
import List from '@material-ui/core/List';
|
import List from '@material-ui/core/List';
|
||||||
import ListItem from '@material-ui/core/ListItem';
|
import ListItem from '@material-ui/core/ListItem';
|
||||||
import ListItemText from '@material-ui/core/ListItemText';
|
import ListItemText from '@material-ui/core/ListItemText';
|
||||||
@ -80,157 +78,124 @@ class WiFiSettingsForm extends React.Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const { classes, wifiSettingsFetched, wifiSettings, errorMessage, selectedNetwork, handleValueChange, handleCheckboxChange, onSubmit, onReset } = this.props;
|
const { classes, wifiSettings, selectedNetwork, handleValueChange, handleCheckboxChange, onSubmit, onReset } = this.props;
|
||||||
return (
|
return (
|
||||||
<div>
|
<ValidatorForm onSubmit={onSubmit} ref="WiFiSettingsForm">
|
||||||
{
|
{
|
||||||
!wifiSettingsFetched ?
|
selectedNetwork ? this.renderSelectedNetwork() :
|
||||||
|
<TextValidator
|
||||||
<div className={classes.loadingSettings}>
|
validators={['matchRegexp:^.{0,32}$']}
|
||||||
<LinearProgress className={classes.loadingSettingsDetails} />
|
errorMessages={['SSID must be 32 characters or less']}
|
||||||
<Typography variant="h4" className={classes.loadingSettingsDetails}>
|
name="ssid"
|
||||||
Loading...
|
label="SSID"
|
||||||
</Typography>
|
className={classes.textField}
|
||||||
</div>
|
value={wifiSettings.ssid}
|
||||||
|
onChange={handleValueChange('ssid')}
|
||||||
: wifiSettings ?
|
margin="normal"
|
||||||
|
/>
|
||||||
<ValidatorForm onSubmit={onSubmit} ref="WiFiSettingsForm">
|
|
||||||
{
|
|
||||||
selectedNetwork ? this.renderSelectedNetwork() :
|
|
||||||
<TextValidator
|
|
||||||
validators={['matchRegexp:^.{0,32}$']}
|
|
||||||
errorMessages={['SSID must be 32 characters or less']}
|
|
||||||
name="ssid"
|
|
||||||
label="SSID"
|
|
||||||
className={classes.textField}
|
|
||||||
value={wifiSettings.ssid}
|
|
||||||
onChange={handleValueChange('ssid')}
|
|
||||||
margin="normal"
|
|
||||||
/>
|
|
||||||
}
|
|
||||||
{
|
|
||||||
!isNetworkOpen(selectedNetwork) &&
|
|
||||||
<PasswordValidator
|
|
||||||
validators={['matchRegexp:^.{0,64}$']}
|
|
||||||
errorMessages={['Password must be 64 characters or less']}
|
|
||||||
name="password"
|
|
||||||
label="Password"
|
|
||||||
className={classes.textField}
|
|
||||||
value={wifiSettings.password}
|
|
||||||
onChange={handleValueChange('password')}
|
|
||||||
margin="normal"
|
|
||||||
/>
|
|
||||||
}
|
|
||||||
|
|
||||||
<TextValidator
|
|
||||||
validators={['required', 'isHostname']}
|
|
||||||
errorMessages={['Hostname is required', "Not a valid hostname"]}
|
|
||||||
name="hostname"
|
|
||||||
label="Hostname"
|
|
||||||
className={classes.textField}
|
|
||||||
value={wifiSettings.hostname}
|
|
||||||
onChange={handleValueChange('hostname')}
|
|
||||||
margin="normal"
|
|
||||||
/>
|
|
||||||
|
|
||||||
<FormControlLabel className={classes.checkboxControl}
|
|
||||||
control={
|
|
||||||
<Checkbox
|
|
||||||
value="static_ip_config"
|
|
||||||
checked={wifiSettings.static_ip_config}
|
|
||||||
onChange={handleCheckboxChange("static_ip_config")}
|
|
||||||
/>
|
|
||||||
}
|
|
||||||
label="Static IP Config?"
|
|
||||||
/>
|
|
||||||
|
|
||||||
{
|
|
||||||
wifiSettings.static_ip_config &&
|
|
||||||
<Fragment>
|
|
||||||
<TextValidator
|
|
||||||
validators={['required', 'isIP']}
|
|
||||||
errorMessages={['Local IP is required', 'Must be an IP address']}
|
|
||||||
name="local_ip"
|
|
||||||
label="Local IP"
|
|
||||||
className={classes.textField}
|
|
||||||
value={wifiSettings.local_ip}
|
|
||||||
onChange={handleValueChange('local_ip')}
|
|
||||||
margin="normal"
|
|
||||||
/>
|
|
||||||
<TextValidator
|
|
||||||
validators={['required', 'isIP']}
|
|
||||||
errorMessages={['Gateway IP is required', 'Must be an IP address']}
|
|
||||||
name="gateway_ip"
|
|
||||||
label="Gateway"
|
|
||||||
className={classes.textField}
|
|
||||||
value={wifiSettings.gateway_ip}
|
|
||||||
onChange={handleValueChange('gateway_ip')}
|
|
||||||
margin="normal"
|
|
||||||
/>
|
|
||||||
<TextValidator
|
|
||||||
validators={['required', 'isIP']}
|
|
||||||
errorMessages={['Subnet mask is required', 'Must be an IP address']}
|
|
||||||
name="subnet_mask"
|
|
||||||
label="Subnet"
|
|
||||||
className={classes.textField}
|
|
||||||
value={wifiSettings.subnet_mask}
|
|
||||||
onChange={handleValueChange('subnet_mask')}
|
|
||||||
margin="normal"
|
|
||||||
/>
|
|
||||||
<TextValidator
|
|
||||||
validators={['isOptionalIP']}
|
|
||||||
errorMessages={['Must be an IP address']}
|
|
||||||
name="dns_ip_1"
|
|
||||||
label="DNS IP #1"
|
|
||||||
className={classes.textField}
|
|
||||||
value={wifiSettings.dns_ip_1}
|
|
||||||
onChange={handleValueChange('dns_ip_1')}
|
|
||||||
margin="normal"
|
|
||||||
/>
|
|
||||||
<TextValidator
|
|
||||||
validators={['isOptionalIP']}
|
|
||||||
errorMessages={['Must be an IP address']}
|
|
||||||
name="dns_ip_2"
|
|
||||||
label="DNS IP #2"
|
|
||||||
className={classes.textField}
|
|
||||||
value={wifiSettings.dns_ip_2}
|
|
||||||
onChange={handleValueChange('dns_ip_2')}
|
|
||||||
margin="normal"
|
|
||||||
/>
|
|
||||||
</Fragment>
|
|
||||||
}
|
|
||||||
|
|
||||||
<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>
|
{
|
||||||
|
!isNetworkOpen(selectedNetwork) &&
|
||||||
|
<PasswordValidator
|
||||||
|
validators={['matchRegexp:^.{0,64}$']}
|
||||||
|
errorMessages={['Password must be 64 characters or less']}
|
||||||
|
name="password"
|
||||||
|
label="Password"
|
||||||
|
className={classes.textField}
|
||||||
|
value={wifiSettings.password}
|
||||||
|
onChange={handleValueChange('password')}
|
||||||
|
margin="normal"
|
||||||
|
/>
|
||||||
|
}
|
||||||
|
<TextValidator
|
||||||
|
validators={['required', 'isHostname']}
|
||||||
|
errorMessages={['Hostname is required', "Not a valid hostname"]}
|
||||||
|
name="hostname"
|
||||||
|
label="Hostname"
|
||||||
|
className={classes.textField}
|
||||||
|
value={wifiSettings.hostname}
|
||||||
|
onChange={handleValueChange('hostname')}
|
||||||
|
margin="normal"
|
||||||
|
/>
|
||||||
|
<FormControlLabel className={classes.checkboxControl}
|
||||||
|
control={
|
||||||
|
<Checkbox
|
||||||
|
value="static_ip_config"
|
||||||
|
checked={wifiSettings.static_ip_config}
|
||||||
|
onChange={handleCheckboxChange("static_ip_config")}
|
||||||
|
/>
|
||||||
|
}
|
||||||
|
label="Static IP Config?"
|
||||||
|
/>
|
||||||
|
{
|
||||||
|
wifiSettings.static_ip_config &&
|
||||||
|
<Fragment>
|
||||||
|
<TextValidator
|
||||||
|
validators={['required', 'isIP']}
|
||||||
|
errorMessages={['Local IP is required', 'Must be an IP address']}
|
||||||
|
name="local_ip"
|
||||||
|
label="Local IP"
|
||||||
|
className={classes.textField}
|
||||||
|
value={wifiSettings.local_ip}
|
||||||
|
onChange={handleValueChange('local_ip')}
|
||||||
|
margin="normal"
|
||||||
|
/>
|
||||||
|
<TextValidator
|
||||||
|
validators={['required', 'isIP']}
|
||||||
|
errorMessages={['Gateway IP is required', 'Must be an IP address']}
|
||||||
|
name="gateway_ip"
|
||||||
|
label="Gateway"
|
||||||
|
className={classes.textField}
|
||||||
|
value={wifiSettings.gateway_ip}
|
||||||
|
onChange={handleValueChange('gateway_ip')}
|
||||||
|
margin="normal"
|
||||||
|
/>
|
||||||
|
<TextValidator
|
||||||
|
validators={['required', 'isIP']}
|
||||||
|
errorMessages={['Subnet mask is required', 'Must be an IP address']}
|
||||||
|
name="subnet_mask"
|
||||||
|
label="Subnet"
|
||||||
|
className={classes.textField}
|
||||||
|
value={wifiSettings.subnet_mask}
|
||||||
|
onChange={handleValueChange('subnet_mask')}
|
||||||
|
margin="normal"
|
||||||
|
/>
|
||||||
|
<TextValidator
|
||||||
|
validators={['isOptionalIP']}
|
||||||
|
errorMessages={['Must be an IP address']}
|
||||||
|
name="dns_ip_1"
|
||||||
|
label="DNS IP #1"
|
||||||
|
className={classes.textField}
|
||||||
|
value={wifiSettings.dns_ip_1}
|
||||||
|
onChange={handleValueChange('dns_ip_1')}
|
||||||
|
margin="normal"
|
||||||
|
/>
|
||||||
|
<TextValidator
|
||||||
|
validators={['isOptionalIP']}
|
||||||
|
errorMessages={['Must be an IP address']}
|
||||||
|
name="dns_ip_2"
|
||||||
|
label="DNS IP #2"
|
||||||
|
className={classes.textField}
|
||||||
|
value={wifiSettings.dns_ip_2}
|
||||||
|
onChange={handleValueChange('dns_ip_2')}
|
||||||
|
margin="normal"
|
||||||
|
/>
|
||||||
|
</Fragment>
|
||||||
|
}
|
||||||
|
<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>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
WiFiSettingsForm.propTypes = {
|
WiFiSettingsForm.propTypes = {
|
||||||
classes: PropTypes.object.isRequired,
|
classes: PropTypes.object.isRequired,
|
||||||
wifiSettingsFetched: PropTypes.bool.isRequired,
|
|
||||||
wifiSettings: PropTypes.object,
|
wifiSettings: PropTypes.object,
|
||||||
errorMessage: PropTypes.string,
|
|
||||||
deselectNetwork: PropTypes.func,
|
deselectNetwork: PropTypes.func,
|
||||||
selectedNetwork: PropTypes.object,
|
selectedNetwork: PropTypes.object,
|
||||||
onSubmit: PropTypes.func.isRequired,
|
onSubmit: PropTypes.func.isRequired,
|
||||||
|
Loading…
Reference in New Issue
Block a user