|  |  |  | 
|---|
|  |  |  | import React, { useState, useRef, useEffect, useMemo } from "react"; | 
|---|
|  |  |  | import { | 
|---|
|  |  |  | RecordContextProvider, | 
|---|
|  |  |  | ReferenceManyField, | 
|---|
|  |  |  | ShowBase, | 
|---|
|  |  |  | SortButton, | 
|---|
|  |  |  | TabbedShowLayout, | 
|---|
|  |  |  | useListContext, | 
|---|
|  |  |  | useRecordContext, | 
|---|
|  |  |  | useShowContext, | 
|---|
|  |  |  | } from 'react-admin'; | 
|---|
|  |  |  | import { Link as RouterLink, useLocation } from 'react-router-dom'; | 
|---|
|  |  |  | import { | 
|---|
|  |  |  | Box, | 
|---|
|  |  |  | Button, | 
|---|
|  |  |  | Card, | 
|---|
|  |  |  | CardContent, | 
|---|
|  |  |  | List, | 
|---|
|  |  |  | ListItem, | 
|---|
|  |  |  | ListItemAvatar, | 
|---|
|  |  |  | ListItemSecondaryAction, | 
|---|
|  |  |  | ListItemText, | 
|---|
|  |  |  | Stack, | 
|---|
|  |  |  | Typography, | 
|---|
|  |  |  | Avatar, | 
|---|
|  |  |  | } from '@mui/material'; | 
|---|
|  |  |  | import { formatDistance } from 'date-fns'; | 
|---|
|  |  |  | import { AgvShowDetail } from "./show/AgvShowDetail"; | 
|---|
|  |  |  | import { AgvShowAside } from "./show/AgvShowAside"; | 
|---|
|  |  |  |  | 
|---|
|  |  |  | import { AgvShowTask } from "./show/AgvShowTask"; | 
|---|
|  |  |  | import { AgvShowError } from "./show/AgvShowError"; | 
|---|
|  |  |  | import CustomerTopToolBar from "../components/EditTopToolBar"; | 
|---|
|  |  |  | import { useTheme } from '@mui/material/styles'; | 
|---|
|  |  |  | import PulseSignal from "../components/PulseSignal"; | 
|---|
|  |  |  |  | 
|---|
|  |  |  | export const AgvShow = () => { | 
|---|
|  |  |  |  | 
|---|
|  |  |  | return ( | 
|---|
|  |  |  | <> | 
|---|
|  |  |  | <ShowBase> | 
|---|
|  |  |  | 
|---|
|  |  |  |  | 
|---|
|  |  |  | const AgvShowContent = (props) => { | 
|---|
|  |  |  | const { record, isPending } = useShowContext(); | 
|---|
|  |  |  | const theme = useTheme(); | 
|---|
|  |  |  | const [online, setOnline] = useState(false); | 
|---|
|  |  |  |  | 
|---|
|  |  |  | useEffect(() => { | 
|---|
|  |  |  | if (record) { | 
|---|
|  |  |  | setOnline(record.online) | 
|---|
|  |  |  | } | 
|---|
|  |  |  | }, [record]) | 
|---|
|  |  |  |  | 
|---|
|  |  |  | if (isPending || !record) return null; | 
|---|
|  |  |  |  | 
|---|
|  |  |  | return ( | 
|---|
|  |  |  | <> | 
|---|
|  |  |  | <Box mt={2} display="flex"> | 
|---|
|  |  |  | <Box flex="1"> | 
|---|
|  |  |  | <Box flex="1" sx={{ | 
|---|
|  |  |  | ...(!record.online && { | 
|---|
|  |  |  | animation: 'showBorderPulse 2s infinite', | 
|---|
|  |  |  | '@keyframes showBorderPulse': { | 
|---|
|  |  |  | '0%': { | 
|---|
|  |  |  | boxShadow: '0 0 2px 1px rgba(255, 0, 0, 0.1)', | 
|---|
|  |  |  | }, | 
|---|
|  |  |  | '50%': { | 
|---|
|  |  |  | boxShadow: '0 0 3px 2px rgba(255, 0, 0, 0.3)', | 
|---|
|  |  |  | }, | 
|---|
|  |  |  | '100%': { | 
|---|
|  |  |  | boxShadow: '0 0 2px 1px rgba(255, 0, 0, 0.1)', | 
|---|
|  |  |  | }, | 
|---|
|  |  |  | }, | 
|---|
|  |  |  | }) | 
|---|
|  |  |  | }}> | 
|---|
|  |  |  | <Card> | 
|---|
|  |  |  | <CardContent> | 
|---|
|  |  |  | <Box display="flex" mb={1}> | 
|---|
|  |  |  | <Typography variant="h5" ml={2} flex="1"> | 
|---|
|  |  |  | {record.uuid} | 
|---|
|  |  |  | </Typography> | 
|---|
|  |  |  | <CardContent sx={{ pt: 0 }}> | 
|---|
|  |  |  | <Box display="flex" mb={1} sx={{ | 
|---|
|  |  |  | justifyContent: 'space-between', | 
|---|
|  |  |  | alignItems: 'center', | 
|---|
|  |  |  | }}> | 
|---|
|  |  |  | <CustomerTopToolBar backPrevious /> | 
|---|
|  |  |  | <Box mt={1} mr={1}> | 
|---|
|  |  |  | <Stack direction='row'> | 
|---|
|  |  |  | <Box mt={.8} mr={2}> | 
|---|
|  |  |  | <PulseSignal | 
|---|
|  |  |  | flag={online} | 
|---|
|  |  |  | width={10} | 
|---|
|  |  |  | /> | 
|---|
|  |  |  | </Box> | 
|---|
|  |  |  | <Typography | 
|---|
|  |  |  | variant="h5" | 
|---|
|  |  |  | sx={{ | 
|---|
|  |  |  | mt: .5, | 
|---|
|  |  |  | mr: 2 | 
|---|
|  |  |  | }} | 
|---|
|  |  |  | > | 
|---|
|  |  |  | {record.agvModelData?.type} | 
|---|
|  |  |  | </Typography> | 
|---|
|  |  |  | <Avatar sx={{ bgcolor: theme.palette.primary.main }}>{record.uuid}</Avatar> | 
|---|
|  |  |  | </Stack> | 
|---|
|  |  |  | </Box> | 
|---|
|  |  |  | </Box> | 
|---|
|  |  |  |  | 
|---|
|  |  |  | <TabbedShowLayout | 
|---|
|  |  |  | 
|---|
|  |  |  | '& .RaTabbedShowLayout-content': { p: 0 }, | 
|---|
|  |  |  | }} | 
|---|
|  |  |  | > | 
|---|
|  |  |  | <TabbedShowLayout.Tab label="DETAIL"> | 
|---|
|  |  |  | <AgvShowDetail /> | 
|---|
|  |  |  | <TabbedShowLayout.Tab label="page.agv.show.tabs.detail"> | 
|---|
|  |  |  | <AgvShowDetail agvId={record.id} setOnline={setOnline} /> | 
|---|
|  |  |  | </TabbedShowLayout.Tab> | 
|---|
|  |  |  | <TabbedShowLayout.Tab label="page.agv.show.tabs.task" path="tasks"> | 
|---|
|  |  |  | <AgvShowTask agvId={record.id} /> | 
|---|
|  |  |  | </TabbedShowLayout.Tab> | 
|---|
|  |  |  | <TabbedShowLayout.Tab label="page.agv.show.tabs.error" path="errors"> | 
|---|
|  |  |  | <AgvShowError agvId={record.id} /> | 
|---|
|  |  |  | </TabbedShowLayout.Tab> | 
|---|
|  |  |  | </TabbedShowLayout> | 
|---|
|  |  |  | </CardContent> | 
|---|