diff --git a/backend/diagrams/diagram_argo.json b/backend/diagrams/diagram_argo.json deleted file mode 100644 index 184c8c0..0000000 --- a/backend/diagrams/diagram_argo.json +++ /dev/null @@ -1,19 +0,0 @@ -{ - "nodes": [ - { - "id": "1", - "type": "custom", - "data": { - "label": "Node 1", - "icon": "https://s3.dvirlabs.com/lab-icons/dev-tools/argocd.svg" - }, - "position": { - "x": 307.58165778037267, - "y": 195.1586839847007 - }, - "width": 103, - "height": 103 - } - ], - "edges": [] -} \ No newline at end of file diff --git a/frontend/src/components/ColorNode.jsx b/frontend/src/components/ColorNode.jsx deleted file mode 100644 index 8eafab3..0000000 --- a/frontend/src/components/ColorNode.jsx +++ /dev/null @@ -1,26 +0,0 @@ -import { Handle, Position } from 'reactflow'; - -function ColorNode({ data }) { - return ( -
- -
🎨 Shape Color
- data.onChange?.(e.target.value)} - style={{ width: '100%' }} - /> - -
- ); -} - -export default ColorNode; diff --git a/frontend/src/components/Diagram.jsx b/frontend/src/components/Diagram.jsx index a5c1165..51074fb 100644 --- a/frontend/src/components/Diagram.jsx +++ b/frontend/src/components/Diagram.jsx @@ -17,42 +17,34 @@ import CustomNode from './CustomNode'; import IconSelector from './IconSelector'; import { toast } from 'react-toastify'; import RouterNode from './RouterNode'; -import ColorNode from './ColorNode'; - const nodeTypes = { custom: CustomNode, router: RouterNode, - color: ColorNode, }; function Diagram() { const [nodes, setNodes, onNodesChange] = useNodesState([]); const [edges, setEdges, onEdgesChange] = useEdgesState([]); const [selectedNode, setSelectedNode] = useState(null); + const [selectedEdge, setSelectedEdge] = useState(null); const [showForm, setShowForm] = useState(false); const [newLabel, setNewLabel] = useState(''); const [newType, setNewType] = useState('custom'); const [selectedIcon, setSelectedIcon] = useState(''); - const [selectedEdge, setSelectedEdge] = useState(null); const [diagramName, setDiagramName] = useState(null); const [diagramList, setDiagramList] = useState([]); const isIframe = window.self !== window.top; useEffect(() => { - let isMounted = true; - const load = async () => { try { const { diagrams } = await listDiagrams(); - if (isMounted) { - setDiagramList(diagrams); - - if (diagrams.length > 0) { - setDiagramName((prev) => prev || diagrams[0]); - } else { - setDiagramName(null); - } + setDiagramList(diagrams); + if (diagrams.length > 0) { + setDiagramName((prev) => prev || diagrams[0]); + } else { + setDiagramName(null); } } catch (err) { console.error(err); @@ -60,16 +52,10 @@ function Diagram() { setDiagramName(null); } }; - load(); - return () => { - isMounted = false; - }; }, []); useEffect(() => { - let isMounted = true; - const loadDiagram = async () => { if (!diagramName) { setNodes([]); @@ -78,18 +64,13 @@ function Diagram() { } try { const data = await fetchDiagramByName(diagramName); - if (isMounted) { - setNodes(data.nodes || []); - const sanitizedEdges = (data.edges || []).map(({ id, source, target, animated }) => ({ - id, - source, - target, - animated: !!animated, - })); - setEdges(sanitizedEdges); - setSelectedNode(null); - setSelectedEdge(null); - } + setNodes(data.nodes || []); + const sanitizedEdges = (data.edges || []).map(({ id, source, target, animated }) => ({ + id, source, target, animated: !!animated + })); + setEdges(sanitizedEdges); + setSelectedNode(null); + setSelectedEdge(null); } catch (err) { console.error(err); toast.error(`❌ Failed to load diagram "${diagramName}"`); @@ -97,29 +78,18 @@ function Diagram() { setEdges([]); } }; - loadDiagram(); - return () => { - isMounted = false; - }; - }, [diagramName, setNodes, setEdges]); + }, [diagramName]); const handleSave = async () => { if (!diagramName) return; const cleanedEdges = edges.map(({ id, source, target, animated }) => ({ - id, - source, - target, - animated: !!animated, + id, source, target, animated: !!animated })); await saveDiagramByName(diagramName, { nodes, edges: cleanedEdges }); toast.success(`✅ Diagram "${diagramName}" saved!`); }; - const handleAddNode = () => { - setShowForm(true); - }; - const handleSubmitNode = () => { const id = (nodes.length + 1).toString(); const label = newLabel || `Node ${id}`; @@ -128,9 +98,7 @@ function Diagram() { const newNode = { id, type: newType, - data: newType === 'custom' - ? { label, icon } - : { label }, // router and other types don't have icons + data: newType === 'custom' ? { label, icon } : { label }, position: { x: Math.random() * 400, y: Math.random() * 300 }, }; @@ -150,6 +118,11 @@ function Diagram() { setSelectedNode(null); }; + const onConnect = useCallback( + (params) => setEdges((eds) => addEdge({ ...params, animated: true }, eds)), + [setEdges] + ); + const onEdgeClick = (_, edge) => { setSelectedEdge(edge); setSelectedNode(null); @@ -162,12 +135,9 @@ function Diagram() { setSelectedEdge(null); }; - const onConnect = useCallback( - (params) => setEdges((eds) => addEdge({ ...params, animated: true }, eds)), - [setEdges] - ); + const onNodeClick = (_, node) => setSelectedNode(node); - const handleNodeDoubleClick = (event, node) => { + const handleNodeDoubleClick = (_, node) => { const newLabel = prompt('Enter new name:', node.data.label); if (newLabel !== null) { setNodes((nds) => @@ -179,19 +149,12 @@ function Diagram() { } }; - const onNodeClick = (_, node) => { - setSelectedNode(node); - }; - const handleDeleteDiagram = async () => { if (!diagramName || diagramName === 'default') { toast.warn("❌ Cannot delete 'default' diagram or nothing selected."); return; } - - const confirmDelete = confirm(`Are you sure you want to delete diagram "${diagramName}"?`); - if (!confirmDelete) return; - + if (!confirm(`Delete "${diagramName}"?`)) return; try { await deleteDiagramByName(diagramName); const updatedList = diagramList.filter(name => name !== diagramName); @@ -208,8 +171,8 @@ function Diagram() { return (
-
-
+
+
-
+
@@ -255,43 +208,36 @@ function Diagram() { const newName = prompt("Enter new diagram name:"); if (newName) { if (!diagramList.includes(newName)) { - const updatedList = [...diagramList, newName]; - setDiagramList(updatedList); + setDiagramList((prev) => [...prev, newName]); } setDiagramName(newName); setNodes([]); setEdges([]); - setSelectedNode(null); - setSelectedEdge(null); } }}>🆕 New Diagram - - - - - - + + + )}
{showForm && ( -
-

🧩 Add New Node

+
+

🧩 Add New Node

- + setNewLabel(e.target.value)} style={{ padding: '6px', width: '100%', borderRadius: 6, border: '1px solid #ccc', marginBottom: 12 }} /> - + - {newType === 'custom' && ( - - )} + {newType === 'custom' && }
diff --git a/frontend/src/components/IconSelector.jsx b/frontend/src/components/IconSelector.jsx index 24a9b3e..845b909 100644 --- a/frontend/src/components/IconSelector.jsx +++ b/frontend/src/components/IconSelector.jsx @@ -25,7 +25,7 @@ function IconSelector({ onSelect }) { return (
- +