Added Custom Node Renaming Functionality
This commit is contained in:
parent
75d1b7d522
commit
84cd4b6a54
@ -267,6 +267,8 @@ export default function FlowEditor({
|
|||||||
}
|
}
|
||||||
: null
|
: null
|
||||||
}
|
}
|
||||||
|
setNodes={setNodes}
|
||||||
|
selectedNode={selectedNode}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
{/* Edge Properties Sidebar */}
|
{/* Edge Properties Sidebar */}
|
||||||
|
@ -1,14 +1,21 @@
|
|||||||
////////// PROJECT FILE SEPARATION LINE ////////// CODE AFTER THIS LINE ARE FROM: <ProjectRoot>/Data/WebUI/src/Node_Configuration_Sidebar.jsx
|
////////// PROJECT FILE SEPARATION LINE ////////// CODE AFTER THIS LINE ARE FROM: <ProjectRoot>/Data/WebUI/src/Node_Configuration_Sidebar.jsx
|
||||||
import { Box, Typography, Tabs, Tab, TextField, MenuItem } from "@mui/material";
|
import { Box, Typography, Tabs, Tab, TextField, MenuItem, IconButton, Dialog, DialogTitle, DialogContent, DialogActions, Button } from "@mui/material";
|
||||||
import React, { useState } from "react";
|
import React, { useState } from "react";
|
||||||
import { useReactFlow } from "reactflow";
|
import { useReactFlow } from "reactflow";
|
||||||
import ReactMarkdown from "react-markdown"; // Used for Node Usage Documentation
|
import ReactMarkdown from "react-markdown"; // Used for Node Usage Documentation
|
||||||
|
import EditIcon from "@mui/icons-material/Edit";
|
||||||
|
|
||||||
export default function NodeConfigurationSidebar({ drawerOpen, setDrawerOpen, title, nodeData }) {
|
export default function NodeConfigurationSidebar({ drawerOpen, setDrawerOpen, title, nodeData, setNodes, selectedNode }) {
|
||||||
const [activeTab, setActiveTab] = useState(0);
|
const [activeTab, setActiveTab] = useState(0);
|
||||||
const { setNodes } = useReactFlow();
|
const contextSetNodes = useReactFlow().setNodes;
|
||||||
|
// Use setNodes from props if provided, else fallback to context (for backward compatibility)
|
||||||
|
const effectiveSetNodes = setNodes || contextSetNodes;
|
||||||
const handleTabChange = (_, newValue) => setActiveTab(newValue);
|
const handleTabChange = (_, newValue) => setActiveTab(newValue);
|
||||||
|
|
||||||
|
// Rename dialog state
|
||||||
|
const [renameOpen, setRenameOpen] = useState(false);
|
||||||
|
const [renameValue, setRenameValue] = useState(title || "");
|
||||||
|
|
||||||
const renderConfigFields = () => {
|
const renderConfigFields = () => {
|
||||||
const config = nodeData?.config || [];
|
const config = nodeData?.config || [];
|
||||||
const nodeId = nodeData?.nodeId;
|
const nodeId = nodeData?.nodeId;
|
||||||
@ -31,7 +38,7 @@ export default function NodeConfigurationSidebar({ drawerOpen, setDrawerOpen, ti
|
|||||||
onChange={(e) => {
|
onChange={(e) => {
|
||||||
const newValue = e.target.value;
|
const newValue = e.target.value;
|
||||||
if (!nodeId) return;
|
if (!nodeId) return;
|
||||||
setNodes((nds) =>
|
effectiveSetNodes((nds) =>
|
||||||
nds.map((n) =>
|
nds.map((n) =>
|
||||||
n.id === nodeId
|
n.id === nodeId
|
||||||
? { ...n, data: { ...n.data, [field.key]: newValue } }
|
? { ...n, data: { ...n.data, [field.key]: newValue } }
|
||||||
@ -101,7 +108,7 @@ export default function NodeConfigurationSidebar({ drawerOpen, setDrawerOpen, ti
|
|||||||
onChange={(e) => {
|
onChange={(e) => {
|
||||||
const newValue = e.target.value;
|
const newValue = e.target.value;
|
||||||
if (!nodeId) return;
|
if (!nodeId) return;
|
||||||
setNodes((nds) =>
|
effectiveSetNodes((nds) =>
|
||||||
nds.map((n) =>
|
nds.map((n) =>
|
||||||
n.id === nodeId
|
n.id === nodeId
|
||||||
? { ...n, data: { ...n.data, [field.key]: newValue } }
|
? { ...n, data: { ...n.data, [field.key]: newValue } }
|
||||||
@ -164,9 +171,22 @@ export default function NodeConfigurationSidebar({ drawerOpen, setDrawerOpen, ti
|
|||||||
>
|
>
|
||||||
<Box sx={{ backgroundColor: "#232323", borderBottom: "1px solid #333" }}>
|
<Box sx={{ backgroundColor: "#232323", borderBottom: "1px solid #333" }}>
|
||||||
<Box sx={{ padding: "12px 16px" }}>
|
<Box sx={{ padding: "12px 16px" }}>
|
||||||
<Typography variant="h7" sx={{ color: "#0475c2", fontWeight: "bold" }}>
|
<Box sx={{ display: "flex", alignItems: "center", justifyContent: "space-between" }}>
|
||||||
{"Edit " + (title || "Node")}
|
<Typography variant="h7" sx={{ color: "#0475c2", fontWeight: "bold" }}>
|
||||||
</Typography>
|
{"Edit " + (title || "Node")}
|
||||||
|
</Typography>
|
||||||
|
<IconButton
|
||||||
|
size="small"
|
||||||
|
aria-label="Rename Node"
|
||||||
|
onClick={() => {
|
||||||
|
setRenameValue(title || "");
|
||||||
|
setRenameOpen(true);
|
||||||
|
}}
|
||||||
|
sx={{ ml: 1, color: "#58a6ff" }}
|
||||||
|
>
|
||||||
|
<EditIcon fontSize="small" />
|
||||||
|
</IconButton>
|
||||||
|
</Box>
|
||||||
</Box>
|
</Box>
|
||||||
<Tabs
|
<Tabs
|
||||||
value={activeTab}
|
value={activeTab}
|
||||||
@ -230,6 +250,61 @@ export default function NodeConfigurationSidebar({ drawerOpen, setDrawerOpen, ti
|
|||||||
)}
|
)}
|
||||||
</Box>
|
</Box>
|
||||||
</Box>
|
</Box>
|
||||||
|
|
||||||
|
{/* Rename Node Dialog */}
|
||||||
|
<Dialog
|
||||||
|
open={renameOpen}
|
||||||
|
onClose={() => setRenameOpen(false)}
|
||||||
|
PaperProps={{ sx: { bgcolor: "#232323" } }}
|
||||||
|
>
|
||||||
|
<DialogTitle>Rename Node</DialogTitle>
|
||||||
|
<DialogContent>
|
||||||
|
<TextField
|
||||||
|
autoFocus
|
||||||
|
fullWidth
|
||||||
|
variant="outlined"
|
||||||
|
label="Node Title"
|
||||||
|
value={renameValue}
|
||||||
|
onChange={(e) => setRenameValue(e.target.value)}
|
||||||
|
sx={{
|
||||||
|
mt: 1,
|
||||||
|
bgcolor: "#1e1e1e",
|
||||||
|
"& .MuiOutlinedInput-root": {
|
||||||
|
color: "#ccc",
|
||||||
|
backgroundColor: "#1e1e1e",
|
||||||
|
"& fieldset": { borderColor: "#444" }
|
||||||
|
},
|
||||||
|
label: { color: "#aaa" }
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</DialogContent>
|
||||||
|
<DialogActions>
|
||||||
|
<Button sx={{ color: "#aaa" }} onClick={() => setRenameOpen(false)}>
|
||||||
|
Cancel
|
||||||
|
</Button>
|
||||||
|
<Button
|
||||||
|
sx={{ color: "#58a6ff" }}
|
||||||
|
onClick={() => {
|
||||||
|
// Use selectedNode (passed as prop) or nodeData?.nodeId as fallback
|
||||||
|
const nodeId = selectedNode?.id || nodeData?.nodeId;
|
||||||
|
if (!nodeId) {
|
||||||
|
setRenameOpen(false);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
effectiveSetNodes((nds) =>
|
||||||
|
nds.map((n) =>
|
||||||
|
n.id === nodeId
|
||||||
|
? { ...n, data: { ...n.data, label: renameValue } }
|
||||||
|
: n
|
||||||
|
)
|
||||||
|
);
|
||||||
|
setRenameOpen(false);
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
Save
|
||||||
|
</Button>
|
||||||
|
</DialogActions>
|
||||||
|
</Dialog>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user