CEC-1450 Show Trex version (#169)
* CEC-1450 Show Trex version * Code smells * Clean up * Fixes * Optimize test
This commit is contained in:
@@ -7484,6 +7484,24 @@ exports[`App Route /vehicle-status authenticated 1`] = `
|
||||
class="MuiTouchRipple-root"
|
||||
/>
|
||||
</button>
|
||||
<button
|
||||
aria-controls="tabpanel-3"
|
||||
aria-selected="false"
|
||||
class="MuiButtonBase-root MuiTab-root MuiTab-textColorInherit"
|
||||
id="tab-3"
|
||||
role="tab"
|
||||
tabindex="-1"
|
||||
type="button"
|
||||
>
|
||||
<span
|
||||
class="MuiTab-wrapper"
|
||||
>
|
||||
Digital Twin
|
||||
</span>
|
||||
<span
|
||||
class="MuiTouchRipple-root"
|
||||
/>
|
||||
</button>
|
||||
</div>
|
||||
<span
|
||||
class="PrivateTabIndicator-root-1424 PrivateTabIndicator-colorSecondary-1426 MuiTabs-indicator"
|
||||
@@ -7634,6 +7652,12 @@ exports[`App Route /vehicle-status authenticated 1`] = `
|
||||
id="tabpanel-2"
|
||||
role="tabpanel"
|
||||
/>
|
||||
<div
|
||||
aria-labelledby="tab-3"
|
||||
hidden=""
|
||||
id="tabpanel-3"
|
||||
role="tabpanel"
|
||||
/>
|
||||
</div>
|
||||
</main>
|
||||
</main>
|
||||
|
||||
64
src/components/Cars/Status/DigitalTwinTab.jsx
Normal file
64
src/components/Cars/Status/DigitalTwinTab.jsx
Normal file
@@ -0,0 +1,64 @@
|
||||
import React, { useEffect, useState } from "react";
|
||||
import clsx from "clsx";
|
||||
import { Typography } from "@material-ui/core";
|
||||
|
||||
import useStyles from "../../useStyles";
|
||||
import DigitalTwin from "../../DigitalTwin";
|
||||
import {
|
||||
useVehicleContext,
|
||||
VehicleProvider,
|
||||
} from "../../Contexts/VehicleContext";
|
||||
import { useStatusContext } from "../../Contexts/StatusContext";
|
||||
import { useUserContext } from "../../Contexts/UserContext";
|
||||
import { logger } from "../../../services/monitoring";
|
||||
|
||||
const Main = (props) => {
|
||||
const { getState } = useVehicleContext();
|
||||
const {
|
||||
token: {
|
||||
idToken: { jwtToken: token },
|
||||
},
|
||||
} = useUserContext();
|
||||
const { setMessage } = useStatusContext();
|
||||
const classes = useStyles();
|
||||
const [carState, setCarState] = useState(null);
|
||||
const { vin } = props;
|
||||
|
||||
useEffect(() => {
|
||||
if (!vin) return;
|
||||
(async () => {
|
||||
try {
|
||||
const result = await getState(token, vin);
|
||||
setCarState(result.data);
|
||||
} catch (e) {
|
||||
setMessage(e.message);
|
||||
logger.warn(e.stack);
|
||||
}
|
||||
})();
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [vin]);
|
||||
|
||||
return (
|
||||
<div className={clsx(classes.paper, classes.tableSize)}>
|
||||
<Typography variant="h6" style={{ paddingBottom: "10px" }}>
|
||||
Digital Twin
|
||||
</Typography>
|
||||
{carState && (
|
||||
<>
|
||||
<div>
|
||||
<b>Connected</b>: {carState.online.toString()}
|
||||
</div>
|
||||
<DigitalTwin {...carState} />
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
const DigitalTwinTab = (props) => (
|
||||
<VehicleProvider>
|
||||
<Main {...props} />
|
||||
</VehicleProvider>
|
||||
);
|
||||
|
||||
export default DigitalTwinTab;
|
||||
36
src/components/Cars/Status/DigitalTwinTab.test.jsx
Normal file
36
src/components/Cars/Status/DigitalTwinTab.test.jsx
Normal file
@@ -0,0 +1,36 @@
|
||||
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 { StatusProvider } from "../../Contexts/StatusContext";
|
||||
import { UserProvider, setToken } from "../../Contexts/UserContext";
|
||||
import { TEST_AUTH_OBJECT } from "../../../utils/testing";
|
||||
import DigitalTwinTab from "./DigitalTwinTab";
|
||||
|
||||
const renderDetailsTab = async () => {
|
||||
const { container } = render(
|
||||
<StatusProvider>
|
||||
<UserProvider>
|
||||
<DigitalTwinTab vin="TESTVIN1234567890" />
|
||||
</UserProvider>
|
||||
</StatusProvider>
|
||||
);
|
||||
await waitFor(() => {
|
||||
/* render */
|
||||
});
|
||||
return container;
|
||||
};
|
||||
|
||||
describe("DigitalTwinTab", () => {
|
||||
it("Render", async () => {
|
||||
setToken(TEST_AUTH_OBJECT);
|
||||
const container = await renderDetailsTab();
|
||||
expect(container).toMatchSnapshot();
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,143 @@
|
||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`DigitalTwinTab Render 1`] = `
|
||||
<div>
|
||||
<div
|
||||
data-testid="mocked-statusprovider"
|
||||
>
|
||||
<div
|
||||
data-testid="mocked-userprovider"
|
||||
>
|
||||
<div
|
||||
data-testid="mocked-vehicleprovider"
|
||||
>
|
||||
<div
|
||||
class="makeStyles-paper-3 makeStyles-tableSize-53"
|
||||
>
|
||||
<h6
|
||||
class="MuiTypography-root MuiTypography-h6"
|
||||
style="padding-bottom: 10px;"
|
||||
>
|
||||
Digital Twin
|
||||
</h6>
|
||||
<div>
|
||||
<b>
|
||||
Connected
|
||||
</b>
|
||||
:
|
||||
false
|
||||
</div>
|
||||
<div>
|
||||
<p>
|
||||
<b>
|
||||
Battery
|
||||
</b>
|
||||
:
|
||||
95%
|
||||
</p>
|
||||
<div
|
||||
class="makeStyles-popupSection-40"
|
||||
>
|
||||
<h3>
|
||||
Doors
|
||||
</h3>
|
||||
<p>
|
||||
<b>
|
||||
hood
|
||||
</b>
|
||||
:
|
||||
closed
|
||||
</p>
|
||||
<p>
|
||||
<b>
|
||||
left_front
|
||||
</b>
|
||||
:
|
||||
closed
|
||||
</p>
|
||||
<p>
|
||||
<b>
|
||||
left_rear
|
||||
</b>
|
||||
:
|
||||
closed
|
||||
</p>
|
||||
<p>
|
||||
<b>
|
||||
right_front
|
||||
</b>
|
||||
:
|
||||
closed
|
||||
</p>
|
||||
<p>
|
||||
<b>
|
||||
right_rear
|
||||
</b>
|
||||
:
|
||||
closed
|
||||
</p>
|
||||
<p>
|
||||
<b>
|
||||
trunk
|
||||
</b>
|
||||
:
|
||||
closed
|
||||
</p>
|
||||
</div>
|
||||
<div
|
||||
class="makeStyles-popupSection-40"
|
||||
>
|
||||
<h3>
|
||||
Location
|
||||
</h3>
|
||||
<p>
|
||||
<b>
|
||||
altitude
|
||||
</b>
|
||||
:
|
||||
17
|
||||
</p>
|
||||
<p>
|
||||
<b>
|
||||
longitude
|
||||
</b>
|
||||
:
|
||||
-122.414°
|
||||
</p>
|
||||
<p>
|
||||
<b>
|
||||
latitude
|
||||
</b>
|
||||
:
|
||||
37.764°
|
||||
</p>
|
||||
</div>
|
||||
<div
|
||||
class="makeStyles-popupSection-40"
|
||||
>
|
||||
<p>
|
||||
<b>
|
||||
Trex Version
|
||||
</b>
|
||||
:
|
||||
1000000
|
||||
</p>
|
||||
</div>
|
||||
<div
|
||||
class="makeStyles-popupSection-40"
|
||||
>
|
||||
<p>
|
||||
<b>
|
||||
Updated at
|
||||
</b>
|
||||
:
|
||||
7/26/2022 12:26:38 AM
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
@@ -83,6 +83,24 @@ exports[`CarStatus Render 1`] = `
|
||||
class="MuiTouchRipple-root"
|
||||
/>
|
||||
</button>
|
||||
<button
|
||||
aria-controls="tabpanel-3"
|
||||
aria-selected="false"
|
||||
class="MuiButtonBase-root MuiTab-root MuiTab-textColorInherit"
|
||||
id="tab-3"
|
||||
role="tab"
|
||||
tabindex="-1"
|
||||
type="button"
|
||||
>
|
||||
<span
|
||||
class="MuiTab-wrapper"
|
||||
>
|
||||
Digital Twin
|
||||
</span>
|
||||
<span
|
||||
class="MuiTouchRipple-root"
|
||||
/>
|
||||
</button>
|
||||
</div>
|
||||
<span
|
||||
class="PrivateTabIndicator-root-63 PrivateTabIndicator-colorSecondary-65 MuiTabs-indicator"
|
||||
@@ -179,6 +197,12 @@ exports[`CarStatus Render 1`] = `
|
||||
id="tabpanel-2"
|
||||
role="tabpanel"
|
||||
/>
|
||||
<div
|
||||
aria-labelledby="tab-3"
|
||||
hidden=""
|
||||
id="tabpanel-3"
|
||||
role="tabpanel"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -7,15 +7,12 @@ import { Box, Tab, Tabs } from "@material-ui/core";
|
||||
import CarDetailsTab from "./DetailsTab";
|
||||
import CarUpdatesTab from "./CarUpdatesTab";
|
||||
import CANFiltersTab from "./CANFiltersTab";
|
||||
import DigitalTwinTab from "./DigitalTwinTab";
|
||||
import TabPanel from "../../Controls/TabPanel";
|
||||
import { useStatusContext } from "../../Contexts/StatusContext";
|
||||
import useStyles from "../../useStyles";
|
||||
|
||||
const tabHashes = [
|
||||
"details",
|
||||
"updates",
|
||||
"filters"
|
||||
]
|
||||
const tabHashes = ["details", "updates", "filters"];
|
||||
|
||||
const CarStatus = () => {
|
||||
const { vin } = useParams();
|
||||
@@ -25,8 +22,8 @@ const CarStatus = () => {
|
||||
const [tabIndex, setTabIndex] = React.useState(0);
|
||||
|
||||
useEffect(() => {
|
||||
const key = hash.replace("#", "")
|
||||
const index = tabHashes.findIndex(element => element === key);
|
||||
const key = hash.replace("#", "");
|
||||
const index = tabHashes.findIndex((element) => element === key);
|
||||
if (index >= 0) setTabIndex(index);
|
||||
}, [hash]);
|
||||
|
||||
@@ -51,11 +48,20 @@ const CarStatus = () => {
|
||||
|
||||
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" indicatorColor="secondary">
|
||||
<Box
|
||||
className={classes.tableToolbar}
|
||||
sx={{ borderBottom: 1, borderColor: "divider" }}
|
||||
>
|
||||
<Tabs
|
||||
value={tabIndex}
|
||||
onChange={handleTabChange}
|
||||
aria-label="car tabs"
|
||||
indicatorColor="secondary"
|
||||
>
|
||||
<Tab label="Details" {...tabProps(0)} />
|
||||
<Tab label="Car Updates" {...tabProps(1)} />
|
||||
<Tab label="CAN Filters" {...tabProps(2)} />
|
||||
<Tab label="Digital Twin" {...tabProps(3)} />
|
||||
</Tabs>
|
||||
</Box>
|
||||
|
||||
@@ -70,14 +76,18 @@ const CarStatus = () => {
|
||||
<TabPanel value={tabIndex} index={2}>
|
||||
<CANFiltersTab />
|
||||
</TabPanel>
|
||||
</div >
|
||||
|
||||
<TabPanel value={tabIndex} index={3}>
|
||||
<DigitalTwinTab vin={vin} />
|
||||
</TabPanel>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
function tabProps(index) {
|
||||
return {
|
||||
id: `tab-${index}`,
|
||||
"aria-controls": `tabpanel-${index}`
|
||||
"aria-controls": `tabpanel-${index}`,
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -5,17 +5,17 @@ let busy = false;
|
||||
const filters = [
|
||||
{
|
||||
can_id: "123-456",
|
||||
interval: 789
|
||||
interval: 789,
|
||||
},
|
||||
{
|
||||
can_id: "1",
|
||||
interval: 1000
|
||||
interval: 1000,
|
||||
},
|
||||
{
|
||||
can_id: "1000",
|
||||
interval: 1
|
||||
}
|
||||
]
|
||||
interval: 1,
|
||||
},
|
||||
];
|
||||
|
||||
let vehicle = {
|
||||
vin: "3C4PDCBG0ET127145",
|
||||
@@ -24,8 +24,55 @@ let vehicle = {
|
||||
trim: "Basic",
|
||||
ecu_list: "ECUA 2.0.0, ECUB 2.1.1",
|
||||
log_level: "info",
|
||||
canbus: { enabled: true, data_logger_enabled: true, max_mem_buffer_size: 1, max_disk_buffer_size: 2, filters: filters },
|
||||
canbus: {
|
||||
enabled: true,
|
||||
data_logger_enabled: true,
|
||||
max_mem_buffer_size: 1,
|
||||
max_disk_buffer_size: 2,
|
||||
filters: filters,
|
||||
},
|
||||
};
|
||||
let vehicleState = {
|
||||
data: {
|
||||
online: false,
|
||||
battery: {
|
||||
percent: 95,
|
||||
},
|
||||
max_range: {
|
||||
max_miles: 577,
|
||||
},
|
||||
doors: {
|
||||
hood: false,
|
||||
left_front: false,
|
||||
left_rear: false,
|
||||
right_front: false,
|
||||
right_rear: false,
|
||||
trunk: false,
|
||||
},
|
||||
location: {
|
||||
altitude: 17,
|
||||
longitude: -122.414,
|
||||
latitude: 37.764,
|
||||
},
|
||||
door_locks: {
|
||||
driver: false,
|
||||
all: false,
|
||||
},
|
||||
sunroof: {
|
||||
sunroof: 0,
|
||||
},
|
||||
cabin_climate: {
|
||||
cabin_temperature: 0,
|
||||
internal_temperature: 29,
|
||||
},
|
||||
ambient_temperature: {
|
||||
temperature: 26,
|
||||
},
|
||||
trex_version: "1000000",
|
||||
updated: "2022-07-26T00:26:38.880381Z",
|
||||
},
|
||||
};
|
||||
|
||||
let vehicles = [];
|
||||
let models = ["Ocean", "PEAR"];
|
||||
let years = [2023, 2024];
|
||||
@@ -83,7 +130,7 @@ export const useVehicleContext = () => ({
|
||||
getModels: jest.fn(() => {
|
||||
models = ["Ocean", "PEAR"];
|
||||
}),
|
||||
getState: jest.fn(),
|
||||
getState: jest.fn(() => vehicleState),
|
||||
getYears: jest.fn(() => {
|
||||
years = [2023, 2024];
|
||||
}),
|
||||
|
||||
60
src/components/DigitalTwin/index.js
Normal file
60
src/components/DigitalTwin/index.js
Normal file
@@ -0,0 +1,60 @@
|
||||
import React from "react";
|
||||
|
||||
import useStyles from "../useStyles";
|
||||
import { LocalDateTimeString } from "../../utils/dates";
|
||||
|
||||
const keyValueTemplate = (key, value) => (
|
||||
<p key={key}>
|
||||
<b>{key}</b>: {value}
|
||||
</p>
|
||||
);
|
||||
const openCloseState = (value) => (value ? "open" : "closed");
|
||||
const mapOpenCloseState = (value) =>
|
||||
keyValueTemplate(value[0], openCloseState(value[1]));
|
||||
|
||||
const DigitalTwin = (props) => {
|
||||
const classes = useStyles();
|
||||
const { battery, doors, location, trex_version, updated, windows } = props;
|
||||
|
||||
return (
|
||||
<div>
|
||||
{battery != null && keyValueTemplate("Battery", `${battery.percent}%`)}
|
||||
{doors != null && (
|
||||
<div className={classes.popupSection}>
|
||||
<h3>Doors</h3>
|
||||
{Object.entries(doors).map(mapOpenCloseState)}
|
||||
</div>
|
||||
)}
|
||||
{windows != null && (
|
||||
<div className={classes.popupSection}>
|
||||
<h3>Windows</h3>
|
||||
{Object.entries(windows).map(mapOpenCloseState)}
|
||||
</div>
|
||||
)}
|
||||
{location != null && (
|
||||
<div className={classes.popupSection}>
|
||||
<h3>Location</h3>
|
||||
{Object.entries(location).map((value) => {
|
||||
if (value[0] === "altitude") {
|
||||
return keyValueTemplate(value[0], value[1]);
|
||||
} else {
|
||||
return keyValueTemplate(value[0], `${value[1]}°`);
|
||||
}
|
||||
})}
|
||||
</div>
|
||||
)}
|
||||
{trex_version && (
|
||||
<div className={classes.popupSection}>
|
||||
{keyValueTemplate("Trex Version", trex_version)}
|
||||
</div>
|
||||
)}
|
||||
{updated != null && (
|
||||
<div className={classes.popupSection}>
|
||||
{keyValueTemplate("Updated at", LocalDateTimeString(updated))}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default DigitalTwin;
|
||||
@@ -179,7 +179,8 @@ const Component = () => {
|
||||
doors={carState.doors}
|
||||
location={carState.location}
|
||||
windows={carState.windows}
|
||||
updatedAt={carState.updated}
|
||||
trex_version={carState.trex_version}
|
||||
updated={carState.updated}
|
||||
className={classes.popup}
|
||||
onClose={handleClose}
|
||||
/>
|
||||
|
||||
@@ -1,84 +1,63 @@
|
||||
import React from "react";
|
||||
import Dialog from '@material-ui/core/Dialog';
|
||||
import MuiDialogTitle from '@material-ui/core/DialogTitle';
|
||||
import IconButton from '@material-ui/core/IconButton';
|
||||
import CloseIcon from '@material-ui/icons/Close';
|
||||
import Typography from '@material-ui/core/Typography';
|
||||
import Dialog from "@material-ui/core/Dialog";
|
||||
import MuiDialogTitle from "@material-ui/core/DialogTitle";
|
||||
import IconButton from "@material-ui/core/IconButton";
|
||||
import CloseIcon from "@material-ui/icons/Close";
|
||||
import Typography from "@material-ui/core/Typography";
|
||||
|
||||
import useStyles from "../useStyles";
|
||||
import { LocalDateTimeString } from "../../utils/dates";
|
||||
import DigitalTwin from "../DigitalTwin";
|
||||
|
||||
const VehiclePopUp = (props) => {
|
||||
const classes = useStyles();
|
||||
const { vin, online, battery, doors, location, updatedAt, windows, onClose } = props;
|
||||
const classes = useStyles();
|
||||
const { vin, online, battery, doors, location, windows, onClose } = props;
|
||||
|
||||
return (
|
||||
<Dialog
|
||||
fullWidth
|
||||
classes={{ paper: classes.popUp }}
|
||||
open={true}
|
||||
onClose={onClose}
|
||||
>
|
||||
<DialogTitle align="center" onClose={onClose}>{vin}</DialogTitle>
|
||||
<div align="center" className={classes.popUpContent}>
|
||||
<p><b>Connected</b>: {online.toString()}</p>
|
||||
{online && (
|
||||
<div>
|
||||
{battery != null && (
|
||||
<p><b>Battery</b>: {battery.percent}%</p>
|
||||
)}
|
||||
{doors != null && (
|
||||
<div className={classes.popupSection}>
|
||||
<h3>Doors</h3>
|
||||
{Object.entries(doors).map((value) => (<p key={value[0]}><b>{value[0]}</b>: {value[1] ? "open" : "closed"}</p>))}
|
||||
</div>
|
||||
)}
|
||||
{windows != null && (
|
||||
<div className={classes.popupSection}>
|
||||
<h3>Windows</h3>
|
||||
{Object.entries(windows).map((value) => (<p key={value[0]}><b>{value[0]}</b>: {value[1] ? "open" : "closed"}</p>))}
|
||||
</div>
|
||||
)}
|
||||
{location != null && (
|
||||
<div className={classes.popupSection}>
|
||||
<h3>Location</h3>
|
||||
{Object.entries(location).map((value) => {
|
||||
if (value[0] === "altitude") {
|
||||
return (<p key={value[0]}><b>{value[0]}</b>: {value[1]}</p>);
|
||||
} else {
|
||||
return (<p key={value[0]}><b>{value[0]}</b>: {value[1]}°</p>)
|
||||
}
|
||||
})}
|
||||
</div>
|
||||
)}
|
||||
{updatedAt != null && (
|
||||
<div className={classes.popupSection}>
|
||||
<p><b>Updated at</b>: {LocalDateTimeString(updatedAt)}</p>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
)}
|
||||
{(!online || (battery == null && doors == null && location == null && windows == null)) && (
|
||||
<p>No vehicle data to display.</p>
|
||||
)}
|
||||
</div>
|
||||
</Dialog >
|
||||
);
|
||||
return (
|
||||
<Dialog
|
||||
fullWidth
|
||||
classes={{ paper: classes.popUp }}
|
||||
open={true}
|
||||
onClose={onClose}
|
||||
>
|
||||
<DialogTitle align="center" onClose={onClose}>
|
||||
{vin}
|
||||
</DialogTitle>
|
||||
<div align="center" className={classes.popUpContent}>
|
||||
<p>
|
||||
<b>Connected</b>: {online.toString()}
|
||||
</p>
|
||||
{online && <DigitalTwin {...props} />}
|
||||
{(!online ||
|
||||
(battery == null &&
|
||||
doors == null &&
|
||||
location == null &&
|
||||
windows == null)) && <p>No vehicle data to display.</p>}
|
||||
</div>
|
||||
</Dialog>
|
||||
);
|
||||
};
|
||||
|
||||
const DialogTitle = (props) => {
|
||||
const { children, onClose, ...other } = props;
|
||||
const classes = useStyles();
|
||||
return (
|
||||
<MuiDialogTitle disableTypography className={classes.ppopUpTItle} {...other}>
|
||||
<Typography variant="h6">{children}</Typography>
|
||||
{onClose ? (
|
||||
<IconButton aria-label="close" className={classes.closeButton} onClick={onClose}>
|
||||
<CloseIcon />
|
||||
</IconButton>
|
||||
) : null}
|
||||
</MuiDialogTitle>
|
||||
);
|
||||
const { children, onClose, ...other } = props;
|
||||
const classes = useStyles();
|
||||
return (
|
||||
<MuiDialogTitle
|
||||
disableTypography
|
||||
className={classes.ppopUpTItle}
|
||||
{...other}
|
||||
>
|
||||
<Typography variant="h6">{children}</Typography>
|
||||
{onClose ? (
|
||||
<IconButton
|
||||
aria-label="close"
|
||||
className={classes.closeButton}
|
||||
onClick={onClose}
|
||||
>
|
||||
<CloseIcon />
|
||||
</IconButton>
|
||||
) : null}
|
||||
</MuiDialogTitle>
|
||||
);
|
||||
};
|
||||
|
||||
export { VehiclePopUp };
|
||||
|
||||
Reference in New Issue
Block a user