"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 { 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, fromColumns = [], toColumns = [], isLoading = false, } = state; const [availableCodes, setAvailableCodes] = useState>({}); // 컴포넌트 마운트 시 컬럼 로드 useEffect(() => { if ( fromConnection && toConnection && fromTable && toTable && fromColumns.length === 0 && toColumns.length === 0 && !isLoading ) { console.log("🔄 ControlConditionStep: 컬럼 로드 시작"); actions.loadColumns(); } }, [ fromConnection?.id, toConnection?.id, fromTable?.tableName, toTable?.tableName, fromColumns.length, toColumns.length, isLoading, ]); // 코드 타입 컬럼의 코드 로드 useEffect(() => { const loadCodes = async () => { const allColumns = [...fromColumns, ...toColumns]; const codeColumns = allColumns.filter((col) => { // 메인 DB(connectionId === 0 또는 undefined)인 경우: column_labels의 input_type이 'code'인 경우만 if (col.connectionId === 0 || col.connectionId === undefined) { return col.inputType === "code"; } // 외부 DB인 경우: 코드 타입 없음 return false; }); if (codeColumns.length === 0) return; console.log( "🔍 모든 컬럼 정보:", allColumns.map((col) => ({ columnName: col.columnName, connectionId: col.connectionId, inputType: col.inputType, webType: col.webType, })), ); 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.connectionId === 0 || selectedField.connectionId === undefined) && // 임시: undefined도 메인 DB로 간주 selectedField.inputType === "code"; const fieldCodes = condition.field ? availableCodes[condition.field] : []; // 디버깅 정보 출력 console.log("🔍 값 입력 필드 디버깅:", { conditionField: condition.field, selectedField: selectedField, selectedFieldKeys: selectedField ? Object.keys(selectedField) : [], webType: selectedField?.webType, inputType: selectedField?.inputType, connectionId: selectedField?.connectionId, 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 && fromColumns.length > 0 && toColumns.length > 0 && controlConditions.length === 0 && (

제어 실행 조건 없음

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

)} {/* 컬럼 정보 로드 실패 시 안내 */} {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;