feat(版本详情): 完善流程日志与需求覆盖
This commit is contained in:
@@ -111,6 +111,10 @@ export function DevTaskTab({ versionId, requirementIds, versionDeadline }: Props
|
||||
}, [paged]);
|
||||
|
||||
const categoryMap = useMemo(() => new Map(categories.map((c) => [c.id, c])), [categories]);
|
||||
const categoryLabelWidthEm = useMemo(
|
||||
() => Math.max(4, ...categories.map((category) => category.name.length)) + 1,
|
||||
[categories],
|
||||
);
|
||||
const requirementMap = useMemo(() => new Map(requirements.map((r) => [r.id, r])), [requirements]);
|
||||
const allTaskIds = useMemo(() => versionTasks.map((t) => t.id), [versionTasks]);
|
||||
|
||||
@@ -179,11 +183,16 @@ export function DevTaskTab({ versionId, requirementIds, versionDeadline }: Props
|
||||
const reqProgress = calcGroupProgress(reqTasks);
|
||||
return (
|
||||
<div key={reqId} className="rounded-lg border border-[var(--line)] bg-[var(--bg-card)] overflow-hidden">
|
||||
<div className="flex items-center gap-2 px-4 py-2 bg-[var(--bg-subtle)] border-b border-[var(--line)]">
|
||||
<input type="checkbox" checked={reqTasks.every((t) => selectedIds.has(t.id))} onChange={() => { const ids = reqTasks.map((t) => t.id); const allSelected = ids.every((id) => selectedIds.has(id)); const next = new Set(selectedIds); if (allSelected) ids.forEach((id) => next.delete(id)); else ids.forEach((id) => next.add(id)); setSelectedIds(next); }} className="h-3.5 w-3.5 rounded border-[var(--line)]" />
|
||||
<span className="text-[11px] font-mono text-[var(--ink-muted)]">{req?.code}</span>
|
||||
<span className="text-[12px] font-medium text-[var(--ink)] flex-1 truncate">{req?.title}</span>
|
||||
<span className="text-[11px] text-[var(--ink-muted)]">{reqProgress}%</span>
|
||||
<div className="flex items-center bg-[var(--bg-subtle)] border-b border-[var(--line)]">
|
||||
<div className="pl-4 flex items-center">
|
||||
<input type="checkbox" checked={reqTasks.every((t) => selectedIds.has(t.id))} onChange={() => { const ids = reqTasks.map((t) => t.id); const allSelected = ids.every((id) => selectedIds.has(id)); const next = new Set(selectedIds); if (allSelected) ids.forEach((id) => next.delete(id)); else ids.forEach((id) => next.add(id)); setSelectedIds(next); }} className="h-3.5 w-3.5 rounded border-[var(--line)]" />
|
||||
</div>
|
||||
<div className="flex flex-1 min-w-0 items-center gap-2 px-4 py-2">
|
||||
<span className="h-2 w-2 shrink-0" />
|
||||
<span className="w-16 shrink-0 truncate text-[11px] font-mono text-[var(--ink-muted)]" title={req?.code}>{req?.code}</span>
|
||||
<span className="min-w-0 flex-1 truncate text-[12px] font-medium text-[var(--ink)]">{req?.title}</span>
|
||||
<span className="shrink-0 text-[11px] text-[var(--ink-muted)]">{reqProgress}%</span>
|
||||
</div>
|
||||
</div>
|
||||
{reqTasks.map((t) => (
|
||||
<div key={t.id} className="flex items-center">
|
||||
@@ -191,7 +200,7 @@ export function DevTaskTab({ versionId, requirementIds, versionDeadline }: Props
|
||||
<input type="checkbox" checked={selectedIds.has(t.id)} onChange={() => toggleSelect(t.id)} className="h-3.5 w-3.5 rounded border-[var(--line)]" onClick={(e) => e.stopPropagation()} />
|
||||
</div>
|
||||
<div className="flex-1 min-w-0">
|
||||
<DevTaskRow task={t} category={categoryMap.get(t.categoryId)} onClick={() => setSelectedTaskId(t.id)} />
|
||||
<DevTaskRow task={t} category={categoryMap.get(t.categoryId)} categoryLabelWidthEm={categoryLabelWidthEm} onClick={() => setSelectedTaskId(t.id)} />
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
|
||||
Reference in New Issue
Block a user