From f2ef7ab0d1842967a79c924f04d9393e2ecf86c9 Mon Sep 17 00:00:00 2001
From: Jiayuan Zhang
Date: Thu, 23 Jul 2026 01:32:43 +0800
Subject: [PATCH] MUL-5127: show issue agent activity in Inbox (#5737)
* feat(inbox): show agent status in list (MUL-5127)
Co-authored-by: multica-agent
* fix(inbox): show issue agent activity (MUL-5127)
Co-authored-by: multica-agent
---------
Co-authored-by: Lambda
Co-authored-by: multica-agent
---
.../inbox/components/inbox-list-item.test.tsx | 46 ++++++++++++++++++-
.../inbox/components/inbox-list-item.tsx | 17 +++++--
2 files changed, 58 insertions(+), 5 deletions(-)
diff --git a/packages/views/inbox/components/inbox-list-item.test.tsx b/packages/views/inbox/components/inbox-list-item.test.tsx
index f0b293866..466a3f0c5 100644
--- a/packages/views/inbox/components/inbox-list-item.test.tsx
+++ b/packages/views/inbox/components/inbox-list-item.test.tsx
@@ -4,7 +4,29 @@ import type { InboxItem } from "@multica/core/types";
import { InboxListItem } from "./inbox-list-item";
vi.mock("../../issues/components", () => ({ StatusIcon: () => null }));
-vi.mock("../../common/actor-avatar", () => ({ ActorAvatar: () => null }));
+vi.mock("../../issues/components/issue-agent-activity-indicator", () => ({
+ IssueAgentActivityIndicator: ({ issueId }: { issueId: string }) => (
+
+ ),
+}));
+vi.mock("../../common/actor-avatar", () => ({
+ ActorAvatar: ({
+ actorType,
+ actorId,
+ showStatusDot,
+ }: {
+ actorType: string;
+ actorId: string;
+ showStatusDot?: boolean;
+ }) => (
+
+ ),
+}));
vi.mock("./inbox-detail-label", () => ({ InboxDetailLabel: () => null }));
vi.mock("../../i18n", () => ({ useT: () => ({ t: () => "label" }) }));
@@ -72,3 +94,25 @@ describe("InboxListItem unread affordance", () => {
expect(title(container)?.className).not.toContain("font-medium");
});
});
+
+describe("InboxListItem issue activity", () => {
+ it("shows issue-specific agent activity without an availability dot", () => {
+ const { getByTestId } = renderRow({ item: item(), view: "inbox" });
+
+ expect(getByTestId("actor-avatar").getAttribute("data-show-status-dot")).toBe(
+ "false",
+ );
+ expect(
+ getByTestId("issue-agent-activity").getAttribute("data-issue-id"),
+ ).toBe("issue-1");
+ });
+
+ it("omits issue activity for a notification without an issue", () => {
+ const { queryByTestId } = renderRow({
+ item: item({ issue_id: null }),
+ view: "inbox",
+ });
+
+ expect(queryByTestId("issue-agent-activity")).toBeNull();
+ });
+});
diff --git a/packages/views/inbox/components/inbox-list-item.tsx b/packages/views/inbox/components/inbox-list-item.tsx
index 7a7b7e76c..b21393896 100644
--- a/packages/views/inbox/components/inbox-list-item.tsx
+++ b/packages/views/inbox/components/inbox-list-item.tsx
@@ -1,6 +1,9 @@
"use client";
import { StatusIcon } from "../../issues/components";
+import {
+ IssueAgentActivityIndicator,
+} from "../../issues/components/issue-agent-activity-indicator";
import { ActorAvatar } from "../../common/actor-avatar";
import { Archive, ArchiveRestore } from "lucide-react";
import type { InboxItem } from "@multica/core/types";
@@ -53,6 +56,7 @@ export function InboxListItem({
const actionLabel = isArchivedView
? t(($) => $.list.unarchive_tooltip)
: t(($) => $.list.archive_tooltip);
+ const actorType = item.actor_type ?? item.recipient_type;
return (
-
- {timeAgo(item.created_at)}
-
+
+ {item.issue_id && (
+
+ )}
+
+ {timeAgo(item.created_at)}
+
+