- Refactored the handling of "in" and "not_in" operators to ensure proper array handling and prevent errors when values are not provided. - Enhanced the InteractiveDataTable component to re-fetch data when filters are applied, improving user experience. - Updated DataFilterConfigPanel to correctly manage filter values based on selected operators. - Adjusted SplitPanelLayoutComponent to apply client-side data filtering based on defined conditions. These changes aim to improve the robustness and usability of the data filtering features across the application.
126 lines
3.6 KiB
TypeScript
126 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
|
|
isOpen={filterPanelOpen}
|
|
onClose={() => setFilterPanelOpen(false)}
|
|
/>
|
|
<GroupingPanel
|
|
tableId={selectedTableId}
|
|
open={groupPanelOpen}
|
|
onOpenChange={setGroupPanelOpen}
|
|
/>
|
|
</>
|
|
)}
|
|
</div>
|
|
);
|
|
};
|
|
|