fix(ui): group plan tasks by User Story or Phase to support Spec Kit format

This commit is contained in:
2026-05-19 15:56:13 -07:00
parent e12882d13b
commit 18355e1421

View File

@@ -1262,39 +1262,75 @@ function TasksPanel({
)}
</div>
) : (
<ul style={taskList}>
{visible.map((t) => (
<li key={t.id}>
<button
type="button"
onClick={() => {
setSelectedId(t.id);
setCreating(false);
}}
style={selectedId === t.id ? taskItemActive : taskItem}
>
<div
style={{ display: "flex", alignItems: "center", gap: 8 }}
>
<span
style={{
...taskStatusDot,
background: TASK_STATUS_COLOR[t.status],
}}
/>
<span style={taskItemTitle}>{taskTitle(t)}</span>
<div>
{(() => {
const groups: Record<string, typeof visible> = {};
for (const t of visible) {
const title = taskTitle(t);
const match = title.match(/^\[(.*?)\]\s*(.*)$/);
const groupName = match ? match[1] : "Uncategorized";
const cleanTitle = match ? match[2] : title;
if (!groups[groupName]) groups[groupName] = [];
groups[groupName].push({ ...t, title: cleanTitle });
}
const groupKeys = Object.keys(groups).sort((a, b) => {
if (a === "Uncategorized") return 1;
if (b === "Uncategorized") return -1;
return a.localeCompare(b);
});
return groupKeys.map(groupKey => (
<div key={groupKey} style={{ marginBottom: 16 }}>
<div style={{
fontSize: "0.75rem",
fontWeight: 600,
color: "var(--fg-mute)",
textTransform: "uppercase",
letterSpacing: "0.04em",
marginBottom: 8,
marginLeft: 2,
}}>
{groupKey}
</div>
<div style={taskItemMeta}>
<span>{TASK_STATUS_LABEL[t.status]}</span>
<span style={{ color: INK.muted }}>·</span>
<span>
{relativeTime(t.doneAt ?? t.startedAt ?? t.createdAt)}
</span>
</div>
</button>
</li>
))}
</ul>
<ul style={taskList}>
{groups[groupKey].map((t) => (
<li key={t.id}>
<button
type="button"
onClick={() => {
setSelectedId(t.id);
setCreating(false);
}}
style={selectedId === t.id ? taskItemActive : taskItem}
>
<div
style={{ display: "flex", alignItems: "center", gap: 8 }}
>
<span
style={{
...taskStatusDot,
background: TASK_STATUS_COLOR[t.status],
}}
/>
<span style={taskItemTitle}>{t.title}</span>
</div>
<div style={taskItemMeta}>
<span>{TASK_STATUS_LABEL[t.status]}</span>
<span style={{ color: INK.muted }}>·</span>
<span>
{relativeTime(t.doneAt ?? t.startedAt ?? t.createdAt)}
</span>
</div>
</button>
</li>
))}
</ul>
</div>
));
})()}
</div>
)}
</div>