diff --git a/desktop/src/components/Automation/ApprovalQueue.tsx b/desktop/src/components/Automation/ApprovalQueue.tsx deleted file mode 100644 index 5b8c9bd..0000000 --- a/desktop/src/components/Automation/ApprovalQueue.tsx +++ /dev/null @@ -1,352 +0,0 @@ -/** - * ApprovalQueue - Approval Management Component - * - * Displays pending approvals for hand executions that require - * human approval, with approve/reject actions. - * - * @module components/Automation/ApprovalQueue - */ - -import { useState, useEffect, useCallback } from 'react'; -import { useHandStore } from '../../store/handStore'; -import type { Approval, ApprovalStatus } from '../../store/handStore'; -import { - Clock, - CheckCircle, - XCircle, - AlertTriangle, - RefreshCw, -} from 'lucide-react'; -import { useToast } from '../ui/Toast'; - -// === Status Config === - -const STATUS_CONFIG: Record = { - pending: { - label: '待处理', - className: 'bg-yellow-100 text-yellow-700 dark:bg-yellow-900/30 dark:text-yellow-400', - icon: Clock, - }, - approved: { - label: '已批准', - className: 'bg-green-100 text-green-700 dark:bg-green-900/30 dark:text-green-400', - icon: CheckCircle, - }, - rejected: { - label: '已拒绝', - className: 'bg-red-100 text-red-700 dark:bg-red-900/30 dark:text-red-400', - icon: XCircle, - }, - expired: { - label: '已过期', - className: 'bg-gray-100 text-gray-500 dark:bg-gray-800 dark:text-gray-400', - icon: AlertTriangle, - }, -}; - -// === Component Props === - -interface ApprovalQueueProps { - showFilters?: boolean; - maxHeight?: string; - onApprove?: (approval: Approval) => void; - onReject?: (approval: Approval) => void; -} - -// === Approval Card Component === - -interface ApprovalCardProps { - approval: Approval; - onApprove: () => Promise; - onReject: (reason: string) => Promise; - isProcessing: boolean; -} - -function ApprovalCard({ approval, onApprove, onReject, isProcessing }: ApprovalCardProps) { - const [showRejectInput, setShowRejectInput] = useState(false); - const [rejectReason, setRejectReason] = useState(''); - const StatusIcon = STATUS_CONFIG[approval.status].icon; - - const handleReject = useCallback(async () => { - if (!rejectReason.trim()) { - setShowRejectInput(true); - return; - } - await onReject(rejectReason); - setShowRejectInput(false); - setRejectReason(''); - }, [rejectReason, onReject]); - - const timeAgo = useCallback((dateStr: string) => { - const date = new Date(dateStr); - const now = new Date(); - const diffMs = now.getTime() - date.getTime(); - const diffMins = Math.floor(diffMs / 60000); - const diffHours = Math.floor(diffMins / 60); - const diffDays = Math.floor(diffHours / 24); - - if (diffMins < 1) return '刚刚'; - if (diffMins < 60) return `${diffMins} 分钟前`; - if (diffHours < 24) return `${diffHours} 小时前`; - return `${diffDays} 天前`; - }, []); - - return ( -
- {/* Header */} -
-
- - - {STATUS_CONFIG[approval.status].label} - - - {timeAgo(approval.requestedAt)} - -
-
- - {/* Content */} -
-

- {approval.handName} -

- {approval.reason && ( -

{approval.reason}

- )} - {approval.action && ( -

- 操作: {approval.action} -

- )} -
- - {/* Params Preview */} - {approval.params && Object.keys(approval.params).length > 0 && ( -
-

参数:

-
-            {JSON.stringify(approval.params, null, 2)}
-          
-
- )} - - {/* Reject Input */} - {showRejectInput && ( -
-