diff --git a/src/assets/css/style.css b/src/assets/css/style.css
index a75a91c..6453f20 100644
--- a/src/assets/css/style.css
+++ b/src/assets/css/style.css
@@ -105,3 +105,7 @@
font-weight: 700;
text-transform: capitalize;
}
+
+.react-flow__panel {
+ position: fixed;
+}
diff --git a/src/assets/icons/icon-exits.svg b/src/assets/icons/icon-exits.svg
new file mode 100644
index 0000000..92847d3
--- /dev/null
+++ b/src/assets/icons/icon-exits.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/src/main.tsx b/src/main.tsx
index 553536f..8a731da 100644
--- a/src/main.tsx
+++ b/src/main.tsx
@@ -1,5 +1,6 @@
import React from 'react';
import ReactDOM from 'react-dom/client';
+import { ReactFlowProvider } from '@xyflow/react';
import App from './App';
import NoteFlow from './nodes/NoteFlow';
diff --git a/src/nodes/CustomEdge.tsx b/src/nodes/CustomEdge.tsx
new file mode 100644
index 0000000..286e9d8
--- /dev/null
+++ b/src/nodes/CustomEdge.tsx
@@ -0,0 +1,46 @@
+// CustomEdge.js
+import React from 'react';
+import { getBezierPath } from '@xyflow/react'; // hoặc một hàm tương tự nếu có
+
+const CustomEdge = ({ id, sourceX, sourceY, targetX, targetY, data }) => {
+ const [path] = getBezierPath({
+ sourceX,
+ sourceY,
+ targetX,
+ targetY
+ });
+
+ return (
+ <>
+
+ {data?.label && (
+
+
+ {data.label}
+
+
+ )}
+ >
+ );
+};
+
+export default CustomEdge;
diff --git a/src/nodes/NoteFlow.tsx b/src/nodes/NoteFlow.tsx
index 2e04727..2e03a6f 100644
--- a/src/nodes/NoteFlow.tsx
+++ b/src/nodes/NoteFlow.tsx
@@ -13,7 +13,8 @@ import { FaShuffle } from 'react-icons/fa6';
import '../assets/css/style.css';
import Tabbar from './Tabbar.tsx';
import ShowPopup from './ShowPopup.tsx';
-import { v4 as uuidv4 } from 'uuid';
+import { nanoid } from 'nanoid';
+import CustomEdge from './CustomEdge';
const initialNodes = [
{
@@ -87,13 +88,13 @@ const NoteFlow = () => {
const [nodeToDelete, setNodeToDelete] = useState(null);
const [showPopup, setShowPopup] = useState(false);
const [selectedNodeContent, setSelectedNodeContent] = useState('');
+ const [addNodeCallback, setAddNodeCallback] = useState(() => () => {});
const handleAddNoteClick = () => {
setShowTabBar(true);
- const handleNodeSelect = (selectedNode) => {
+ setAddNodeCallback(() => (selectedNode) => {
addNodeBetween(selectedNode, sourceId, targetId);
- };
- setAddNodeCallback(() => addNodeBetweenWithIds);
+ });
};
const onNodeClick = (event, node) => {
@@ -149,28 +150,38 @@ const NoteFlow = () => {
return lastNode.position.y + spacing;
};
+ const removeEdgesRelatedToNode = (nodeId) => {
+ setEdges((eds) =>
+ eds.filter((edge) => edge.source !== nodeId && edge.target !== nodeId)
+ );
+ };
+
const addNode = (option) => {
- const newNodeId = uuidv4(); // Generate a unique ID for the new node
+ const newNodeId = nanoid(8); // Generate a unique ID for the new node
const addNoteNode = nodes.find((node) => node.id === '2');
const initialX = addNoteNode.position.x;
+ console.log(initialX);
+
const nextY =
nodes.length > 2
? getNextYPosition(initialX, 130)
: addNoteNode.position.y;
- if (option.id === '4') {
- // Handle specific option case
- setNodes((nds) => nds.filter((node) => node.id !== '2'));
+ // Remove existing edges from addNoteNode
+ setEdges((eds) =>
+ eds.filter((edge) => edge.source !== '2' && edge.target !== '2')
+ );
+ if (option.id === '4') {
const repliedNode = {
id: newNodeId,
key: option.key,
data: { label: option.htmlNode },
- position: { x: option.position.x, y: nextY }
+ position: { x: initialX, y: nextY }
};
const yesNode = {
- id: uuidv4(),
+ id: nanoid(8),
type: 'output',
key: 'contact-exists',
data: {
@@ -188,12 +199,12 @@ const NoteFlow = () => {
)
},
- position: { x: option.position.x - 150, y: nextY + 150 }
+ position: { x: initialX - 150, y: nextY + 150 }
};
const noNode = {
- id: uuidv4(),
- type: 'output',
+ id: nanoid(8),
+ type: '',
key: 'send-survey',
data: {
label: (
@@ -210,30 +221,50 @@ const NoteFlow = () => {
)
},
- position: { x: option.position.x + 150, y: nextY + 150 }
+ position: { x: initialX + 150, y: nextY + 150 }
};
+ // Di chuyển node add-note sang nhánh no
+ setNodes((nds) =>
+ nds.map((node) =>
+ node.id === '2'
+ ? {
+ ...node,
+ position: {
+ x: noNode.position.x,
+ y: noNode.position.y + 150
+ }
+ }
+ : node
+ )
+ );
+
+ // Thêm các node mới (replied, yes, no)
setNodes((nds) => [...nds, repliedNode, yesNode, noNode]);
+ // Kết nối các edges giữa các node
setEdges((eds) => [
...eds,
{
- id: uuidv4(),
+ id: nanoid(8),
source: repliedNode.id,
target: yesNode.id,
- label: 'yes',
- animated: false
+ label: 'yes'
},
{
- id: uuidv4(),
+ id: nanoid(8),
source: repliedNode.id,
target: noNode.id,
- label: 'no',
- animated: false
+ label: 'no'
},
- { id: uuidv4(), source: lastNodeId, target: repliedNode.id }
+ { id: nanoid(8), source: lastNodeId, target: repliedNode.id },
+ { id: nanoid(8), source: noNode.id, target: addNoteNode.id }
]);
+
+ setLastNodeId(noNode.id);
} else {
+ console.log(option);
+
// Add new node logic
if (addNoteNode) {
const initialX = addNoteNode.position.x;
@@ -256,24 +287,37 @@ const NoteFlow = () => {
key: option.key,
data: { label: option.htmlNode },
position: {
- x: option.position.x,
+ x: initialX,
y: nodes.length > 2 ? nextY : addNoteNode.position.y
}
};
- console.log(getNextYPosition(option.position.x, 130));
+ const newEdge = {
+ id: nanoid(8),
+ source: lastNodeId,
+ target: newNodeId
+ };
setNodes((nds) => [...nds, newNode]);
-
setEdges((eds) => [
...eds,
- {
- id: uuidv4(),
- source: lastNodeId,
- target: newNodeId
- }
+ newEdge,
+ { id: nanoid(8), source: newNodeId, target: addNoteNode.id }
]);
+ // setEdges((eds) => [
+ // ...eds,
+ // {
+ // id: uuidv4(),
+ // source: lastNodeId,
+ // data: {
+ // label:
Add Note
, // Use HTML or React component
+ // onClick: handleAddNoteClick
+ // },
+ // target: newNodeId
+ // }
+ // ]);
+ // Cuộn tới node mới thêm
setLastNodeId(newNodeId);
}
@@ -294,6 +338,7 @@ const NoteFlow = () => {