update 24/8
This commit is contained in:
@@ -1,4 +1,4 @@
|
|||||||
import { useState } from 'react';
|
import { useState,useCallback } from 'react';
|
||||||
import { ReactFlow, addEdge, Controls, Background } from '@xyflow/react';
|
import { ReactFlow, addEdge, Controls, Background } from '@xyflow/react';
|
||||||
import '@xyflow/react/dist/style.css';
|
import '@xyflow/react/dist/style.css';
|
||||||
import { FiUser, FiMail, FiCheckCircle, FiList } from 'react-icons/fi';
|
import { FiUser, FiMail, FiCheckCircle, FiList } from 'react-icons/fi';
|
||||||
@@ -25,6 +25,7 @@ const initialNodes = [
|
|||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
|
// nội dung tabbar
|
||||||
const tabBarOptions = [
|
const tabBarOptions = [
|
||||||
{
|
{
|
||||||
label: 'Send email',
|
label: 'Send email',
|
||||||
@@ -76,6 +77,40 @@ const tabBarOptions = [
|
|||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
|
// Nội dung cho mỗi node
|
||||||
|
const nodeContents = {
|
||||||
|
'2': `
|
||||||
|
<label for="email-subject">Subject:</label>
|
||||||
|
<input type="text" id="email-subject" name="email-subject" placeholder="Enter subject">
|
||||||
|
<label for="email-body">Body:</label>
|
||||||
|
<textarea id="email-body" name="email-body" rows="4" placeholder="Enter email body"></textarea>
|
||||||
|
`,
|
||||||
|
'1': `
|
||||||
|
<label for="customer-name">Customer Name:</label>
|
||||||
|
<input type="text" id="customer-name" name="customer-name" placeholder="Enter customer name">
|
||||||
|
<label for="customer-email">Customer Email:</label>
|
||||||
|
<input type="email" id="customer-email" name="customer-email" placeholder="Enter customer email">
|
||||||
|
`,
|
||||||
|
'3': `
|
||||||
|
<label for="reply-status">Reply Status:</label>
|
||||||
|
<select id="reply-status" name="reply-status">
|
||||||
|
<option value="replied">Replied</option>
|
||||||
|
<option value="not-replied">Not Replied</option>
|
||||||
|
</select>
|
||||||
|
`,
|
||||||
|
'5': `
|
||||||
|
<label for="contact-id">Contact ID:</label>
|
||||||
|
<input type="text" id="contact-id" name="contact-id" placeholder="Enter contact ID">
|
||||||
|
`,
|
||||||
|
'4': `
|
||||||
|
<label for="survey-question">Survey Question:</label>
|
||||||
|
<input type="text" id="survey-question" name="survey-question" placeholder="Enter survey question">
|
||||||
|
<label for="survey-options">Options (comma-separated):</label>
|
||||||
|
<input type="text" id="survey-options" name="survey-options" placeholder="Option 1, Option 2, ...">
|
||||||
|
`
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
const NoteFlow = () => {
|
const NoteFlow = () => {
|
||||||
const [nodes, setNodes] = useState(initialNodes);
|
const [nodes, setNodes] = useState(initialNodes);
|
||||||
const [edges, setEdges] = useState([
|
const [edges, setEdges] = useState([
|
||||||
@@ -84,6 +119,11 @@ const NoteFlow = () => {
|
|||||||
const [showTabBar, setShowTabBar] = useState(false);
|
const [showTabBar, setShowTabBar] = useState(false);
|
||||||
const [lastNodeId, setLastNodeId] = useState('1');
|
const [lastNodeId, setLastNodeId] = useState('1');
|
||||||
const [selectedNodeId, setSelectedNodeId] = useState(null); // Theo dõi node đã chọn
|
const [selectedNodeId, setSelectedNodeId] = useState(null); // Theo dõi node đã chọn
|
||||||
|
const [nodeToDelete, setNodeToDelete] = useState(null);
|
||||||
|
const [showPopup, setShowPopup] = useState(false);
|
||||||
|
const [selectedNodeContent, setSelectedNodeContent] = useState('');
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
const handleAddNoteClick = () => {
|
const handleAddNoteClick = () => {
|
||||||
setShowTabBar(true);
|
setShowTabBar(true);
|
||||||
@@ -186,9 +226,33 @@ const NoteFlow = () => {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const onNodeContextMenu = useCallback((event, node) => {
|
||||||
|
event.preventDefault(); // Ngăn không cho menu chuột phải mặc định hiện ra
|
||||||
|
setNodeToDelete(node);
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
const handleNodeDelete = () => {
|
||||||
|
if (nodeToDelete) {
|
||||||
|
setNodes((nds) => nds.filter((node) => node.id !== nodeToDelete.id));
|
||||||
|
setEdges((eds) => eds.filter((edge) => edge.source !== nodeToDelete.id && edge.target !== nodeToDelete.id));
|
||||||
|
setNodeToDelete(null);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
const onNodeDoubleClick = (event, node) => {
|
||||||
|
const content = nodeContents[node.id];
|
||||||
|
setSelectedNodeContent(content);
|
||||||
|
setShowPopup(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
const hideenPopup = () => {
|
||||||
|
setShowPopup(false);
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div style={{ height: '100vh', width: '100%', position: 'relative' }}>
|
<div style={{ height: '100vh', width: '100%', position: 'relative' }}>
|
||||||
<ReactFlow nodes={nodes} edges={edges} onNodeClick={onNodeClick}>
|
<ReactFlow nodes={nodes} edges={edges} onNodeClick={onNodeClick} onNodeContextMenu={onNodeContextMenu} onNodeDoubleClick={onNodeDoubleClick}>
|
||||||
<Controls />
|
<Controls />
|
||||||
<Background />
|
<Background />
|
||||||
</ReactFlow>
|
</ReactFlow>
|
||||||
@@ -220,6 +284,46 @@ const NoteFlow = () => {
|
|||||||
))}
|
))}
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
{nodeToDelete && (
|
||||||
|
<div
|
||||||
|
style={{
|
||||||
|
position: 'absolute',
|
||||||
|
top: nodeToDelete.position.y - 12,
|
||||||
|
left: nodeToDelete.position.x + 260,
|
||||||
|
zIndex: 10,
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<button
|
||||||
|
onClick={handleNodeDelete}
|
||||||
|
style={{
|
||||||
|
background: 'red',
|
||||||
|
color: 'white',
|
||||||
|
border: 'none',
|
||||||
|
borderRadius: '4px',
|
||||||
|
cursor: 'pointer'
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
X
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
{showPopup && (
|
||||||
|
<>
|
||||||
|
<div className="popup-overlay" onClick={hideenPopup}></div>
|
||||||
|
<div
|
||||||
|
className={`popup global-popup ${showPopup ? '' : 'hidden'}`}
|
||||||
|
>
|
||||||
|
<div className="popup-content">
|
||||||
|
<div className="conent-form">
|
||||||
|
<form>
|
||||||
|
<div dangerouslySetInnerHTML={{ __html: selectedNodeContent }} />
|
||||||
|
<button onClick={() => setShowPopup(false)}>Close</button>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user