feat(frontend): surface UI des tâches de fond (F1-F4)
Expose les tâches de fond côté front : modèle domaine et normalisation du work state, panneau ProjectWorkStatePanel, intégration dans LayoutGrid et ProjectsView, et abonnement aux événements backgroundTaskChanged / agentInboxChanged / agentWakeChanged pour rafraîchir l'état. npm run build + npm test (449) verts. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@ -317,6 +317,16 @@ function LeafView({
|
||||
? workState?.agents.find((row) => row.agentId === agentId)
|
||||
: undefined;
|
||||
const activeTicket = agentWork?.tickets.find((ticket) => ticket.status === "inProgress");
|
||||
const queuedTickets = agentWork?.tickets.filter((ticket) => ticket.status === "queued") ?? [];
|
||||
const inboxDepth = Math.max(
|
||||
agentWork?.inboxDepth ?? 0,
|
||||
agentWork?.inbox?.length ?? 0,
|
||||
queuedTickets.length,
|
||||
);
|
||||
const completedBackgroundTasks =
|
||||
agentWork?.backgroundTasks?.filter((task) =>
|
||||
task.status === "completed" || task.status === "failed" || task.status === "cancelled",
|
||||
) ?? [];
|
||||
const busyByWorkState = agentWork?.busy.state === "busy" || Boolean(activeTicket);
|
||||
const delegatedTicket = activeTicket?.source.kind === "agent" ? activeTicket : undefined;
|
||||
const historyConversationId =
|
||||
@ -661,7 +671,7 @@ function LeafView({
|
||||
</button>
|
||||
)}
|
||||
</div>
|
||||
{agentId && (busyByWorkState || historyConversationId) && (
|
||||
{agentId && (busyByWorkState || inboxDepth > 0 || completedBackgroundTasks.length > 0 || historyConversationId) && (
|
||||
<div
|
||||
role="status"
|
||||
aria-live="polite"
|
||||
@ -699,6 +709,60 @@ function LeafView({
|
||||
: "Busy"}
|
||||
</span>
|
||||
)}
|
||||
{!busyByWorkState && inboxDepth > 0 && (
|
||||
<span
|
||||
title={`${inboxDepth} pending message${inboxDepth === 1 ? "" : "s"}`}
|
||||
style={{
|
||||
maxWidth: 180,
|
||||
overflow: "hidden",
|
||||
textOverflow: "ellipsis",
|
||||
whiteSpace: "nowrap",
|
||||
border: "1px solid var(--color-primary, #5b9bd5)",
|
||||
borderRadius: 3,
|
||||
background: "rgba(91, 155, 213, 0.14)",
|
||||
color: "var(--color-primary, #5b9bd5)",
|
||||
padding: "1px 6px",
|
||||
fontSize: 11,
|
||||
fontWeight: 600,
|
||||
}}
|
||||
>
|
||||
Queued · {inboxDepth}
|
||||
</span>
|
||||
)}
|
||||
{busyByWorkState && inboxDepth > 0 && (
|
||||
<span
|
||||
title={`${inboxDepth} queued message${inboxDepth === 1 ? "" : "s"}`}
|
||||
style={{
|
||||
flexShrink: 0,
|
||||
border: "1px solid var(--color-primary, #5b9bd5)",
|
||||
borderRadius: 3,
|
||||
background: "rgba(91, 155, 213, 0.14)",
|
||||
color: "var(--color-primary, #5b9bd5)",
|
||||
padding: "1px 6px",
|
||||
fontSize: 11,
|
||||
fontWeight: 600,
|
||||
}}
|
||||
>
|
||||
Queued {inboxDepth}
|
||||
</span>
|
||||
)}
|
||||
{completedBackgroundTasks.length > 0 && (
|
||||
<span
|
||||
title={`${completedBackgroundTasks.length} background task result${completedBackgroundTasks.length === 1 ? "" : "s"}`}
|
||||
style={{
|
||||
flexShrink: 0,
|
||||
border: "1px solid var(--color-success, #57b36a)",
|
||||
borderRadius: 3,
|
||||
background: "rgba(87, 179, 106, 0.14)",
|
||||
color: "var(--color-success, #57b36a)",
|
||||
padding: "1px 6px",
|
||||
fontSize: 11,
|
||||
fontWeight: 600,
|
||||
}}
|
||||
>
|
||||
Task done {completedBackgroundTasks.length}
|
||||
</span>
|
||||
)}
|
||||
{busyByWorkState && (
|
||||
<button
|
||||
type="button"
|
||||
|
||||
Reference in New Issue
Block a user