62 lines
1.7 KiB
TypeScript
62 lines
1.7 KiB
TypeScript
import React, { memo, useCallback, Dispatch, FC } from 'react';
|
|
import { useZoomPanHelper, OnLoadParams, Elements, FlowExportObject } from 'react-flow-renderer';
|
|
import localforage from 'localforage';
|
|
|
|
localforage.config({
|
|
name: 'react-flow',
|
|
storeName: 'flows',
|
|
});
|
|
|
|
const flowKey = 'example-flow';
|
|
|
|
const getNodeId = () => `randomnode_${+new Date()}`;
|
|
|
|
type ControlsProps = {
|
|
rfInstance?: OnLoadParams;
|
|
setElements: Dispatch<React.SetStateAction<Elements<any>>>;
|
|
};
|
|
|
|
const Controls: FC<ControlsProps> = ({ rfInstance, setElements }) => {
|
|
const { transform } = useZoomPanHelper();
|
|
|
|
const onSave = useCallback(() => {
|
|
if (rfInstance) {
|
|
const flow = rfInstance.toObject();
|
|
localforage.setItem(flowKey, flow);
|
|
}
|
|
}, [rfInstance]);
|
|
|
|
const onRestore = useCallback(() => {
|
|
const restoreFlow = async () => {
|
|
const flow: FlowExportObject | null = await localforage.getItem(flowKey);
|
|
|
|
if (flow) {
|
|
const [x = 0, y = 0] = flow.position;
|
|
setElements(flow.elements || []);
|
|
transform({ x, y, zoom: flow.zoom || 0 });
|
|
}
|
|
};
|
|
|
|
restoreFlow();
|
|
}, [setElements, transform]);
|
|
|
|
const onAdd = useCallback(() => {
|
|
const newNode = {
|
|
id: `random_node-${getNodeId()}`,
|
|
data: { label: 'Added node' },
|
|
position: { x: Math.random() * window.innerWidth - 100, y: Math.random() * window.innerHeight },
|
|
};
|
|
setElements((els) => els.concat(newNode));
|
|
}, [setElements]);
|
|
|
|
return (
|
|
<div className="save__controls">
|
|
<button onClick={onSave}>save</button>
|
|
<button onClick={onRestore}>restore</button>
|
|
<button onClick={onAdd}>add node</button>
|
|
</div>
|
|
);
|
|
};
|
|
|
|
export default memo(Controls);
|