CEC-3519 Add car version history (#260)
* CEC-3519 Add car version history CEC-3455 Delete button is icon and remove column CEC-3496 Fix Issue delete * smell * Remove tab from issues details page * Fix date format
This commit is contained in:
@@ -1752,115 +1752,64 @@ exports[`App Route /issue-info authenticated 1`] = `
|
|||||||
class="makeStyles-paper-0 makeStyles-tableSize-0"
|
class="makeStyles-paper-0 makeStyles-tableSize-0"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
class="MuiBox-root MuiBox-root-0 makeStyles-tableToolbar-0"
|
class="makeStyles-paper-0 makeStyles-tableSize-0"
|
||||||
>
|
>
|
||||||
<div
|
<h6
|
||||||
class="MuiTabs-root"
|
class="MuiTypography-root MuiTypography-h6"
|
||||||
>
|
>
|
||||||
<div
|
Issue Details
|
||||||
class="MuiTabs-scroller MuiTabs-fixed"
|
</h6>
|
||||||
style="overflow: hidden;"
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
aria-label="issue tabs"
|
|
||||||
class="MuiTabs-flexContainer"
|
|
||||||
role="tablist"
|
|
||||||
>
|
|
||||||
<button
|
|
||||||
aria-controls="tabpanel-0"
|
|
||||||
aria-selected="true"
|
|
||||||
class="MuiButtonBase-root MuiTab-root MuiTab-textColorInherit Mui-selected"
|
|
||||||
id="tab-0"
|
|
||||||
role="tab"
|
|
||||||
tabindex="0"
|
|
||||||
type="button"
|
|
||||||
>
|
|
||||||
<span
|
|
||||||
class="MuiTab-wrapper"
|
|
||||||
>
|
|
||||||
Details
|
|
||||||
</span>
|
|
||||||
<span
|
|
||||||
class="MuiTouchRipple-root"
|
|
||||||
/>
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
<span
|
|
||||||
class="PrivateTabIndicator-root-0 PrivateTabIndicator-colorSecondary-0 MuiTabs-indicator"
|
|
||||||
style="left: 0px; width: 0px;"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div
|
|
||||||
aria-labelledby="tab-0"
|
|
||||||
id="tabpanel-0"
|
|
||||||
role="tabpanel"
|
|
||||||
>
|
|
||||||
<div
|
<div
|
||||||
class="MuiBox-root MuiBox-root-0"
|
data-testid="mocked-issueprovider"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
class="makeStyles-paper-0 makeStyles-tableSize-0"
|
class="makeStyles-paper-0 makeStyles-tableSize-0"
|
||||||
>
|
>
|
||||||
<h6
|
|
||||||
class="MuiTypography-root MuiTypography-h6"
|
|
||||||
>
|
|
||||||
Issue Details
|
|
||||||
</h6>
|
|
||||||
<div
|
<div
|
||||||
data-testid="mocked-issueprovider"
|
class="MuiGrid-root makeStyles-root-0 MuiGrid-container MuiGrid-spacing-xs-2"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
class="makeStyles-paper-0 makeStyles-tableSize-0"
|
class="MuiGrid-root makeStyles-textCenterAlign-0 MuiGrid-item MuiGrid-grid-md-12"
|
||||||
>
|
>
|
||||||
<div
|
<p>
|
||||||
class="MuiGrid-root makeStyles-root-0 MuiGrid-container MuiGrid-spacing-xs-2"
|
<b>
|
||||||
>
|
ID
|
||||||
<div
|
</b>
|
||||||
class="MuiGrid-root makeStyles-textCenterAlign-0 MuiGrid-item MuiGrid-grid-md-12"
|
:
|
||||||
>
|
FISKER123
|
||||||
<p>
|
</p>
|
||||||
<b>
|
<p>
|
||||||
ID
|
<b>
|
||||||
</b>
|
VIN
|
||||||
:
|
</b>
|
||||||
FISKER123
|
:
|
||||||
</p>
|
1GNGC26RXXJ407648
|
||||||
<p>
|
</p>
|
||||||
<b>
|
<p>
|
||||||
VIN
|
<b>
|
||||||
</b>
|
Title
|
||||||
:
|
</b>
|
||||||
1GNGC26RXXJ407648
|
:
|
||||||
</p>
|
sometitle
|
||||||
<p>
|
</p>
|
||||||
<b>
|
<p>
|
||||||
Title
|
<b>
|
||||||
</b>
|
Description
|
||||||
:
|
</b>
|
||||||
sometitle
|
:
|
||||||
</p>
|
2343242
|
||||||
<p>
|
</p>
|
||||||
<b>
|
<p>
|
||||||
Description
|
<b>
|
||||||
</b>
|
timestamp
|
||||||
:
|
</b>
|
||||||
2343242
|
:
|
||||||
</p>
|
12/9/2022 11:16:38 PM
|
||||||
<p>
|
</p>
|
||||||
<b>
|
<img
|
||||||
timestamp
|
alt="Issue images"
|
||||||
</b>
|
src="data:image/png;base64, SGVsbG8x"
|
||||||
:
|
/>
|
||||||
2022-12-09T23:16:38.074858Z
|
|
||||||
</p>
|
|
||||||
<img
|
|
||||||
alt="Issue images"
|
|
||||||
src="data:image/png;base64, SGVsbG8x"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -2472,29 +2421,6 @@ exports[`App Route /issues authenticated 1`] = `
|
|||||||
</svg>
|
</svg>
|
||||||
</span>
|
</span>
|
||||||
</th>
|
</th>
|
||||||
<th
|
|
||||||
class="MuiTableCell-root MuiTableCell-head MuiTableCell-alignCenter"
|
|
||||||
scope="col"
|
|
||||||
>
|
|
||||||
<span
|
|
||||||
aria-disabled="false"
|
|
||||||
class="MuiButtonBase-root MuiTableSortLabel-root"
|
|
||||||
role="button"
|
|
||||||
tabindex="0"
|
|
||||||
>
|
|
||||||
Description
|
|
||||||
<svg
|
|
||||||
aria-hidden="true"
|
|
||||||
class="MuiSvgIcon-root MuiTableSortLabel-icon MuiTableSortLabel-iconDirectionAsc"
|
|
||||||
focusable="false"
|
|
||||||
viewBox="0 0 24 24"
|
|
||||||
>
|
|
||||||
<path
|
|
||||||
d="M20 12l-1.41-1.41L13 16.17V4h-2v12.17l-5.58-5.59L4 12l8 8 8-8z"
|
|
||||||
/>
|
|
||||||
</svg>
|
|
||||||
</span>
|
|
||||||
</th>
|
|
||||||
<th
|
<th
|
||||||
class="MuiTableCell-root MuiTableCell-head MuiTableCell-alignCenter"
|
class="MuiTableCell-root MuiTableCell-head MuiTableCell-alignCenter"
|
||||||
scope="col"
|
scope="col"
|
||||||
@@ -2578,11 +2504,6 @@ exports[`App Route /issues authenticated 1`] = `
|
|||||||
>
|
>
|
||||||
sometitle
|
sometitle
|
||||||
</td>
|
</td>
|
||||||
<td
|
|
||||||
class="MuiTableCell-root MuiTableCell-body MuiTableCell-alignCenter"
|
|
||||||
>
|
|
||||||
2343242
|
|
||||||
</td>
|
|
||||||
<td
|
<td
|
||||||
class="MuiTableCell-root MuiTableCell-body MuiTableCell-alignCenter"
|
class="MuiTableCell-root MuiTableCell-body MuiTableCell-alignCenter"
|
||||||
>
|
>
|
||||||
@@ -2616,11 +2537,6 @@ exports[`App Route /issues authenticated 1`] = `
|
|||||||
>
|
>
|
||||||
sometitle
|
sometitle
|
||||||
</td>
|
</td>
|
||||||
<td
|
|
||||||
class="MuiTableCell-root MuiTableCell-body MuiTableCell-alignCenter"
|
|
||||||
>
|
|
||||||
2343242
|
|
||||||
</td>
|
|
||||||
<td
|
<td
|
||||||
class="MuiTableCell-root MuiTableCell-body MuiTableCell-alignCenter"
|
class="MuiTableCell-root MuiTableCell-body MuiTableCell-alignCenter"
|
||||||
>
|
>
|
||||||
@@ -2639,8 +2555,122 @@ exports[`App Route /issues authenticated 1`] = `
|
|||||||
<tr
|
<tr
|
||||||
class="MuiTableRow-root MuiTableRow-footer"
|
class="MuiTableRow-root MuiTableRow-footer"
|
||||||
>
|
>
|
||||||
<td>
|
<td
|
||||||
No issues found
|
class="MuiTableCell-root MuiTableCell-footer MuiTablePagination-root"
|
||||||
|
colspan="6"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
class="MuiToolbar-root MuiToolbar-regular MuiTablePagination-toolbar MuiToolbar-gutters"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
class="MuiTablePagination-spacer"
|
||||||
|
/>
|
||||||
|
<p
|
||||||
|
class="MuiTypography-root MuiTablePagination-caption MuiTypography-body2 MuiTypography-colorInherit"
|
||||||
|
id="mui-0"
|
||||||
|
>
|
||||||
|
Rows per page:
|
||||||
|
</p>
|
||||||
|
<div
|
||||||
|
class="MuiInputBase-root MuiTablePagination-input MuiTablePagination-selectRoot"
|
||||||
|
>
|
||||||
|
<select
|
||||||
|
aria-label="rows per page"
|
||||||
|
class="MuiSelect-root MuiSelect-select MuiTablePagination-select MuiInputBase-input"
|
||||||
|
id="mui-0"
|
||||||
|
>
|
||||||
|
<option
|
||||||
|
class="MuiTablePagination-menuItem"
|
||||||
|
value="5"
|
||||||
|
>
|
||||||
|
5
|
||||||
|
</option>
|
||||||
|
<option
|
||||||
|
class="MuiTablePagination-menuItem"
|
||||||
|
value="10"
|
||||||
|
>
|
||||||
|
10
|
||||||
|
</option>
|
||||||
|
<option
|
||||||
|
class="MuiTablePagination-menuItem"
|
||||||
|
value="25"
|
||||||
|
>
|
||||||
|
25
|
||||||
|
</option>
|
||||||
|
<option
|
||||||
|
class="MuiTablePagination-menuItem"
|
||||||
|
value="100"
|
||||||
|
>
|
||||||
|
100
|
||||||
|
</option>
|
||||||
|
</select>
|
||||||
|
<svg
|
||||||
|
aria-hidden="true"
|
||||||
|
class="MuiSvgIcon-root MuiSelect-icon MuiTablePagination-selectIcon"
|
||||||
|
focusable="false"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
d="M7 10l5 5 5-5z"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
</div>
|
||||||
|
<p
|
||||||
|
class="MuiTypography-root MuiTablePagination-caption MuiTypography-body2 MuiTypography-colorInherit"
|
||||||
|
>
|
||||||
|
0-0 of 0
|
||||||
|
</p>
|
||||||
|
<div
|
||||||
|
class="MuiTablePagination-actions"
|
||||||
|
>
|
||||||
|
<button
|
||||||
|
aria-label="Previous page"
|
||||||
|
class="MuiButtonBase-root MuiIconButton-root MuiIconButton-colorInherit Mui-disabled Mui-disabled"
|
||||||
|
disabled=""
|
||||||
|
tabindex="-1"
|
||||||
|
title="Previous page"
|
||||||
|
type="button"
|
||||||
|
>
|
||||||
|
<span
|
||||||
|
class="MuiIconButton-label"
|
||||||
|
>
|
||||||
|
<svg
|
||||||
|
aria-hidden="true"
|
||||||
|
class="MuiSvgIcon-root"
|
||||||
|
focusable="false"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
d="M15.41 16.09l-4.58-4.59 4.58-4.59L14 5.5l-6 6 6 6z"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
</span>
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
aria-label="Next page"
|
||||||
|
class="MuiButtonBase-root MuiIconButton-root MuiIconButton-colorInherit Mui-disabled Mui-disabled"
|
||||||
|
disabled=""
|
||||||
|
tabindex="-1"
|
||||||
|
title="Next page"
|
||||||
|
type="button"
|
||||||
|
>
|
||||||
|
<span
|
||||||
|
class="MuiIconButton-label"
|
||||||
|
>
|
||||||
|
<svg
|
||||||
|
aria-hidden="true"
|
||||||
|
class="MuiSvgIcon-root"
|
||||||
|
focusable="false"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
d="M8.59 16.34l4.58-4.59-4.58-4.59L10 5.75l6 6-6 6z"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
</span>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
</tfoot>
|
</tfoot>
|
||||||
@@ -9623,8 +9653,12 @@ exports[`App Route /vehicle-status authenticated 1`] = `
|
|||||||
class="MuiTabs-root"
|
class="MuiTabs-root"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
class="MuiTabs-scroller MuiTabs-fixed"
|
class="MuiTabs-scrollable"
|
||||||
style="overflow: hidden;"
|
style="width: 99px; height: 99px; position: absolute; top: -9999px; overflow: scroll;"
|
||||||
|
/>
|
||||||
|
<div
|
||||||
|
class="MuiTabs-scroller MuiTabs-scrollable"
|
||||||
|
style="margin-bottom: 0px;"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
aria-label="car tabs"
|
aria-label="car tabs"
|
||||||
@@ -9733,7 +9767,7 @@ exports[`App Route /vehicle-status authenticated 1`] = `
|
|||||||
<span
|
<span
|
||||||
class="MuiTab-wrapper"
|
class="MuiTab-wrapper"
|
||||||
>
|
>
|
||||||
Remote Commands
|
ECUs
|
||||||
</span>
|
</span>
|
||||||
<span
|
<span
|
||||||
class="MuiTouchRipple-root"
|
class="MuiTouchRipple-root"
|
||||||
@@ -9747,6 +9781,24 @@ exports[`App Route /vehicle-status authenticated 1`] = `
|
|||||||
role="tab"
|
role="tab"
|
||||||
tabindex="-1"
|
tabindex="-1"
|
||||||
type="button"
|
type="button"
|
||||||
|
>
|
||||||
|
<span
|
||||||
|
class="MuiTab-wrapper"
|
||||||
|
>
|
||||||
|
Remote Commands
|
||||||
|
</span>
|
||||||
|
<span
|
||||||
|
class="MuiTouchRipple-root"
|
||||||
|
/>
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
aria-controls="tabpanel-7"
|
||||||
|
aria-selected="false"
|
||||||
|
class="MuiButtonBase-root MuiTab-root MuiTab-textColorInherit"
|
||||||
|
id="tab-7"
|
||||||
|
role="tab"
|
||||||
|
tabindex="-1"
|
||||||
|
type="button"
|
||||||
>
|
>
|
||||||
<span
|
<span
|
||||||
class="MuiTab-wrapper"
|
class="MuiTab-wrapper"
|
||||||
@@ -9972,6 +10024,12 @@ exports[`App Route /vehicle-status authenticated 1`] = `
|
|||||||
id="tabpanel-6"
|
id="tabpanel-6"
|
||||||
role="tabpanel"
|
role="tabpanel"
|
||||||
/>
|
/>
|
||||||
|
<div
|
||||||
|
aria-labelledby="tab-7"
|
||||||
|
hidden=""
|
||||||
|
id="tabpanel-7"
|
||||||
|
role="tabpanel"
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
</main>
|
</main>
|
||||||
</main>
|
</main>
|
||||||
|
|||||||
@@ -1,12 +1,12 @@
|
|||||||
|
import { Typography } from "@material-ui/core";
|
||||||
|
import clsx from "clsx";
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import { useParams } from "react-router";
|
import { useParams } from "react-router";
|
||||||
import clsx from "clsx";
|
|
||||||
import { Typography } from "@material-ui/core";
|
|
||||||
|
|
||||||
import CarECUsTable from "../../Controls/CarECUsTable";
|
|
||||||
import CarUpdatesTable from "../../Controls/CarUpdatesTable";
|
|
||||||
import { VehicleProvider } from "../../Contexts/VehicleContext";
|
|
||||||
import { useUserContext } from "../../Contexts/UserContext";
|
import { useUserContext } from "../../Contexts/UserContext";
|
||||||
|
import { VehicleProvider } from "../../Contexts/VehicleContext";
|
||||||
|
import CarUpdatesTable from "../../Controls/CarUpdatesTable";
|
||||||
|
import CarVersionLogTable from "../../Controls/CarVersionLogTable";
|
||||||
import useStyles from "../../useStyles";
|
import useStyles from "../../useStyles";
|
||||||
|
|
||||||
const MainForm = () => {
|
const MainForm = () => {
|
||||||
@@ -22,10 +22,8 @@ const MainForm = () => {
|
|||||||
<div className={clsx(classes.paper, classes.tableSize)}>
|
<div className={clsx(classes.paper, classes.tableSize)}>
|
||||||
<Typography variant="h6">Car Updates</Typography>
|
<Typography variant="h6">Car Updates</Typography>
|
||||||
<CarUpdatesTable vin={vin} token={token} classes={classes} />
|
<CarUpdatesTable vin={vin} token={token} classes={classes} />
|
||||||
<Typography variant="h6" className={classes.labelInline}>
|
<Typography variant="h6" className={classes.labelInline}>Version Log</Typography>
|
||||||
Car ECUs
|
<CarVersionLogTable vin={vin} token={token} classes={classes} />
|
||||||
</Typography>
|
|
||||||
<CarECUsTable vin={vin} token={token} classes={classes} />
|
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
jest.mock("../../Contexts/CANFiltersContext");
|
jest.mock("../../Contexts/CANFiltersContext");
|
||||||
jest.mock("../../Contexts/StatusContext");
|
jest.mock("../../Contexts/StatusContext");
|
||||||
jest.mock("../../Contexts/UserContext");
|
jest.mock("../../Contexts/UserContext");
|
||||||
|
jest.mock("../../../services/vehiclesAPI");
|
||||||
jest.mock("@material-ui/core/utils/unstable_useId", () =>
|
jest.mock("@material-ui/core/utils/unstable_useId", () =>
|
||||||
jest.fn().mockReturnValue("mui-test-id")
|
jest.fn().mockReturnValue("mui-test-id")
|
||||||
);
|
);
|
||||||
@@ -8,12 +9,12 @@ jest.mock("@material-ui/core/utils/unstable_useId", () =>
|
|||||||
import { render, waitFor } from "@testing-library/react";
|
import { render, waitFor } from "@testing-library/react";
|
||||||
import { BrowserRouter } from "react-router-dom";
|
import { BrowserRouter } from "react-router-dom";
|
||||||
|
|
||||||
|
import addSnapshotSerializer from "../../../utils/snapshot";
|
||||||
|
import { TEST_AUTH_OBJECT_FISKER } from "../../../utils/testing";
|
||||||
import { CANFiltersProvider } from "../../Contexts/CANFiltersContext";
|
import { CANFiltersProvider } from "../../Contexts/CANFiltersContext";
|
||||||
import { StatusProvider } from "../../Contexts/StatusContext";
|
import { StatusProvider } from "../../Contexts/StatusContext";
|
||||||
import { UserProvider, setToken } from "../../Contexts/UserContext";
|
import { setToken, UserProvider } from "../../Contexts/UserContext";
|
||||||
import { TEST_AUTH_OBJECT_FISKER } from "../../../utils/testing";
|
|
||||||
import MainForm from "./CarUpdatesTab";
|
import MainForm from "./CarUpdatesTab";
|
||||||
import addSnapshotSerializer from "../../../utils/snapshot";
|
|
||||||
|
|
||||||
const renderCarUpdatesTab = async () => {
|
const renderCarUpdatesTab = async () => {
|
||||||
const { container } = render(
|
const { container } = render(
|
||||||
|
|||||||
36
src/components/Cars/Status/ECUsTab.jsx
Normal file
36
src/components/Cars/Status/ECUsTab.jsx
Normal file
@@ -0,0 +1,36 @@
|
|||||||
|
import { Typography } from "@material-ui/core";
|
||||||
|
import clsx from "clsx";
|
||||||
|
import React from "react";
|
||||||
|
import { useParams } from "react-router";
|
||||||
|
|
||||||
|
import { useUserContext } from "../../Contexts/UserContext";
|
||||||
|
import { VehicleProvider } from "../../Contexts/VehicleContext";
|
||||||
|
import CarECUsTable from "../../Controls/CarECUsTable";
|
||||||
|
import useStyles from "../../useStyles";
|
||||||
|
|
||||||
|
const MainForm = () => {
|
||||||
|
const { vin } = useParams();
|
||||||
|
const classes = useStyles();
|
||||||
|
const {
|
||||||
|
token: {
|
||||||
|
idToken: { jwtToken: token },
|
||||||
|
},
|
||||||
|
} = useUserContext();
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className={clsx(classes.paper, classes.tableSize)}>
|
||||||
|
<Typography variant="h6" className={classes.labelInline}>
|
||||||
|
Car ECUs
|
||||||
|
</Typography>
|
||||||
|
<CarECUsTable vin={vin} token={token} classes={classes} />
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
const CarUpdatesTab = () => (
|
||||||
|
<VehicleProvider>
|
||||||
|
<MainForm />
|
||||||
|
</VehicleProvider>
|
||||||
|
);
|
||||||
|
|
||||||
|
export default CarUpdatesTab;
|
||||||
44
src/components/Cars/Status/ECUsTab.test.jsx
Normal file
44
src/components/Cars/Status/ECUsTab.test.jsx
Normal file
@@ -0,0 +1,44 @@
|
|||||||
|
jest.mock("../../Contexts/CANFiltersContext");
|
||||||
|
jest.mock("../../Contexts/StatusContext");
|
||||||
|
jest.mock("../../Contexts/UserContext");
|
||||||
|
jest.mock("../../../services/vehiclesAPI");
|
||||||
|
jest.mock("@material-ui/core/utils/unstable_useId", () =>
|
||||||
|
jest.fn().mockReturnValue("mui-test-id")
|
||||||
|
);
|
||||||
|
|
||||||
|
import { render, waitFor } from "@testing-library/react";
|
||||||
|
import { BrowserRouter } from "react-router-dom";
|
||||||
|
|
||||||
|
import addSnapshotSerializer from "../../../utils/snapshot";
|
||||||
|
import { TEST_AUTH_OBJECT_FISKER } from "../../../utils/testing";
|
||||||
|
import { StatusProvider } from "../../Contexts/StatusContext";
|
||||||
|
import { setToken, UserProvider } from "../../Contexts/UserContext";
|
||||||
|
import MainForm from "./ECUsTab";
|
||||||
|
|
||||||
|
const renderECUsTab = async () => {
|
||||||
|
const { container } = render(
|
||||||
|
<StatusProvider>
|
||||||
|
<UserProvider>
|
||||||
|
<BrowserRouter>
|
||||||
|
<MainForm vin="TESTVIN1234567890" />
|
||||||
|
</BrowserRouter>
|
||||||
|
</UserProvider>
|
||||||
|
</StatusProvider>
|
||||||
|
);
|
||||||
|
await waitFor(() => {
|
||||||
|
/* render */
|
||||||
|
});
|
||||||
|
return container;
|
||||||
|
};
|
||||||
|
|
||||||
|
describe("ECUsTab", () => {
|
||||||
|
beforeAll(() => {
|
||||||
|
addSnapshotSerializer(expect);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("Render", async () => {
|
||||||
|
setToken(TEST_AUTH_OBJECT_FISKER);
|
||||||
|
const container = await renderECUsTab();
|
||||||
|
expect(container).toMatchSnapshot();
|
||||||
|
});
|
||||||
|
});
|
||||||
@@ -173,7 +173,7 @@ exports[`CarUpdatesTab Render 1`] = `
|
|||||||
<h6
|
<h6
|
||||||
class="MuiTypography-root makeStyles-labelInline-0 MuiTypography-h6"
|
class="MuiTypography-root makeStyles-labelInline-0 MuiTypography-h6"
|
||||||
>
|
>
|
||||||
Car ECUs
|
Version Log
|
||||||
</h6>
|
</h6>
|
||||||
<div
|
<div
|
||||||
class="makeStyles-paper-0 makeStyles-tableSize-0"
|
class="makeStyles-paper-0 makeStyles-tableSize-0"
|
||||||
@@ -187,6 +187,52 @@ exports[`CarUpdatesTab Render 1`] = `
|
|||||||
<tr
|
<tr
|
||||||
class="MuiTableRow-root MuiTableRow-head"
|
class="MuiTableRow-root MuiTableRow-head"
|
||||||
>
|
>
|
||||||
|
<th
|
||||||
|
class="MuiTableCell-root MuiTableCell-head MuiTableCell-alignCenter"
|
||||||
|
scope="col"
|
||||||
|
>
|
||||||
|
<span
|
||||||
|
aria-disabled="false"
|
||||||
|
class="MuiButtonBase-root MuiTableSortLabel-root"
|
||||||
|
role="button"
|
||||||
|
tabindex="0"
|
||||||
|
>
|
||||||
|
Type
|
||||||
|
<svg
|
||||||
|
aria-hidden="true"
|
||||||
|
class="MuiSvgIcon-root MuiTableSortLabel-icon MuiTableSortLabel-iconDirectionAsc"
|
||||||
|
focusable="false"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
d="M20 12l-1.41-1.41L13 16.17V4h-2v12.17l-5.58-5.59L4 12l8 8 8-8z"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
</span>
|
||||||
|
</th>
|
||||||
|
<th
|
||||||
|
class="MuiTableCell-root MuiTableCell-head MuiTableCell-alignCenter"
|
||||||
|
scope="col"
|
||||||
|
>
|
||||||
|
<span
|
||||||
|
aria-disabled="false"
|
||||||
|
class="MuiButtonBase-root MuiTableSortLabel-root"
|
||||||
|
role="button"
|
||||||
|
tabindex="0"
|
||||||
|
>
|
||||||
|
Version
|
||||||
|
<svg
|
||||||
|
aria-hidden="true"
|
||||||
|
class="MuiSvgIcon-root MuiTableSortLabel-icon MuiTableSortLabel-iconDirectionAsc"
|
||||||
|
focusable="false"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
d="M20 12l-1.41-1.41L13 16.17V4h-2v12.17l-5.58-5.59L4 12l8 8 8-8z"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
</span>
|
||||||
|
</th>
|
||||||
<th
|
<th
|
||||||
aria-sort="descending"
|
aria-sort="descending"
|
||||||
class="MuiTableCell-root MuiTableCell-head MuiTableCell-alignCenter"
|
class="MuiTableCell-root MuiTableCell-head MuiTableCell-alignCenter"
|
||||||
@@ -198,7 +244,7 @@ exports[`CarUpdatesTab Render 1`] = `
|
|||||||
role="button"
|
role="button"
|
||||||
tabindex="0"
|
tabindex="0"
|
||||||
>
|
>
|
||||||
ECU
|
Date
|
||||||
<span
|
<span
|
||||||
class="makeStyles-hiddenSortSpan-0"
|
class="makeStyles-hiddenSortSpan-0"
|
||||||
>
|
>
|
||||||
@@ -216,121 +262,6 @@ exports[`CarUpdatesTab Render 1`] = `
|
|||||||
</svg>
|
</svg>
|
||||||
</span>
|
</span>
|
||||||
</th>
|
</th>
|
||||||
<th
|
|
||||||
class="MuiTableCell-root MuiTableCell-head MuiTableCell-alignCenter"
|
|
||||||
scope="col"
|
|
||||||
>
|
|
||||||
<span
|
|
||||||
aria-disabled="false"
|
|
||||||
class="MuiButtonBase-root MuiTableSortLabel-root"
|
|
||||||
role="button"
|
|
||||||
tabindex="0"
|
|
||||||
>
|
|
||||||
SW Version
|
|
||||||
<svg
|
|
||||||
aria-hidden="true"
|
|
||||||
class="MuiSvgIcon-root MuiTableSortLabel-icon MuiTableSortLabel-iconDirectionAsc"
|
|
||||||
focusable="false"
|
|
||||||
viewBox="0 0 24 24"
|
|
||||||
>
|
|
||||||
<path
|
|
||||||
d="M20 12l-1.41-1.41L13 16.17V4h-2v12.17l-5.58-5.59L4 12l8 8 8-8z"
|
|
||||||
/>
|
|
||||||
</svg>
|
|
||||||
</span>
|
|
||||||
</th>
|
|
||||||
<th
|
|
||||||
class="MuiTableCell-root MuiTableCell-head MuiTableCell-alignCenter"
|
|
||||||
scope="col"
|
|
||||||
>
|
|
||||||
<span
|
|
||||||
aria-disabled="false"
|
|
||||||
class="MuiButtonBase-root MuiTableSortLabel-root"
|
|
||||||
role="button"
|
|
||||||
tabindex="0"
|
|
||||||
>
|
|
||||||
HW Version
|
|
||||||
<svg
|
|
||||||
aria-hidden="true"
|
|
||||||
class="MuiSvgIcon-root MuiTableSortLabel-icon MuiTableSortLabel-iconDirectionAsc"
|
|
||||||
focusable="false"
|
|
||||||
viewBox="0 0 24 24"
|
|
||||||
>
|
|
||||||
<path
|
|
||||||
d="M20 12l-1.41-1.41L13 16.17V4h-2v12.17l-5.58-5.59L4 12l8 8 8-8z"
|
|
||||||
/>
|
|
||||||
</svg>
|
|
||||||
</span>
|
|
||||||
</th>
|
|
||||||
<th
|
|
||||||
class="MuiTableCell-root MuiTableCell-head MuiTableCell-alignCenter"
|
|
||||||
scope="col"
|
|
||||||
>
|
|
||||||
<span
|
|
||||||
aria-disabled="false"
|
|
||||||
class="MuiButtonBase-root MuiTableSortLabel-root"
|
|
||||||
role="button"
|
|
||||||
tabindex="0"
|
|
||||||
>
|
|
||||||
Config
|
|
||||||
<svg
|
|
||||||
aria-hidden="true"
|
|
||||||
class="MuiSvgIcon-root MuiTableSortLabel-icon MuiTableSortLabel-iconDirectionAsc"
|
|
||||||
focusable="false"
|
|
||||||
viewBox="0 0 24 24"
|
|
||||||
>
|
|
||||||
<path
|
|
||||||
d="M20 12l-1.41-1.41L13 16.17V4h-2v12.17l-5.58-5.59L4 12l8 8 8-8z"
|
|
||||||
/>
|
|
||||||
</svg>
|
|
||||||
</span>
|
|
||||||
</th>
|
|
||||||
<th
|
|
||||||
class="MuiTableCell-root MuiTableCell-head MuiTableCell-alignCenter"
|
|
||||||
scope="col"
|
|
||||||
>
|
|
||||||
<span
|
|
||||||
aria-disabled="false"
|
|
||||||
class="MuiButtonBase-root MuiTableSortLabel-root"
|
|
||||||
role="button"
|
|
||||||
tabindex="0"
|
|
||||||
>
|
|
||||||
Created
|
|
||||||
<svg
|
|
||||||
aria-hidden="true"
|
|
||||||
class="MuiSvgIcon-root MuiTableSortLabel-icon MuiTableSortLabel-iconDirectionAsc"
|
|
||||||
focusable="false"
|
|
||||||
viewBox="0 0 24 24"
|
|
||||||
>
|
|
||||||
<path
|
|
||||||
d="M20 12l-1.41-1.41L13 16.17V4h-2v12.17l-5.58-5.59L4 12l8 8 8-8z"
|
|
||||||
/>
|
|
||||||
</svg>
|
|
||||||
</span>
|
|
||||||
</th>
|
|
||||||
<th
|
|
||||||
class="MuiTableCell-root MuiTableCell-head MuiTableCell-alignCenter"
|
|
||||||
scope="col"
|
|
||||||
>
|
|
||||||
<span
|
|
||||||
aria-disabled="false"
|
|
||||||
class="MuiButtonBase-root MuiTableSortLabel-root"
|
|
||||||
role="button"
|
|
||||||
tabindex="0"
|
|
||||||
>
|
|
||||||
Updated
|
|
||||||
<svg
|
|
||||||
aria-hidden="true"
|
|
||||||
class="MuiSvgIcon-root MuiTableSortLabel-icon MuiTableSortLabel-iconDirectionAsc"
|
|
||||||
focusable="false"
|
|
||||||
viewBox="0 0 24 24"
|
|
||||||
>
|
|
||||||
<path
|
|
||||||
d="M20 12l-1.41-1.41L13 16.17V4h-2v12.17l-5.58-5.59L4 12l8 8 8-8z"
|
|
||||||
/>
|
|
||||||
</svg>
|
|
||||||
</span>
|
|
||||||
</th>
|
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody
|
<tbody
|
||||||
@@ -344,7 +275,7 @@ exports[`CarUpdatesTab Render 1`] = `
|
|||||||
>
|
>
|
||||||
<td
|
<td
|
||||||
class="MuiTableCell-root MuiTableCell-footer MuiTablePagination-root"
|
class="MuiTableCell-root MuiTableCell-footer MuiTablePagination-root"
|
||||||
colspan="10"
|
colspan="3"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
class="MuiToolbar-root MuiToolbar-regular MuiTablePagination-toolbar MuiToolbar-gutters"
|
class="MuiToolbar-root MuiToolbar-regular MuiTablePagination-toolbar MuiToolbar-gutters"
|
||||||
|
|||||||
309
src/components/Cars/Status/__snapshots__/ECUsTab.test.jsx.snap
Normal file
309
src/components/Cars/Status/__snapshots__/ECUsTab.test.jsx.snap
Normal file
@@ -0,0 +1,309 @@
|
|||||||
|
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||||
|
|
||||||
|
exports[`ECUsTab Render 1`] = `
|
||||||
|
<div>
|
||||||
|
<div
|
||||||
|
data-testid="mocked-statusprovider"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
data-testid="mocked-userprovider"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
class="makeStyles-paper-0 makeStyles-tableSize-0"
|
||||||
|
>
|
||||||
|
<h6
|
||||||
|
class="MuiTypography-root makeStyles-labelInline-0 MuiTypography-h6"
|
||||||
|
>
|
||||||
|
Car ECUs
|
||||||
|
</h6>
|
||||||
|
<div
|
||||||
|
class="makeStyles-paper-0 makeStyles-tableSize-0"
|
||||||
|
>
|
||||||
|
<table
|
||||||
|
class="MuiTable-root"
|
||||||
|
>
|
||||||
|
<thead
|
||||||
|
class="MuiTableHead-root"
|
||||||
|
>
|
||||||
|
<tr
|
||||||
|
class="MuiTableRow-root MuiTableRow-head"
|
||||||
|
>
|
||||||
|
<th
|
||||||
|
aria-sort="descending"
|
||||||
|
class="MuiTableCell-root MuiTableCell-head MuiTableCell-alignCenter"
|
||||||
|
scope="col"
|
||||||
|
>
|
||||||
|
<span
|
||||||
|
aria-disabled="false"
|
||||||
|
class="MuiButtonBase-root MuiTableSortLabel-root MuiTableSortLabel-active"
|
||||||
|
role="button"
|
||||||
|
tabindex="0"
|
||||||
|
>
|
||||||
|
ECU
|
||||||
|
<span
|
||||||
|
class="makeStyles-hiddenSortSpan-0"
|
||||||
|
>
|
||||||
|
sorted descending
|
||||||
|
</span>
|
||||||
|
<svg
|
||||||
|
aria-hidden="true"
|
||||||
|
class="MuiSvgIcon-root MuiTableSortLabel-icon MuiTableSortLabel-iconDirectionDesc"
|
||||||
|
focusable="false"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
d="M20 12l-1.41-1.41L13 16.17V4h-2v12.17l-5.58-5.59L4 12l8 8 8-8z"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
</span>
|
||||||
|
</th>
|
||||||
|
<th
|
||||||
|
class="MuiTableCell-root MuiTableCell-head MuiTableCell-alignCenter"
|
||||||
|
scope="col"
|
||||||
|
>
|
||||||
|
<span
|
||||||
|
aria-disabled="false"
|
||||||
|
class="MuiButtonBase-root MuiTableSortLabel-root"
|
||||||
|
role="button"
|
||||||
|
tabindex="0"
|
||||||
|
>
|
||||||
|
SW Version
|
||||||
|
<svg
|
||||||
|
aria-hidden="true"
|
||||||
|
class="MuiSvgIcon-root MuiTableSortLabel-icon MuiTableSortLabel-iconDirectionAsc"
|
||||||
|
focusable="false"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
d="M20 12l-1.41-1.41L13 16.17V4h-2v12.17l-5.58-5.59L4 12l8 8 8-8z"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
</span>
|
||||||
|
</th>
|
||||||
|
<th
|
||||||
|
class="MuiTableCell-root MuiTableCell-head MuiTableCell-alignCenter"
|
||||||
|
scope="col"
|
||||||
|
>
|
||||||
|
<span
|
||||||
|
aria-disabled="false"
|
||||||
|
class="MuiButtonBase-root MuiTableSortLabel-root"
|
||||||
|
role="button"
|
||||||
|
tabindex="0"
|
||||||
|
>
|
||||||
|
HW Version
|
||||||
|
<svg
|
||||||
|
aria-hidden="true"
|
||||||
|
class="MuiSvgIcon-root MuiTableSortLabel-icon MuiTableSortLabel-iconDirectionAsc"
|
||||||
|
focusable="false"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
d="M20 12l-1.41-1.41L13 16.17V4h-2v12.17l-5.58-5.59L4 12l8 8 8-8z"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
</span>
|
||||||
|
</th>
|
||||||
|
<th
|
||||||
|
class="MuiTableCell-root MuiTableCell-head MuiTableCell-alignCenter"
|
||||||
|
scope="col"
|
||||||
|
>
|
||||||
|
<span
|
||||||
|
aria-disabled="false"
|
||||||
|
class="MuiButtonBase-root MuiTableSortLabel-root"
|
||||||
|
role="button"
|
||||||
|
tabindex="0"
|
||||||
|
>
|
||||||
|
Config
|
||||||
|
<svg
|
||||||
|
aria-hidden="true"
|
||||||
|
class="MuiSvgIcon-root MuiTableSortLabel-icon MuiTableSortLabel-iconDirectionAsc"
|
||||||
|
focusable="false"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
d="M20 12l-1.41-1.41L13 16.17V4h-2v12.17l-5.58-5.59L4 12l8 8 8-8z"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
</span>
|
||||||
|
</th>
|
||||||
|
<th
|
||||||
|
class="MuiTableCell-root MuiTableCell-head MuiTableCell-alignCenter"
|
||||||
|
scope="col"
|
||||||
|
>
|
||||||
|
<span
|
||||||
|
aria-disabled="false"
|
||||||
|
class="MuiButtonBase-root MuiTableSortLabel-root"
|
||||||
|
role="button"
|
||||||
|
tabindex="0"
|
||||||
|
>
|
||||||
|
Created
|
||||||
|
<svg
|
||||||
|
aria-hidden="true"
|
||||||
|
class="MuiSvgIcon-root MuiTableSortLabel-icon MuiTableSortLabel-iconDirectionAsc"
|
||||||
|
focusable="false"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
d="M20 12l-1.41-1.41L13 16.17V4h-2v12.17l-5.58-5.59L4 12l8 8 8-8z"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
</span>
|
||||||
|
</th>
|
||||||
|
<th
|
||||||
|
class="MuiTableCell-root MuiTableCell-head MuiTableCell-alignCenter"
|
||||||
|
scope="col"
|
||||||
|
>
|
||||||
|
<span
|
||||||
|
aria-disabled="false"
|
||||||
|
class="MuiButtonBase-root MuiTableSortLabel-root"
|
||||||
|
role="button"
|
||||||
|
tabindex="0"
|
||||||
|
>
|
||||||
|
Updated
|
||||||
|
<svg
|
||||||
|
aria-hidden="true"
|
||||||
|
class="MuiSvgIcon-root MuiTableSortLabel-icon MuiTableSortLabel-iconDirectionAsc"
|
||||||
|
focusable="false"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
d="M20 12l-1.41-1.41L13 16.17V4h-2v12.17l-5.58-5.59L4 12l8 8 8-8z"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
</span>
|
||||||
|
</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody
|
||||||
|
class="MuiTableBody-root"
|
||||||
|
/>
|
||||||
|
<tfoot
|
||||||
|
class="MuiTableFooter-root"
|
||||||
|
>
|
||||||
|
<tr
|
||||||
|
class="MuiTableRow-root MuiTableRow-footer"
|
||||||
|
>
|
||||||
|
<td
|
||||||
|
class="MuiTableCell-root MuiTableCell-footer MuiTablePagination-root"
|
||||||
|
colspan="10"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
class="MuiToolbar-root MuiToolbar-regular MuiTablePagination-toolbar MuiToolbar-gutters"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
class="MuiTablePagination-spacer"
|
||||||
|
/>
|
||||||
|
<p
|
||||||
|
class="MuiTypography-root MuiTablePagination-caption MuiTypography-body2 MuiTypography-colorInherit"
|
||||||
|
>
|
||||||
|
Rows per page:
|
||||||
|
</p>
|
||||||
|
<div
|
||||||
|
class="MuiInputBase-root MuiTablePagination-input MuiTablePagination-selectRoot"
|
||||||
|
>
|
||||||
|
<select
|
||||||
|
aria-label="rows per page"
|
||||||
|
class="MuiSelect-root MuiSelect-select MuiTablePagination-select MuiInputBase-input"
|
||||||
|
>
|
||||||
|
<option
|
||||||
|
class="MuiTablePagination-menuItem"
|
||||||
|
value="5"
|
||||||
|
>
|
||||||
|
5
|
||||||
|
</option>
|
||||||
|
<option
|
||||||
|
class="MuiTablePagination-menuItem"
|
||||||
|
value="10"
|
||||||
|
>
|
||||||
|
10
|
||||||
|
</option>
|
||||||
|
<option
|
||||||
|
class="MuiTablePagination-menuItem"
|
||||||
|
value="25"
|
||||||
|
>
|
||||||
|
25
|
||||||
|
</option>
|
||||||
|
<option
|
||||||
|
class="MuiTablePagination-menuItem"
|
||||||
|
value="100"
|
||||||
|
>
|
||||||
|
100
|
||||||
|
</option>
|
||||||
|
</select>
|
||||||
|
<svg
|
||||||
|
aria-hidden="true"
|
||||||
|
class="MuiSvgIcon-root MuiSelect-icon MuiTablePagination-selectIcon"
|
||||||
|
focusable="false"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
d="M7 10l5 5 5-5z"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
</div>
|
||||||
|
<p
|
||||||
|
class="MuiTypography-root MuiTablePagination-caption MuiTypography-body2 MuiTypography-colorInherit"
|
||||||
|
>
|
||||||
|
0-0 of 0
|
||||||
|
</p>
|
||||||
|
<div
|
||||||
|
class="MuiTablePagination-actions"
|
||||||
|
>
|
||||||
|
<button
|
||||||
|
aria-label="Previous page"
|
||||||
|
class="MuiButtonBase-root MuiIconButton-root MuiIconButton-colorInherit Mui-disabled Mui-disabled"
|
||||||
|
disabled=""
|
||||||
|
tabindex="-1"
|
||||||
|
title="Previous page"
|
||||||
|
type="button"
|
||||||
|
>
|
||||||
|
<span
|
||||||
|
class="MuiIconButton-label"
|
||||||
|
>
|
||||||
|
<svg
|
||||||
|
aria-hidden="true"
|
||||||
|
class="MuiSvgIcon-root"
|
||||||
|
focusable="false"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
d="M15.41 16.09l-4.58-4.59 4.58-4.59L14 5.5l-6 6 6 6z"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
</span>
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
aria-label="Next page"
|
||||||
|
class="MuiButtonBase-root MuiIconButton-root MuiIconButton-colorInherit Mui-disabled Mui-disabled"
|
||||||
|
disabled=""
|
||||||
|
tabindex="-1"
|
||||||
|
title="Next page"
|
||||||
|
type="button"
|
||||||
|
>
|
||||||
|
<span
|
||||||
|
class="MuiIconButton-label"
|
||||||
|
>
|
||||||
|
<svg
|
||||||
|
aria-hidden="true"
|
||||||
|
class="MuiSvgIcon-root"
|
||||||
|
focusable="false"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
d="M8.59 16.34l4.58-4.59-4.58-4.59L10 5.75l6 6-6 6z"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
</span>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</tfoot>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
`;
|
||||||
@@ -21,8 +21,12 @@ exports[`CarStatus Render 1`] = `
|
|||||||
class="MuiTabs-root"
|
class="MuiTabs-root"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
class="MuiTabs-scroller MuiTabs-fixed"
|
class="MuiTabs-scrollable"
|
||||||
style="overflow: hidden;"
|
style="width: 99px; height: 99px; position: absolute; top: -9999px; overflow: scroll;"
|
||||||
|
/>
|
||||||
|
<div
|
||||||
|
class="MuiTabs-scroller MuiTabs-scrollable"
|
||||||
|
style="margin-bottom: 0px;"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
aria-label="car tabs"
|
aria-label="car tabs"
|
||||||
@@ -131,7 +135,7 @@ exports[`CarStatus Render 1`] = `
|
|||||||
<span
|
<span
|
||||||
class="MuiTab-wrapper"
|
class="MuiTab-wrapper"
|
||||||
>
|
>
|
||||||
Remote Commands
|
ECUs
|
||||||
</span>
|
</span>
|
||||||
<span
|
<span
|
||||||
class="MuiTouchRipple-root"
|
class="MuiTouchRipple-root"
|
||||||
@@ -145,6 +149,24 @@ exports[`CarStatus Render 1`] = `
|
|||||||
role="tab"
|
role="tab"
|
||||||
tabindex="-1"
|
tabindex="-1"
|
||||||
type="button"
|
type="button"
|
||||||
|
>
|
||||||
|
<span
|
||||||
|
class="MuiTab-wrapper"
|
||||||
|
>
|
||||||
|
Remote Commands
|
||||||
|
</span>
|
||||||
|
<span
|
||||||
|
class="MuiTouchRipple-root"
|
||||||
|
/>
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
aria-controls="tabpanel-7"
|
||||||
|
aria-selected="false"
|
||||||
|
class="MuiButtonBase-root MuiTab-root MuiTab-textColorInherit"
|
||||||
|
id="tab-7"
|
||||||
|
role="tab"
|
||||||
|
tabindex="-1"
|
||||||
|
type="button"
|
||||||
>
|
>
|
||||||
<span
|
<span
|
||||||
class="MuiTab-wrapper"
|
class="MuiTab-wrapper"
|
||||||
@@ -314,6 +336,12 @@ exports[`CarStatus Render 1`] = `
|
|||||||
id="tabpanel-6"
|
id="tabpanel-6"
|
||||||
role="tabpanel"
|
role="tabpanel"
|
||||||
/>
|
/>
|
||||||
|
<div
|
||||||
|
aria-labelledby="tab-7"
|
||||||
|
hidden=""
|
||||||
|
id="tabpanel-7"
|
||||||
|
role="tabpanel"
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ import CANSignalsTab from "./CANSignalsTab";
|
|||||||
import CarUpdatesTab from "./CarUpdatesTab";
|
import CarUpdatesTab from "./CarUpdatesTab";
|
||||||
import CarDetailsTab from "./DetailsTab";
|
import CarDetailsTab from "./DetailsTab";
|
||||||
import DigitalTwinTab from "./DigitalTwinTab";
|
import DigitalTwinTab from "./DigitalTwinTab";
|
||||||
|
import ECUsTab from "./ECUsTab";
|
||||||
import FleetsTab from "./FleetsTab";
|
import FleetsTab from "./FleetsTab";
|
||||||
import RemoteCommandsTab from "./RemoteCommandsTab";
|
import RemoteCommandsTab from "./RemoteCommandsTab";
|
||||||
|
|
||||||
@@ -41,6 +42,10 @@ const TabViews = [
|
|||||||
label: "CAN Signals",
|
label: "CAN Signals",
|
||||||
component: CANSignalsTab,
|
component: CANSignalsTab,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
label: "ECUs",
|
||||||
|
component: ECUsTab,
|
||||||
|
},
|
||||||
{
|
{
|
||||||
label: "Remote Commands",
|
label: "Remote Commands",
|
||||||
component: RemoteCommandsTab,
|
component: RemoteCommandsTab,
|
||||||
@@ -110,6 +115,7 @@ const CarStatus = () => {
|
|||||||
value={tabIndex}
|
value={tabIndex}
|
||||||
onChange={handleTabChange}
|
onChange={handleTabChange}
|
||||||
aria-label="car tabs"
|
aria-label="car tabs"
|
||||||
|
variant="scrollable"
|
||||||
indicatorColor="secondary">
|
indicatorColor="secondary">
|
||||||
{tabs.map((item, index) => <Tab key={index} label={item.label} {...tabProps(index)} />)}
|
{tabs.map((item, index) => <Tab key={index} label={item.label} {...tabProps(index)} />)}
|
||||||
</Tabs>
|
</Tabs>
|
||||||
|
|||||||
@@ -233,6 +233,17 @@ export const VehicleProvider = ({ children }) => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const getVersionLog = async (search, token) => {
|
||||||
|
try {
|
||||||
|
setBusy(true);
|
||||||
|
const result = await api.getVersionLog(search, token);
|
||||||
|
if (result.error) throw new Error(`Get version log error. ${result.message}`);
|
||||||
|
return result;
|
||||||
|
} finally {
|
||||||
|
setBusy(false);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<VehicleContext.Provider
|
<VehicleContext.Provider
|
||||||
value={{
|
value={{
|
||||||
@@ -258,6 +269,7 @@ export const VehicleProvider = ({ children }) => {
|
|||||||
sendCommand,
|
sendCommand,
|
||||||
updateVehicle,
|
updateVehicle,
|
||||||
getFleets,
|
getFleets,
|
||||||
|
getVersionLog,
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{children}
|
{children}
|
||||||
|
|||||||
136
src/components/Controls/CarVersionLogTable/index.jsx
Normal file
136
src/components/Controls/CarVersionLogTable/index.jsx
Normal file
@@ -0,0 +1,136 @@
|
|||||||
|
import {
|
||||||
|
Table,
|
||||||
|
TableBody,
|
||||||
|
TableCell,
|
||||||
|
TableFooter,
|
||||||
|
TablePagination,
|
||||||
|
TableRow
|
||||||
|
} from "@material-ui/core";
|
||||||
|
import clsx from "clsx";
|
||||||
|
import React, { useEffect, useState } from "react";
|
||||||
|
|
||||||
|
import { logger } from "../../../services/monitoring";
|
||||||
|
import { LocalDateTimeString } from "../../../utils/dates";
|
||||||
|
import { useStatusContext } from "../../Contexts/StatusContext";
|
||||||
|
import { useVehicleContext } from "../../Contexts/VehicleContext";
|
||||||
|
import TableHeaderSortable from "../../Table/HeaderSortable";
|
||||||
|
import { useLocalStorage } from "../../useLocalStorage";
|
||||||
|
|
||||||
|
const tableColumns = [
|
||||||
|
{
|
||||||
|
id: "version_source",
|
||||||
|
label: "Type",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: "version",
|
||||||
|
label: "Version",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: "created_at",
|
||||||
|
label: "Date",
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
const PAGE_SIZE = "CAR_VERSIONLOG_TABLE_PAGE_SIZE";
|
||||||
|
|
||||||
|
const CarVersionLogTable = ({ vin, token, classes }) => {
|
||||||
|
const [versions, setVersions] = useState([]);
|
||||||
|
const [total, setTotal] = useState(0);
|
||||||
|
const [pageSize, setPageSize] = useLocalStorage(PAGE_SIZE, 10);
|
||||||
|
const [pageIndex, setPageIndex] = useState(0);
|
||||||
|
const [orderBy, setOrderBy] = useState("created_at");
|
||||||
|
const [order, setOrder] = useState("desc");
|
||||||
|
const { getVersionLog } = useVehicleContext();
|
||||||
|
const { setMessage } = useStatusContext();
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
(async () => {
|
||||||
|
try {
|
||||||
|
if (!vin || !token) return;
|
||||||
|
const result = await getVersionLog(
|
||||||
|
{
|
||||||
|
vin,
|
||||||
|
limit: pageSize,
|
||||||
|
offset: pageSize * pageIndex,
|
||||||
|
order: `${orderBy} ${order}`,
|
||||||
|
},
|
||||||
|
token
|
||||||
|
);
|
||||||
|
setVersions(result.data);
|
||||||
|
if (result.total > -1) setTotal(result.total);
|
||||||
|
} catch (e) {
|
||||||
|
setMessage(e.message);
|
||||||
|
logger.warn(e.stack);
|
||||||
|
}
|
||||||
|
})();
|
||||||
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||||
|
}, [vin, token, pageIndex, pageSize, orderBy, order]);
|
||||||
|
|
||||||
|
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 (
|
||||||
|
<div className={clsx(classes.paper, classes.tableSize)}>
|
||||||
|
<Table>
|
||||||
|
<TableHeaderSortable
|
||||||
|
classes={classes}
|
||||||
|
orderBy={orderBy}
|
||||||
|
order={order}
|
||||||
|
columnData={tableColumns}
|
||||||
|
onSortRequest={handleSort}
|
||||||
|
/>
|
||||||
|
<TableBody>
|
||||||
|
{versions && versions.map((row, i) => (
|
||||||
|
<TableRow key={`row${i}`}>
|
||||||
|
<TableCell align="center">{row.version_source}</TableCell>
|
||||||
|
<TableCell align="center">{row.version}</TableCell>
|
||||||
|
<TableCell align="center">{LocalDateTimeString(row.created_at)}</TableCell>
|
||||||
|
</TableRow>
|
||||||
|
))}
|
||||||
|
</TableBody>
|
||||||
|
<TableFooter>
|
||||||
|
<TableRow>
|
||||||
|
<TablePagination
|
||||||
|
rowsPerPageOptions={[5, 10, 25, 100]}
|
||||||
|
colSpan={3}
|
||||||
|
count={total}
|
||||||
|
rowsPerPage={pageSize}
|
||||||
|
page={pageIndex}
|
||||||
|
SelectProps={{
|
||||||
|
inputProps: { "aria-label": "rows per page" },
|
||||||
|
native: true,
|
||||||
|
}}
|
||||||
|
onPageChange={handleChangePageIndex}
|
||||||
|
onRowsPerPageChange={handleChangePageSize}
|
||||||
|
/>
|
||||||
|
</TableRow>
|
||||||
|
</TableFooter>
|
||||||
|
</Table>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default CarVersionLogTable;
|
||||||
@@ -1,26 +1,26 @@
|
|||||||
import React, { useEffect, useState } from "react";
|
|
||||||
import { Link } from "react-router-dom";
|
|
||||||
import PropTypes from "prop-types";
|
|
||||||
import {
|
import {
|
||||||
Table,
|
Table,
|
||||||
TableBody,
|
TableBody,
|
||||||
TableCell,
|
TableCell,
|
||||||
TableFooter,
|
TableFooter,
|
||||||
TablePagination,
|
TablePagination,
|
||||||
TableRow,
|
TableRow
|
||||||
Button,
|
|
||||||
} from "@material-ui/core";
|
} from "@material-ui/core";
|
||||||
|
import DeleteIcon from "@material-ui/icons/Delete";
|
||||||
import clsx from "clsx";
|
import clsx from "clsx";
|
||||||
|
import PropTypes from "prop-types";
|
||||||
|
import React, { useEffect, useState } from "react";
|
||||||
|
import { Link } from "react-router-dom";
|
||||||
|
|
||||||
|
import { logger } from "../../../services/monitoring";
|
||||||
|
import { LocalDateTimeString } from "../../../utils/dates";
|
||||||
|
import { Permissions } from "../../../utils/roles";
|
||||||
import { useIssueContext } from "../../Contexts/IssueContext";
|
import { useIssueContext } from "../../Contexts/IssueContext";
|
||||||
import { useStatusContext } from "../../Contexts/StatusContext";
|
import { useStatusContext } from "../../Contexts/StatusContext";
|
||||||
import { LocalDateTimeString } from "../../../utils/dates";
|
import { useUserContext } from "../../Contexts/UserContext";
|
||||||
import TableHeaderSortable from "../../Table/HeaderSortable";
|
import TableHeaderSortable from "../../Table/HeaderSortable";
|
||||||
import { logger } from "../../../services/monitoring";
|
|
||||||
import { useLocalStorage } from "../../useLocalStorage";
|
import { useLocalStorage } from "../../useLocalStorage";
|
||||||
import { RoleWrap } from "../RoleWrap";
|
import { RoleWrap } from "../RoleWrap";
|
||||||
import { useUserContext } from "../../Contexts/UserContext";
|
|
||||||
import { Permissions } from "../../../utils/roles";
|
|
||||||
|
|
||||||
const tableColumns = [
|
const tableColumns = [
|
||||||
{
|
{
|
||||||
@@ -35,10 +35,6 @@ const tableColumns = [
|
|||||||
id: "title",
|
id: "title",
|
||||||
label: "Title",
|
label: "Title",
|
||||||
},
|
},
|
||||||
{
|
|
||||||
id: "description",
|
|
||||||
label: "Description",
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
id: "driver_id",
|
id: "driver_id",
|
||||||
label: "Driver ID",
|
label: "Driver ID",
|
||||||
@@ -69,7 +65,7 @@ const IssueSelectionTable = (props) => {
|
|||||||
const [pageIndex, setPageIndex] = useState(0);
|
const [pageIndex, setPageIndex] = useState(0);
|
||||||
const [orderBy, setOrderBy] = useState("created_at");
|
const [orderBy, setOrderBy] = useState("created_at");
|
||||||
const [order, setOrder] = useState("asc");
|
const [order, setOrder] = useState("asc");
|
||||||
const { getIssues, issues, totalIssues = 0 } = useIssueContext();
|
const { deleteIssue, getIssues, issues, totalIssues = 0 } = useIssueContext();
|
||||||
const { groups, providers } = useUserContext();
|
const { groups, providers } = useUserContext();
|
||||||
const { setMessage } = useStatusContext();
|
const { setMessage } = useStatusContext();
|
||||||
|
|
||||||
@@ -132,12 +128,19 @@ const IssueSelectionTable = (props) => {
|
|||||||
setPageIndex(0);
|
setPageIndex(0);
|
||||||
}, [search]);
|
}, [search]);
|
||||||
|
|
||||||
const { deleteIssue } = useIssueContext();
|
|
||||||
const handleDelete = (id) => {
|
const handleDelete = (id) => {
|
||||||
deleteIssue(id, token).then(() => {
|
deleteIssue(id, token).then(() => {
|
||||||
getIssues(token)
|
getIssues(
|
||||||
|
{
|
||||||
|
limit: pageSize,
|
||||||
|
offset: pageSize * pageIndex,
|
||||||
|
order: `${orderBy} ${order}`,
|
||||||
|
},
|
||||||
|
token
|
||||||
|
);
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={clsx(classes.paper, classes.tableSize)}>
|
<div className={clsx(classes.paper, classes.tableSize)}>
|
||||||
<Table>
|
<Table>
|
||||||
@@ -161,7 +164,6 @@ const IssueSelectionTable = (props) => {
|
|||||||
</TableCell>
|
</TableCell>
|
||||||
<TableCell align="center">{row.vin}</TableCell>
|
<TableCell align="center">{row.vin}</TableCell>
|
||||||
<TableCell align="center">{row.title}</TableCell>
|
<TableCell align="center">{row.title}</TableCell>
|
||||||
<TableCell align="center">{row.description || ""}</TableCell>
|
|
||||||
<TableCell align="center">{row.driver_id}</TableCell>
|
<TableCell align="center">{row.driver_id}</TableCell>
|
||||||
<TableCell align="center">
|
<TableCell align="center">
|
||||||
{LocalDateTimeString(row.timestamp)}
|
{LocalDateTimeString(row.timestamp)}
|
||||||
@@ -172,7 +174,9 @@ const IssueSelectionTable = (props) => {
|
|||||||
rolesPerProvider={Permissions.FiskerDelete}
|
rolesPerProvider={Permissions.FiskerDelete}
|
||||||
>
|
>
|
||||||
<TableCell>
|
<TableCell>
|
||||||
<Button onClick={() => handleDelete(row.id)}>Delete</Button>
|
<Link to="#" onClick={() => handleDelete(row.id)}>
|
||||||
|
<DeleteIcon />
|
||||||
|
</Link>
|
||||||
</TableCell>
|
</TableCell>
|
||||||
</RoleWrap>
|
</RoleWrap>
|
||||||
</TableRow>
|
</TableRow>
|
||||||
@@ -181,12 +185,9 @@ const IssueSelectionTable = (props) => {
|
|||||||
</TableBody>
|
</TableBody>
|
||||||
<TableFooter>
|
<TableFooter>
|
||||||
<TableRow>
|
<TableRow>
|
||||||
{totalIssues === 0 ? (
|
|
||||||
<td>No issues found</td>
|
|
||||||
) : (
|
|
||||||
<TablePagination
|
<TablePagination
|
||||||
rowsPerPageOptions={[5, 10, 25, 100]}
|
rowsPerPageOptions={[5, 10, 25, 100]}
|
||||||
colSpan={7}
|
colSpan={6}
|
||||||
count={totalIssues}
|
count={totalIssues}
|
||||||
rowsPerPage={pageSize}
|
rowsPerPage={pageSize}
|
||||||
page={pageIndex}
|
page={pageIndex}
|
||||||
@@ -197,7 +198,6 @@ const IssueSelectionTable = (props) => {
|
|||||||
onPageChange={handleChangePageIndex}
|
onPageChange={handleChangePageIndex}
|
||||||
onRowsPerPageChange={handleChangePageSize}
|
onRowsPerPageChange={handleChangePageSize}
|
||||||
/>
|
/>
|
||||||
)}
|
|
||||||
</TableRow>
|
</TableRow>
|
||||||
</TableFooter>
|
</TableFooter>
|
||||||
</Table>
|
</Table>
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ import { Grid } from "@material-ui/core";
|
|||||||
import clsx from "clsx";
|
import clsx from "clsx";
|
||||||
import React, { useEffect } from "react";
|
import React, { useEffect } from "react";
|
||||||
|
|
||||||
|
import { LocalDateTimeString } from "../../../../utils/dates";
|
||||||
import { logger } from "../../../../services/monitoring";
|
import { logger } from "../../../../services/monitoring";
|
||||||
import { useStatusContext } from "../../../Contexts/StatusContext";
|
import { useStatusContext } from "../../../Contexts/StatusContext";
|
||||||
import { useUserContext } from "../../../Contexts/UserContext";
|
import { useUserContext } from "../../../Contexts/UserContext";
|
||||||
@@ -11,7 +12,6 @@ import {
|
|||||||
} from "../../../Contexts/IssueContext";
|
} from "../../../Contexts/IssueContext";
|
||||||
import useStyles from "../../../useStyles";
|
import useStyles from "../../../useStyles";
|
||||||
|
|
||||||
|
|
||||||
const MainForm = ({ id }) => {
|
const MainForm = ({ id }) => {
|
||||||
const classes = useStyles();
|
const classes = useStyles();
|
||||||
const { setMessage } = useStatusContext();
|
const { setMessage } = useStatusContext();
|
||||||
@@ -55,7 +55,7 @@ const MainForm = ({ id }) => {
|
|||||||
<b>Description</b>: {issue.description}
|
<b>Description</b>: {issue.description}
|
||||||
</p>
|
</p>
|
||||||
<p>
|
<p>
|
||||||
<b>timestamp</b>: {issue.timestamp}
|
<b>timestamp</b>: {LocalDateTimeString(issue.timestamp)}
|
||||||
</p>
|
</p>
|
||||||
{issue.images && issue.images.map((image, index) => (
|
{issue.images && issue.images.map((image, index) => (
|
||||||
<img key={image.id} src={`data:image/png;base64, ${image.image}`} alt="Issue images" />
|
<img key={image.id} src={`data:image/png;base64, ${image.image}`} alt="Issue images" />
|
||||||
|
|||||||
@@ -1,55 +1,15 @@
|
|||||||
import { Box, Tab, Tabs } from "@material-ui/core";
|
|
||||||
import clsx from "clsx";
|
import clsx from "clsx";
|
||||||
import React, { useEffect, useState } from "react";
|
import React, { useEffect } from "react";
|
||||||
import { useParams } from "react-router";
|
import { useParams } from "react-router";
|
||||||
import { useLocation } from "react-router-dom";
|
|
||||||
|
|
||||||
import { hasRole } from "../../../utils/roles";
|
|
||||||
import { useStatusContext } from "../../Contexts/StatusContext";
|
import { useStatusContext } from "../../Contexts/StatusContext";
|
||||||
import { useUserContext } from "../../Contexts/UserContext";
|
|
||||||
import TabPanel from "../../Controls/TabPanel";
|
|
||||||
import useStyles from "../../useStyles";
|
import useStyles from "../../useStyles";
|
||||||
import IssueDetailsTab from "./DetailsTab";
|
import IssueDetailsTab from "./DetailsTab";
|
||||||
|
|
||||||
|
|
||||||
const tabHashes = ["details", "updates", "filters"];
|
|
||||||
|
|
||||||
const TabViews = [
|
|
||||||
{
|
|
||||||
label: "Details",
|
|
||||||
component: IssueDetailsTab,
|
|
||||||
},
|
|
||||||
|
|
||||||
];
|
|
||||||
|
|
||||||
const filterTabs = (data, groups, providers) => {
|
|
||||||
return data.reduce((result, item) => {
|
|
||||||
if (hasRole(groups, item.rolesPerProvider, providers)) {
|
|
||||||
result.push(item);
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}, []);
|
|
||||||
};
|
|
||||||
|
|
||||||
const IssueInfo = () => {
|
const IssueInfo = () => {
|
||||||
const { id } = useParams();
|
const { id } = useParams();
|
||||||
const classes = useStyles();
|
const classes = useStyles();
|
||||||
const { setTitle, setSitePath } = useStatusContext();
|
const { setTitle, setSitePath } = useStatusContext();
|
||||||
const { hash } = useLocation();
|
|
||||||
const [tabIndex, setTabIndex] = useState(0);
|
|
||||||
const [tabs, setTabs] = useState([]);
|
|
||||||
const { groups, providers } = useUserContext();
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
const data = filterTabs(TabViews, groups, providers);
|
|
||||||
setTabs(data);
|
|
||||||
}, [groups, providers]);
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
const key = hash.replace("#", "");
|
|
||||||
const index = tabHashes.findIndex((element) => element === key);
|
|
||||||
if (index >= 0) setTabIndex(index);
|
|
||||||
}, [hash]);
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const title = `Issue ${id} Details`;
|
const title = `Issue ${id} Details`;
|
||||||
@@ -66,39 +26,12 @@ const IssueInfo = () => {
|
|||||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||||
}, [id]);
|
}, [id]);
|
||||||
|
|
||||||
const handleTabChange = (_event, newIndex) => {
|
|
||||||
setTabIndex(newIndex);
|
|
||||||
};
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={clsx(classes.paper, classes.tableSize)}>
|
<div className={clsx(classes.paper, classes.tableSize)}>
|
||||||
<Box
|
<IssueDetailsTab id={id} />
|
||||||
className={classes.tableToolbar}
|
|
||||||
sx={{ borderBottom: 1, borderColor: "divider" }}
|
|
||||||
>
|
|
||||||
<Tabs
|
|
||||||
value={tabIndex}
|
|
||||||
onChange={handleTabChange}
|
|
||||||
aria-label="issue tabs"
|
|
||||||
indicatorColor="secondary">
|
|
||||||
{tabs.map((item, index) => <Tab key={index} label={item.label} {...tabProps(index)} />)}
|
|
||||||
</Tabs>
|
|
||||||
</Box>
|
|
||||||
{tabs.map((item, index) => (
|
|
||||||
<TabPanel key={index} value={tabIndex} index={index}>
|
|
||||||
<item.component id={id} />
|
|
||||||
</TabPanel>
|
|
||||||
))}
|
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
function tabProps(index) {
|
|
||||||
return {
|
|
||||||
id: `tab-${index}`,
|
|
||||||
"aria-controls": `tabpanel-${index}`,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
export default IssueInfo;
|
export default IssueInfo;
|
||||||
|
|||||||
@@ -116,7 +116,26 @@ const vehiclesAPI = {
|
|||||||
},
|
},
|
||||||
getCANSignals: async (vin, vehicle) => {
|
getCANSignals: async (vin, vehicle) => {
|
||||||
return signals;
|
return signals;
|
||||||
}
|
},
|
||||||
|
getVersionLog: async (vin) => ({
|
||||||
|
"data": [
|
||||||
|
{
|
||||||
|
"id": 1,
|
||||||
|
"vin": "${vin}",
|
||||||
|
"version_source": "TREX",
|
||||||
|
"version": "0.9.56",
|
||||||
|
"created_at": "2023-01-13T02:11:33.327214Z"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": 2,
|
||||||
|
"vin": "${vin}",
|
||||||
|
"version_source": "DBC",
|
||||||
|
"version": "386c18977a1be3cda60c953e5902c680dbe82b89523f2527e80cd9db863db991",
|
||||||
|
"created_at": "2023-01-13T02:11:33.330932Z"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"total": 2
|
||||||
|
})
|
||||||
};
|
};
|
||||||
|
|
||||||
export default vehiclesAPI;
|
export default vehiclesAPI;
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import {
|
import {
|
||||||
addQueryParams, errorHandler, fetchRespHandler, getAuthHeaderOptions
|
addQueryParams, errorHandler, fetchRespHandler, getAuthHeaderOptions
|
||||||
} from "../utils/http";
|
} from "../utils/http";
|
||||||
|
|
||||||
const API_ENDPOINT = process.env.REACT_APP_OTA_SERVICE_URL;
|
const API_ENDPOINT = process.env.REACT_APP_OTA_SERVICE_URL;
|
||||||
@@ -172,6 +172,19 @@ const vehiclesAPI = {
|
|||||||
})
|
})
|
||||||
.then(fetchRespHandler)
|
.then(fetchRespHandler)
|
||||||
.catch(errorHandler),
|
.catch(errorHandler),
|
||||||
|
|
||||||
|
getVersionLog: async ({vin, ...search}, token) => {
|
||||||
|
const u = addQueryParams(`${API_ENDPOINT}/vehicle/${vin}/version/logs`, search);
|
||||||
|
return fetch(u, {
|
||||||
|
method: "GET",
|
||||||
|
headers: Object.assign(
|
||||||
|
{ "Content-Type": "application/json" },
|
||||||
|
getAuthHeaderOptions(token)
|
||||||
|
),
|
||||||
|
})
|
||||||
|
.then(fetchRespHandler)
|
||||||
|
.catch(errorHandler)
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
export default vehiclesAPI;
|
export default vehiclesAPI;
|
||||||
|
|||||||
Reference in New Issue
Block a user