feat(ST-313): merge sprint board into single three-panel view
- TriplePane component with two resizable dividers, localStorage persistence, mobile tabs - SprintBoardClient replaces SprintBacklogClient + PlanningRightClient - Left panel: Product Backlog (PBIs with stories to add to sprint) - Middle panel: Sprint Backlog (stories in sprint, click to select, sortable) - Right panel: TaskList for selected story - /sprint/planning redirects to /sprint - Remove PlanningLeft, PlanningRightClient, SprintBacklogClient Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
4df83dcdbb
commit
0a27be4886
8 changed files with 320 additions and 273 deletions
|
|
@ -119,22 +119,28 @@ function EditSubmitButton() {
|
|||
}
|
||||
|
||||
function CreateTaskForm({ storyId, sprintId, onDone }: { storyId: string; sprintId: string; onDone: () => void }) {
|
||||
const [, formAction] = useActionState(
|
||||
const [state, formAction] = useActionState(
|
||||
async (_prev: unknown, fd: FormData) => {
|
||||
const result = await createTaskAction(_prev, fd)
|
||||
if (result?.success) onDone()
|
||||
if (result?.success) { onDone(); return result }
|
||||
if (result?.error) toast.error(typeof result.error === 'string' ? result.error : 'Aanmaken mislukt')
|
||||
return result
|
||||
},
|
||||
undefined
|
||||
)
|
||||
return (
|
||||
<form action={formAction} className="flex gap-2 px-4 py-2 border-b border-border">
|
||||
<form action={formAction} className="flex flex-col gap-1.5 px-4 py-2 border-b border-border">
|
||||
<input type="hidden" name="storyId" value={storyId} />
|
||||
<input type="hidden" name="sprintId" value={sprintId} />
|
||||
<input type="hidden" name="priority" value="2" />
|
||||
<Input name="title" autoFocus placeholder="Taaknaam…" className="h-7 text-sm flex-1" required />
|
||||
<CreateSubmitButton />
|
||||
<Button type="button" variant="ghost" size="sm" className="h-7" onClick={onDone}>×</Button>
|
||||
<div className="flex gap-2">
|
||||
<Input name="title" autoFocus placeholder="Taaknaam…" className="h-7 text-sm flex-1" required />
|
||||
<CreateSubmitButton />
|
||||
<Button type="button" variant="ghost" size="sm" className="h-7" onClick={onDone}>×</Button>
|
||||
</div>
|
||||
{state && 'error' in state && typeof state.error === 'string' && (
|
||||
<p className="text-xs text-destructive">{state.error}</p>
|
||||
)}
|
||||
</form>
|
||||
)
|
||||
}
|
||||
|
|
@ -219,6 +225,7 @@ export function TaskList({ storyId, sprintId, productId: _productId, tasks, isDe
|
|||
</div>
|
||||
) : (
|
||||
<DndContext
|
||||
id="task-list"
|
||||
sensors={sensors}
|
||||
collisionDetection={closestCenter}
|
||||
onDragStart={e => setActiveDragId(e.active.id as string)}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue