* first push * fix snapshot * remove unused vars * update snap * remove some console logs * Remove snapshot * Update * CEC-3770 Update cert expire text (#282) * CEC-3577: fetch T.Rex log from the cloud (#283) * CEC-3577: fetch T.Rex log from the cloud * tabs? * CSS * smells * fix smells and warnings * suggestions * CEC-3577 Style tweak (#284) * CEC-3577: trex logs (#285) * CEC-3577: trex logs add filtering add progress bar for log fetching always fetch all the logs request canceling * don't hide progress * CEC-3751, CEC-3478 misc window status and invalid location value (#287) * CEC-3751 misc window status CEC-3478 invalid location value * Fix snapshot Update browser list * merge develop update snap * resolve comments * add date and time picker seperately, use checkbox for dropdown * added verification for date and fixed time picker * fix snap * resolve comments * removed small bug * tweak layout * added snap shot test for can signals * small change * Fix test * fix sms snap * change function name * mock can signals api * resolved comments * fix ci * Clean up --------- Co-authored-by: jwu-fisker <jwu@fiskerinc.com> Co-authored-by: John Wu <76966357+jwu-fisker@users.noreply.github.com> Co-authored-by: Eduard Voronkin <116690094+eduardvoronkin@users.noreply.github.com>
150 lines
3.7 KiB
JavaScript
150 lines
3.7 KiB
JavaScript
import { Box, Tab, Tabs } from "@material-ui/core";
|
|
import clsx from "clsx";
|
|
import React, { useEffect, useState } from "react";
|
|
import { useParams } from "react-router";
|
|
import { useLocation } from "react-router-dom";
|
|
|
|
import { hasRole, Permissions } from "../../../utils/roles";
|
|
import SelfServeTab from "../../CANSelfServe/SelfServeTab";
|
|
import { useStatusContext } from "../../Contexts/StatusContext";
|
|
import { useUserContext } from "../../Contexts/UserContext";
|
|
import TabPanel from "../../Controls/TabPanel";
|
|
import useStyles from "../../useStyles";
|
|
import CANFiltersTab from "./CANFiltersTab";
|
|
import CANSignalsTab from "./CANSignalsTab";
|
|
import CarUpdatesTab from "./CarUpdatesTab";
|
|
import CarDetailsTab from "./DetailsTab";
|
|
import DigitalTwinTab from "./DigitalTwinTab";
|
|
import ECUsTab from "./ECUsTab";
|
|
import FleetsTab from "./FleetsTab";
|
|
import RemoteCommandsTab from "./RemoteCommandsTab";
|
|
import TRexLogsTab from "./TRexLogsTab";
|
|
|
|
const tabHashes = ["details", "updates", "filters"];
|
|
|
|
const TabViews = [
|
|
{
|
|
label: "Details",
|
|
component: CarDetailsTab,
|
|
},
|
|
{
|
|
label: "Car Updates",
|
|
component: CarUpdatesTab,
|
|
},
|
|
{
|
|
label: "CAN Filters",
|
|
component: CANFiltersTab,
|
|
rolesPerProvider: Permissions.FiskerRead,
|
|
},
|
|
{
|
|
label: "Digital Twin",
|
|
component: DigitalTwinTab,
|
|
},
|
|
{
|
|
label: "CAN Signals",
|
|
component: CANSignalsTab,
|
|
},
|
|
{
|
|
label: "T.Rex logs",
|
|
component: TRexLogsTab,
|
|
},
|
|
{
|
|
label: "ECUs",
|
|
component: ECUsTab,
|
|
},
|
|
{
|
|
label: "Remote Commands",
|
|
component: RemoteCommandsTab,
|
|
},
|
|
{
|
|
label: "Fleets",
|
|
component: FleetsTab,
|
|
rolesPerProvider: Permissions.FiskerRead,
|
|
},
|
|
{
|
|
label: "CAN Signal Export",
|
|
component: SelfServeTab
|
|
}
|
|
];
|
|
|
|
const filterTabs = (data, groups, providers) => {
|
|
return data.reduce((result, item) => {
|
|
if (hasRole(groups, item.rolesPerProvider, providers)) {
|
|
result.push(item);
|
|
}
|
|
return result;
|
|
}, []);
|
|
};
|
|
|
|
const CarStatus = () => {
|
|
const { vin } = useParams();
|
|
const classes = useStyles();
|
|
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(() => {
|
|
const title = `Vehicle ${vin} Details`;
|
|
setTitle(title);
|
|
setSitePath([
|
|
{
|
|
label: "Vehicles",
|
|
link: "/vehicles",
|
|
},
|
|
{
|
|
label: title,
|
|
},
|
|
]);
|
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
}, [vin]);
|
|
|
|
const handleTabChange = (_event, newIndex) => {
|
|
setTabIndex(newIndex);
|
|
};
|
|
|
|
return (
|
|
<div className={clsx(classes.paper, classes.tableSize)}>
|
|
<Box
|
|
className={classes.tableToolbar}
|
|
sx={{ borderBottom: 1, borderColor: "divider" }}
|
|
>
|
|
<Tabs
|
|
value={tabIndex}
|
|
onChange={handleTabChange}
|
|
aria-label="car tabs"
|
|
variant="scrollable"
|
|
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 vin={vin}/>
|
|
</TabPanel>
|
|
))}
|
|
</div>
|
|
);
|
|
};
|
|
|
|
function tabProps(index) {
|
|
return {
|
|
id: `tab-${index}`,
|
|
"aria-controls": `tabpanel-${index}`,
|
|
};
|
|
}
|
|
|
|
export default CarStatus;
|