Merge branch 'develop' into release/0.0.3

This commit is contained in:
jwu-fisker
2022-09-28 20:12:23 -07:00
11 changed files with 231 additions and 104 deletions

View File

@@ -3329,7 +3329,6 @@ exports[`App Route /packages authenticated 1`] = `
/> />
</svg> </svg>
</a> </a>
<div />
</div> </div>
</td> </td>
</tr> </tr>
@@ -3460,6 +3459,7 @@ exports[`App Route /packages authenticated 1`] = `
</tr> </tr>
</tfoot> </tfoot>
</table> </table>
<div />
</div> </div>
</div> </div>
</main> </main>

View File

@@ -76,10 +76,11 @@ export const CarUpdatesProvider = ({ children }) => {
result = await api.getCarUpdates(search, token); result = await api.getCarUpdates(search, token);
if (result.error) if (result.error)
throw new Error(`Get car updates error. ${result.message}`); throw new Error(`Get car updates error. ${result.message}`);
result.data.forEach((item) => { result.data.forEach((item, i) => {
item.progress = 0;
item.msg = item.status; item.msg = item.status;
applyProgressStatus(item, item); item.progress = 0;
applyProgressStatus(item);
result.data[i] = Object.assign(result.data[i], item);
}); });
setCarUpdates(result.data); setCarUpdates(result.data);
if (search && search.offset === 0 && result.total) { if (search && search.offset === 0 && result.total) {
@@ -119,28 +120,27 @@ export const CarUpdatesProvider = ({ children }) => {
return 0; return 0;
}; };
const applyProgressStatus = (item, status) => { const applyProgressStatus = (item) => {
if (validateStatusMessage(status)) { if (validateStatusMessage(item)) {
if (status.msg === "downloading") { if (item.msg === "downloading") {
item.progress = getDownloadProgress(status); item.progress = getDownloadProgress(item);
item.status = `${item.ecu || ""} downloading ${item.progress}%`.trim(); item.status = `${item.ecu || ""} downloading ${item.progress}%`.trim();
return; return;
} else if (status.msg === "package_download_complete") { } else if (item.msg === "package_download_complete") {
item.progress = 100; item.progress = 100;
item.status = "download complete"; item.status = `${item.ecu || ""} download complete`.trim();
return; return;
} else if (status.msg === "installing") { } else if (item.msg === "installing") {
item.progress = getInstallProgress(status); item.progress = getInstallProgress(item);
item.status = `${item.ecu || ""} installing ${item.progress}%`.trim(); item.status = `${item.ecu || ""} installing ${item.progress}%`.trim();
return; return;
} else if (status.msg === "package_install_complete") { } else if (item.msg === "package_install_complete") {
item.progress = 100; item.progress = 100;
item.status = "install complete"; item.status = `${item.ecu || ""} install complete`.trim();
return; return;
} }
} }
delete item.progress; delete item.progress;
item.status = status.msg;
}; };
const applyProgressStatuses = (statuses) => { const applyProgressStatuses = (statuses) => {

View File

@@ -45,6 +45,7 @@ export const VehicleProvider = ({ children }) => {
} }
cars.forEach((car) => { cars.forEach((car) => {
car.connected = result[car.vin] || false; car.connected = result[car.vin] || false;
car.connectedHMI = result[`2:${car.vin}`] || false;
}); });
} catch (e) { } catch (e) {
logger.error(e.stack); logger.error(e.stack);

View File

@@ -13,7 +13,7 @@ import { StatusProvider, useStatusContext } from "./StatusContext";
const checkVehicleResult = (error, busy, vehicle) => { const checkVehicleResult = (error, busy, vehicle) => {
checkBaseResults(error, busy); checkBaseResults(error, busy);
expect(screen.getByTestId("vehicle").innerHTML).toEqual(vehicle); expect(screen.getByTestId("vehicle").innerHTML).toEqual(vehicle);
} };
const checkVehiclesResult = (error, busy, vehicles) => { const checkVehiclesResult = (error, busy, vehicles) => {
checkBaseResults(error, busy); checkBaseResults(error, busy);
@@ -195,12 +195,22 @@ describe("VehicleContext", () => {
<> <>
<div data-testid="error">{message}</div> <div data-testid="error">{message}</div>
<div data-testid="busy">{busy.toString()}</div> <div data-testid="busy">{busy.toString()}</div>
<button data-testid="updateVehicleNull" onClick={() => update(null)} /> <button
<button data-testid="updateVehicleNoVIN" onClick={() => update({})} /> data-testid="updateVehicleNull"
onClick={() => update(null)}
/>
<button
data-testid="updateVehicleNoVIN"
onClick={() => update({})}
/>
<button <button
data-testid="updateVehicle" data-testid="updateVehicle"
onClick={() => onClick={() =>
update({ vin: "3C4PDCBG0ET127145", log_level: "warn", canbus: { enabled: false } }) update({
vin: "3C4PDCBG0ET127145",
log_level: "warn",
canbus: { enabled: false },
})
} }
/> />
</> </>
@@ -265,13 +275,17 @@ describe("VehicleContext", () => {
<> <>
<div data-testid="error">{message}</div> <div data-testid="error">{message}</div>
<div data-testid="busy">{busy.toString()}</div> <div data-testid="busy">{busy.toString()}</div>
<button data-testid="deleteVehicleNull" onClick={() => deleteV(null)} /> <button
<button data-testid="deleteVehicleNonexistent" onClick={() => deleteV("11111111111111111")} /> data-testid="deleteVehicleNull"
onClick={() => deleteV(null)}
/>
<button
data-testid="deleteVehicleNonexistent"
onClick={() => deleteV("11111111111111111")}
/>
<button <button
data-testid="deleteVehicle" data-testid="deleteVehicle"
onClick={() => onClick={() => deleteV("3C4PDCBG0ET127145")}
deleteV("3C4PDCBG0ET127145")
}
/> />
</> </>
); );
@@ -336,18 +350,31 @@ describe("VehicleContext", () => {
<> <>
<div data-testid="error">{message}</div> <div data-testid="error">{message}</div>
<div data-testid="busy">{busy.toString()}</div> <div data-testid="busy">{busy.toString()}</div>
<button data-testid="sendCommandNullVin" onClick={() => sendC(null, {command:"doors_lock"})} /> <button
<button data-testid="sendCommandNonexistentVin" onClick={() => sendC(["11111111111111111"], {command:"doors_lock"})} /> data-testid="sendCommandNullVin"
onClick={() => sendC(null, { command: "doors_lock" })}
/>
<button
data-testid="sendCommandNonexistentVin"
onClick={() =>
sendC(["11111111111111111"], { command: "doors_lock" })
}
/>
<button <button
data-testid="sendCommandVin" data-testid="sendCommandVin"
onClick={() => sendC("3C4PDCBG0ET127145", {command:"doors_lock"})} onClick={() =>
sendC("3C4PDCBG0ET127145", { command: "doors_lock" })
}
/> />
<button <button
data-testid="sendCommandWrongCommand" data-testid="sendCommandWrongCommand"
onClick={() => sendC("3C4PDCBG0ET127145", {command:"noSuchCommand"})} onClick={() =>
sendC("3C4PDCBG0ET127145", { command: "noSuchCommand" })
}
/> />
</> </>
);} );
};
render( render(
<StatusProvider> <StatusProvider>
<VehicleProvider> <VehicleProvider>
@@ -364,24 +391,23 @@ describe("VehicleContext", () => {
it("initial state", () => { it("initial state", () => {
checkBaseResults("", "false"); checkBaseResults("", "false");
}); });
});
})
}); });
const expectedFilters = [ const expectedFilters = [
{ {
can_id: "123-456", can_id: "123-456",
interval: 789 interval: 789,
}, },
{ {
can_id: "1", can_id: "1",
interval: 1000 interval: 1000,
}, },
{ {
can_id: "1000", can_id: "1000",
interval: 1 interval: 1,
} },
] ];
const expectedVehicleData = { const expectedVehicleData = {
vin: "3C4PDCBG0ET127145", vin: "3C4PDCBG0ET127145",
@@ -390,9 +416,16 @@ const expectedVehicleData = {
trim: "Basic", trim: "Basic",
ecu_list: "ECUA 2.0.0, ECUB 2.1.1", ecu_list: "ECUA 2.0.0, ECUB 2.1.1",
log_level: "info", log_level: "info",
canbus: { enabled: true, data_logger_enabled: true, max_mem_buffer_size: 1, max_disk_buffer_size: 2, filters: expectedFilters }, canbus: {
enabled: true,
data_logger_enabled: true,
max_mem_buffer_size: 1,
max_disk_buffer_size: 2,
filters: expectedFilters,
},
connected: true, connected: true,
} connectedHMI: false,
};
const expectedVehiclesData = [ const expectedVehiclesData = [
{ {
@@ -402,19 +435,44 @@ const expectedVehiclesData = [
trim: "Basic", trim: "Basic",
ecu_list: "ECUA 2.0.0, ECUB 2.1.1", ecu_list: "ECUA 2.0.0, ECUB 2.1.1",
log_level: "info", log_level: "info",
canbus: { enabled: true, data_logger_enabled: true, max_mem_buffer_size: 1, max_disk_buffer_size: 2, filters: expectedFilters }, canbus: {
connected: true, enabled: true,
data_logger_enabled: true,
max_mem_buffer_size: 1,
max_disk_buffer_size: 2,
filters: expectedFilters,
},
connected: true,
connectedHMI: false,
},
{ vin: "1G1FP87S3GN100062", connected: true, connectedHMI: false },
{
vin: "1HGCG325XYA062256",
year: 2021,
connected: true,
connectedHMI: false,
},
{
vin: "1J4GZ78YXWC160024",
year: 2021,
model: "Ocean",
connected: true,
connectedHMI: false,
},
{
vin: "2C3CCAAG8CH222800",
model: "Ocean",
trim: "Basic",
connected: true,
connectedHMI: false,
}, },
{ vin: "1G1FP87S3GN100062", connected: true },
{ vin: "1HGCG325XYA062256", year: 2021, connected: true },
{ vin: "1J4GZ78YXWC160024", year: 2021, model: "Ocean", connected: true },
{ vin: "2C3CCAAG8CH222800", model: "Ocean", trim: "Basic", connected: true },
{ {
vin: "KNADM4A39C6028108", vin: "KNADM4A39C6028108",
year: 2021, year: 2021,
model: "Ocean", model: "Ocean",
trim: "Basic", trim: "Basic",
connected: true, connected: true,
connectedHMI: false,
}, },
{ {
vin: "1G11C5SL9FF153507", vin: "1G11C5SL9FF153507",
@@ -422,5 +480,6 @@ const expectedVehiclesData = [
model: "Ocean", model: "Ocean",
trim: "Basic", trim: "Basic",
connected: true, connected: true,
connectedHMI: false,
}, },
]; ];

View File

@@ -163,7 +163,8 @@ const CarSelectionTable = (props) => {
<TableCell align="center"> <TableCell align="center">
<ConnectedIcon <ConnectedIcon
connected={row.connected} connected={row.connected}
style={{ marginRight: 5 }} connectedHMI={row.connectedHMI}
style={{ marginRight: 3 }}
/> />
<Link to={`/vehicle-status/${row.vin}`}>{row.vin}</Link> <Link to={`/vehicle-status/${row.vin}`}>{row.vin}</Link>
{row.ecu_list && ( {row.ecu_list && (

View File

@@ -1,5 +1,6 @@
import React, { useEffect, useState } from "react"; import React, { useEffect, useState } from "react";
import { import {
LinearProgress,
Table, Table,
TableBody, TableBody,
TableCell, TableCell,
@@ -57,14 +58,21 @@ const MainForm = ({ vin, token }) => {
const [pageIndex, setPageIndex] = useState(0); const [pageIndex, setPageIndex] = useState(0);
const [orderBy, setOrderBy] = useState("id"); const [orderBy, setOrderBy] = useState("id");
const [order, setOrder] = useState("desc"); const [order, setOrder] = useState("desc");
const { cancelUpdate, getCarUpdates, carUpdates, totalCarUpdates } = const {
useCarUpdatesContext(); cancelUpdate,
getCarUpdates,
carUpdates,
totalCarUpdates,
startMonitor,
stopMonitor,
} = useCarUpdatesContext();
const { setMessage } = useStatusContext(); const { setMessage } = useStatusContext();
useEffect(() => { useEffect(() => {
(async () => { (async () => {
try { try {
if (!vin || !token) return; if (!vin || !token) return;
stopMonitor();
await getCarUpdates( await getCarUpdates(
{ {
vin, vin,
@@ -82,6 +90,20 @@ const MainForm = ({ vin, token }) => {
// eslint-disable-next-line react-hooks/exhaustive-deps // eslint-disable-next-line react-hooks/exhaustive-deps
}, [vin, token, pageIndex, pageSize, orderBy, order]); }, [vin, token, pageIndex, pageSize, orderBy, order]);
useEffect(() => {
try {
if (carUpdates.length === 0) return;
startMonitor(token);
} catch (e) {
setMessage(e.message);
logger.warn(e.stack);
}
return () => {
stopMonitor();
};
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [carUpdates]);
const handleChangePageIndex = (event, newIndex) => { const handleChangePageIndex = (event, newIndex) => {
setPageIndex(newIndex); setPageIndex(newIndex);
}; };
@@ -141,7 +163,12 @@ const MainForm = ({ vin, token }) => {
{updateName(row)} {updateName(row)}
</Link> </Link>
</TableCell> </TableCell>
<TableCell align="center">{row.status}</TableCell> <TableCell align="center">
{row.status}
{row.progress > -1 && (
<LinearProgress variant="determinate" value={row.progress} />
)}
</TableCell>
<TableCell align="center"> <TableCell align="center">
{LocalDateTimeString(row.created)} {LocalDateTimeString(row.created)}
</TableCell> </TableCell>

View File

@@ -1,12 +1,27 @@
import React from "react"; import React from "react";
import PropTypes from "prop-types"; import PropTypes from "prop-types";
import CheckCircleIcon from "@material-ui/icons/CheckCircle"; import CheckCircleIcon from "@material-ui/icons/CheckCircle";
import CheckBoxIcon from "@material-ui/icons/CheckBox";
import { Tooltip } from "@material-ui/core";
const ConnectedIcon = (props) => { const ConnectedIcon = (props) => {
if (props.connected) { if (props.connected || props.connectedHMI) {
return ( return (
<span style={props.style}> <span style={props.style}>
<CheckCircleIcon style={{ color: "Green", fontSize: 12 }} /> {props.connected && (
<Tooltip title="TBOX">
<CheckCircleIcon
style={{ color: "Green", fontSize: 12, marginRight: 3 }}
/>
</Tooltip>
)}
{props.connectedHMI && (
<Tooltip title="ICC">
<CheckBoxIcon
style={{ color: "Blue", fontSize: 12, marginRight: 3 }}
/>
</Tooltip>
)}
</span> </span>
); );
} }

View File

@@ -9,30 +9,30 @@ import {
FormLabel, FormLabel,
Radio, Radio,
RadioGroup, RadioGroup,
TextField TextField,
} from "@material-ui/core"; } from "@material-ui/core";
import useStyles from "../../useStyles"; import useStyles from "../../useStyles";
import { import { useFleetContext, FleetProvider } from "../../Contexts/FleetContext";
useFleetContext,
FleetProvider
} from "../../Contexts/FleetContext";
import { useStatusContext } from "../../Contexts/StatusContext"; import { useStatusContext } from "../../Contexts/StatusContext";
import { useUserContext } from "../../Contexts/UserContext"; import { useUserContext } from "../../Contexts/UserContext";
import { logger } from "../../../services/monitoring"; import { logger } from "../../../services/monitoring";
const MainForm = () => { const MainForm = () => {
const queries = new URLSearchParams(useLocation().search); const queries = new URLSearchParams(useLocation().search);
const { fleet, getFleet, updateFleet, busy } = useFleetContext(); const { fleet, getFleet, updateFleet, busy } = useFleetContext();
const { token: { idToken: { jwtToken: token } } } = useUserContext(); const {
token: {
idToken: { jwtToken: token },
},
} = useUserContext();
const { setMessage, setTitle, setSitePath } = useStatusContext(); const { setMessage, setTitle, setSitePath } = useStatusContext();
const [redirect, setRedirect] = useState(null); const [redirect, setRedirect] = useState(null);
const classes = useStyles(); const classes = useStyles();
const [name, setName] = useState(queries.get("name") ?? ""); const [name, setName] = useState(queries.get("name") ?? "");
const [oldName, ] = useState(name); const [oldName] = useState(name);
const [selectedLogLevel, setSelectedLogLevel] = useState("info"); const [selectedLogLevel, setSelectedLogLevel] = useState("info");
const [canbusEnabled, setCANBusEnabled] = useState(true); const [canbusEnabled, setCANBusEnabled] = useState(true);
const [dataLoggerEnabled, setDataLoggerEnabled] = useState(false); const [dataLoggerEnabled, setDataLoggerEnabled] = useState(false);
@@ -71,36 +71,40 @@ const MainForm = () => {
if (fleet.canbus) { if (fleet.canbus) {
setCANBusEnabled(fleet.canbus.enabled ?? canbusEnabled); setCANBusEnabled(fleet.canbus.enabled ?? canbusEnabled);
setDataLoggerEnabled(fleet.canbus.data_logger_enabled ?? dataLoggerEnabled); setDataLoggerEnabled(
fleet.canbus.data_logger_enabled ?? dataLoggerEnabled
);
setMaxMemBufferSize(fleet.canbus.max_mem_buffer_size ?? maxMemBufferSize); setMaxMemBufferSize(fleet.canbus.max_mem_buffer_size ?? maxMemBufferSize);
setMaxDiskBufferSize(fleet.canbus.max_disk_buffer_size ?? maxDiskBufferSize); setMaxDiskBufferSize(
fleet.canbus.max_disk_buffer_size ?? maxDiskBufferSize
);
} }
// eslint-disable-next-line react-hooks/exhaustive-deps // eslint-disable-next-line react-hooks/exhaustive-deps
}, [fleet]); }, [fleet]);
const onNameChange = (event) => { const onNameChange = (event) => {
setName(event.target.value); setName(event.target.value);
} };
const onLogLevelChange = (event) => { const onLogLevelChange = (event) => {
setSelectedLogLevel(event.target.value); setSelectedLogLevel(event.target.value);
} };
const onCANBusChange = (event) => { const onCANBusChange = (event) => {
setCANBusEnabled(event.target.checked); setCANBusEnabled(event.target.checked);
} };
const onDataLoggerChange = (event) => { const onDataLoggerChange = (event) => {
setDataLoggerEnabled(event.target.checked); setDataLoggerEnabled(event.target.checked);
} };
const onMaxMemBufferSizeChange = (event) => { const onMaxMemBufferSizeChange = (event) => {
setMaxMemBufferSize(event.target.value); setMaxMemBufferSize(event.target.value);
} };
const onMaxDiskBufferSizeChange = (event) => { const onMaxDiskBufferSizeChange = (event) => {
setMaxDiskBufferSize(event.target.value); setMaxDiskBufferSize(event.target.value);
} };
const onSubmit = async (event) => { const onSubmit = async (event) => {
try { try {
@@ -112,12 +116,13 @@ const MainForm = () => {
enabled: canbusEnabled, enabled: canbusEnabled,
data_logger_enabled: canbusEnabled ? dataLoggerEnabled : false, data_logger_enabled: canbusEnabled ? dataLoggerEnabled : false,
max_mem_buffer_size: canbusEnabled ? parseInt(maxMemBufferSize) : 0, max_mem_buffer_size: canbusEnabled ? parseInt(maxMemBufferSize) : 0,
max_disk_buffer_size: canbusEnabled && dataLoggerEnabled ? parseInt(maxDiskBufferSize) : 0 max_disk_buffer_size:
} canbusEnabled && dataLoggerEnabled
? parseInt(maxDiskBufferSize)
: 0,
},
}; };
console.log(oldName);
const result = await updateFleet(oldName, formData, token); const result = await updateFleet(oldName, formData, token);
if (!result || result.error) return; if (!result || result.error) return;
@@ -164,20 +169,24 @@ const MainForm = () => {
<FormControlLabel value="info" control={<Radio />} label="Info" /> <FormControlLabel value="info" control={<Radio />} label="Info" />
<FormControlLabel value="warn" control={<Radio />} label="Warn" /> <FormControlLabel value="warn" control={<Radio />} label="Warn" />
<FormControlLabel value="error" control={<Radio />} label="Error" /> <FormControlLabel value="error" control={<Radio />} label="Error" />
<FormControlLabel value="critical" control={<Radio />} label="Critical" /> <FormControlLabel
value="critical"
control={<Radio />}
label="Critical"
/>
</RadioGroup> </RadioGroup>
<FormLabel id="demo-row-radio-buttons-group-label">CAN Bus</FormLabel> <FormLabel id="demo-row-radio-buttons-group-label">CAN Bus</FormLabel>
<FormGroup> <FormGroup>
<FormControlLabel control={ <FormControlLabel
<Checkbox control={
checked={canbusEnabled} <Checkbox checked={canbusEnabled} onChange={onCANBusChange} />
onChange={onCANBusChange} }
label="CAN Bus Enabled"
/> />
} label="CAN Bus Enabled" />
<TextField <TextField
id="max_mem_buffer_size" id="max_mem_buffer_size"
name="max_mem_buffer_size" name="max_mem_buffer_size"
label='Max Memory Buffer Size (0 uses default size)' label="Max Memory Buffer Size (0 uses default size)"
value={maxMemBufferSize} value={maxMemBufferSize}
onChange={onMaxMemBufferSizeChange} onChange={onMaxMemBufferSizeChange}
variant="outlined" variant="outlined"
@@ -190,18 +199,21 @@ const MainForm = () => {
required required
fullWidth fullWidth
/> />
<FormControlLabel control={ <FormControlLabel
control={
<Checkbox <Checkbox
checked={dataLoggerEnabled} checked={dataLoggerEnabled}
onChange={onDataLoggerChange} onChange={onDataLoggerChange}
disabled={!canbusEnabled} disabled={!canbusEnabled}
/> />
} label="Data Logger Enabled" /> }
label="Data Logger Enabled"
/>
</FormGroup> </FormGroup>
<TextField <TextField
id="max_disk_buffer_size" id="max_disk_buffer_size"
name="max_disk_buffer_size" name="max_disk_buffer_size"
label='Max Disk Buffer Size (0 uses default size)' label="Max Disk Buffer Size (0 uses default size)"
value={maxDiskBufferSize} value={maxDiskBufferSize}
onChange={onMaxDiskBufferSizeChange} onChange={onMaxDiskBufferSizeChange}
variant="outlined" variant="outlined"

View File

@@ -68,7 +68,11 @@ const MainForm = () => {
const [orderBy, setOrderBy] = useState("id"); const [orderBy, setOrderBy] = useState("id");
const [order, setOrder] = useState("asc"); const [order, setOrder] = useState("asc");
const [search, setSearch] = useState(""); const [search, setSearch] = useState("");
const [showDeleteModal, setShowDeleteModal] = useState(false); const [showDeleteModal, setShowDeleteModal] = useState(false);
const [deleteId, setDeleteId] = useState("");
const [deleteRowName, setDeleteRowName] = useState("");
const { getManifests, deleteManifest, manifests, totalManifests } = const { getManifests, deleteManifest, manifests, totalManifests } =
useManifestsContext(); useManifestsContext();
const { setMessage, setTitle, setSitePath } = useStatusContext(); const { setMessage, setTitle, setSitePath } = useStatusContext();
@@ -133,6 +137,12 @@ const MainForm = () => {
setSearch(query); setSearch(query);
}; };
const setDeletePopup = (id, row) => {
setDeleteId(id);
setDeleteRowName(`${row.name} ${row.version}`);
setShowDeleteModal(true);
}
const onDelete = async (manifest_id) => { const onDelete = async (manifest_id) => {
try { try {
await deleteManifest(parseInt(manifest_id), token); await deleteManifest(parseInt(manifest_id), token);
@@ -182,16 +192,10 @@ const MainForm = () => {
return ( return (
<div> <div>
<Tooltip key={`delete-${action.id}`} title={action.tip}> <Tooltip key={`delete-${action.id}`} title={action.tip}>
<Link to="#" onClick={() => onDelete(action.id)}> <Link to="#" onClick={() => setDeletePopup(action.id, row)}>
{action.icon} {action.icon}
</Link> </Link>
</Tooltip> </Tooltip>
<DeleteConfirmation
message={action.id}
open={showDeleteModal}
close={() => setShowDeleteModal(false)}
deleteFunction={() => onDelete(action.id)}
/>
</div> </div>
); );
} }
@@ -261,6 +265,11 @@ const MainForm = () => {
</TableRow> </TableRow>
</TableFooter> </TableFooter>
</Table> </Table>
<DeleteConfirmation
message={deleteRowName}
open={showDeleteModal}
close={() => setShowDeleteModal(false)}
deleteFunction={() => onDelete(deleteId)} />
</div> </div>
); );
}; };

View File

@@ -151,7 +151,6 @@ const Component = () => {
url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png" url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"
/> />
<CenterFocus center={center} zoom={zoom} /> <CenterFocus center={center} zoom={zoom} />
{markers.map((marker) => ( {markers.map((marker) => (
<Marker <Marker
icon={getCarIcon(marker[2])} icon={getCarIcon(marker[2])}
@@ -184,6 +183,7 @@ const Component = () => {
key={carState.vin} key={carState.vin}
vin={carState.vin} vin={carState.vin}
online={carState.online} online={carState.online}
onlineHMI={carState.online_hmi}
battery={carState.battery} battery={carState.battery}
doors={carState.doors} doors={carState.doors}
location={carState.location} location={carState.location}

View File

@@ -13,7 +13,7 @@ import CANSignals from "../Cars/CANSignals";
const VehiclePopUp = (props) => { const VehiclePopUp = (props) => {
const classes = useStyles(); const classes = useStyles();
const [viewCAN, setViewCAN] = useState(false); const [viewCAN, setViewCAN] = useState(false);
const { vin, online, onClose } = props; const { vin, online, onClose, onlineHMI } = props;
const toggleView = (e) => { const toggleView = (e) => {
e.preventDefault(); e.preventDefault();
@@ -43,6 +43,9 @@ const VehiclePopUp = (props) => {
<p> <p>
<b>Connected</b>: {online.toString()} <b>Connected</b>: {online.toString()}
</p> </p>
<p>
<b>ICC Connected</b>: {onlineHMI?.toString()}
</p>
{viewCAN && <CANSignals vin={vin} />} {viewCAN && <CANSignals vin={vin} />}
{!viewCAN && <DigitalTwin {...props} />} {!viewCAN && <DigitalTwin {...props} />}
</div> </div>