chore: 과도한 콘솔 로그 정리

- ModalRepeaterTableComponent: 반복 렌더링 로그 제거
- TableListComponent: 렌더링 조건 체크 IIFE 단순화
- ConditionalContainerComponent: 디버깅 로그 삭제
- DynamicComponentRenderer: value 설정 로그 제거
- resizable-dialog: userStyle 상세 로그 정리
- page.tsx: 반복 데이터 탐색 로그 삭제

에러 핸들링 및 주요 분기점 로그만 보존
This commit is contained in:
SeongHyun Kim 2025-11-25 16:56:50 +09:00
parent 6317ae7b0b
commit 8fdf57bedd
6 changed files with 14 additions and 169 deletions

View File

@ -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([]); // 선택 해제
}}

View File

@ -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);
}
}

View File

@ -289,17 +289,8 @@ export const DynamicComponentRenderer: React.FC<DynamicComponentRendererProps> =
// 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] || "";
}

View File

@ -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<HTMLDivElement>(null);
const previousHeightRef = useRef<number>(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) => {

View File

@ -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<string, any> = {};
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 호출 완료");
}
};

View File

@ -2404,18 +2404,9 @@ export const TableListComponent: React.FC<TableListComponentProps> = ({
</div>
</td>
</tr>
) : (() => {
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 (
<React.Fragment key={group.groupKey}>
@ -2508,10 +2499,7 @@ export const TableListComponent: React.FC<TableListComponentProps> = ({
})
) : (
// 일반 렌더링 (그룹 없음)
(() => {
console.log("📋 [TableList] 일반 렌더링 시작:", data.length, "개 행");
return data;
})().map((row, index) => (
data.map((row, index) => (
<tr
key={index}
className={cn(