feat(FN-5055): merge fusion/fn-5055
This commit is contained in:
@@ -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,
|
||||||
|
|||||||
@@ -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}
|
||||||
|
|||||||
@@ -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 () => {
|
||||||
|
|||||||
Reference in New Issue
Block a user