From 9cd6281816bc0f881c70c5ff22079811eedcc5c7 Mon Sep 17 00:00:00 2001 From: janpeter visser Date: Fri, 1 May 2026 10:55:08 +0200 Subject: [PATCH] feat: 'Start agents (n)'-knop in Solo header, productname weg SoloBoard-header toont nu een primary button die het aantal queueable TO_DO-taken telt (TO_DO zonder actieve ClaudeJob via claudeJobsByTaskId-store) en bij klik de nieuwe enqueueAllTodoJobsAction aanroept. Toast geeft het aantal gestarte agents terug. - productname-h1 verwijderd (staat al in NavBar-dropdown, dubbel) - sprintdoel blijft naast de knop - 'Toon openstaande stories'-link blijft rechts - demo-modus disabled met DemoTooltip - batch-pending state voorkomt dubbele klikken - productName-prop weg uit SoloBoard + page.tsx (was alleen voor h1) Co-Authored-By: Claude Opus 4.7 (1M context) --- app/(app)/products/[id]/solo/page.tsx | 1 - components/solo/solo-board.tsx | 41 +++++++++++++++++++++++---- 2 files changed, 36 insertions(+), 6 deletions(-) diff --git a/app/(app)/products/[id]/solo/page.tsx b/app/(app)/products/[id]/solo/page.tsx index 995aee2..980bcc0 100644 --- a/app/(app)/products/[id]/solo/page.tsx +++ b/app/(app)/products/[id]/solo/page.tsx @@ -105,7 +105,6 @@ export default async function SoloProductPage({ params }: Props) { return ( s.claudeJobsByTaskId) const [activeDragId, setActiveDragId] = useState(null) const [selectedTask, setSelectedTask] = useState(null) const [sheetOpen, setSheetOpen] = useState(false) const [unassignedStories, setUnassignedStories] = useState(initialUnassigned) const [, startTransition] = useTransition() + const [batchPending, startBatchTransition] = useTransition() const taskKey = initialTasks.map(t => t.id).join(',') useEffect(() => { @@ -125,13 +129,40 @@ export function SoloBoard({ const activeTask = activeDragId ? tasks[activeDragId] : null + const queueableCount = columnTasks.TO_DO.filter(t => { + const job = claudeJobsByTaskId[t.id] + return !job || (job.status !== 'queued' && job.status !== 'claimed' && job.status !== 'running') + }).length + + function handleStartAll() { + if (queueableCount === 0) return + startBatchTransition(async () => { + const result = await enqueueAllTodoJobsAction(productId) + if ('error' in result) { + toast.error(result.error) + } else if (result.count === 0) { + toast.info('Geen taken om te starten') + } else { + toast.success(`${result.count} ${result.count === 1 ? 'agent' : 'agents'} ingeschakeld`) + } + }) + } + return (
-
-

{productName}

+
+ + + {sprintGoal && ( -

{sprintGoal}

+

{sprintGoal}

)}