diff --git a/frontend/components/dataflow/ConnectionSetupModal.tsx b/frontend/components/dataflow/ConnectionSetupModal.tsx index 8cb2c831..d00b2068 100644 --- a/frontend/components/dataflow/ConnectionSetupModal.tsx +++ b/frontend/components/dataflow/ConnectionSetupModal.tsx @@ -87,13 +87,17 @@ export const ConnectionSetupModal: React.FC = ({ } else if (connectionType === "data-save") { // data-save 설정 로드 - 안전하게 처리 (다양한 구조 지원) let actionsData: Record[] = []; + const settingsRecord = settings as Record; - if (Array.isArray((settings as any).actions)) { + if (Array.isArray(settingsRecord.actions)) { // 직접 actions 배열이 있는 경우 - actionsData = (settings as any).actions; - } else if ((settings as any).plan && Array.isArray((settings as any).plan.actions)) { + actionsData = settingsRecord.actions as Record[]; + } else if (settingsRecord.plan && typeof settingsRecord.plan === "object" && settingsRecord.plan !== null) { // plan 객체 안에 actions가 있는 경우 - actionsData = (settings as any).plan.actions; + const planRecord = settingsRecord.plan as Record; + if (Array.isArray(planRecord.actions)) { + actionsData = planRecord.actions as Record[]; + } } else if (Array.isArray(settings)) { // settings 자체가 actions 배열인 경우 actionsData = settings as Record[]; @@ -130,26 +134,34 @@ export const ConnectionSetupModal: React.FC = ({ }); // control 설정도 로드 (전체 실행 조건) - if ( - (settings as any).control && - (settings as any).control.conditionTree && - Array.isArray((settings as any).control.conditionTree) - ) { - const conditionTree = (settings as any).control.conditionTree as ConditionNode[]; - setConditions( - conditionTree.map((condition) => ({ - ...condition, - operator: condition.operator || "=", // 기본값 보장 - })), - ); + if (settingsRecord.control && typeof settingsRecord.control === "object" && settingsRecord.control !== null) { + const controlRecord = settingsRecord.control as Record; + if (Array.isArray(controlRecord.conditionTree)) { + const conditionTree = controlRecord.conditionTree as ConditionNode[]; + setConditions( + conditionTree.map((condition) => ({ + ...condition, + operator: condition.operator || "=", // 기본값 보장 + })), + ); + } } } else if (connectionType === "external-call") { setExternalCallSettings({ - callType: (settings.callType as "rest-api" | "webhook") || "rest-api", + callType: (settings.callType as "rest-api" | "email" | "ftp" | "queue") || "rest-api", apiUrl: (settings.apiUrl as string) || "", httpMethod: (settings.httpMethod as "GET" | "POST" | "PUT" | "DELETE") || "POST", headers: (settings.headers as string) || "{}", bodyTemplate: (settings.bodyTemplate as string) || "{}", + // 새로운 필드들도 로드 + apiType: (settings.apiType as "slack" | "kakao-talk" | "discord" | "generic") || "generic", + slackWebhookUrl: (settings.slackWebhookUrl as string) || "", + slackChannel: (settings.slackChannel as string) || "", + slackMessage: (settings.slackMessage as string) || "", + kakaoAccessToken: (settings.kakaoAccessToken as string) || "", + kakaoMessage: (settings.kakaoMessage as string) || "", + discordWebhookUrl: (settings.discordWebhookUrl as string) || "", + discordMessage: (settings.discordMessage as string) || "", }); } }, @@ -515,13 +527,24 @@ export const ConnectionSetupModal: React.FC = ({ switch (externalCallSettings.callType) { case "rest-api": - return !externalCallSettings.apiUrl?.trim(); - case "kakao-talk": - return !externalCallSettings.kakaoAccessToken?.trim() || !externalCallSettings.bodyTemplate?.trim(); + // REST API의 경우 apiType에 따라 다른 검증 + switch (externalCallSettings.apiType) { + case "slack": + return !externalCallSettings.slackWebhookUrl?.trim() || !externalCallSettings.slackMessage?.trim(); + case "kakao-talk": + return !externalCallSettings.kakaoAccessToken?.trim() || !externalCallSettings.kakaoMessage?.trim(); + case "discord": + return !externalCallSettings.discordWebhookUrl?.trim() || !externalCallSettings.discordMessage?.trim(); + case "generic": + default: + return !externalCallSettings.apiUrl?.trim(); + } case "email": return !externalCallSettings.apiUrl?.trim(); // 이메일 서버 URL 필요 - case "webhook": - return !externalCallSettings.apiUrl?.trim(); + case "ftp": + return !externalCallSettings.apiUrl?.trim(); // FTP 서버 URL 필요 + case "queue": + return !externalCallSettings.apiUrl?.trim(); // 큐 서버 URL 필요 default: return true; } diff --git a/frontend/components/dataflow/connection/ExternalCallSettings.tsx b/frontend/components/dataflow/connection/ExternalCallSettings.tsx index f919ad6c..f320585d 100644 --- a/frontend/components/dataflow/connection/ExternalCallSettings.tsx +++ b/frontend/components/dataflow/connection/ExternalCallSettings.tsx @@ -27,7 +27,7 @@ export const ExternalCallSettings: React.FC = ({ sett onSettingsChange({ ...settings, apiUrl: e.target.value })} - placeholder="https://api.example.com/webhook" - className="text-sm" - /> - -
-
- - -
-
- -