엣지 정보 조회 팝업 구현
This commit is contained in:
parent
16bc77797a
commit
f97e414df9
|
|
@ -250,8 +250,14 @@ export const DataFlowDesigner: React.FC<DataFlowDesignerProps> = ({
|
|||
console.log("📋 관계 목록:", relationships);
|
||||
console.log("📊 테이블 목록:", tableNames);
|
||||
|
||||
// 기존 데이터에서 relationshipName이 없는 경우 기본값 설정
|
||||
const normalizedRelationships = relationships.map((rel: JsonRelationship) => ({
|
||||
...rel,
|
||||
relationshipName: rel.relationshipName || `${rel.fromTable} → ${rel.toTable}`, // 기본값 설정
|
||||
}));
|
||||
|
||||
// 메모리에 관계 저장 (기존 관계도 편집 시)
|
||||
setTempRelationships(relationships);
|
||||
setTempRelationships(normalizedRelationships);
|
||||
setCurrentDiagramId(currentDiagramId);
|
||||
|
||||
// 테이블 노드 생성을 위한 테이블 정보 로드
|
||||
|
|
@ -381,7 +387,7 @@ export const DataFlowDesigner: React.FC<DataFlowDesignerProps> = ({
|
|||
},
|
||||
data: {
|
||||
relationshipId: rel.id,
|
||||
relationshipName: "기존 관계",
|
||||
relationshipName: rel.relationshipName,
|
||||
relationshipType: rel.relationshipType,
|
||||
connectionType: rel.connectionType,
|
||||
fromTable: fromTable,
|
||||
|
|
@ -703,6 +709,7 @@ export const DataFlowDesigner: React.FC<DataFlowDesignerProps> = ({
|
|||
// JSON 형태의 관계 객체 생성
|
||||
const newRelationship: JsonRelationship = {
|
||||
id: editingRelationshipId || generateUniqueId("rel", Date.now()), // 수정 모드면 기존 ID 사용
|
||||
relationshipName: relationship.relationship_name, // 연결 이름 추가
|
||||
fromTable,
|
||||
toTable,
|
||||
fromColumns,
|
||||
|
|
@ -737,7 +744,7 @@ export const DataFlowDesigner: React.FC<DataFlowDesignerProps> = ({
|
|||
},
|
||||
data: {
|
||||
relationshipId: newRelationship.id,
|
||||
relationshipName: "임시 관계",
|
||||
relationshipName: newRelationship.relationshipName,
|
||||
relationshipType: relationship.relationship_type,
|
||||
connectionType: relationship.connection_type,
|
||||
fromTable,
|
||||
|
|
@ -1149,39 +1156,6 @@ export const DataFlowDesigner: React.FC<DataFlowDesignerProps> = ({
|
|||
</div>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{/* 선택된 엣지 정보 */}
|
||||
{selectedEdgeInfo && (
|
||||
<div className="mt-6 space-y-4">
|
||||
<div className="rounded-lg border border-green-200 bg-green-50 p-4">
|
||||
<div className="mb-3 flex items-center justify-between">
|
||||
<div className="text-sm font-semibold text-green-800">🔗 연결 정보</div>
|
||||
<button onClick={() => setSelectedEdgeInfo(null)} className="text-green-600 hover:text-green-800">
|
||||
✕
|
||||
</button>
|
||||
</div>
|
||||
<div className="space-y-2 text-xs">
|
||||
<div className="rounded bg-white p-2">
|
||||
<div className="font-medium text-gray-700">연결</div>
|
||||
<div className="text-gray-600">
|
||||
{selectedEdgeInfo.fromTable}({selectedEdgeInfo.fromColumns.join(", ")}) →{" "}
|
||||
{selectedEdgeInfo.toTable}({selectedEdgeInfo.toColumns.join(", ")})
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex gap-2">
|
||||
<div className="flex-1 rounded bg-white p-2">
|
||||
<div className="font-medium text-gray-700">관계 유형</div>
|
||||
<div className="text-gray-600">{selectedEdgeInfo.relationshipType}</div>
|
||||
</div>
|
||||
<div className="flex-1 rounded bg-white p-2">
|
||||
<div className="font-medium text-gray-700">연결 유형</div>
|
||||
<div className="text-gray-600">{selectedEdgeInfo.connectionType}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
|
@ -1213,7 +1187,6 @@ export const DataFlowDesigner: React.FC<DataFlowDesignerProps> = ({
|
|||
selectionMode={SelectionMode.Partial}
|
||||
>
|
||||
<Controls />
|
||||
|
||||
<Background variant={BackgroundVariant.Dots} gap={20} size={1} color="#E5E7EB" />
|
||||
</ReactFlow>
|
||||
|
||||
|
|
@ -1243,27 +1216,108 @@ export const DataFlowDesigner: React.FC<DataFlowDesignerProps> = ({
|
|||
onCancel={handleCancelConnection}
|
||||
/>
|
||||
|
||||
{/* 엣지 액션 버튼 */}
|
||||
{showEdgeActions && selectedEdgeForEdit && (
|
||||
{/* 엣지 정보 및 액션 버튼 */}
|
||||
{showEdgeActions && selectedEdgeForEdit && selectedEdgeInfo && (
|
||||
<div
|
||||
className="fixed z-50 flex gap-2 rounded-lg border bg-white p-2 shadow-lg"
|
||||
className="fixed z-50 rounded-xl border border-gray-200 bg-white shadow-xl"
|
||||
style={{
|
||||
left: edgeActionPosition.x - 80,
|
||||
top: edgeActionPosition.y - 60,
|
||||
left: edgeActionPosition.x - 160,
|
||||
top: edgeActionPosition.y - 100,
|
||||
minWidth: "320px",
|
||||
maxWidth: "400px",
|
||||
}}
|
||||
>
|
||||
<button
|
||||
onClick={handleEditEdge}
|
||||
className="flex items-center gap-1 rounded bg-blue-500 px-3 py-1 text-xs text-white hover:bg-blue-600"
|
||||
>
|
||||
✏️ 수정
|
||||
</button>
|
||||
<button
|
||||
onClick={handleDeleteEdge}
|
||||
className="flex items-center gap-1 rounded bg-red-500 px-3 py-1 text-xs text-white hover:bg-red-600"
|
||||
>
|
||||
🗑️ 삭제
|
||||
</button>
|
||||
{/* 헤더 */}
|
||||
<div className="flex items-center justify-between rounded-t-xl border-b border-gray-100 bg-gradient-to-r from-blue-50 to-indigo-50 p-4">
|
||||
<div className="flex items-center gap-2">
|
||||
<div className="flex h-8 w-8 items-center justify-center rounded-full bg-blue-100">
|
||||
<span className="text-blue-600">🔗</span>
|
||||
</div>
|
||||
<div>
|
||||
<div className="font-semibold text-gray-800">{selectedEdgeInfo.relationshipName}</div>
|
||||
<div className="text-xs text-gray-500">데이터 관계</div>
|
||||
</div>
|
||||
</div>
|
||||
<button
|
||||
onClick={() => {
|
||||
setSelectedEdgeInfo(null);
|
||||
setShowEdgeActions(false);
|
||||
setSelectedEdgeForEdit(null);
|
||||
setSelectedColumns({});
|
||||
}}
|
||||
className="flex h-6 w-6 items-center justify-center rounded-full text-gray-400 hover:bg-gray-100 hover:text-gray-600"
|
||||
>
|
||||
✕
|
||||
</button>
|
||||
</div>
|
||||
|
||||
{/* 연결 정보 */}
|
||||
<div className="space-y-3 p-4">
|
||||
{/* From 테이블 */}
|
||||
<div className="rounded-lg bg-green-50 p-3">
|
||||
<div className="mb-1 text-xs font-medium text-green-700">From 테이블</div>
|
||||
<div className="font-semibold text-gray-800">{selectedEdgeInfo.fromTable}</div>
|
||||
<div className="mt-1 flex flex-wrap gap-1">
|
||||
{selectedEdgeInfo.fromColumns.map((column, index) => (
|
||||
<span key={index} className="rounded bg-green-100 px-2 py-1 text-xs text-green-800">
|
||||
{column}
|
||||
</span>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* 화살표 */}
|
||||
<div className="flex justify-center">
|
||||
<div className="flex items-center gap-2 text-gray-400">
|
||||
<div className="h-px w-8 bg-gray-300"></div>
|
||||
<span className="text-lg">→</span>
|
||||
<div className="h-px w-8 bg-gray-300"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* To 테이블 */}
|
||||
<div className="rounded-lg bg-blue-50 p-3">
|
||||
<div className="mb-1 text-xs font-medium text-blue-700">To 테이블</div>
|
||||
<div className="font-semibold text-gray-800">{selectedEdgeInfo.toTable}</div>
|
||||
<div className="mt-1 flex flex-wrap gap-1">
|
||||
{selectedEdgeInfo.toColumns.map((column, index) => (
|
||||
<span key={index} className="rounded bg-blue-100 px-2 py-1 text-xs text-blue-800">
|
||||
{column}
|
||||
</span>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* 관계 정보 */}
|
||||
<div className="grid grid-cols-2 gap-2">
|
||||
<div className="rounded-lg bg-gray-50 p-2">
|
||||
<div className="text-xs font-medium text-gray-600">관계 유형</div>
|
||||
<div className="text-sm font-semibold text-gray-800">{selectedEdgeInfo.relationshipType}</div>
|
||||
</div>
|
||||
<div className="rounded-lg bg-gray-50 p-2">
|
||||
<div className="text-xs font-medium text-gray-600">연결 유형</div>
|
||||
<div className="text-sm font-semibold text-gray-800">{selectedEdgeInfo.connectionType}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* 액션 버튼 */}
|
||||
<div className="flex gap-2 border-t border-gray-100 p-4">
|
||||
<button
|
||||
onClick={handleEditEdge}
|
||||
className="flex flex-1 items-center justify-center gap-2 rounded-lg bg-blue-500 px-4 py-2 text-sm font-medium text-white transition-colors hover:bg-blue-600"
|
||||
>
|
||||
<span>✏️</span>
|
||||
<span>수정</span>
|
||||
</button>
|
||||
<button
|
||||
onClick={handleDeleteEdge}
|
||||
className="flex flex-1 items-center justify-center gap-2 rounded-lg bg-red-500 px-4 py-2 text-sm font-medium text-white transition-colors hover:bg-red-600"
|
||||
>
|
||||
<span>🗑️</span>
|
||||
<span>삭제</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
|
||||
|
|
|
|||
|
|
@ -143,6 +143,7 @@ export interface JsonDataFlowDiagram {
|
|||
|
||||
export interface JsonRelationship {
|
||||
id: string;
|
||||
relationshipName: string; // 연결 이름 추가
|
||||
fromTable: string;
|
||||
toTable: string;
|
||||
fromColumns: string[];
|
||||
|
|
@ -520,7 +521,7 @@ export class DataFlowAPI {
|
|||
const relationshipsData = jsonDiagram.relationships as { relationships: JsonRelationship[]; tables: string[] };
|
||||
const relationships: TableRelationship[] = relationshipsData.relationships.map((rel: JsonRelationship) => ({
|
||||
relationship_id: 0, // JSON 기반에서는 개별 relationship_id가 없음
|
||||
relationship_name: rel.id || "관계",
|
||||
relationship_name: rel.relationshipName || rel.id || "관계", // relationshipName 우선 사용
|
||||
from_table_name: rel.fromTable,
|
||||
to_table_name: rel.toTable,
|
||||
from_column_name: rel.fromColumns.join(","),
|
||||
|
|
|
|||
Loading…
Reference in New Issue