import React, { useState, useRef, useEffect, useMemo } from "react";
|
import {
|
useTranslate,
|
TabbedShowLayout,
|
useShowContext,
|
} from 'react-admin';
|
import {
|
Box,
|
Button,
|
Card,
|
CardContent,
|
Stack,
|
Typography,
|
Avatar,
|
Skeleton,
|
Divider,
|
List,
|
ListItem,
|
ListItemAvatar,
|
ListItemText,
|
ListItemSecondaryAction,
|
} from '@mui/material';
|
import { formatDistance } from 'date-fns';
|
import request from '@/utils/request';
|
import { useTheme } from '@mui/material/styles';
|
import { getTaskStsColor } from '@/utils/color-util';
|
import ListEmptyTip from "../../components/ListEmptyTip";
|
|
const TaskItem = ({ record, now }) => {
|
const translate = useTranslate();
|
const theme = useTheme();
|
|
return (
|
<>
|
<ListItem button>
|
<Stack direction="row" spacing={1} alignItems="center" width="100%">
|
<ListItemAvatar>
|
<Avatar
|
alt={record.seqNum}
|
variant="rounded"
|
sx={{
|
'& img': { objectFit: 'contain' },
|
fontSize: '0.9rem',
|
width: 40,
|
height: 25,
|
bgcolor: getTaskStsColor(record.taskSts$),
|
}}
|
>
|
{record.seqNum}
|
</Avatar>
|
</ListItemAvatar>
|
<ListItemText
|
primary={<>
|
<Stack direction={'row'}>
|
<Typography
|
variant="body1"
|
color="textSecondary"
|
component="span"
|
sx={{ fontWeight: '600' }}
|
>
|
{record.taskType$}
|
</Typography>
|
<Typography
|
variant="caption"
|
color="textSecondary"
|
component="span"
|
>
|
- {record.taskTypeEl}
|
</Typography>
|
</Stack>
|
|
</>}
|
secondary={
|
<>
|
<Typography
|
variant="body2"
|
color="textSecondary"
|
component="span"
|
sx={{ fontWeight: 'bold' }}
|
>
|
{record.taskSts$}
|
</Typography>
|
</>
|
}
|
/>
|
<ListItemText
|
variant="body2"
|
color="textSecondary"
|
primary={<>
|
<Typography
|
variant="body2"
|
color="textPrimary"
|
component="span"
|
>
|
{record.oriLoc$ || ''}{record.oriSta$ || ''} - {record.destLoc$ || ''}{record.destSta$ || ''}
|
</Typography>
|
</>}
|
secondary={`code: ${record.destCode$ || ''}`}
|
/>
|
<ListItemSecondaryAction>
|
<Typography
|
variant="body2"
|
color="textSecondary"
|
component="span"
|
>
|
last update {' '}
|
{formatDistance(record.createTime, now)} ago{' '}
|
</Typography>
|
</ListItemSecondaryAction>
|
</Stack>
|
</ListItem>
|
</>
|
)
|
}
|
|
export const AgvShowTask = ({ agvId, pageSize = 10 }) => {
|
const [currCount, setCurrCount] = useState(pageSize);
|
const [records, setRecords] = useState(null);
|
const [total, setTotal] = useState(0);
|
const translate = useTranslate();
|
|
useEffect(() => {
|
const http = async () => {
|
const res = await request.post('task/page', {
|
agvId: agvId,
|
pageSize: currCount,
|
orderBy: 'create_time desc',
|
});
|
const { code, msg, data } = res.data;
|
if (code === 200) {
|
setTotal(data.total);
|
setRecords(data.records);
|
} else {
|
setTotal(0);
|
setRecords(null);
|
}
|
}
|
if (agvId) { http() }
|
}, [agvId, currCount]);
|
|
if (!records) {
|
return (
|
<Stack mt={0.5}>
|
{Array.from({ length: 5 }).map((_, index) => (
|
<Stack spacing={2} sx={{ mt: 1 }} key={index}>
|
<Stack
|
direction="row"
|
spacing={2}
|
sx={{ alignItems: 'center' }}
|
>
|
<Skeleton
|
variant="circular"
|
width={20}
|
height={20}
|
/>
|
<Skeleton width="100%" />
|
</Stack>
|
<Skeleton variant="rectangular" height={50} />
|
<Divider />
|
</Stack>
|
))}
|
</Stack>
|
);
|
}
|
const now = Date.now();
|
|
return (
|
<>
|
{records.length > 0 ? (
|
<Box >
|
<List>
|
{records.map(record => {
|
return (
|
<React.Fragment key={record.id}>
|
<TaskItem
|
key={record.id}
|
record={record}
|
now={now}
|
/>
|
<Divider />
|
</React.Fragment>
|
)
|
})}
|
{currCount < total && (
|
<Button
|
onClick={() =>
|
setCurrCount(
|
currCount =>
|
currCount + pageSize
|
)
|
}
|
fullWidth
|
sx={{ mt: 1 }}
|
>
|
{translate('common.action.loadMore')}
|
</Button>
|
)}
|
</List>
|
</Box>
|
) : (
|
<ListEmptyTip />
|
)}
|
|
</>
|
)
|
}
|