| | |
| | | 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> |