ERP-node/frontend/components/dataflow/RelationshipListModal.tsx

219 lines
8.4 KiB
TypeScript
Raw Normal View History

2025-09-16 14:57:47 +09:00
"use client";
import React from "react";
import { ExtendedJsonRelationship, TableNodeData } from "@/types/dataflowTypes";
import { DataFlowAPI } from "@/lib/api/dataflow";
interface RelationshipListModalProps {
isOpen: boolean;
relationships: ExtendedJsonRelationship[];
nodes: Array<{ id: string; data: TableNodeData }>;
diagramId?: number;
companyCode: string;
editingRelationshipId: string | null;
onClose: () => void;
onEdit: (relationship: ExtendedJsonRelationship) => void;
onDelete: (relationshipId: string) => void;
onSetEditingId: (id: string | null) => void;
onSetSelectedColumns: (columns: { [tableName: string]: string[] }) => void;
onSetPendingConnection: (connection: any) => void;
}
export const RelationshipListModal: React.FC<RelationshipListModalProps> = ({
isOpen,
relationships,
nodes,
diagramId,
companyCode,
editingRelationshipId,
onClose,
onEdit,
onDelete,
onSetEditingId,
onSetSelectedColumns,
onSetPendingConnection,
}) => {
if (!isOpen) return null;
const handleEdit = async (relationship: ExtendedJsonRelationship) => {
// 관계 선택 시 수정 모드로 전환
onSetEditingId(relationship.id);
// 관련 컬럼 하이라이트
const newSelectedColumns: { [tableName: string]: string[] } = {};
if (relationship.fromTable && relationship.fromColumns) {
newSelectedColumns[relationship.fromTable] = [...relationship.fromColumns];
}
if (relationship.toTable && relationship.toColumns) {
newSelectedColumns[relationship.toTable] = [...relationship.toColumns];
}
onSetSelectedColumns(newSelectedColumns);
// 🔥 수정: 관계 설정 정보 로드 (임시 관계 우선, 없으면 데이터베이스에서)
2025-09-16 14:57:47 +09:00
let relationshipSettings = {};
// 1. 먼저 임시 관계의 settings 사용 (메모리에 있는 데이터)
if (relationship.settings && Object.keys(relationship.settings).length > 0) {
relationshipSettings = relationship.settings;
}
// 2. 임시 settings가 없고 저장된 관계도인 경우 데이터베이스에서 로드
else if (diagramId && diagramId > 0) {
2025-09-16 14:57:47 +09:00
try {
const jsonDiagram = await DataFlowAPI.getJsonDataFlowDiagramById(diagramId, companyCode);
if (jsonDiagram && relationship.connectionType === "data-save") {
const control = jsonDiagram.control?.find((c) => c.id === relationship.id);
const plan = jsonDiagram.plan?.find((p) => p.id === relationship.id);
relationshipSettings = {
control: control
? {
triggerType: control.triggerType,
conditionTree: control.conditions || [],
}
: undefined,
actions: plan ? plan.actions || [] : [],
};
}
} catch (error) {
console.error("관계 설정 정보 로드 실패:", error);
}
}
// 연결 설정 모달 열기
const fromTable = nodes.find((node) => node.data?.table?.tableName === relationship.fromTable);
const toTable = nodes.find((node) => node.data?.table?.tableName === relationship.toTable);
if (fromTable && toTable) {
onSetPendingConnection({
fromNode: {
id: fromTable.id,
tableName: relationship.fromTable,
displayName: fromTable.data?.table?.displayName || relationship.fromTable,
},
toNode: {
id: toTable.id,
tableName: relationship.toTable,
displayName: toTable.data?.table?.displayName || relationship.toTable,
},
selectedColumnsData: {
[relationship.fromTable]: {
displayName: fromTable.data?.table?.displayName || relationship.fromTable,
columns: relationship.fromColumns || [],
},
[relationship.toTable]: {
displayName: toTable.data?.table?.displayName || relationship.toTable,
columns: relationship.toColumns || [],
},
},
existingRelationship: {
relationshipName: relationship.relationshipName,
connectionType: relationship.connectionType,
note: relationship.note, // 🔥 연결 설명 포함
2025-09-16 14:57:47 +09:00
settings: relationshipSettings,
},
});
}
// 모달 닫기
onClose();
};
const handleDelete = (relationship: ExtendedJsonRelationship) => {
onDelete(relationship.id);
// 선택된 컬럼 초기화
onSetSelectedColumns({});
// 편집 모드 해제
if (editingRelationshipId === relationship.id) {
onSetEditingId(null);
}
// 모달 닫기
onClose();
};
return (
<div className="pointer-events-auto absolute top-4 right-4 z-40 w-80 rounded-xl border border-primary/20 bg-white shadow-lg">
2025-09-16 14:57:47 +09:00
{/* 헤더 */}
<div className="flex items-center justify-between rounded-t-xl border-b border-blue-100 bg-gradient-to-r from-blue-50 to-indigo-50 p-3">
<div className="flex items-center gap-2">
<div className="rounded-full bg-primary/20 p-1">
<span className="text-sm text-primary">🔗</span>
2025-09-16 14:57:47 +09:00
</div>
<div className="text-sm font-semibold text-gray-800"> </div>
</div>
<button
onClick={onClose}
className="flex h-6 w-6 items-center justify-center rounded-full text-gray-400 transition-colors hover:bg-gray-100 hover:text-muted-foreground"
2025-09-16 14:57:47 +09:00
>
<svg className="h-4 w-4" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M6 18L18 6M6 6l12 12" />
</svg>
</button>
</div>
{/* 관계 목록 */}
<div className="p-3">
<div className="max-h-96 space-y-2 overflow-y-auto">
{relationships.map((relationship) => (
<div
key={relationship.id}
className="rounded-lg border border-gray-200 p-3 transition-all hover:border-blue-300 hover:bg-accent"
2025-09-16 14:57:47 +09:00
>
<div className="mb-1 flex items-center justify-between">
<h4 className="text-sm font-medium text-gray-900">
2025-09-16 16:49:59 +09:00
{relationship.relationshipName || `${relationship.fromTable}${relationship.toTable}`}
2025-09-16 14:57:47 +09:00
</h4>
<div className="flex items-center gap-1">
{/* 편집 버튼 */}
<button
onClick={(e) => {
e.stopPropagation();
handleEdit(relationship);
}}
className="flex h-6 w-6 items-center justify-center rounded text-gray-400 hover:bg-primary/20 hover:text-primary"
2025-09-16 14:57:47 +09:00
title="관계 편집"
>
<svg className="h-3 w-3" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path
strokeLinecap="round"
strokeLinejoin="round"
strokeWidth={2}
d="M11 5H6a2 2 0 00-2 2v11a2 2 0 002 2h11a2 2 0 002-2v-5m-1.414-9.414a2 2 0 112.828 2.828L11.828 15H9v-2.828l8.586-8.586z"
/>
</svg>
</button>
{/* 삭제 버튼 */}
<button
onClick={(e) => {
e.stopPropagation();
handleDelete(relationship);
}}
className="flex h-6 w-6 items-center justify-center rounded text-gray-400 hover:bg-destructive/20 hover:text-destructive"
2025-09-16 14:57:47 +09:00
title="관계 삭제"
>
<svg className="h-3 w-3" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path
strokeLinecap="round"
strokeLinejoin="round"
strokeWidth={2}
d="M19 7l-.867 12.142A2 2 0 0116.138 21H7.862a2 2 0 01-1.995-1.858L5 7m5 4v6m4-6v6m1-10V4a1 1 0 00-1-1h-4a1 1 0 00-1 1v3M4 7h16"
/>
</svg>
</button>
</div>
</div>
<div className="space-y-1 text-xs text-muted-foreground">
2025-09-16 14:57:47 +09:00
<p>: {relationship.connectionType}</p>
<p>From: {relationship.fromTable}</p>
<p>To: {relationship.toTable}</p>
</div>
</div>
))}
</div>
</div>
</div>
);
};