467 lines
13 KiB
JavaScript
467 lines
13 KiB
JavaScript
import {
|
|
Button,
|
|
Checkbox,
|
|
FormControlLabel,
|
|
FormGroup,
|
|
FormLabel,
|
|
Radio,
|
|
RadioGroup,
|
|
TextField
|
|
} from "@material-ui/core";
|
|
import React, { useEffect, useRef, useState } from "react";
|
|
import { Redirect } from "react-router";
|
|
import { useLocation } from "react-router-dom";
|
|
|
|
import { logger } from "../../../services/monitoring";
|
|
import { useStatusContext } from "../../Contexts/StatusContext";
|
|
import { useUserContext } from "../../Contexts/UserContext";
|
|
import {
|
|
useVehicleContext,
|
|
VehicleProvider
|
|
} from "../../Contexts/VehicleContext";
|
|
import useStyles from "../../useStyles";
|
|
|
|
|
|
const MainForm = () => {
|
|
const queries = new URLSearchParams(useLocation().search);
|
|
const vin = queries.get("vin") ?? "";
|
|
|
|
const { vehicle, getVehicle, updateVehicle, busy } = useVehicleContext();
|
|
const { token: { idToken: { jwtToken: token } } } = useUserContext();
|
|
const { setMessage, setTitle, setSitePath } = useStatusContext();
|
|
const [redirect, setRedirect] = useState(null);
|
|
const classes = useStyles();
|
|
|
|
const iccidEl = useRef(null);
|
|
const modelEl = useRef(null);
|
|
const yearEl = useRef(null);
|
|
const trimEl = useRef(null);
|
|
const countryEl = useRef(null);
|
|
const powertrainEl = useRef(null);
|
|
const restraintEl = useRef(null);
|
|
const bodyTypeEl = useRef(null);
|
|
const infoSourceEl = useRef(null);
|
|
const [selectedLogLevel, setSelectedLogLevel] = useState("info");
|
|
const [canbusEnabled, setCANBusEnabled] = useState(true);
|
|
const [dataLoggerEnabled, setDataLoggerEnabled] = useState(false);
|
|
const [maxMemBufferSize, setMaxMemBufferSize] = useState(0);
|
|
const [maxDiskBufferSize, setMaxDiskBufferSize] = useState(0);
|
|
const [dtcEnabled, setDTCEnabled] = useState(true);
|
|
const debugMaskEl = useRef(null);
|
|
const tagsEl = useRef(null);
|
|
|
|
const showDebugMask = (process.env.REACT_APP_ENABLE_DEBUGMASK === "1");
|
|
|
|
useEffect(() => {
|
|
setTitle("Update Vehicle");
|
|
setSitePath([
|
|
{
|
|
label: `Vehicle ${vin}`,
|
|
link: "/vehicles",
|
|
},
|
|
{
|
|
label: "Update Vehicle",
|
|
},
|
|
]);
|
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
}, []);
|
|
|
|
useEffect(() => {
|
|
(async () => {
|
|
try {
|
|
if (!vin || !token) return;
|
|
await getVehicle(vin, token);
|
|
} catch (e) {
|
|
setMessage(e.message);
|
|
logger.warn(e.stack);
|
|
}
|
|
})();
|
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
}, [token]);
|
|
|
|
useEffect(() => {
|
|
setSelectedLogLevel(vehicle.log_level ?? selectedLogLevel);
|
|
|
|
iccidEl.current.value = vehicle.iccid ?? ""
|
|
modelEl.current.value = vehicle.model ?? "Ocean"
|
|
yearEl.current.value = vehicle.year ?? "2022"
|
|
trimEl.current.value = vehicle.trim ?? "Base"
|
|
countryEl.current.value = vehicle.country ?? ""
|
|
powertrainEl.current.value = vehicle.powertrain ?? ""
|
|
restraintEl.current.value = vehicle.restraint ?? ""
|
|
bodyTypeEl.current.value = vehicle.body_type ?? ""
|
|
infoSourceEl.current.value = vehicle.info_source ?? ""
|
|
|
|
if (vehicle.canbus) {
|
|
setCANBusEnabled(vehicle.canbus.enabled ?? canbusEnabled);
|
|
setDataLoggerEnabled(vehicle.canbus.data_logger_enabled ?? dataLoggerEnabled);
|
|
setMaxMemBufferSize(vehicle.canbus.max_mem_buffer_size ?? maxMemBufferSize);
|
|
setMaxDiskBufferSize(vehicle.canbus.max_disk_buffer_size ?? maxDiskBufferSize);
|
|
setDTCEnabled(vehicle.canbus.dtc_enabled ?? dtcEnabled);
|
|
}
|
|
|
|
if (showDebugMask) {
|
|
debugMaskEl.current.value = vehicle.debug_mask ?? ""
|
|
}
|
|
|
|
tagsEl.current.value = vehicle.tags ?? ""
|
|
|
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
}, [vehicle]);
|
|
|
|
const onLogLevelChange = (event) => {
|
|
setSelectedLogLevel(event.target.value);
|
|
}
|
|
|
|
const onCANBusChange = (event) => {
|
|
setCANBusEnabled(event.target.checked);
|
|
}
|
|
|
|
const onDataLoggerChange = (event) => {
|
|
setDataLoggerEnabled(event.target.checked);
|
|
}
|
|
|
|
const onDtcEnabledChange = (event) => {
|
|
setDTCEnabled(event.target.checked);
|
|
}
|
|
|
|
const onMaxMemBufferSizeChange = (event) => {
|
|
setMaxMemBufferSize(event.target.value);
|
|
}
|
|
|
|
const onMaxDiskBufferSizeChange = (event) => {
|
|
setMaxDiskBufferSize(event.target.value);
|
|
}
|
|
|
|
const onSubmit = async (event) => {
|
|
try {
|
|
event.preventDefault();
|
|
|
|
const formData = {
|
|
vin: vin,
|
|
iccid: iccidEl.current.value,
|
|
model: modelEl.current.value,
|
|
year: parseInt(yearEl.current.value),
|
|
trim: trimEl.current.value,
|
|
country: countryEl.current.value,
|
|
powertrain: powertrainEl.current.value,
|
|
restraint: restraintEl.current.value,
|
|
body_type: bodyTypeEl.current.value,
|
|
log_level: selectedLogLevel,
|
|
tags: tagsEl.current.value.split(",").map(function (word) {
|
|
return word.trim();
|
|
}),
|
|
canbus: {
|
|
enabled: canbusEnabled,
|
|
data_logger_enabled: canbusEnabled ? dataLoggerEnabled : false,
|
|
max_mem_buffer_size: canbusEnabled ? parseInt(maxMemBufferSize) : 0,
|
|
max_disk_buffer_size: canbusEnabled && dataLoggerEnabled ? parseInt(maxDiskBufferSize) : 0,
|
|
dtc_enabled: dtcEnabled
|
|
},
|
|
debug_mask: debugMaskEl.current?.value
|
|
};
|
|
|
|
const result = await updateVehicle(vin, formData, token);
|
|
if (!result || result.error) return;
|
|
|
|
setMessage(`Updated ${result.vin}`);
|
|
setRedirect(`/vehicle-status/${result.vin}`);
|
|
} catch (e) {
|
|
setMessage(e.message);
|
|
logger.warn(e.stack);
|
|
}
|
|
};
|
|
|
|
if (redirect && redirect.length > 0) {
|
|
return <Redirect to={redirect} />;
|
|
}
|
|
|
|
return (
|
|
<div className={classes.paper}>
|
|
<form className={classes.form} noValidate action="{onSubmit}">
|
|
<TextField
|
|
id="vin"
|
|
name="vin"
|
|
label="VIN"
|
|
variant="outlined"
|
|
margin="normal"
|
|
inputProps={{
|
|
maxLength: "17",
|
|
readOnly: true,
|
|
}}
|
|
disabled
|
|
value={vin}
|
|
required
|
|
fullWidth
|
|
/>
|
|
<TextField
|
|
id="iccid"
|
|
name="iccid"
|
|
label="ICCID"
|
|
InputLabelProps={{
|
|
shrink: true
|
|
}}
|
|
defaultValue=""
|
|
variant="outlined"
|
|
margin="normal"
|
|
inputProps={{
|
|
maxLength: "50",
|
|
}}
|
|
fullWidth
|
|
inputRef={iccidEl}
|
|
/>
|
|
<TextField
|
|
id="model"
|
|
name="model"
|
|
label="Model"
|
|
defaultValue="Ocean"
|
|
variant="outlined"
|
|
margin="normal"
|
|
inputProps={{
|
|
maxLength: "255",
|
|
}}
|
|
required
|
|
fullWidth
|
|
inputRef={modelEl}
|
|
/>
|
|
<TextField
|
|
id="year"
|
|
name="year"
|
|
label="Year"
|
|
type="number"
|
|
defaultValue="2022"
|
|
variant="outlined"
|
|
margin="normal"
|
|
inputProps={{
|
|
maxLength: "4",
|
|
minLength: "4",
|
|
}}
|
|
required
|
|
fullWidth
|
|
inputRef={yearEl}
|
|
/>
|
|
<TextField
|
|
id="trim"
|
|
name="trim"
|
|
label="Trim"
|
|
defaultValue="Base"
|
|
variant="outlined"
|
|
margin="normal"
|
|
inputProps={{
|
|
maxLength: "4",
|
|
minLength: "4",
|
|
}}
|
|
required
|
|
fullWidth
|
|
inputRef={trimEl}
|
|
/>
|
|
<TextField
|
|
id="country"
|
|
name="country"
|
|
label="Country"
|
|
InputLabelProps={{
|
|
shrink: true
|
|
}}
|
|
defaultValue=""
|
|
variant="outlined"
|
|
margin="normal"
|
|
inputProps={{
|
|
shrink: +true,
|
|
maxLength: "256",
|
|
}}
|
|
fullWidth
|
|
inputRef={countryEl}
|
|
/>
|
|
<TextField
|
|
id="powertrain"
|
|
name="powertrain"
|
|
label="Powertrain Type"
|
|
InputLabelProps={{
|
|
shrink: true
|
|
}}
|
|
defaultValue=""
|
|
variant="outlined"
|
|
margin="normal"
|
|
inputProps={{
|
|
maxLength: "256",
|
|
}}
|
|
fullWidth
|
|
inputRef={powertrainEl}
|
|
/>
|
|
<TextField
|
|
id="restraint"
|
|
name="restraint"
|
|
label="Restraint Type"
|
|
InputLabelProps={{
|
|
shrink: true
|
|
}}
|
|
defaultValue=""
|
|
variant="outlined"
|
|
margin="normal"
|
|
inputProps={{
|
|
maxLength: "256",
|
|
}}
|
|
fullWidth
|
|
inputRef={restraintEl}
|
|
/>
|
|
<TextField
|
|
id="body_type"
|
|
name="body_type"
|
|
label="Body Type"
|
|
InputLabelProps={{
|
|
shrink: true
|
|
}}
|
|
defaultValue=""
|
|
variant="outlined"
|
|
margin="normal"
|
|
inputProps={{
|
|
maxLength: "256",
|
|
}}
|
|
fullWidth
|
|
inputRef={bodyTypeEl}
|
|
/>
|
|
<TextField
|
|
id="info_source"
|
|
name="info_source"
|
|
label="Info Source"
|
|
InputLabelProps={{
|
|
shrink: true
|
|
}}
|
|
inputProps={{
|
|
readOnly: true
|
|
}}
|
|
disabled
|
|
defaultValue=""
|
|
variant="outlined"
|
|
margin="normal"
|
|
fullWidth
|
|
inputRef={infoSourceEl}
|
|
/>
|
|
<TextField
|
|
id="tag"
|
|
name="tags"
|
|
label='Tags (comma separated, alphanumeric and - only)'
|
|
InputLabelProps={{
|
|
shrink: true
|
|
}}
|
|
defaultValue=""
|
|
variant="outlined"
|
|
margin="normal"
|
|
inputProps={{
|
|
maxLength: "1024",
|
|
}}
|
|
fullWidth
|
|
inputRef={tagsEl}
|
|
/>
|
|
<FormLabel id="demo-row-radio-buttons-group-label">Log Level</FormLabel>
|
|
<RadioGroup
|
|
row
|
|
aria-labelledby="demo-row-radio-buttons-group-label"
|
|
name="log-level-group"
|
|
value={selectedLogLevel}
|
|
onChange={onLogLevelChange}
|
|
margin="normal"
|
|
>
|
|
<FormControlLabel value="trace" control={<Radio />} label="Trace" />
|
|
<FormControlLabel value="debug" control={<Radio />} label="Debug" />
|
|
<FormControlLabel value="info" control={<Radio />} label="Info" />
|
|
<FormControlLabel value="warning" control={<Radio />} label="Warning" />
|
|
<FormControlLabel value="error" control={<Radio />} label="Error" />
|
|
<FormControlLabel value="critical" control={<Radio />} label="Critical" />
|
|
</RadioGroup>
|
|
<FormLabel id="demo-row-radio-buttons-group-label">CAN Bus</FormLabel>
|
|
<FormGroup>
|
|
<FormControlLabel control={
|
|
<Checkbox
|
|
checked={canbusEnabled}
|
|
onChange={onCANBusChange}
|
|
/>
|
|
} label="CAN Bus Enabled" />
|
|
<TextField
|
|
id="max_mem_buffer_size"
|
|
name="max_mem_buffer_size"
|
|
label='Max Memory Buffer Size (0 uses default size)'
|
|
value={maxMemBufferSize}
|
|
onChange={onMaxMemBufferSizeChange}
|
|
variant="outlined"
|
|
margin="normal"
|
|
inputProps={{
|
|
maxLength: "12",
|
|
}}
|
|
type="number"
|
|
disabled={!canbusEnabled}
|
|
required
|
|
fullWidth
|
|
/>
|
|
<FormControlLabel control={
|
|
<Checkbox
|
|
checked={dataLoggerEnabled}
|
|
onChange={onDataLoggerChange}
|
|
disabled={!canbusEnabled}
|
|
/>
|
|
} label="Data Logger Enabled" />
|
|
</FormGroup>
|
|
<TextField
|
|
id="max_disk_buffer_size"
|
|
name="max_disk_buffer_size"
|
|
label='Max Disk Buffer Size (0 uses default size)'
|
|
value={maxDiskBufferSize}
|
|
onChange={onMaxDiskBufferSizeChange}
|
|
variant="outlined"
|
|
margin="normal"
|
|
inputProps={{
|
|
maxLength: "12",
|
|
}}
|
|
type="number"
|
|
disabled={!dataLoggerEnabled}
|
|
required
|
|
fullWidth
|
|
/>
|
|
<FormControlLabel control={
|
|
<Checkbox
|
|
checked={dtcEnabled}
|
|
onChange={onDtcEnabledChange}
|
|
/>
|
|
} label="DTC Enabled" />
|
|
{showDebugMask && (
|
|
<TextField
|
|
id="debug_mask"
|
|
name="debug_mask"
|
|
label="Debug Mask"
|
|
InputLabelProps={{
|
|
shrink: true
|
|
}}
|
|
defaultValue=""
|
|
variant="outlined"
|
|
margin="normal"
|
|
inputProps={{
|
|
maxLength: "255",
|
|
}}
|
|
fullWidth
|
|
inputRef={debugMaskEl}
|
|
/>
|
|
)}
|
|
<Button
|
|
type="submit"
|
|
disabled={busy}
|
|
fullWidth
|
|
variant="contained"
|
|
color="primary"
|
|
className={classes.submit}
|
|
onClick={onSubmit}
|
|
>
|
|
Submit
|
|
</Button>
|
|
</form>
|
|
</div>
|
|
);
|
|
};
|
|
|
|
const VehicleUpdateForm = (props) => (
|
|
<VehicleProvider>
|
|
<MainForm {...props} />
|
|
</VehicleProvider>
|
|
);
|
|
|
|
export default VehicleUpdateForm;
|