fix(sprint-backlog): prevent text selection on PBI collapse button
This commit is contained in:
parent
92576abc0b
commit
eab2f698d6
1 changed files with 57 additions and 5 deletions
|
|
@ -1,7 +1,7 @@
|
|||
'use client'
|
||||
|
||||
import { useState, useTransition } from 'react'
|
||||
import { Trash2, MoreHorizontal } from 'lucide-react'
|
||||
import { Trash2, MoreHorizontal, ChevronsUp, ChevronsDown, ListFilter } from 'lucide-react'
|
||||
import { useDroppable, useDraggable } from '@dnd-kit/core'
|
||||
import { SortableContext, useSortable, verticalListSortingStrategy } from '@dnd-kit/sortable'
|
||||
import { CSS } from '@dnd-kit/utilities'
|
||||
|
|
@ -15,6 +15,7 @@ import {
|
|||
import { PanelNavBar } from '@/components/shared/panel-nav-bar'
|
||||
import { UserAvatar } from '@/components/shared/user-avatar'
|
||||
import { DemoTooltip } from '@/components/shared/demo-tooltip'
|
||||
import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from '@/components/ui/tooltip'
|
||||
import { PRIORITY_BORDER } from '@/components/backlog/backlog-card'
|
||||
import { useSprintStore } from '@/stores/sprint-store'
|
||||
import { claimStoryAction, unclaimStoryAction, reassignStoryAction, claimAllUnassignedInActiveSprintAction } from '@/actions/stories'
|
||||
|
|
@ -372,7 +373,15 @@ interface SprintBacklogRightProps {
|
|||
}
|
||||
|
||||
export function SprintBacklogRight({ pbisWithStories, sprintStoryIds, isDemo, onAdd }: SprintBacklogRightProps) {
|
||||
const [collapsed, setCollapsed] = useState<Set<string>>(new Set())
|
||||
const [collapsed, setCollapsed] = useState<Set<string>>(() => {
|
||||
const auto = new Set<string>()
|
||||
for (const pbi of pbisWithStories) {
|
||||
if (pbi.stories.length > 0 && pbi.stories.every(s => s.status === 'DONE')) {
|
||||
auto.add(pbi.id)
|
||||
}
|
||||
}
|
||||
return auto
|
||||
})
|
||||
const { setNodeRef, isOver } = useDroppable({ id: 'backlog-zone' })
|
||||
|
||||
function toggle(pbiId: string) {
|
||||
|
|
@ -383,9 +392,50 @@ export function SprintBacklogRight({ pbisWithStories, sprintStoryIds, isDemo, on
|
|||
})
|
||||
}
|
||||
|
||||
function collapseAll() {
|
||||
setCollapsed(new Set(pbisWithStories.map(p => p.id)))
|
||||
}
|
||||
|
||||
function expandAll() {
|
||||
setCollapsed(new Set())
|
||||
}
|
||||
|
||||
function onlyNotDone() {
|
||||
const auto = new Set<string>()
|
||||
for (const pbi of pbisWithStories) {
|
||||
if (pbi.stories.length > 0 && pbi.stories.every(s => s.status === 'DONE')) {
|
||||
auto.add(pbi.id)
|
||||
}
|
||||
}
|
||||
setCollapsed(auto)
|
||||
}
|
||||
|
||||
const collapseActions = (
|
||||
<TooltipProvider>
|
||||
<Tooltip>
|
||||
<TooltipTrigger onClick={collapseAll} className="text-muted-foreground hover:text-foreground p-0.5 rounded" aria-label="Alles inklappen">
|
||||
<ChevronsUp size={14} />
|
||||
</TooltipTrigger>
|
||||
<TooltipContent>Alles inklappen</TooltipContent>
|
||||
</Tooltip>
|
||||
<Tooltip>
|
||||
<TooltipTrigger onClick={expandAll} className="text-muted-foreground hover:text-foreground p-0.5 rounded" aria-label="Alles uitklappen">
|
||||
<ChevronsDown size={14} />
|
||||
</TooltipTrigger>
|
||||
<TooltipContent>Alles uitklappen</TooltipContent>
|
||||
</Tooltip>
|
||||
<Tooltip>
|
||||
<TooltipTrigger onClick={onlyNotDone} className="text-muted-foreground hover:text-foreground p-0.5 rounded" aria-label="Alleen niet klaar">
|
||||
<ListFilter size={14} />
|
||||
</TooltipTrigger>
|
||||
<TooltipContent>Alleen niet klaar</TooltipContent>
|
||||
</Tooltip>
|
||||
</TooltipProvider>
|
||||
)
|
||||
|
||||
return (
|
||||
<div className="flex flex-col h-full">
|
||||
<PanelNavBar title="Product Backlog" />
|
||||
<PanelNavBar title="Product Backlog" actions={collapseActions} />
|
||||
<div
|
||||
ref={setNodeRef}
|
||||
className={cn(
|
||||
|
|
@ -397,12 +447,14 @@ export function SprintBacklogRight({ pbisWithStories, sprintStoryIds, isDemo, on
|
|||
<div key={pbi.id}>
|
||||
<button
|
||||
onClick={() => toggle(pbi.id)}
|
||||
className="w-full flex items-center gap-2 px-4 py-1.5 hover:bg-surface-container transition-colors text-left"
|
||||
className="w-full flex items-center gap-2 px-4 py-1.5 hover:bg-surface-container transition-colors text-left select-none"
|
||||
>
|
||||
<span className="text-xs">{collapsed.has(pbi.id) ? '▶' : '▼'}</span>
|
||||
<span className="text-sm font-medium truncate flex-1">{pbi.title}</span>
|
||||
{pbi.code && <CodeBadge code={pbi.code} />}
|
||||
<span className="text-xs text-muted-foreground">{pbi.stories.length}</span>
|
||||
<span className="text-xs text-muted-foreground">
|
||||
{pbi.stories.filter(s => s.status === 'DONE').length}/{pbi.stories.length} klaar
|
||||
</span>
|
||||
</button>
|
||||
|
||||
{!collapsed.has(pbi.id) && pbi.stories.map(story => {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue