"use client"; import React from "react"; import { Label } from "@/components/ui/label"; import { Input } from "@/components/ui/input"; import { Textarea } from "@/components/ui/textarea"; import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select"; import { Button } from "@/components/ui/button"; import { ExternalCallAPI } from "@/lib/api/externalCall"; import { toast } from "sonner"; import { Globe } from "lucide-react"; import { ExternalCallSettings as ExternalCallSettingsType } from "@/types/connectionTypes"; interface ExternalCallSettingsProps { settings: ExternalCallSettingsType; onSettingsChange: (settings: ExternalCallSettingsType) => void; } const handleTestExternalCall = async (settings: ExternalCallSettingsType) => { let loadingToastId: string | number | undefined; try { // 설정을 백엔드 형식으로 변환 const backendSettings: Record = { callType: settings.callType, timeout: 10000, // 10초 타임아웃 설정 }; if (settings.callType === "rest-api") { backendSettings.apiType = settings.apiType; switch (settings.apiType) { case "slack": backendSettings.webhookUrl = settings.slackWebhookUrl; backendSettings.message = settings.slackMessage || "테스트 메시지: {{recordCount}}건의 데이터가 처리되었습니다."; backendSettings.channel = settings.slackChannel; break; case "kakao-talk": backendSettings.accessToken = settings.kakaoAccessToken; backendSettings.message = settings.kakaoMessage || "테스트 메시지: {{recordCount}}건의 데이터가 처리되었습니다."; break; case "discord": backendSettings.webhookUrl = settings.discordWebhookUrl; backendSettings.message = settings.discordMessage || "테스트 메시지: {{recordCount}}건의 데이터가 처리되었습니다."; backendSettings.username = settings.discordUsername; break; case "generic": default: backendSettings.url = settings.apiUrl; backendSettings.method = settings.httpMethod || "POST"; try { backendSettings.headers = settings.headers ? JSON.parse(settings.headers) : {}; } catch (error) { console.warn("Headers JSON 파싱 실패, 기본값 사용:", error); backendSettings.headers = {}; } backendSettings.body = settings.bodyTemplate || "{}"; break; } } // 로딩 토스트 시작 loadingToastId = toast.loading("외부 호출 테스트 중...", { duration: 12000, // 12초 후 자동으로 사라짐 }); // 타임아웃을 위한 Promise.race 사용 const timeoutPromise = new Promise((_, reject) => { setTimeout(() => reject(new Error("테스트 요청이 10초 내에 완료되지 않았습니다.")), 10000); }); const testPromise = ExternalCallAPI.testExternalCall({ settings: backendSettings, templateData: { recordCount: 5, tableName: "test_table", timestamp: new Date().toISOString(), message: "데이터플로우 테스트 실행", }, }); const result = await Promise.race([testPromise, timeoutPromise]); // 로딩 토스트 제거 if (loadingToastId) { toast.dismiss(loadingToastId); } if (result.success && result.result?.success) { toast.success("외부 호출 테스트 성공!", { description: `응답 시간: ${result.result.executionTime}ms`, duration: 4000, }); } else { toast.error("외부 호출 테스트 실패", { description: result.result?.error || result.error || "알 수 없는 오류", duration: 6000, }); } } catch (error) { console.error("테스트 실행 중 오류:", error); // 로딩 토스트 제거 if (loadingToastId) { toast.dismiss(loadingToastId); } if (error instanceof Error) { toast.error("테스트 실행 중 오류가 발생했습니다.", { description: error.message, duration: 6000, }); } else { toast.error("테스트 실행 중 알 수 없는 오류가 발생했습니다.", { duration: 6000, }); } } }; export const ExternalCallSettings: React.FC = ({ settings, onSettingsChange }) => { return (
외부 호출 설정
{settings.callType === "rest-api" && ( <>
{/* 슬랙 설정 */} {settings.apiType === "slack" && ( <>
onSettingsChange({ ...settings, slackWebhookUrl: e.target.value })} placeholder="https://hooks.slack.com/services/..." className="text-sm" />
onSettingsChange({ ...settings, slackChannel: e.target.value })} placeholder="#general" className="text-sm" />