* CEC-371 Car ECU display (#79) * Merge Development (#53) * Use responsive iframe control for charts (#49) * Use responsive iframe control to charts * Move external Grafana link to Dashboard page * Remove unused embedded style class * Add button label * added delete button to deploy packages * Fix unit test warning Remove unused route from test * Fix styling of button * minor fixes per pr review Co-authored-by: jcw-fisker <jwatson@fiskerinc.com> Co-authored-by: John Cotten Watson <83605808+jcw-fisker@users.noreply.github.com> * Development Merge (#57) * CEC-287 Car connection status (#59) (#60) * Car connection status * Formatting * Merge Development (#64) * Add connection status to vehicles page * ConnectedIcon control * Handle Style * Development (#67) * preliminary map for vehicles * weird zoom bug * passing react tests * fixing warnings and updating snapshots * update node environment to 14 * addressing comments by changing variable types and adding styles to home page title * adding CODEOWNERS file * fixing token error * CEC-371 Update car ECUs display (#78) * Clean up className styles Update car status page to show update and ECUs * Add update ecu version button Show all ECUs on car status page Only show car ecus for search Co-authored-by: jcw-fisker <jwatson@fiskerinc.com> Co-authored-by: John Cotten Watson <83605808+jcw-fisker@users.noreply.github.com> Co-authored-by: Drew Taylor <69828061+drew-fisker@users.noreply.github.com> * CEC-394 Car update log (#81) * CEC-394 Car update status control * Remove Datadog RUM Remove package update components Move control components into Controls folder Add Car update status page * Display update status log Clean up unused update package code * Remove console.logs * no vars * adding timestamp to vehicle popup * modifying vehicle data query * removing extraneous code * removing console log * Clean up SonarCloud warnings (#83) * Clean up SonarCloud warnings * Bogus security warning * Fix another warning * Fix unauthorized locations request * Fix update progress control * CEC-563 New manifest format (#88) * Add ManifestCreateContext Update create manifest page * Finish UI changes and API integration * Fixes * Fix test * Remove manifest ECU file version and type * Fixes * Add manifest ecu file type control * Fix Sonar warnings * Fix test * Update codeowners * Formatting * CEC-553 Change file type to string (#90) * CEC-553 File type uses string enum * Fix test timeout * Fix * Merge development * Increase timeout * Clean up (#95) * Clean up Mock missing methods * Smell Co-authored-by: jcw-fisker <jwatson@fiskerinc.com> Co-authored-by: John Cotten Watson <83605808+jcw-fisker@users.noreply.github.com> Co-authored-by: Drew Taylor <69828061+drew-fisker@users.noreply.github.com> Co-authored-by: Drew Taylor <dtaylor@fiskerinc.com>
187 lines
4.6 KiB
JavaScript
187 lines
4.6 KiB
JavaScript
import React, { useContext, useState } from "react";
|
|
import { logger } from "../../services/monitoring";
|
|
import api from "../../services/vehiclesAPI";
|
|
|
|
const VehicleContext = React.createContext();
|
|
|
|
const validateAdd = (vehicle) => {
|
|
if (vehicle === null) {
|
|
throw new Error("No vehicle data");
|
|
}
|
|
|
|
if (!vehicle.vin || vehicle.vin.length === 0) {
|
|
throw new Error("VIN required");
|
|
}
|
|
|
|
if (vehicle.vin.length > 17) {
|
|
throw new Error("VIN cannot be larger than 17 characters");
|
|
}
|
|
|
|
if (!vehicle.model || vehicle.model.length === 0) {
|
|
throw new Error("model required");
|
|
}
|
|
|
|
if (!vehicle.year || vehicle.year < 2000 || vehicle.year > 9999) {
|
|
throw new Error("year required");
|
|
}
|
|
};
|
|
|
|
export const VehicleProvider = ({ children }) => {
|
|
const [busy, setBusy] = useState(false);
|
|
const [vehicles, setVehicles] = useState([]);
|
|
const [totalVehicles, setTotalVehicles] = useState(0);
|
|
const [models, setModels] = useState([]);
|
|
const [years, setYears] = useState([]);
|
|
|
|
const addConnections = async (cars, token) => {
|
|
try {
|
|
const vins = cars.map((car) => car.vin);
|
|
const result = await api.getConnections(vins, token);
|
|
|
|
if (result.error) {
|
|
throw new Error(`Add connections error. ${result.message}`);
|
|
}
|
|
cars.forEach((car) => {
|
|
car.connected = result[car.vin] || false;
|
|
});
|
|
} catch (e) {
|
|
logger.error(e.stack);
|
|
}
|
|
};
|
|
|
|
const addVehicle = async (vehicle, token) => {
|
|
try {
|
|
setBusy(true);
|
|
validateAdd(vehicle);
|
|
const result = await api.addVehicle(vehicle, token);
|
|
if (result.error) throw new Error(`Add vehicle error. ${result.message}`);
|
|
return result;
|
|
} finally {
|
|
setBusy(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);
|
|
}
|
|
};
|
|
|
|
const getECUs = async (search, token) => {
|
|
try {
|
|
setBusy(true);
|
|
const result = await api.getECUs(search, token);
|
|
if (result.error) throw new Error(`Get ECUs error. ${result.message}`);
|
|
return result;
|
|
} finally {
|
|
setBusy(false);
|
|
}
|
|
};
|
|
|
|
const getLocations = async (token) => {
|
|
try {
|
|
setBusy(true);
|
|
const result = await api.getLocations(token);
|
|
if (result.error)
|
|
throw new Error(`Get locations error. ${result.message}`);
|
|
return result;
|
|
} finally {
|
|
setBusy(false);
|
|
}
|
|
};
|
|
|
|
const getModels = async (token) => {
|
|
try {
|
|
setBusy(true);
|
|
const result = await api.getModels(token);
|
|
if (result.error) throw new Error(`Get models error. ${result.message}`);
|
|
setModels(result.data);
|
|
} finally {
|
|
setBusy(false);
|
|
}
|
|
};
|
|
|
|
const getState = async (token, vin) => {
|
|
try {
|
|
setBusy(true);
|
|
const result = await api.getState(token, vin);
|
|
if (result.error) throw new Error(`Get state error. ${result.message}`);
|
|
return result;
|
|
} finally {
|
|
setBusy(false);
|
|
}
|
|
};
|
|
|
|
const getVehicles = async (search, token) => {
|
|
try {
|
|
setBusy(true);
|
|
const result = await api.getVehicles(search, token);
|
|
if (result.error) {
|
|
setVehicles([]);
|
|
throw new Error(`Get vehicles error. ${result.message}`);
|
|
}
|
|
await addConnections(result.data, token);
|
|
setVehicles(result.data);
|
|
if (result.total) {
|
|
setTotalVehicles(result.total);
|
|
}
|
|
} finally {
|
|
setBusy(false);
|
|
}
|
|
};
|
|
|
|
const getYears = async (token) => {
|
|
try {
|
|
setBusy(true);
|
|
const result = await api.getYears(token);
|
|
if (result.error) throw new Error(`Get years error. ${result.message}`);
|
|
setYears(result.data);
|
|
} finally {
|
|
setBusy(false);
|
|
}
|
|
};
|
|
|
|
const sendCommand = async (vins, command, parameters, token) => {
|
|
try {
|
|
setBusy(true);
|
|
const result = await api.sendCommand(vins, command, parameters, token);
|
|
if (result.error)
|
|
throw new Error(`Send command error. ${result.message}`);
|
|
return result;
|
|
} finally {
|
|
setBusy(false);
|
|
}
|
|
};
|
|
|
|
return (
|
|
<VehicleContext.Provider
|
|
value={{
|
|
busy,
|
|
models,
|
|
totalVehicles,
|
|
vehicles,
|
|
years,
|
|
addVehicle,
|
|
getConnections,
|
|
getECUs,
|
|
getLocations,
|
|
getModels,
|
|
getState,
|
|
getYears,
|
|
getVehicles,
|
|
sendCommand,
|
|
}}
|
|
>
|
|
{children}
|
|
</VehicleContext.Provider>
|
|
);
|
|
};
|
|
|
|
export const useVehicleContext = () => useContext(VehicleContext);
|