diff --git a/frontend/components/dataflow/ConnectionSetupModal.tsx b/frontend/components/dataflow/ConnectionSetupModal.tsx index 1ece10f5..9a3b41d8 100644 --- a/frontend/components/dataflow/ConnectionSetupModal.tsx +++ b/frontend/components/dataflow/ConnectionSetupModal.tsx @@ -8,8 +8,8 @@ import { Label } from "@/components/ui/label"; import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select"; import { Badge } from "@/components/ui/badge"; import { Textarea } from "@/components/ui/textarea"; -import { ArrowRight, Link, Key, Save, Globe, Plus } from "lucide-react"; -import { DataFlowAPI, TableRelationship, TableInfo, ColumnInfo } from "@/lib/api/dataflow"; +import { Link, Key, Save, Globe, Plus, Zap, Trash2 } from "lucide-react"; +import { DataFlowAPI, TableRelationship, TableInfo, ColumnInfo, ConditionNode } from "@/lib/api/dataflow"; import toast from "react-hot-toast"; // 연결 정보 타입 @@ -36,7 +36,7 @@ interface ConnectionInfo { relationshipName: string; relationshipType: string; connectionType: string; - settings?: any; + settings?: Record; }; } @@ -76,7 +76,6 @@ interface ConnectionSetupModalProps { isOpen: boolean; connection: ConnectionInfo | null; companyCode: string; - diagramId?: number; onConfirm: (relationship: TableRelationship) => void; onCancel: () => void; } @@ -85,7 +84,6 @@ export const ConnectionSetupModal: React.FC = ({ isOpen, connection, companyCode, - diagramId, onConfirm, onCancel, }) => { @@ -127,6 +125,12 @@ export const ConnectionSetupModal: React.FC = ({ const [selectedFromColumns, setSelectedFromColumns] = useState([]); const [selectedToColumns, setSelectedToColumns] = useState([]); + // 조건부 연결을 위한 새로운 상태들 + const [triggerType, setTriggerType] = useState<"insert" | "update" | "delete" | "insert_update">("insert"); + const [conditions, setConditions] = useState([]); + const [rollbackOnError, setRollbackOnError] = useState(true); + const [enableLogging, setEnableLogging] = useState(true); + // 테이블 목록 로드 useEffect(() => { const loadTables = async () => { @@ -166,7 +170,8 @@ export const ConnectionSetupModal: React.FC = ({ connectionType: (existingRel?.connectionType as "simple-key" | "data-save" | "external-call") || "simple-key", fromColumnName: "", toColumnName: "", - description: existingRel?.settings?.description || `${fromDisplayName}과 ${toDisplayName} 간의 데이터 관계`, + description: + (existingRel?.settings?.description as string) || `${fromDisplayName}과 ${toDisplayName} 간의 데이터 관계`, settings: existingRel?.settings || {}, }); @@ -282,6 +287,32 @@ export const ConnectionSetupModal: React.FC = ({ const fromTableName = selectedFromTable || connection.fromNode.tableName; const toTableName = selectedToTable || connection.toNode.tableName; + // 조건부 연결 설정 데이터 준비 + const conditionalSettings = isConditionalConnection() + ? { + control: { + triggerType, + conditionTree: + conditions.length > 0 + ? { + type: "group" as const, + operator: "AND" as const, + children: conditions, + } + : null, + }, + category: { + type: config.connectionType, + rollbackOnError, + enableLogging, + }, + plan: { + sourceTable: fromTableName, + targetActions: [], // 나중에 액션 설정 UI에서 채울 예정 + }, + } + : {}; + // 메모리 기반 시스템: 관계 데이터만 생성하여 부모로 전달 const relationshipData: TableRelationship = { relationship_name: config.relationshipName, @@ -289,11 +320,12 @@ export const ConnectionSetupModal: React.FC = ({ to_table_name: toTableName, from_column_name: selectedFromColumns.join(","), // 여러 컬럼을 콤마로 구분 to_column_name: selectedToColumns.join(","), // 여러 컬럼을 콤마로 구분 - relationship_type: config.relationshipType as any, - connection_type: config.connectionType as any, + relationship_type: config.relationshipType, + connection_type: config.connectionType, company_code: companyCode, settings: { ...settings, + ...conditionalSettings, // 조건부 연결 설정 추가 description: config.description, multiColumnMapping: { fromColumns: selectedFromColumns, @@ -330,14 +362,165 @@ export const ConnectionSetupModal: React.FC = ({ if (!connection) return null; - // 선택된 컬럼 데이터 가져오기 - const selectedColumnsData = connection.selectedColumnsData || {}; - const tableNames = Object.keys(selectedColumnsData); - const fromTable = tableNames[0]; - const toTable = tableNames[1]; + // 선택된 컬럼 데이터 가져오기 (현재 사용되지 않음 - 향후 확장을 위해 유지) + // const selectedColumnsData = connection.selectedColumnsData || {}; - const fromTableData = selectedColumnsData[fromTable]; - const toTableData = selectedColumnsData[toTable]; + // 조건부 연결인지 확인하는 헬퍼 함수 + const isConditionalConnection = () => { + return config.connectionType === "data-save" || config.connectionType === "external-call"; + }; + + // 조건 관리 헬퍼 함수들 + const addCondition = () => { + const newCondition: ConditionNode = { + type: "condition", + field: "", + operator_type: "=", + value: "", + dataType: "string", + }; + setConditions([...conditions, newCondition]); + }; + + const updateCondition = (index: number, field: keyof ConditionNode, value: string) => { + const updatedConditions = [...conditions]; + updatedConditions[index] = { ...updatedConditions[index], [field]: value }; + setConditions(updatedConditions); + }; + + const removeCondition = (index: number) => { + const updatedConditions = conditions.filter((_, i) => i !== index); + setConditions(updatedConditions); + }; + + // 조건부 연결 설정 UI 렌더링 + const renderConditionalSettings = () => { + return ( +
+
+ + 조건부 실행 설정 +
+ + {/* 트리거 타입 선택 */} +
+ + +
+ + {/* 실행 조건 설정 */} +
+
+ + +
+ + {/* 조건 목록 */} +
+ {conditions.length === 0 ? ( +
+ 조건을 추가하면 해당 조건을 만족할 때만 실행됩니다. +
+ 조건이 없으면 항상 실행됩니다. +
+ ) : ( + conditions.map((condition, index) => ( +
+ + + + + updateCondition(index, "value", e.target.value)} + className="h-8 flex-1 text-xs" + /> + + +
+ )) + )} +
+
+ + {/* 추가 옵션 */} +
+ + + +
+
+ ); + }; // 연결 종류별 설정 패널 렌더링 const renderConnectionTypeSettings = () => { @@ -724,6 +907,9 @@ export const ConnectionSetupModal: React.FC = ({ + {/* 조건부 연결을 위한 조건 설정 */} + {isConditionalConnection() && renderConditionalSettings()} + {/* 연결 종류별 상세 설정 */} {renderConnectionTypeSettings()} diff --git a/frontend/components/dataflow/DataFlowDesigner.tsx b/frontend/components/dataflow/DataFlowDesigner.tsx index a9e52128..93c7f3fe 100644 --- a/frontend/components/dataflow/DataFlowDesigner.tsx +++ b/frontend/components/dataflow/DataFlowDesigner.tsx @@ -1254,7 +1254,6 @@ export const DataFlowDesigner: React.FC = ({ isOpen={!!pendingConnection} connection={pendingConnection} companyCode={companyCode} - diagramId={currentDiagramId || diagramId || (relationshipId ? parseInt(relationshipId) : undefined)} onConfirm={handleConfirmConnection} onCancel={handleCancelConnection} />