diff --git a/src/components/App/__snapshots__/App.test.js.snap b/src/components/App/__snapshots__/App.test.js.snap
index 637ad6b..c42b644 100644
--- a/src/components/App/__snapshots__/App.test.js.snap
+++ b/src/components/App/__snapshots__/App.test.js.snap
@@ -6918,6 +6918,24 @@ exports[`App Route /vehicle-status authenticated 1`] = `
class="MuiTouchRipple-root"
/>
+
+
diff --git a/src/components/CANFilter/Table/index.jsx b/src/components/CANFilter/Table/index.jsx
index 61b2a7a..55d985d 100644
--- a/src/components/CANFilter/Table/index.jsx
+++ b/src/components/CANFilter/Table/index.jsx
@@ -53,6 +53,7 @@ const PAGE_SIZE = "CAN_FILTER_TABLE_PAGE_SIZE";
const MainForm = ({ vin }) => {
const classes = useStyles();
+ const [search, onSearch] = useState("");
const [pageSize, setPageSize] = useLocalStorage(PAGE_SIZE, 10);
const [pageIndex, setPageIndex] = useState(0);
const [orderBy, setOrderBy] = useState("id");
@@ -68,6 +69,7 @@ const MainForm = ({ vin }) => {
await getFilters(
vin,
{
+ search,
limit: pageSize,
offset: pageSize * pageIndex,
order: `${orderBy} ${order}`,
@@ -80,7 +82,7 @@ const MainForm = ({ vin }) => {
}
})();
// eslint-disable-next-line react-hooks/exhaustive-deps
- }, [vin, token, pageIndex, pageSize, orderBy, order]);
+ }, [vin, token, pageIndex, pageSize, orderBy, order, search]);
const handleChangePageIndex = (event, newIndex) => {
setPageIndex(newIndex);
@@ -166,7 +168,7 @@ const MainForm = ({ vin }) => {
-
+
diff --git a/src/components/Cars/Status/FleetsTab.jsx b/src/components/Cars/Status/FleetsTab.jsx
new file mode 100644
index 0000000..f981fd0
--- /dev/null
+++ b/src/components/Cars/Status/FleetsTab.jsx
@@ -0,0 +1,140 @@
+import useStyles from "../../useStyles";
+import clsx from "clsx";
+import {Grid, Table, TableBody, TableCell, TableFooter, TablePagination, TableRow, Typography} from "@material-ui/core";
+import React, {useEffect, useState} from "react";
+import {useVehicleContext, VehicleProvider} from "../../Contexts/VehicleContext";
+import SearchField from "../../Controls/SearchField";
+import {useLocalStorage} from "../../useLocalStorage";
+import {useStatusContext} from "../../Contexts/StatusContext";
+import {useUserContext} from "../../Contexts/UserContext";
+import {logger} from "../../../services/monitoring";
+import TableHeaderSortable from "../../Table/HeaderSortable";
+import {Link} from "react-router-dom";
+
+const PAGE_SIZE = "VEHICLE_FLEETS_TABLE_PAGE_SIZE";
+
+const tableColumns = [
+ {
+ id: "fleet",
+ label: "CAN ID"
+ },
+];
+
+const MainForm = (props) => {
+ const classes = useStyles();
+ const {vin} = props;
+
+ const [search, onSearch] = useState("");
+ const [pageSize, setPageSize] = useLocalStorage(PAGE_SIZE, 10);
+ const [pageIndex, setPageIndex] = useState(0);
+ const [orderBy, setOrderBy] = useState("id");
+ const [order, setOrder] = useState("desc");
+ const {setMessage} = useStatusContext();
+ const {token: {idToken: {jwtToken: token}}} = useUserContext();
+ const {getFleets, fleets, totalFleets} = useVehicleContext();
+
+ useEffect(() => {
+ (async () => {
+ try {
+ if (!vin || !token) return;
+ await getFleets(
+ vin,
+ {
+ search,
+ limit: pageSize,
+ offset: pageSize * pageIndex,
+ order: `${orderBy} ${order}`,
+ },
+ token
+ );
+ } catch (e) {
+ setMessage(e.message);
+ logger.warn(e.stack);
+ }
+ })();
+ // eslint-disable-next-line react-hooks/exhaustive-deps
+ }, [vin, token, pageIndex, pageSize, orderBy, order, search]);
+
+ 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 (
+
+
Fleets
+
+
+
+
+
+
+
+
+ {fleets.map((row) => (
+
+
+ {row}
+
+
+ ))}
+
+
+
+
+
+
+
+
+ )
+}
+
+const FleetsTab = (props) => {
+ return (
+
+
+
+ )
+}
+
+
+export default FleetsTab;
\ No newline at end of file
diff --git a/src/components/Cars/Status/FleetsTab.test.jsx b/src/components/Cars/Status/FleetsTab.test.jsx
new file mode 100644
index 0000000..58fad88
--- /dev/null
+++ b/src/components/Cars/Status/FleetsTab.test.jsx
@@ -0,0 +1,47 @@
+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 React from "react";
+import {render, waitFor} from "@testing-library/react";
+import { BrowserRouter } from "react-router-dom";
+
+import {StatusProvider} from "../../Contexts/StatusContext";
+import {VehicleProvider} from "../../Contexts/VehicleContext";
+import {setToken, UserProvider} from "../../Contexts/UserContext";
+import {TEST_AUTH_OBJECT} from "../../../utils/testing";
+import addSnapshotSerializer from "../../../utils/snapshot";
+import FleetsTab from "./FleetsTab";
+
+const renderFleetsTab = async () => {
+ const {container} = render(
+
+
+
+
+
+
+
+
+
+ );
+ await waitFor(() => {
+ /* render */
+ });
+ return container;
+};
+
+describe("FleetsTab", () => {
+ beforeAll(() => {
+ addSnapshotSerializer(expect);
+ });
+
+ it("Render", async () => {
+ setToken(TEST_AUTH_OBJECT);
+ const container = await renderFleetsTab();
+ expect(container).toMatchSnapshot();
+ });
+});
diff --git a/src/components/Cars/Status/__snapshots__/FleetsTab.test.jsx.snap b/src/components/Cars/Status/__snapshots__/FleetsTab.test.jsx.snap
new file mode 100644
index 0000000..4353af6
--- /dev/null
+++ b/src/components/Cars/Status/__snapshots__/FleetsTab.test.jsx.snap
@@ -0,0 +1,280 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`FleetsTab Render 1`] = `
+
+`;
diff --git a/src/components/Cars/Status/__snapshots__/index.test.jsx.snap b/src/components/Cars/Status/__snapshots__/index.test.jsx.snap
index 02f5063..87bafee 100644
--- a/src/components/Cars/Status/__snapshots__/index.test.jsx.snap
+++ b/src/components/Cars/Status/__snapshots__/index.test.jsx.snap
@@ -137,6 +137,24 @@ exports[`CarStatus Render 1`] = `
class="MuiTouchRipple-root"
/>
+
+
diff --git a/src/components/Cars/Status/index.jsx b/src/components/Cars/Status/index.jsx
index 0943eb7..bed8b79 100644
--- a/src/components/Cars/Status/index.jsx
+++ b/src/components/Cars/Status/index.jsx
@@ -13,6 +13,7 @@ import { useStatusContext } from "../../Contexts/StatusContext";
import useStyles from "../../useStyles";
import CANSignalsTab from "./CANSignalsTab";
import RemoteCommandsTab from "./RemoteCommandsTab";
+import FleetsTab from "./FleetsTab";
const tabHashes = ["details", "updates", "filters"];
@@ -66,6 +67,8 @@ const CarStatus = () => {
+
+
@@ -92,6 +95,10 @@ const CarStatus = () => {
+
+
+
+
);
};
diff --git a/src/components/Contexts/VehicleContext.jsx b/src/components/Contexts/VehicleContext.jsx
index 657dbec..3896f9d 100644
--- a/src/components/Contexts/VehicleContext.jsx
+++ b/src/components/Contexts/VehicleContext.jsx
@@ -31,6 +31,8 @@ export const VehicleProvider = ({ children }) => {
const [vehicle, setVehicle] = useState({});
const [vehicles, setVehicles] = useState([]);
const [totalVehicles, setTotalVehicles] = useState(0);
+ const [fleets, setFleets] = useState([]);
+ const [totalFleets, setTotalFleets] = useState(0);
const [models, setModels] = useState([]);
const [years, setYears] = useState([]);
@@ -220,6 +222,25 @@ export const VehicleProvider = ({ children }) => {
}
};
+ const getFleets = async (vin, search, token) => {
+ try {
+ setBusy(true);
+ validateVIN(vin);
+
+ const result = await api.getFleets(vin, search, token);
+ if (result.error) {
+ setFleets([]);
+ throw new Error(`Get Fleets of vehicle`)
+ }
+ setFleets(result.data ?? []);
+ if (result.total) {
+ setTotalFleets(result.total);
+ }
+ } finally {
+ setBusy(false)
+ }
+ }
+
return (
{
vehicle,
vehicles,
years,
+ fleets,
+ totalFleets,
addVehicle,
deleteVehicle,
getConnections,
@@ -242,6 +265,7 @@ export const VehicleProvider = ({ children }) => {
getVehicles,
sendCommand,
updateVehicle,
+ getFleets,
}}
>
{children}
diff --git a/src/components/Contexts/VehicleContext.test.jsx b/src/components/Contexts/VehicleContext.test.jsx
index cda9d11..6478414 100644
--- a/src/components/Contexts/VehicleContext.test.jsx
+++ b/src/components/Contexts/VehicleContext.test.jsx
@@ -20,12 +20,57 @@ const checkVehiclesResult = (error, busy, vehicles) => {
expect(screen.getByTestId("vehicles").innerHTML).toEqual(vehicles);
};
+const checkFleetsResult = (error, busy, fleets) => {
+ checkBaseResults(error, busy);
+ expect(screen.getByTestId("fleets").innerHTML).toEqual(fleets);
+}
+
const checkBaseResults = (error, busy) => {
expect(screen.getByTestId("error").innerHTML).toEqual(error);
expect(screen.getByTestId("busy").innerHTML).toEqual(busy);
};
describe("VehicleContext", () => {
+ describe("getFleets", () => {
+ beforeEach(() => {
+ const TestComp = () => {
+ const { busy, error, fleets, getFleets } = useVehicleContext();
+
+ return (
+ <>
+ {error}
+ {busy.toString()}
+ {JSON.stringify(fleets)}
+