import and export inside flow
This commit is contained in:
parent
fa51eb3d3a
commit
7023a11f04
2 changed files with 171 additions and 149 deletions
|
|
@ -6,7 +6,8 @@ import { TabsContext } from "../../../../contexts/tabsContext";
|
|||
var _ = require("lodash");
|
||||
|
||||
export default function TabComponent({ selected, flow, onClick }) {
|
||||
const { removeFlow, updateFlow, flows, downloadFlow } = useContext(TabsContext);
|
||||
const { removeFlow, updateFlow, flows, downloadFlow } =
|
||||
useContext(TabsContext);
|
||||
const [isRename, setIsRename] = useState(false);
|
||||
const [value, setValue] = useState("");
|
||||
return (
|
||||
|
|
@ -57,7 +58,10 @@ export default function TabComponent({ selected, flow, onClick }) {
|
|||
>
|
||||
{flow.name}
|
||||
</span>
|
||||
<ArrowDownTrayIcon onClick={()=>downloadFlow()} className="w-4 h-4 hover:text-blue-500 cursor-pointer"/>
|
||||
{/* <ArrowDownTrayIcon
|
||||
onClick={() => downloadFlow()}
|
||||
className="w-4 h-4 hover:text-blue-500 cursor-pointer"
|
||||
/> */}
|
||||
</div>
|
||||
)}
|
||||
<button
|
||||
|
|
|
|||
|
|
@ -1,12 +1,13 @@
|
|||
import { useCallback, useContext, useEffect, useRef, useState } from "react";
|
||||
import ReactFlow, {
|
||||
Background,
|
||||
Controls,
|
||||
addEdge,
|
||||
useEdgesState,
|
||||
useNodesState,
|
||||
ReactFlowProvider,
|
||||
useReactFlow,
|
||||
Background,
|
||||
Controls,
|
||||
addEdge,
|
||||
useEdgesState,
|
||||
useNodesState,
|
||||
ReactFlowProvider,
|
||||
useReactFlow,
|
||||
ControlButton,
|
||||
} from "reactflow";
|
||||
import { locationContext } from "../../contexts/locationContext";
|
||||
import ExtraSidebar from "./components/extraSidebarComponent";
|
||||
|
|
@ -20,164 +21,181 @@ import BooleanNode from "../../CustomNodes/BooleanNode";
|
|||
import { alertContext } from "../../contexts/alertContext";
|
||||
import { TabsContext } from "../../contexts/tabsContext";
|
||||
import { typesContext } from "../../contexts/typesContext";
|
||||
import {
|
||||
ArrowDownTrayIcon,
|
||||
ArrowUpTrayIcon,
|
||||
} from "@heroicons/react/24/outline";
|
||||
|
||||
const nodeTypes = {
|
||||
genericNode: GenericNode,
|
||||
inputNode: InputNode,
|
||||
chatInputNode: ChatInputNode,
|
||||
chatOutputNode: ChatOutputNode,
|
||||
booleanNode: BooleanNode,
|
||||
genericNode: GenericNode,
|
||||
inputNode: InputNode,
|
||||
chatInputNode: ChatInputNode,
|
||||
chatOutputNode: ChatOutputNode,
|
||||
booleanNode: BooleanNode,
|
||||
};
|
||||
|
||||
var _ = require("lodash");
|
||||
|
||||
export default function FlowPage({ flow }) {
|
||||
let { updateFlow, incrementNodeId } = useContext(TabsContext);
|
||||
const { types, reactFlowInstance, setReactFlowInstance } =
|
||||
useContext(typesContext);
|
||||
const reactFlowWrapper = useRef(null);
|
||||
let { updateFlow, incrementNodeId, downloadFlow, uploadFlow } =
|
||||
useContext(TabsContext);
|
||||
const { types, reactFlowInstance, setReactFlowInstance } =
|
||||
useContext(typesContext);
|
||||
const reactFlowWrapper = useRef(null);
|
||||
|
||||
function getId(){
|
||||
return `dndnode_}`+incrementNodeId();
|
||||
};
|
||||
function getId() {
|
||||
return `dndnode_}` + incrementNodeId();
|
||||
}
|
||||
|
||||
const { setExtraComponent, setExtraNavigation } = useContext(locationContext);
|
||||
const { setErrorData } = useContext(alertContext);
|
||||
const { setExtraComponent, setExtraNavigation } = useContext(locationContext);
|
||||
const { setErrorData } = useContext(alertContext);
|
||||
|
||||
const [nodes, setNodes, onNodesChange] = useNodesState(
|
||||
flow.data?.nodes ?? []
|
||||
);
|
||||
const [edges, setEdges, onEdgesChange] = useEdgesState(
|
||||
flow.data?.edges ?? []
|
||||
);
|
||||
const {setViewport} = useReactFlow()
|
||||
const [nodes, setNodes, onNodesChange] = useNodesState(
|
||||
flow.data?.nodes ?? []
|
||||
);
|
||||
const [edges, setEdges, onEdgesChange] = useEdgesState(
|
||||
flow.data?.edges ?? []
|
||||
);
|
||||
const { setViewport } = useReactFlow();
|
||||
|
||||
useEffect(() => {
|
||||
if (reactFlowInstance && flow) {
|
||||
flow.data = reactFlowInstance.toObject();
|
||||
updateFlow(flow);
|
||||
}
|
||||
}, [nodes, edges]);
|
||||
useEffect(() => {
|
||||
if (reactFlowInstance && flow) {
|
||||
flow.data = reactFlowInstance.toObject();
|
||||
updateFlow(flow);
|
||||
}
|
||||
}, [nodes, edges]);
|
||||
|
||||
useEffect(() => {
|
||||
setNodes(flow?.data?.nodes ?? []);
|
||||
setEdges(flow?.data?.edges ?? []);
|
||||
if (reactFlowInstance) {
|
||||
setViewport(
|
||||
flow?.data?.viewport ?? { x: 1, y: 0, zoom: 1 }
|
||||
);
|
||||
}
|
||||
}, [flow, reactFlowInstance, setEdges, setNodes]);
|
||||
useEffect(() => {
|
||||
setNodes(flow?.data?.nodes ?? []);
|
||||
setEdges(flow?.data?.edges ?? []);
|
||||
if (reactFlowInstance) {
|
||||
setViewport(flow?.data?.viewport ?? { x: 1, y: 0, zoom: 1 });
|
||||
}
|
||||
}, [flow, reactFlowInstance, setEdges, setNodes]);
|
||||
|
||||
useEffect(() => {
|
||||
setExtraComponent(<ExtraSidebar />);
|
||||
setExtraNavigation({ title: "Nodes" });
|
||||
}, [setExtraComponent, setExtraNavigation]);
|
||||
useEffect(() => {
|
||||
setExtraComponent(<ExtraSidebar />);
|
||||
setExtraNavigation({ title: "Nodes" });
|
||||
}, [setExtraComponent, setExtraNavigation]);
|
||||
|
||||
const onEdgesChangeMod = useCallback(
|
||||
(s) => {
|
||||
onEdgesChange(s);
|
||||
setNodes((x) => {
|
||||
let newX = _.cloneDeep(x);
|
||||
return newX;
|
||||
});
|
||||
},
|
||||
[onEdgesChange, setNodes]
|
||||
);
|
||||
const onEdgesChangeMod = useCallback(
|
||||
(s) => {
|
||||
onEdgesChange(s);
|
||||
setNodes((x) => {
|
||||
let newX = _.cloneDeep(x);
|
||||
return newX;
|
||||
});
|
||||
},
|
||||
[onEdgesChange, setNodes]
|
||||
);
|
||||
|
||||
const onConnect = useCallback(
|
||||
(params) => {
|
||||
setEdges((eds) =>
|
||||
addEdge({ ...params, className: "animate-pulse" }, eds)
|
||||
);
|
||||
setNodes((x) => {
|
||||
let newX = _.cloneDeep(x);
|
||||
return newX;
|
||||
});
|
||||
},
|
||||
[setEdges, setNodes]
|
||||
);
|
||||
const onConnect = useCallback(
|
||||
(params) => {
|
||||
setEdges((eds) =>
|
||||
addEdge({ ...params, className: "animate-pulse" }, eds)
|
||||
);
|
||||
setNodes((x) => {
|
||||
let newX = _.cloneDeep(x);
|
||||
return newX;
|
||||
});
|
||||
},
|
||||
[setEdges, setNodes]
|
||||
);
|
||||
|
||||
const onDragOver = useCallback((event) => {
|
||||
event.preventDefault();
|
||||
event.dataTransfer.dropEffect = "move";
|
||||
}, []);
|
||||
const onDragOver = useCallback((event) => {
|
||||
event.preventDefault();
|
||||
event.dataTransfer.dropEffect = "move";
|
||||
}, []);
|
||||
|
||||
const onDrop = useCallback(
|
||||
(event) => {
|
||||
event.preventDefault();
|
||||
const onDrop = useCallback(
|
||||
(event) => {
|
||||
event.preventDefault();
|
||||
|
||||
const reactflowBounds = reactFlowWrapper.current.getBoundingClientRect();
|
||||
let data = JSON.parse(event.dataTransfer.getData("json"));
|
||||
if (
|
||||
data.type !== "chatInput" ||
|
||||
(data.type === "chatInput" &&
|
||||
!reactFlowInstance.getNodes().some((n) => n.type === "chatInputNode"))
|
||||
) {
|
||||
const position = reactFlowInstance.project({
|
||||
x: event.clientX - reactflowBounds.left,
|
||||
y: event.clientY - reactflowBounds.top,
|
||||
});
|
||||
let newId = getId();
|
||||
const reactflowBounds = reactFlowWrapper.current.getBoundingClientRect();
|
||||
let data = JSON.parse(event.dataTransfer.getData("json"));
|
||||
if (
|
||||
data.type !== "chatInput" ||
|
||||
(data.type === "chatInput" &&
|
||||
!reactFlowInstance.getNodes().some((n) => n.type === "chatInputNode"))
|
||||
) {
|
||||
const position = reactFlowInstance.project({
|
||||
x: event.clientX - reactflowBounds.left,
|
||||
y: event.clientY - reactflowBounds.top,
|
||||
});
|
||||
let newId = getId();
|
||||
|
||||
const newNode = {
|
||||
id: newId,
|
||||
type:
|
||||
data.type === "str"
|
||||
? "inputNode"
|
||||
: data.type === "chatInput"
|
||||
? "chatInputNode"
|
||||
: data.type === "chatOutput"
|
||||
? "chatOutputNode"
|
||||
: data.type === "bool"
|
||||
? "booleanNode"
|
||||
: "genericNode",
|
||||
position,
|
||||
data: {
|
||||
...data,
|
||||
id: newId,
|
||||
value: null,
|
||||
},
|
||||
};
|
||||
setNodes((nds) => nds.concat(newNode));
|
||||
} else {
|
||||
setErrorData({
|
||||
title: "Error creating node",
|
||||
list: ["There can't be more than one chat input."],
|
||||
});
|
||||
}
|
||||
},
|
||||
[reactFlowInstance, setErrorData, setNodes]
|
||||
);
|
||||
const newNode = {
|
||||
id: newId,
|
||||
type:
|
||||
data.type === "str"
|
||||
? "inputNode"
|
||||
: data.type === "chatInput"
|
||||
? "chatInputNode"
|
||||
: data.type === "chatOutput"
|
||||
? "chatOutputNode"
|
||||
: data.type === "bool"
|
||||
? "booleanNode"
|
||||
: "genericNode",
|
||||
position,
|
||||
data: {
|
||||
...data,
|
||||
id: newId,
|
||||
value: null,
|
||||
},
|
||||
};
|
||||
setNodes((nds) => nds.concat(newNode));
|
||||
} else {
|
||||
setErrorData({
|
||||
title: "Error creating node",
|
||||
list: ["There can't be more than one chat input."],
|
||||
});
|
||||
}
|
||||
},
|
||||
[reactFlowInstance, setErrorData, setNodes]
|
||||
);
|
||||
|
||||
return (
|
||||
<div className="w-full h-full" ref={reactFlowWrapper}>
|
||||
{Object.keys(types).length > 0 ? (
|
||||
<>
|
||||
<ReactFlow
|
||||
nodes={nodes}
|
||||
onMove={() =>
|
||||
updateFlow({ ...flow, data: reactFlowInstance.toObject() })
|
||||
}
|
||||
edges={edges}
|
||||
onNodesChange={onNodesChange}
|
||||
onEdgesChange={onEdgesChangeMod}
|
||||
onConnect={onConnect}
|
||||
onLoad={setReactFlowInstance}
|
||||
onInit={setReactFlowInstance}
|
||||
nodeTypes={nodeTypes}
|
||||
connectionLineComponent={connection}
|
||||
onDragOver={onDragOver}
|
||||
onDrop={onDrop}
|
||||
>
|
||||
<Background />
|
||||
<Controls></Controls>
|
||||
</ReactFlow>
|
||||
<Chat flow={flow} reactFlowInstance={reactFlowInstance} />
|
||||
</>
|
||||
) : (
|
||||
<></>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
return (
|
||||
<div className="w-full h-full" ref={reactFlowWrapper}>
|
||||
{Object.keys(types).length > 0 ? (
|
||||
<>
|
||||
<ReactFlow
|
||||
nodes={nodes}
|
||||
onMove={() =>
|
||||
updateFlow({ ...flow, data: reactFlowInstance.toObject() })
|
||||
}
|
||||
edges={edges}
|
||||
onNodesChange={onNodesChange}
|
||||
onEdgesChange={onEdgesChangeMod}
|
||||
onConnect={onConnect}
|
||||
onLoad={setReactFlowInstance}
|
||||
onInit={setReactFlowInstance}
|
||||
nodeTypes={nodeTypes}
|
||||
connectionLineComponent={connection}
|
||||
onDragOver={onDragOver}
|
||||
onDrop={onDrop}
|
||||
>
|
||||
<Background />
|
||||
<Controls>
|
||||
<ControlButton
|
||||
className="text-black hover:text-blue-500"
|
||||
onClick={() => uploadFlow()}
|
||||
>
|
||||
<ArrowUpTrayIcon />
|
||||
</ControlButton>
|
||||
|
||||
<ControlButton
|
||||
className="text-black hover:text-blue-500"
|
||||
onClick={() => downloadFlow()}
|
||||
>
|
||||
<ArrowDownTrayIcon />
|
||||
</ControlButton>
|
||||
</Controls>
|
||||
</ReactFlow>
|
||||
<Chat flow={flow} reactFlowInstance={reactFlowInstance} />
|
||||
</>
|
||||
) : (
|
||||
<></>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue