From b5605d93da6c1e37ba9b3f31f49238d2326d047d Mon Sep 17 00:00:00 2001 From: kjs Date: Tue, 28 Oct 2025 16:26:55 +0900 Subject: [PATCH] =?UTF-8?q?=ED=85=8C=EC=9D=B4=EB=B8=94=20=EC=BB=AC?= =?UTF-8?q?=EB=9F=BC=20=EA=B2=80=EC=83=89=20=EA=B8=B0=EB=8A=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../screen/panels/ComponentsPanel.tsx | 51 ++-- .../components/screen/panels/TablesPanel.tsx | 221 ++++++------------ 2 files changed, 109 insertions(+), 163 deletions(-) diff --git a/frontend/components/screen/panels/ComponentsPanel.tsx b/frontend/components/screen/panels/ComponentsPanel.tsx index 893bef5f..991ace3b 100644 --- a/frontend/components/screen/panels/ComponentsPanel.tsx +++ b/frontend/components/screen/panels/ComponentsPanel.tsx @@ -162,14 +162,21 @@ export function ComponentsPanel({

{allComponents.length}개 사용 가능

- {/* 검색 */} + {/* 통합 검색 */}
setSearchQuery(e.target.value)} + onChange={(e) => { + const value = e.target.value; + setSearchQuery(value); + // 테이블 검색도 함께 업데이트 + if (onSearchChange) { + onSearchChange(value); + } + }} className="h-8 pl-8 text-xs" />
@@ -177,26 +184,42 @@ export function ComponentsPanel({ {/* 카테고리 탭 */} - - + + - 테이블 + 테이블 - + - 입력 + 입력 - + - 액션 + 액션 - + - 표시 + 표시 - + - 레이아웃 + 레이아웃 diff --git a/frontend/components/screen/panels/TablesPanel.tsx b/frontend/components/screen/panels/TablesPanel.tsx index f75b699e..abeff8d6 100644 --- a/frontend/components/screen/panels/TablesPanel.tsx +++ b/frontend/components/screen/panels/TablesPanel.tsx @@ -1,23 +1,8 @@ "use client"; -import React, { useState } from "react"; -import { Button } from "@/components/ui/button"; +import React from "react"; import { Badge } from "@/components/ui/badge"; -import { - Database, - ChevronDown, - ChevronRight, - Type, - Hash, - Calendar, - CheckSquare, - List, - AlignLeft, - Code, - Building, - File, - Search, -} from "lucide-react"; +import { Database, Type, Hash, Calendar, CheckSquare, List, AlignLeft, Code, Building, File } from "lucide-react"; import { TableInfo, WebType } from "@/types/screen"; interface TablesPanelProps { @@ -65,23 +50,9 @@ const getWidgetIcon = (widgetType: WebType) => { export const TablesPanel: React.FC = ({ tables, searchTerm, - onSearchChange, onDragStart, - selectedTableName, placedColumns = new Set(), }) => { - const [expandedTables, setExpandedTables] = useState>(new Set()); - - const toggleTable = (tableName: string) => { - const newExpanded = new Set(expandedTables); - if (newExpanded.has(tableName)) { - newExpanded.delete(tableName); - } else { - newExpanded.add(tableName); - } - setExpandedTables(newExpanded); - }; - // 이미 배치된 컬럼을 제외한 테이블 정보 생성 const tablesWithAvailableColumns = tables.map((table) => ({ ...table, @@ -91,137 +62,89 @@ export const TablesPanel: React.FC = ({ }), })); + // 검색어가 있으면 컬럼 필터링 const filteredTables = tablesWithAvailableColumns - .filter((table) => table.columns.length > 0) // 사용 가능한 컬럼이 있는 테이블만 표시 - .filter( - (table) => - table.tableName.toLowerCase().includes(searchTerm.toLowerCase()) || - table.columns.some((col) => col.columnName.toLowerCase().includes(searchTerm.toLowerCase())), - ); + .map((table) => { + if (!searchTerm) { + return table; + } + + const searchLower = searchTerm.toLowerCase(); + + // 테이블명이 검색어와 일치하면 모든 컬럼 표시 + if ( + table.tableName.toLowerCase().includes(searchLower) || + (table.tableLabel && table.tableLabel.toLowerCase().includes(searchLower)) + ) { + return table; + } + + // 그렇지 않으면 컬럼명/라벨이 검색어와 일치하는 컬럼만 필터링 + const filteredColumns = table.columns.filter( + (col) => + col.columnName.toLowerCase().includes(searchLower) || + (col.columnLabel && col.columnLabel.toLowerCase().includes(searchLower)), + ); + + return { + ...table, + columns: filteredColumns, + }; + }) + .filter((table) => table.columns.length > 0); // 컬럼이 있는 테이블만 표시 return (
- {/* 헤더 */} -
- {selectedTableName && ( -
-
선택된 테이블
-
- - {selectedTableName} -
-
- )} - - {/* 검색 */} -
- - onSearchChange(e.target.value)} - className="border-input bg-background focus-visible:ring-ring h-8 w-full rounded-md border px-3 pl-8 text-xs focus-visible:ring-1 focus-visible:outline-none" - /> -
- -
총 {filteredTables.length}개
-
- - {/* 테이블 목록 */} -
-
- {filteredTables.map((table) => { - const isExpanded = expandedTables.has(table.tableName); - - return ( -
- {/* 테이블 헤더 */} -
toggleTable(table.tableName)} - > -
- {isExpanded ? ( - - ) : ( - - )} - -
-
{table.tableLabel || table.tableName}
-
{table.columns.length}개
-
-
- - + {/* 테이블과 컬럼 평면 목록 */} +
+
+ {filteredTables.map((table) => ( +
+ {/* 테이블 헤더 */} +
+
+ + {table.tableLabel || table.tableName} + + {table.columns.length}개 +
+
- {/* 컬럼 목록 */} - {isExpanded && ( -
-
8 ? "max-h-64 overflow-y-auto" : ""}`}> - {table.columns.map((column, index) => ( -
onDragStart(e, table, column)} - > -
- {getWidgetIcon(column.widgetType)} -
-
- {column.columnLabel || column.columnName} -
-
{column.dataType}
-
-
+ {/* 컬럼 목록 (항상 표시) */} +
+ {table.columns.map((column) => ( +
onDragStart(e, table, column)} + > +
+ {getWidgetIcon(column.widgetType)} +
+
{column.columnLabel || column.columnName}
+
{column.dataType}
+
+
-
- - {column.widgetType} - - {column.required && ( - - 필수 - - )} -
-
- ))} - - {/* 컬럼 수가 많을 때 안내 메시지 */} - {table.columns.length > 8 && ( -
-
- 📜 총 {table.columns.length}개 컬럼 (스크롤하여 더 보기) -
-
+
+ + {column.widgetType} + + {column.required && ( + + 필수 + )}
- )} + ))}
- ); - })} +
+ ))}
- - {/* 푸터 */} -
-
💡 테이블이나 컬럼을 캔버스로 드래그하세요
-
); };