feat: 与我相关点击打开侧边详情 + 开发/测试转交功能
一、工作台交互改为侧边栏详情(点击卡片打开): - 调研/产品/UI:新建 PlanDetailDrawer - 子任务勾选、进度条、上传成果(链接/文件) - 开始/提交完成操作、转交功能 - 开发任务:复用 DevTaskDetailDrawer - 状态流转、阻塞管理、前置任务等完整功能 - 测试用例:复用 TestCaseDetailDrawer - 测试步骤、预期结果、关联Bug、提Bug - Bug:复用 BugDetailDrawer - 描述、截图、操作日志、状态转换 二、开发任务增加转交功能: - DevTaskDetailDrawer 顶部增加转交按钮 - 从 members 列表选择新负责人 - 更新 assigneeId 三、测试用例增加转交功能: - TestCaseDetailDrawer 顶部增加转交按钮 - 人员离职等场景可转交 四、版本详情同步: - 所有 Drawer 改动同时生效于版本详情页 (因为复用同一组件) Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -1,12 +1,13 @@
|
||||
'use client';
|
||||
|
||||
import { useState } from 'react';
|
||||
import { X, AlertTriangle, Link2, ChevronRight, Clock, User, Tag, Calendar, Play, Trash2, Pencil } from 'lucide-react';
|
||||
import { X, AlertTriangle, Link2, ChevronRight, Clock, User, Tag, Calendar, Play, Trash2, Pencil, ArrowRightLeft } from 'lucide-react';
|
||||
import { StatusBadge } from './StatusBadge';
|
||||
import { CategoryChip } from './CategoryChip';
|
||||
import { useDevTaskStore } from '@/stores/useDevTaskStore';
|
||||
import { useTaskCategoryStore } from '@/stores/useTaskCategoryStore';
|
||||
import { useRequirementStore } from '@/stores/useRequirementStore';
|
||||
import { useMemberStore } from '@/stores/useMemberStore';
|
||||
import { ALLOWED_TRANSITIONS, DEV_TASK_STATUS_LABEL, DEV_TASK_STATUS_COLOR, formatHours, calcActualHoursByDates } from '@/lib/dev-task';
|
||||
import type { DevTaskStatus } from '@/lib/dev-task';
|
||||
|
||||
@@ -17,9 +18,12 @@ interface Props {
|
||||
}
|
||||
|
||||
export function DevTaskDetailDrawer({ taskId, allTaskIds, onClose }: Props) {
|
||||
const { tasks, changeStatus, setBlocked, deleteTask } = useDevTaskStore();
|
||||
const { tasks, changeStatus, setBlocked, deleteTask, updateTask } = useDevTaskStore();
|
||||
const { categories } = useTaskCategoryStore();
|
||||
const { requirements } = useRequirementStore();
|
||||
const { members } = useMemberStore();
|
||||
const [showTransfer, setShowTransfer] = useState(false);
|
||||
const [transferTo, setTransferTo] = useState('');
|
||||
|
||||
const task = tasks.find((t) => t.id === taskId);
|
||||
if (!task) return null;
|
||||
@@ -59,11 +63,27 @@ export function DevTaskDetailDrawer({ taskId, allTaskIds, onClose }: Props) {
|
||||
<span className="text-[14px] font-semibold text-[var(--ink)] truncate max-w-[240px]">{task.title}</span>
|
||||
</div>
|
||||
<div className="flex items-center gap-1">
|
||||
{task.status !== 'submitted' && (
|
||||
<button onClick={() => setShowTransfer(!showTransfer)} className="p-1.5 rounded-lg hover:bg-blue-50 text-[var(--ink-muted)] hover:text-blue-500" title="转交"><ArrowRightLeft className="h-4 w-4" /></button>
|
||||
)}
|
||||
<button onClick={() => { if (confirm('确定删除此任务?')) { deleteTask(task.id); onClose(); } }} className="p-1.5 rounded-lg hover:bg-red-50 text-[var(--ink-muted)] hover:text-red-500" title="删除"><Trash2 className="h-4 w-4" /></button>
|
||||
<button onClick={onClose} className="p-1.5 rounded-lg hover:bg-[var(--bg-subtle)]"><X className="h-4 w-4 text-[var(--ink-muted)]" /></button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* 转交 */}
|
||||
{showTransfer && (
|
||||
<div className="mx-5 mt-3 rounded-lg border border-[var(--line)] p-3 flex items-center gap-2">
|
||||
<span className="text-[11px] text-[var(--ink-muted)] shrink-0">转交给:</span>
|
||||
<select value={transferTo} onChange={(e) => setTransferTo(e.target.value)} className="h-7 flex-1 rounded-lg border border-[var(--line)] px-2 text-[12px] focus:border-[var(--accent)] focus:outline-none">
|
||||
<option value="">选择人员</option>
|
||||
{members.filter((m) => m.name !== task.assigneeId).map((m) => <option key={m.id} value={m.name}>{m.name}</option>)}
|
||||
</select>
|
||||
<button onClick={() => { if (transferTo) { updateTask(task.id, { assigneeId: transferTo }); setShowTransfer(false); setTransferTo(''); } }} disabled={!transferTo} className="h-7 px-2.5 rounded text-[11px] font-medium bg-blue-500 text-white disabled:opacity-50">确认</button>
|
||||
<button onClick={() => setShowTransfer(false)} className="h-7 px-2 text-[11px] text-[var(--ink-muted)]">取消</button>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{/* 滚动区域 */}
|
||||
<div className="flex-1 overflow-y-auto p-4 space-y-3">
|
||||
|
||||
|
||||
Reference in New Issue
Block a user