feat(FN-1777): merge fusion/fn-1777
This commit is contained in:
@@ -887,6 +887,35 @@ function TaskCardComponent({
|
||||
)}
|
||||
</div>
|
||||
)}
|
||||
{task.column === "in-review" && onMoveTask && (
|
||||
<div className="card-send-back" ref={sendBackRef}>
|
||||
<button
|
||||
className="card-send-back-btn"
|
||||
onClick={handleSendBackClick}
|
||||
title="Move task"
|
||||
aria-label="Move task"
|
||||
aria-haspopup="menu"
|
||||
aria-expanded={showSendBackMenu}
|
||||
>
|
||||
Move
|
||||
<ChevronDown size={10} />
|
||||
</button>
|
||||
{showSendBackMenu && (
|
||||
<div className="card-send-back-menu" role="menu">
|
||||
{VALID_TRANSITIONS["in-review"].map((col) => (
|
||||
<button
|
||||
key={col}
|
||||
className="card-send-back-menu-item"
|
||||
role="menuitem"
|
||||
onClick={(e) => handleSendBackOptionClick(e, col)}
|
||||
>
|
||||
{col === "done" ? "Done (no merge)" : COLUMN_LABELS[col]}
|
||||
</button>
|
||||
))}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
)}
|
||||
{task.size && (
|
||||
<span className={`card-size-badge size-${task.size.toLowerCase()}`}>
|
||||
{task.size}
|
||||
|
||||
@@ -3625,14 +3625,98 @@ describe("TaskCard send-back functionality", () => {
|
||||
expect(screen.queryByRole("button", { name: /send back/i })).not.toBeInTheDocument();
|
||||
});
|
||||
|
||||
it("does not render send-back button when task is in in-review", () => {
|
||||
it("renders Move button when task is in in-review and onMoveTask is provided", () => {
|
||||
const onMoveTask = vi.fn().mockResolvedValue({});
|
||||
const task = createTask({ column: "in-review" });
|
||||
render(<TaskCard task={task} onOpenDetail={vi.fn()} addToast={vi.fn()} onMoveTask={onMoveTask} />);
|
||||
|
||||
expect(screen.getByRole("button", { name: /move task/i })).toBeInTheDocument();
|
||||
expect(screen.queryByRole("button", { name: /send back/i })).not.toBeInTheDocument();
|
||||
});
|
||||
|
||||
it("does not render Move button for in-review when onMoveTask is not provided", () => {
|
||||
const task = createTask({ column: "in-review" });
|
||||
render(<TaskCard task={task} onOpenDetail={vi.fn()} addToast={vi.fn()} />);
|
||||
|
||||
expect(screen.queryByRole("button", { name: /move task/i })).not.toBeInTheDocument();
|
||||
});
|
||||
|
||||
it("toggles Move dropdown when in-review Move button is clicked", () => {
|
||||
const onMoveTask = vi.fn().mockResolvedValue({});
|
||||
const task = createTask({ column: "in-review" });
|
||||
render(<TaskCard task={task} onOpenDetail={vi.fn()} addToast={vi.fn()} onMoveTask={onMoveTask} />);
|
||||
|
||||
// Initially, dropdown is not visible
|
||||
expect(screen.queryByRole("menu")).not.toBeInTheDocument();
|
||||
|
||||
// Click the Move button
|
||||
const btn = screen.getByRole("button", { name: /move task/i });
|
||||
fireEvent.click(btn);
|
||||
|
||||
// Dropdown should now be visible
|
||||
expect(screen.getByRole("menu")).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it("in-review Move dropdown shows Done (no merge), In Progress, and Todo options", () => {
|
||||
const onMoveTask = vi.fn().mockResolvedValue({});
|
||||
const task = createTask({ column: "in-review" });
|
||||
render(<TaskCard task={task} onOpenDetail={vi.fn()} addToast={vi.fn()} onMoveTask={onMoveTask} />);
|
||||
|
||||
// Open the dropdown
|
||||
fireEvent.click(screen.getByRole("button", { name: /move task/i }));
|
||||
|
||||
// Check menu is visible
|
||||
const menu = screen.getByRole("menu");
|
||||
expect(menu).toBeInTheDocument();
|
||||
|
||||
// Should show all three options
|
||||
expect(screen.getByRole("menuitem", { name: /done \(no merge\)/i })).toBeInTheDocument();
|
||||
expect(screen.getByRole("menuitem", { name: /in progress/i })).toBeInTheDocument();
|
||||
expect(screen.getByRole("menuitem", { name: /todo/i })).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it("clicking Done (no merge) in in-review dropdown calls onMoveTask with done and closes menu", async () => {
|
||||
const onMoveTask = vi.fn().mockResolvedValue({});
|
||||
const addToast = vi.fn();
|
||||
const task = createTask({ column: "in-review" });
|
||||
render(<TaskCard task={task} onOpenDetail={vi.fn()} addToast={addToast} onMoveTask={onMoveTask} />);
|
||||
|
||||
// Open the dropdown
|
||||
fireEvent.click(screen.getByRole("button", { name: /move task/i }));
|
||||
|
||||
// Click "Done (no merge)" option
|
||||
fireEvent.click(screen.getByRole("menuitem", { name: /done \(no merge\)/i }));
|
||||
|
||||
// Should have called onMoveTask
|
||||
await waitFor(() => {
|
||||
expect(onMoveTask).toHaveBeenCalledWith("FN-001", "done");
|
||||
});
|
||||
|
||||
// Dropdown should be closed
|
||||
expect(screen.queryByRole("menu")).not.toBeInTheDocument();
|
||||
|
||||
// Toast should have been shown
|
||||
await waitFor(() => {
|
||||
expect(addToast).toHaveBeenCalledWith("Moved FN-001 to Done", "success");
|
||||
});
|
||||
});
|
||||
|
||||
it("clicking outside closes in-review Move dropdown", () => {
|
||||
const onMoveTask = vi.fn().mockResolvedValue({});
|
||||
const task = createTask({ column: "in-review" });
|
||||
render(<TaskCard task={task} onOpenDetail={vi.fn()} addToast={vi.fn()} onMoveTask={onMoveTask} />);
|
||||
|
||||
// Open the dropdown
|
||||
fireEvent.click(screen.getByRole("button", { name: /move task/i }));
|
||||
expect(screen.getByRole("menu")).toBeInTheDocument();
|
||||
|
||||
// Click outside (on the card itself, not inside the Move dropdown)
|
||||
fireEvent.click(document.querySelector(".card")!);
|
||||
|
||||
// Dropdown should be closed
|
||||
expect(screen.queryByRole("menu")).not.toBeInTheDocument();
|
||||
});
|
||||
|
||||
it("does not render send-back button when onMoveTask is not provided", () => {
|
||||
const task = createTask({ column: "in-progress" });
|
||||
render(<TaskCard task={task} onOpenDetail={vi.fn()} addToast={vi.fn()} />);
|
||||
|
||||
Reference in New Issue
Block a user