fix(web): kanban add-task tests #646
@@ -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(
|
||||
|
||||
@@ -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>
|
||||
|
||||
Reference in New Issue
Block a user