기타 수정사항 적용
This commit is contained in:
parent
fe6c0af5a8
commit
8e64b338a1
|
|
@ -15,7 +15,6 @@ export default function DataFlowPage() {
|
||||||
const { user } = useAuth();
|
const { user } = useAuth();
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const [currentStep, setCurrentStep] = useState<Step>("list");
|
const [currentStep, setCurrentStep] = useState<Step>("list");
|
||||||
const [selectedDiagram, setSelectedDiagram] = useState<DataFlowDiagram | null>(null);
|
|
||||||
const [stepHistory, setStepHistory] = useState<Step[]>(["list"]);
|
const [stepHistory, setStepHistory] = useState<Step[]>(["list"]);
|
||||||
|
|
||||||
// 단계별 제목과 설명
|
// 단계별 제목과 설명
|
||||||
|
|
@ -26,10 +25,8 @@ export default function DataFlowPage() {
|
||||||
icon: "📊",
|
icon: "📊",
|
||||||
},
|
},
|
||||||
design: {
|
design: {
|
||||||
title: selectedDiagram ? `${selectedDiagram.diagramName} 관계도 설계` : "새 관계도 설계",
|
title: "새 관계도 설계",
|
||||||
description: selectedDiagram
|
description: "테이블 간 데이터 관계를 시각적으로 설계하세요",
|
||||||
? "기존 관계도를 수정하거나 새로운 관계를 추가하세요"
|
|
||||||
: "테이블 간 데이터 관계를 시각적으로 설계하세요",
|
|
||||||
icon: "🎨",
|
icon: "🎨",
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
@ -47,11 +44,6 @@ export default function DataFlowPage() {
|
||||||
const previousStep = newHistory[newHistory.length - 1];
|
const previousStep = newHistory[newHistory.length - 1];
|
||||||
setStepHistory(newHistory);
|
setStepHistory(newHistory);
|
||||||
setCurrentStep(previousStep);
|
setCurrentStep(previousStep);
|
||||||
|
|
||||||
// list로 돌아갈 때 선택된 관계도 초기화
|
|
||||||
if (previousStep === "list") {
|
|
||||||
setSelectedDiagram(null);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -63,11 +55,6 @@ export default function DataFlowPage() {
|
||||||
if (stepIndex !== -1) {
|
if (stepIndex !== -1) {
|
||||||
setStepHistory(stepHistory.slice(0, stepIndex + 1));
|
setStepHistory(stepHistory.slice(0, stepIndex + 1));
|
||||||
}
|
}
|
||||||
|
|
||||||
// list로 이동할 때 선택된 관계도 초기화
|
|
||||||
if (step === "list") {
|
|
||||||
setSelectedDiagram(null);
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleSave = (relationships: TableRelationship[]) => {
|
const handleSave = (relationships: TableRelationship[]) => {
|
||||||
|
|
@ -78,17 +65,12 @@ export default function DataFlowPage() {
|
||||||
}, 0);
|
}, 0);
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleDiagramSelect = (diagram: DataFlowDiagram) => {
|
|
||||||
setSelectedDiagram(diagram);
|
|
||||||
};
|
|
||||||
|
|
||||||
const handleDesignDiagram = (diagram: DataFlowDiagram | null) => {
|
const handleDesignDiagram = (diagram: DataFlowDiagram | null) => {
|
||||||
if (diagram) {
|
if (diagram) {
|
||||||
// 기존 관계도 편집 - 새로운 URL로 이동
|
// 기존 관계도 편집 - 새로운 URL로 이동
|
||||||
router.push(`/admin/dataflow/edit/${diagram.diagramId}`);
|
router.push(`/admin/dataflow/edit/${diagram.diagramId}`);
|
||||||
} else {
|
} else {
|
||||||
// 새 관계도 생성 - 현재 페이지에서 처리
|
// 새 관계도 생성 - 현재 페이지에서 처리
|
||||||
setSelectedDiagram(null);
|
|
||||||
goToNextStep("design");
|
goToNextStep("design");
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
@ -121,11 +103,7 @@ export default function DataFlowPage() {
|
||||||
{/* 관계도 목록 단계 */}
|
{/* 관계도 목록 단계 */}
|
||||||
{currentStep === "list" && (
|
{currentStep === "list" && (
|
||||||
<div className="h-full p-6">
|
<div className="h-full p-6">
|
||||||
<DataFlowList
|
<DataFlowList onDesignDiagram={handleDesignDiagram} />
|
||||||
onDiagramSelect={handleDiagramSelect}
|
|
||||||
selectedDiagram={selectedDiagram}
|
|
||||||
onDesignDiagram={handleDesignDiagram}
|
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
|
|
@ -135,7 +113,7 @@ export default function DataFlowPage() {
|
||||||
<DataFlowDesigner
|
<DataFlowDesigner
|
||||||
companyCode={user?.company_code || "COMP001"}
|
companyCode={user?.company_code || "COMP001"}
|
||||||
onSave={handleSave}
|
onSave={handleSave}
|
||||||
selectedDiagram={selectedDiagram}
|
selectedDiagram={null}
|
||||||
onBackToList={() => goToStep("list")}
|
onBackToList={() => goToStep("list")}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -32,6 +32,12 @@ interface ConnectionInfo {
|
||||||
columns: string[];
|
columns: string[];
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
existingRelationship?: {
|
||||||
|
relationshipName: string;
|
||||||
|
relationshipType: string;
|
||||||
|
connectionType: string;
|
||||||
|
settings?: any;
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
// 연결 설정 타입
|
// 연결 설정 타입
|
||||||
|
|
@ -150,14 +156,18 @@ export const ConnectionSetupModal: React.FC<ConnectionSetupModalProps> = ({
|
||||||
setSelectedFromTable(fromTableName);
|
setSelectedFromTable(fromTableName);
|
||||||
setSelectedToTable(toTableName);
|
setSelectedToTable(toTableName);
|
||||||
|
|
||||||
|
// 기존 관계 정보가 있으면 사용, 없으면 기본값 설정
|
||||||
|
const existingRel = connection.existingRelationship;
|
||||||
setConfig({
|
setConfig({
|
||||||
relationshipName: `${fromDisplayName} → ${toDisplayName}`,
|
relationshipName: existingRel?.relationshipName || `${fromDisplayName} → ${toDisplayName}`,
|
||||||
relationshipType: "one-to-one",
|
relationshipType:
|
||||||
connectionType: "simple-key",
|
(existingRel?.relationshipType as "one-to-one" | "one-to-many" | "many-to-one" | "many-to-many") ||
|
||||||
|
"one-to-one",
|
||||||
|
connectionType: (existingRel?.connectionType as "simple-key" | "data-save" | "external-call") || "simple-key",
|
||||||
fromColumnName: "",
|
fromColumnName: "",
|
||||||
toColumnName: "",
|
toColumnName: "",
|
||||||
description: `${fromDisplayName}과 ${toDisplayName} 간의 데이터 관계`,
|
description: existingRel?.settings?.description || `${fromDisplayName}과 ${toDisplayName} 간의 데이터 관계`,
|
||||||
settings: {},
|
settings: existingRel?.settings || {},
|
||||||
});
|
});
|
||||||
|
|
||||||
// 단순 키값 연결 기본값 설정
|
// 단순 키값 연결 기본값 설정
|
||||||
|
|
|
||||||
|
|
@ -101,6 +101,12 @@ export const DataFlowDesigner: React.FC<DataFlowDesignerProps> = ({
|
||||||
columns: string[];
|
columns: string[];
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
existingRelationship?: {
|
||||||
|
relationshipName: string;
|
||||||
|
relationshipType: string;
|
||||||
|
connectionType: string;
|
||||||
|
settings?: any;
|
||||||
|
};
|
||||||
} | null>(null);
|
} | null>(null);
|
||||||
const [relationships, setRelationships] = useState<TableRelationship[]>([]); // eslint-disable-line @typescript-eslint/no-unused-vars
|
const [relationships, setRelationships] = useState<TableRelationship[]>([]); // eslint-disable-line @typescript-eslint/no-unused-vars
|
||||||
const [currentDiagramId, setCurrentDiagramId] = useState<number | null>(null); // 현재 화면의 diagram_id
|
const [currentDiagramId, setCurrentDiagramId] = useState<number | null>(null); // 현재 화면의 diagram_id
|
||||||
|
|
@ -989,6 +995,13 @@ export const DataFlowDesigner: React.FC<DataFlowDesignerProps> = ({
|
||||||
columns: edgeData.toColumns,
|
columns: edgeData.toColumns,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
// 기존 관계 정보 추가 (연결 이름 유지를 위해)
|
||||||
|
existingRelationship: {
|
||||||
|
relationshipName: existingRelationship.relationshipName,
|
||||||
|
relationshipType: existingRelationship.relationshipType,
|
||||||
|
connectionType: existingRelationship.connectionType,
|
||||||
|
settings: existingRelationship.settings,
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
// ConnectionSetupModal을 위한 연결 정보 설정
|
// ConnectionSetupModal을 위한 연결 정보 설정
|
||||||
|
|
@ -1123,8 +1136,8 @@ export const DataFlowDesigner: React.FC<DataFlowDesignerProps> = ({
|
||||||
<Background variant={BackgroundVariant.Dots} gap={20} size={1} color="#E5E7EB" />
|
<Background variant={BackgroundVariant.Dots} gap={20} size={1} color="#E5E7EB" />
|
||||||
</ReactFlow>
|
</ReactFlow>
|
||||||
|
|
||||||
{/* 선택된 컬럼 팝업 - 캔버스 좌측 상단 고정 (엣지 정보 팝업이 없을 때만 표시) */}
|
{/* 선택된 컬럼 팝업 - 캔버스 좌측 상단 고정 (신규 관계도 생성 시에만 표시) */}
|
||||||
{Object.keys(selectedColumns).length > 0 && !showEdgeActions && (
|
{Object.keys(selectedColumns).length > 0 && !showEdgeActions && !pendingConnection && !diagramId && (
|
||||||
<div className="pointer-events-auto absolute top-4 left-4 z-40 w-80 rounded-xl border border-blue-200 bg-white shadow-lg">
|
<div className="pointer-events-auto absolute top-4 left-4 z-40 w-80 rounded-xl border border-blue-200 bg-white shadow-lg">
|
||||||
{/* 헤더 */}
|
{/* 헤더 */}
|
||||||
<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 justify-between rounded-t-xl border-b border-blue-100 bg-gradient-to-r from-blue-50 to-indigo-50 p-3">
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,6 @@
|
||||||
import { useState, useEffect, useCallback } from "react";
|
import { useState, useEffect, useCallback } from "react";
|
||||||
import { Button } from "@/components/ui/button";
|
import { Button } from "@/components/ui/button";
|
||||||
import { Input } from "@/components/ui/input";
|
import { Input } from "@/components/ui/input";
|
||||||
import { Badge } from "@/components/ui/badge";
|
|
||||||
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
|
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
|
||||||
import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from "@/components/ui/table";
|
import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from "@/components/ui/table";
|
||||||
import {
|
import {
|
||||||
|
|
@ -26,12 +25,10 @@ import { toast } from "sonner";
|
||||||
import { useAuth } from "@/hooks/useAuth";
|
import { useAuth } from "@/hooks/useAuth";
|
||||||
|
|
||||||
interface DataFlowListProps {
|
interface DataFlowListProps {
|
||||||
onDiagramSelect: (diagram: DataFlowDiagram) => void;
|
|
||||||
selectedDiagram: DataFlowDiagram | null;
|
|
||||||
onDesignDiagram: (diagram: DataFlowDiagram | null) => void;
|
onDesignDiagram: (diagram: DataFlowDiagram | null) => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
export default function DataFlowList({ onDiagramSelect, selectedDiagram, onDesignDiagram }: DataFlowListProps) {
|
export default function DataFlowList({ onDesignDiagram }: DataFlowListProps) {
|
||||||
const { user } = useAuth();
|
const { user } = useAuth();
|
||||||
const [diagrams, setDiagrams] = useState<DataFlowDiagram[]>([]);
|
const [diagrams, setDiagrams] = useState<DataFlowDiagram[]>([]);
|
||||||
const [loading, setLoading] = useState(true);
|
const [loading, setLoading] = useState(true);
|
||||||
|
|
@ -88,10 +85,6 @@ export default function DataFlowList({ onDiagramSelect, selectedDiagram, onDesig
|
||||||
loadDiagrams();
|
loadDiagrams();
|
||||||
}, [loadDiagrams]);
|
}, [loadDiagrams]);
|
||||||
|
|
||||||
const handleDiagramSelect = (diagram: DataFlowDiagram) => {
|
|
||||||
onDiagramSelect(diagram);
|
|
||||||
};
|
|
||||||
|
|
||||||
const handleDelete = (diagram: DataFlowDiagram) => {
|
const handleDelete = (diagram: DataFlowDiagram) => {
|
||||||
setSelectedDiagramForAction(diagram);
|
setSelectedDiagramForAction(diagram);
|
||||||
setShowDeleteModal(true);
|
setShowDeleteModal(true);
|
||||||
|
|
@ -149,38 +142,6 @@ export default function DataFlowList({ onDiagramSelect, selectedDiagram, onDesig
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// 연결 타입에 따른 배지 색상
|
|
||||||
const getConnectionTypeBadge = (connectionType: string) => {
|
|
||||||
switch (connectionType) {
|
|
||||||
case "simple-key":
|
|
||||||
return (
|
|
||||||
<Badge variant="outline" className="border-blue-200 bg-blue-50 text-blue-700">
|
|
||||||
단순 키값
|
|
||||||
</Badge>
|
|
||||||
);
|
|
||||||
case "data-save":
|
|
||||||
return (
|
|
||||||
<Badge variant="outline" className="border-green-200 bg-green-50 text-green-700">
|
|
||||||
데이터 저장
|
|
||||||
</Badge>
|
|
||||||
);
|
|
||||||
case "external-call":
|
|
||||||
return (
|
|
||||||
<Badge variant="outline" className="border-purple-200 bg-purple-50 text-purple-700">
|
|
||||||
외부 호출
|
|
||||||
</Badge>
|
|
||||||
);
|
|
||||||
case "json-based":
|
|
||||||
return (
|
|
||||||
<Badge variant="outline" className="border-indigo-200 bg-indigo-50 text-indigo-700">
|
|
||||||
JSON 기반
|
|
||||||
</Badge>
|
|
||||||
);
|
|
||||||
default:
|
|
||||||
return <Badge variant="outline">{connectionType}</Badge>;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
if (loading) {
|
if (loading) {
|
||||||
return (
|
return (
|
||||||
<div className="flex items-center justify-center py-8">
|
<div className="flex items-center justify-center py-8">
|
||||||
|
|
@ -224,7 +185,6 @@ export default function DataFlowList({ onDiagramSelect, selectedDiagram, onDesig
|
||||||
<TableHeader>
|
<TableHeader>
|
||||||
<TableRow>
|
<TableRow>
|
||||||
<TableHead>관계도명</TableHead>
|
<TableHead>관계도명</TableHead>
|
||||||
<TableHead>연결 타입</TableHead>
|
|
||||||
<TableHead>회사 코드</TableHead>
|
<TableHead>회사 코드</TableHead>
|
||||||
<TableHead>테이블 수</TableHead>
|
<TableHead>테이블 수</TableHead>
|
||||||
<TableHead>관계 수</TableHead>
|
<TableHead>관계 수</TableHead>
|
||||||
|
|
@ -234,13 +194,7 @@ export default function DataFlowList({ onDiagramSelect, selectedDiagram, onDesig
|
||||||
</TableHeader>
|
</TableHeader>
|
||||||
<TableBody>
|
<TableBody>
|
||||||
{diagrams.map((diagram) => (
|
{diagrams.map((diagram) => (
|
||||||
<TableRow
|
<TableRow key={diagram.diagramId} className="hover:bg-gray-50">
|
||||||
key={diagram.diagramId}
|
|
||||||
className={`cursor-pointer hover:bg-gray-50 ${
|
|
||||||
selectedDiagram?.diagramId === diagram.diagramId ? "border-blue-200 bg-blue-50" : ""
|
|
||||||
}`}
|
|
||||||
onClick={() => handleDiagramSelect(diagram)}
|
|
||||||
>
|
|
||||||
<TableCell>
|
<TableCell>
|
||||||
<div>
|
<div>
|
||||||
<div className="flex items-center font-medium text-gray-900">
|
<div className="flex items-center font-medium text-gray-900">
|
||||||
|
|
@ -253,7 +207,6 @@ export default function DataFlowList({ onDiagramSelect, selectedDiagram, onDesig
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</TableCell>
|
</TableCell>
|
||||||
<TableCell>{getConnectionTypeBadge(diagram.connectionType)}</TableCell>
|
|
||||||
<TableCell>{diagram.companyCode || "*"}</TableCell>
|
<TableCell>{diagram.companyCode || "*"}</TableCell>
|
||||||
<TableCell>
|
<TableCell>
|
||||||
<div className="flex items-center">
|
<div className="flex items-center">
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue