This commit is contained in:
2024-09-10 10:56:15 +07:00
parent e4ce452bd4
commit 18bd3e782b
5 changed files with 126 additions and 29 deletions

View File

@@ -105,3 +105,7 @@
font-weight: 700;
text-transform: capitalize;
}
.react-flow__panel {
position: fixed;
}

View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" focusable="false" aria-hidden="true" class="wink-icon exitIndicatorIcon-1gdYp"><path d="M7 2a2 2 0 00-2 2v5h2V4h12v16H7v-5H5v5a2 2 0 002 2h12a2 2 0 002-2V4a2 2 0 00-2-2H7z"></path><path d="M11.743 6.331l-1.486 1.338 3.181 3.535L2 11v2l11.438-.204-3.181 3.535 1.486 1.338L16.845 12l-5.102-5.669z"></path></svg>

After

Width:  |  Height:  |  Size: 369 B

View File

@@ -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';

46
src/nodes/CustomEdge.tsx Normal file
View File

@@ -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 (
<>
<path
id={id}
d={path}
style={{ stroke: '#ccc', strokeWidth: .8, fill: 'transparent' }}
/>
{data?.label && (
<foreignObject
width={90}
height={30}
x={(sourceX + targetX) / 2 - 38}
y={(sourceY + targetY) / 2 - 15}
>
<div
xmlns='http://www.w3.org/1999/xhtml'
style={{
background: 'white',
padding: '5px',
borderRadius: '0.8px',
cursor: 'pointer',
fontSize: '13px'
}}
onClick={data.onClick}
>
{data.label}
</div>
</foreignObject>
)}
</>
);
};
export default CustomEdge;

View File

@@ -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 = () => {
</div>
)
},
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 = () => {
</div>
)
},
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: <div onClick={handleAddNoteClick}>Add Note</div>, // 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 = () => {
<ReactFlow
nodes={nodes}
edges={edges}
edgeTypes={{ custom: CustomEdge }}
onNodeClick={onNodeClick}
onNodeContextMenu={onNodeContextMenu}
panOnScroll