diff --git a/actions/sprints.ts b/actions/sprints.ts index a431ced..de096d3 100644 --- a/actions/sprints.ts +++ b/actions/sprints.ts @@ -40,6 +40,7 @@ export async function createSprintAction(_prevState: unknown, formData: FormData sprint_goal: formData.get('sprint_goal'), start_date: formData.get('start_date'), end_date: formData.get('end_date'), + pbi_id: formData.get('pbi_id'), }) if (!parsed.success) { return { @@ -72,6 +73,35 @@ export async function createSprintAction(_prevState: unknown, formData: FormData }), ) + if (parsed.data.pbi_id) { + const pbi = await prisma.pbi.findFirst({ + where: { id: parsed.data.pbi_id, product_id: parsed.data.productId }, + select: { id: true }, + }) + if (pbi) { + const stories = await prisma.story.findMany({ + where: { pbi_id: pbi.id, sprint_id: null }, + orderBy: [{ priority: 'asc' }, { sort_order: 'asc' }], + select: { id: true }, + }) + if (stories.length > 0) { + const storyIds = stories.map(s => s.id) + await prisma.$transaction([ + ...stories.map((s, i) => + prisma.story.update({ + where: { id: s.id }, + data: { sprint_id: sprint.id, status: 'IN_SPRINT', sort_order: i + 1 }, + }), + ), + prisma.task.updateMany({ + where: { story_id: { in: storyIds }, sprint_id: null }, + data: { sprint_id: sprint.id }, + }), + ]) + } + } + } + await setActiveSprintCookie(parsed.data.productId, sprint.id) revalidatePath(`/products/${parsed.data.productId}`) return { success: true, sprintId: sprint.id } diff --git a/components/sprint/start-sprint-button.tsx b/components/sprint/start-sprint-button.tsx index 9d3ab18..fcebf17 100644 --- a/components/sprint/start-sprint-button.tsx +++ b/components/sprint/start-sprint-button.tsx @@ -21,6 +21,7 @@ import { entityDialogHeaderClasses, } from '@/components/shared/entity-dialog-layout' import { createSprintAction } from '@/actions/sprints' +import { useSelectionStore } from '@/stores/selection-store' interface StartSprintButtonProps { productId: string @@ -44,6 +45,7 @@ export function StartSprintButton({ productId, isDemo = false }: StartSprintButt const [dirty, setDirty] = useState(false) const formRef = useRef(null) const router = useRouter() + const selectedPbiId = useSelectionStore((s) => s.selectedPbiId) const [state, formAction, pending] = useActionState( async (_prev, fd) => { @@ -92,6 +94,7 @@ export function StartSprintButton({ productId, isDemo = false }: StartSprintButt className="flex-1 overflow-y-auto px-6 py-6 space-y-6" > + {selectedPbiId && }