feat(WEB): 테이블 컬럼 표시/숨김 설정 기능 추가

- useColumnSettings 훅: 컬럼 가시성 토글 로직
- useTableColumnStore: Zustand 기반 컬럼 설정 영속화 (localStorage)
- ColumnSettingsPopover: 컬럼 설정 UI 컴포넌트
- UniversalListPage/IntegratedListTemplateV2에 컬럼 설정 통합

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
유병철
2026-02-20 18:09:17 +09:00
parent 30ca2afca8
commit ceeeeb1ef4
6 changed files with 353 additions and 6 deletions

View File

@@ -0,0 +1,73 @@
'use client';
import { Settings2, RotateCcw } from 'lucide-react';
import { Button } from '@/components/ui/button';
import { Checkbox } from '@/components/ui/checkbox';
import {
Popover,
PopoverContent,
PopoverTrigger,
} from '@/components/ui/popover';
import type { ColumnWithVisibility } from '@/hooks/useColumnSettings';
interface ColumnSettingsPopoverProps {
columns: ColumnWithVisibility[];
onToggle: (key: string) => void;
onReset: () => void;
hasHiddenColumns: boolean;
}
export function ColumnSettingsPopover({
columns,
onToggle,
onReset,
hasHiddenColumns,
}: ColumnSettingsPopoverProps) {
return (
<Popover>
<PopoverTrigger asChild>
<Button variant="outline" size="sm" className="relative h-8 px-2">
<Settings2 className="h-4 w-4" />
<span className="hidden sm:inline ml-1"></span>
{hasHiddenColumns && (
<span className="absolute -top-1 -right-1 h-2 w-2 rounded-full bg-blue-500" />
)}
</Button>
</PopoverTrigger>
<PopoverContent align="end" className="w-56 p-3">
<div className="flex items-center justify-between mb-2">
<span className="text-sm font-medium"> </span>
<Button
variant="ghost"
size="sm"
className="h-7 px-2 text-xs"
onClick={onReset}
>
<RotateCcw className="h-3 w-3 mr-1" />
</Button>
</div>
<div className="space-y-1 max-h-[300px] overflow-y-auto">
{columns.map((col) => (
<label
key={col.key}
className={`flex items-center gap-2 px-2 py-1.5 rounded text-sm cursor-pointer hover:bg-muted/50 ${
col.locked ? 'opacity-50 cursor-not-allowed' : ''
}`}
>
<Checkbox
checked={col.visible}
onCheckedChange={() => onToggle(col.key)}
disabled={col.locked}
/>
<span>{col.label}</span>
{col.locked && (
<span className="text-xs text-muted-foreground ml-auto"></span>
)}
</label>
))}
</div>
</PopoverContent>
</Popover>
);
}