feat(ST-1111.6): add 'Voer uit' + cancel buttons to task detail dialog
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
ece0aa963d
commit
b9c65eb145
1 changed files with 54 additions and 2 deletions
|
|
@ -5,9 +5,11 @@ import Link from 'next/link'
|
|||
import { toast } from 'sonner'
|
||||
import { Dialog, DialogContent, DialogHeader, DialogTitle } from '@/components/ui/dialog'
|
||||
import { Badge } from '@/components/ui/badge'
|
||||
import { Button } from '@/components/ui/button'
|
||||
import { Textarea } from '@/components/ui/textarea'
|
||||
import { DemoTooltip } from '@/components/shared/demo-tooltip'
|
||||
import { useSoloStore } from '@/stores/solo-store'
|
||||
import { enqueueClaudeJobAction, cancelClaudeJobAction } from '@/actions/claude-jobs'
|
||||
import { cn } from '@/lib/utils'
|
||||
import type { SoloTask } from './solo-board'
|
||||
|
||||
|
|
@ -43,12 +45,33 @@ type SaveState = 'idle' | 'saving' | 'saved'
|
|||
|
||||
function TaskDetailContent({ task, productId, isDemo, onClose }: TaskDetailContentProps) {
|
||||
const { updatePlan } = useSoloStore()
|
||||
const job = useSoloStore(s => s.claudeJobsByTaskId[task.id])
|
||||
const [localPlan, setLocalPlan] = useState(task.implementation_plan ?? '')
|
||||
const [saveState, setSaveState] = useState<SaveState>('idle')
|
||||
const [, startTransition] = useTransition()
|
||||
const [jobPending, startJobTransition] = useTransition()
|
||||
const fadeTimer = useRef<ReturnType<typeof setTimeout> | null>(null)
|
||||
const savedPlanRef = useRef(task.implementation_plan ?? '')
|
||||
|
||||
function handleEnqueue() {
|
||||
startJobTransition(async () => {
|
||||
const result = await enqueueClaudeJobAction(task.id)
|
||||
if ('error' in result) {
|
||||
toast.error(result.error)
|
||||
} else {
|
||||
toast.success('Agent ingeschakeld')
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
function handleCancel() {
|
||||
if (!job) return
|
||||
startJobTransition(async () => {
|
||||
const result = await cancelClaudeJobAction(job.job_id)
|
||||
if ('error' in result) toast.error(result.error)
|
||||
})
|
||||
}
|
||||
|
||||
function handleBlur() {
|
||||
if (isDemo || localPlan === savedPlanRef.current) return
|
||||
|
||||
|
|
@ -133,14 +156,43 @@ function TaskDetailContent({ task, productId, isDemo, onClose }: TaskDetailConte
|
|||
</div>
|
||||
</div>
|
||||
|
||||
<div className="-mx-4 -mb-4 flex items-center border-t bg-muted/50 px-4 py-3 rounded-b-xl">
|
||||
<div className="-mx-4 -mb-4 flex flex-wrap items-center gap-2 border-t bg-muted/50 px-4 py-3 rounded-b-xl">
|
||||
<Link
|
||||
href={`/products/${productId}/sprint/planning`}
|
||||
className="text-xs text-primary hover:underline"
|
||||
className="text-xs text-primary hover:underline mr-auto"
|
||||
onClick={onClose}
|
||||
>
|
||||
Open in Sprint Board ↗
|
||||
</Link>
|
||||
|
||||
{!isDemo && !job && (
|
||||
<Button size="sm" className="h-7 text-xs" onClick={handleEnqueue} disabled={jobPending}>
|
||||
Voer uit
|
||||
</Button>
|
||||
)}
|
||||
|
||||
{job?.status === 'queued' && (
|
||||
<span className="text-xs text-muted-foreground">Wacht op agent…</span>
|
||||
)}
|
||||
|
||||
{(job?.status === 'claimed' || job?.status === 'running') && (
|
||||
<>
|
||||
<span className="text-xs text-muted-foreground">Bezig: {job.summary ?? '…'}</span>
|
||||
<Button size="sm" variant="outline" className="h-7 text-xs" onClick={handleCancel} disabled={jobPending}>
|
||||
Annuleer
|
||||
</Button>
|
||||
</>
|
||||
)}
|
||||
|
||||
{job?.status === 'done' && (
|
||||
<span className="text-xs text-status-done">
|
||||
Klaar{job.branch ? ` — branch ${job.branch}` : ''}
|
||||
</span>
|
||||
)}
|
||||
|
||||
{job?.status === 'failed' && (
|
||||
<span className="text-xs text-error">Mislukt: {job.error}</span>
|
||||
)}
|
||||
</div>
|
||||
</>
|
||||
)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue