Enhance batch management functionality by adding node flow execution support and improving batch configuration creation. Introduce new API endpoint for retrieving node flows and update existing batch services to handle execution types. Update frontend components to support new scheduling options and node flow selection.
This commit is contained in:
@@ -1,87 +1,38 @@
|
||||
"use client";
|
||||
|
||||
/**
|
||||
* 데이터 변환 노드
|
||||
*/
|
||||
|
||||
import { memo } from "react";
|
||||
import { Handle, Position, NodeProps } from "reactflow";
|
||||
import { Wand2, ArrowRight } from "lucide-react";
|
||||
import { NodeProps } from "reactflow";
|
||||
import { Repeat } from "lucide-react";
|
||||
import { CompactNodeShell } from "./CompactNodeShell";
|
||||
import type { DataTransformNodeData } from "@/types/node-editor";
|
||||
|
||||
export const DataTransformNode = memo(({ data, selected }: NodeProps<DataTransformNodeData>) => {
|
||||
const ruleCount = data.transformRules?.length || 0;
|
||||
const summary = ruleCount > 0
|
||||
? `${ruleCount}개 변환 규칙`
|
||||
: "변환 규칙을 설정해 주세요";
|
||||
|
||||
return (
|
||||
<div
|
||||
className={`min-w-[250px] rounded-lg border-2 bg-white shadow-md transition-all ${
|
||||
selected ? "border-orange-500 shadow-lg" : "border-border"
|
||||
}`}
|
||||
<CompactNodeShell
|
||||
color="#06B6D4"
|
||||
label={data.displayName || "데이터 변환"}
|
||||
summary={summary}
|
||||
icon={<Repeat className="h-3.5 w-3.5" />}
|
||||
selected={selected}
|
||||
>
|
||||
{/* 헤더 */}
|
||||
<div className="flex items-center gap-2 rounded-t-lg bg-primary px-3 py-2 text-white">
|
||||
<Wand2 className="h-4 w-4" />
|
||||
<div className="flex-1">
|
||||
<div className="text-sm font-semibold">{data.displayName || "데이터 변환"}</div>
|
||||
<div className="text-xs opacity-80">{data.transformations?.length || 0}개 변환</div>
|
||||
{ruleCount > 0 && (
|
||||
<div className="space-y-0.5">
|
||||
{data.transformRules!.slice(0, 3).map((r: any, i: number) => (
|
||||
<div key={i} className="flex items-center gap-1.5">
|
||||
<div className="h-1 w-1 rounded-full bg-cyan-400" />
|
||||
<span>{r.sourceField || r.field || `규칙 ${i + 1}`}</span>
|
||||
{r.targetField && <span className="text-zinc-600">→ {r.targetField}</span>}
|
||||
</div>
|
||||
))}
|
||||
{ruleCount > 3 && <span className="text-zinc-600">외 {ruleCount - 3}개</span>}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* 본문 */}
|
||||
<div className="p-3">
|
||||
{data.transformations && data.transformations.length > 0 ? (
|
||||
<div className="space-y-2">
|
||||
{data.transformations.slice(0, 3).map((transform, idx) => {
|
||||
const sourceLabel = transform.sourceFieldLabel || transform.sourceField || "소스";
|
||||
const targetField = transform.targetField || transform.sourceField;
|
||||
const targetLabel = transform.targetFieldLabel || targetField;
|
||||
const isInPlace = !transform.targetField || transform.targetField === transform.sourceField;
|
||||
|
||||
return (
|
||||
<div key={idx} className="rounded bg-indigo-50 p-2">
|
||||
<div className="mb-1 flex items-center gap-2 text-xs">
|
||||
<span className="font-medium text-indigo-700">{transform.type}</span>
|
||||
</div>
|
||||
<div className="text-xs text-muted-foreground">
|
||||
{sourceLabel}
|
||||
<span className="mx-1 text-muted-foreground/70">→</span>
|
||||
{isInPlace ? (
|
||||
<span className="font-medium text-primary">(자기자신)</span>
|
||||
) : (
|
||||
<span>{targetLabel}</span>
|
||||
)}
|
||||
</div>
|
||||
{/* 타입별 추가 정보 */}
|
||||
{transform.type === "EXPLODE" && transform.delimiter && (
|
||||
<div className="mt-1 text-xs text-muted-foreground">구분자: {transform.delimiter}</div>
|
||||
)}
|
||||
{transform.type === "CONCAT" && transform.separator && (
|
||||
<div className="mt-1 text-xs text-muted-foreground">구분자: {transform.separator}</div>
|
||||
)}
|
||||
{transform.type === "REPLACE" && (
|
||||
<div className="mt-1 text-xs text-muted-foreground">
|
||||
"{transform.searchValue}" → "{transform.replaceValue}"
|
||||
</div>
|
||||
)}
|
||||
{transform.expression && (
|
||||
<div className="mt-1 text-xs text-muted-foreground">
|
||||
<code className="rounded bg-white px-1 py-0.5">{transform.expression}</code>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
})}
|
||||
{data.transformations.length > 3 && (
|
||||
<div className="text-xs text-muted-foreground/70">... 외 {data.transformations.length - 3}개</div>
|
||||
)}
|
||||
</div>
|
||||
) : (
|
||||
<div className="py-4 text-center text-xs text-muted-foreground/70">변환 규칙 없음</div>
|
||||
)}
|
||||
</div>
|
||||
|
||||
{/* 핸들 */}
|
||||
<Handle type="target" position={Position.Left} className="!h-3 !w-3 !bg-primary" />
|
||||
<Handle type="source" position={Position.Right} className="!h-3 !w-3 !bg-primary" />
|
||||
</div>
|
||||
)}
|
||||
</CompactNodeShell>
|
||||
);
|
||||
});
|
||||
|
||||
|
||||
Reference in New Issue
Block a user