Files
ota-admin-portal/src/components/CANSelfServe/SelfServe/index.jsx
Tristan Timblin 7eed1dd25c CEC-4455: Add GMT conversion (#345)
adds a checkbox to show time/date in GMT+0 regardless of the users timezone.
2023-06-02 11:07:12 -04:00

232 lines
8.0 KiB
JavaScript

import DateFnsUtils from '@date-io/date-fns';
import { Button, Checkbox, Chip, CircularProgress, FormControl, FormControlLabel, Grid, InputLabel, ListItemText, MenuItem, Select } from "@material-ui/core";
import { KeyboardDatePicker, KeyboardTimePicker, MuiPickersUtilsProvider } from '@material-ui/pickers';
import React, { useEffect, useState } from "react";
import { logger } from "../../../services/monitoring";
import { CANSignalsExportProvider, useCANSignalsExportContext } from "../../Contexts/CANSignalsExportContext";
import { useStatusContext } from "../../Contexts/StatusContext";
import { useUserContext } from "../../Contexts/UserContext";
import useStyles from "../../useStyles";
const MainForm = ({ id }) => {
const classes = useStyles();
const { setMessage } = useStatusContext();
const { busy, canSignals, getCANSignalList, getDynamicColumnCANSignals } = useCANSignalsExportContext();
const [selectedStartDate, setSelectedStartDate] = useState(new Date(Date.now() - 24 * 60 * 60 * 1000));
const [selectedEndDate, setSelectedEndDate] = useState(new Date());
const [selectedCanSignals, setSelectedCanSignals] = useState([]);
const [selectAllCanSignals, setSelectAllCanSignals] = useState(false);
const [gmtTimezone, setGmtTimezone] = useState(false);
const {
token: {
idToken: { jwtToken: token },
},
} = useUserContext();
const handleSubmit = async (event) => {
event.preventDefault();
let timestamp_start = Date.parse(selectedStartDate.toUTCString()) / 1000
let timestamp_end = Date.parse(selectedEndDate.toUTCString()) / 1000
try {
await getDynamicColumnCANSignals(id, timestamp_start, timestamp_end, selectedCanSignals, selectAllCanSignals, token)
} catch (e) {
setMessage(e.message);
logger.error(e.stack)
}
};
const isSubmitDisabled = !selectedStartDate || !selectedEndDate || selectedCanSignals.length === 0;
useEffect(() => {
(async () => {
try {
if (!token) return;
await getCANSignalList(token);
} catch (e) {
setMessage(e.message);
logger.warn(e.stack);
}
})();
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [token]);
const handleDateChange = (value, dateType) => {
const newDate = new Date(value);
const oldDate = dateType === "start" ? selectedStartDate || new Date() : selectedEndDate || new Date();
newDate.setHours(oldDate.getHours());
newDate.setMinutes(oldDate.getMinutes());
newDate.setSeconds(oldDate.getSeconds());
if (dateType === "start") {
setSelectedStartDate(newDate);
} else {
setSelectedEndDate(newDate);
}
};
const handleTimeFromChange = (value) => {
setSelectedStartDate(value);
};
const handleTimeToChange = (value) => {
setSelectedEndDate(value);
};
const handleSelectedItemsChange = (event) => {
const { value } = event.target;
if (value.some(item => item === "Select All")) {
setSelectAllCanSignals(true);
if (selectedCanSignals.length === canSignals.length) {
setSelectedCanSignals([]);
} else {
setSelectedCanSignals(canSignals.map(signal => signal.signal_name));
}
} else {
setSelectAllCanSignals(false);
setSelectedCanSignals(value);
}
};
const displayTimeAsGMT = (date) => {
return gmtTimezone
? date.toLocaleString("en-US", {timeZone: "Etc/GMT"})
: date;
}
return (
<div className={classes.paper}>
<Grid container spacing={3} justifyContent="center">
<Grid item xs={12}>
<MuiPickersUtilsProvider utils={DateFnsUtils}>
<Grid container justifyContent="space-between">
<Grid item xs={6} md={3}>
<KeyboardDatePicker
required
disableToolbar
variant="inline"
format="MM/dd/yyyy"
margin="normal"
id="date-picker-inline"
label="Date From"
value={displayTimeAsGMT(selectedStartDate)}
onChange={(value) => handleDateChange(value, "start")}
KeyboardButtonProps={{
'aria-label': 'change date',
}}
/>
</Grid>
<Grid item xs={6} md={3}>
<KeyboardTimePicker
required
margin="normal"
variant="inline"
id="time-picker"
label="Time From"
value={displayTimeAsGMT(selectedStartDate)}
onChange={handleTimeFromChange}
KeyboardButtonProps={{
'aria-label': 'change time',
}}
/>
</Grid>
<Grid item xs={6} md={3}>
<KeyboardDatePicker
required
disableToolbar
variant="inline"
format="MM/dd/yyyy"
margin="normal"
id="date-picker-inline"
label="Date To"
value={displayTimeAsGMT(selectedEndDate)}
onChange={(value) => handleDateChange(value, "end")}
KeyboardButtonProps={{
'aria-label': 'change date',
}}
/>
</Grid>
<Grid item xs={6} md={3}>
<KeyboardTimePicker
required
margin="normal"
id="time-picker"
variant="inline"
label="Time To"
value={displayTimeAsGMT(selectedEndDate)}
onChange={handleTimeToChange}
KeyboardButtonProps={{
'aria-label': 'change time',
}}
/>
</Grid>
<Grid item xs={6} md={3}>
<FormControlLabel
label="GMT"
control={
<Checkbox
checked={gmtTimezone}
onChange={() => setGmtTimezone((current) => !current)}
/>
}
/>
</Grid>
</Grid>
</MuiPickersUtilsProvider>
</Grid>
<Grid item xs={12}>
<FormControl fullWidth required>
<InputLabel id="select-can-signals-label">Select CAN signals</InputLabel>
<Select
labelId="select-can-signals-label"
id="select-can-signals"
multiple
value={selectedCanSignals}
onChange={handleSelectedItemsChange}
fullWidth
inputvariant="outlined"
renderValue={(selected) => (
<div className={classes.chips}>
{selected.map((value) => (
<Chip key={value} label={value} className={classes.chip} />
))}
</div>
)}
>
<MenuItem value="Select All">
<Checkbox checked={selectedCanSignals.length === canSignals.length} />
<ListItemText primary="Select All" />
</MenuItem>
{canSignals.map((signal) => (
<MenuItem key={signal.signal_name} value={signal.signal_name}>
<Checkbox checked={selectedCanSignals.indexOf(signal.signal_name) > -1} />
<ListItemText primary={signal.signal_name} />
</MenuItem>
))}
</Select>
</FormControl>
</Grid>
<Grid item xs={12}>
<Button
variant="contained"
color="primary"
onClick={handleSubmit}
disabled={isSubmitDisabled || busy}
fullWidth
>
{busy ? <CircularProgress size={24} /> : "Submit"}
</Button>
</Grid>
</Grid>
</div>
);
};
const CANSignalExport = (props) => (
<CANSignalsExportProvider>
<MainForm {...props} />
</CANSignalsExportProvider>
);
export default CANSignalExport;