189 lines
7.4 KiB
TypeScript
189 lines
7.4 KiB
TypeScript
"use client";
|
|
|
|
import React from "react";
|
|
import { Label } from "@/components/ui/label";
|
|
import { Textarea } from "@/components/ui/textarea";
|
|
import { Badge } from "@/components/ui/badge";
|
|
import { Key } from "lucide-react";
|
|
import { TableInfo, ColumnInfo } from "@/lib/api/dataflow";
|
|
import { SimpleKeySettings as SimpleKeySettingsType } from "@/types/connectionTypes";
|
|
|
|
interface SimpleKeySettingsProps {
|
|
settings: SimpleKeySettingsType;
|
|
onSettingsChange: (settings: SimpleKeySettingsType) => void;
|
|
availableTables: TableInfo[];
|
|
selectedFromTable: string;
|
|
selectedToTable: string;
|
|
fromTableColumns: ColumnInfo[];
|
|
toTableColumns: ColumnInfo[];
|
|
selectedFromColumns: string[];
|
|
selectedToColumns: string[];
|
|
onFromColumnsChange: (columns: string[]) => void;
|
|
onToColumnsChange: (columns: string[]) => void;
|
|
}
|
|
|
|
export const SimpleKeySettings: React.FC<SimpleKeySettingsProps> = ({
|
|
settings,
|
|
onSettingsChange,
|
|
availableTables,
|
|
selectedFromTable,
|
|
selectedToTable,
|
|
fromTableColumns,
|
|
toTableColumns,
|
|
selectedFromColumns,
|
|
selectedToColumns,
|
|
onFromColumnsChange,
|
|
onToColumnsChange,
|
|
}) => {
|
|
return (
|
|
<div className="space-y-4">
|
|
{/* 테이블 및 컬럼 선택 */}
|
|
<div className="rounded-lg border bg-gray-50 p-4">
|
|
<div className="mb-4 text-sm font-medium">테이블 및 컬럼 선택</div>
|
|
|
|
{/* 현재 선택된 테이블 표시 */}
|
|
<div className="mb-4 grid grid-cols-2 gap-4">
|
|
<div>
|
|
<Label className="text-xs font-medium text-gray-600">From 테이블</Label>
|
|
<div className="mt-1">
|
|
<span className="text-sm font-medium text-gray-800">
|
|
{availableTables.find((t) => t.tableName === selectedFromTable)?.displayName || selectedFromTable}
|
|
</span>
|
|
<span className="ml-2 text-xs text-gray-500">({selectedFromTable})</span>
|
|
</div>
|
|
</div>
|
|
|
|
<div>
|
|
<Label className="text-xs font-medium text-gray-600">To 테이블</Label>
|
|
<div className="mt-1">
|
|
<span className="text-sm font-medium text-gray-800">
|
|
{availableTables.find((t) => t.tableName === selectedToTable)?.displayName || selectedToTable}
|
|
</span>
|
|
<span className="ml-2 text-xs text-gray-500">({selectedToTable})</span>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
{/* 컬럼 선택 */}
|
|
<div className="grid grid-cols-2 gap-4">
|
|
<div>
|
|
<Label className="text-xs font-medium text-gray-600">From 컬럼</Label>
|
|
<div className="mt-2 max-h-32 overflow-y-auto rounded border bg-white p-2">
|
|
{fromTableColumns.map((column) => (
|
|
<label key={column.columnName} className="flex items-center gap-2 py-1 text-sm">
|
|
<input
|
|
type="checkbox"
|
|
checked={selectedFromColumns.includes(column.columnName)}
|
|
onChange={(e) => {
|
|
if (e.target.checked) {
|
|
onFromColumnsChange([...selectedFromColumns, column.columnName]);
|
|
} else {
|
|
onFromColumnsChange(selectedFromColumns.filter((col) => col !== column.columnName));
|
|
}
|
|
}}
|
|
className="rounded"
|
|
/>
|
|
<span>{column.columnName}</span>
|
|
<span className="text-xs text-gray-500">({column.dataType})</span>
|
|
</label>
|
|
))}
|
|
{fromTableColumns.length === 0 && (
|
|
<div className="py-2 text-xs text-gray-500">
|
|
{selectedFromTable ? "컬럼을 불러오는 중..." : "테이블을 먼저 선택해주세요"}
|
|
</div>
|
|
)}
|
|
</div>
|
|
</div>
|
|
|
|
<div>
|
|
<Label className="text-xs font-medium text-gray-600">To 컬럼</Label>
|
|
<div className="mt-2 max-h-32 overflow-y-auto rounded border bg-white p-2">
|
|
{toTableColumns.map((column) => (
|
|
<label key={column.columnName} className="flex items-center gap-2 py-1 text-sm">
|
|
<input
|
|
type="checkbox"
|
|
checked={selectedToColumns.includes(column.columnName)}
|
|
onChange={(e) => {
|
|
if (e.target.checked) {
|
|
onToColumnsChange([...selectedToColumns, column.columnName]);
|
|
} else {
|
|
onToColumnsChange(selectedToColumns.filter((col) => col !== column.columnName));
|
|
}
|
|
}}
|
|
className="rounded"
|
|
/>
|
|
<span>{column.columnName}</span>
|
|
<span className="text-xs text-gray-500">({column.dataType})</span>
|
|
</label>
|
|
))}
|
|
{toTableColumns.length === 0 && (
|
|
<div className="py-2 text-xs text-gray-500">
|
|
{selectedToTable ? "컬럼을 불러오는 중..." : "테이블을 먼저 선택해주세요"}
|
|
</div>
|
|
)}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
{/* 선택된 컬럼 미리보기 */}
|
|
{(selectedFromColumns.length > 0 || selectedToColumns.length > 0) && (
|
|
<div className="mt-4 grid grid-cols-2 gap-4">
|
|
<div>
|
|
<Label className="text-xs font-medium text-gray-600">선택된 From 컬럼</Label>
|
|
<div className="mt-1 flex flex-wrap gap-1">
|
|
{selectedFromColumns.length > 0 ? (
|
|
selectedFromColumns.map((column) => (
|
|
<Badge key={column} variant="outline" className="text-xs">
|
|
{column}
|
|
</Badge>
|
|
))
|
|
) : (
|
|
<span className="text-xs text-gray-400">선택된 컬럼 없음</span>
|
|
)}
|
|
</div>
|
|
</div>
|
|
|
|
<div>
|
|
<Label className="text-xs font-medium text-gray-600">선택된 To 컬럼</Label>
|
|
<div className="mt-1 flex flex-wrap gap-1">
|
|
{selectedToColumns.length > 0 ? (
|
|
selectedToColumns.map((column) => (
|
|
<Badge key={column} variant="secondary" className="text-xs">
|
|
{column}
|
|
</Badge>
|
|
))
|
|
) : (
|
|
<span className="text-xs text-gray-400">선택된 컬럼 없음</span>
|
|
)}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
)}
|
|
</div>
|
|
|
|
{/* 단순 키값 연결 설정 */}
|
|
<div className="rounded-lg border border-l-4 border-l-blue-500 bg-blue-50/30 p-4">
|
|
<div className="mb-3 flex items-center gap-2">
|
|
<Key className="h-4 w-4 text-blue-500" />
|
|
<span className="text-sm font-medium">단순 키값 연결 설정</span>
|
|
</div>
|
|
<div className="space-y-3">
|
|
<div>
|
|
<Label htmlFor="notes" className="text-sm">
|
|
연결 설명
|
|
</Label>
|
|
<Textarea
|
|
id="notes"
|
|
value={settings.notes}
|
|
onChange={(e) => onSettingsChange({ ...settings, notes: e.target.value })}
|
|
placeholder="데이터 연결에 대한 설명을 입력하세요"
|
|
rows={2}
|
|
className="text-sm"
|
|
/>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
);
|
|
};
|