Implemented tabs storage, only working if current tab is empty
This commit is contained in:
parent
06a17c5eb9
commit
45d6f8e569
8 changed files with 119 additions and 48 deletions
45
space_flow/package-lock.json
generated
45
space_flow/package-lock.json
generated
|
|
@ -23,6 +23,7 @@
|
||||||
"@types/react-dom": "^18.0.10",
|
"@types/react-dom": "^18.0.10",
|
||||||
"axios": "^1.3.2",
|
"axios": "^1.3.2",
|
||||||
"react": "^18.2.0",
|
"react": "^18.2.0",
|
||||||
|
"react-cookie": "^4.1.1",
|
||||||
"react-dom": "^18.2.0",
|
"react-dom": "^18.2.0",
|
||||||
"react-icons": "^4.7.1",
|
"react-icons": "^4.7.1",
|
||||||
"react-laag": "^2.0.5",
|
"react-laag": "^2.0.5",
|
||||||
|
|
@ -4212,6 +4213,11 @@
|
||||||
"@types/node": "*"
|
"@types/node": "*"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/@types/cookie": {
|
||||||
|
"version": "0.3.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/@types/cookie/-/cookie-0.3.3.tgz",
|
||||||
|
"integrity": "sha512-LKVP3cgXBT9RYj+t+9FDKwS5tdI+rPBXaNSkma7hvqy35lc7mAokC2zsqWJH0LaqIt3B962nuYI77hsJoT1gow=="
|
||||||
|
},
|
||||||
"node_modules/@types/d3": {
|
"node_modules/@types/d3": {
|
||||||
"version": "7.4.0",
|
"version": "7.4.0",
|
||||||
"resolved": "https://registry.npmjs.org/@types/d3/-/d3-7.4.0.tgz",
|
"resolved": "https://registry.npmjs.org/@types/d3/-/d3-7.4.0.tgz",
|
||||||
|
|
@ -4491,6 +4497,15 @@
|
||||||
"@types/node": "*"
|
"@types/node": "*"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/@types/hoist-non-react-statics": {
|
||||||
|
"version": "3.3.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/@types/hoist-non-react-statics/-/hoist-non-react-statics-3.3.1.tgz",
|
||||||
|
"integrity": "sha512-iMIqiko6ooLrTh1joXodJK5X9xeEALT1kM5G3ZLhD3hszxBdIEd5C75U834D9mLcINgD4OyZf5uQXjkuYydWvA==",
|
||||||
|
"dependencies": {
|
||||||
|
"@types/react": "*",
|
||||||
|
"hoist-non-react-statics": "^3.3.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/@types/html-minifier-terser": {
|
"node_modules/@types/html-minifier-terser": {
|
||||||
"version": "6.1.0",
|
"version": "6.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/@types/html-minifier-terser/-/html-minifier-terser-6.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/@types/html-minifier-terser/-/html-minifier-terser-6.1.0.tgz",
|
||||||
|
|
@ -14802,6 +14817,19 @@
|
||||||
"node": ">=14"
|
"node": ">=14"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/react-cookie": {
|
||||||
|
"version": "4.1.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/react-cookie/-/react-cookie-4.1.1.tgz",
|
||||||
|
"integrity": "sha512-ffn7Y7G4bXiFbnE+dKhHhbP+b8I34mH9jqnm8Llhj89zF4nPxPutxHT1suUqMeCEhLDBI7InYwf1tpaSoK5w8A==",
|
||||||
|
"dependencies": {
|
||||||
|
"@types/hoist-non-react-statics": "^3.0.1",
|
||||||
|
"hoist-non-react-statics": "^3.0.0",
|
||||||
|
"universal-cookie": "^4.0.0"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"react": ">= 16.3.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/react-dev-utils": {
|
"node_modules/react-dev-utils": {
|
||||||
"version": "12.0.1",
|
"version": "12.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/react-dev-utils/-/react-dev-utils-12.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/react-dev-utils/-/react-dev-utils-12.0.1.tgz",
|
||||||
|
|
@ -16832,6 +16860,23 @@
|
||||||
"node": ">=8"
|
"node": ">=8"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/universal-cookie": {
|
||||||
|
"version": "4.0.4",
|
||||||
|
"resolved": "https://registry.npmjs.org/universal-cookie/-/universal-cookie-4.0.4.tgz",
|
||||||
|
"integrity": "sha512-lbRVHoOMtItjWbM7TwDLdl8wug7izB0tq3/YVKhT/ahB4VDvWMyvnADfnJI8y6fSvsjh51Ix7lTGC6Tn4rMPhw==",
|
||||||
|
"dependencies": {
|
||||||
|
"@types/cookie": "^0.3.3",
|
||||||
|
"cookie": "^0.4.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/universal-cookie/node_modules/cookie": {
|
||||||
|
"version": "0.4.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.2.tgz",
|
||||||
|
"integrity": "sha512-aSWTXFzaKWkvHO1Ny/s+ePFpvKsPnjc551iI41v3ny/ow6tBG5Vd+FuqGNhh1LxOmVzOlGUriIlOaokOvhaStA==",
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.6"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/universalify": {
|
"node_modules/universalify": {
|
||||||
"version": "2.0.0",
|
"version": "2.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz",
|
||||||
|
|
|
||||||
|
|
@ -18,6 +18,7 @@
|
||||||
"@types/react-dom": "^18.0.10",
|
"@types/react-dom": "^18.0.10",
|
||||||
"axios": "^1.3.2",
|
"axios": "^1.3.2",
|
||||||
"react": "^18.2.0",
|
"react": "^18.2.0",
|
||||||
|
"react-cookie": "^4.1.1",
|
||||||
"react-dom": "^18.2.0",
|
"react-dom": "^18.2.0",
|
||||||
"react-icons": "^4.7.1",
|
"react-icons": "^4.7.1",
|
||||||
"react-laag": "^2.0.5",
|
"react-laag": "^2.0.5",
|
||||||
|
|
|
||||||
|
|
@ -5,10 +5,11 @@ import {
|
||||||
nodeColors,
|
nodeColors,
|
||||||
snakeToNormalCase,
|
snakeToNormalCase,
|
||||||
} from "../../../../utils";
|
} from "../../../../utils";
|
||||||
import { useEffect, useRef, useState } from "react";
|
import { useContext, useEffect, useRef, useState } from "react";
|
||||||
import InputComponent from "../../../../components/inputComponent";
|
import InputComponent from "../../../../components/inputComponent";
|
||||||
import ToggleComponent from "../../../../components/toggleComponent";
|
import ToggleComponent from "../../../../components/toggleComponent";
|
||||||
import InputListComponent from "../../../../components/inputListComponent";
|
import InputListComponent from "../../../../components/inputListComponent";
|
||||||
|
import { typesContext } from "../../../../contexts/typesContext";
|
||||||
|
|
||||||
export default function ParameterComponent({
|
export default function ParameterComponent({
|
||||||
left,
|
left,
|
||||||
|
|
@ -37,7 +38,8 @@ export default function ParameterComponent({
|
||||||
}, [data.id, position, updateNodeInternals]);
|
}, [data.id, position, updateNodeInternals]);
|
||||||
|
|
||||||
const [enabled, setEnabled] = useState(data.node.template[name]?.value ?? false);
|
const [enabled, setEnabled] = useState(data.node.template[name]?.value ?? false);
|
||||||
let disabled = data.reactFlowInstance.getEdges().some((e) => (e.sourceHandle === id));
|
const {reactFlowInstance} = useContext(typesContext);
|
||||||
|
let disabled = reactFlowInstance?.getEdges().some((e) => (e.sourceHandle === id)) ?? false;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div ref={ref} className="w-full flex flex-wrap justify-between items-center bg-gray-50 mt-1 px-5 py-2">
|
<div ref={ref} className="w-full flex flex-wrap justify-between items-center bg-gray-50 mt-1 px-5 py-2">
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,4 @@
|
||||||
|
import { CookiesProvider } from "react-cookie";
|
||||||
import { AlertProvider } from "./alertContext";
|
import { AlertProvider } from "./alertContext";
|
||||||
import { LocationProvider } from "./locationContext";
|
import { LocationProvider } from "./locationContext";
|
||||||
import PopUpProvider from "./popUpContext";
|
import PopUpProvider from "./popUpContext";
|
||||||
|
|
@ -7,15 +8,17 @@ import { TypesProvider } from "./typesContext";
|
||||||
export default function ContextWrapper({ children }) {
|
export default function ContextWrapper({ children }) {
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<LocationProvider>
|
<CookiesProvider>
|
||||||
<PopUpProvider>
|
<LocationProvider>
|
||||||
<TypesProvider>
|
<PopUpProvider>
|
||||||
<TabsProvider>
|
<TypesProvider>
|
||||||
<AlertProvider>{children}</AlertProvider>
|
<TabsProvider>
|
||||||
</TabsProvider>
|
<AlertProvider>{children}</AlertProvider>
|
||||||
</TypesProvider>
|
</TabsProvider>
|
||||||
</PopUpProvider>
|
</TypesProvider>
|
||||||
</LocationProvider>
|
</PopUpProvider>
|
||||||
|
</LocationProvider>
|
||||||
|
</CookiesProvider>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
import { createContext, useState } from "react";
|
import { createContext, useEffect, useState } from "react";
|
||||||
|
|
||||||
type flow={name:string,id:string,data:any}
|
type flow={name:string,id:string,data:any}
|
||||||
|
|
||||||
|
|
@ -7,8 +7,8 @@ type TabsContextType={
|
||||||
setTabIndex:(index:number)=>void;
|
setTabIndex:(index:number)=>void;
|
||||||
flows:Array<flow>
|
flows:Array<flow>
|
||||||
removeFlow:(id:string)=>void;
|
removeFlow:(id:string)=>void;
|
||||||
addFlow:(newFlow:flow)=>void;
|
addFlow:()=>void;
|
||||||
updateFlow:(newFLow:flow)=>void;
|
updateFlow:(newFlow:flow)=>void;
|
||||||
}
|
}
|
||||||
|
|
||||||
const TabsContextInitialValue = {
|
const TabsContextInitialValue = {
|
||||||
|
|
@ -16,8 +16,8 @@ const TabsContextInitialValue = {
|
||||||
setTabIndex:(index:number)=>{},
|
setTabIndex:(index:number)=>{},
|
||||||
flows:[],
|
flows:[],
|
||||||
removeFlow:(id:string)=>{},
|
removeFlow:(id:string)=>{},
|
||||||
addFlow:(newFlow:flow)=>{},
|
addFlow:()=>{},
|
||||||
updateFlow:(newFLow:flow)=>{}
|
updateFlow:(newFlow:flow)=>{}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
@ -27,6 +27,22 @@ export const TabsContext = createContext<TabsContextType>(TabsContextInitialValu
|
||||||
export function TabsProvider({children}){
|
export function TabsProvider({children}){
|
||||||
const [tabIndex,setTabIndex] = useState(0)
|
const [tabIndex,setTabIndex] = useState(0)
|
||||||
const [flows,setFlows] = useState<Array<flow>>([])
|
const [flows,setFlows] = useState<Array<flow>>([])
|
||||||
|
const [id, setId] = useState(0);
|
||||||
|
useEffect(() => {
|
||||||
|
if(flows.length !== 0)
|
||||||
|
window.localStorage.setItem('tabsData', JSON.stringify({tabIndex, flows, id}));
|
||||||
|
}, [flows, id, tabIndex]);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
let cookie = window.localStorage.getItem('tabsData');
|
||||||
|
if(cookie){
|
||||||
|
let cookieObject = JSON.parse(cookie);
|
||||||
|
setTabIndex(cookieObject.tabIndex);
|
||||||
|
setFlows(cookieObject.flows)
|
||||||
|
setId(cookieObject.id)
|
||||||
|
}
|
||||||
|
}, [])
|
||||||
|
|
||||||
function removeFlow(id:string){
|
function removeFlow(id:string){
|
||||||
setFlows(prevState=>{
|
setFlows(prevState=>{
|
||||||
const newFlows = [...prevState];
|
const newFlows = [...prevState];
|
||||||
|
|
@ -42,14 +58,14 @@ export function TabsProvider({children}){
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
window.sessionStorage.setItem('tabs', JSON.stringify(newFlows));
|
|
||||||
return newFlows;
|
return newFlows;
|
||||||
})
|
});
|
||||||
}
|
}
|
||||||
function addFlow(newFlow: flow) {
|
function addFlow() {
|
||||||
|
let newFlow: flow = {name: "flow"+id, id: id.toString(), data:null}
|
||||||
|
setId((old) => old+1);
|
||||||
setFlows(prevState => {
|
setFlows(prevState => {
|
||||||
const newFlows = [...prevState, newFlow];
|
const newFlows = [...prevState, newFlow];
|
||||||
window.sessionStorage.setItem('tabs', JSON.stringify(newFlows));
|
|
||||||
return newFlows;
|
return newFlows;
|
||||||
});
|
});
|
||||||
setTabIndex(flows.length);
|
setTabIndex(flows.length);
|
||||||
|
|
@ -62,7 +78,6 @@ export function TabsProvider({children}){
|
||||||
newFlows[index].data = newFlow.data
|
newFlows[index].data = newFlow.data
|
||||||
newFlows[index].name = newFlow.name
|
newFlows[index].name = newFlow.name
|
||||||
}
|
}
|
||||||
window.sessionStorage.setItem('tabs', JSON.stringify(newFlows));
|
|
||||||
return newFlows;
|
return newFlows;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,12 +1,17 @@
|
||||||
import { createContext, useState } from "react";
|
import { ReactEventHandler, createContext, useState } from "react";
|
||||||
|
import { ReactFlowInstance } from "reactflow";
|
||||||
|
|
||||||
type typesContextType=
|
type typesContextType=
|
||||||
{
|
{
|
||||||
|
reactFlowInstance: ReactFlowInstance;
|
||||||
|
setReactFlowInstance: any;
|
||||||
types: {};
|
types: {};
|
||||||
setTypes:(newState:{})=>void;
|
setTypes:(newState:{})=>void;
|
||||||
}
|
}
|
||||||
|
|
||||||
const initialValue= {
|
const initialValue= {
|
||||||
|
reactFlowInstance: null,
|
||||||
|
setReactFlowInstance: ()=>{},
|
||||||
types: {},
|
types: {},
|
||||||
setTypes:()=>{},
|
setTypes:()=>{},
|
||||||
}
|
}
|
||||||
|
|
@ -15,8 +20,9 @@ export const typesContext = createContext<typesContextType>(initialValue);
|
||||||
|
|
||||||
export function TypesProvider({children}){
|
export function TypesProvider({children}){
|
||||||
const [types, setTypes] = useState({});
|
const [types, setTypes] = useState({});
|
||||||
|
const [reactFlowInstance, setReactFlowInstance] = useState(null);
|
||||||
return (
|
return (
|
||||||
<typesContext.Provider value={{ types, setTypes}}>
|
<typesContext.Provider value={{ types, setTypes, reactFlowInstance, setReactFlowInstance}}>
|
||||||
{children}
|
{children}
|
||||||
</typesContext.Provider>
|
</typesContext.Provider>
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -9,14 +9,13 @@ export function TabsManager() {
|
||||||
const { flows, addFlow, tabIndex, setTabIndex } = useContext(TabsContext);
|
const { flows, addFlow, tabIndex, setTabIndex } = useContext(TabsContext);
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (flows.length === 0) {
|
if (flows.length === 0) {
|
||||||
const id = _.uniqueId();
|
addFlow();
|
||||||
addFlow({ name: "flow " + id, data: null, id });
|
|
||||||
}
|
}
|
||||||
}, []);
|
}, [addFlow, flows.length]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="h-full w-full flex flex-col">
|
<div className="h-full w-full flex flex-col">
|
||||||
<div className="w-full flex pr-2 flex-row text-center items-center bg-gray-100">
|
<div className="w-full flex pr-2 flex-row text-center items-center bg-gray-100 px-2">
|
||||||
{flows.map((flow, index) => {
|
{flows.map((flow, index) => {
|
||||||
return (
|
return (
|
||||||
<TabComponent
|
<TabComponent
|
||||||
|
|
@ -29,17 +28,19 @@ export function TabsManager() {
|
||||||
})}
|
})}
|
||||||
<TabComponent
|
<TabComponent
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
const id = _.uniqueId();
|
addFlow();
|
||||||
addFlow({ name: "flow" + id, data: null, id });
|
|
||||||
}}
|
}}
|
||||||
selected={false}
|
selected={false}
|
||||||
key={0}
|
|
||||||
flow={null}
|
flow={null}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div className="w-full h-full">
|
<div className="w-full h-full">
|
||||||
<ReactFlowProvider>
|
<ReactFlowProvider>
|
||||||
<FlowPage flow={flows[tabIndex]}></FlowPage>
|
{flows[tabIndex] ? (
|
||||||
|
<FlowPage flow={flows[tabIndex]}></FlowPage>
|
||||||
|
) : (
|
||||||
|
<></>
|
||||||
|
)}
|
||||||
</ReactFlowProvider>
|
</ReactFlowProvider>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -19,6 +19,7 @@ import InputNode from "../../CustomNodes/InputNode";
|
||||||
import BooleanNode from "../../CustomNodes/BooleanNode";
|
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";
|
||||||
|
|
||||||
const nodeTypes = {
|
const nodeTypes = {
|
||||||
genericNode: GenericNode,
|
genericNode: GenericNode,
|
||||||
|
|
@ -31,9 +32,9 @@ const nodeTypes = {
|
||||||
var _ = require("lodash");
|
var _ = require("lodash");
|
||||||
|
|
||||||
export default function FlowPage({flow}) {
|
export default function FlowPage({flow}) {
|
||||||
console.log(flow?.data)
|
|
||||||
|
|
||||||
const {updateFlow} = useContext(TabsContext)
|
const {updateFlow} = useContext(TabsContext)
|
||||||
|
const {reactFlowInstance, setReactFlowInstance} = useContext(typesContext);
|
||||||
const reactFlowWrapper = useRef(null);
|
const reactFlowWrapper = useRef(null);
|
||||||
|
|
||||||
const getId = () => `dndnode_${_.uniqueId()}`;
|
const getId = () => `dndnode_${_.uniqueId()}`;
|
||||||
|
|
@ -41,30 +42,27 @@ export default function FlowPage({flow}) {
|
||||||
const { setExtraComponent, setExtraNavigation } = useContext(locationContext);
|
const { setExtraComponent, setExtraNavigation } = useContext(locationContext);
|
||||||
const { setErrorData } = useContext(alertContext);
|
const { setErrorData } = useContext(alertContext);
|
||||||
|
|
||||||
const [nodes, setNodes, onNodesChange] = useNodesState(flow?.data?.nodes || []);
|
const [nodes, setNodes, onNodesChange] = useNodesState(flow.data?.nodes ?? []);
|
||||||
const [edges, setEdges, onEdgesChange] = useEdgesState(flow?.data?.edges || []);
|
const [edges, setEdges, onEdgesChange] = useEdgesState(flow.data?.edges ?? []);
|
||||||
const [reactFlowInstance, setReactFlowInstance] = useState(null);
|
|
||||||
const { setViewport} = useReactFlow();
|
|
||||||
|
|
||||||
|
|
||||||
useEffect(()=>{
|
|
||||||
if(flow?.data && reactFlowInstance){
|
|
||||||
setViewport(flow.data.viewport)
|
|
||||||
}
|
|
||||||
},[nodes, edges, flow, reactFlowInstance, setViewport])
|
|
||||||
|
|
||||||
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 || [])
|
console.log(flow);
|
||||||
setEdges(flow?.data?.edges || [])
|
setNodes(flow?.data?.nodes ?? [])
|
||||||
|
setEdges(flow?.data?.edges ?? [])
|
||||||
},[flow])
|
},[flow])
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
console.log(nodes);
|
||||||
|
console.log(edges);
|
||||||
|
}, [edges, nodes])
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
setExtraComponent(<ExtraSidebar />);
|
setExtraComponent(<ExtraSidebar />);
|
||||||
setExtraNavigation({ title: "Nodes" });
|
setExtraNavigation({ title: "Nodes" });
|
||||||
|
|
@ -133,7 +131,6 @@ export default function FlowPage({flow}) {
|
||||||
...data,
|
...data,
|
||||||
id: newId,
|
id: newId,
|
||||||
value: null,
|
value: null,
|
||||||
reactFlowInstance,
|
|
||||||
onDelete: () => {
|
onDelete: () => {
|
||||||
setNodes(
|
setNodes(
|
||||||
reactFlowInstance.getNodes().filter((n) => n.id !== newId)
|
reactFlowInstance.getNodes().filter((n) => n.id !== newId)
|
||||||
|
|
@ -156,6 +153,7 @@ export default function FlowPage({flow}) {
|
||||||
<div className="w-full h-full" ref={reactFlowWrapper}>
|
<div className="w-full h-full" ref={reactFlowWrapper}>
|
||||||
<ReactFlow
|
<ReactFlow
|
||||||
nodes={nodes}
|
nodes={nodes}
|
||||||
|
defaultViewport={flow?.data?.viewport ?? {x: 1, y: 0, zoom: 1}}
|
||||||
onMove={()=>updateFlow({...flow,data:reactFlowInstance.toObject()})}
|
onMove={()=>updateFlow({...flow,data:reactFlowInstance.toObject()})}
|
||||||
edges={edges}
|
edges={edges}
|
||||||
onNodesChange={onNodesChange}
|
onNodesChange={onNodesChange}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue