import { CheckCircleOutlined, CloseCircleOutlined, ExclamationCircleOutlined, SyncOutlined, } from '@ant-design/icons'; import { Alert, type AlertProps, Button, Divider, Flex, List, Modal, Progress, Space, Tag, Tooltip, } from 'antd'; import { useCallback, useEffect, useMemo, useRef, useState } from 'react'; import { processSingleRule } from '@/pages/rules/utils'; import { $t } from '@/utils/i18n'; type TaskStatus = 'waiting' | 'processing' | 'success' | 'warning' | 'error'; type Task = { name: string; status: TaskStatus; errorMsg: string }; type BatchCloneModalProps = { visible: boolean; selectedRows: Partial[]; onClose?: (cb?: () => void) => void; onFinish?: (cb?: () => void) => void; }; const BatchCloneModal = ({ visible, selectedRows, onClose, onFinish, }: BatchCloneModalProps) => { const [tasks, setTasks] = useState([]); const [isRunning, setIsRunning] = useState(false); const [currentRunning, setCurrentRunning] = useState(0); const selectedRowsRef = useRef(selectedRows); selectedRowsRef.current = selectedRows; useEffect(() => { if (visible) { setTasks( selectedRows.map((row) => ({ name: row.name || '', status: 'waiting', errorMsg: '', })), ); setIsRunning(false); setCurrentRunning(0); } }, [visible]); const finishedTasks = useMemo( () => tasks.filter((t) => t.status === 'success' || t.status === 'warning'), [tasks], ); const finishedMessage = useMemo(() => { const hasWarning = finishedTasks.some((t) => t.status === 'warning'); const type: AlertProps['type'] = hasWarning ? 'warning' : finishedTasks.length === tasks.length ? 'success' : 'error'; return { type, message: type === 'success' ? $t('pages.clones.step3.success') : type === 'warning' ? $t('pages.clones.step3.warning') : $t('pages.clones.step3.error'), }; }, [finishedTasks, tasks]); const startBatch = useCallback(async () => { const rows = selectedRowsRef.current; setIsRunning(true); for (let i = 0; i < rows.length; i++) { setCurrentRunning(i + 1); setTasks((prev) => { const next = [...prev]; next[i].status = 'processing'; return next; }); try { await processSingleRule({ payload: rows[i] }); setTasks((prev) => { const next = [...prev]; next[i].status = 'success'; return next; }); } catch (e: any) { setTasks((prev) => { const next = [...prev]; next[i].status = [1, 2, 3].includes(e.errType) ? 'warning' : 'error'; next[i].errorMsg = e.errMsg ? $t(e.errMsg) : e.respMessage; return next; }); } } setIsRunning(false); }, []); const handleReset = useCallback(() => { setTasks([]); setIsRunning(false); setCurrentRunning(0); }, []); return (
( {item.name} {item.status === 'processing' && ( }> {$t('pages.clones.step3.status1')} )} {item.status === 'success' && ( }> {$t('pages.clones.step3.status2')} )} {item.status === 'error' && ( }> {$t('pages.clones.step3.status3')} )} {item.status === 'warning' && ( }> {$t('pages.clones.step3.status4')} )} {item.status === 'waiting' && ( {$t('pages.clones.step3.status5')} )} )} />
{!isRunning && currentRunning === tasks.length && ( <> )} {!isRunning && currentRunning === 0 && ( )}
); }; export default BatchCloneModal;