From 33bef7f5fc0ae7e9d0083623df0d3de2e64a422d Mon Sep 17 00:00:00 2001 From: wangjia <809946525@qq.com> Date: Tue, 30 Jun 2026 07:34:47 +0800 Subject: [PATCH] =?UTF-8?q?feat(console):=20=E4=BE=A7=E6=A0=8F=E9=A1=B9?= =?UTF-8?q?=E7=9B=AE=E6=8C=89=E4=BC=98=E5=85=88=E7=BA=A7=E6=98=BE=E7=A4=BA?= =?UTF-8?q?=E4=B8=89=E7=B1=BB=E8=AE=A1=E6=95=B0=E5=BE=BD=E6=A0=87?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 左侧项目状态新增数字提示,按优先级展示: 1. 需人工处理数(紫,attention) 2. agent 运行数(青,executing) 3. 被阻塞数(琥珀,blocked) 仅非零显示,固定「人工 > 运行 > 阻塞」排列;折叠态仍单状态点, 任一计数 > 0 时放大。后端 projectSummary 已就绪,仅透出 blocked 并渲染。i18n 五语言补齐 projAgentsTip / projBlockedTip。 tsk_0VF1URfdoe3d Co-Authored-By: Claude Opus 4.8 --- app/src/adapt.js | 2 +- design/ui_kits/console/Sidebar.jsx | 30 ++++++++++++++++++++---------- design/ui_kits/console/data.js | 6 +++--- design/ui_kits/console/i18n.js | 10 ++++++++++ 4 files changed, 34 insertions(+), 14 deletions(-) diff --git a/app/src/adapt.js b/app/src/adapt.js index bf4b21c..66d03e5 100644 --- a/app/src/adapt.js +++ b/app/src/adapt.js @@ -25,7 +25,7 @@ export function adaptProject(p) { return { id: p.id, name: p.name, path: shortPath(p.repoPath), branch: p.defaultBranch, autonomy: p.autonomy, concurrency: p.concurrency, hue: hueFor(p.name), - state, pending: s.attention || 0, agents: s.executing || 0, + state, pending: s.attention || 0, agents: s.executing || 0, blocked: s.blocked || 0, // 透传给 ConfigPanel 用的原始字段 model: p.model, verifyCmd: p.verifyCmd, maxRetries: p.maxRetries, repoPath: p.repoPath, logo: p.logo, budgetUsd: p.budgetUsd ?? null, budgetPeriod: p.budgetPeriod ?? 'month', diff --git a/design/ui_kits/console/Sidebar.jsx b/design/ui_kits/console/Sidebar.jsx index a6cbec3..a33e2a2 100644 --- a/design/ui_kits/console/Sidebar.jsx +++ b/design/ui_kits/console/Sidebar.jsx @@ -48,6 +48,17 @@ function projStateMeta(state, t) { })[state] || { color: 'var(--muted)', pulse: false, label: t.projIdle }; } +// 项目计数徽标:按优先级展示「需人工 / 运行中 / 被阻塞」,仅非零显示 +function CountBadge({ value, color, title }) { + return ( + {value} + ); +} + function ProjStatusDot({ meta, size = 7 }) { return ( onSelect(p.id)} title={p.name + ' · ' + meta.label + (p.pending ? ' · ' + t.projPendingTip.replace('{n}', p.pending) : '')} +
  • onSelect(p.id)} title={p.name + ' · ' + meta.label + + (p.pending ? ' · ' + t.projPendingTip.replace('{n}', p.pending) : '') + + (p.agents ? ' · ' + t.projAgentsTip.replace('{n}', p.agents) : '') + + (p.blocked ? ' · ' + t.projBlockedTip.replace('{n}', p.blocked) : '')} draggable={!collapsed} onDragStart={(e) => { setDragId(p.id); e.dataTransfer.effectAllowed = 'move'; }} onDragOver={(e) => { if (dragId) { e.preventDefault(); if (p.id !== dragId && overId !== p.id) setOverId(p.id); } }} @@ -536,20 +550,16 @@ function Sidebar({ projects, currentId, onSelect, onNewProject, collapsed, onTog {p.name} {p.path} - - {p.pending > 0 ? ( - {p.pending} - ) : null} + + {p.pending > 0 ? : null} + {p.agents > 0 ? : null} + {p.blocked > 0 ? : null} ) : ( - 0 ? 8 : 6} /> + 0 ? 8 : 6} /> )}
  • diff --git a/design/ui_kits/console/data.js b/design/ui_kits/console/data.js index cac40b1..04b1ed1 100644 --- a/design/ui_kits/console/data.js +++ b/design/ui_kits/console/data.js @@ -1,9 +1,9 @@ // MAESTRO 调度台 · UI kit 假数据(与 src/model 状态机对齐) window.MAESTRO_MOCK = { projects: [ - { id: 'p1', name: 'maestro', path: '~/dev/maestro', branch: 'main', autonomy: 'auto-easy', concurrency: 2, hue: 140, state: 'running', pending: 1, agents: 1 }, - { id: 'p2', name: 'blog-engine', path: '~/dev/blog-engine', branch: 'main', autonomy: 'manual', concurrency: 1, hue: 38, state: 'paused', pending: 0, agents: 0 }, - { id: 'p3', name: 'dotfiles', path: '~/.dotfiles', branch: 'master', autonomy: 'auto-approved', concurrency: 1, hue: 265, state: 'blocked', pending: 0, agents: 0 }, + { id: 'p1', name: 'maestro', path: '~/dev/maestro', branch: 'main', autonomy: 'auto-easy', concurrency: 2, hue: 140, state: 'running', pending: 1, agents: 1, blocked: 0 }, + { id: 'p2', name: 'blog-engine', path: '~/dev/blog-engine', branch: 'main', autonomy: 'manual', concurrency: 1, hue: 38, state: 'paused', pending: 0, agents: 0, blocked: 0 }, + { id: 'p3', name: 'dotfiles', path: '~/.dotfiles', branch: 'master', autonomy: 'auto-approved', concurrency: 1, hue: 265, state: 'blocked', pending: 2, agents: 0, blocked: 2 }, ], agents: [ { id: 'r1', project: 'maestro', title: '把轮询改为 WS 推送', kind: 'EXECUTOR', time: '06:12', meta: 'wt-127 · claude-sonnet' }, diff --git a/design/ui_kits/console/i18n.js b/design/ui_kits/console/i18n.js index d62eb8a..82259d1 100644 --- a/design/ui_kits/console/i18n.js +++ b/design/ui_kits/console/i18n.js @@ -22,6 +22,8 @@ window.MAESTRO_I18N = { agentSection: 'Agent 执行', agentEmpty: '无运行中的 agent', running: 'RUNNING', since: '起', projRunning: '运行中', projPaused: '暂停', projBlocked: '阻塞', projIdle: '空闲', projPendingTip: '{n} 项待你审批', + projAgentsTip: '{n} 个 agent 运行中', + projBlockedTip: '{n} 项被阻塞', gAgents: '全局 Agent', gAgentsDetail: '{p}/{P} 个项目运行 · {a} 个 agent', apActive: '运行', apRuns: '次运行', apTokens: 'token', apWeek: '本周', apCost: '花费', apTotal: '所有项目', apPerProj: '按项目', apIdle: '空闲', apMore: '展开其余 {n} 个', apCollapse: '收起', apDetail: '详情', apDetailTitle: '用量详情', apByDay: '按天', apByWeek: '按周', apByMonth: '按月', apColProject: '项目', apColTasks: '任务数', apColModels: '模型', apEmpty: '暂无用量数据', @@ -74,6 +76,8 @@ window.MAESTRO_I18N = { agentSection: 'Agent runs', agentEmpty: 'No running agents', running: 'RUNNING', since: '', projRunning: 'Running', projPaused: 'Paused', projBlocked: 'Blocked', projIdle: 'Idle', projPendingTip: '{n} awaiting your review', + projAgentsTip: '{n} agents running', + projBlockedTip: '{n} blocked', gAgents: 'Agents', gAgentsDetail: '{p}/{P} projects · {a} agents', apActive: 'active', apRuns: 'runs', apTokens: 'tokens', apWeek: 'this week', apCost: 'cost', apTotal: 'All projects', apPerProj: 'BY PROJECT', apIdle: 'idle', apMore: '+{n} more', apCollapse: 'Collapse', apDetail: 'Details', apDetailTitle: 'Usage detail', apByDay: 'By day', apByWeek: 'By week', apByMonth: 'By month', apColProject: 'Project', apColTasks: 'Tasks', apColModels: 'Models', apEmpty: 'No usage data yet', @@ -126,6 +130,8 @@ window.MAESTRO_I18N = { agentSection: 'Ejecución de agents', agentEmpty: 'Sin agents en ejecución', running: 'RUNNING', since: '', projRunning: 'En curso', projPaused: 'Pausado', projBlocked: 'Bloqueado', projIdle: 'Inactivo', projPendingTip: '{n} esperan tu revisión', + projAgentsTip: '{n} agentes en curso', + projBlockedTip: '{n} bloqueadas', gAgents: 'Agents globales', gAgentsDetail: '{p}/{P} proyectos · {a} agents', apActive: 'activos', apRuns: 'ejecuciones', apTokens: 'tokens', apWeek: 'esta semana', apCost: 'coste', apTotal: 'Todos los proyectos', apPerProj: 'POR PROYECTO', apIdle: 'inactivo', apMore: '+{n} más', apCollapse: 'Contraer', apDetail: 'Detalles', apDetailTitle: 'Detalle de uso', apByDay: 'Por día', apByWeek: 'Por semana', apByMonth: 'Por mes', apColProject: 'Proyecto', apColTasks: 'Tareas', apColModels: 'Modelos', apEmpty: 'Sin datos de uso', @@ -178,6 +184,8 @@ window.MAESTRO_I18N = { agentSection: 'Agent 実行', agentEmpty: '実行中の agent はありません', running: 'RUNNING', since: '開始', projRunning: '実行中', projPaused: '一時停止', projBlocked: 'ブロック', projIdle: 'アイドル', projPendingTip: '{n} 件があなたの承認待ち', + projAgentsTip: '{n} 件のエージェント実行中', + projBlockedTip: '{n} 件ブロック中', gAgents: 'グローバル Agent', gAgentsDetail: '{p}/{P} プロジェクト · {a} 個の agent', apActive: '実行中', apRuns: '回実行', apTokens: 'token', apWeek: '今週', apCost: 'コスト', apTotal: '全プロジェクト', apPerProj: 'プロジェクト別', apIdle: 'アイドル', apMore: '他 {n} 件', apCollapse: '折りたたむ', apDetail: '詳細', apDetailTitle: '使用量の詳細', apByDay: '日別', apByWeek: '週別', apByMonth: '月別', apColProject: 'プロジェクト', apColTasks: 'タスク数', apColModels: 'モデル', apEmpty: '使用量データなし', @@ -230,6 +238,8 @@ window.MAESTRO_I18N = { agentSection: 'Exécutions agent', agentEmpty: 'Aucun agent en cours', running: 'RUNNING', since: '', projRunning: 'En cours', projPaused: 'En pause', projBlocked: 'Bloqué', projIdle: 'Inactif', projPendingTip: '{n} en attente de votre revue', + projAgentsTip: '{n} agents en cours', + projBlockedTip: '{n} bloquées', gAgents: 'Agents globaux', gAgentsDetail: '{p}/{P} projets · {a} agents', apActive: 'actifs', apRuns: 'exécutions', apTokens: 'tokens', apWeek: 'cette semaine', apCost: 'coût', apTotal: 'Tous les projets', apPerProj: 'PAR PROJET', apIdle: 'inactif', apMore: '+{n} de plus', apCollapse: 'Réduire', apDetail: 'Détails', apDetailTitle: "Détail d'usage", apByDay: 'Par jour', apByWeek: 'Par semaine', apByMonth: 'Par mois', apColProject: 'Projet', apColTasks: 'Tâches', apColModels: 'Modèles', apEmpty: "Aucune donnée d'usage",