From 29966872ce2173a9d60d26a165ae893d1fd40660 Mon Sep 17 00:00:00 2001 From: John Tennant Date: Wed, 9 Sep 2026 14:40:42 -0400 Subject: [PATCH] Allow task reassignment and color review results Signed-off-by: John Tennant --- .../channels/lib/taskAssignment.test.mjs | 8 +-- .../features/channels/lib/taskAssignment.ts | 2 - .../src/features/channels/ui/AssignTask.tsx | 30 ++++++++++-- .../features/channels/ui/TaskReviewModal.tsx | 49 +++++++++++++++---- desktop/tests/e2e/task-channel-views.spec.ts | 36 +++++++++++++- 5 files changed, 103 insertions(+), 22 deletions(-) diff --git a/desktop/src/features/channels/lib/taskAssignment.test.mjs b/desktop/src/features/channels/lib/taskAssignment.test.mjs index e7d03e8442..3c5ea188e3 100644 --- a/desktop/src/features/channels/lib/taskAssignment.test.mjs +++ b/desktop/src/features/channels/lib/taskAssignment.test.mjs @@ -21,16 +21,16 @@ test("assignment preserves unrelated frontmatter, comments and body", () => { }); }); -test("retry retains operation and refuses another assignee", () => { +test("retry retains operation and reassignment replaces notification state", () => { const pending = assignmentCanvas(canvas, pubkey, "operation", "pending"); assert.equal( taskAssignee(assignmentCanvas(pending, pubkey, "operation", "sent")) .notification.status, "sent", ); - assert.throws( - () => assignmentCanvas(pending, "b".repeat(64), "new", "pending"), - /already assigned/, + assert.deepEqual( + taskAssignee(assignmentCanvas(pending, "b".repeat(64), "new", "pending")), + { pubkey: "b".repeat(64), notification: { id: "new", status: "pending" } }, ); assert.throws( () => assignmentCanvas(canvas, "bad", "new", "pending"), diff --git a/desktop/src/features/channels/lib/taskAssignment.ts b/desktop/src/features/channels/lib/taskAssignment.ts index b390d2323e..fd33996840 100644 --- a/desktop/src/features/channels/lib/taskAssignment.ts +++ b/desktop/src/features/channels/lib/taskAssignment.ts @@ -32,8 +32,6 @@ export function assignmentCanvas( ): string { if (!/^[a-f0-9]{64}$/i.test(pubkey)) throw new Error("Invalid agent pubkey"); const existing = taskAssignee(content); - if (existing && existing.pubkey !== pubkey) - throw new Error("Task is already assigned"); const { doc, body } = document(content); if (!existing) doc.set("assignee", doc.createNode({})); doc.setIn(["assignee", "pubkey"], pubkey); diff --git a/desktop/src/features/channels/ui/AssignTask.tsx b/desktop/src/features/channels/ui/AssignTask.tsx index abb197c08e..5f00d60d8c 100644 --- a/desktop/src/features/channels/ui/AssignTask.tsx +++ b/desktop/src/features/channels/ui/AssignTask.tsx @@ -38,7 +38,11 @@ export function AssignTask({ setPending(true); setError(""); try { - const operationId = assignee?.notification?.id ?? crypto.randomUUID(); + const operationId = + assignee?.pubkey === pubkey && + assignee.notification?.status === "pending" + ? assignee.notification.id + : crypto.randomUUID(); const result = await invokeTauri<{ assigned: boolean; notified: boolean; @@ -72,13 +76,20 @@ export function AssignTask({ return (
- {assignee ? ( + {assignee && !choosing ? ( <> - + {assignee.notification?.status === "pending" && (