From ef5b86cc4ce990aa1dc35737e59979861f6112c8 Mon Sep 17 00:00:00 2001 From: dohyeons Date: Mon, 27 Oct 2025 09:39:11 +0900 Subject: [PATCH] =?UTF-8?q?rest=20api=20=EC=97=B0=EA=B2=B0=20ui=20?= =?UTF-8?q?=EA=B0=9C=EC=84=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../admin/ExternalDbConnectionModal.tsx | 21 +- .../admin/RestApiConnectionList.tsx | 204 +++++++++--------- .../admin/RestApiConnectionModal.tsx | 51 ++++- 3 files changed, 167 insertions(+), 109 deletions(-) diff --git a/frontend/components/admin/ExternalDbConnectionModal.tsx b/frontend/components/admin/ExternalDbConnectionModal.tsx index 5ab52491..8bf6c144 100644 --- a/frontend/components/admin/ExternalDbConnectionModal.tsx +++ b/frontend/components/admin/ExternalDbConnectionModal.tsx @@ -73,6 +73,9 @@ export const ExternalDbConnectionModal: React.FC // 연결 정보가 변경될 때 폼 데이터 업데이트 useEffect(() => { + // 테스트 관련 상태 초기화 + setTestResult(null); + if (connection) { setFormData({ ...connection, @@ -304,7 +307,9 @@ export const ExternalDbConnectionModal: React.FC - {isEditMode ? "연결 정보 수정" : "새 외부 DB 연결 추가"} + + {isEditMode ? "연결 정보 수정" : "새 외부 DB 연결 추가"} +
@@ -437,7 +442,7 @@ export const ExternalDbConnectionModal: React.FC type="button" variant="ghost" size="sm" - className="absolute right-0 top-0 h-full px-3 py-2 hover:bg-transparent" + className="absolute top-0 right-0 h-full px-3 py-2 hover:bg-transparent" onClick={() => setShowPassword(!showPassword)} > {showPassword ? : } @@ -464,7 +469,7 @@ export const ExternalDbConnectionModal: React.FC > {testingConnection ? "테스트 중..." : "연결 테스트"} - {testingConnection &&
연결을 확인하고 있습니다...
} + {testingConnection &&
연결을 확인하고 있습니다...
}
{/* 테스트 결과 표시 */} @@ -492,7 +497,9 @@ export const ExternalDbConnectionModal: React.FC {!testResult.success && testResult.error && (
오류 코드: {testResult.error.code}
- {testResult.error.details &&
{testResult.error.details}
} + {testResult.error.details && ( +
{testResult.error.details}
+ )}
)} @@ -602,7 +609,11 @@ export const ExternalDbConnectionModal: React.FC > 취소 - diff --git a/frontend/components/admin/RestApiConnectionList.tsx b/frontend/components/admin/RestApiConnectionList.tsx index 3f512af2..a66d79c4 100644 --- a/frontend/components/admin/RestApiConnectionList.tsx +++ b/frontend/components/admin/RestApiConnectionList.tsx @@ -206,7 +206,7 @@ export function RestApiConnectionList() {
{/* 검색 */}
- + - - 새 연결 추가 + 새 연결 추가
{/* 연결 목록 */} {loading ? ( -
-
로딩 중...
+
+
로딩 중...
) : connections.length === 0 ? ( -
+
-

등록된 REST API 연결이 없습니다

+

등록된 REST API 연결이 없습니다

) : ( -
+
- - - 연결명 - 기본 URL - 인증 타입 - 헤더 수 - 상태 - 마지막 테스트 - 연결 테스트 - 작업 - - - - {connections.map((connection) => ( - - -
{connection.connection_name}
+ + + 연결명 + 기본 URL + 인증 타입 + 헤더 수 + 상태 + 마지막 테스트 + 연결 테스트 + 작업 + + + + {connections.map((connection) => ( + + +
+
+ {connection.connection_name} +
{connection.description && ( -
{connection.description}
- )} - - {connection.base_url} - - - {AUTH_TYPE_LABELS[connection.auth_type] || connection.auth_type} - - - - {Object.keys(connection.default_headers || {}).length} - - - - {connection.is_active === "Y" ? "활성" : "비활성"} - - - - {connection.last_test_date ? ( -
-
{new Date(connection.last_test_date).toLocaleDateString()}
- - {connection.last_test_result === "Y" ? "성공" : "실패"} - +
+ {connection.description}
- ) : ( - - )} - - -
-
+
+ +
+ {connection.base_url} +
+
+ + {AUTH_TYPE_LABELS[connection.auth_type] || connection.auth_type} + + + {Object.keys(connection.default_headers || {}).length} + + + + {connection.is_active === "Y" ? "활성" : "비활성"} + + + + {connection.last_test_date ? ( +
+
{new Date(connection.last_test_date).toLocaleDateString()}
+ - {testingConnections.has(connection.id!) ? "테스트 중..." : "테스트"} - - {testResults.has(connection.id!) && ( - - {testResults.get(connection.id!) ? "성공" : "실패"} - - )} + {connection.last_test_result === "Y" ? "성공" : "실패"} +
-
- -
- - -
-
- - ))} - -
-
+ ) : ( + - + )} + + +
+ + {testResults.has(connection.id!) && ( + + {testResults.get(connection.id!) ? "성공" : "실패"} + + )} +
+
+ +
+ + +
+
+ + ))} + + +
)} {/* 연결 설정 모달 */} @@ -377,8 +384,7 @@ export function RestApiConnectionList() { 연결 삭제 확인 "{connectionToDelete?.connection_name}" 연결을 삭제하시겠습니까? -
- 이 작업은 되돌릴 수 없습니다. +
이 작업은 되돌릴 수 없습니다.
@@ -390,7 +396,7 @@ export function RestApiConnectionList() { 삭제 diff --git a/frontend/components/admin/RestApiConnectionModal.tsx b/frontend/components/admin/RestApiConnectionModal.tsx index 27b421cb..2b5d2097 100644 --- a/frontend/components/admin/RestApiConnectionModal.tsx +++ b/frontend/components/admin/RestApiConnectionModal.tsx @@ -46,6 +46,7 @@ export function RestApiConnectionModal({ isOpen, onClose, onSave, connection }: const [testEndpoint, setTestEndpoint] = useState(""); const [testing, setTesting] = useState(false); const [testResult, setTestResult] = useState(null); + const [testRequestUrl, setTestRequestUrl] = useState(""); const [saving, setSaving] = useState(false); // 기존 연결 데이터 로드 @@ -77,6 +78,7 @@ export function RestApiConnectionModal({ isOpen, onClose, onSave, connection }: setTestResult(null); setTestEndpoint(""); + setTestRequestUrl(""); }, [connection, isOpen]); // 연결 테스트 @@ -94,6 +96,10 @@ export function RestApiConnectionModal({ isOpen, onClose, onSave, connection }: setTesting(true); setTestResult(null); + // 사용자가 테스트하려는 실제 외부 API URL 설정 + const fullUrl = testEndpoint ? `${baseUrl}${testEndpoint}` : baseUrl; + setTestRequestUrl(fullUrl); + try { const result = await ExternalRestApiConnectionAPI.testConnection({ base_url: baseUrl, @@ -220,7 +226,7 @@ export function RestApiConnectionModal({ isOpen, onClose, onSave, connection }:
setShowAdvanced(!showAdvanced)} - className="flex items-center space-x-2 text-sm font-semibold hover:text-blue-600" + className="hover:text-primary flex items-center space-x-2 text-sm font-semibold transition-colors" > 고급 설정 {showAdvanced ? : } {showAdvanced && ( -
+
@@ -342,7 +348,7 @@ export function RestApiConnectionModal({ isOpen, onClose, onSave, connection }: id="test-endpoint" value={testEndpoint} onChange={(e) => setTestEndpoint(e.target.value)} - placeholder="/api/v1/test 또는 빈칸 (기본 URL만 테스트)" + placeholder="엔드포인트 또는 빈칸(기본 URL만 테스트)" />
@@ -351,6 +357,41 @@ export function RestApiConnectionModal({ isOpen, onClose, onSave, connection }: {testing ? "테스트 중..." : "연결 테스트"} + {/* 테스트 요청 정보 표시 */} + {testRequestUrl && ( +
+
+
테스트 요청 URL
+ GET {testRequestUrl} +
+ + {Object.keys(defaultHeaders).length > 0 && ( +
+
요청 헤더
+
+ {Object.entries(defaultHeaders).map(([key, value]) => ( + + {key}: {value} + + ))} +
+
+ )} + + {authType !== "none" && ( +
+
인증 방식
+ + {authType === "api-key" && "API Key"} + {authType === "bearer" && "Bearer Token"} + {authType === "basic" && "Basic Auth"} + {authType === "oauth2" && "OAuth 2.0"} + +
+ )} +
+ )} + {testResult && (