사이드바 디자인 다듬기
This commit is contained in:
@@ -1,12 +1,11 @@
|
||||
"use client";
|
||||
|
||||
import React, { useState, useEffect } from "react";
|
||||
import { useRouter } from "next/navigation";
|
||||
import { ChartDataSource } from "../types";
|
||||
import { ExternalDbConnectionAPI, ExternalDbConnection } from "@/lib/api/externalDbConnection";
|
||||
import { Card } from "@/components/ui/card";
|
||||
import { Label } from "@/components/ui/label";
|
||||
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { ExternalLink, Database, Server } from "lucide-react";
|
||||
|
||||
interface DatabaseConfigProps {
|
||||
@@ -20,6 +19,7 @@ interface DatabaseConfigProps {
|
||||
* - 외부 커넥션 목록 불러오기
|
||||
*/
|
||||
export function DatabaseConfig({ dataSource, onChange }: DatabaseConfigProps) {
|
||||
const router = useRouter();
|
||||
const [connections, setConnections] = useState<ExternalDbConnection[]>([]);
|
||||
const [loading, setLoading] = useState(false);
|
||||
const [error, setError] = useState<string | null>(null);
|
||||
@@ -49,93 +49,87 @@ export function DatabaseConfig({ dataSource, onChange }: DatabaseConfigProps) {
|
||||
const selectedConnection = connections.find((conn) => String(conn.id) === dataSource.externalConnectionId);
|
||||
|
||||
return (
|
||||
<div className="space-y-4">
|
||||
<div>
|
||||
<h3 className="text-lg font-semibold text-gray-800">2단계: 데이터베이스 설정</h3>
|
||||
<p className="mt-1 text-sm text-gray-600">데이터를 조회할 데이터베이스를 선택하세요</p>
|
||||
</div>
|
||||
|
||||
<div className="space-y-3">
|
||||
{/* 현재 DB vs 외부 DB 선택 */}
|
||||
<Card className="p-4">
|
||||
<Label className="mb-3 block text-sm font-medium text-gray-700">데이터베이스 선택</Label>
|
||||
<div className="grid grid-cols-2 gap-3">
|
||||
<Button
|
||||
variant={dataSource.connectionType === "current" ? "default" : "outline"}
|
||||
className="h-auto justify-start py-3"
|
||||
<div>
|
||||
<Label className="mb-2 block text-xs font-medium text-gray-700">데이터베이스 선택</Label>
|
||||
<div className="flex gap-2">
|
||||
<button
|
||||
onClick={() => {
|
||||
onChange({ connectionType: "current", externalConnectionId: undefined });
|
||||
}}
|
||||
className={`flex flex-1 items-center gap-1.5 rounded border px-2 py-1.5 text-xs transition-colors ${
|
||||
dataSource.connectionType === "current"
|
||||
? "bg-primary border-primary text-white"
|
||||
: "border-gray-200 bg-white hover:bg-gray-50"
|
||||
}`}
|
||||
>
|
||||
<Database className="mr-2 h-4 w-4" />
|
||||
<div className="text-left">
|
||||
<div className="font-medium">현재 DB</div>
|
||||
<div className="text-xs opacity-80">기본 DB</div>
|
||||
</div>
|
||||
</Button>
|
||||
<Database className="h-3 w-3" />
|
||||
현재 DB
|
||||
</button>
|
||||
|
||||
<Button
|
||||
variant={dataSource.connectionType === "external" ? "default" : "outline"}
|
||||
className="h-auto justify-start py-3"
|
||||
<button
|
||||
onClick={() => {
|
||||
onChange({ connectionType: "external" });
|
||||
}}
|
||||
className={`flex flex-1 items-center gap-1.5 rounded border px-2 py-1.5 text-xs transition-colors ${
|
||||
dataSource.connectionType === "external"
|
||||
? "bg-primary border-primary text-white"
|
||||
: "border-gray-200 bg-white hover:bg-gray-50"
|
||||
}`}
|
||||
>
|
||||
<Server className="mr-2 h-4 w-4" />
|
||||
<div className="text-left">
|
||||
<div className="font-medium">외부 DB</div>
|
||||
<div className="text-xs opacity-80">등록된 외부 커넥션</div>
|
||||
</div>
|
||||
</Button>
|
||||
<Server className="h-3 w-3" />
|
||||
외부 DB
|
||||
</button>
|
||||
</div>
|
||||
</Card>
|
||||
</div>
|
||||
|
||||
{/* 외부 DB 선택 시 커넥션 목록 */}
|
||||
{dataSource.connectionType === "external" && (
|
||||
<Card className="space-y-4 p-4">
|
||||
<div className="space-y-2">
|
||||
<div className="flex items-center justify-between">
|
||||
<Label className="text-sm font-medium text-gray-700">외부 커넥션 선택</Label>
|
||||
<Button
|
||||
variant="ghost"
|
||||
size="sm"
|
||||
<Label className="text-xs font-medium text-gray-700">외부 커넥션</Label>
|
||||
<button
|
||||
onClick={() => {
|
||||
window.open("/admin/external-connections", "_blank");
|
||||
router.push("/admin/external-connections");
|
||||
}}
|
||||
className="text-xs"
|
||||
className="flex items-center gap-1 text-[11px] text-blue-600 transition-colors hover:text-blue-700"
|
||||
>
|
||||
<ExternalLink className="mr-1 h-3 w-3" />
|
||||
<ExternalLink className="h-3 w-3" />
|
||||
커넥션 관리
|
||||
</Button>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
{loading && (
|
||||
<div className="flex items-center justify-center py-4">
|
||||
<div className="h-5 w-5 animate-spin rounded-full border-2 border-gray-300 border-t-blue-600" />
|
||||
<span className="ml-2 text-sm text-gray-600">커넥션 목록 불러오는 중...</span>
|
||||
<div className="flex items-center justify-center py-3">
|
||||
<div className="h-4 w-4 animate-spin rounded-full border-2 border-gray-300 border-t-blue-600" />
|
||||
<span className="ml-2 text-xs text-gray-600">로딩 중...</span>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{error && (
|
||||
<div className="rounded-lg border border-red-200 bg-red-50 p-3">
|
||||
<div className="text-sm text-red-800">❌ {error}</div>
|
||||
<Button variant="ghost" size="sm" onClick={loadExternalConnections} className="mt-2 text-xs">
|
||||
<div className="rounded bg-red-50 px-2 py-1.5">
|
||||
<div className="text-xs text-red-800">{error}</div>
|
||||
<button
|
||||
onClick={loadExternalConnections}
|
||||
className="mt-1 text-[11px] text-red-600 underline hover:no-underline"
|
||||
>
|
||||
다시 시도
|
||||
</Button>
|
||||
</button>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{!loading && !error && connections.length === 0 && (
|
||||
<div className="rounded-lg border border-yellow-200 bg-yellow-50 p-4 text-center">
|
||||
<div className="mb-2 text-sm text-yellow-800">등록된 외부 커넥션이 없습니다</div>
|
||||
<Button
|
||||
variant="outline"
|
||||
size="sm"
|
||||
<div className="rounded bg-yellow-50 px-2 py-2 text-center">
|
||||
<div className="mb-1 text-xs text-yellow-800">등록된 커넥션이 없습니다</div>
|
||||
<button
|
||||
onClick={() => {
|
||||
window.open("/admin/external-connections", "_blank");
|
||||
router.push("/admin/external-connections");
|
||||
}}
|
||||
className="text-[11px] text-yellow-700 underline hover:no-underline"
|
||||
>
|
||||
<ExternalLink className="mr-1 h-3 w-3" />
|
||||
커넥션 등록하기
|
||||
</Button>
|
||||
</button>
|
||||
</div>
|
||||
)}
|
||||
|
||||
@@ -147,15 +141,15 @@ export function DatabaseConfig({ dataSource, onChange }: DatabaseConfigProps) {
|
||||
onChange({ externalConnectionId: value });
|
||||
}}
|
||||
>
|
||||
<SelectTrigger className="w-full">
|
||||
<SelectValue placeholder="커넥션을 선택하세요" />
|
||||
<SelectTrigger className="h-8 w-full text-xs">
|
||||
<SelectValue placeholder="커넥션 선택" />
|
||||
</SelectTrigger>
|
||||
<SelectContent className="z-[9999]">
|
||||
{connections.map((conn) => (
|
||||
<SelectItem key={conn.id} value={String(conn.id)}>
|
||||
<div className="flex items-center gap-2">
|
||||
<SelectItem key={conn.id} value={String(conn.id)} className="text-xs">
|
||||
<div className="flex items-center gap-1.5">
|
||||
<span className="font-medium">{conn.connection_name}</span>
|
||||
<span className="text-xs text-gray-500">({conn.db_type.toUpperCase()})</span>
|
||||
<span className="text-[10px] text-gray-500">({conn.db_type.toUpperCase()})</span>
|
||||
</div>
|
||||
</SelectItem>
|
||||
))}
|
||||
@@ -163,31 +157,17 @@ export function DatabaseConfig({ dataSource, onChange }: DatabaseConfigProps) {
|
||||
</Select>
|
||||
|
||||
{selectedConnection && (
|
||||
<div className="rounded-lg border border-gray-200 bg-gray-50 p-3">
|
||||
<div className="space-y-1 text-xs text-gray-600">
|
||||
<div>
|
||||
<span className="font-medium">커넥션명:</span> {selectedConnection.connection_name}
|
||||
</div>
|
||||
<div>
|
||||
<span className="font-medium">타입:</span> {selectedConnection.db_type.toUpperCase()}
|
||||
</div>
|
||||
<div className="space-y-0.5 rounded bg-gray-50 px-2 py-1.5 text-[11px] text-gray-600">
|
||||
<div>
|
||||
<span className="font-medium">커넥션:</span> {selectedConnection.connection_name}
|
||||
</div>
|
||||
<div>
|
||||
<span className="font-medium">타입:</span> {selectedConnection.db_type.toUpperCase()}
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</>
|
||||
)}
|
||||
</Card>
|
||||
)}
|
||||
|
||||
{/* 다음 단계 안내 */}
|
||||
{(dataSource.connectionType === "current" ||
|
||||
(dataSource.connectionType === "external" && dataSource.externalConnectionId)) && (
|
||||
<div className="rounded-lg border border-blue-200 bg-blue-50 p-3">
|
||||
<div className="text-sm text-blue-800">
|
||||
데이터베이스가 선택되었습니다.
|
||||
<br />
|
||||
아래에서 SQL 쿼리를 작성하세요.
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user