diff --git a/components/sprint/task-list.tsx b/components/sprint/task-list.tsx
index 99650c3..028e449 100644
--- a/components/sprint/task-list.tsx
+++ b/components/sprint/task-list.tsx
@@ -1,7 +1,7 @@
'use client'
-import { useState, useTransition, useEffect, useActionState } from 'react'
-import { useFormStatus } from 'react-dom'
+import { useState, useTransition, useEffect } from 'react'
+import { useRouter, usePathname } from 'next/navigation'
import {
DndContext, DragEndEvent, DragOverlay,
KeyboardSensor, PointerSensor, useSensor, useSensors, closestCenter,
@@ -13,17 +13,13 @@ import {
import { CSS } from '@dnd-kit/utilities'
import { toast } from 'sonner'
import { Button } from '@/components/ui/button'
-import { Input } from '@/components/ui/input'
import { Badge } from '@/components/ui/badge'
import { CodeBadge } from '@/components/shared/code-badge'
import { PanelNavBar } from '@/components/shared/panel-nav-bar'
import { PRIORITY_BORDER } from '@/components/backlog/backlog-card'
import { deriveTaskCode } from '@/lib/code'
import { useSprintStore } from '@/stores/sprint-store'
-import {
- createTaskAction, updateTaskStatusAction, updateTaskAction,
- deleteTaskAction, reorderTasksAction,
-} from '@/actions/tasks'
+import { updateTaskStatusAction, reorderTasksAction } from '@/actions/tasks'
import { DemoTooltip } from '@/components/shared/demo-tooltip'
import { cn } from '@/lib/utils'
@@ -60,69 +56,69 @@ interface TaskListProps {
}
function SortableTaskRow({
- task, code, isDemo, onStatusToggle, onDelete,
-}: { task: Task; code: string | null; isDemo: boolean; onStatusToggle: () => void; onDelete: () => void }) {
- const [editing, setEditing] = useState(false)
+ task, code, isDemo, onStatusToggle, onEdit,
+}: {
+ task: Task
+ code: string | null
+ isDemo: boolean
+ onStatusToggle: () => void
+ onEdit: () => void
+}) {
const { attributes, listeners, setNodeRef, transform, transition, isDragging } = useSortable({ id: task.id })
const style = { transform: CSS.Transform.toString(transform), transition, opacity: isDragging ? 0.4 : 1 }
- const [, formAction] = useActionState(
- async (_prev: unknown, fd: FormData) => {
- const result = await updateTaskAction(_prev, fd)
- if (result?.success) setEditing(false)
- return result
- },
- undefined
- )
-
- if (editing) {
- return (
-
- )
- }
-
return (
-
+
onEdit()}
+ role="button"
+ tabIndex={0}
+ aria-label={`Bewerk taak: ${task.title}`}
+ onKeyDown={(e) => {
+ if (e.key === 'Enter' || e.key === ' ') {
+ e.preventDefault()
+ onEdit()
+ }
+ }}
+ >
{!isDemo && (
-
⠿
+
e.stopPropagation()}
+ className="text-muted-foreground cursor-grab active:cursor-grabbing shrink-0 text-sm select-none mt-0.5"
+ aria-hidden="true"
+ >
+ ⠿
+
)}
-
+
{task.title}
{code &&
}
-
-
@@ -130,48 +126,12 @@ function SortableTaskRow({
)
}
-function EditSubmitButton() {
- const { pending } = useFormStatus()
- return
{pending ? '…' : 'Opslaan'}
-}
-
-function CreateTaskForm({ storyId, sprintId, onDone }: { storyId: string; sprintId: string; onDone: () => void }) {
- const [state, formAction] = useActionState(
- async (_prev: unknown, fd: FormData) => {
- const result = await createTaskAction(_prev, fd)
- if (result?.success) { onDone(); return result }
- if (result?.error) toast.error(typeof result.error === 'string' ? result.error : 'Aanmaken mislukt')
- return result
- },
- undefined
- )
- return (
-
- )
-}
-
-function CreateSubmitButton() {
- const { pending } = useFormStatus()
- return
{pending ? '…' : 'Toevoegen'}
-}
-
-export function TaskList({ storyId, storyCode, sprintId, productId: _productId, tasks, isDemo }: TaskListProps) {
+export function TaskList({ storyId, storyCode, sprintId: _sprintId, productId: _productId, tasks, isDemo }: TaskListProps) {
const { taskOrder, initTasks, reorderTasks, rollbackTasks } = useSprintStore()
- const [creating, setCreating] = useState(false)
const [activeDragId, setActiveDragId] = useState
(null)
const [, startTransition] = useTransition()
+ const router = useRouter()
+ const pathname = usePathname()
const idKey = tasks.map(t => t.id).join(',')
useEffect(() => {
@@ -187,7 +147,7 @@ export function TaskList({ storyId, storyCode, sprintId, productId: _productId,
const sensors = useSensors(
useSensor(PointerSensor, { activationConstraint: { distance: 5 } }),
- useSensor(KeyboardSensor, { coordinateGetter: sortableKeyboardCoordinates })
+ useSensor(KeyboardSensor, { coordinateGetter: sortableKeyboardCoordinates }),
)
function handleDragEnd(event: DragEndEvent) {
@@ -209,11 +169,12 @@ export function TaskList({ storyId, storyCode, sprintId, productId: _productId,
})
}
- function handleDelete(id: string) {
- startTransition(async () => {
- const result = await deleteTaskAction(id)
- if (result && 'error' in result) toast.error(result.error ?? 'Verwijderen mislukt')
- })
+ function openCreateDialog() {
+ router.push(`${pathname}?newTask=1&storyId=${storyId}`)
+ }
+
+ function openEditDialog(taskId: string) {
+ router.push(`${pathname}?editTask=${taskId}`)
}
return (
@@ -224,22 +185,32 @@ export function TaskList({ storyId, storyCode, sprintId, productId: _productId,
<>
{doneCount}/{orderedTasks.length} klaar
- !isDemo && setCreating(true)}>+ Taak
+ !isDemo && openCreateDialog()}
+ >
+ + Taak
+
>
}
/>
- {creating && (
-
setCreating(false)} />
- )}
-
- {orderedTasks.length === 0 && !creating ? (
+ {orderedTasks.length === 0 ? (
Geen taken voor deze story.
- !isDemo && setCreating(true)}>Maak eerste taak aan
+ !isDemo && openCreateDialog()}
+ >
+ Maak eerste taak aan
+
) : (
@@ -258,7 +229,7 @@ export function TaskList({ storyId, storyCode, sprintId, productId: _productId,
code={deriveTaskCode(storyCode, idx + 1)}
isDemo={isDemo}
onStatusToggle={() => handleStatusToggle(task)}
- onDelete={() => handleDelete(task.id)}
+ onEdit={() => openEditDialog(task.id)}
/>
))}
@@ -266,7 +237,7 @@ export function TaskList({ storyId, storyCode, sprintId, productId: _productId,
{activeDragId && taskMap[activeDragId] && (
{taskMap[activeDragId].title}