다중데이터베이스 연결 가능하게 함, 차트 위젯은 테스트 용도입니다.

This commit is contained in:
leeheejin
2025-10-28 18:58:40 +09:00
parent 0fe2fa9db1
commit 88d71da1a9
4 changed files with 175 additions and 449 deletions

View File

@@ -186,11 +186,11 @@ export default function MultiDatabaseConfig({ dataSource, onChange, onTestResult
};
return (
<div className="space-y-4 rounded-lg border p-4">
<h5 className="text-sm font-semibold">Database </h5>
<div className="space-y-2 rounded-lg border p-3">
<h5 className="text-xs font-semibold">Database </h5>
{/* 커넥션 타입 */}
<div className="space-y-2">
<div className="space-y-1">
<Label className="text-xs"> </Label>
<RadioGroup
value={dataSource.connectionType || "current"}
@@ -311,15 +311,12 @@ ORDER BY 하위부서수 DESC`,
value={dataSource.query || ""}
onChange={(e) => onChange({ query: e.target.value })}
placeholder="SELECT * FROM table_name WHERE ..."
className="min-h-[120px] font-mono text-xs"
className="min-h-[80px] font-mono text-xs"
/>
<p className="text-[10px] text-muted-foreground">
SELECT . .
</p>
</div>
{/* 자동 새로고침 설정 */}
<div className="space-y-2">
<div className="space-y-1">
<Label htmlFor={`refresh-${dataSource.id}`} className="text-xs">
</Label>
@@ -341,62 +338,53 @@ ORDER BY 하위부서수 DESC`,
<SelectItem value="3600">1</SelectItem>
</SelectContent>
</Select>
<p className="text-[10px] text-muted-foreground">
</p>
</div>
{/* 지도 색상 설정 (MapTestWidgetV2 전용) */}
<div className="space-y-3 rounded-lg border bg-muted/30 p-3">
<h5 className="text-xs font-semibold">🎨 </h5>
<div className="space-y-2 rounded-lg border bg-muted/30 p-2">
<h5 className="text-xs font-semibold">🎨 </h5>
{/* 색상 팔레트 */}
<div className="space-y-2">
<Label className="text-xs"></Label>
<div className="grid grid-cols-4 gap-2">
{[
{ name: "파랑", marker: "#3b82f6", polygon: "#3b82f6" },
{ name: "빨강", marker: "#ef4444", polygon: "#ef4444" },
{ name: "초록", marker: "#10b981", polygon: "#10b981" },
{ name: "노랑", marker: "#f59e0b", polygon: "#f59e0b" },
{ name: "보라", marker: "#8b5cf6", polygon: "#8b5cf6" },
{ name: "주황", marker: "#f97316", polygon: "#f97316" },
{ name: "청록", marker: "#06b6d4", polygon: "#06b6d4" },
{ name: "분홍", marker: "#ec4899", polygon: "#ec4899" },
].map((color) => {
const isSelected = dataSource.markerColor === color.marker;
return (
<button
key={color.name}
type="button"
onClick={() => onChange({
markerColor: color.marker,
polygonColor: color.polygon,
polygonOpacity: 0.5,
})}
className={`flex h-16 flex-col items-center justify-center gap-1 rounded-md border-2 transition-all hover:scale-105 ${
isSelected
? "border-primary bg-primary/10 shadow-md"
: "border-border bg-background hover:border-primary/50"
}`}
>
<div
className="h-6 w-6 rounded-full border-2 border-white shadow-sm"
style={{ backgroundColor: color.marker }}
/>
<span className="text-[10px] font-medium">{color.name}</span>
</button>
);
})}
</div>
<p className="text-[10px] text-muted-foreground">
</p>
<div className="grid grid-cols-4 gap-1.5">
{[
{ name: "파랑", marker: "#3b82f6", polygon: "#3b82f6" },
{ name: "빨강", marker: "#ef4444", polygon: "#ef4444" },
{ name: "초록", marker: "#10b981", polygon: "#10b981" },
{ name: "노랑", marker: "#f59e0b", polygon: "#f59e0b" },
{ name: "보라", marker: "#8b5cf6", polygon: "#8b5cf6" },
{ name: "주황", marker: "#f97316", polygon: "#f97316" },
{ name: "청록", marker: "#06b6d4", polygon: "#06b6d4" },
{ name: "분홍", marker: "#ec4899", polygon: "#ec4899" },
].map((color) => {
const isSelected = dataSource.markerColor === color.marker;
return (
<button
key={color.name}
type="button"
onClick={() => onChange({
markerColor: color.marker,
polygonColor: color.polygon,
polygonOpacity: 0.5,
})}
className={`flex h-12 flex-col items-center justify-center gap-0.5 rounded-md border-2 transition-all hover:scale-105 ${
isSelected
? "border-primary bg-primary/10 shadow-md"
: "border-border bg-background hover:border-primary/50"
}`}
>
<div
className="h-5 w-5 rounded-full border-2 border-white shadow-sm"
style={{ backgroundColor: color.marker }}
/>
<span className="text-[9px] font-medium">{color.name}</span>
</button>
);
})}
</div>
</div>
{/* 테스트 버튼 */}
<div className="space-y-2 border-t pt-4">
<div className="space-y-2 border-t pt-2">
<Button
variant="outline"
size="sm"
@@ -439,13 +427,13 @@ ORDER BY 하위부서수 DESC`,
{/* 컬럼 선택 (메트릭 위젯용) - 개선된 UI */}
{availableColumns.length > 0 && (
<div className="space-y-3 border-t pt-4">
<div className="space-y-2 border-t pt-2">
<div className="flex items-center justify-between">
<div>
<Label className="text-sm font-semibold"> </Label>
<p className="text-xs text-muted-foreground mt-0.5">
<Label className="text-xs font-semibold"> </Label>
<p className="text-[10px] text-muted-foreground mt-0.5">
{dataSource.selectedColumns && dataSource.selectedColumns.length > 0
? `${dataSource.selectedColumns.length} 컬럼 선택됨`
? `${dataSource.selectedColumns.length}개 선택됨`
: "모든 컬럼 표시"}
</p>
</div>
@@ -454,7 +442,7 @@ ORDER BY 하위부서수 DESC`,
variant="outline"
size="sm"
onClick={() => onChange({ selectedColumns: availableColumns })}
className="h-7 text-xs"
className="h-6 px-2 text-xs"
>
</Button>
@@ -462,7 +450,7 @@ ORDER BY 하위부서수 DESC`,
variant="outline"
size="sm"
onClick={() => onChange({ selectedColumns: [] })}
className="h-7 text-xs"
className="h-6 px-2 text-xs"
>
</Button>
@@ -475,12 +463,12 @@ ORDER BY 하위부서수 DESC`,
placeholder="컬럼 검색..."
value={columnSearchTerm}
onChange={(e) => setColumnSearchTerm(e.target.value)}
className="h-8 text-xs"
className="h-7 text-xs"
/>
)}
{/* 컬럼 카드 그리드 */}
<div className="grid grid-cols-1 gap-2 max-h-80 overflow-y-auto">
<div className="grid grid-cols-1 gap-1.5 max-h-60 overflow-y-auto">
{availableColumns
.filter(col =>
!columnSearchTerm ||
@@ -526,7 +514,7 @@ ORDER BY 하위부서수 DESC`,
onChange({ selectedColumns: newSelected });
}}
className={`
relative flex items-start gap-3 rounded-lg border p-3 cursor-pointer transition-all
relative flex items-start gap-2 rounded-lg border p-2 cursor-pointer transition-all
${isSelected
? "border-primary bg-primary/5 shadow-sm"
: "border-border bg-card hover:border-primary/50 hover:bg-muted/50"