From 11c2a16986fd07ec67cc5243c16e0453f952df4f Mon Sep 17 00:00:00 2001 From: Menghuan1918 Date: Sun, 27 Sep 2026 21:32:32 +0800 Subject: [PATCH] =?UTF-8?q?feat(tasks):=20=E7=A9=BA=E9=97=B2=E4=B8=8E?= =?UTF-8?q?=E5=B7=B2=E5=AE=8C=E6=88=90=E5=88=86=E6=88=90=E4=B8=A4=E4=B8=AA?= =?UTF-8?q?=E8=81=9A=E5=90=88=E8=A1=8C=EF=BC=9B=E5=BE=85=E5=91=BD=E5=8D=A1?= =?UTF-8?q?=E7=89=87=E8=A1=A5=E4=B8=8A=E8=87=AA=E5=B7=B1=E7=9A=84=E6=8A=98?= =?UTF-8?q?=E5=8F=A0=E6=8C=89=E9=92=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 用户两条反馈: 1. 空闲和已完成分开折叠合集 2. 空闲的无法折叠 第 2 条是纯疏漏:chevron 的出现条件写死在 `settled = done | error` 上, 「待命」的卡因此从来不画折叠按钮(跟折叠规则无关,规则早就允许手动收)。 现在 chevron 按「不在执行」(done | error | idle)出现,而 `settled` 仍只 表示完成/出错 —— 它管的是卡片该不该变淡,待命不是完成的工作。 第 1 条把上一轮那个「混合聚合」拆开: - 一个父节点现在最多两行 —— `fold:`(已完成/出错)与 `fold::idle`(待命成员); - 各自的徽标说实话:完成行仍是「✓ N 已完成」,待命行是「N 个待命」; 完成行的条会额外报 `出错 N`(全是失败时只剩这一项),否则失败会藏在 ✓ 里; - 待命行的条只写 `N 待命`(同组同状态,不重复计数); - 阈值只作用于**自动**规则(≥3 待命成员才随页面级折叠一起收),手动 chevron 永远有效,两行互不牵连 —— 想扫掉待命的成员,不必连已完成的一起带走。 新增 tasksFoldIdleGroup ×20 词典;删掉上一轮的 hasIdle 与 foldBadgeCount (分组后它们没有意义)。 测试:新增/改写 7 例 —— 三个待命成员收进 idle 行、两个保持可见、运行中成员 达标也不收、混合场景两行各归各的、手动折叠单个待命成员落进 idle 行、 待命卡确实带 chevron 且点后只剩聚合、聚合徽标说「N 个待命」。 pnpm test 1286 passed / 9 skipped,typecheck / lint 通过。 (cherry picked from commit 0c9c8abca85e8aeb54bb2e9fcaaeed0486a56c28) --- src/client/TasksGraph.tsx | 25 ++++--- src/client/locales-ar.ts | 1 + src/client/locales-de.ts | 1 + src/client/locales-fr.ts | 1 + src/client/locales-hi.ts | 1 + src/client/locales-id.ts | 1 + src/client/locales-it.ts | 1 + src/client/locales-ja.ts | 1 + src/client/locales-ko.ts | 1 + src/client/locales-nl.ts | 1 + src/client/locales-pl.ts | 1 + src/client/locales-pt.ts | 1 + src/client/locales-ru.ts | 1 + src/client/locales-sv.ts | 1 + src/client/locales-th.ts | 1 + src/client/locales-tr.ts | 1 + src/client/locales-vi.ts | 1 + src/client/locales-zh-HK.ts | 1 + src/client/locales-zh-MO.ts | 1 + src/client/locales-zh-TW.ts | 1 + src/client/locales.ts | 2 + src/client/tasks-card.tsx | 26 +++---- src/client/tasks-model.ts | 138 +++++++++++++++++++++--------------- src/client/tasks-shared.tsx | 18 ++--- tests/tasks-model.spec.ts | 43 ++++++++--- tests/tasks-page.spec.tsx | 39 ++++++++-- 26 files changed, 210 insertions(+), 100 deletions(-) diff --git a/src/client/TasksGraph.tsx b/src/client/TasksGraph.tsx index 3f070b7..964d823 100644 --- a/src/client/TasksGraph.tsx +++ b/src/client/TasksGraph.tsx @@ -41,7 +41,7 @@ import { type GraphBox, } from './tasks-graph-layout.ts' import { - agentIdentity, agentMeta, foldBadgeCount, foldPreviews, foldTally, TaskLine, WorkflowGlyph, workflowMeta, + agentIdentity, agentMeta, foldPreviews, foldTally, TaskLine, WorkflowGlyph, workflowMeta, } from './tasks-shared.tsx' import { CardBar, CardTop, phaseClass, type CardKind } from './tasks-card.tsx' import { doneActivityTitle, liveActivityLabel } from './process-labels.ts' @@ -558,6 +558,14 @@ function renderAgentNode( onFold?: (node: TasksAgentNode) => void, ): ReactNode { const settled = node.state === 'done' || node.state === 'error' + /** + * Whether this card offers its own fold chevron. A WAITING member counts: + * it is not executing either, and the chevron is the reader's own trigger + * (independent of the page-level rule and of the idle head count). The + * `settled` flag stays a separate idea — that one controls how the card + * RECEDES, and an idle teammate is not finished work. + */ + const foldable = settled || node.state === 'idle' return (
{ onFold(node) } } : {})} /> @@ -667,16 +675,17 @@ function renderFoldNode( > - - {/* The tally SAYS what was folded (✓N 已完成 · N 待命 · 出错 N): the - badge alone would read as "all done" once idle members ride along, - and the bar is too narrow for a tally AND an action word. */} + + {/* The bar SAYS what the row holds — "✓ N 已完成 · 出错 N" for finished + work (a stray failure would otherwise hide inside the ✓) and + "N 待命" for the waiting members. No action word: the tally needs + the room and the chevron already points at 展开. */} {foldTally(node)}