다중데이터베이스 연결 가능하게 함, 차트 위젯은 테스트 용도입니다.
This commit is contained in:
@@ -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"
|
||||
|
||||
Reference in New Issue
Block a user