feat: story cards match solo task card style, 4-column grid layout
Replaced fixed w-28 blocks with priority-border cards identical to solo task cards. Grid layout (grid-cols-4) replaces flex-wrap. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
9a5cc484b7
commit
3a78018e31
1 changed files with 21 additions and 22 deletions
|
|
@ -15,7 +15,7 @@ import {
|
|||
import {
|
||||
SortableContext,
|
||||
useSortable,
|
||||
horizontalListSortingStrategy,
|
||||
rectSortingStrategy,
|
||||
arrayMove,
|
||||
sortableKeyboardCoordinates,
|
||||
} from '@dnd-kit/sortable'
|
||||
|
|
@ -38,6 +38,12 @@ const PRIORITY_COLORS: Record<number, string> = {
|
|||
3: 'bg-priority-medium/15 text-priority-medium border-priority-medium/30',
|
||||
4: 'bg-priority-low/15 text-priority-low border-priority-low/30',
|
||||
}
|
||||
const PRIORITY_BORDER: Record<number, string> = {
|
||||
1: 'border-l-4 border-l-priority-critical',
|
||||
2: 'border-l-4 border-l-priority-high',
|
||||
3: 'border-l-4 border-l-priority-medium',
|
||||
4: 'border-l-4 border-l-priority-low',
|
||||
}
|
||||
const STATUS_COLORS: Record<string, string> = {
|
||||
OPEN: 'bg-status-todo/15 text-status-todo border-status-todo/30',
|
||||
IN_SPRINT: 'bg-status-in-progress/15 text-status-in-progress border-status-in-progress/30',
|
||||
|
|
@ -90,24 +96,14 @@ function SortableStoryBlock({
|
|||
{...attributes}
|
||||
{...listeners}
|
||||
onClick={onClick}
|
||||
title={story.title}
|
||||
className="relative w-28 shrink-0 bg-surface-container-low border border-border rounded-lg p-2 cursor-pointer hover:border-primary transition-colors space-y-1.5 select-none"
|
||||
className={cn(
|
||||
'bg-surface-container rounded border border-border px-3 py-2 select-none transition-colors cursor-pointer hover:bg-surface-container-high',
|
||||
PRIORITY_BORDER[story.priority],
|
||||
isDragging && 'opacity-40 shadow-lg',
|
||||
)}
|
||||
>
|
||||
<button
|
||||
onClick={(e) => { e.stopPropagation(); onClick() }}
|
||||
onPointerDown={(e) => e.stopPropagation()}
|
||||
className="absolute top-1.5 right-2 border border-border rounded px-1 py-0.5 text-xs text-muted-foreground hover:text-foreground hover:bg-surface-container transition-colors leading-none"
|
||||
aria-label="Bewerk story"
|
||||
>
|
||||
✎
|
||||
</button>
|
||||
<p className="text-xs font-medium text-foreground line-clamp-3 min-h-[3rem] pr-4">
|
||||
{story.title}
|
||||
</p>
|
||||
<div className="flex flex-col gap-1">
|
||||
<Badge className={cn('text-[10px] px-1.5 py-0 border', PRIORITY_COLORS[story.priority])}>
|
||||
{PRIORITY_LABELS[story.priority]}
|
||||
</Badge>
|
||||
<p className="text-sm text-foreground leading-snug line-clamp-2">{story.title}</p>
|
||||
<div className="flex items-center gap-1 mt-1.5">
|
||||
<Badge className={cn('text-[10px] px-1.5 py-0 border', STATUS_COLORS[story.status])}>
|
||||
{STATUS_LABELS[story.status] ?? story.status}
|
||||
</Badge>
|
||||
|
|
@ -275,9 +271,9 @@ export function StoryPanel({ productId, storiesByPbi, isDemo }: StoryPanelProps)
|
|||
|
||||
<SortableContext
|
||||
items={grouped[priority].map(s => s.id)}
|
||||
strategy={horizontalListSortingStrategy}
|
||||
strategy={rectSortingStrategy}
|
||||
>
|
||||
<div className="flex flex-wrap gap-2">
|
||||
<div className="grid grid-cols-4 gap-2">
|
||||
{grouped[priority].map(story => (
|
||||
<SortableStoryBlock
|
||||
key={story.id}
|
||||
|
|
@ -294,8 +290,11 @@ export function StoryPanel({ productId, storiesByPbi, isDemo }: StoryPanelProps)
|
|||
|
||||
<DragOverlay>
|
||||
{activeDragId && storyMap[activeDragId] && (
|
||||
<div className="w-28 bg-surface-container-low border border-primary rounded-lg p-2 shadow-lg opacity-90">
|
||||
<p className="text-xs font-medium line-clamp-3">{storyMap[activeDragId].title}</p>
|
||||
<div className={cn(
|
||||
'bg-surface-container border border-primary rounded px-3 py-2 shadow-xl opacity-90',
|
||||
PRIORITY_BORDER[storyMap[activeDragId].priority],
|
||||
)}>
|
||||
<p className="text-sm text-foreground leading-snug line-clamp-2">{storyMap[activeDragId].title}</p>
|
||||
</div>
|
||||
)}
|
||||
</DragOverlay>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue