diff --git a/__tests__/components/solo/solo-board-batch-enqueue.test.tsx b/__tests__/components/solo/solo-board-batch-enqueue.test.tsx index 392bf6e..d47242d 100644 --- a/__tests__/components/solo/solo-board-batch-enqueue.test.tsx +++ b/__tests__/components/solo/solo-board-batch-enqueue.test.tsx @@ -94,6 +94,9 @@ const TODO_TASK = { story_code: 'ST-1', story_title: 'Story 1', task_code: 'ST-1.1', + pbi_code: null, + pbi_title: null, + pbi_description: null, } const DEFAULT_PROPS = { diff --git a/__tests__/components/solo/task-detail-dialog.test.tsx b/__tests__/components/solo/task-detail-dialog.test.tsx index 3b767fc..6c56a22 100644 --- a/__tests__/components/solo/task-detail-dialog.test.tsx +++ b/__tests__/components/solo/task-detail-dialog.test.tsx @@ -65,6 +65,9 @@ const baseTask: SoloTask = { story_code: 'ST-100', story_title: 'Test Story', task_code: 'ST-100.1', + pbi_code: null, + pbi_title: null, + pbi_description: null, } const DEFAULT_PROPS = { diff --git a/__tests__/stores/solo-store-realtime.test.ts b/__tests__/stores/solo-store-realtime.test.ts index f61a7f8..2047a77 100644 --- a/__tests__/stores/solo-store-realtime.test.ts +++ b/__tests__/stores/solo-store-realtime.test.ts @@ -17,6 +17,9 @@ const baseTask = (id: string, overrides: Partial = {}): SoloTask => ({ story_code: 'ST-100', story_title: 'Original Story', task_code: 'ST-100.1', + pbi_code: null, + pbi_title: null, + pbi_description: null, ...overrides, }) diff --git a/app/(app)/products/[id]/solo/page.tsx b/app/(app)/products/[id]/solo/page.tsx index 868e579..6c03d5b 100644 --- a/app/(app)/products/[id]/solo/page.tsx +++ b/app/(app)/products/[id]/solo/page.tsx @@ -46,6 +46,7 @@ export default async function SoloProductPage({ params }: Props) { code: true, title: true, tasks: { select: { id: true }, orderBy: { sort_order: 'asc' } }, + pbi: { select: { code: true, title: true, description: true } }, }, }, }, @@ -86,6 +87,9 @@ export default async function SoloProductPage({ params }: Props) { story_code: t.story.code, story_title: t.story.title, task_code: t.code, + pbi_code: t.story.pbi?.code ?? null, + pbi_title: t.story.pbi?.title ?? null, + pbi_description: t.story.pbi?.description ?? null, })) const unassignedStories: UnassignedStory[] = rawUnassigned.map(s => ({ diff --git a/app/(mobile)/m/products/[id]/solo/page.tsx b/app/(mobile)/m/products/[id]/solo/page.tsx index ce8aa19..132e980 100644 --- a/app/(mobile)/m/products/[id]/solo/page.tsx +++ b/app/(mobile)/m/products/[id]/solo/page.tsx @@ -51,6 +51,7 @@ export default async function MobileSoloProductPage({ params }: Props) { code: true, title: true, tasks: { select: { id: true }, orderBy: { sort_order: 'asc' } }, + pbi: { select: { code: true, title: true, description: true } }, }, }, }, @@ -91,6 +92,9 @@ export default async function MobileSoloProductPage({ params }: Props) { story_code: t.story.code, story_title: t.story.title, task_code: t.code, + pbi_code: t.story.pbi?.code ?? null, + pbi_title: t.story.pbi?.title ?? null, + pbi_description: t.story.pbi?.description ?? null, })) const unassignedStories: UnassignedStory[] = rawUnassigned.map(s => ({ diff --git a/components/solo/solo-board.tsx b/components/solo/solo-board.tsx index 0dd6fa2..24b5cdf 100644 --- a/components/solo/solo-board.tsx +++ b/components/solo/solo-board.tsx @@ -32,6 +32,9 @@ export interface SoloTask { story_code: string | null story_title: string task_code: string | null + pbi_code: string | null + pbi_title: string | null + pbi_description: string | null } export interface SoloBoardProps { diff --git a/components/solo/solo-task-card.tsx b/components/solo/solo-task-card.tsx index 6ba263f..5629dca 100644 --- a/components/solo/solo-task-card.tsx +++ b/components/solo/solo-task-card.tsx @@ -8,6 +8,7 @@ import { cn } from '@/lib/utils' import { CodeBadge } from '@/components/shared/code-badge' import { JOB_STATUS_LABELS, JOB_STATUS_COLORS, JOB_STATUS_ACTIVE } from '@/components/shared/job-status' import { useSoloStore } from '@/stores/solo-store' +import { Tooltip, TooltipTrigger, TooltipContent, TooltipProvider } from '@/components/ui/tooltip' import type { SoloTask } from './solo-board' const PRIORITY_BORDER: Record = { @@ -30,10 +31,6 @@ export function SoloTaskCard({ task, isDemo, onClick }: SoloTaskCardProps) { disabled: isDemo, }) - // view-transition-name laat de browser deze card snapshotten zodat hij - // soepel van kolom naar kolom animeert wanneer de status realtime wijzigt - // (ST-805 animatie A). Tijdens drag uit zetten — dnd-kit beheert de - // transform dan zelf en dubbele transitions willen we niet. const style: React.CSSProperties | undefined = transform ? { transform: CSS.Translate.toString(transform) } : { viewTransitionName: `solo-task-${task.id}` } @@ -51,12 +48,66 @@ export function SoloTaskCard({ task, isDemo, onClick }: SoloTaskCardProps) { )} {...(!isDemo ? { ...attributes, ...listeners } : {})} > + {/* Regel 1: taaknaam + task_code */}

{task.title}

- {task.task_code && } + {task.task_code && ( + + + }> + + + +

{task.title}

+ {task.description && ( +

{task.description.slice(0, 100)}

+ )} +
+
+
+ )}
+ + {/* Regels 2–3: beschrijving + pbi_code */} +
+ {task.description ? ( + + + + }> + {task.description} + + {task.description.length > 80 && ( + + {task.description} + + )} + + + ) : ( +
+ )} + {task.pbi_code && ( + + + }> + + + +

{task.pbi_title}

+ {task.pbi_description && ( +

{task.pbi_description.slice(0, 100)}

+ )} +
+
+
+ )} +
+ + {/* Regel 4: story-info + job-badge */}
-

+

{task.story_code && {task.story_code}} {task.story_title}

@@ -95,10 +146,21 @@ export function SoloTaskCardOverlay({ task }: { task: SoloTask }) { PRIORITY_BORDER[task.priority], )} > + {/* Regel 1 */}

{task.title}

{task.task_code && }
+ {/* Regels 2–3 */} +
+ {task.description ? ( +

{task.description}

+ ) : ( +
+ )} + {task.pbi_code && } +
+ {/* Regel 4 */}

{task.story_code && {task.story_code}} {task.story_title}