diff --git a/src/components/App/__snapshots__/App.test.js.snap b/src/components/App/__snapshots__/App.test.js.snap index 8012769..8bea8d3 100644 --- a/src/components/App/__snapshots__/App.test.js.snap +++ b/src/components/App/__snapshots__/App.test.js.snap @@ -456,6 +456,28 @@ exports[`App Route / authenticated 1`] = ` /> +
  • + +
    + + Flashpack + +
    + +
    +
  • @@ -1853,6 +1875,28 @@ exports[`App Route /home authenticated 1`] = ` /> +
  • + +
    + + Flashpack + +
    + +
    +
  • @@ -2627,6 +2671,28 @@ exports[`App Route /issue-info authenticated 1`] = ` /> +
  • + +
    + + Flashpack + +
    + +
    +
  • @@ -3239,6 +3305,28 @@ exports[`App Route /issues authenticated 1`] = ` /> +
  • + +
    + + Flashpack + +
    + +
    +
  • @@ -4220,6 +4308,28 @@ exports[`App Route /package-deploy authenticated 1`] = ` /> +
  • + +
    + + Flashpack + +
    + +
    +
  • @@ -5324,6 +5434,28 @@ exports[`App Route /package-status authenticated 1`] = ` /> +
  • + +
    + + Flashpack + +
    + +
    +
  • @@ -6383,6 +6515,28 @@ exports[`App Route /packages authenticated 1`] = ` /> +
  • + +
    + + Flashpack + +
    + +
    +
  • @@ -7561,6 +7715,28 @@ exports[`App Route /page-not-found authenticated 1`] = ` /> +
  • + +
    + + Flashpack + +
    + +
    +
  • @@ -8189,6 +8365,28 @@ exports[`App Route /tools/certificates/add authenticated 1`] = ` /> +
  • + +
    + + Flashpack + +
    + +
    +
  • @@ -9483,6 +9681,28 @@ exports[`App Route /tools/sms/send authenticated 1`] = ` /> +
  • + +
    + + Flashpack + +
    + +
    +
  • @@ -10210,6 +10430,28 @@ exports[`App Route /vehicle-add authenticated 1`] = ` /> +
  • + +
    + + Flashpack + +
    + +
    +
  • @@ -11392,6 +11634,28 @@ exports[`App Route /vehicle-status authenticated 1`] = ` /> +
  • + +
    + + Flashpack + +
    + +
    +
  • @@ -12503,6 +12767,28 @@ exports[`App Route /vehicles authenticated 1`] = ` /> +
  • + +
    + + Flashpack + +
    + +
    +
  • diff --git a/src/components/Contexts/VehicleContext.jsx b/src/components/Contexts/VehicleContext.jsx index c52d2fb..f2f74a9 100644 --- a/src/components/Contexts/VehicleContext.jsx +++ b/src/components/Contexts/VehicleContext.jsx @@ -30,6 +30,8 @@ export const VehicleProvider = ({ children }) => { const [totalFleets, setTotalFleets] = useState(0); const [models, setModels] = useState([]); const [years, setYears] = useState([]); + const [flashpacks, setFlashpacks] = useState([]); + const [totalFlashpacks, setTotalFlashpacks] = useState(0); const addConnections = async (cars, token) => { try { @@ -287,6 +289,26 @@ export const VehicleProvider = ({ children }) => { } }; + const getAllFlashpacks = async (options, token) => { + let result; + try { + setBusy(true); + + result = await api.getAllFlashpacks(options, token); + if (result.error) + throw new Error(`Get all flashpacks error. ${result.message}`); + + setFlashpacks(result.data); + if (options && options.offset === 0 && result.total) { + setTotalFlashpacks(result.total); + } + } finally { + setBusy(false); + } + + return result; + }; + return ( { getVersionLog, uploadConfig, addTags, + flashpacks, + totalFlashpacks, + getAllFlashpacks, + // getFlashpackECUMappings, + // addFlashpackECUMapping, + // deleteFlashpackECUMapping, }} > {children} diff --git a/src/components/Flashpack/index.jsx b/src/components/Flashpack/index.jsx new file mode 100644 index 0000000..6c3981e --- /dev/null +++ b/src/components/Flashpack/index.jsx @@ -0,0 +1,154 @@ +import { + Table, + TableBody, + TableCell, + TableFooter, + TablePagination, + TableRow, +} from "@material-ui/core"; +import { logger } from "../../services/monitoring"; +import React, { useEffect, useState } from "react"; +import { useVehicleContext, VehicleProvider } from "../Contexts/VehicleContext"; +import { useStatusContext } from "../Contexts/StatusContext"; +import { useUserContext } from "../Contexts/UserContext"; +import TableHeaderSortable from "../Table/HeaderSortable"; +import { useLocalStorage } from "../useLocalStorage"; +import useStyles from "../useStyles"; + +const tableColumns = [ + { + id: "flashpack", + label: "Flashpack Number", + }, +]; + +const PAGE_SIZE = "FLASHPACKS_TABLE_PAGE_SIZE"; + +const MainForm = () => { + const classes = useStyles(); + const { setMessage, setTitle, setSitePath } = useStatusContext(); + const [pageSize, setPageSize] = useLocalStorage(PAGE_SIZE, 10); + const [pageIndex, setPageIndex] = useState(0); + const [orderBy, setOrderBy] = useState("flashpack"); + const [order, setOrder] = useState("desc"); + const { + getAllFlashpacks, + flashpacks, + totalFlashpacks, + } = useVehicleContext(); + const { + token: { + idToken: { jwtToken: token }, + }, + } = useUserContext(); + + useEffect(() => { + setTitle("Flashpacks"); + setSitePath([ + { + label: "Tools", + link: "/tools/flashpacks", + }, + ]); + // eslint-disable-next-line react-hooks/exhaustive-deps + }, []); + + useEffect(() => { + loadFlashpacks(); + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [token, token, pageIndex, pageSize, orderBy, order]); + + const loadFlashpacks = async () => { + try { + if (!token) return; + await getAllFlashpacks( + { + limit: pageSize, + offset: pageSize * pageIndex, + order: `${orderBy} ${order}`, + }, + token + ); + } catch (e) { + setMessage(e.message); + logger.warn(e.stack); + } + }; + + const handleChangePageIndex = (event, newIndex) => { + setPageIndex(newIndex); + }; + + const handleChangePageSize = (event) => { + setPageSize(parseInt(event.target.value, 10)); + setPageIndex(0); + }; + + const handleSort = (event, property) => { + try { + if (property === orderBy) { + if (order === "asc") { + setOrder("desc"); + } else { + setOrder("asc"); + } + } else { + setOrderBy(property); + setOrder("asc"); + } + } catch (e) { + logger.warn(e.stack); + } + }; + + return ( +
    + + + + {flashpacks && flashpacks.map((row, index) => ( + + + {row} + + + ))} + + + + {!flashpacks || flashpacks.length === 0 ? ( + No Flashpack Numbers + ) : ( + )} + + +
    +
    + ); +}; + +const Flashpacks = () => ( + + + +); + +export default Flashpacks; \ No newline at end of file diff --git a/src/components/Layouts/SideMenu.jsx b/src/components/Layouts/SideMenu.jsx index 61139ae..97a89e8 100644 --- a/src/components/Layouts/SideMenu.jsx +++ b/src/components/Layouts/SideMenu.jsx @@ -79,6 +79,11 @@ const menuData = [ to: "/tools/sms/send", rolesPerProvider: Permissions.FiskerCreate, }, + { + label: "Flashpack", + to: "/tools/flashpacks", + rolesPerProvider: Permissions.FiskerRead, + }, ], }, ]; diff --git a/src/components/Layouts/__snapshots__/SideMenu.test.jsx.snap b/src/components/Layouts/__snapshots__/SideMenu.test.jsx.snap index 44be0aa..2e282bf 100644 --- a/src/components/Layouts/__snapshots__/SideMenu.test.jsx.snap +++ b/src/components/Layouts/__snapshots__/SideMenu.test.jsx.snap @@ -375,6 +375,28 @@ exports[`SideMenu Authenticated 1`] = ` /> +
  • + +
    + + Flashpack + +
    + +
    +
  • diff --git a/src/components/Routes/SiteRoutes.jsx b/src/components/Routes/SiteRoutes.jsx index ed31bb0..f3118ac 100644 --- a/src/components/Routes/SiteRoutes.jsx +++ b/src/components/Routes/SiteRoutes.jsx @@ -40,6 +40,7 @@ const SecurityDLL = React.lazy(() => import("../Magna/SecurityDLL")); const SMSSend = React.lazy(() => import("../SMS/Send")); const SuppliersList = React.lazy(() => import("../Suppliers/List")); const SupplierDetails = React.lazy(() => import("../Suppliers/Details")); +const Flashpacks = React.lazy(() => import("../Flashpack")); const Datascope = React.lazy(() => import("../Dashboard")); const SumsRxSwin = React.lazy(() => import("../SUMS")); const SumsRxSwinAdd = React.lazy(() => import("../SUMS/Add")); @@ -280,6 +281,24 @@ const SiteRoutes = () => { rolesPerGroup={Permissions.FiskerCreate} providers={providers} /> + } + type={TYPES.PROTECTED} + token={token} + groups={groups} + rolesPerGroup={Permissions.FiskerRead} + providers={providers} + /> + {/* } + type={TYPES.PROTECTED} + token={token} + groups={groups} + rolesPerGroup={Permissions.FiskerCreate} + providers={providers} + /> */} } diff --git a/src/services/__mocks__/vehiclesAPI.js b/src/services/__mocks__/vehiclesAPI.js index 966dd3f..e4baec9 100644 --- a/src/services/__mocks__/vehiclesAPI.js +++ b/src/services/__mocks__/vehiclesAPI.js @@ -199,6 +199,36 @@ const vehiclesAPI = { sendDiagnosticCommand: async (search) => ({ Message: `remote diagnostic command sent to ${search.vins.length} vehicles` }), + getAllFlashpacks: async (token) => { + return { + data: ["41.14", "43.19"], + }; + }, + getFlashpackECUMappings: async (model, year, flashpack, token) => { + return { + "data": [ + { + "flashpack": "41.14", + "car_model": "Ocean", + "car_year": 2023, + "car_ecu_name": "ADAS", + "car_ecu_version": "ADASVersion" + }, + { + "flashpack": "41.14", + "car_model": "Ocean", + "car_year": 2023, "car_ecu_name": "ACUN", + "car_ecu_version": "ACUNVersion" + } + ], + }; + }, + addFlashpackECUMapping: async (data, token) => { + return { message: "Created" }; + }, + deleteFlashpackECUMapping: async (data, token) => { + return { message: "Deleted" }; + }, }; export default vehiclesAPI; diff --git a/src/services/vehiclesAPI.js b/src/services/vehiclesAPI.js index f40da4e..d5a242b 100644 --- a/src/services/vehiclesAPI.js +++ b/src/services/vehiclesAPI.js @@ -260,6 +260,52 @@ const vehiclesAPI = { }).then(fetchRespHandler) .catch(errorHandler) }, + + getAllFlashpacks: async (options, token) => { + return fetch(addQueryParams(`${API_ENDPOINT}/flashpack_get_all`, options), { + method: "GET", + headers: Object.assign( + { "Content-Type": "application/json" }, + getAuthHeaderOptions(token) + ), + }).then(fetchRespHandler) + .catch(errorHandler) + }, + + getFlashpackECUMappings: async (model, year, flashpack, options, token) => { + return fetch(addQueryParams(`${API_ENDPOINT}/flashpack_ecu_mappings/${model}/${year}/${flashpack}`, options), { + method: "GET", + headers: Object.assign( + { "Content-Type": "application/json" }, + getAuthHeaderOptions(token) + ), + }).then(fetchRespHandler) + .catch(errorHandler) + }, + + addFlashpackECUMapping: async (data, token) => { + return fetch(`${API_ENDPOINT}/flashpack_ecu_mapping`, { + method: "POST", + headers: Object.assign( + { "Content-Type": "application/json" }, + getAuthHeaderOptions(token), + ), + body: JSON.stringify(data), + }).then(fetchRespHandler) + .catch(errorHandler) + }, + + deleteFlashpackECUMapping: async (data, token) => { + return fetch(`${API_ENDPOINT}/flashpack_ecu_mapping`, { + method: "DELETE", + headers: Object.assign( + { "Content-Type": "application/json" }, + getAuthHeaderOptions(token) + ), + body: JSON.stringify(data), + }).then(fetchRespHandler) + .catch(errorHandler) + }, }; export default vehiclesAPI;