'use client'; import { useState } from 'react'; import { X, AlertTriangle, Link2 } from 'lucide-react'; import { StatusBadge } from './StatusBadge'; import { CategoryChip } from './CategoryChip'; import { WorklogPanel } from './WorklogPanel'; import { useDevTaskStore } from '@/stores/useDevTaskStore'; import { useTaskCategoryStore } from '@/stores/useTaskCategoryStore'; import { ALLOWED_TRANSITIONS, DEV_TASK_STATUS_LABEL, formatHours } from '@/lib/dev-task'; import type { DevTask, DevTaskStatus } from '@/lib/dev-task'; interface Props { task: DevTask; allTasks: DevTask[]; onClose: () => void; } export function DevTaskDetailDrawer({ task, allTasks, onClose }: Props) { const { changeStatus, setBlocked } = useDevTaskStore(); const { categories } = useTaskCategoryStore(); const category = categories.find((c) => c.id === task.categoryId); const [blockReason, setBlockReason] = useState(task.blockReason || ''); const [showBlockInput, setShowBlockInput] = useState(false); const nextStatuses = ALLOWED_TRANSITIONS[task.status]; const predecessors = (task.predecessorIds || []).map((id) => allTasks.find((t) => t.id === id)).filter(Boolean) as DevTask[]; const handleTransition = (to: DevTaskStatus) => { const result = changeStatus(task.id, to); if (!result.ok) alert(result.message); }; const handleBlock = () => { if (!blockReason.trim()) return; setBlocked(task.id, true, blockReason.trim()); setShowBlockInput(false); }; const handleUnblock = () => { setBlocked(task.id, false); setBlockReason(''); }; return (
e.stopPropagation()}> {/* Header */}
{task.taskNo} {task.isBlocked && 阻塞}
{/* Body */}

{task.title}

{task.description &&

{task.description}

} {/* 状态流转 */} {nextStatuses.length > 0 && (
流转到: {nextStatuses.map((s) => ( ))}
)} {/* 阻塞管理 */}
阻塞状态 {task.isBlocked ? ( ) : ( )}
{task.isBlocked && (
{task.blockReason}
)} {showBlockInput && !task.isBlocked && (
setBlockReason(e.target.value)} onKeyDown={(e) => { if (e.key === 'Enter') handleBlock(); }} placeholder="阻塞原因" className="flex-1 h-8 rounded-md border border-[var(--line)] px-2 text-[12px] focus:border-[var(--accent)] focus:outline-none" />
)}
{/* 基本信息 */}
类型:
负责人:{task.assigneeId}
优先级:{task.priority}
预计工时:{formatHours(task.estimateHours)}
{task.dueDate &&
截止日期:{task.dueDate}
} {task.completedAt &&
完成日期:{task.completedAt}
}
{/* 前置任务 */} {predecessors.length > 0 && (
前置任务 {predecessors.map((p) => (
{p.taskNo} {p.title}
))}
)} {/* 工时记录 */}
); }