CEC-287 Car connection status (#59)

* Car connection status

* Formatting
This commit is contained in:
John Wu
2021-06-23 14:48:19 -07:00
committed by GitHub
parent 5b37f39e74
commit a3b6b01bf3
6 changed files with 79 additions and 19 deletions

View File

@@ -10,6 +10,7 @@ import {
TablePagination, TablePagination,
TableRow, TableRow,
} from "@material-ui/core"; } from "@material-ui/core";
import CheckCircleIcon from "@material-ui/icons/CheckCircle";
import { useVehicleContext } from "../../Contexts/VehicleContext"; import { useVehicleContext } from "../../Contexts/VehicleContext";
import { useStatusContext } from "../../Contexts/StatusContext"; import { useStatusContext } from "../../Contexts/StatusContext";
@@ -133,6 +134,14 @@ const CarSelectionTable = (props) => {
/> />
</TableCell> </TableCell>
<TableCell align="center"> <TableCell align="center">
{row.connected && (
<>
<CheckCircleIcon
style={{ color: "Green", fontSize: 12 }}
/>
<span>&nbsp;</span>
</>
)}
<Link to={`/vehicle-status/${row.vin}`}>{row.vin}</Link> <Link to={`/vehicle-status/${row.vin}`}>{row.vin}</Link>
</TableCell> </TableCell>
<TableCell align="center">{row.model}</TableCell> <TableCell align="center">{row.model}</TableCell>
@@ -177,6 +186,7 @@ CarSelectionTable.propTypes = {
selected: PropTypes.array.isRequired, selected: PropTypes.array.isRequired,
onSelect: PropTypes.func.isRequired, onSelect: PropTypes.func.isRequired,
onSelectAll: PropTypes.func.isRequired, onSelectAll: PropTypes.func.isRequired,
connectionStatus: PropTypes.bool,
}; };
export default CarSelectionTable; export default CarSelectionTable;

View File

@@ -39,12 +39,12 @@ export const VehicleProvider = ({ children }) => {
if (result.error) { if (result.error) {
setVehicles([]); setVehicles([]);
throw new Error(`Get vehicles error. ${result.message}`); throw new Error(`Get vehicles error. ${result.message}`);
} else { }
await addConnections(result.data, token);
setVehicles(result.data); setVehicles(result.data);
if (result.total) { if (result.total) {
setTotalVehicles(result.total); setTotalVehicles(result.total);
} }
}
} finally { } finally {
setBusy(false); setBusy(false);
} }
@@ -96,6 +96,30 @@ export const VehicleProvider = ({ children }) => {
} }
}; };
const addConnections = async (cars, token) => {
const vins = cars.map((car) => car.vin);
const result = await api.getConnections(vins, token);
if (result.error) {
throw new Error(`Get connections error. ${result.message}`);
}
cars.forEach((car) => {
car.connected = result[car.vin] || false;
});
};
const getConnections = async (vins, token) => {
try {
setBusy(true);
const result = await api.getConnections(vins, token);
if (result.error)
throw new Error(`Get connections error. ${result.message}`);
return result;
} finally {
setBusy(false);
}
};
return ( return (
<VehicleContext.Provider <VehicleContext.Provider
value={{ value={{
@@ -109,6 +133,7 @@ export const VehicleProvider = ({ children }) => {
getModels, getModels,
getYears, getYears,
sendCommand, sendCommand,
getConnections,
}} }}
> >
{children} {children}

View File

@@ -133,14 +133,12 @@ describe("VehicleContext", () => {
}); });
}); });
const expectedVehicleData = { const expectedVehicleData = [
data: [ { vin: "3C4PDCBG0ET127145", connected: true },
{ vin: "3C4PDCBG0ET127145" }, { vin: "1G1FP87S3GN100062", connected: true },
{ vin: "1G1FP87S3GN100062" }, { vin: "1HGCG325XYA062256", connected: true },
{ vin: "1HGCG325XYA062256" }, { vin: "1J4GZ78YXWC160024", connected: true },
{ vin: "1J4GZ78YXWC160024" }, { vin: "2C3CCAAG8CH222800", connected: true },
{ vin: "2C3CCAAG8CH222800" }, { vin: "KNADM4A39C6028108", connected: true },
{ vin: "KNADM4A39C6028108" }, { vin: "1G11C5SL9FF153507", connected: true },
{ vin: "1G11C5SL9FF153507" }, ];
],
};

View File

@@ -25,11 +25,20 @@ export const useVehicleContext = () => ({
getYears: jest.fn(() => { getYears: jest.fn(() => {
years = [2023, 2024]; years = [2023, 2024];
}), }),
sendCommand: jest.fn((vin, command, parameters, token) => ({ sendCommand: jest.fn((vins, command, parameters, token) => ({
vin, vins,
command, command,
parameters, parameters,
})), })),
getConnections: jest.fn((vins, token) => {
const result = {};
vins.forEach((vin) => {
result[vin] = true;
});
return result;
}),
}); });
export const setBusy = (val) => { export const setBusy = (val) => {

View File

@@ -10,7 +10,7 @@ const data = [
]; ];
const vehiclesAPI = { const vehiclesAPI = {
getVehicles: async (search, token) => { return { data: { data } }; }, getVehicles: async (search, token) => { return { data }; },
addVehicle: async (vehicle, token) => { addVehicle: async (vehicle, token) => {
data.push(vehicle); data.push(vehicle);
return vehicle; return vehicle;
@@ -30,6 +30,15 @@ const vehiclesAPI = {
vin, command, parameters vin, command, parameters
} }
}, },
getConnections: async (vins, token) => {
const result = {};
vins.forEach(vin => {
result[vin] = true;
});
return result;
}
}; };
export default vehiclesAPI; export default vehiclesAPI;

View File

@@ -39,6 +39,15 @@ const vehiclesAPI = {
}), }),
}) })
.then(fetchRespHandler), .then(fetchRespHandler),
getConnections: async (vins, token) => {
const u = `${API_ENDPOINT}/carsconnected?vins=${vins.join(",")}`
return fetch(u, {
method: "GET",
headers: Object.assign({ "Content-Type": "application/json" }, getAuthHeaderOptions(token)),
})
.then(fetchRespHandler)
},
}; };
export default vehiclesAPI; export default vehiclesAPI;