"use client"; import React, { useState, useEffect } from "react"; import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card"; import { Button } from "@/components/ui/button"; import { Input } from "@/components/ui/input"; import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select"; import { Badge } from "@/components/ui/badge"; import { ArrowLeft, CheckCircle, AlertCircle, Settings, Plus, Trash2 } from "lucide-react"; // 타입 import import { DataConnectionState, DataConnectionActions } from "../types/redesigned"; import { ColumnInfo } from "@/lib/types/multiConnection"; import { getColumnsFromConnection } from "@/lib/api/multiConnection"; import { getCodesForColumn, CodeItem } from "@/lib/api/codeManagement"; // 컴포넌트 import interface ControlConditionStepProps { state: DataConnectionState; actions: DataConnectionActions; onBack: () => void; onNext: () => void; } /** * 🎯 4단계: 제어 조건 설정 * - 전체 제어가 언제 실행될지 설정 * - INSERT/UPDATE/DELETE 트리거 조건 */ const ControlConditionStep: React.FC = ({ state, actions, onBack, onNext }) => { const { controlConditions, fromTable, toTable, fromConnection, toConnection } = state; const [fromColumns, setFromColumns] = useState([]); const [toColumns, setToColumns] = useState([]); const [isLoading, setIsLoading] = useState(false); const [availableCodes, setAvailableCodes] = useState>({}); // 컬럼 정보 로드 useEffect(() => { const loadColumns = async () => { console.log("🔄 ControlConditionStep 컬럼 로드 시작"); console.log("fromConnection:", fromConnection); console.log("toConnection:", toConnection); console.log("fromTable:", fromTable); console.log("toTable:", toTable); if (!fromConnection || !toConnection || !fromTable || !toTable) { console.log("❌ 필수 정보 누락으로 컬럼 로드 중단"); return; } setIsLoading(true); try { console.log( `🚀 컬럼 조회 시작: FROM=${fromConnection.id}/${fromTable.tableName}, TO=${toConnection.id}/${toTable.tableName}`, ); const [fromCols, toCols] = await Promise.all([ getColumnsFromConnection(fromConnection.id, fromTable.tableName), getColumnsFromConnection(toConnection.id, toTable.tableName), ]); console.log(`✅ 컬럼 조회 완료: FROM=${fromCols.length}개, TO=${toCols.length}개`); setFromColumns(fromCols); setToColumns(toCols); } catch (error) { console.error("❌ 컬럼 정보 로드 실패:", error); } finally { setIsLoading(false); } }; loadColumns(); }, [fromConnection, toConnection, fromTable, toTable]); // 코드 타입 컬럼의 코드 로드 useEffect(() => { const loadCodes = async () => { const allColumns = [...fromColumns, ...toColumns]; const codeColumns = allColumns.filter( (col) => col.webType === "code" || col.dataType?.toLowerCase().includes("code"), ); if (codeColumns.length === 0) return; console.log("🔍 코드 타입 컬럼들:", codeColumns); const codePromises = codeColumns.map(async (col) => { try { const codes = await getCodesForColumn(col.columnName, col.webType, col.codeCategory); return { columnName: col.columnName, codes }; } catch (error) { console.error(`코드 로딩 실패 (${col.columnName}):`, error); return { columnName: col.columnName, codes: [] }; } }); const results = await Promise.all(codePromises); const codeMap: Record = {}; results.forEach(({ columnName, codes }) => { codeMap[columnName] = codes; }); console.log("📋 로딩된 코드들:", codeMap); setAvailableCodes(codeMap); }; if (fromColumns.length > 0 || toColumns.length > 0) { loadCodes(); } }, [fromColumns, toColumns]); // 완료 가능 여부 확인 const canProceed = controlConditions.length === 0 || controlConditions.some( (condition) => condition.field && condition.operator && (condition.value !== "" || ["IS NULL", "IS NOT NULL"].includes(condition.operator)), ); const isCompleted = canProceed; return ( <> {isCompleted ? ( ) : ( )} 4단계: 제어 실행 조건

이 전체 제어가 언제 실행될지 설정합니다. 조건을 설정하지 않으면 항상 실행됩니다.

{/* 제어 실행 조건 안내 */}

제어 실행 조건이란?

전체 제어의 트리거 조건을 설정합니다

• 예: "상태가 '활성'이고 유형이 'A'인 경우에만 데이터 동기화 실행"

• 조건을 설정하지 않으면 모든 경우에 실행됩니다

{/* 간단한 조건 추가 UI */} {!isLoading && (fromColumns.length > 0 || toColumns.length > 0 || controlConditions.length > 0) && (

실행 조건 (WHERE)

{controlConditions.length === 0 ? (

제어 실행 조건을 설정하세요

"조건 추가" 버튼을 클릭하여 시작하세요

) : (
{controlConditions.map((condition, index) => (
{/* 논리 연산자 */} {index > 0 && ( )} {/* 필드 선택 */} {/* 연산자 선택 */} {/* 값 입력 */} {!["IS NULL", "IS NOT NULL"].includes(condition.operator || "") && (() => { // 선택된 필드가 코드 타입인지 확인 const selectedField = [...fromColumns, ...toColumns].find( (col) => col.columnName === condition.field, ); const isCodeField = selectedField && (selectedField.webType === "code" || selectedField.dataType?.toLowerCase().includes("code")); const fieldCodes = condition.field ? availableCodes[condition.field] : []; // 디버깅 정보 출력 console.log("🔍 값 입력 필드 디버깅:", { conditionField: condition.field, selectedField: selectedField, webType: selectedField?.webType, dataType: selectedField?.dataType, isCodeField: isCodeField, fieldCodes: fieldCodes, availableCodesKeys: Object.keys(availableCodes), }); if (isCodeField && fieldCodes && fieldCodes.length > 0) { // 코드 타입 필드면 코드 선택 드롭다운 return ( ); } else { // 일반 필드면 텍스트 입력 return ( actions.updateControlCondition(index, { ...condition, value: e.target.value, }) } className="w-32" /> ); } })()} {/* 삭제 버튼 */}
))}
)}
)} {/* 로딩 상태 */} {isLoading && (
컬럼 정보를 불러오는 중...
)} {/* 조건 없음 안내 */} {!isLoading && controlConditions.length === 0 && (

제어 실행 조건 없음

현재 제어 실행 조건이 설정되지 않았습니다.
모든 경우에 제어가 실행됩니다.

)} {/* 컬럼 정보 로드 실패 시 안내 */} {!isLoading && fromColumns.length === 0 && toColumns.length === 0 && controlConditions.length === 0 && (

컬럼 정보를 불러올 수 없습니다

• 외부 데이터베이스 연결에 문제가 있을 수 있습니다

• 조건 없이 진행하면 항상 실행됩니다

• 나중에 수동으로 조건을 추가할 수 있습니다

)} {/* 설정 요약 */} {controlConditions.length > 0 && (

설정 요약

제어 실행 조건: 0 ? "default" : "secondary"}> {controlConditions.length > 0 ? `${controlConditions.length}개 조건` : "조건 없음"}
실행 방식: {controlConditions.length === 0 ? "항상 실행" : "조건부 실행"}
)}
{/* 하단 네비게이션 */}
); }; export default ControlConditionStep;