2020-02-09 10:21:13 +00:00
|
|
|
import React, { Component, Fragment } from 'react';
|
|
|
|
|
|
|
|
import { WithTheme, withTheme } from '@material-ui/core/styles';
|
2020-06-16 22:24:15 +01:00
|
|
|
import { Avatar, Divider, List, ListItem, ListItemAvatar, ListItemText, Button } from '@material-ui/core';
|
|
|
|
import { Dialog, DialogTitle, DialogContent, DialogActions, Box, TextField } from '@material-ui/core';
|
2020-02-09 10:21:13 +00:00
|
|
|
|
|
|
|
import SwapVerticalCircleIcon from '@material-ui/icons/SwapVerticalCircle';
|
|
|
|
import AccessTimeIcon from '@material-ui/icons/AccessTime';
|
|
|
|
import DNSIcon from '@material-ui/icons/Dns';
|
|
|
|
import UpdateIcon from '@material-ui/icons/Update';
|
|
|
|
import AvTimerIcon from '@material-ui/icons/AvTimer';
|
|
|
|
import RefreshIcon from '@material-ui/icons/Refresh';
|
|
|
|
|
2020-06-16 22:24:15 +01:00
|
|
|
import { RestFormProps, FormButton, HighlightAvatar } from '../components';
|
2020-02-09 10:21:13 +00:00
|
|
|
import { isNtpActive, ntpStatusHighlight, ntpStatus } from './NTPStatus';
|
2021-01-29 23:42:00 +00:00
|
|
|
import { formatDuration, formatDateTime, formatLocalDateTime } from './TimeFormat';
|
2020-06-16 22:24:15 +01:00
|
|
|
import { NTPStatus, Time } from './types';
|
|
|
|
import { redirectingAuthorizedFetch, withAuthenticatedContext, AuthenticatedContextProps } from '../authentication';
|
|
|
|
import { TIME_ENDPOINT } from '../api';
|
|
|
|
|
|
|
|
type NTPStatusFormProps = RestFormProps<NTPStatus> & WithTheme & AuthenticatedContextProps;
|
2020-02-09 10:21:13 +00:00
|
|
|
|
2020-06-16 22:24:15 +01:00
|
|
|
interface NTPStatusFormState {
|
|
|
|
settingTime: boolean;
|
|
|
|
localTime: string;
|
|
|
|
processing: boolean;
|
|
|
|
}
|
2020-02-09 10:21:13 +00:00
|
|
|
|
2020-06-16 22:24:15 +01:00
|
|
|
class NTPStatusForm extends Component<NTPStatusFormProps, NTPStatusFormState> {
|
|
|
|
|
|
|
|
constructor(props: NTPStatusFormProps) {
|
|
|
|
super(props);
|
|
|
|
this.state = {
|
|
|
|
settingTime: false,
|
|
|
|
localTime: '',
|
|
|
|
processing: false
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
updateLocalTime = (event: React.ChangeEvent<HTMLInputElement>) => {
|
2021-01-29 23:42:00 +00:00
|
|
|
this.setState({
|
|
|
|
localTime: event.target.value
|
|
|
|
});
|
2020-06-16 22:24:15 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
openSetTime = () => {
|
2021-01-29 23:42:00 +00:00
|
|
|
this.setState({
|
|
|
|
localTime: formatLocalDateTime(new Date()),
|
|
|
|
settingTime: true
|
|
|
|
});
|
2020-06-16 22:24:15 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
closeSetTime = () => {
|
2021-01-29 23:42:00 +00:00
|
|
|
this.setState({
|
|
|
|
settingTime: false
|
|
|
|
});
|
2020-06-16 22:24:15 +01:00
|
|
|
}
|
|
|
|
|
2021-01-29 23:42:00 +00:00
|
|
|
createTime = (): Time => ({
|
|
|
|
local_time: formatLocalDateTime(new Date(this.state.localTime))
|
|
|
|
});
|
2020-06-16 22:24:15 +01:00
|
|
|
|
|
|
|
configureTime = () => {
|
|
|
|
this.setState({ processing: true });
|
|
|
|
redirectingAuthorizedFetch(TIME_ENDPOINT,
|
|
|
|
{
|
|
|
|
method: 'POST',
|
2021-01-29 23:42:00 +00:00
|
|
|
body: JSON.stringify(this.createTime()),
|
2020-06-16 22:24:15 +01:00
|
|
|
headers: {
|
|
|
|
'Content-Type': 'application/json'
|
|
|
|
}
|
|
|
|
})
|
|
|
|
.then(response => {
|
|
|
|
if (response.status === 200) {
|
|
|
|
this.props.enqueueSnackbar("Time set successfully", { variant: 'success' });
|
|
|
|
this.setState({ processing: false, settingTime: false }, this.props.loadData);
|
|
|
|
} else {
|
|
|
|
throw Error("Error setting time, status code: " + response.status);
|
|
|
|
}
|
|
|
|
})
|
|
|
|
.catch(error => {
|
|
|
|
this.props.enqueueSnackbar(error.message || "Problem setting the time", { variant: 'error' });
|
|
|
|
this.setState({ processing: false, settingTime: false });
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
renderSetTimeDialog() {
|
|
|
|
return (
|
|
|
|
<Dialog
|
|
|
|
open={this.state.settingTime}
|
|
|
|
onClose={this.closeSetTime}
|
|
|
|
>
|
|
|
|
<DialogTitle>Set Time</DialogTitle>
|
|
|
|
<DialogContent dividers>
|
|
|
|
<Box mb={2}>Enter local date and time below to set the device's time.</Box>
|
|
|
|
<TextField
|
|
|
|
label="Local Time"
|
|
|
|
type="datetime-local"
|
|
|
|
value={this.state.localTime}
|
|
|
|
onChange={this.updateLocalTime}
|
|
|
|
disabled={this.state.processing}
|
|
|
|
variant="outlined"
|
|
|
|
fullWidth
|
|
|
|
InputLabelProps={{
|
|
|
|
shrink: true,
|
|
|
|
}}
|
|
|
|
/>
|
|
|
|
</DialogContent>
|
|
|
|
<DialogActions>
|
|
|
|
<Button variant="contained" onClick={this.closeSetTime} color="secondary">
|
|
|
|
Cancel
|
|
|
|
</Button>
|
|
|
|
<Button startIcon={<AccessTimeIcon />} variant="contained" onClick={this.configureTime} disabled={this.state.processing} color="primary" autoFocus>
|
|
|
|
Set Time
|
|
|
|
</Button>
|
|
|
|
</DialogActions>
|
|
|
|
</Dialog>
|
|
|
|
)
|
|
|
|
}
|
2020-02-09 10:21:13 +00:00
|
|
|
|
|
|
|
render() {
|
|
|
|
const { data, theme } = this.props
|
2020-06-16 22:24:15 +01:00
|
|
|
const me = this.props.authenticatedContext.me;
|
2020-02-09 10:21:13 +00:00
|
|
|
return (
|
|
|
|
<Fragment>
|
|
|
|
<List>
|
|
|
|
<ListItem>
|
|
|
|
<ListItemAvatar>
|
|
|
|
<HighlightAvatar color={ntpStatusHighlight(data, theme)}>
|
|
|
|
<UpdateIcon />
|
|
|
|
</HighlightAvatar>
|
|
|
|
</ListItemAvatar>
|
|
|
|
<ListItemText primary="Status" secondary={ntpStatus(data)} />
|
|
|
|
</ListItem>
|
|
|
|
<Divider variant="inset" component="li" />
|
|
|
|
{isNtpActive(data) && (
|
|
|
|
<Fragment>
|
|
|
|
<ListItem>
|
|
|
|
<ListItemAvatar>
|
|
|
|
<Avatar>
|
2020-06-16 22:24:15 +01:00
|
|
|
<DNSIcon />
|
2020-02-09 10:21:13 +00:00
|
|
|
</Avatar>
|
|
|
|
</ListItemAvatar>
|
2020-06-16 22:24:15 +01:00
|
|
|
<ListItemText primary="NTP Server" secondary={data.server} />
|
2020-02-09 10:21:13 +00:00
|
|
|
</ListItem>
|
|
|
|
<Divider variant="inset" component="li" />
|
|
|
|
</Fragment>
|
|
|
|
)}
|
|
|
|
<ListItem>
|
|
|
|
<ListItemAvatar>
|
|
|
|
<Avatar>
|
2020-06-16 22:24:15 +01:00
|
|
|
<AccessTimeIcon />
|
2020-02-09 10:21:13 +00:00
|
|
|
</Avatar>
|
|
|
|
</ListItemAvatar>
|
2021-01-29 23:42:00 +00:00
|
|
|
<ListItemText primary="Local Time" secondary={formatDateTime(data.local_time)} />
|
2020-06-16 22:24:15 +01:00
|
|
|
</ListItem>
|
|
|
|
<Divider variant="inset" component="li" />
|
|
|
|
<ListItem>
|
|
|
|
<ListItemAvatar>
|
|
|
|
<Avatar>
|
|
|
|
<SwapVerticalCircleIcon />
|
|
|
|
</Avatar>
|
|
|
|
</ListItemAvatar>
|
2021-01-29 23:42:00 +00:00
|
|
|
<ListItemText primary="UTC Time" secondary={formatDateTime(data.utc_time)} />
|
2020-02-09 10:21:13 +00:00
|
|
|
</ListItem>
|
|
|
|
<Divider variant="inset" component="li" />
|
|
|
|
<ListItem>
|
|
|
|
<ListItemAvatar>
|
|
|
|
<Avatar>
|
|
|
|
<AvTimerIcon />
|
|
|
|
</Avatar>
|
|
|
|
</ListItemAvatar>
|
2021-01-29 23:42:00 +00:00
|
|
|
<ListItemText primary="Uptime" secondary={formatDuration(data.uptime)} />
|
2020-02-09 10:21:13 +00:00
|
|
|
</ListItem>
|
|
|
|
<Divider variant="inset" component="li" />
|
|
|
|
</List>
|
2020-06-16 22:24:15 +01:00
|
|
|
<Box display="flex" flexWrap="wrap">
|
|
|
|
<Box flexGrow={1} padding={1}>
|
|
|
|
<FormButton startIcon={<RefreshIcon />} variant="contained" color="secondary" onClick={this.props.loadData}>
|
|
|
|
Refresh
|
|
|
|
</FormButton>
|
|
|
|
</Box>
|
|
|
|
{me.admin && !isNtpActive(data) && (
|
|
|
|
<Box flexWrap="none" padding={1} whiteSpace="nowrap">
|
|
|
|
<Button onClick={this.openSetTime} variant="contained" color="primary" startIcon={<AccessTimeIcon />}>
|
|
|
|
Set Time
|
|
|
|
</Button>
|
|
|
|
</Box>
|
|
|
|
)}
|
|
|
|
</Box>
|
|
|
|
{this.renderSetTimeDialog()}
|
2020-02-09 10:21:13 +00:00
|
|
|
</Fragment>
|
|
|
|
);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-06-16 22:24:15 +01:00
|
|
|
export default withAuthenticatedContext(withTheme(NTPStatusForm));
|