From 126da9b46f481f6a4650965c1d91d6977252b2ef Mon Sep 17 00:00:00 2001 From: leeheejin Date: Wed, 7 Jan 2026 09:37:02 +0900 Subject: [PATCH] =?UTF-8?q?=ED=95=98=EC=9D=B4=ED=81=90=EB=A7=88=EA=B7=B8?= =?UTF-8?q?=20=EC=A0=90=EA=B2=80=ED=95=AD=EB=AA=A9=20=EC=B6=94=EA=B0=80=20?= =?UTF-8?q?=ED=9B=84=20=EC=A3=BC=EA=B8=B0=EB=AA=85/=EC=A0=90=EA=B2=80?= =?UTF-8?q?=EB=B0=A9=EB=B2=95=EB=AA=85=20=EC=98=A4=EB=A5=98=20=ED=95=B4?= =?UTF-8?q?=EA=B2=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../table-list/TableListComponent.tsx | 68 ++++++++++++++++++- 1 file changed, 66 insertions(+), 2 deletions(-) diff --git a/frontend/lib/registry/components/table-list/TableListComponent.tsx b/frontend/lib/registry/components/table-list/TableListComponent.tsx index 389dd92d..74cea859 100644 --- a/frontend/lib/registry/components/table-list/TableListComponent.tsx +++ b/frontend/lib/registry/components/table-list/TableListComponent.tsx @@ -2392,6 +2392,44 @@ export const TableListComponent: React.FC = ({ fetchLabels(); }, [columnUniqueValues, categoryLabelCache]); + // 🆕 데이터에서 CATEGORY_ 코드를 찾아 라벨 미리 로드 (테이블 셀 렌더링용) + useEffect(() => { + if (data.length === 0) return; + + const categoryCodesToFetch = new Set(); + + // 모든 데이터 행에서 CATEGORY_ 코드 수집 + data.forEach((row) => { + Object.entries(row).forEach(([key, value]) => { + if (value && typeof value === "string") { + // 콤마로 구분된 다중 값도 처리 + const codes = value.split(",").map((v) => v.trim()); + codes.forEach((code) => { + if (code.startsWith("CATEGORY_") && !categoryLabelCache[code]) { + categoryCodesToFetch.add(code); + } + }); + } + }); + }); + + if (categoryCodesToFetch.size === 0) return; + + // API로 라벨 조회 + const fetchLabels = async () => { + try { + const response = await getCategoryLabelsByCodes(Array.from(categoryCodesToFetch)); + if (response.success && response.data && Object.keys(response.data).length > 0) { + setCategoryLabelCache((prev) => ({ ...prev, ...response.data })); + } + } catch (error) { + console.error("CATEGORY_ 라벨 조회 실패:", error); + } + }; + + fetchLabels(); + }, [data, categoryLabelCache]); + // 🆕 헤더 필터 토글 const toggleHeaderFilter = useCallback((columnName: string, value: string) => { setHeaderFilters((prev) => { @@ -4548,10 +4586,36 @@ export const TableListComponent: React.FC = ({ case "boolean": return value ? "예" : "아니오"; default: - return String(value); + // 🆕 CATEGORY_ 코드 자동 변환 (inputType이 category가 아니어도) + const strValue = String(value); + if (strValue.startsWith("CATEGORY_")) { + // rowData에서 _label 필드 찾기 + if (rowData) { + const labelFieldCandidates = [ + `${column.columnName}_label`, + `${column.columnName}_name`, + `${column.columnName}_value_label`, + ]; + for (const labelField of labelFieldCandidates) { + if (rowData[labelField] && rowData[labelField] !== "") { + return String(rowData[labelField]); + } + } + } + // categoryMappings에서 찾기 + const mapping = categoryMappings[column.columnName]; + if (mapping && mapping[strValue]) { + return mapping[strValue].label; + } + // categoryLabelCache에서 찾기 (필터용 캐시) + if (categoryLabelCache[strValue]) { + return categoryLabelCache[strValue]; + } + } + return strValue; } }, - [columnMeta, joinedColumnMeta, optimizedConvertCode, categoryMappings], + [columnMeta, joinedColumnMeta, optimizedConvertCode, categoryMappings, categoryLabelCache], ); // ========================================