diff --git a/frontend/app/(main)/admin/automaticMng/batchmngList/create/page.tsx b/frontend/app/(main)/admin/automaticMng/batchmngList/create/page.tsx index a4e1095c..2c8feef2 100644 --- a/frontend/app/(main)/admin/automaticMng/batchmngList/create/page.tsx +++ b/frontend/app/(main)/admin/automaticMng/batchmngList/create/page.tsx @@ -7,6 +7,7 @@ import { Input } from "@/components/ui/input"; import { Label } from "@/components/ui/label"; import { Textarea } from "@/components/ui/textarea"; import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select"; +import { RadioGroup, RadioGroupItem } from "@/components/ui/radio-group"; import { Badge } from "@/components/ui/badge"; import { ArrowLeft, Save, RefreshCw, ArrowRight, Trash2 } from "lucide-react"; import { toast } from "sonner"; @@ -18,6 +19,7 @@ import { ConnectionInfo, ColumnInfo, BatchMappingRequest, + NodeFlowItem, } from "@/lib/api/batch"; export default function BatchCreatePage() { @@ -42,6 +44,11 @@ export default function BatchCreatePage() { // 매핑 상태 const [selectedFromColumn, setSelectedFromColumn] = useState(null); const [mappings, setMappings] = useState([]); + + // 실행 타입: 데이터 매핑 / 노드 플로우 + const [executionType, setExecutionType] = useState<"mapping" | "node_flow">("mapping"); + const [selectedFlowId, setSelectedFlowId] = useState(null); + const [nodeFlows, setNodeFlows] = useState([]); // 로딩 상태 const [loading, setLoading] = useState(false); @@ -52,6 +59,17 @@ export default function BatchCreatePage() { loadConnections(); }, []); + // 노드 플로우 목록 로드 (실행 타입 노드 플로우 시 사용) + useEffect(() => { + if (executionType !== "node_flow") return; + const load = async () => { + const res = await BatchAPI.getNodeFlows(); + if (res.success && res.data) setNodeFlows(res.data); + else setNodeFlows([]); + }; + load(); + }, [executionType]); + const loadConnections = async () => { setLoadingConnections(true); try { @@ -221,19 +239,28 @@ export default function BatchCreatePage() { return; } - if (mappings.length === 0) { - toast.error("최소 하나 이상의 매핑을 추가해주세요."); - return; + if (executionType === "mapping") { + if (mappings.length === 0) { + toast.error("최소 하나 이상의 매핑을 추가해주세요."); + return; + } + } else { + if (selectedFlowId == null) { + toast.error("노드 플로우를 선택해주세요."); + return; + } } setLoading(true); try { - const request = { + const request: BatchMappingRequest = { batchName: batchName, description: description || undefined, cronSchedule: cronSchedule, - mappings: mappings, - isActive: true + mappings: executionType === "mapping" ? mappings : [], + isActive: true, + executionType, + nodeFlowId: executionType === "node_flow" ? selectedFlowId ?? undefined : undefined, }; await BatchAPI.createBatchConfig(request); @@ -305,10 +332,66 @@ export default function BatchCreatePage() { rows={3} /> + + {/* 실행 타입 */} +
+ + { + setExecutionType(v as "mapping" | "node_flow"); + if (v === "mapping") setSelectedFlowId(null); + }} + className="flex flex-col gap-2 sm:flex-row sm:gap-6" + > +
+ + +
+
+ + +
+
+ {executionType === "node_flow" && ( +
+ + + {selectedFlowId != null && nodeFlows.find((f) => f.flow_id === selectedFlowId)?.description && ( +

+ {nodeFlows.find((f) => f.flow_id === selectedFlowId)?.description} +

+ )} +
+ )} +
- {/* 매핑 설정 */} + {/* 매핑 설정 - 데이터 매핑일 때만 표시 */} + {executionType === "mapping" && (
{/* FROM 섹션 */} @@ -474,9 +557,10 @@ export default function BatchCreatePage() {
+ )} {/* 매핑 현황 */} - {mappings.length > 0 && ( + {executionType === "mapping" && mappings.length > 0 && ( 컬럼 매핑 현황 ({mappings.length}개) @@ -529,7 +613,7 @@ export default function BatchCreatePage() {