diff --git a/web/src/components/graph-console/GoalTaskPane.vue b/web/src/components/graph-console/GoalTaskPane.vue index b0d6b77..4912918 100644 --- a/web/src/components/graph-console/GoalTaskPane.vue +++ b/web/src/components/graph-console/GoalTaskPane.vue @@ -76,58 +76,70 @@
这个目标下还没有任务。
@@ -173,6 +185,14 @@ let clock = null; onMounted(() => { clock = setInterval(() => { now.value = Date.now(); }, 30000); }); onBeforeUnmount(() => clearInterval(clock)); +/** 43 号文档:g.tasks 是摊平的(父任务 + 子任务同一个数组),这里按 parentTaskId 分两层 */ +function topLevel(tasks) { + return (tasks || []).filter((t) => !t.parentTaskId); +} +function childrenOf(tasks, parentTaskId) { + return (tasks || []).filter((t) => t.parentTaskId === parentTaskId); +} + function toggle(goalId) { const next = new Set(collapsed.value); if (next.has(goalId)) next.delete(goalId); else next.add(goalId); @@ -378,6 +398,12 @@ function onDispatched(d) { .dot.pulse { animation: pulse 1.6s ease-in-out infinite; } @keyframes pulse { 0%, 100% { opacity: 1; } 50% { opacity: .35; } } +.subtasks { list-style: none; margin: 0 0 2px; padding: 0 0 0 27px; } +.subtask { display: flex; align-items: center; gap: 5px; padding: 2px 6px; font-size: 11px; } +.subtask .dot.sm { margin-top: 0; width: 6px; height: 6px; } +.st-title { min-width: 0; flex: 1; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; color: #555; } +.st-status { font-size: 10px; font-weight: 600; white-space: nowrap; } + .t-body { min-width: 0; flex: 1; } .t-title { font-size: 12px; line-height: 1.4; color: #1a1a1a; diff --git a/web/src/components/task-board/TaskTable.vue b/web/src/components/task-board/TaskTable.vue index df96297..ed34338 100644 --- a/web/src/components/task-board/TaskTable.vue +++ b/web/src/components/task-board/TaskTable.vue @@ -50,6 +50,9 @@ {{ queueBadge(t).text }}