console.log 주석 처리 - 개발환경 정리

- menu, company, screenMng, i18n, tableMng 모듈 console 주석 처리
- 총 55개 파일 수정
- 빌드 에러 수정 완료
- 백엔드 서버 정상 작동 확인

관련 파일:
- frontend/components/admin/MenuManagement.tsx
- frontend/components/admin/MenuFormModal.tsx
- frontend/components/admin/ScreenAssignmentTab.tsx
- frontend/components/admin/CompanyTable.tsx
- frontend/components/admin/MultiLang.tsx
- frontend/app/(main)/admin/tableMng/page.tsx
- 기타 screen 관련 컴포넌트 49개 파일
This commit is contained in:
leeheejin
2025-10-01 18:17:30 +09:00
parent 4202a5b310
commit 2c0dca08b4
55 changed files with 1757 additions and 1464 deletions

View File

@@ -153,7 +153,7 @@ export const InteractiveScreenViewer: React.FC<InteractiveScreenViewerProps> = (
const loadPopupLayout = async () => {
try {
setPopupLoading(true);
console.log("🔍 팝업 화면 로드 시작:", popupScreen);
// console.log("🔍 팝업 화면 로드 시작:", popupScreen);
// 화면 레이아웃과 화면 정보를 병렬로 가져오기
const [layout, screen] = await Promise.all([
@@ -180,7 +180,7 @@ export const InteractiveScreenViewer: React.FC<InteractiveScreenViewerProps> = (
// 팝업 formData 초기화
setPopupFormData({});
} catch (error) {
console.error("❌ 팝업 화면 로드 실패:", error);
// console.error("❌ 팝업 화면 로드 실패:", error);
setPopupLayout([]);
setPopupScreenInfo(null);
} finally {
@@ -203,27 +203,27 @@ export const InteractiveScreenViewer: React.FC<InteractiveScreenViewerProps> = (
// 폼 데이터 업데이트
const updateFormData = (fieldName: string, value: any) => {
console.log(`🔄 updateFormData: ${fieldName} = "${value}" (외부콜백: ${!!onFormDataChange})`);
// console.log(`🔄 updateFormData: ${fieldName} = "${value}" (외부콜백: ${!!onFormDataChange})`);
// 항상 로컬 상태도 업데이트
setLocalFormData((prev) => ({
...prev,
[fieldName]: value,
}));
console.log(`💾 로컬 상태 업데이트: ${fieldName} = "${value}"`);
// console.log(`💾 로컬 상태 업데이트: ${fieldName} = "${value}"`);
// 외부 콜백이 있는 경우에도 전달 (개별 필드 단위로)
if (onFormDataChange) {
onFormDataChange(fieldName, value);
console.log(`📤 외부 콜백으로 전달: ${fieldName} = "${value}"`);
// console.log(`📤 외부 콜백으로 전달: ${fieldName} = "${value}"`);
}
};
// 자동입력 필드들의 값을 formData에 초기 설정
React.useEffect(() => {
console.log("🚀 자동입력 초기화 useEffect 실행 - allComponents 개수:", allComponents.length);
// console.log("🚀 자동입력 초기화 useEffect 실행 - allComponents 개수:", allComponents.length);
const initAutoInputFields = () => {
console.log("🔧 initAutoInputFields 실행 시작");
// console.log("🔧 initAutoInputFields 실행 시작");
allComponents.forEach(comp => {
if (comp.type === 'widget') {
const widget = comp as WidgetComponent;
@@ -258,7 +258,7 @@ export const InteractiveScreenViewer: React.FC<InteractiveScreenViewerProps> = (
updateFormData(fieldName, autoValue);
} else {
console.log(`⏭️ 자동입력 건너뜀 (값 있음): ${fieldName} = "${currentValue}"`);
// console.log(`⏭️ 자동입력 건너뜀 (값 있음): ${fieldName} = "${currentValue}"`);
}
}
}
@@ -378,7 +378,7 @@ export const InteractiveScreenViewer: React.FC<InteractiveScreenViewerProps> = (
// 입력 검증 함수
const handleInputChange = (e: React.ChangeEvent<HTMLInputElement>) => {
const value = e.target.value;
console.log(`📝 입력 변경: ${fieldName} = "${value}"`);
// console.log(`📝 입력 변경: ${fieldName} = "${value}"`);
// 형식별 실시간 검증
if (config?.format && config.format !== "none") {
@@ -386,7 +386,7 @@ export const InteractiveScreenViewer: React.FC<InteractiveScreenViewerProps> = (
if (pattern) {
const regex = new RegExp(`^${pattern}$`);
if (value && !regex.test(value)) {
console.log(`❌ 형식 검증 실패: ${fieldName} = "${value}"`);
// console.log(`❌ 형식 검증 실패: ${fieldName} = "${value}"`);
return; // 유효하지 않은 입력 차단
}
}
@@ -394,11 +394,11 @@ export const InteractiveScreenViewer: React.FC<InteractiveScreenViewerProps> = (
// 길이 제한 검증
if (config?.maxLength && value.length > config.maxLength) {
console.log(`❌ 길이 제한 초과: ${fieldName} = "${value}" (최대: ${config.maxLength})`);
// console.log(`❌ 길이 제한 초과: ${fieldName} = "${value}" (최대: ${config.maxLength})`);
return; // 최대 길이 초과 차단
}
console.log(`✅ updateFormData 호출: ${fieldName} = "${value}"`);
// console.log(`✅ updateFormData 호출: ${fieldName} = "${value}"`);
updateFormData(fieldName, value);
};
@@ -797,16 +797,16 @@ export const InteractiveScreenViewer: React.FC<InteractiveScreenViewerProps> = (
// 파일 선택을 취소한 경우 (files가 null이거나 길이가 0)
if (!files || files.length === 0) {
console.log("📁 파일 선택 취소됨 - 기존 파일 유지");
// console.log("📁 파일 선택 취소됨 - 기존 파일 유지");
// 현재 저장된 파일이 있는지 확인
const currentStoredValue = externalFormData?.[fieldName] || localFormData[fieldName];
if (currentStoredValue) {
console.log("📁 기존 파일 있음 - 유지:", currentStoredValue);
// console.log("📁 기존 파일 있음 - 유지:", currentStoredValue);
// 기존 파일이 있으면 그대로 유지 (아무것도 하지 않음)
return;
} else {
console.log("📁 기존 파일 없음 - 빈 상태 유지");
// console.log("📁 기존 파일 없음 - 빈 상태 유지");
// 기존 파일이 없으면 빈 상태 유지
return;
}
@@ -831,7 +831,7 @@ export const InteractiveScreenViewer: React.FC<InteractiveScreenViewerProps> = (
const uploadResult = await uploadFilesAndCreateData(files);
if (uploadResult.success) {
console.log("📁 업로드 완료된 파일 데이터:", uploadResult.data);
// console.log("📁 업로드 완료된 파일 데이터:", uploadResult.data);
setLocalFormData(prev => ({ ...prev, [fieldName]: uploadResult.data }));
@@ -845,7 +845,7 @@ export const InteractiveScreenViewer: React.FC<InteractiveScreenViewerProps> = (
throw new Error("파일 업로드에 실패했습니다.");
}
} catch (error) {
console.error("파일 업로드 오류:", error);
// console.error("파일 업로드 오류:", error);
toast.error("파일 업로드에 실패했습니다.");
// 파일 입력 초기화
@@ -1023,12 +1023,12 @@ export const InteractiveScreenViewer: React.FC<InteractiveScreenViewerProps> = (
isCodeType: true, // 코드 타입임을 명시
}}
onEvent={(event: string, data: any) => {
console.log(`Code widget event: ${event}`, data);
// console.log(`Code widget event: ${event}`, data);
}}
/>
);
} catch (error) {
console.error("DynamicWebTypeRenderer 로딩 실패, 기본 Select 사용:", error);
// console.error("DynamicWebTypeRenderer 로딩 실패, 기본 Select 사용:", error);
// 폴백: 기본 Select 컴포넌트 사용
return applyStyles(
@@ -1148,21 +1148,21 @@ export const InteractiveScreenViewer: React.FC<InteractiveScreenViewerProps> = (
await handleCustomAction();
break;
default:
console.log(`알 수 없는 액션 타입: ${actionType}`);
// console.log(`알 수 없는 액션 타입: ${actionType}`);
}
} catch (error) {
console.error(`버튼 액션 실행 오류 (${actionType}):`, error);
// console.error(`버튼 액션 실행 오류 (${actionType}):`, error);
alert(`작업 중 오류가 발생했습니다: ${error.message}`);
}
};
// 저장 액션 (개선된 버전)
const handleSaveAction = async () => {
console.log("💾 저장 시작");
// console.log("💾 저장 시작");
// 개선된 검증 시스템이 활성화된 경우
if (enhancedValidation) {
console.log("🔍 개선된 검증 시스템 사용");
// console.log("🔍 개선된 검증 시스템 사용");
const success = await enhancedValidation.saveForm();
if (success) {
toast.success("데이터가 성공적으로 저장되었습니다!");
@@ -1172,7 +1172,7 @@ export const InteractiveScreenViewer: React.FC<InteractiveScreenViewerProps> = (
// 기존 방식 (레거시 지원)
const currentFormData = { ...localFormData, ...externalFormData };
console.log("💾 기존 방식으로 저장 - currentFormData:", currentFormData);
// console.log("💾 기존 방식으로 저장 - currentFormData:", currentFormData);
// formData 유효성 체크를 완화 (빈 객체라도 위젯이 있으면 저장 진행)
const hasWidgets = allComponents.some(comp => comp.type === 'widget');
@@ -1249,7 +1249,7 @@ export const InteractiveScreenViewer: React.FC<InteractiveScreenViewerProps> = (
existingValue: value
});
} else if (!isAutoInput) {
console.log(`📝 일반 입력 필드: ${fieldName} = "${value}"`);
// console.log(`📝 일반 입력 필드: ${fieldName} = "${value}"`);
}
}
@@ -1260,7 +1260,7 @@ export const InteractiveScreenViewer: React.FC<InteractiveScreenViewerProps> = (
mappedData[saveKey] = value;
} else if (widget.columnName) {
// 값이 없지만 columnName이 있는 경우, 빈 문자열로 저장
console.log(`⚠️ ${widget.columnName} 필드에 값이 없어 빈 문자열로 저장`);
// console.log(`⚠️ ${widget.columnName} 필드에 값이 없어 빈 문자열로 저장`);
mappedData[widget.columnName] = "";
}
}
@@ -1275,20 +1275,20 @@ export const InteractiveScreenViewer: React.FC<InteractiveScreenViewerProps> = (
});
// 각 컴포넌트의 상세 정보 로그
console.log("🔍 컴포넌트별 데이터 수집 상세:");
// console.log("🔍 컴포넌트별 데이터 수집 상세:");
allComponents.forEach(comp => {
if (comp.type === 'widget') {
const widget = comp as WidgetComponent;
const fieldName = widget.columnName || widget.id;
const value = currentFormData[fieldName];
const hasValue = value !== undefined && value !== null && value !== '';
console.log(` - ${fieldName} (${widget.widgetType}): "${value}" (값있음: ${hasValue}, 컬럼명: ${widget.columnName})`);
// console.log(` - ${fieldName} (${widget.widgetType}): "${value}" (값있음: ${hasValue}, 컬럼명: ${widget.columnName})`);
}
});
// 매핑된 데이터가 비어있으면 경고
if (Object.keys(mappedData).length === 0) {
console.warn("⚠️ 매핑된 데이터가 없습니다. 빈 데이터로 저장됩니다.");
// console.warn("⚠️ 매핑된 데이터가 없습니다. 빈 데이터로 저장됩니다.");
}
// 테이블명 결정 (화면 정보에서 가져오거나 첫 번째 컴포넌트의 테이블명 사용)
@@ -1302,13 +1302,13 @@ export const InteractiveScreenViewer: React.FC<InteractiveScreenViewerProps> = (
data: mappedData,
};
console.log("🚀 API 저장 요청:", saveData);
// console.log("🚀 API 저장 요청:", saveData);
const result = await dynamicFormApi.saveFormData(saveData);
if (result.success) {
alert("저장되었습니다.");
console.log("✅ 저장 성공:", result.data);
// console.log("✅ 저장 성공:", result.data);
// 저장 후 데이터 초기화 (선택사항)
if (onFormDataChange) {
@@ -1322,7 +1322,7 @@ export const InteractiveScreenViewer: React.FC<InteractiveScreenViewerProps> = (
throw new Error(result.message || "저장에 실패했습니다.");
}
} catch (error: any) {
console.error("❌ 저장 실패:", error);
// console.error("❌ 저장 실패:", error);
alert(`저장 중 오류가 발생했습니다: ${error.message}`);
}
};
@@ -1355,13 +1355,13 @@ export const InteractiveScreenViewer: React.FC<InteractiveScreenViewerProps> = (
}
try {
console.log("🗑️ 삭제 실행:", { recordId, tableName, formData });
// console.log("🗑️ 삭제 실행:", { recordId, tableName, formData });
const result = await dynamicFormApi.deleteFormDataFromTable(recordId, tableName);
if (result.success) {
alert("삭제되었습니다.");
console.log("✅ 삭제 성공");
// console.log("✅ 삭제 성공");
// 삭제 후 폼 초기화
if (onFormDataChange) {
@@ -1375,28 +1375,28 @@ export const InteractiveScreenViewer: React.FC<InteractiveScreenViewerProps> = (
throw new Error(result.message || "삭제에 실패했습니다.");
}
} catch (error: any) {
console.error("❌ 삭제 실패:", error);
// console.error("❌ 삭제 실패:", error);
alert(`삭제 중 오류가 발생했습니다: ${error.message}`);
}
};
// 편집 액션
const handleEditAction = () => {
console.log("✏️ 편집 모드 활성화");
// console.log("✏️ 편집 모드 활성화");
// 읽기 전용 모드를 편집 모드로 전환
alert("편집 모드로 전환되었습니다.");
};
// 추가 액션
const handleAddAction = () => {
console.log(" 새 항목 추가");
// console.log(" 새 항목 추가");
// 새 항목 추가 로직
alert("새 항목을 추가할 수 있습니다.");
};
// 검색 액션
const handleSearchAction = () => {
console.log("🔍 검색 실행:", formData);
// console.log("🔍 검색 실행:", formData);
// 검색 로직
const searchTerms = Object.values(formData).filter(v => v && v.toString().trim());
if (searchTerms.length === 0) {
@@ -1416,21 +1416,21 @@ export const InteractiveScreenViewer: React.FC<InteractiveScreenViewerProps> = (
});
onFormDataChange(resetData);
}
console.log("🔄 폼 초기화 완료");
// console.log("🔄 폼 초기화 완료");
alert("입력이 초기화되었습니다.");
}
};
// 제출 액션
const handleSubmitAction = async () => {
console.log("📤 폼 제출:", formData);
// console.log("📤 폼 제출:", formData);
// 제출 로직
alert("제출되었습니다.");
};
// 닫기 액션
const handleCloseAction = () => {
console.log("❌ 닫기 액션 실행");
// console.log("❌ 닫기 액션 실행");
// 모달 내부에서 실행되는지 확인
const isInModal = document.querySelector('[role="dialog"]') !== null;
@@ -1438,7 +1438,7 @@ export const InteractiveScreenViewer: React.FC<InteractiveScreenViewerProps> = (
if (isInModal) {
// 모달 내부인 경우: 모달의 닫기 버튼 클릭하거나 모달 닫기 이벤트 발생
console.log("🔄 모달 내부에서 닫기 - 모달 닫기 시도");
// console.log("🔄 모달 내부에서 닫기 - 모달 닫기 시도");
// 모달의 닫기 버튼을 찾아서 클릭
const modalCloseButton = document.querySelector('[role="dialog"] button[aria-label*="Close"], [role="dialog"] button[data-dismiss="modal"], [role="dialog"] .dialog-close');
@@ -1451,18 +1451,18 @@ export const InteractiveScreenViewer: React.FC<InteractiveScreenViewerProps> = (
}
} else if (isInPopup) {
// 팝업 창인 경우
console.log("🔄 팝업 창 닫기");
// console.log("🔄 팝업 창 닫기");
window.close();
} else {
// 일반 페이지인 경우 - 이전 페이지로 이동하지 않고 아무것도 하지 않음
console.log("🔄 일반 페이지에서 닫기 - 아무 동작 하지 않음");
// console.log("🔄 일반 페이지에서 닫기 - 아무 동작 하지 않음");
alert("닫기 버튼이 클릭되었습니다.");
}
};
// 팝업 액션
const handlePopupAction = () => {
console.log("🎯 팝업 액션 실행:", { popupScreenId: config?.popupScreenId });
// console.log("🎯 팝업 액션 실행:", { popupScreenId: config?.popupScreenId });
if (config?.popupScreenId) {
// 화면 모달 열기
@@ -1528,12 +1528,12 @@ export const InteractiveScreenViewer: React.FC<InteractiveScreenViewerProps> = (
if (result instanceof Promise) {
await result;
}
console.log("⚡ 커스텀 액션 실행 완료");
// console.log("⚡ 커스텀 액션 실행 완료");
} catch (error) {
throw new Error(`커스텀 액션 실행 실패: ${error.message}`);
}
} else {
console.log("⚡ 커스텀 액션이 설정되지 않았습니다.");
// console.log("⚡ 커스텀 액션이 설정되지 않았습니다.");
}
};
@@ -1619,7 +1619,7 @@ export const InteractiveScreenViewer: React.FC<InteractiveScreenViewerProps> = (
company_code: file.companyCode
}));
console.log("💾 attach_file_info 형태로 변환된 데이터:", fileInfoForDB);
// console.log("💾 attach_file_info 형태로 변환된 데이터:", fileInfoForDB);
// FormData에는 파일 연결 정보만 저장 (간단한 형태)
const formDataValue = {
@@ -1633,7 +1633,7 @@ export const InteractiveScreenViewer: React.FC<InteractiveScreenViewerProps> = (
}))
};
console.log("📝 FormData 저장값:", { fieldName, formDataValue });
// console.log("📝 FormData 저장값:", { fieldName, formDataValue });
onFormDataChange(fieldName, formDataValue);
// TODO: 실제 API 연동 시 attach_file_info 테이블에 저장