From bb49073bf7be47f665de13cb8b16731c11bf0ebb Mon Sep 17 00:00:00 2001 From: kjs Date: Fri, 21 Nov 2025 10:03:26 +0900 Subject: [PATCH] =?UTF-8?q?feat:=20=ED=85=8C=EC=9D=B4=EB=B8=94=20=EB=A6=AC?= =?UTF-8?q?=EC=8A=A4=ED=8A=B8=EC=97=90=EC=84=9C=20=EC=B9=B4=ED=85=8C?= =?UTF-8?q?=EA=B3=A0=EB=A6=AC=20=EB=8B=A4=EC=A4=91=20=EA=B0=92=20=EB=B0=B0?= =?UTF-8?q?=EC=A7=80=20=ED=91=9C=EC=8B=9C=20=EC=A7=80=EC=9B=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 문제: - 테이블에서 'CATEGORY_218152,CATEGORY_205381' 같은 다중 값이 - 배지로 표시되지 않고 코드값 그대로 보임 원인: - formatCellValue의 카테고리 렌더링이 단일 값만 처리 - 콤마로 구분된 다중 값 파싱 로직 없음 해결: 1. 콤마 구분자 감지 및 값 배열로 분리 2. 단일 값: 기존 로직 유지 (단일 배지) 3. 다중 값: flex-wrap gap-1로 여러 배지 렌더링 4. 각 배지는 매핑된 라벨과 색상 사용 결과: ✅ 다중선택 저장된 데이터가 테이블에서 여러 배지로 표시됨 ✅ 각 배지에 올바른 색상과 라벨 적용 ✅ 단일 값도 기존처럼 정상 작동 --- .../select-basic/SelectBasicComponent.tsx | 39 ++++++++-- .../table-list/TableListComponent.tsx | 76 ++++++++++++++----- 2 files changed, 90 insertions(+), 25 deletions(-) diff --git a/frontend/lib/registry/components/select-basic/SelectBasicComponent.tsx b/frontend/lib/registry/components/select-basic/SelectBasicComponent.tsx index 5915a58c..7e12dda9 100644 --- a/frontend/lib/registry/components/select-basic/SelectBasicComponent.tsx +++ b/frontend/lib/registry/components/select-basic/SelectBasicComponent.tsx @@ -207,14 +207,39 @@ const SelectBasicComponent: React.FC = ({ // 외부 value prop 변경 시 selectedValue 업데이트 useEffect(() => { const newValue = externalValue || config?.value || ""; - // 값이 실제로 다른 경우에만 업데이트 (빈 문자열도 유효한 값으로 처리) - if (newValue !== selectedValue) { - setSelectedValue(newValue); - - // 다중선택 모드인 경우 selectedValues도 업데이트 - if (isMultiple && typeof newValue === "string" && newValue) { + + console.log("🔍 [SelectBasic] 외부 값 변경 감지:", { + componentId: component.id, + columnName: (component as any).columnName, + isMultiple, + newValue, + selectedValue, + selectedValues, + externalValue, + "config.value": config?.value, + }); + + // 다중선택 모드인 경우 + if (isMultiple) { + if (typeof newValue === "string" && newValue) { const values = newValue.split(",").map(v => v.trim()).filter(v => v); - setSelectedValues(values); + const currentValuesStr = selectedValues.join(","); + + if (newValue !== currentValuesStr) { + console.log("✅ [SelectBasic] 다중선택 값 업데이트:", { + from: selectedValues, + to: values, + }); + setSelectedValues(values); + } + } else if (!newValue && selectedValues.length > 0) { + console.log("✅ [SelectBasic] 다중선택 값 초기화"); + setSelectedValues([]); + } + } else { + // 단일선택 모드인 경우 + if (newValue !== selectedValue) { + setSelectedValue(newValue); } } }, [externalValue, config?.value, isMultiple]); diff --git a/frontend/lib/registry/components/table-list/TableListComponent.tsx b/frontend/lib/registry/components/table-list/TableListComponent.tsx index 4a6aec26..12bdb7d1 100644 --- a/frontend/lib/registry/components/table-list/TableListComponent.tsx +++ b/frontend/lib/registry/components/table-list/TableListComponent.tsx @@ -1425,33 +1425,73 @@ export const TableListComponent: React.FC = ({ ); } - // 카테고리 타입: 배지로 표시 (배지 없음 옵션 지원) + // 카테고리 타입: 배지로 표시 (배지 없음 옵션 지원, 다중 값 지원) if (inputType === "category") { if (!value) return ""; const mapping = categoryMappings[column.columnName]; - const categoryData = mapping?.[String(value)]; + const { Badge } = require("@/components/ui/badge"); - // 매핑 데이터가 있으면 라벨과 색상 사용, 없으면 코드값과 기본색상 - const displayLabel = categoryData?.label || String(value); - const displayColor = categoryData?.color || "#64748b"; // 기본 slate 색상 + // 다중 값 처리: 콤마로 구분된 값들을 분리 + const valueStr = String(value); + const values = valueStr.includes(",") + ? valueStr.split(",").map(v => v.trim()).filter(v => v) + : [valueStr]; - // 배지 없음 옵션: color가 "none"이면 텍스트만 표시 - if (displayColor === "none") { - return {displayLabel}; + // 단일 값인 경우 (기존 로직) + if (values.length === 1) { + const categoryData = mapping?.[values[0]]; + const displayLabel = categoryData?.label || values[0]; + const displayColor = categoryData?.color || "#64748b"; + + if (displayColor === "none") { + return {displayLabel}; + } + + return ( + + {displayLabel} + + ); } - const { Badge } = require("@/components/ui/badge"); + // 다중 값인 경우: 여러 배지 렌더링 return ( - - {displayLabel} - +
+ {values.map((val, idx) => { + const categoryData = mapping?.[val]; + const displayLabel = categoryData?.label || val; + const displayColor = categoryData?.color || "#64748b"; + + if (displayColor === "none") { + return ( + + {displayLabel} + {idx < values.length - 1 && ", "} + + ); + } + + return ( + + {displayLabel} + + ); + })} +
); }