From e27d25a662873109016691300e855cd0270d3677 Mon Sep 17 00:00:00 2001 From: Madhura68 Date: Wed, 29 Apr 2026 23:46:56 +0200 Subject: [PATCH] feat(ST-1112): wire TaskDialog into sprint page via searchParams Sprint page now reads ?newTask, ?storyId, and ?editTask query params. For edit mode: fetches the task server-side with productAccessFilter scope (invalid/foreign IDs redirect to closePath). Renders TaskDialog when either param is present. closePath is the sprint route without query params. Co-Authored-By: Claude Sonnet 4.6 --- app/(app)/products/[id]/sprint/page.tsx | 47 ++++++++++++++++++++++++- 1 file changed, 46 insertions(+), 1 deletion(-) diff --git a/app/(app)/products/[id]/sprint/page.tsx b/app/(app)/products/[id]/sprint/page.tsx index 0365842..d58603c 100644 --- a/app/(app)/products/[id]/sprint/page.tsx +++ b/app/(app)/products/[id]/sprint/page.tsx @@ -1,19 +1,29 @@ import { notFound, redirect } from 'next/navigation' import { getSession } from '@/lib/auth' import { getAccessibleProduct } from '@/lib/product-access' +import { productAccessFilter } from '@/lib/product-access' import { prisma } from '@/lib/prisma' import { SprintBoardClient } from '@/components/sprint/sprint-board-client' import { SprintHeader } from '@/components/sprint/sprint-header' import type { SprintStory, PbiWithStories, ProductMember } from '@/components/sprint/sprint-backlog' import type { Task } from '@/components/sprint/task-list' +import { TaskDialog } from '@/app/_components/tasks/task-dialog' +import type { TaskDialogTask } from '@/app/_components/tasks/task-dialog' import Link from 'next/link' interface Props { params: Promise<{ id: string }> + searchParams: Promise<{ + newTask?: string + storyId?: string + editTask?: string + }> } -export default async function SprintBoardPage({ params }: Props) { +export default async function SprintBoardPage({ params, searchParams }: Props) { const { id } = await params + const { newTask, storyId: storyIdParam, editTask } = await searchParams + const session = await getSession() if (!session.userId) redirect('/login') @@ -104,6 +114,31 @@ export default async function SprintBoardPage({ params }: Props) { const sprintStoryIdList = sprintStories.map(s => s.id) const isDemo = session.isDemo ?? false + const closePath = `/products/${id}/sprint` + + // Fetch task for edit mode (auth-scoped) + let editTaskData: TaskDialogTask | null = null + if (editTask) { + const t = await prisma.task.findFirst({ + where: { + id: editTask, + story: { product: productAccessFilter(session.userId) }, + }, + select: { + id: true, + title: true, + description: true, + implementation_plan: true, + priority: true, + status: true, + created_at: true, + }, + }) + if (!t) redirect(closePath) + editTaskData = t + } + + const showDialog = !!newTask || !!editTaskData return (
@@ -134,6 +169,16 @@ export default async function SprintBoardPage({ params }: Props) { ← Product Backlog
+ + {showDialog && ( + + )} ) }