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 <noreply@anthropic.com>
This commit is contained in:
parent
45adaa2f76
commit
e27d25a662
1 changed files with 46 additions and 1 deletions
|
|
@ -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 (
|
||||
<div className="flex flex-col h-full">
|
||||
|
|
@ -134,6 +169,16 @@ export default async function SprintBoardPage({ params }: Props) {
|
|||
← Product Backlog
|
||||
</Link>
|
||||
</div>
|
||||
|
||||
{showDialog && (
|
||||
<TaskDialog
|
||||
task={editTaskData ?? undefined}
|
||||
storyId={storyIdParam}
|
||||
productId={id}
|
||||
closePath={closePath}
|
||||
isDemo={isDemo}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue