fix(web): kanban add-task tests #646

Closed
jason.woltje wants to merge 2 commits from fix/kanban-tests into main
2 changed files with 56 additions and 23 deletions

View File

@@ -140,8 +140,8 @@ describe("KanbanPage add task flow", (): void => {
const titleInput = screen.getByPlaceholderText("Task title...");
await user.type(titleInput, createdTask.title);
// Click the Add button
await user.click(screen.getByRole("button", { name: /✓ Add/i }));
// Press Enter to submit
await user.keyboard("{Enter}");
await waitFor((): void => {
expect(mockCreateTask).toHaveBeenCalledWith(

View File

@@ -184,10 +184,11 @@ function TaskCard({ task, provided, snapshot, columnAccent }: TaskCardProps): Re
interface KanbanColumnProps {
config: ColumnConfig;
tasks: Task[];
onAddTask: (status: TaskStatus, title: string) => Promise<void>;
onAddTask: (status: TaskStatus, title: string, projectId?: string) => Promise<void>;
projectId?: string;
}
function KanbanColumn({ config, tasks, onAddTask }: KanbanColumnProps): ReactElement {
function KanbanColumn({ config, tasks, onAddTask, projectId }: KanbanColumnProps): ReactElement {
const [showAddForm, setShowAddForm] = useState(false);
const [inputValue, setInputValue] = useState("");
const [isSubmitting, setIsSubmitting] = useState(false);
@@ -208,7 +209,7 @@ function KanbanColumn({ config, tasks, onAddTask }: KanbanColumnProps): ReactEle
setIsSubmitting(true);
try {
await onAddTask(config.status, inputValue.trim());
await onAddTask(config.status, inputValue.trim(), projectId);
setInputValue("");
setShowAddForm(false);
} catch (err) {
@@ -362,6 +363,45 @@ function KanbanColumn({ config, tasks, onAddTask }: KanbanColumnProps): ReactEle
}}
autoFocus
/>
<div style={{ display: "flex", gap: 6, marginTop: 6 }}>
<button
type="submit"
disabled={isSubmitting || !inputValue.trim()}
style={{
padding: "6px 12px",
borderRadius: "var(--r)",
border: "1px solid var(--primary)",
background: "var(--primary)",
color: "#fff",
fontSize: "0.8rem",
fontWeight: 500,
cursor: isSubmitting || !inputValue.trim() ? "not-allowed" : "pointer",
opacity: isSubmitting || !inputValue.trim() ? 0.5 : 1,
}}
>
Add
</button>
<button
type="button"
onClick={() => {
setShowAddForm(false);
setInputValue("");
}}
disabled={isSubmitting}
style={{
padding: "6px 12px",
borderRadius: "var(--r)",
border: "1px solid var(--border)",
background: "transparent",
color: "var(--muted)",
fontSize: "0.8rem",
cursor: isSubmitting ? "not-allowed" : "pointer",
opacity: isSubmitting ? 0.5 : 1,
}}
>
Cancel
</button>
</div>
<div style={{ marginTop: 6, fontSize: "0.75rem", color: "var(--muted)" }}>
Press{" "}
<kbd
@@ -745,10 +785,17 @@ export default function KanbanPage(): ReactElement {
/* --- add task handler --- */
const handleAddTask = useCallback(
async (status: TaskStatus, title: string) => {
async (status: TaskStatus, title: string, projectId?: string) => {
try {
const wsId = workspaceId ?? undefined;
const newTask = await createTask({ title, status }, wsId);
const taskData: { title: string; status: TaskStatus; projectId?: string } = {
title,
status,
};
if (projectId) {
taskData.projectId = projectId;
}
const newTask = await createTask(taskData, wsId);
// Optimistically add to local state
setTasks((prev) => [...prev, newTask]);
} catch (err: unknown) {
@@ -866,23 +913,8 @@ export default function KanbanPage(): ReactElement {
Clear filters
</button>
</div>
) : tasks.length === 0 ? (
/* Empty state */
<div
style={{
background: "var(--surface)",
border: "1px solid var(--border)",
borderRadius: "var(--r-lg)",
padding: 48,
textAlign: "center",
}}
>
<p style={{ color: "var(--muted)", margin: 0, fontSize: "0.9rem" }}>
No tasks yet. Create some tasks to see them here.
</p>
</div>
) : (
/* Board */
/* Board (always render columns to allow adding first task) */
<DragDropContext onDragEnd={handleDragEnd}>
<div
style={{
@@ -899,6 +931,7 @@ export default function KanbanPage(): ReactElement {
config={col}
tasks={grouped[col.status]}
onAddTask={handleAddTask}
projectId={filterProject}
/>
))}
</div>