From 3fe876cd7606cedf9bcb276ecd365c8b750a26ff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EB=B3=B4=EA=B3=A4?= Date: Thu, 19 Mar 2026 07:55:45 +0900 Subject: [PATCH] =?UTF-8?q?feat:=20[item-master]=20=ED=95=AD=EB=AA=A9=20?= =?UTF-8?q?=ED=83=AD=20=EA=B2=80=EC=83=89=20=EA=B8=B0=EB=8A=A5=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 항목명, 입력타입, 카테고리, 설명, ID로 실시간 필터링 - 검색 결과 건수 표시 및 초기화 버튼 --- .../tabs/MasterFieldTab/index.tsx | 50 ++++++++++++++++++- 1 file changed, 48 insertions(+), 2 deletions(-) diff --git a/src/components/items/ItemMasterDataManagement/tabs/MasterFieldTab/index.tsx b/src/components/items/ItemMasterDataManagement/tabs/MasterFieldTab/index.tsx index 8889fc5f..cad851c1 100644 --- a/src/components/items/ItemMasterDataManagement/tabs/MasterFieldTab/index.tsx +++ b/src/components/items/ItemMasterDataManagement/tabs/MasterFieldTab/index.tsx @@ -6,12 +6,14 @@ * - item_fields WHERE section_id IS NULL로 통합 * - 향후 FieldTab으로 리네임 예정 */ +import { useState, useMemo } from 'react'; import type { ItemMasterField } from '@/contexts/ItemMasterContext'; import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card'; import { Button } from '@/components/ui/button'; import { Badge } from '@/components/ui/badge'; +import { Input } from '@/components/ui/input'; import { getPresetStyle } from '@/lib/utils/status-config'; -import { Plus, Edit, Trash2 } from 'lucide-react'; +import { Plus, Edit, Trash2, Search, X } from 'lucide-react'; // 입력방식 옵션 (ItemMasterDataManagement에서 사용하는 상수) const INPUT_TYPE_OPTIONS = [ @@ -50,6 +52,21 @@ export function MasterFieldTab({ hasUnsavedChanges: _hasUnsavedChanges, pendingChanges: _pendingChanges }: MasterFieldTabProps) { + const [searchQuery, setSearchQuery] = useState(''); + + const filteredFields = useMemo(() => { + if (!searchQuery.trim()) return itemMasterFields; + const query = searchQuery.trim().toLowerCase(); + return itemMasterFields.filter(field => { + const fieldName = field.field_name?.toLowerCase() || ''; + const fieldType = INPUT_TYPE_OPTIONS.find(t => t.value === field.field_type)?.label?.toLowerCase() || ''; + const category = field.category?.toLowerCase() || ''; + const description = field.description?.toLowerCase() || ''; + const fieldId = String(field.id); + return fieldName.includes(query) || fieldType.includes(query) || category.includes(query) || description.includes(query) || fieldId.includes(query); + }); + }, [itemMasterFields, searchQuery]); + return ( @@ -70,6 +87,25 @@ export function MasterFieldTab({ 항목 추가 + {itemMasterFields.length > 0 && ( +
+ + setSearchQuery(e.target.value)} + className="pl-9 pr-9" + /> + {searchQuery && ( + + )} +
+ )}
{itemMasterFields.length === 0 ? ( @@ -81,7 +117,17 @@ export function MasterFieldTab({ ) : (
- {itemMasterFields.map((field, index) => ( + {searchQuery && ( +

+ {filteredFields.length}건 검색됨 (전체 {itemMasterFields.length}건) +

+ )} + {filteredFields.length === 0 && searchQuery ? ( +
+

"{searchQuery}"에 대한 검색 결과가 없습니다

+
+ ) : null} + {filteredFields.map((field, index) => (