From 076b7ab7b513453ac5eeca95a019a2c0bc710a5c Mon Sep 17 00:00:00 2001 From: padamsen_fisker Date: Thu, 30 Nov 2023 10:59:31 -0500 Subject: [PATCH 01/10] CEC-5443 - Ability to add Flashpack/ECU mappings --- .../App/__snapshots__/App.test.js.snap | 286 ++++++++++++++++++ src/components/Contexts/VehicleContext.jsx | 28 ++ src/components/Flashpack/index.jsx | 154 ++++++++++ src/components/Layouts/SideMenu.jsx | 5 + .../__snapshots__/SideMenu.test.jsx.snap | 22 ++ src/components/Routes/SiteRoutes.jsx | 19 ++ src/services/__mocks__/vehiclesAPI.js | 30 ++ src/services/vehiclesAPI.js | 46 +++ 8 files changed, 590 insertions(+) create mode 100644 src/components/Flashpack/index.jsx 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; From 754c5eb746e4878fce338e1a38aa27df2df99699 Mon Sep 17 00:00:00 2001 From: padamsen_fisker Date: Fri, 8 Dec 2023 12:27:54 -0500 Subject: [PATCH 02/10] further improvements --- src/components/Contexts/VehicleContext.jsx | 22 ++- src/components/Flashpack/Details/index.jsx | 159 +++++++++++++++++++++ src/components/Flashpack/index.jsx | 2 +- src/components/Routes/SiteRoutes.jsx | 7 +- 4 files changed, 185 insertions(+), 5 deletions(-) create mode 100644 src/components/Flashpack/Details/index.jsx diff --git a/src/components/Contexts/VehicleContext.jsx b/src/components/Contexts/VehicleContext.jsx index f2f74a9..8b25310 100644 --- a/src/components/Contexts/VehicleContext.jsx +++ b/src/components/Contexts/VehicleContext.jsx @@ -309,6 +309,26 @@ export const VehicleProvider = ({ children }) => { return result; }; + const getFlashpackECUMappings = async (flashpack, model, year, 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 ( { flashpacks, totalFlashpacks, getAllFlashpacks, - // getFlashpackECUMappings, + getFlashpackECUMappings, // addFlashpackECUMapping, // deleteFlashpackECUMapping, }} diff --git a/src/components/Flashpack/Details/index.jsx b/src/components/Flashpack/Details/index.jsx new file mode 100644 index 0000000..7bf6ba5 --- /dev/null +++ b/src/components/Flashpack/Details/index.jsx @@ -0,0 +1,159 @@ +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: "ecu_name", + label: "ECU Name", + }, + { + id: "ecu_version", + label: "ECU Version", + }, +]; + +const PAGE_SIZE = "FLASHPACK_MAPPINGS_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(); + const { flashpack } = useParams(); + + useEffect(() => { + setTitle(`Flashpack ${flashpack}`); + setSitePath([ + { + label: `Flashpack ${flashpack}`, + link: `/tools/flashpack/${flashpack}`, + }, + ]); + // 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 FlashpackDetails = () => ( + + + +); + +export default FlashpackDetails; \ No newline at end of file diff --git a/src/components/Flashpack/index.jsx b/src/components/Flashpack/index.jsx index 6c3981e..8a84e66 100644 --- a/src/components/Flashpack/index.jsx +++ b/src/components/Flashpack/index.jsx @@ -46,7 +46,7 @@ const MainForm = () => { setTitle("Flashpacks"); setSitePath([ { - label: "Tools", + label: "Flashpacks", link: "/tools/flashpacks", }, ]); diff --git a/src/components/Routes/SiteRoutes.jsx b/src/components/Routes/SiteRoutes.jsx index f3118ac..a56a54e 100644 --- a/src/components/Routes/SiteRoutes.jsx +++ b/src/components/Routes/SiteRoutes.jsx @@ -41,6 +41,7 @@ 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 FlashpackDetails = React.lazy(() => import("../Flashpack/Details")); const Datascope = React.lazy(() => import("../Dashboard")); const SumsRxSwin = React.lazy(() => import("../SUMS")); const SumsRxSwinAdd = React.lazy(() => import("../SUMS/Add")); @@ -290,15 +291,15 @@ const SiteRoutes = () => { rolesPerGroup={Permissions.FiskerRead} providers={providers} /> - {/* } + render={() => } type={TYPES.PROTECTED} token={token} groups={groups} rolesPerGroup={Permissions.FiskerCreate} providers={providers} - /> */} + /> } From 437ec9e1242d4187a3d5861ba354fed8a708acc2 Mon Sep 17 00:00:00 2001 From: padamsen_fisker Date: Tue, 9 Jan 2024 13:20:45 -0500 Subject: [PATCH 03/10] improvements to UI; display working --- src/components/Contexts/VehicleContext.jsx | 16 +++++---- src/components/Flashpack/Details/index.jsx | 39 +++++++++++++--------- src/components/Flashpack/index.jsx | 39 ++++++++++------------ src/components/Routes/SiteRoutes.jsx | 4 +-- src/services/vehiclesAPI.js | 4 +-- 5 files changed, 54 insertions(+), 48 deletions(-) diff --git a/src/components/Contexts/VehicleContext.jsx b/src/components/Contexts/VehicleContext.jsx index 8b25310..b74d50f 100644 --- a/src/components/Contexts/VehicleContext.jsx +++ b/src/components/Contexts/VehicleContext.jsx @@ -32,6 +32,8 @@ export const VehicleProvider = ({ children }) => { const [years, setYears] = useState([]); const [flashpacks, setFlashpacks] = useState([]); const [totalFlashpacks, setTotalFlashpacks] = useState(0); + const [flashpackECUMappings, setFlashpackECUMappings] = useState([]) + const [totalFlashpackECUMappings, setTotalFlashpackECUMappings] = useState(0) const addConnections = async (cars, token) => { try { @@ -309,18 +311,18 @@ export const VehicleProvider = ({ children }) => { return result; }; - const getFlashpackECUMappings = async (flashpack, model, year, options, token) => { + const getFlashpackECUMappings = async (model, year, flashpack, options, token) => { let result; try { setBusy(true); - result = await api.getAllFlashpacks(options, token); + result = await api.getFlashpackECUMappings(model, year, flashpack, options, token); if (result.error) - throw new Error(`Get all flashpacks error. ${result.message}`); + throw new Error(`Get flashpack ecu mappings error. ${result.message}`); - setFlashpacks(result.data); + setFlashpackECUMappings(result.data); if (options && options.offset === 0 && result.total) { - setTotalFlashpacks(result.total); + setTotalFlashpackECUMappings(result.total); } } finally { setBusy(false); @@ -361,9 +363,9 @@ export const VehicleProvider = ({ children }) => { flashpacks, totalFlashpacks, getAllFlashpacks, + totalFlashpackECUMappings, + flashpackECUMappings, getFlashpackECUMappings, - // addFlashpackECUMapping, - // deleteFlashpackECUMapping, }} > {children} diff --git a/src/components/Flashpack/Details/index.jsx b/src/components/Flashpack/Details/index.jsx index 7bf6ba5..7e53f58 100644 --- a/src/components/Flashpack/Details/index.jsx +++ b/src/components/Flashpack/Details/index.jsx @@ -1,3 +1,5 @@ +import React, { useEffect, useState } from "react"; +import { useParams } from "react-router-dom"; import { Table, TableBody, @@ -7,7 +9,6 @@ import { 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"; @@ -17,11 +18,11 @@ import useStyles from "../../useStyles"; const tableColumns = [ { - id: "ecu_name", + id: "car_ecu_name", label: "ECU Name", }, { - id: "ecu_version", + id: "car_ecu_version", label: "ECU Version", }, ]; @@ -29,6 +30,7 @@ const tableColumns = [ const PAGE_SIZE = "FLASHPACK_MAPPINGS_TABLE_PAGE_SIZE"; const MainForm = () => { + const { model, year, flashpack } = useParams(); const classes = useStyles(); const { setMessage, setTitle, setSitePath } = useStatusContext(); const [pageSize, setPageSize] = useLocalStorage(PAGE_SIZE, 10); @@ -36,37 +38,39 @@ const MainForm = () => { const [orderBy, setOrderBy] = useState("flashpack"); const [order, setOrder] = useState("desc"); const { - getAllFlashpacks, - flashpacks, - totalFlashpacks, + getFlashpackECUMappings, + flashpackECUMappings, + totalFlashpackECUMappings, } = useVehicleContext(); const { token: { idToken: { jwtToken: token }, }, } = useUserContext(); - const { flashpack } = useParams(); useEffect(() => { setTitle(`Flashpack ${flashpack}`); setSitePath([ { label: `Flashpack ${flashpack}`, - link: `/tools/flashpack/${flashpack}`, + link: `/flashpack/${model}/${year}/${flashpack}`, }, ]); // eslint-disable-next-line react-hooks/exhaustive-deps }, []); useEffect(() => { - loadFlashpacks(); + loadFlashpackECUMappings(); // eslint-disable-next-line react-hooks/exhaustive-deps }, [token, token, pageIndex, pageSize, orderBy, order]); - const loadFlashpacks = async () => { + const loadFlashpackECUMappings = async () => { try { if (!token) return; - await getAllFlashpacks( + await getFlashpackECUMappings( + model, + year, + flashpack, { limit: pageSize, offset: pageSize * pageIndex, @@ -117,23 +121,26 @@ const MainForm = () => { onSortRequest={handleSort} /> - {flashpacks && flashpacks.map((row, index) => ( + {flashpackECUMappings && flashpackECUMappings.map((row, index) => ( - {row} + {row.car_ecu_name} + + + {row.car_ecu_version} ))} - {!flashpacks || flashpacks.length === 0 ? ( - No Flashpack Numbers + {!flashpackECUMappings || flashpackECUMappings.length === 0 ? ( + No Flashpack ECU Mappings ) : ( { 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} + + {row.flashpack} + + + + {row.car_model} + + + {row.car_year} ))} diff --git a/src/components/Routes/SiteRoutes.jsx b/src/components/Routes/SiteRoutes.jsx index a56a54e..57575e3 100644 --- a/src/components/Routes/SiteRoutes.jsx +++ b/src/components/Routes/SiteRoutes.jsx @@ -292,12 +292,12 @@ const SiteRoutes = () => { providers={providers} /> } type={TYPES.PROTECTED} token={token} groups={groups} - rolesPerGroup={Permissions.FiskerCreate} + rolesPerGroup={Permissions.FiskerRead} providers={providers} /> { - return fetch(addQueryParams(`${API_ENDPOINT}/flashpack_get_all`, options), { + return fetch(addQueryParams(`${API_ENDPOINT}/flashpack_versions`, options), { method: "GET", headers: Object.assign( { "Content-Type": "application/json" }, @@ -273,7 +273,7 @@ const vehiclesAPI = { }, getFlashpackECUMappings: async (model, year, flashpack, options, token) => { - return fetch(addQueryParams(`${API_ENDPOINT}/flashpack_ecu_mappings/${model}/${year}/${flashpack}`, options), { + return fetch(addQueryParams(`${API_ENDPOINT}/flashpack_version_ecu_mappings/${model}/${year}/${flashpack}`, options), { method: "GET", headers: Object.assign( { "Content-Type": "application/json" }, From 43d1721804d4b1533a6a2d766dd8b669886f6d32 Mon Sep 17 00:00:00 2001 From: padamsen_fisker Date: Fri, 12 Jan 2024 16:36:28 -0500 Subject: [PATCH 04/10] delete working --- src/components/Contexts/VehicleContext.jsx | 29 +++++++++- src/components/Flashpack/Add/index.jsx | 0 src/components/Flashpack/index.jsx | 66 ++++++++++++++++++++-- src/components/Routes/SiteRoutes.jsx | 10 ++++ src/services/vehiclesAPI.js | 4 +- 5 files changed, 100 insertions(+), 9 deletions(-) create mode 100644 src/components/Flashpack/Add/index.jsx diff --git a/src/components/Contexts/VehicleContext.jsx b/src/components/Contexts/VehicleContext.jsx index b74d50f..c71860f 100644 --- a/src/components/Contexts/VehicleContext.jsx +++ b/src/components/Contexts/VehicleContext.jsx @@ -304,11 +304,11 @@ export const VehicleProvider = ({ children }) => { if (options && options.offset === 0 && result.total) { setTotalFlashpacks(result.total); } + + return result; } finally { setBusy(false); } - - return result; }; const getFlashpackECUMappings = async (model, year, flashpack, options, token) => { @@ -324,11 +324,33 @@ export const VehicleProvider = ({ children }) => { if (options && options.offset === 0 && result.total) { setTotalFlashpackECUMappings(result.total); } + + return result; + } finally { + setBusy(false); + } + }; + + const deleteFlashpackVersion = async (model, year, flashpack, token) => { + let result; + try { + setBusy(true); + + const data = { + "car_model": model, + "car_year": year, + "flashpack": flashpack, + } + + result = await api.deleteFlashpackVersion(data, token); + if (result.error) + throw new Error(`Delete flashpack ecu mappings error. ${result.message}`); + + return result; } finally { setBusy(false); } - return result; }; return ( @@ -366,6 +388,7 @@ export const VehicleProvider = ({ children }) => { totalFlashpackECUMappings, flashpackECUMappings, getFlashpackECUMappings, + deleteFlashpackVersion, }} > {children} diff --git a/src/components/Flashpack/Add/index.jsx b/src/components/Flashpack/Add/index.jsx new file mode 100644 index 0000000..e69de29 diff --git a/src/components/Flashpack/index.jsx b/src/components/Flashpack/index.jsx index de81b58..b0f7499 100644 --- a/src/components/Flashpack/index.jsx +++ b/src/components/Flashpack/index.jsx @@ -1,4 +1,6 @@ import { + Grid, + IconButton, Table, TableBody, TableCell, @@ -6,6 +8,9 @@ import { TablePagination, TableRow, } from "@material-ui/core"; +import AddCircleIcon from "@material-ui/icons/AddCircle"; +import DeleteIcon from "@material-ui/icons/Delete"; +import clsx from "clsx"; import { Link } from "react-router-dom"; import { logger } from "../../services/monitoring"; import React, { useEffect, useState } from "react"; @@ -14,6 +19,8 @@ import { useStatusContext } from "../Contexts/StatusContext"; import { useUserContext } from "../Contexts/UserContext"; import TableHeaderSortable from "../Table/HeaderSortable"; import { useLocalStorage } from "../useLocalStorage"; +import DeleteConfirmation from "../DeleteConfirmation"; +import { RoleWrap } from "../Controls/RoleWrap"; import useStyles from "../useStyles"; const tableColumns = [ @@ -38,17 +45,20 @@ const MainForm = () => { 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 [showDeleteModal, setShowDeleteModal] = useState(false); + const [rowToDelete, setRowToDelete] = useState({}); const { getAllFlashpacks, flashpacks, totalFlashpacks, + deleteFlashpackVersion, } = useVehicleContext(); const { token: { idToken: { jwtToken: token }, }, + groups, + providers, } = useUserContext(); useEffect(() => { @@ -65,7 +75,7 @@ const MainForm = () => { useEffect(() => { loadFlashpacks(); // eslint-disable-next-line react-hooks/exhaustive-deps - }, [token, token, pageIndex, pageSize, orderBy, order]); + }, [token, token, pageIndex, pageSize]); const loadFlashpacks = async () => { try { @@ -74,7 +84,6 @@ const MainForm = () => { { limit: pageSize, offset: pageSize * pageIndex, - order: `${orderBy} ${order}`, }, token ); @@ -93,8 +102,35 @@ const MainForm = () => { setPageIndex(0); }; + const onDeleteClick = (row) => { + setRowToDelete(row); + setShowDeleteModal(true); + } + + const sendDelete = async () => { + if (rowToDelete) { + try { + const result = await deleteFlashpackVersion(rowToDelete.car_model, rowToDelete.car_year, rowToDelete.flashpack, token); + if (!result || result.error) return; + + setMessage(`Deleted ${rowToDelete.car_year} ${rowToDelete.car_model} ${rowToDelete.flashpack}`); + loadFlashpacks(); + } catch (e) { + setMessage(e.message); + logger.warn(e.stack); + } + } + }; + return (
    + + + + + + +
    { {row.car_year} + + + onDeleteClick(row)} + aria-label={`Send delete for ${row.car_year} ${row.car_model} ${row.flashpack}`} + size="small" + color="primary" + > + + + + ))} @@ -138,6 +190,12 @@ const MainForm = () => {
    + setShowDeleteModal(false)} + deleteFunction={sendDelete} + />
    ); }; diff --git a/src/components/Routes/SiteRoutes.jsx b/src/components/Routes/SiteRoutes.jsx index 57575e3..aac7613 100644 --- a/src/components/Routes/SiteRoutes.jsx +++ b/src/components/Routes/SiteRoutes.jsx @@ -42,6 +42,7 @@ const SuppliersList = React.lazy(() => import("../Suppliers/List")); const SupplierDetails = React.lazy(() => import("../Suppliers/Details")); const Flashpacks = React.lazy(() => import("../Flashpack")); const FlashpackDetails = React.lazy(() => import("../Flashpack/Details")); +const FlashpackAdd = React.lazy(() => import("../Flashpack/Add")) const Datascope = React.lazy(() => import("../Dashboard")); const SumsRxSwin = React.lazy(() => import("../SUMS")); const SumsRxSwinAdd = React.lazy(() => import("../SUMS/Add")); @@ -300,6 +301,15 @@ const SiteRoutes = () => { rolesPerGroup={Permissions.FiskerRead} providers={providers} /> + } + type={TYPES.PROTECTED} + token={token} + groups={groups} + rolesPerGroup={Permissions.FiskerCreate} + providers={providers} + /> } diff --git a/src/services/vehiclesAPI.js b/src/services/vehiclesAPI.js index 1e45fcb..6280d14 100644 --- a/src/services/vehiclesAPI.js +++ b/src/services/vehiclesAPI.js @@ -295,8 +295,8 @@ const vehiclesAPI = { .catch(errorHandler) }, - deleteFlashpackECUMapping: async (data, token) => { - return fetch(`${API_ENDPOINT}/flashpack_ecu_mapping`, { + deleteFlashpackVersion: async (data, token) => { + return fetch(`${API_ENDPOINT}/flashpack_version`, { method: "DELETE", headers: Object.assign( { "Content-Type": "application/json" }, From 421a8480dd16630709e64f92e2288b018008ad98 Mon Sep 17 00:00:00 2001 From: padamsen_fisker Date: Mon, 15 Jan 2024 17:15:09 -0500 Subject: [PATCH 05/10] working, just need to prettify --- src/components/Contexts/VehicleContext.jsx | 22 +++ src/components/Flashpack/Add/index.jsx | 215 +++++++++++++++++++++ src/services/vehiclesAPI.js | 4 +- 3 files changed, 239 insertions(+), 2 deletions(-) diff --git a/src/components/Contexts/VehicleContext.jsx b/src/components/Contexts/VehicleContext.jsx index c71860f..3744469 100644 --- a/src/components/Contexts/VehicleContext.jsx +++ b/src/components/Contexts/VehicleContext.jsx @@ -331,6 +331,27 @@ export const VehicleProvider = ({ children }) => { } }; + const addFlashpackVersion = async (model, year, flashpack, carFlashpackVersions, token) => { + try { + setBusy(true); + + const data = { + "car_model": model, + "car_year": year, + "flashpack": flashpack, + "car_flashpack_versions": carFlashpackVersions, + } + + const result = await api.addFlashpackVersion(data, token) + if (result.error) + throw new Error(`Add flashpack version error. ${result.message}`); + + return result; + } finally { + setBusy(false) + } + } + const deleteFlashpackVersion = async (model, year, flashpack, token) => { let result; try { @@ -388,6 +409,7 @@ export const VehicleProvider = ({ children }) => { totalFlashpackECUMappings, flashpackECUMappings, getFlashpackECUMappings, + addFlashpackVersion, deleteFlashpackVersion, }} > diff --git a/src/components/Flashpack/Add/index.jsx b/src/components/Flashpack/Add/index.jsx index e69de29..69d527a 100644 --- a/src/components/Flashpack/Add/index.jsx +++ b/src/components/Flashpack/Add/index.jsx @@ -0,0 +1,215 @@ +import { + Button, + TextField +} from "@material-ui/core"; +import React, { useEffect, useState } from "react"; +import { Redirect } from "react-router"; +import { logger } from "../../../services/monitoring"; +import { useStatusContext } from "../../Contexts/StatusContext"; +import { useVehicleContext, VehicleProvider } from "../../Contexts/VehicleContext"; +import { useUserContext } from "../../Contexts/UserContext"; +import useStyles from "../../useStyles"; + +const MainForm = () => { + const { + token: { + idToken: { jwtToken: token }, + }, + } = useUserContext(); + const classes = useStyles(); + const [redirect, setRedirect] = useState(null); + const { setMessage, setTitle, setSitePath } = useStatusContext(); + const [carModel, setCarModel] = useState(""); + const [carYear, setCarYear] = useState(0); + const [flashpack, setFlashpack] = useState(""); + const [mappingInputs, setMappingInputs] = useState([{ ecuName: "", ecuVersion: "" }]); + const { + addFlashpackVersion, + busy, + } = useVehicleContext(); + + useEffect(() => { + setTitle(`Add Flashpack Version`); + setSitePath([ + { + label: `Add Flashpack Version`, + link: `/tools/flashpack/add`, + }, + ]); + // eslint-disable-next-line react-hooks/exhaustive-deps + }, []); + + const onCarModelChange = (event) => { + setCarModel(event.target.value); + } + + const onCarYearChange = (event) => { + setCarYear(event.target.value); + } + + const onFlashpackChange = (event) => { + setFlashpack(event.target.value); + } + + const onSubmit = async (event) => { + try { + event.preventDefault(); + + const carFlashpackVersions = [] + for (let i = 0; i < mappingInputs.length; i++) { + carFlashpackVersions.push({ + "car_model": carModel, + "car_year": parseInt(carYear), + "flashpack": flashpack, + "car_ecu_name": mappingInputs[i].ecuName, + "car_ecu_version": mappingInputs[i].ecuVersion, + }) + } + + const result = await addFlashpackVersion(carModel, parseInt(carYear), flashpack, carFlashpackVersions, token); + if (!result || result.error) return; + + setMessage(`Added ${carYear} ${carModel} ${flashpack}`); + setRedirect(`/tools/flashpacks`); + } catch (e) { + setMessage(e.message); + logger.warn(e.stack); + } + }; + + if (redirect && redirect.length > 0) { + return ; + } + + // code for handling the dynamic input fields adapted from + // https://blog.stackademic.com/how-to-dynamically-add-input-fields-on-button-click-in-reactjs-ddf8d8fe495b + + const handleAddMappingInput = () => { + setMappingInputs([...mappingInputs, { ecuName: "", ecuVersion: "", }]); + }; + + const handleChange = (event, index) => { + let { name, value } = event.target; + let onChangeValue = [...mappingInputs]; + onChangeValue[index][name] = value; + setMappingInputs(onChangeValue); + }; + + const handleDeleteMappingInput = (index) => { + const newArray = [...mappingInputs]; + newArray.splice(index, 1); + setMappingInputs(newArray); + }; + + return ( +
    +
    +
    + + + +
    + {mappingInputs.map((item, index) => ( +
    + handleChange(event, index)} + type="text" + /> + handleChange(event, index)} + type="text" + /> + {mappingInputs.length > 1 && ( + + )} + {index === mappingInputs.length - 1 && ( + + )} +
    + ))} +
    {JSON.stringify(mappingInputs)}
    +
    +
    + +
    +
    + ); +}; + +const FlashpackAdd = () => ( + + + +); + +export default FlashpackAdd; \ No newline at end of file diff --git a/src/services/vehiclesAPI.js b/src/services/vehiclesAPI.js index 6280d14..1ad68ec 100644 --- a/src/services/vehiclesAPI.js +++ b/src/services/vehiclesAPI.js @@ -283,8 +283,8 @@ const vehiclesAPI = { .catch(errorHandler) }, - addFlashpackECUMapping: async (data, token) => { - return fetch(`${API_ENDPOINT}/flashpack_ecu_mapping`, { + addFlashpackVersion: async (data, token) => { + return fetch(`${API_ENDPOINT}/flashpack_version`, { method: "POST", headers: Object.assign( { "Content-Type": "application/json" }, From bf77a37139e43a5ebcceadee4420683b754e4fa0 Mon Sep 17 00:00:00 2001 From: padamsen_fisker Date: Tue, 16 Jan 2024 21:46:29 -0500 Subject: [PATCH 06/10] works, and looks good --- src/components/Flashpack/Add/index.jsx | 48 ++++++++++++++++------ src/components/Flashpack/Details/index.jsx | 11 ++++- src/components/Flashpack/index.jsx | 7 +++- 3 files changed, 50 insertions(+), 16 deletions(-) diff --git a/src/components/Flashpack/Add/index.jsx b/src/components/Flashpack/Add/index.jsx index 69d527a..a0b1df1 100644 --- a/src/components/Flashpack/Add/index.jsx +++ b/src/components/Flashpack/Add/index.jsx @@ -1,8 +1,11 @@ import { Button, + IconButton, TextField } from "@material-ui/core"; import React, { useEffect, useState } from "react"; +import AddCircleIcon from "@material-ui/icons/AddCircle"; +import DeleteIcon from "@material-ui/icons/Delete"; import { Redirect } from "react-router"; import { logger } from "../../../services/monitoring"; import { useStatusContext } from "../../Contexts/StatusContext"; @@ -31,9 +34,16 @@ const MainForm = () => { useEffect(() => { setTitle(`Add Flashpack Version`); setSitePath([ + { + label: "Tools", + link: "/tools/flashpacks", + }, + { + label: "Flashpack Versions", + link: "/tools/flashpacks", + }, { label: `Add Flashpack Version`, - link: `/tools/flashpack/add`, }, ]); // eslint-disable-next-line react-hooks/exhaustive-deps @@ -57,20 +67,21 @@ const MainForm = () => { const carFlashpackVersions = [] for (let i = 0; i < mappingInputs.length; i++) { - carFlashpackVersions.push({ - "car_model": carModel, - "car_year": parseInt(carYear), - "flashpack": flashpack, - "car_ecu_name": mappingInputs[i].ecuName, - "car_ecu_version": mappingInputs[i].ecuVersion, - }) + mappingInputs[i] && mappingInputs[i].ecuName && mappingInputs[i].ecuVersion && + carFlashpackVersions.push({ + "car_model": carModel, + "car_year": parseInt(carYear), + "flashpack": flashpack, + "car_ecu_name": mappingInputs[i].ecuName, + "car_ecu_version": mappingInputs[i].ecuVersion, + }) } const result = await addFlashpackVersion(carModel, parseInt(carYear), flashpack, carFlashpackVersions, token); if (!result || result.error) return; setMessage(`Added ${carYear} ${carModel} ${flashpack}`); - setRedirect(`/tools/flashpacks`); + setRedirect(`/tools/flashpack/${carModel}/${carYear}/${flashpack}`); } catch (e) { setMessage(e.message); logger.warn(e.stack); @@ -180,14 +191,27 @@ const MainForm = () => { type="text" /> {mappingInputs.length > 1 && ( - + handleDeleteMappingInput(index)} + aria-label={`Delete`} + size="small" + color="primary" + > + + )} {index === mappingInputs.length - 1 && ( - + handleAddMappingInput()} + aria-label={`Add`} + size="small" + color="primary" + > + + )} ))} -
    {JSON.stringify(mappingInputs)}
    + + + + + + + + + + + +`; diff --git a/src/components/Flashpack/Add/index.test.jsx b/src/components/Flashpack/Add/index.test.jsx new file mode 100644 index 0000000..ba1235b --- /dev/null +++ b/src/components/Flashpack/Add/index.test.jsx @@ -0,0 +1,46 @@ +jest.mock("../../Contexts/VehicleContext"); +jest.mock("../../Contexts/StatusContext"); +jest.mock("../../Contexts/UserContext"); +jest.mock("@material-ui/core/utils/unstable_useId", () => + jest.fn().mockReturnValue("mui-test-id") +); +import { render, waitFor } from "@testing-library/react"; +import { MemoryRouter, Route } from "react-router-dom"; +import { VehicleProvider } from "../../Contexts/VehicleContext"; +import { StatusProvider } from "../../Contexts/StatusContext"; +import { UserProvider, setToken } from "../../Contexts/UserContext"; +import { TEST_AUTH_OBJECT_FISKER } from "../../../utils/testing"; +import MainForm from "./index"; +import addSnapshotSerializer from "../../../utils/snapshot"; + +const renderFlashpackAdd = async () => { + const { container } = render( + + + + + + + + + + + + ); + await waitFor(() => { + /* render */ + }); + return container; +}; + +describe("FlashpackAdd", () => { + beforeAll(() => { + addSnapshotSerializer(expect); + }); + + it("Render", async () => { + setToken(TEST_AUTH_OBJECT_FISKER); + const container = await renderFlashpackAdd(); + expect(container).toMatchSnapshot(); + }); +}); diff --git a/src/components/Flashpack/Details/__snapshots__/index.test.jsx.snap b/src/components/Flashpack/Details/__snapshots__/index.test.jsx.snap new file mode 100644 index 0000000..303487f --- /dev/null +++ b/src/components/Flashpack/Details/__snapshots__/index.test.jsx.snap @@ -0,0 +1,99 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`FlashpackDetails Render 1`] = ` +
    +
    +
    +
    +
    +
    + + + + + + + + + + + + + +
    + + ECU Name + + + + + ECU Version + + +
    +
    +
    +
    +
    +
    +
    +`; diff --git a/src/components/Flashpack/Details/index.test.jsx b/src/components/Flashpack/Details/index.test.jsx new file mode 100644 index 0000000..b0f11fb --- /dev/null +++ b/src/components/Flashpack/Details/index.test.jsx @@ -0,0 +1,46 @@ +jest.mock("../../Contexts/VehicleContext"); +jest.mock("../../Contexts/StatusContext"); +jest.mock("../../Contexts/UserContext"); +jest.mock("@material-ui/core/utils/unstable_useId", () => + jest.fn().mockReturnValue("mui-test-id") +); +import { render, waitFor } from "@testing-library/react"; +import { MemoryRouter, Route } from "react-router-dom"; +import { VehicleProvider } from "../../Contexts/VehicleContext"; +import { StatusProvider } from "../../Contexts/StatusContext"; +import { UserProvider, setToken } from "../../Contexts/UserContext"; +import { TEST_AUTH_OBJECT_FISKER } from "../../../utils/testing"; +import MainForm from "./index"; +import addSnapshotSerializer from "../../../utils/snapshot"; + +const renderFlashpackDetails = async () => { + const { container } = render( + + + + + + + + + + + + ); + await waitFor(() => { + /* render */ + }); + return container; +}; + +describe("FlashpackDetails", () => { + beforeAll(() => { + addSnapshotSerializer(expect); + }); + + it("Render", async () => { + setToken(TEST_AUTH_OBJECT_FISKER); + const container = await renderFlashpackDetails(); + expect(container).toMatchSnapshot(); + }); +}); diff --git a/src/components/Flashpack/__snapshots__/index.test.jsx.snap b/src/components/Flashpack/__snapshots__/index.test.jsx.snap new file mode 100644 index 0000000..85aac96 --- /dev/null +++ b/src/components/Flashpack/__snapshots__/index.test.jsx.snap @@ -0,0 +1,152 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`Flashpack Render 1`] = ` +
    +
    +
    +
    +
    +
    +
    + +
    + + + + + + + + + + + + + + +
    + + Flashpack Number + + sorted descending + + + + + + Model + + + + + Year + + +
    +
    +
    +
    +
    +
    +
    +
    +`; diff --git a/src/components/Flashpack/index.jsx b/src/components/Flashpack/index.jsx index b403782..4534d8b 100644 --- a/src/components/Flashpack/index.jsx +++ b/src/components/Flashpack/index.jsx @@ -137,7 +137,10 @@ const MainForm = () => { {flashpacks && flashpacks.map((row, index) => ( diff --git a/src/components/Flashpack/index.test.jsx b/src/components/Flashpack/index.test.jsx new file mode 100644 index 0000000..1d282cf --- /dev/null +++ b/src/components/Flashpack/index.test.jsx @@ -0,0 +1,46 @@ +jest.mock("../Contexts/VehicleContext"); +jest.mock("../Contexts/StatusContext"); +jest.mock("../Contexts/UserContext"); +jest.mock("@material-ui/core/utils/unstable_useId", () => + jest.fn().mockReturnValue("mui-test-id") +); +import { render, waitFor } from "@testing-library/react"; +import { MemoryRouter, Route } from "react-router-dom"; +import { VehicleProvider } from "../Contexts/VehicleContext"; +import { StatusProvider } from "../Contexts/StatusContext"; +import { UserProvider, setToken } from "../Contexts/UserContext"; +import { TEST_AUTH_OBJECT_FISKER } from "../../utils/testing"; +import MainForm from "./index"; +import addSnapshotSerializer from "../../utils/snapshot"; + +const renderFlashpack = async () => { + const { container } = render( + + + + + + + + + + + + ); + await waitFor(() => { + /* render */ + }); + return container; +}; + +describe("Flashpack", () => { + beforeAll(() => { + addSnapshotSerializer(expect); + }); + + it("Render", async () => { + setToken(TEST_AUTH_OBJECT_FISKER); + const container = await renderFlashpack(); + expect(container).toMatchSnapshot(); + }); +}); From 4228876090e1932ae860c7880accfe4905b313b3 Mon Sep 17 00:00:00 2001 From: padamsen_fisker Date: Wed, 17 Jan 2024 10:37:22 -0500 Subject: [PATCH 09/10] fix --- src/components/Flashpack/index.jsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/Flashpack/index.jsx b/src/components/Flashpack/index.jsx index 4534d8b..dd8e1b1 100644 --- a/src/components/Flashpack/index.jsx +++ b/src/components/Flashpack/index.jsx @@ -140,7 +140,7 @@ const MainForm = () => { orderBy={"flashpack"} order={"desc"} columnData={tableColumns} - onSortRequest={null} + onSortRequest={() => { return null }} /> {flashpacks && flashpacks.map((row, index) => ( From f99130b40948fc700b2977a02c9055252376199e Mon Sep 17 00:00:00 2001 From: padamsen_fisker Date: Mon, 22 Jan 2024 11:32:31 -0500 Subject: [PATCH 10/10] Fixes from review --- src/components/Contexts/VehicleContext.jsx | 21 +++++----- .../Contexts/__mocks__/VehicleContext.jsx | 38 +++++++++++++++++++ src/components/Flashpack/Details/index.jsx | 2 +- .../__snapshots__/index.test.jsx.snap | 23 +++++++++++ src/components/Flashpack/index.jsx | 10 +++-- 5 files changed, 80 insertions(+), 14 deletions(-) diff --git a/src/components/Contexts/VehicleContext.jsx b/src/components/Contexts/VehicleContext.jsx index 3744469..7ebd07f 100644 --- a/src/components/Contexts/VehicleContext.jsx +++ b/src/components/Contexts/VehicleContext.jsx @@ -292,13 +292,13 @@ export const VehicleProvider = ({ children }) => { }; const getAllFlashpacks = async (options, token) => { - let result; try { setBusy(true); - result = await api.getAllFlashpacks(options, token); - if (result.error) + const 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) { @@ -312,13 +312,13 @@ export const VehicleProvider = ({ children }) => { }; const getFlashpackECUMappings = async (model, year, flashpack, options, token) => { - let result; try { setBusy(true); - result = await api.getFlashpackECUMappings(model, year, flashpack, options, token); - if (result.error) + const result = await api.getFlashpackECUMappings(model, year, flashpack, options, token); + if (result.error) { throw new Error(`Get flashpack ecu mappings error. ${result.message}`); + } setFlashpackECUMappings(result.data); if (options && options.offset === 0 && result.total) { @@ -343,8 +343,9 @@ export const VehicleProvider = ({ children }) => { } const result = await api.addFlashpackVersion(data, token) - if (result.error) + if (result.error) { throw new Error(`Add flashpack version error. ${result.message}`); + } return result; } finally { @@ -353,7 +354,6 @@ export const VehicleProvider = ({ children }) => { } const deleteFlashpackVersion = async (model, year, flashpack, token) => { - let result; try { setBusy(true); @@ -363,9 +363,10 @@ export const VehicleProvider = ({ children }) => { "flashpack": flashpack, } - result = await api.deleteFlashpackVersion(data, token); - if (result.error) + const result = await api.deleteFlashpackVersion(data, token); + if (result.error) { throw new Error(`Delete flashpack ecu mappings error. ${result.message}`); + } return result; } finally { diff --git a/src/components/Contexts/__mocks__/VehicleContext.jsx b/src/components/Contexts/__mocks__/VehicleContext.jsx index e280bc9..a996671 100644 --- a/src/components/Contexts/__mocks__/VehicleContext.jsx +++ b/src/components/Contexts/__mocks__/VehicleContext.jsx @@ -187,6 +187,44 @@ export const useVehicleContext = () => ({ total: 2, } }), + getAllFlashpacks: jest.fn((options, token) => { + return { + data: [ + { + flashpack: "44.4", + car_model: "Ocean", + car_year: "2023", + }, + { + flashpack: "38.4", + car_model: "Ocean", + car_year: "2023", + }, + ], + total: 2, + } + }), + getFlashpackECUMappings: jest.fn((model, year, flashpack, options, token) => { + return { + data: [ + { + flashpack: "44.4", + car_model: "Ocean", + car_year: "2023", + car_ecu_name: "ADAS", + car_ecu_version: "99", + }, + { + flashpack: "44.4", + car_model: "Ocean", + car_year: "2023", + car_ecu_name: "PDI", + car_ecu_version: "11", + }, + ], + total: 2, + } + }), }); export const setBusy = (val) => { diff --git a/src/components/Flashpack/Details/index.jsx b/src/components/Flashpack/Details/index.jsx index a40bb91..2fc8bee 100644 --- a/src/components/Flashpack/Details/index.jsx +++ b/src/components/Flashpack/Details/index.jsx @@ -146,7 +146,7 @@ const MainForm = () => { ) : ( + { /> {flashpacks && flashpacks.map((row, index) => ( - + {row.flashpack} @@ -156,7 +160,7 @@ const MainForm = () => { {row.car_year} - + { ) : (
    + + Delete + + +