diff --git a/components/sprint/sprint-header.tsx b/components/sprint/sprint-header.tsx index 3668466..dac19e4 100644 --- a/components/sprint/sprint-header.tsx +++ b/components/sprint/sprint-header.tsx @@ -8,6 +8,16 @@ import { DialogContent, DialogTitle, } from '@/components/ui/dialog' +import { + AlertDialog, + AlertDialogAction, + AlertDialogCancel, + AlertDialogContent, + AlertDialogDescription, + AlertDialogFooter, + AlertDialogHeader, + AlertDialogTitle, +} from '@/components/ui/alert-dialog' import { toast } from 'sonner' import { DemoTooltip } from '@/components/shared/demo-tooltip' import { @@ -20,7 +30,7 @@ import { entityDialogFooterClasses, entityDialogHeaderClasses, } from '@/components/shared/entity-dialog-layout' -import { updateSprintGoalAction, updateSprintDatesAction, completeSprintAction } from '@/actions/sprints' +import { updateSprintGoalAction, updateSprintDatesAction, completeSprintAction, setAllSprintTasksDoneAction } from '@/actions/sprints' import type { SprintStory } from './sprint-backlog' interface Sprint { @@ -51,12 +61,14 @@ function toDateInputValue(d: Date | null) { return d.toISOString().slice(0, 10) } -export function SprintHeader({ productId: _productId, productName, sprint, isDemo, sprintStories }: SprintHeaderProps) { +export function SprintHeader({ productId, productName, sprint, isDemo, sprintStories }: SprintHeaderProps) { const [editingGoal, setEditingGoal] = useState(false) const [editingDates, setEditingDates] = useState(false) const [completeOpen, setCompleteOpen] = useState(false) const [decisions, setDecisions] = useState>({}) const [isCompleting, startCompleting] = useTransition() + const [showAllDoneConfirm, setShowAllDoneConfirm] = useState(false) + const [isSettingAllDone, startSettingAllDone] = useTransition() const [datesDirty, setDatesDirty] = useState(false) const datesFormRef = useRef(null) @@ -102,6 +114,20 @@ export function SprintHeader({ productId: _productId, productName, sprint, isDem }) } + function handleAllDone() { + startSettingAllDone(async () => { + const result = await setAllSprintTasksDoneAction(sprint.id) + if (!result.ok) { + toast.error(result.error ?? 'Alles op done mislukt') + } else { + const allDone: Record = {} + sprintStories.forEach(s => { allDone[s.id] = 'DONE' }) + setDecisions(allDone) + } + setShowAllDoneConfirm(false) + }) + } + return (
@@ -208,6 +234,18 @@ export function SprintHeader({ productId: _productId, productName, sprint, isDem

Geef per story aan wat er mee moet gebeuren:

+
+ +
{sprintStories.map(story => (
@@ -245,6 +283,26 @@ export function SprintHeader({ productId: _productId, productName, sprint, isDem
+ + + + + Alles op done zetten? + + Alle taken én stories in de sprint — inclusief taken met status + REVIEW — worden op DONE gezet. De per-story toggles hieronder + worden daarna bijgewerkt. Je kunt daarna nog per story aanpassen + vóór je de sprint afrondt. + + + + Annuleren + + {isSettingAllDone ? 'Bezig…' : 'Alles op done'} + + + +
) }