diff --git a/packages/dashboard/app/components/Board.tsx b/packages/dashboard/app/components/Board.tsx index 4b30ed7e4e..82ddcc328a 100644 --- a/packages/dashboard/app/components/Board.tsx +++ b/packages/dashboard/app/components/Board.tsx @@ -456,17 +456,6 @@ export function Board({ tasks, projectId, maxConcurrent, onMoveTask, onPauseTask )} - {onCreateWorkflow && ( - - )} {onOpenWorkflowEditor && ( )} + {onCreateWorkflow && ( + + )} )}
{ }); } + function workflowToolbarActionNames() { + const toolbar = document.querySelector(".board-workflow-toolbar"); + expect(toolbar).not.toBeNull(); + return Array.from(toolbar?.querySelectorAll("button") ?? []).map((button) => button.getAttribute("aria-label")); + } + it("flag OFF renders the legacy single-lane board byte-identically", async () => { fetchBoardWorkflowsMock.mockResolvedValue({ flagEnabled: false, @@ -1000,6 +1006,7 @@ describe("Board", () => { await waitFor(() => expect(screen.getByTestId("column-triage")).toBeDefined()); expect(screen.queryByLabelText("Select workflow")).toBeNull(); + expect(workflowToolbarActionNames()).toEqual(["Edit workflows", "New workflow"]); fireEvent.click(screen.getByRole("button", { name: "New workflow" })); fireEvent.click(screen.getByRole("button", { name: "Edit workflows" })); @@ -1007,8 +1014,30 @@ describe("Board", () => { expect(onOpenWorkflowEditor).toHaveBeenCalledTimes(1); }); + it("preserves workflow toolbar partial action visibility", async () => { + const onCreateWorkflow = vi.fn(); + enableFlag({}, [DEFAULT_WORKFLOW]); + const { unmount } = renderBoard({ onCreateWorkflow }); + + await waitFor(() => expect(screen.getByTestId("column-triage")).toBeDefined()); + expect(workflowToolbarActionNames()).toEqual(["New workflow"]); + fireEvent.click(screen.getByRole("button", { name: "New workflow" })); + expect(onCreateWorkflow).toHaveBeenCalledTimes(1); + unmount(); + + const onOpenWorkflowEditor = vi.fn(); + enableFlag({}, [DEFAULT_WORKFLOW]); + renderBoard({ onOpenWorkflowEditor }); + + await waitFor(() => expect(screen.getByTestId("column-triage")).toBeDefined()); + expect(workflowToolbarActionNames()).toEqual(["Edit workflows"]); + fireEvent.click(screen.getByRole("button", { name: "Edit workflows" })); + expect(onOpenWorkflowEditor).toHaveBeenCalledTimes(1); + }); + it("renders one selected workflow at a time and switches workflows from the dropdown", async () => { const onCreateWorkflow = vi.fn(); + const onOpenWorkflowEditor = vi.fn(); enableFlag( { "FN-1": "builtin:coding", "FN-2": "wf-custom", "FN-3": "wf-custom" }, [DEFAULT_WORKFLOW, CUSTOM_WORKFLOW], @@ -1020,11 +1049,15 @@ describe("Board", () => { mkTask({ id: "FN-3", column: "intake" }), ], onCreateWorkflow, + onOpenWorkflowEditor, }); const selector = await screen.findByLabelText("Select workflow") as HTMLSelectElement; expect(selector.value).toBe("builtin:coding"); + expect(workflowToolbarActionNames()).toEqual(["Edit workflows", "New workflow"]); fireEvent.click(screen.getByRole("button", { name: "New workflow" })); + fireEvent.click(screen.getByRole("button", { name: "Edit workflows" })); expect(onCreateWorkflow).toHaveBeenCalledTimes(1); + expect(onOpenWorkflowEditor).toHaveBeenCalledTimes(1); expect(JSON.parse(screen.getByTestId("column-todo").getAttribute("data-tasks") || "[]").map((task: Task) => task.id)).toEqual(["FN-1"]); expect(screen.queryByTestId("column-intake")).toBeNull();