외부호출 노드들
This commit is contained in:
@@ -0,0 +1,124 @@
|
||||
"use client";
|
||||
|
||||
/**
|
||||
* HTTP 요청 액션 노드
|
||||
* REST API를 호출하는 노드
|
||||
*/
|
||||
|
||||
import { memo } from "react";
|
||||
import { Handle, Position, NodeProps } from "reactflow";
|
||||
import { Globe, Lock, Unlock } from "lucide-react";
|
||||
import type { HttpRequestActionNodeData } from "@/types/node-editor";
|
||||
|
||||
// HTTP 메서드별 색상
|
||||
const METHOD_COLORS: Record<string, { bg: string; text: string }> = {
|
||||
GET: { bg: "bg-green-100", text: "text-green-700" },
|
||||
POST: { bg: "bg-blue-100", text: "text-blue-700" },
|
||||
PUT: { bg: "bg-orange-100", text: "text-orange-700" },
|
||||
PATCH: { bg: "bg-yellow-100", text: "text-yellow-700" },
|
||||
DELETE: { bg: "bg-red-100", text: "text-red-700" },
|
||||
HEAD: { bg: "bg-gray-100", text: "text-gray-700" },
|
||||
OPTIONS: { bg: "bg-purple-100", text: "text-purple-700" },
|
||||
};
|
||||
|
||||
export const HttpRequestActionNode = memo(({ data, selected }: NodeProps<HttpRequestActionNodeData>) => {
|
||||
const methodColor = METHOD_COLORS[data.method] || METHOD_COLORS.GET;
|
||||
const hasUrl = data.url && data.url.trim().length > 0;
|
||||
const hasAuth = data.authentication?.type && data.authentication.type !== "none";
|
||||
|
||||
// URL에서 도메인 추출
|
||||
const getDomain = (url: string) => {
|
||||
try {
|
||||
const urlObj = new URL(url);
|
||||
return urlObj.hostname;
|
||||
} catch {
|
||||
return url;
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<div
|
||||
className={`min-w-[250px] rounded-lg border-2 bg-white shadow-md transition-all ${
|
||||
selected ? "border-cyan-500 shadow-lg" : "border-gray-200"
|
||||
}`}
|
||||
>
|
||||
{/* 입력 핸들 */}
|
||||
<Handle
|
||||
type="target"
|
||||
position={Position.Left}
|
||||
className="!h-3 !w-3 !border-2 !border-white !bg-cyan-500"
|
||||
/>
|
||||
|
||||
{/* 헤더 */}
|
||||
<div className="flex items-center gap-2 rounded-t-lg bg-cyan-500 px-3 py-2 text-white">
|
||||
<Globe className="h-4 w-4" />
|
||||
<div className="flex-1">
|
||||
<div className="text-sm font-semibold">{data.displayName || "HTTP 요청"}</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* 본문 */}
|
||||
<div className="space-y-2 p-3">
|
||||
{/* 메서드 & 인증 */}
|
||||
<div className="flex items-center gap-2">
|
||||
<span className={`rounded px-2 py-0.5 text-xs font-bold ${methodColor.bg} ${methodColor.text}`}>
|
||||
{data.method}
|
||||
</span>
|
||||
{hasAuth ? (
|
||||
<span className="flex items-center gap-1 rounded bg-green-100 px-1.5 py-0.5 text-xs text-green-700">
|
||||
<Lock className="h-3 w-3" />
|
||||
{data.authentication?.type}
|
||||
</span>
|
||||
) : (
|
||||
<span className="flex items-center gap-1 rounded bg-gray-100 px-1.5 py-0.5 text-xs text-gray-500">
|
||||
<Unlock className="h-3 w-3" />
|
||||
인증없음
|
||||
</span>
|
||||
)}
|
||||
</div>
|
||||
|
||||
{/* URL */}
|
||||
<div className="text-xs">
|
||||
<span className="text-gray-500">URL: </span>
|
||||
{hasUrl ? (
|
||||
<span className="truncate text-gray-700" title={data.url}>
|
||||
{getDomain(data.url)}
|
||||
</span>
|
||||
) : (
|
||||
<span className="text-orange-500">URL 설정 필요</span>
|
||||
)}
|
||||
</div>
|
||||
|
||||
{/* 바디 타입 */}
|
||||
{data.bodyType && data.bodyType !== "none" && (
|
||||
<div className="text-xs">
|
||||
<span className="text-gray-500">Body: </span>
|
||||
<span className="rounded bg-gray-100 px-1.5 py-0.5 text-gray-600">
|
||||
{data.bodyType.toUpperCase()}
|
||||
</span>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{/* 타임아웃 & 재시도 */}
|
||||
<div className="flex gap-2 text-xs text-gray-500">
|
||||
{data.options?.timeout && (
|
||||
<span>타임아웃: {Math.round(data.options.timeout / 1000)}초</span>
|
||||
)}
|
||||
{data.options?.retryCount && data.options.retryCount > 0 && (
|
||||
<span>재시도: {data.options.retryCount}회</span>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* 출력 핸들 */}
|
||||
<Handle
|
||||
type="source"
|
||||
position={Position.Right}
|
||||
className="!h-3 !w-3 !border-2 !border-white !bg-cyan-500"
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
});
|
||||
|
||||
HttpRequestActionNode.displayName = "HttpRequestActionNode";
|
||||
|
||||
Reference in New Issue
Block a user