### What problem does this PR solve? feat: clear the selection box to delete the corresponding edge. #918 feat: fix the problem of form entries being deleted when adding a new line #918 ### Type of change - [x] New Feature (non-breaking change which adds functionality)tags/v0.8.0
| export const useHandleFormValuesChange = ({ | export const useHandleFormValuesChange = ({ | ||||
| onValuesChange, | onValuesChange, | ||||
| form, | form, | ||||
| node, | |||||
| nodeId, | |||||
| }: IOperatorForm) => { | }: IOperatorForm) => { | ||||
| const edges = useGraphStore((state) => state.edges); | const edges = useGraphStore((state) => state.edges); | ||||
| const getNode = useGraphStore((state) => state.getNode); | |||||
| const node = getNode(nodeId); | |||||
| const handleValuesChange = useCallback( | const handleValuesChange = useCallback( | ||||
| (changedValues: any, values: any) => { | (changedValues: any, values: any) => { | ||||
| ); | ); | ||||
| useEffect(() => { | useEffect(() => { | ||||
| const items = buildCategorizeListFromObject( | |||||
| get(node, 'data.form.category_description', {}), | |||||
| edges, | |||||
| node, | |||||
| ); | |||||
| form?.setFieldsValue({ | form?.setFieldsValue({ | ||||
| items: buildCategorizeListFromObject( | |||||
| get(node, 'data.form.category_description', {}), | |||||
| edges, | |||||
| node, | |||||
| ), | |||||
| items, | |||||
| }); | }); | ||||
| }, [form, node, edges]); | }, [form, node, edges]); | ||||
| }; | }; | ||||
| export const useHandleToSelectChange = (nodeId?: string) => { | export const useHandleToSelectChange = (nodeId?: string) => { | ||||
| const { addEdge } = useGraphStore((state) => state); | |||||
| const { addEdge, deleteEdgeBySourceAndSourceHandle } = useGraphStore( | |||||
| (state) => state, | |||||
| ); | |||||
| const handleSelectChange = useCallback( | const handleSelectChange = useCallback( | ||||
| (name?: string) => (value?: string) => { | (name?: string) => (value?: string) => { | ||||
| if (nodeId && value && name) { | |||||
| addEdge({ | |||||
| source: nodeId, | |||||
| target: value, | |||||
| sourceHandle: name, | |||||
| targetHandle: null, | |||||
| }); | |||||
| if (nodeId && name) { | |||||
| if (value) { | |||||
| addEdge({ | |||||
| source: nodeId, | |||||
| target: value, | |||||
| sourceHandle: name, | |||||
| targetHandle: null, | |||||
| }); | |||||
| } else { | |||||
| // clear selected value | |||||
| deleteEdgeBySourceAndSourceHandle({ | |||||
| source: nodeId, | |||||
| sourceHandle: name, | |||||
| }); | |||||
| } | |||||
| } | } | ||||
| }, | }, | ||||
| [addEdge, nodeId], | |||||
| [addEdge, nodeId, deleteEdgeBySourceAndSourceHandle], | |||||
| ); | ); | ||||
| return { handleSelectChange }; | return { handleSelectChange }; |
| const { t } = useTranslate('flow'); | const { t } = useTranslate('flow'); | ||||
| const { handleValuesChange } = useHandleFormValuesChange({ | const { handleValuesChange } = useHandleFormValuesChange({ | ||||
| form, | form, | ||||
| node, | |||||
| nodeId: node?.id, | |||||
| onValuesChange, | onValuesChange, | ||||
| }); | }); | ||||
| useSetLlmSetting(form); | useSetLlmSetting(form); |
| // key is the source of the edge, value is the target of the edge | // key is the source of the edge, value is the target of the edge | ||||
| // no connection lines are allowed between key and value | // no connection lines are allowed between key and value | ||||
| export const RestrictedUpstreamMap = { | export const RestrictedUpstreamMap = { | ||||
| [Operator.Begin]: [ | |||||
| Operator.Begin, | |||||
| Operator.Answer, | |||||
| Operator.Categorize, | |||||
| Operator.Generate, | |||||
| Operator.Retrieval, | |||||
| ], | |||||
| [Operator.Begin]: [], | |||||
| [Operator.Categorize]: [Operator.Begin, Operator.Categorize, Operator.Answer], | [Operator.Categorize]: [Operator.Begin, Operator.Categorize, Operator.Answer], | ||||
| [Operator.Answer]: [], | [Operator.Answer]: [], | ||||
| [Operator.Retrieval]: [], | [Operator.Retrieval]: [], |
| onValuesChange?(changedValues: any, values: any): void; | onValuesChange?(changedValues: any, values: any): void; | ||||
| form?: FormInstance; | form?: FormInstance; | ||||
| node?: Node<NodeData>; | node?: Node<NodeData>; | ||||
| nodeId?: string; | |||||
| } | } | ||||
| export interface IBeginForm { | export interface IBeginForm { |
| graph: { | graph: { | ||||
| nodes: [ | nodes: [ | ||||
| { | { | ||||
| id: 'begin', | |||||
| id: 'Begin', | |||||
| type: 'beginNode', | type: 'beginNode', | ||||
| position: { | position: { | ||||
| x: 50, | x: 50, |
| updateNodeForm: (nodeId: string, values: any) => void; | updateNodeForm: (nodeId: string, values: any) => void; | ||||
| onSelectionChange: OnSelectionChangeFunc; | onSelectionChange: OnSelectionChangeFunc; | ||||
| addNode: (nodes: Node) => void; | addNode: (nodes: Node) => void; | ||||
| getNode: (id: string) => Node | undefined; | |||||
| getNode: (id?: string) => Node | undefined; | |||||
| addEdge: (connection: Connection) => void; | addEdge: (connection: Connection) => void; | ||||
| getEdge: (id: string) => Edge | undefined; | getEdge: (id: string) => Edge | undefined; | ||||
| deletePreviousEdgeOfClassificationNode: (connection: Connection) => void; | deletePreviousEdgeOfClassificationNode: (connection: Connection) => void; | ||||
| deleteEdge: () => void; | deleteEdge: () => void; | ||||
| deleteEdgeById: (id: string) => void; | deleteEdgeById: (id: string) => void; | ||||
| deleteNodeById: (id: string) => void; | deleteNodeById: (id: string) => void; | ||||
| deleteEdgeBySourceAndTarget: (source: string, target: string) => void; | |||||
| deleteEdgeBySourceAndSourceHandle: (connection: Partial<Connection>) => void; | |||||
| findNodeByName: (operatorName: Operator) => Node | undefined; | findNodeByName: (operatorName: Operator) => Node | undefined; | ||||
| updateMutableNodeFormItem: (id: string, field: string, value: any) => void; | updateMutableNodeFormItem: (id: string, field: string, value: any) => void; | ||||
| }; | }; | ||||
| addNode: (node: Node) => { | addNode: (node: Node) => { | ||||
| set({ nodes: get().nodes.concat(node) }); | set({ nodes: get().nodes.concat(node) }); | ||||
| }, | }, | ||||
| getNode: (id: string) => { | |||||
| getNode: (id?: string) => { | |||||
| return get().nodes.find((x) => x.id === id); | return get().nodes.find((x) => x.id === id); | ||||
| }, | }, | ||||
| addEdge: (connection: Connection) => { | addEdge: (connection: Connection) => { | ||||
| edges: edges.filter((edge) => edge.id !== id), | edges: edges.filter((edge) => edge.id !== id), | ||||
| }); | }); | ||||
| }, | }, | ||||
| deleteEdgeBySourceAndTarget: (source: string, target: string) => { | |||||
| deleteEdgeBySourceAndSourceHandle: ({ | |||||
| source, | |||||
| sourceHandle, | |||||
| }: Partial<Connection>) => { | |||||
| const { edges } = get(); | const { edges } = get(); | ||||
| const nextEdges = edges.filter( | |||||
| (edge) => | |||||
| edge.source !== source || edge.sourceHandle !== sourceHandle, | |||||
| ); | |||||
| set({ | set({ | ||||
| edges: edges.filter( | |||||
| (edge) => edge.target !== target && edge.source !== source, | |||||
| ), | |||||
| edges: nextEdges, | |||||
| }); | }); | ||||
| }, | }, | ||||
| deleteNodeById: (id: string) => { | deleteNodeById: (id: string) => { |
| // restricted lines cannot be connected successfully. | // restricted lines cannot be connected successfully. | ||||
| export const isValidConnection = (connection: Connection) => { | export const isValidConnection = (connection: Connection) => { | ||||
| return RestrictedUpstreamMap[ | |||||
| const ret = RestrictedUpstreamMap[ | |||||
| getOperatorTypeFromId(connection.source) as Operator | getOperatorTypeFromId(connection.source) as Operator | ||||
| ]?.every((x) => x !== getOperatorTypeFromId(connection.target)); | ]?.every((x) => x !== getOperatorTypeFromId(connection.target)); | ||||
| return ret; | |||||
| }; | }; |