2024-05-23 18:53:04 +08:00
|
|
|
import { useSetModalState } from '@/hooks/commonHooks';
|
2024-06-05 10:46:06 +08:00
|
|
|
import { useFetchFlowTemplates } from '@/hooks/flow-hooks';
|
|
|
|
|
import { useFetchLlmList } from '@/hooks/llmHooks';
|
|
|
|
|
import React, { KeyboardEventHandler, useCallback, useState } from 'react';
|
|
|
|
|
import { Node, Position, ReactFlowInstance } from 'reactflow';
|
2024-05-23 18:53:04 +08:00
|
|
|
import { v4 as uuidv4 } from 'uuid';
|
2024-06-05 10:46:06 +08:00
|
|
|
import useStore, { RFState } from './store';
|
|
|
|
|
import { buildDslComponentsByGraph } from './utils';
|
|
|
|
|
|
|
|
|
|
const selector = (state: RFState) => ({
|
|
|
|
|
nodes: state.nodes,
|
|
|
|
|
edges: state.edges,
|
|
|
|
|
onNodesChange: state.onNodesChange,
|
|
|
|
|
onEdgesChange: state.onEdgesChange,
|
|
|
|
|
onConnect: state.onConnect,
|
|
|
|
|
setNodes: state.setNodes,
|
|
|
|
|
onSelectionChange: state.onSelectionChange,
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
export const useSelectCanvasData = () => {
|
|
|
|
|
// return useStore(useShallow(selector)); throw error
|
|
|
|
|
return useStore(selector);
|
|
|
|
|
};
|
2024-04-28 19:03:54 +08:00
|
|
|
|
|
|
|
|
export const useHandleDrag = () => {
|
2024-05-23 18:53:04 +08:00
|
|
|
const handleDragStart = useCallback(
|
2024-04-28 19:03:54 +08:00
|
|
|
(operatorId: string) => (ev: React.DragEvent<HTMLDivElement>) => {
|
2024-05-23 18:53:04 +08:00
|
|
|
ev.dataTransfer.setData('application/reactflow', operatorId);
|
|
|
|
|
ev.dataTransfer.effectAllowed = 'move';
|
2024-04-28 19:03:54 +08:00
|
|
|
},
|
|
|
|
|
[],
|
|
|
|
|
);
|
|
|
|
|
|
2024-05-23 18:53:04 +08:00
|
|
|
return { handleDragStart };
|
2024-04-28 19:03:54 +08:00
|
|
|
};
|
|
|
|
|
|
2024-06-05 10:46:06 +08:00
|
|
|
export const useHandleDrop = () => {
|
|
|
|
|
const addNode = useStore((state) => state.addNode);
|
2024-05-23 18:53:04 +08:00
|
|
|
const [reactFlowInstance, setReactFlowInstance] =
|
|
|
|
|
useState<ReactFlowInstance<any, any>>();
|
|
|
|
|
|
|
|
|
|
const onDragOver = useCallback((event: React.DragEvent<HTMLDivElement>) => {
|
|
|
|
|
event.preventDefault();
|
|
|
|
|
event.dataTransfer.dropEffect = 'move';
|
|
|
|
|
}, []);
|
|
|
|
|
|
|
|
|
|
const onDrop = useCallback(
|
|
|
|
|
(event: React.DragEvent<HTMLDivElement>) => {
|
|
|
|
|
event.preventDefault();
|
|
|
|
|
|
|
|
|
|
const type = event.dataTransfer.getData('application/reactflow');
|
|
|
|
|
|
|
|
|
|
// check if the dropped element is valid
|
|
|
|
|
if (typeof type === 'undefined' || !type) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
2024-04-28 19:03:54 +08:00
|
|
|
|
2024-05-23 18:53:04 +08:00
|
|
|
// reactFlowInstance.project was renamed to reactFlowInstance.screenToFlowPosition
|
|
|
|
|
// and you don't need to subtract the reactFlowBounds.left/top anymore
|
|
|
|
|
// details: https://reactflow.dev/whats-new/2023-11-10
|
|
|
|
|
const position = reactFlowInstance?.screenToFlowPosition({
|
|
|
|
|
x: event.clientX,
|
|
|
|
|
y: event.clientY,
|
2024-04-28 19:03:54 +08:00
|
|
|
});
|
2024-05-23 18:53:04 +08:00
|
|
|
const newNode = {
|
|
|
|
|
id: uuidv4(),
|
2024-05-27 08:21:30 +08:00
|
|
|
type: 'textUpdater',
|
2024-05-23 18:53:04 +08:00
|
|
|
position: position || {
|
|
|
|
|
x: 0,
|
|
|
|
|
y: 0,
|
|
|
|
|
},
|
2024-05-27 08:21:30 +08:00
|
|
|
data: { label: `${type}` },
|
|
|
|
|
sourcePosition: Position.Right,
|
|
|
|
|
targetPosition: Position.Left,
|
2024-05-23 18:53:04 +08:00
|
|
|
};
|
|
|
|
|
|
2024-06-05 10:46:06 +08:00
|
|
|
addNode(newNode);
|
2024-04-28 19:03:54 +08:00
|
|
|
},
|
2024-06-05 10:46:06 +08:00
|
|
|
[reactFlowInstance, addNode],
|
2024-04-28 19:03:54 +08:00
|
|
|
);
|
|
|
|
|
|
2024-05-23 18:53:04 +08:00
|
|
|
return { onDrop, onDragOver, setReactFlowInstance };
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
export const useShowDrawer = () => {
|
2024-06-05 10:46:06 +08:00
|
|
|
const [clickedNode, setClickedNode] = useState<Node>();
|
2024-05-23 18:53:04 +08:00
|
|
|
const {
|
|
|
|
|
visible: drawerVisible,
|
|
|
|
|
hideModal: hideDrawer,
|
|
|
|
|
showModal: showDrawer,
|
|
|
|
|
} = useSetModalState();
|
|
|
|
|
|
2024-06-05 10:46:06 +08:00
|
|
|
const handleShow = useCallback(
|
|
|
|
|
(node: Node) => {
|
|
|
|
|
setClickedNode(node);
|
|
|
|
|
showDrawer();
|
|
|
|
|
},
|
|
|
|
|
[showDrawer],
|
|
|
|
|
);
|
|
|
|
|
|
2024-05-23 18:53:04 +08:00
|
|
|
return {
|
|
|
|
|
drawerVisible,
|
|
|
|
|
hideDrawer,
|
2024-06-05 10:46:06 +08:00
|
|
|
showDrawer: handleShow,
|
|
|
|
|
clickedNode,
|
2024-05-23 18:53:04 +08:00
|
|
|
};
|
2024-04-28 19:03:54 +08:00
|
|
|
};
|
2024-05-29 10:01:39 +08:00
|
|
|
|
2024-06-05 10:46:06 +08:00
|
|
|
export const useHandleKeyUp = () => {
|
|
|
|
|
const deleteEdge = useStore((state) => state.deleteEdge);
|
2024-05-29 10:01:39 +08:00
|
|
|
const handleKeyUp: KeyboardEventHandler = useCallback(
|
|
|
|
|
(e) => {
|
|
|
|
|
if (e.code === 'Delete') {
|
|
|
|
|
deleteEdge();
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
[deleteEdge],
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
return { handleKeyUp };
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
export const useSaveGraph = () => {
|
2024-06-05 10:46:06 +08:00
|
|
|
const { nodes, edges } = useStore((state) => state);
|
|
|
|
|
const saveGraph = useCallback(() => {
|
|
|
|
|
const x = buildDslComponentsByGraph(nodes, edges);
|
|
|
|
|
console.info('components:', x);
|
|
|
|
|
}, [nodes, edges]);
|
2024-05-29 10:01:39 +08:00
|
|
|
|
|
|
|
|
return { saveGraph };
|
|
|
|
|
};
|
2024-06-05 10:46:06 +08:00
|
|
|
|
|
|
|
|
export const useHandleFormValuesChange = (id?: string) => {
|
|
|
|
|
const updateNodeForm = useStore((state) => state.updateNodeForm);
|
|
|
|
|
const handleValuesChange = useCallback(
|
|
|
|
|
(changedValues: any, values: any) => {
|
|
|
|
|
console.info(changedValues, values);
|
|
|
|
|
if (id) {
|
|
|
|
|
updateNodeForm(id, values);
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
[updateNodeForm, id],
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
return { handleValuesChange };
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
export const useFetchDataOnMount = () => {
|
|
|
|
|
useFetchFlowTemplates();
|
|
|
|
|
useFetchLlmList();
|
|
|
|
|
};
|