Files
kandev/apps/web/components/kanban-display-dropdown.tsx
T
2026-01-22 21:30:26 +00:00

140 lines
4.8 KiB
TypeScript

'use client';
import { Button } from '@kandev/ui/button';
import { Checkbox } from '@kandev/ui/checkbox';
import {
DropdownMenu,
DropdownMenuContent,
DropdownMenuLabel,
DropdownMenuSeparator,
DropdownMenuTrigger,
} from '@kandev/ui/dropdown-menu';
import {
Select,
SelectContent,
SelectItem,
SelectTrigger,
SelectValue,
} from '@kandev/ui/select';
import { IconAdjustmentsHorizontal } from '@tabler/icons-react';
import { useKanbanDisplaySettings } from '@/hooks/use-kanban-display-settings';
import type { Workspace, Repository } from '@/lib/types/http';
import type { BoardState } from '@/lib/state/slices';
export function KanbanDisplayDropdown() {
const {
workspaces,
boards,
activeWorkspaceId,
activeBoardId,
repositories,
repositoriesLoading,
allRepositoriesSelected,
selectedRepositoryId,
enablePreviewOnClick,
onWorkspaceChange,
onBoardChange,
onRepositoryChange,
onTogglePreviewOnClick,
} = useKanbanDisplaySettings();
const repositoryValue = allRepositoriesSelected ? 'all' : selectedRepositoryId ?? 'all';
return (
<DropdownMenu>
<DropdownMenuTrigger asChild>
<Button variant="outline" className="cursor-pointer">
<IconAdjustmentsHorizontal className="h-4 w-4 mr-2" />
Display
</Button>
</DropdownMenuTrigger>
<DropdownMenuContent align="end" className="w-[280px] p-3">
<div className="space-y-3">
<div className="space-y-1.5">
<DropdownMenuLabel className="px-0">Workspace</DropdownMenuLabel>
<Select
value={activeWorkspaceId ?? ''}
onValueChange={(value) => onWorkspaceChange(value || null)}
>
<SelectTrigger className="w-full">
<SelectValue placeholder="Select workspace" />
</SelectTrigger>
<SelectContent>
{workspaces.map((workspace: Workspace) => (
<SelectItem key={workspace.id} value={workspace.id}>
{workspace.name}
</SelectItem>
))}
</SelectContent>
</Select>
</div>
<DropdownMenuSeparator />
<div className="space-y-1.5">
<DropdownMenuLabel className="px-0">Board</DropdownMenuLabel>
<Select
value={activeBoardId ?? ''}
onValueChange={(value) => onBoardChange(value || null)}
>
<SelectTrigger className="w-full">
<SelectValue placeholder="Select board" />
</SelectTrigger>
<SelectContent>
{boards.map((board: BoardState['items'][number]) => (
<SelectItem key={board.id} value={board.id}>
{board.name}
</SelectItem>
))}
</SelectContent>
</Select>
</div>
<DropdownMenuSeparator />
<div className="space-y-1.5">
<DropdownMenuLabel className="px-0">Repository</DropdownMenuLabel>
<Select
value={repositoryValue}
onValueChange={(value) => onRepositoryChange(value as string | 'all')}
disabled={repositories.length === 0}
>
<SelectTrigger className="w-full">
<SelectValue
placeholder={
repositoriesLoading
? 'Loading repositories...'
: repositories.length === 0
? 'No repositories'
: 'Select repository'
}
/>
</SelectTrigger>
<SelectContent>
<SelectItem value="all">All repositories</SelectItem>
{repositories.map((repo: Repository) => (
<SelectItem key={repo.id} value={repo.id}>
{repo.name}
</SelectItem>
))}
</SelectContent>
</Select>
</div>
<DropdownMenuSeparator />
<div className="space-y-1.5">
<DropdownMenuLabel className="px-0">Preview Panel</DropdownMenuLabel>
<label className="flex items-center gap-2 cursor-pointer">
<Checkbox
checked={enablePreviewOnClick ?? false}
onCheckedChange={(checked) => {
onTogglePreviewOnClick?.(!!checked);
}}
/>
<span className="text-sm">Open preview on click</span>
</label>
<p className="text-xs text-muted-foreground pl-6">
When enabled, clicking a task opens the preview panel. When disabled, clicking navigates directly to the session.
</p>
</div>
</div>
</DropdownMenuContent>
</DropdownMenu>
);
}