import and export inside flow

This commit is contained in:
anovazzi1 2023-02-27 11:42:02 -03:00
commit 7023a11f04
2 changed files with 171 additions and 149 deletions

View file

@ -6,7 +6,8 @@ import { TabsContext } from "../../../../contexts/tabsContext";
var _ = require("lodash"); var _ = require("lodash");
export default function TabComponent({ selected, flow, onClick }) { 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 [isRename, setIsRename] = useState(false);
const [value, setValue] = useState(""); const [value, setValue] = useState("");
return ( return (
@ -57,7 +58,10 @@ export default function TabComponent({ selected, flow, onClick }) {
> >
{flow.name} {flow.name}
</span> </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> </div>
)} )}
<button <button

View file

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