ERP-node/frontend/lib/registry/components/table-search-widget/TableSearchWidget.tsx

162 lines
5.4 KiB
TypeScript
Raw Normal View History

"use client";
import React, { useState, useEffect } from "react";
import { Button } from "@/components/ui/button";
import { Settings, Filter, Layers } from "lucide-react";
import { useTableOptions } from "@/contexts/TableOptionsContext";
import { ColumnVisibilityPanel } from "@/components/screen/table-options/ColumnVisibilityPanel";
import { FilterPanel } from "@/components/screen/table-options/FilterPanel";
import { GroupingPanel } from "@/components/screen/table-options/GroupingPanel";
import {
Select,
SelectContent,
SelectItem,
SelectTrigger,
SelectValue,
} from "@/components/ui/select";
interface TableSearchWidgetProps {
component: {
id: string;
title?: string;
style?: {
width?: string;
height?: string;
padding?: string;
backgroundColor?: string;
};
componentConfig?: {
autoSelectFirstTable?: boolean; // 첫 번째 테이블 자동 선택 여부
showTableSelector?: boolean; // 테이블 선택 드롭다운 표시 여부
};
};
}
export function TableSearchWidget({ component }: TableSearchWidgetProps) {
const { registeredTables, selectedTableId, setSelectedTableId } = useTableOptions();
const [columnVisibilityOpen, setColumnVisibilityOpen] = useState(false);
const [filterOpen, setFilterOpen] = useState(false);
const [groupingOpen, setGroupingOpen] = useState(false);
const autoSelectFirstTable = component.componentConfig?.autoSelectFirstTable ?? true;
const showTableSelector = component.componentConfig?.showTableSelector ?? true;
// Map을 배열로 변환
const tableList = Array.from(registeredTables.values());
// 첫 번째 테이블 자동 선택
useEffect(() => {
const tables = Array.from(registeredTables.values());
if (autoSelectFirstTable && tables.length > 0 && !selectedTableId) {
setSelectedTableId(tables[0].tableId);
}
}, [registeredTables, selectedTableId, autoSelectFirstTable, setSelectedTableId]);
const hasMultipleTables = tableList.length > 1;
return (
<div
className="flex h-full w-full items-center justify-between gap-2 border-b bg-card"
style={{
padding: component.style?.padding || "0.75rem",
backgroundColor: component.style?.backgroundColor,
}}
>
{/* 왼쪽: 제목 + 테이블 정보 */}
<div className="flex items-center gap-3">
{/* 제목 */}
{component.title && (
<div className="text-sm font-medium text-foreground">
{component.title}
</div>
)}
{/* 테이블 선택 드롭다운 (여러 테이블이 있고, showTableSelector가 true일 때만) */}
{showTableSelector && hasMultipleTables && (
<Select value={selectedTableId || ""} onValueChange={setSelectedTableId}>
<SelectTrigger className="h-8 w-[200px] text-xs sm:h-9 sm:text-sm">
<SelectValue placeholder="테이블 선택" />
</SelectTrigger>
<SelectContent>
{tableList.map((table) => (
<SelectItem key={table.tableId} value={table.tableId} className="text-xs sm:text-sm">
{table.label}
</SelectItem>
))}
</SelectContent>
</Select>
)}
{/* 테이블이 하나만 있을 때는 라벨만 표시 */}
{!hasMultipleTables && tableList.length === 1 && (
<div className="text-xs text-muted-foreground sm:text-sm">
{tableList[0].label}
</div>
)}
{/* 테이블이 없을 때 */}
{tableList.length === 0 && (
<div className="text-xs text-muted-foreground sm:text-sm">
</div>
)}
</div>
{/* 오른쪽: 버튼들 */}
<div className="flex items-center gap-2 flex-shrink-0">
<Button
variant="outline"
size="sm"
onClick={() => {
console.log("🔘 [TableSearchWidget] 테이블 옵션 버튼 클릭");
setColumnVisibilityOpen(true);
}}
disabled={!selectedTableId}
className="h-8 text-xs sm:h-9 sm:text-sm"
>
<Settings className="mr-1 h-3 w-3 sm:h-4 sm:w-4" />
</Button>
<Button
variant="outline"
size="sm"
onClick={() => {
console.log("🔘 [TableSearchWidget] 필터 설정 버튼 클릭");
setFilterOpen(true);
}}
disabled={!selectedTableId}
className="h-8 text-xs sm:h-9 sm:text-sm"
>
<Filter className="mr-1 h-3 w-3 sm:h-4 sm:w-4" />
</Button>
<Button
variant="outline"
size="sm"
onClick={() => {
console.log("🔘 [TableSearchWidget] 그룹 설정 버튼 클릭");
setGroupingOpen(true);
}}
disabled={!selectedTableId}
className="h-8 text-xs sm:h-9 sm:text-sm"
>
<Layers className="mr-1 h-3 w-3 sm:h-4 sm:w-4" />
</Button>
</div>
{/* 패널들 */}
<ColumnVisibilityPanel
isOpen={columnVisibilityOpen}
onClose={() => setColumnVisibilityOpen(false)}
/>
<FilterPanel isOpen={filterOpen} onClose={() => setFilterOpen(false)} />
<GroupingPanel isOpen={groupingOpen} onClose={() => setGroupingOpen(false)} />
</div>
);
}