From 8fdf57bedd891b6f545ab938d3163f878bfbcddc Mon Sep 17 00:00:00 2001 From: SeongHyun Kim Date: Tue, 25 Nov 2025 16:56:50 +0900 Subject: [PATCH] =?UTF-8?q?chore:=20=EA=B3=BC=EB=8F=84=ED=95=9C=20?= =?UTF-8?q?=EC=BD=98=EC=86=94=20=EB=A1=9C=EA=B7=B8=20=EC=A0=95=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - ModalRepeaterTableComponent: 반복 렌더링 로그 제거 - TableListComponent: 렌더링 조건 체크 IIFE 단순화 - ConditionalContainerComponent: 디버깅 로그 삭제 - DynamicComponentRenderer: value 설정 로그 제거 - resizable-dialog: userStyle 상세 로그 정리 - page.tsx: 반복 데이터 탐색 로그 삭제 에러 핸들링 및 주요 분기점 로그만 보존 --- .../app/(main)/screens/[screenId]/page.tsx | 46 +------------ frontend/components/ui/resizable-dialog.tsx | 22 ------- .../lib/registry/DynamicComponentRenderer.tsx | 11 +--- .../ConditionalContainerComponent.tsx | 23 ------- .../ModalRepeaterTableComponent.tsx | 65 +++---------------- .../table-list/TableListComponent.tsx | 16 +---- 6 files changed, 14 insertions(+), 169 deletions(-) diff --git a/frontend/app/(main)/screens/[screenId]/page.tsx b/frontend/app/(main)/screens/[screenId]/page.tsx index ce99a685..5685d23a 100644 --- a/frontend/app/(main)/screens/[screenId]/page.tsx +++ b/frontend/app/(main)/screens/[screenId]/page.tsx @@ -356,17 +356,6 @@ function ScreenViewPage() { return isButton; }); - console.log( - "🔍 메뉴에서 발견된 전체 버튼:", - allButtons.map((b) => ({ - id: b.id, - label: b.label, - positionX: b.position.x, - positionY: b.position.y, - width: b.size?.width, - height: b.size?.height, - })), - ); topLevelComponents.forEach((component) => { const isButton = @@ -406,33 +395,13 @@ function ScreenViewPage() { (c) => (c as any).componentId === "table-search-widget", ); - // 디버그: 모든 컴포넌트 타입 확인 - console.log( - "🔍 전체 컴포넌트 타입:", - regularComponents.map((c) => ({ - id: c.id, - type: c.type, - componentType: (c as any).componentType, - componentId: (c as any).componentId, - })), - ); - - // 🆕 조건부 컨테이너들을 찾기 + // 조건부 컨테이너들을 찾기 const conditionalContainers = regularComponents.filter( (c) => (c as any).componentId === "conditional-container" || (c as any).componentType === "conditional-container", ); - console.log( - "🔍 조건부 컨테이너 발견:", - conditionalContainers.map((c) => ({ - id: c.id, - y: c.position.y, - size: c.size, - })), - ); - // TableSearchWidget 및 조건부 컨테이너 높이 차이를 계산하여 Y 위치 조정 const adjustedComponents = regularComponents.map((component) => { const isTableSearchWidget = (component as any).componentId === "table-search-widget"; @@ -520,12 +489,6 @@ function ScreenViewPage() { columnOrder={tableColumnOrder} tableDisplayData={tableDisplayData} onSelectedRowsChange={(_, selectedData, sortBy, sortOrder, columnOrder, tableDisplayData) => { - console.log("🔍 화면에서 선택된 행 데이터:", selectedData); - console.log("📊 정렬 정보:", { sortBy, sortOrder, columnOrder }); - console.log("📊 화면 표시 데이터:", { - count: tableDisplayData?.length, - firstRow: tableDisplayData?.[0], - }); setSelectedRowsData(selectedData); setTableSortBy(sortBy); setTableSortOrder(sortOrder || "asc"); @@ -604,12 +567,6 @@ function ScreenViewPage() { columnOrder, tableDisplayData, ) => { - console.log("🔍 화면에서 선택된 행 데이터 (자식):", selectedData); - console.log("📊 정렬 정보 (자식):", { sortBy, sortOrder, columnOrder }); - console.log("📊 화면 표시 데이터 (자식):", { - count: tableDisplayData?.length, - firstRow: tableDisplayData?.[0], - }); setSelectedRowsData(selectedData); setTableSortBy(sortBy); setTableSortOrder(sortOrder || "asc"); @@ -618,7 +575,6 @@ function ScreenViewPage() { }} refreshKey={tableRefreshKey} onRefresh={() => { - console.log("🔄 테이블 새로고침 요청됨 (자식)"); setTableRefreshKey((prev) => prev + 1); setSelectedRowsData([]); // 선택 해제 }} diff --git a/frontend/components/ui/resizable-dialog.tsx b/frontend/components/ui/resizable-dialog.tsx index 74a53411..cc28be85 100644 --- a/frontend/components/ui/resizable-dialog.tsx +++ b/frontend/components/ui/resizable-dialog.tsx @@ -122,10 +122,6 @@ const ResizableDialogContent = React.forwardRef< // 1순위: userStyle에서 크기 추출 (화면관리에서 지정한 크기 - 항상 초기값으로 사용) if (userStyle) { - console.log("🔍 userStyle 감지:", userStyle); - console.log("🔍 userStyle.width 타입:", typeof userStyle.width, "값:", userStyle.width); - console.log("🔍 userStyle.height 타입:", typeof userStyle.height, "값:", userStyle.height); - const styleWidth = typeof userStyle.width === 'string' ? parseInt(userStyle.width) : userStyle.width; @@ -133,31 +129,15 @@ const ResizableDialogContent = React.forwardRef< ? parseInt(userStyle.height) : userStyle.height; - console.log("📏 파싱된 크기:", { - styleWidth, - styleHeight, - "styleWidth truthy?": !!styleWidth, - "styleHeight truthy?": !!styleHeight, - minWidth, - maxWidth, - minHeight, - maxHeight - }); - if (styleWidth && styleHeight) { const finalSize = { width: Math.max(minWidth, Math.min(maxWidth, styleWidth)), height: Math.max(minHeight, Math.min(maxHeight, styleHeight)), }; - console.log("✅ userStyle 크기 사용:", finalSize); return finalSize; - } else { - console.log("❌ styleWidth 또는 styleHeight가 falsy:", { styleWidth, styleHeight }); } } - console.log("⚠️ userStyle 없음, defaultWidth/defaultHeight 사용:", { defaultWidth, defaultHeight }); - // 2순위: 현재 렌더링된 크기 사용 (주석처리 - 모달이 열린 후 늘어나는 현상 방지) // if (contentRef.current) { // const rect = contentRef.current.getBoundingClientRect(); @@ -209,7 +189,6 @@ const ResizableDialogContent = React.forwardRef< // 사용자가 리사이징한 크기 우선 setSize({ width: savedSize.width, height: savedSize.height }); setUserResized(true); - console.log("✅ 사용자 리사이징 크기 적용:", savedSize); } else if (userStyle && userStyle.width && userStyle.height) { // 화면관리에서 설정한 크기 const styleWidth = typeof userStyle.width === 'string' @@ -224,7 +203,6 @@ const ResizableDialogContent = React.forwardRef< width: Math.max(minWidth, Math.min(maxWidth, styleWidth)), height: Math.max(minHeight, Math.min(maxHeight, styleHeight)), }; - console.log("🔄 userStyle 크기 적용:", newSize); setSize(newSize); } } diff --git a/frontend/lib/registry/DynamicComponentRenderer.tsx b/frontend/lib/registry/DynamicComponentRenderer.tsx index cf6037eb..245e2527 100644 --- a/frontend/lib/registry/DynamicComponentRenderer.tsx +++ b/frontend/lib/registry/DynamicComponentRenderer.tsx @@ -289,17 +289,8 @@ export const DynamicComponentRenderer: React.FC = // modal-repeater-table은 배열 데이터를 다루므로 빈 배열로 초기화 let currentValue; if (componentType === "modal-repeater-table") { - // 🆕 EditModal에서 전달된 groupedData가 있으면 우선 사용 + // EditModal에서 전달된 groupedData가 있으면 우선 사용 currentValue = props.groupedData || formData?.[fieldName] || []; - - // 디버깅 로그 - console.log("🔍 [DynamicComponentRenderer] ModalRepeaterTable value 설정:", { - hasGroupedData: !!props.groupedData, - groupedDataLength: props.groupedData?.length || 0, - fieldName, - formDataValue: formData?.[fieldName], - finalValueLength: Array.isArray(currentValue) ? currentValue.length : 0, - }); } else { currentValue = formData?.[fieldName] || ""; } diff --git a/frontend/lib/registry/components/conditional-container/ConditionalContainerComponent.tsx b/frontend/lib/registry/components/conditional-container/ConditionalContainerComponent.tsx index 626ee137..6f2ab183 100644 --- a/frontend/lib/registry/components/conditional-container/ConditionalContainerComponent.tsx +++ b/frontend/lib/registry/components/conditional-container/ConditionalContainerComponent.tsx @@ -13,8 +13,6 @@ import { ConditionalContainerProps, ConditionalSection } from "./types"; import { ConditionalSectionViewer } from "./ConditionalSectionViewer"; import { cn } from "@/lib/utils"; -console.log("🚀 ConditionalContainerComponent 모듈 로드됨!"); - /** * 조건부 컨테이너 컴포넌트 * 상단 셀렉트박스 값에 따라 하단에 다른 UI를 표시 @@ -43,11 +41,6 @@ export function ConditionalContainerComponent({ groupedData, // 🆕 그룹 데이터 onSave, // 🆕 EditModal의 handleSave 콜백 }: ConditionalContainerProps) { - console.log("🎯 ConditionalContainerComponent 렌더링!", { - isDesignMode, - hasOnHeightChange: !!onHeightChange, - componentId, - }); // config prop 우선, 없으면 개별 prop 사용 const controlField = config?.controlField || propControlField || "condition"; @@ -86,24 +79,8 @@ export function ConditionalContainerComponent({ const containerRef = useRef(null); const previousHeightRef = useRef(0); - // 🔍 디버그: props 확인 - useEffect(() => { - console.log("🔍 ConditionalContainer props:", { - isDesignMode, - hasOnHeightChange: !!onHeightChange, - componentId, - selectedValue, - }); - }, [isDesignMode, onHeightChange, componentId, selectedValue]); - // 높이 변화 감지 및 콜백 호출 useEffect(() => { - console.log("🔍 ResizeObserver 등록 조건:", { - hasContainer: !!containerRef.current, - isDesignMode, - hasOnHeightChange: !!onHeightChange, - }); - if (!containerRef.current || isDesignMode || !onHeightChange) return; const resizeObserver = new ResizeObserver((entries) => { diff --git a/frontend/lib/registry/components/modal-repeater-table/ModalRepeaterTableComponent.tsx b/frontend/lib/registry/components/modal-repeater-table/ModalRepeaterTableComponent.tsx index 59ce35a8..91d7b36f 100644 --- a/frontend/lib/registry/components/modal-repeater-table/ModalRepeaterTableComponent.tsx +++ b/frontend/lib/registry/components/modal-repeater-table/ModalRepeaterTableComponent.tsx @@ -224,13 +224,11 @@ export function ModalRepeaterTableComponent({ const configuredColumns = componentConfig?.columns || propColumns || []; if (configuredColumns.length > 0) { - console.log("✅ 설정된 columns 사용:", configuredColumns); return configuredColumns; } // columns가 비어있으면 sourceColumns로부터 자동 생성 if (sourceColumns.length > 0) { - console.log("🔄 sourceColumns로부터 자동 생성:", sourceColumns); const autoColumns: RepeaterColumnConfig[] = sourceColumns.map((field) => ({ field: field, label: field, // 필드명을 라벨로 사용 (나중에 설정에서 변경 가능) @@ -238,85 +236,49 @@ export function ModalRepeaterTableComponent({ type: "text" as const, width: "150px", })); - console.log("📋 자동 생성된 columns:", autoColumns); return autoColumns; } - console.warn("⚠️ columns와 sourceColumns 모두 비어있음!"); + console.warn("⚠️ [ModalRepeaterTable] columns와 sourceColumns 모두 비어있음!"); return []; }, [componentConfig?.columns, propColumns, sourceColumns]); - // 초기 props 로깅 + // 초기 props 검증 useEffect(() => { if (rawSourceColumns.length !== sourceColumns.length) { - console.warn(`⚠️ sourceColumns 필터링: ${rawSourceColumns.length}개 → ${sourceColumns.length}개 (빈 문자열 제거)`); + console.warn(`⚠️ [ModalRepeaterTable] sourceColumns 필터링: ${rawSourceColumns.length}개 → ${sourceColumns.length}개`); } if (rawUniqueField !== uniqueField) { - console.warn(`⚠️ uniqueField 자동 보정: "${rawUniqueField}" → "${uniqueField}"`); + console.warn(`⚠️ [ModalRepeaterTable] uniqueField 자동 보정: "${rawUniqueField}" → "${uniqueField}"`); } - console.log("🎬 ModalRepeaterTableComponent 마운트:", { - columnsLength: columns.length, - sourceTable, - sourceColumns, - uniqueField, - }); - if (columns.length === 0) { - console.error("❌ columns가 비어있습니다! sourceColumns:", sourceColumns); - } else { - console.log("✅ columns 설정 완료:", columns.map(c => c.label || c.field).join(", ")); + console.error("❌ [ModalRepeaterTable] columns가 비어있습니다!", { sourceColumns }); } }, []); - // value 변경 감지 - useEffect(() => { - console.log("📦 ModalRepeaterTableComponent value 변경:", { - valueLength: value.length, - }); - }, [value]); - // 🆕 저장 요청 시에만 데이터 전달 (beforeFormSave 이벤트 리스너) useEffect(() => { const handleSaveRequest = async (event: Event) => { const componentKey = columnName || component?.id || "modal_repeater_data"; - console.log("🔔 [ModalRepeaterTable] beforeFormSave 이벤트 수신!", { - componentKey, - itemsCount: value.length, - hasOnFormDataChange: !!onFormDataChange, - columnName, - componentId: component?.id, - targetTable, - }); - if (value.length === 0) { console.warn("⚠️ [ModalRepeaterTable] 저장할 데이터 없음"); return; } - // 🔥 sourceColumns에 포함된 컬럼 제외 (조인된 컬럼 제거) - console.log("🔍 [ModalRepeaterTable] 필터링 전 데이터:", { - sourceColumns, - sourceTable, - targetTable, - sampleItem: value[0], - itemKeys: value[0] ? Object.keys(value[0]) : [], - }); - + // sourceColumns에 포함된 컬럼 제외 (조인된 컬럼 제거) const filteredData = value.map((item: any) => { const filtered: Record = {}; Object.keys(item).forEach((key) => { // sourceColumns에 포함된 컬럼은 제외 (item_info 테이블의 컬럼) if (sourceColumns.includes(key)) { - console.log(` ⛔ ${key} 제외 (sourceColumn)`); return; } // 메타데이터 필드도 제외 if (key.startsWith("_")) { - console.log(` ⛔ ${key} 제외 (메타데이터)`); return; } filtered[key] = item[key]; @@ -325,12 +287,7 @@ export function ModalRepeaterTableComponent({ return filtered; }); - console.log("✅ [ModalRepeaterTable] 필터링 후 데이터:", { - filteredItemKeys: filteredData[0] ? Object.keys(filteredData[0]) : [], - sampleFilteredItem: filteredData[0], - }); - - // 🔥 targetTable 메타데이터를 배열 항목에 추가 + // targetTable 메타데이터를 배열 항목에 추가 const dataWithTargetTable = targetTable ? filteredData.map((item: any) => ({ ...item, @@ -338,21 +295,19 @@ export function ModalRepeaterTableComponent({ })) : filteredData; - // ✅ CustomEvent의 detail에 데이터 추가 + // CustomEvent의 detail에 데이터 추가 if (event instanceof CustomEvent && event.detail) { event.detail.formData[componentKey] = dataWithTargetTable; - console.log("✅ [ModalRepeaterTable] context.formData에 데이터 추가 완료:", { + console.log("✅ [ModalRepeaterTable] 저장 데이터 준비:", { key: componentKey, itemCount: dataWithTargetTable.length, - targetTable: targetTable || "미설정 (화면 설계에서 설정 필요)", - sampleItem: dataWithTargetTable[0], + targetTable: targetTable || "미설정", }); } // 기존 onFormDataChange도 호출 (호환성) if (onFormDataChange) { onFormDataChange(componentKey, dataWithTargetTable); - console.log("✅ [ModalRepeaterTable] onFormDataChange 호출 완료"); } }; diff --git a/frontend/lib/registry/components/table-list/TableListComponent.tsx b/frontend/lib/registry/components/table-list/TableListComponent.tsx index a8356721..76556ecb 100644 --- a/frontend/lib/registry/components/table-list/TableListComponent.tsx +++ b/frontend/lib/registry/components/table-list/TableListComponent.tsx @@ -2404,18 +2404,9 @@ export const TableListComponent: React.FC = ({ - ) : (() => { - console.log("🔍 [TableList] 렌더링 조건 체크", { - groupByColumns: groupByColumns.length, - groupedDataLength: groupedData.length, - willRenderGrouped: groupByColumns.length > 0 && groupedData.length > 0, - dataLength: data.length, - }); - return groupByColumns.length > 0 && groupedData.length > 0; - })() ? ( + ) : groupByColumns.length > 0 && groupedData.length > 0 ? ( // 그룹화된 렌더링 groupedData.map((group) => { - console.log("📊 [TableList] 그룹 렌더링:", group.groupKey, group.count); const isCollapsed = collapsedGroups.has(group.groupKey); return ( @@ -2508,10 +2499,7 @@ export const TableListComponent: React.FC = ({ }) ) : ( // 일반 렌더링 (그룹 없음) - (() => { - console.log("📋 [TableList] 일반 렌더링 시작:", data.length, "개 행"); - return data; - })().map((row, index) => ( + data.map((row, index) => (