diff --git a/packages/views/inbox/components/inbox-list-item.tsx b/packages/views/inbox/components/inbox-list-item.tsx
index 06e9b41543..0bc7e4c800 100644
--- a/packages/views/inbox/components/inbox-list-item.tsx
+++ b/packages/views/inbox/components/inbox-list-item.tsx
@@ -2,7 +2,7 @@
import { StatusIcon } from "../../issues/components";
import { ActorAvatar } from "../../common/actor-avatar";
-import { Archive } from "lucide-react";
+import { Archive, CircleCheck } from "lucide-react";
import type { InboxItem } from "@multica/core/types";
import { InboxDetailLabel } from "./inbox-detail-label";
import { getInboxDisplayTitle } from "./inbox-display";
@@ -25,11 +25,13 @@ export function InboxListItem({
isSelected,
onClick,
onArchive,
+ onDone,
}: {
item: InboxItem;
isSelected: boolean;
onClick: () => void;
onArchive: () => void;
+ onDone?: () => void;
}) {
const displayTitle = getInboxDisplayTitle(item);
@@ -59,6 +61,26 @@ export function InboxListItem({
+ {onDone && (
+ {
+ e.stopPropagation();
+ onDone();
+ }}
+ onKeyDown={(e) => {
+ if (e.key === "Enter" || e.key === " ") {
+ e.stopPropagation();
+ onDone();
+ }
+ }}
+ className="hidden rounded p-0.5 text-muted-foreground hover:bg-accent hover:text-info group-hover:inline-flex"
+ >
+
+
+ )}
{
+ if (!item.issue_id) return;
+ setSelectedKey("");
+ updateIssueMutation.mutate(
+ { id: item.issue_id, status: "done" },
+ { onError: () => toast.error("Failed to mark as done") },
+ );
+ archiveMutation.mutate(item.id, {
+ onError: () => toast.error("Failed to archive"),
+ });
+ };
+
// Batch operations
const handleMarkAllRead = () => {
markAllReadMutation.mutate(undefined, {
@@ -235,6 +249,11 @@ export function InboxPage() {
isSelected={(item.issue_id ?? item.id) === selectedKey}
onClick={() => handleSelect(item)}
onArchive={() => handleArchive(item.id)}
+ onDone={
+ item.issue_id && item.issue_status !== "done" && item.issue_status !== "cancelled"
+ ? () => handleDone(item)
+ : undefined
+ }
/>
))}