127 lines
3.6 KiB
TypeScript
127 lines
3.6 KiB
TypeScript
import React, { useState } from "react";
|
|
import { useTableOptions } from "@/contexts/TableOptionsContext";
|
|
import { Button } from "@/components/ui/button";
|
|
import {
|
|
Select,
|
|
SelectContent,
|
|
SelectItem,
|
|
SelectTrigger,
|
|
SelectValue,
|
|
} from "@/components/ui/select";
|
|
import { Settings, Filter, Layers } from "lucide-react";
|
|
import { ColumnVisibilityPanel } from "./ColumnVisibilityPanel";
|
|
import { FilterPanel } from "./FilterPanel";
|
|
import { GroupingPanel } from "./GroupingPanel";
|
|
|
|
export const TableOptionsToolbar: React.FC = () => {
|
|
const { registeredTables, selectedTableId, setSelectedTableId } =
|
|
useTableOptions();
|
|
|
|
const [columnPanelOpen, setColumnPanelOpen] = useState(false);
|
|
const [filterPanelOpen, setFilterPanelOpen] = useState(false);
|
|
const [groupPanelOpen, setGroupPanelOpen] = useState(false);
|
|
|
|
const tableList = Array.from(registeredTables.values());
|
|
const selectedTable = selectedTableId
|
|
? registeredTables.get(selectedTableId)
|
|
: null;
|
|
|
|
// 테이블이 없으면 표시하지 않음
|
|
if (tableList.length === 0) {
|
|
return null;
|
|
}
|
|
|
|
return (
|
|
<div className="flex items-center gap-2 border-b bg-background p-2">
|
|
{/* 테이블 선택 (2개 이상일 때만 표시) */}
|
|
{tableList.length > 1 && (
|
|
<Select
|
|
value={selectedTableId || ""}
|
|
onValueChange={setSelectedTableId}
|
|
>
|
|
<SelectTrigger className="h-8 w-48 text-xs sm:h-9 sm:w-64 sm:text-sm">
|
|
<SelectValue placeholder="테이블 선택" />
|
|
</SelectTrigger>
|
|
<SelectContent>
|
|
{tableList.map((table) => (
|
|
<SelectItem key={table.tableId} value={table.tableId}>
|
|
{table.label}
|
|
</SelectItem>
|
|
))}
|
|
</SelectContent>
|
|
</Select>
|
|
)}
|
|
|
|
{/* 테이블이 1개일 때는 이름만 표시 */}
|
|
{tableList.length === 1 && (
|
|
<div className="text-xs font-medium sm:text-sm">
|
|
{tableList[0].label}
|
|
</div>
|
|
)}
|
|
|
|
{/* 컬럼 수 표시 */}
|
|
<div className="text-xs text-muted-foreground sm:text-sm">
|
|
전체 {selectedTable?.columns.length || 0}개
|
|
</div>
|
|
|
|
<div className="flex-1" />
|
|
|
|
{/* 옵션 버튼들 */}
|
|
<Button
|
|
variant="outline"
|
|
size="sm"
|
|
onClick={() => setColumnPanelOpen(true)}
|
|
className="h-8 text-xs sm:h-9 sm:text-sm"
|
|
disabled={!selectedTableId}
|
|
>
|
|
<Settings className="mr-2 h-4 w-4" />
|
|
테이블 옵션
|
|
</Button>
|
|
|
|
<Button
|
|
variant="outline"
|
|
size="sm"
|
|
onClick={() => setFilterPanelOpen(true)}
|
|
className="h-8 text-xs sm:h-9 sm:text-sm"
|
|
disabled={!selectedTableId}
|
|
>
|
|
<Filter className="mr-2 h-4 w-4" />
|
|
필터 설정
|
|
</Button>
|
|
|
|
<Button
|
|
variant="outline"
|
|
size="sm"
|
|
onClick={() => setGroupPanelOpen(true)}
|
|
className="h-8 text-xs sm:h-9 sm:text-sm"
|
|
disabled={!selectedTableId}
|
|
>
|
|
<Layers className="mr-2 h-4 w-4" />
|
|
그룹 설정
|
|
</Button>
|
|
|
|
{/* 패널들 */}
|
|
{selectedTableId && (
|
|
<>
|
|
<ColumnVisibilityPanel
|
|
tableId={selectedTableId}
|
|
open={columnPanelOpen}
|
|
onOpenChange={setColumnPanelOpen}
|
|
/>
|
|
<FilterPanel
|
|
tableId={selectedTableId}
|
|
open={filterPanelOpen}
|
|
onOpenChange={setFilterPanelOpen}
|
|
/>
|
|
<GroupingPanel
|
|
tableId={selectedTableId}
|
|
open={groupPanelOpen}
|
|
onOpenChange={setGroupPanelOpen}
|
|
/>
|
|
</>
|
|
)}
|
|
</div>
|
|
);
|
|
};
|
|
|