외부 호출 설정 개선: API 종류 추가 및 슬랙, 카카오톡, 디스코드 전용 설정 필드 추가. ConnectionSetupModal에서 설정 로드 로직 개선 및 유효성 검사 로직 수정.
This commit is contained in:
@@ -27,7 +27,7 @@ export const ExternalCallSettings: React.FC<ExternalCallSettingsProps> = ({ sett
|
||||
</Label>
|
||||
<Select
|
||||
value={settings.callType}
|
||||
onValueChange={(value: "rest-api" | "email" | "webhook" | "kakao-talk" | "ftp" | "queue") =>
|
||||
onValueChange={(value: "rest-api" | "email" | "ftp" | "queue") =>
|
||||
onSettingsChange({ ...settings, callType: value })
|
||||
}
|
||||
>
|
||||
@@ -36,9 +36,7 @@ export const ExternalCallSettings: React.FC<ExternalCallSettingsProps> = ({ sett
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
<SelectItem value="rest-api">REST API 호출</SelectItem>
|
||||
<SelectItem value="kakao-talk"> 카카오톡 알림</SelectItem>
|
||||
<SelectItem value="email">이메일 전송</SelectItem>
|
||||
<SelectItem value="webhook">웹훅</SelectItem>
|
||||
<SelectItem value="ftp">FTP 업로드</SelectItem>
|
||||
<SelectItem value="queue">메시지 큐</SelectItem>
|
||||
</SelectContent>
|
||||
@@ -48,124 +46,199 @@ export const ExternalCallSettings: React.FC<ExternalCallSettingsProps> = ({ sett
|
||||
{settings.callType === "rest-api" && (
|
||||
<>
|
||||
<div>
|
||||
<Label htmlFor="apiUrl" className="text-sm">
|
||||
API URL
|
||||
<Label htmlFor="apiType" className="text-sm">
|
||||
API 종류
|
||||
</Label>
|
||||
<Input
|
||||
id="apiUrl"
|
||||
value={settings.apiUrl}
|
||||
onChange={(e) => onSettingsChange({ ...settings, apiUrl: e.target.value })}
|
||||
placeholder="https://api.example.com/webhook"
|
||||
className="text-sm"
|
||||
/>
|
||||
</div>
|
||||
<div className="grid grid-cols-2 gap-3">
|
||||
<div>
|
||||
<Label htmlFor="httpMethod" className="text-sm">
|
||||
HTTP Method
|
||||
</Label>
|
||||
<Select
|
||||
value={settings.httpMethod}
|
||||
onValueChange={(value: "GET" | "POST" | "PUT" | "DELETE") =>
|
||||
onSettingsChange({ ...settings, httpMethod: value })
|
||||
}
|
||||
>
|
||||
<SelectTrigger className="text-sm">
|
||||
<SelectValue />
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
<SelectItem value="GET">GET</SelectItem>
|
||||
<SelectItem value="POST">POST</SelectItem>
|
||||
<SelectItem value="PUT">PUT</SelectItem>
|
||||
<SelectItem value="DELETE">DELETE</SelectItem>
|
||||
</SelectContent>
|
||||
</Select>
|
||||
</div>
|
||||
<div>
|
||||
<Label htmlFor="headers" className="text-sm">
|
||||
Headers
|
||||
</Label>
|
||||
<Textarea
|
||||
id="headers"
|
||||
value={settings.headers}
|
||||
onChange={(e) => onSettingsChange({ ...settings, headers: e.target.value })}
|
||||
placeholder="{}"
|
||||
rows={1}
|
||||
className="text-sm"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<Label htmlFor="bodyTemplate" className="text-sm">
|
||||
Body Template
|
||||
</Label>
|
||||
<Textarea
|
||||
id="bodyTemplate"
|
||||
value={settings.bodyTemplate}
|
||||
onChange={(e) => onSettingsChange({ ...settings, bodyTemplate: e.target.value })}
|
||||
placeholder="{}"
|
||||
rows={2}
|
||||
className="text-sm"
|
||||
/>
|
||||
</div>
|
||||
</>
|
||||
)}
|
||||
|
||||
{settings.callType === "kakao-talk" && (
|
||||
<>
|
||||
<div>
|
||||
<Label htmlFor="kakaoAccessToken" className="text-sm">
|
||||
카카오 액세스 토큰 <span className="text-red-500">*</span>
|
||||
</Label>
|
||||
<Input
|
||||
id="kakaoAccessToken"
|
||||
type="password"
|
||||
value={settings.kakaoAccessToken || ""}
|
||||
onChange={(e) =>
|
||||
onSettingsChange({
|
||||
...settings,
|
||||
kakaoAccessToken: e.target.value,
|
||||
})
|
||||
<Select
|
||||
value={settings.apiType || "generic"}
|
||||
onValueChange={(value: "slack" | "kakao-talk" | "discord" | "generic") =>
|
||||
onSettingsChange({ ...settings, apiType: value })
|
||||
}
|
||||
placeholder="카카오 개발자 센터에서 발급받은 토큰"
|
||||
className="text-sm"
|
||||
/>
|
||||
<p className="mt-1 text-xs text-gray-600">
|
||||
💡{" "}
|
||||
<a
|
||||
href="https://developers.kakao.com"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
className="text-blue-500 hover:underline"
|
||||
>
|
||||
카카오 개발자 센터
|
||||
</a>
|
||||
에서 앱 등록 후 토큰을 발급받으세요
|
||||
</p>
|
||||
>
|
||||
<SelectTrigger className="text-sm">
|
||||
<SelectValue />
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
<SelectItem value="slack">슬랙</SelectItem>
|
||||
<SelectItem value="kakao-talk">카카오톡</SelectItem>
|
||||
<SelectItem value="discord">디스코드</SelectItem>
|
||||
<SelectItem value="generic">기타 (일반 API)</SelectItem>
|
||||
</SelectContent>
|
||||
</Select>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<Label htmlFor="kakaoMessage" className="text-sm">
|
||||
메시지 템플릿 <span className="text-red-500">*</span>
|
||||
</Label>
|
||||
<Textarea
|
||||
id="kakaoMessage"
|
||||
value={settings.bodyTemplate || ""}
|
||||
onChange={(e) =>
|
||||
onSettingsChange({
|
||||
...settings,
|
||||
bodyTemplate: e.target.value,
|
||||
})
|
||||
}
|
||||
placeholder="안녕하세요! {{customer_name}}님의 주문({{order_id}})이 처리되었습니다."
|
||||
rows={3}
|
||||
className="text-sm"
|
||||
/>
|
||||
<p className="mt-1 text-xs text-gray-600">
|
||||
💡 {"{{"} 필드명 {"}"} 형태로 데이터를 삽입할 수 있습니다 (예: {"{{"} user_name {"}"}, {"{{"} amount{" "}
|
||||
{"}"})
|
||||
</p>
|
||||
</div>
|
||||
{/* 슬랙 설정 */}
|
||||
{settings.apiType === "slack" && (
|
||||
<>
|
||||
<div>
|
||||
<Label htmlFor="slackWebhookUrl" className="text-sm">
|
||||
슬랙 웹훅 URL
|
||||
</Label>
|
||||
<Input
|
||||
id="slackWebhookUrl"
|
||||
value={settings.slackWebhookUrl || ""}
|
||||
onChange={(e) => onSettingsChange({ ...settings, slackWebhookUrl: e.target.value })}
|
||||
placeholder="https://hooks.slack.com/services/..."
|
||||
className="text-sm"
|
||||
/>
|
||||
</div>
|
||||
<div>
|
||||
<Label htmlFor="slackChannel" className="text-sm">
|
||||
채널
|
||||
</Label>
|
||||
<Input
|
||||
id="slackChannel"
|
||||
value={settings.slackChannel || ""}
|
||||
onChange={(e) => onSettingsChange({ ...settings, slackChannel: e.target.value })}
|
||||
placeholder="#general"
|
||||
className="text-sm"
|
||||
/>
|
||||
</div>
|
||||
<div>
|
||||
<Label htmlFor="slackMessage" className="text-sm">
|
||||
메시지 템플릿
|
||||
</Label>
|
||||
<Textarea
|
||||
id="slackMessage"
|
||||
value={settings.slackMessage || ""}
|
||||
onChange={(e) => onSettingsChange({ ...settings, slackMessage: e.target.value })}
|
||||
placeholder="데이터 처리가 완료되었습니다. 총 {{recordCount}}건이 처리되었습니다."
|
||||
rows={2}
|
||||
className="text-sm"
|
||||
/>
|
||||
</div>
|
||||
</>
|
||||
)}
|
||||
|
||||
{/* 카카오톡 설정 */}
|
||||
{settings.apiType === "kakao-talk" && (
|
||||
<>
|
||||
<div>
|
||||
<Label htmlFor="kakaoAccessToken" className="text-sm">
|
||||
카카오 액세스 토큰 <span className="text-red-500">*</span>
|
||||
</Label>
|
||||
<Input
|
||||
id="kakaoAccessToken"
|
||||
type="password"
|
||||
value={settings.kakaoAccessToken || ""}
|
||||
onChange={(e) => onSettingsChange({ ...settings, kakaoAccessToken: e.target.value })}
|
||||
placeholder="카카오 API 액세스 토큰을 입력하세요"
|
||||
className="text-sm"
|
||||
/>
|
||||
</div>
|
||||
<div>
|
||||
<Label htmlFor="kakaoMessage" className="text-sm">
|
||||
메시지 내용
|
||||
</Label>
|
||||
<Textarea
|
||||
id="kakaoMessage"
|
||||
value={settings.kakaoMessage || ""}
|
||||
onChange={(e) => onSettingsChange({ ...settings, kakaoMessage: e.target.value })}
|
||||
placeholder="데이터 처리 완료! 총 {{recordCount}}건 처리되었습니다."
|
||||
rows={2}
|
||||
className="text-sm"
|
||||
/>
|
||||
</div>
|
||||
</>
|
||||
)}
|
||||
|
||||
{/* 디스코드 설정 */}
|
||||
{settings.apiType === "discord" && (
|
||||
<>
|
||||
<div>
|
||||
<Label htmlFor="discordWebhookUrl" className="text-sm">
|
||||
디스코드 웹훅 URL
|
||||
</Label>
|
||||
<Input
|
||||
id="discordWebhookUrl"
|
||||
value={settings.discordWebhookUrl || ""}
|
||||
onChange={(e) => onSettingsChange({ ...settings, discordWebhookUrl: e.target.value })}
|
||||
placeholder="https://discord.com/api/webhooks/..."
|
||||
className="text-sm"
|
||||
/>
|
||||
</div>
|
||||
<div>
|
||||
<Label htmlFor="discordMessage" className="text-sm">
|
||||
메시지 내용
|
||||
</Label>
|
||||
<Textarea
|
||||
id="discordMessage"
|
||||
value={settings.discordMessage || ""}
|
||||
onChange={(e) => onSettingsChange({ ...settings, discordMessage: e.target.value })}
|
||||
placeholder="데이터 처리가 완료되었습니다! 🎉"
|
||||
rows={2}
|
||||
className="text-sm"
|
||||
/>
|
||||
</div>
|
||||
</>
|
||||
)}
|
||||
|
||||
{/* 일반 API 설정 */}
|
||||
{settings.apiType === "generic" && (
|
||||
<>
|
||||
<div>
|
||||
<Label htmlFor="apiUrl" className="text-sm">
|
||||
API URL
|
||||
</Label>
|
||||
<Input
|
||||
id="apiUrl"
|
||||
value={settings.apiUrl || ""}
|
||||
onChange={(e) => onSettingsChange({ ...settings, apiUrl: e.target.value })}
|
||||
placeholder="https://api.example.com/webhook"
|
||||
className="text-sm"
|
||||
/>
|
||||
</div>
|
||||
<div className="grid grid-cols-2 gap-3">
|
||||
<div>
|
||||
<Label htmlFor="httpMethod" className="text-sm">
|
||||
HTTP Method
|
||||
</Label>
|
||||
<Select
|
||||
value={settings.httpMethod}
|
||||
onValueChange={(value: "GET" | "POST" | "PUT" | "DELETE") =>
|
||||
onSettingsChange({ ...settings, httpMethod: value })
|
||||
}
|
||||
>
|
||||
<SelectTrigger className="text-sm">
|
||||
<SelectValue />
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
<SelectItem value="GET">GET</SelectItem>
|
||||
<SelectItem value="POST">POST</SelectItem>
|
||||
<SelectItem value="PUT">PUT</SelectItem>
|
||||
<SelectItem value="DELETE">DELETE</SelectItem>
|
||||
</SelectContent>
|
||||
</Select>
|
||||
</div>
|
||||
<div>
|
||||
<Label htmlFor="headers" className="text-sm">
|
||||
Headers
|
||||
</Label>
|
||||
<Textarea
|
||||
id="headers"
|
||||
value={settings.headers}
|
||||
onChange={(e) => onSettingsChange({ ...settings, headers: e.target.value })}
|
||||
placeholder="{}"
|
||||
rows={1}
|
||||
className="text-sm"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<Label htmlFor="bodyTemplate" className="text-sm">
|
||||
Body Template
|
||||
</Label>
|
||||
<Textarea
|
||||
id="bodyTemplate"
|
||||
value={settings.bodyTemplate}
|
||||
onChange={(e) => onSettingsChange({ ...settings, bodyTemplate: e.target.value })}
|
||||
placeholder="{}"
|
||||
rows={2}
|
||||
className="text-sm"
|
||||
/>
|
||||
</div>
|
||||
</>
|
||||
)}
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user