Skip to content

Commit b3b63df

Browse files
committed
Delete and duplicate buttons (buggy)
1 parent 8d3705a commit b3b63df

File tree

4 files changed

+149
-90
lines changed

4 files changed

+149
-90
lines changed

src/App.jsx

Lines changed: 81 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -341,6 +341,7 @@ const DnDFlow = () => {
341341

342342
// Create node data with label and initialize all expected fields as empty strings
343343
let nodeData = {
344+
id: newNodeId,
344345
label: `${type} ${newNodeId}`,
345346
nodeColor: '#DDE6ED' // Default node color
346347
};
@@ -1094,45 +1095,62 @@ const DnDFlow = () => {
10941095
}, [selectedEdge, selectedNode, copiedNode, duplicateNode, setCopyFeedback]);
10951096

10961097
return (
1097-
<div style={{ width: '100vw', height: '100vh', display: 'flex', flexDirection: 'column' }}>
1098-
1098+
<div
1099+
style={{
1100+
width: "100vw",
1101+
height: "100vh",
1102+
display: "flex",
1103+
flexDirection: "column",
1104+
}}
1105+
>
10991106
{/* Tab Navigation */}
1100-
<TopBar activeTab={activeTab} setActiveTab={setActiveTab} versionInfo={versionInfo} />
1107+
<TopBar
1108+
activeTab={activeTab}
1109+
setActiveTab={setActiveTab}
1110+
versionInfo={versionInfo}
1111+
/>
11011112

11021113
{/* Graph Editor Tab */}
1103-
{activeTab === 'graph' && (
1104-
<div style={{ display: 'flex', flex: 1, height: 'calc(100vh - 50px)', overflow: 'hidden' }}>
1114+
{activeTab === "graph" && (
1115+
<div
1116+
style={{
1117+
display: "flex",
1118+
flex: 1,
1119+
height: "calc(100vh - 50px)",
1120+
overflow: "hidden",
1121+
}}
1122+
>
11051123
{/* Sidebar */}
11061124
<div
1107-
data-sidebar-state={sidebarVisible ? 'expanded' : 'collapsed'}
1125+
data-sidebar-state={sidebarVisible ? "expanded" : "collapsed"}
11081126
className="sidebar-container"
11091127
style={{
1110-
position: 'relative',
1111-
width: sidebarVisible ? '250px' : '0px',
1112-
height: '100%',
1113-
transition: 'width 0.5s ease',
1114-
overflow: 'hidden'
1128+
position: "relative",
1129+
width: sidebarVisible ? "250px" : "0px",
1130+
height: "100%",
1131+
transition: "width 0.5s ease",
1132+
overflow: "hidden",
11151133
}}
11161134
>
11171135
<div
11181136
style={{
1119-
position: 'fixed',
1120-
left: sidebarVisible ? '0px' : '-250px',
1121-
top: '50px', // Account for top bar height
1122-
width: '250px',
1123-
height: 'calc(100vh - 50px)',
1124-
transition: 'left 0.5s ease',
1137+
position: "fixed",
1138+
left: sidebarVisible ? "0px" : "-250px",
1139+
top: "50px", // Account for top bar height
1140+
width: "250px",
1141+
height: "calc(100vh - 50px)",
1142+
transition: "left 0.5s ease",
11251143
zIndex: 10,
1126-
borderRight: '1px solid #ccc',
1127-
backgroundColor: '#1e1e2f'
1144+
borderRight: "1px solid #ccc",
1145+
backgroundColor: "#1e1e2f",
11281146
}}
11291147
>
11301148
<Sidebar />
11311149
</div>
11321150
</div>
11331151

11341152
{/* Main content area that moves with sidebar */}
1135-
<div style={{ position: 'relative', flex: 1, height: '100%' }}>
1153+
<div style={{ position: "relative", flex: 1, height: "100%" }}>
11361154
<GraphView
11371155
refEl={ref}
11381156
reactFlowWrapperRef={reactFlowWrapper}
@@ -1153,13 +1171,23 @@ const DnDFlow = () => {
11531171
duplicateNode={duplicateNode}
11541172
copyFeedback={copyFeedback}
11551173
ui={{
1156-
selectedNode, selectedEdge,
1157-
deleteSelectedNode, deleteSelectedEdge,
1158-
saveGraph, loadGraph, resetGraph, saveToPython, runPathsim,
1174+
selectedNode,
1175+
selectedEdge,
1176+
deleteSelectedNode,
1177+
deleteSelectedEdge,
1178+
saveGraph,
1179+
loadGraph,
1180+
resetGraph,
1181+
saveToPython,
1182+
runPathsim,
11591183
shareGraphURL,
1160-
dockOpen, setDockOpen, onToggleLogs,
1161-
showKeyboardShortcuts, setShowKeyboardShortcuts,
1162-
sidebarVisible, setSidebarVisible,
1184+
dockOpen,
1185+
setDockOpen,
1186+
onToggleLogs,
1187+
showKeyboardShortcuts,
1188+
setShowKeyboardShortcuts,
1189+
sidebarVisible,
1190+
setSidebarVisible,
11631191
}}
11641192
/>
11651193

@@ -1197,42 +1225,38 @@ const DnDFlow = () => {
11971225
)}
11981226

11991227
{/* Events tab */}
1200-
{activeTab === 'events' && <EventsTab events={events} setEvents={setEvents} />}
1228+
{activeTab === "events" && (
1229+
<EventsTab events={events} setEvents={setEvents} />
1230+
)}
12011231

12021232
{/* Solver Parameters Tab */}
1203-
{
1204-
activeTab === 'solver' && (
1205-
<SolverPanel
1206-
solverParams={solverParams}
1207-
setSolverParams={setSolverParams}
1208-
setActiveTab={setActiveTab}
1209-
/>
1210-
)
1211-
}
1233+
{activeTab === "solver" && (
1234+
<SolverPanel
1235+
solverParams={solverParams}
1236+
setSolverParams={setSolverParams}
1237+
setActiveTab={setActiveTab}
1238+
/>
1239+
)}
12121240

12131241
{/* Global Variables Tab */}
1214-
{
1215-
activeTab === 'globals' && (
1216-
<GlobalVariablesTab
1217-
globalVariables={globalVariables}
1218-
setGlobalVariables={setGlobalVariables}
1219-
setActiveTab={setActiveTab}
1220-
pythonCode={pythonCode}
1221-
setPythonCode={setPythonCode}
1222-
/>
1223-
)
1224-
}
1242+
{activeTab === "globals" && (
1243+
<GlobalVariablesTab
1244+
globalVariables={globalVariables}
1245+
setGlobalVariables={setGlobalVariables}
1246+
setActiveTab={setActiveTab}
1247+
pythonCode={pythonCode}
1248+
setPythonCode={setPythonCode}
1249+
/>
1250+
)}
12251251

12261252
{/* Results Tab */}
1227-
{
1228-
activeTab === 'results' && (
1229-
<ResultsPanel
1230-
simulationResults={simulationResults}
1231-
downloadHtml={downloadHtml}
1232-
downloadCsv={downloadCsv}
1233-
/>
1234-
)
1235-
}
1253+
{activeTab === "results" && (
1254+
<ResultsPanel
1255+
simulationResults={simulationResults}
1256+
downloadHtml={downloadHtml}
1257+
downloadCsv={downloadCsv}
1258+
/>
1259+
)}
12361260

12371261
{/* Share URL Modal */}
12381262
<ShareModal
@@ -1241,8 +1265,7 @@ const DnDFlow = () => {
12411265
shareableURL={shareableURL}
12421266
urlMetadata={urlMetadata}
12431267
/>
1244-
1245-
</div >
1268+
</div>
12461269
);
12471270
}
12481271

src/components/GraphView.jsx

Lines changed: 51 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import { ReactFlow, Controls, MiniMap, Background } from '@xyflow/react';
22
import ContextMenu from './ContextMenu';
3+
import { NodeActionsCtx } from './nodes/nodecomponents/NodeActionsContext';
34

45
export default function GraphView(props) {
56
const {
@@ -11,37 +12,59 @@ export default function GraphView(props) {
1112
} = props;
1213

1314
return (
14-
<div className="dndflow" style={{ flex: 1, position: 'relative' }}>
15-
<div className="reactflow-wrapper" ref={reactFlowWrapperRef} style={{ width: '100%', height: '100%' }}>
16-
<ReactFlow
17-
ref={refEl}
18-
nodes={nodes}
19-
edges={edges}
20-
onNodesChange={onNodesChange}
21-
onEdgesChange={onEdgesChange}
22-
onConnect={onConnect}
23-
onNodeClick={onNodeClick}
24-
onEdgeClick={onEdgeClick}
25-
onPaneClick={onPaneClick}
26-
onNodeContextMenu={onNodeContextMenu}
27-
nodeTypes={nodeTypes}
28-
onDrop={onDrop}
29-
onDragStart={onDragStart}
30-
onDragOver={onDragOver}
31-
fitView
32-
>
33-
<Controls />
34-
<MiniMap />
35-
<Background variant="dots" gap={12} size={1} />
15+
<div className="dndflow" style={{ flex: 1, position: "relative" }}>
16+
<div
17+
className="reactflow-wrapper"
18+
ref={reactFlowWrapperRef}
19+
style={{ width: "100%", height: "100%" }}
20+
>
21+
<NodeActionsCtx.Provider value={
22+
{
23+
deleteSelectedNode: ui.deleteSelectedNode,
24+
duplicateNode: duplicateNode
25+
}
26+
}
27+
>
28+
<ReactFlow
29+
ref={refEl}
30+
nodes={nodes}
31+
edges={edges}
32+
onNodesChange={onNodesChange}
33+
onEdgesChange={onEdgesChange}
34+
onConnect={onConnect}
35+
onNodeClick={onNodeClick}
36+
onEdgeClick={onEdgeClick}
37+
onPaneClick={onPaneClick}
38+
onNodeContextMenu={onNodeContextMenu}
39+
nodeTypes={nodeTypes}
40+
onDrop={onDrop}
41+
onDragStart={onDragStart}
42+
onDragOver={onDragOver}
43+
fitView
44+
>
45+
<Controls />
46+
<MiniMap />
47+
<Background variant="dots" gap={12} size={1} />
3648

37-
{menu && <ContextMenu onClick={onPaneClick} onDuplicate={duplicateNode} {...menu} />}
49+
{menu && (
50+
<ContextMenu
51+
onClick={onPaneClick}
52+
onDuplicate={duplicateNode}
53+
{...menu}
54+
/>
55+
)}
3856

39-
<FloatingButtons {...ui} />
40-
<CopyToast copyFeedback={copyFeedback} />
41-
{ui.showKeyboardShortcuts && <KeyboardShortcuts onClose={() => ui.setShowKeyboardShortcuts(false)} />}
42-
</ReactFlow>
43-
</div>
57+
<FloatingButtons {...ui} />
58+
<CopyToast copyFeedback={copyFeedback} />
59+
{ui.showKeyboardShortcuts && (
60+
<KeyboardShortcuts
61+
onClose={() => ui.setShowKeyboardShortcuts(false)}
62+
/>
63+
)}
64+
</ReactFlow>
65+
</NodeActionsCtx.Provider>
4466
</div>
67+
</div>
4568
);
4669
}
4770

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
import { createContext } from "react";
2+
3+
export const NodeActionsCtx = createContext(null);

src/components/nodes/nodecomponents/NodeTop.jsx

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,34 @@
11
// Icons from Reshot
22
import trashcan from "$assets/trashcan.svg";
33
import duplicate from "$assets/duplicate.svg";
4+
import { useContext } from "react";
5+
import { NodeActionsCtx } from "./NodeActionsContext";
46

57

6-
function TopButton({icon}) {
8+
function TopButton({icon, callback}) {
79
// TODO: Link button side with wrapper size
810
return (
9-
<button className="bg-transparent my-auto px-0.5 py-0">
11+
<button className="bg-transparent my-auto px-0.5 py-0" onClick={callback}>
1012
<img src={icon} className="w-3 h-3"></img>
1113
</button>
1214
);
1315
}
1416

1517
export default function NodeTop({ data }) {
18+
// TODO: The delete node and duplicate node feature should be rewritten in future refactor work
19+
// to directly use the nodes id
20+
const { deleteSelectedNode, duplicateNode } = useContext(NodeActionsCtx);
1621
return (
1722
<div className="bg-inherit flex">
1823
<div className="text-xs m-auto">{data.label}</div>
1924
<div className="flex justify-end w-10">
20-
<TopButton icon={duplicate} />
21-
<TopButton icon={trashcan} />
25+
<TopButton
26+
icon={duplicate}
27+
callback={() => {
28+
duplicateNode(data.id);
29+
}}
30+
/>
31+
<TopButton icon={trashcan} callback={deleteSelectedNode} />
2232
</div>
2333
</div>
2434
);

0 commit comments

Comments
 (0)