feat(FN-5055): merge fusion/fn-5055

This commit is contained in:
gsxdsm
2026-05-18 09:02:00 -07:00
parent d9214b69c9
commit ead2ed89aa
3 changed files with 13 additions and 49 deletions

View File

@@ -137,10 +137,6 @@ export {
type DuplicateMatchInput, type DuplicateMatchInput,
} from "./duplicate-detection.js"; } from "./duplicate-detection.js";
export { getTaskDuplicateLineage } from "./duplicate-lineage.js"; export { getTaskDuplicateLineage } from "./duplicate-lineage.js";
export { DUPLICATE_OF_METADATA_KEY } from "./types.js";
export {
getTaskDuplicateLineage,
} from "./duplicate-lineage.js";
export { export {
findSameAgentDuplicates, findSameAgentDuplicates,
archiveAsSameAgentDuplicate, archiveAsSameAgentDuplicate,

View File

@@ -549,7 +549,7 @@ function TaskCardComponent({
const sendBackRef = useRef<HTMLDivElement>(null); const sendBackRef = useRef<HTMLDivElement>(null);
const [isInViewport, setIsInViewport] = useState(false); const [isInViewport, setIsInViewport] = useState(false);
const { badgeUpdates, subscribeToBadge, unsubscribeFromBadge } = useBadgeWebSocket(projectId); const { badgeUpdates, subscribeToBadge, unsubscribeFromBadge } = useBadgeWebSocket(projectId);
const { confirm, confirmWithChoice } = useConfirm(); const { confirm } = useConfirm();
const retryWarningThreshold = useRetryWarning(); const retryWarningThreshold = useRetryWarning();
// Touch gesture detection refs // Touch gesture detection refs
@@ -1189,38 +1189,13 @@ function TaskCardComponent({
e.stopPropagation(); e.stopPropagation();
if (!onDeleteTask) return; if (!onDeleteTask) return;
if (task.column === "done" && onArchiveTask) { const shouldDelete = await confirm({
const deleteChoice = await confirmWithChoice({ title: "Delete Task",
title: "Delete Task", message: `Delete ${task.id}?`,
message: `Delete ${task.id}?`, danger: true,
confirmLabel: "Delete", });
cancelLabel: "Cancel", if (!shouldDelete) {
tertiaryLabel: "Archive Instead", return;
danger: true,
});
if (deleteChoice === "tertiary") {
try {
await onArchiveTask(task.id);
addToast(`Archived ${task.id}`, "success");
} catch (err) {
addToast(`Failed to archive ${task.id}: ${getErrorMessage(err)}`, "error");
}
return;
}
if (deleteChoice !== "primary") {
return;
}
} else {
const shouldDelete = await confirm({
title: "Delete Task",
message: `Delete ${task.id}?`,
danger: true,
});
if (!shouldDelete) {
return;
}
} }
const trackedIssue = task.githubTracking?.enabled === true ? task.githubTracking.issue : undefined; const trackedIssue = task.githubTracking?.enabled === true ? task.githubTracking.issue : undefined;
@@ -1284,7 +1259,7 @@ function TaskCardComponent({
addToast(`Failed to delete ${task.id}: ${getErrorMessage(retryErr)}`, "error"); addToast(`Failed to delete ${task.id}: ${getErrorMessage(retryErr)}`, "error");
} }
} }
}, [addToast, confirm, confirmWithChoice, onArchiveTask, onDeleteTask, task.column, task.githubTracking?.enabled, task.githubTracking?.issue, task.id]); }, [addToast, confirm, onDeleteTask, task.githubTracking?.enabled, task.githubTracking?.issue, task.id]);
const handleOpenFiles = useCallback((e: React.MouseEvent) => { const handleOpenFiles = useCallback((e: React.MouseEvent) => {
e.stopPropagation(); e.stopPropagation();
@@ -1639,7 +1614,7 @@ function TaskCardComponent({
<Pencil size={12} /> <Pencil size={12} />
</button> </button>
)} )}
{(task.column === "triage" || task.column === "done") && onDeleteTask && ( {task.column === "triage" && onDeleteTask && (
<button <button
className="card-delete-btn" className="card-delete-btn"
onClick={handleDeleteClick} onClick={handleDeleteClick}

View File

@@ -271,10 +271,9 @@ describe("TaskCard", () => {
}); });
}); });
it("archives done task when archive-instead is chosen", async () => { it("hides delete button for done tasks while keeping archive action", () => {
const onDeleteTask = vi.fn(async () => makeTask()); const onDeleteTask = vi.fn(async () => makeTask());
const onArchiveTask = vi.fn(async () => makeTask({ column: "archived" })); const onArchiveTask = vi.fn(async () => makeTask({ column: "archived" }));
mockConfirmWithChoice.mockResolvedValueOnce("tertiary");
render( render(
<TaskCard <TaskCard
@@ -286,14 +285,8 @@ describe("TaskCard", () => {
/>, />,
); );
await act(async () => { expect(screen.queryByLabelText("Delete task")).toBeNull();
fireEvent.click(screen.getByLabelText("Delete task")); expect(screen.getByLabelText("Archive task")).toBeDefined();
});
await waitFor(() => {
expect(onArchiveTask).toHaveBeenCalledWith("FN-001");
expect(onDeleteTask).not.toHaveBeenCalled();
});
}); });
it("keeps two-button delete flow for non-done task", async () => { it("keeps two-button delete flow for non-done task", async () => {