From de610091eb7abc467206159dbc2c8b34b648f905 Mon Sep 17 00:00:00 2001 From: balibabu Date: Fri, 5 Jul 2024 19:08:00 +0800 Subject: [PATCH] feat: after deleting the edge, set the corresponding field in the node's form field to undefined #918 (#1393) ### What problem does this PR solve? feat: after deleting the edge, set the corresponding field in the node's form field to undefined #918 ### Type of change - [x] New Feature (non-breaking change which adds functionality) --- web/src/locales/en.ts | 5 ++-- web/src/locales/zh.ts | 21 ++++++++++++++++ web/src/pages/flow/flow-sider/index.tsx | 5 ++-- web/src/pages/flow/relevant-form/hooks.ts | 13 ++++++++-- web/src/pages/flow/store.ts | 30 ++++++++++++++++++----- 5 files changed, 61 insertions(+), 13 deletions(-) diff --git a/web/src/locales/en.ts b/web/src/locales/en.ts index 2dc8fb4d0..43cc67a67 100644 --- a/web/src/locales/en.ts +++ b/web/src/locales/en.ts @@ -573,9 +573,8 @@ The above is the content you need to summarize.`, relevantDescription: `This component is used to judge if the output of upstream is relevent to user's latest question. 'Yes' represents that they're relevant. 'No' represents they're irrelevant.`, rewriteQuestionDescription: `This component is used to refine user's quesion. Typically, when a user's original question can't retrieve relevant information from knowledge base, this component help you change the question into a proper one which might be more consistant with the expressions in knowledge base. Only 'Retrieval' can be its downstreams.`, messageDescription: - 'This component is used to send user static information.', - keywordDescription: - 'This component is used to send user static information.', + 'This component is used to send user static information. You can prepare several messages which will be chosen randomly.', + keywordDescription: `This component is used to extract keywords from user's question. Top N specifies the number of keywords you need to extract.`, promptText: `Please summarize the following paragraphs. Be careful with the numbers, do not make things up. Paragraphs as following: {input} The above is the content you need to summarize.`, diff --git a/web/src/locales/zh.ts b/web/src/locales/zh.ts index 15f726a4a..f792c8307 100644 --- a/web/src/locales/zh.ts +++ b/web/src/locales/zh.ts @@ -537,6 +537,27 @@ export default { messageMsg: '请输入消息或删除此字段。', addField: '新增字段', loop: '环', + createFlow: 'Create a workflow', + yes: 'Yes', + no: 'No', + key: 'key', + componentId: 'component id', + add: 'Add', + operation: 'operation', + beginDescription: 'This is where the flow begin', + answerDescription: `This component is used as an interface between bot and human. It receives input of user and display the result of the computation of the bot.`, + retrievalDescription: `This component is for the process of retrieving relevent information from knowledge base. So, knowledgebases should be selected. If there's nothing retrieved, the 'Empty response' will be returned.`, + generateDescription: `This component is used to call LLM to generate text. Be careful about the prompt setting.`, + categorizeDescription: `This component is used to categorize text. Please specify the name, description and examples of the category. Every single category leads to different downstream components.`, + relevantDescription: `This component is used to judge if the output of upstream is relevent to user's latest question. 'Yes' represents that they're relevant. 'No' represents they're irrelevant.`, + rewriteQuestionDescription: `This component is used to refine user's quesion. Typically, when a user's original question can't retrieve relevant information from knowledge base, this component help you change the question into a proper one which might be more consistant with the expressions in knowledge base. Only 'Retrieval' can be its downstreams.`, + messageDescription: + 'This component is used to send user static information.', + keywordDescription: + 'This component is used to send user static information.', + promptText: `Please summarize the following paragraphs. Be careful with the numbers, do not make things up. Paragraphs as following: + {input} + The above is the content you need to summarize.`, }, footer: { profile: 'All rights reserved @ React', diff --git a/web/src/pages/flow/flow-sider/index.tsx b/web/src/pages/flow/flow-sider/index.tsx index d417c9832..f6b537611 100644 --- a/web/src/pages/flow/flow-sider/index.tsx +++ b/web/src/pages/flow/flow-sider/index.tsx @@ -2,6 +2,7 @@ import { useTranslate } from '@/hooks/commonHooks'; import { Card, Divider, Flex, Layout, Tooltip } from 'antd'; import classNames from 'classnames'; import lowerFirst from 'lodash/lowerFirst'; +import React from 'react'; import { Operator, componentMenuList } from '../constant'; import { useHandleDrag } from '../hooks'; import OperatorIcon from '../operator-icon'; @@ -29,7 +30,7 @@ const FlowSide = ({ setCollapsed, collapsed }: IProps) => { {componentMenuList.map((x) => { return ( - <> + {x.name === Operator.DuckDuckGo && ( { - + ); })} diff --git a/web/src/pages/flow/relevant-form/hooks.ts b/web/src/pages/flow/relevant-form/hooks.ts index befadbbee..815b9701a 100644 --- a/web/src/pages/flow/relevant-form/hooks.ts +++ b/web/src/pages/flow/relevant-form/hooks.ts @@ -1,3 +1,4 @@ +import pick from 'lodash/pick'; import { useCallback, useEffect } from 'react'; import { Edge } from 'reactflow'; import { IOperatorForm } from '../interface'; @@ -30,6 +31,14 @@ const getTargetOfEdge = (edges: Edge[], sourceHandle: string) => */ export const useWatchConnectionChanges = ({ nodeId, form }: IOperatorForm) => { const edges = useGraphStore((state) => state.edges); + const getNode = useGraphStore((state) => state.getNode); + const node = getNode(nodeId); + + const watchFormChanges = useCallback(() => { + if (node) { + form?.setFieldsValue(pick(node, ['yes', 'no'])); + } + }, [node, form]); const watchConnectionChanges = useCallback(() => { const edgeList = edges.filter((x) => x.source === nodeId); @@ -39,6 +48,6 @@ export const useWatchConnectionChanges = ({ nodeId, form }: IOperatorForm) => { }, [edges, nodeId, form]); useEffect(() => { - watchConnectionChanges(); - }, [watchConnectionChanges]); + watchFormChanges(); + }, [watchFormChanges]); }; diff --git a/web/src/pages/flow/store.ts b/web/src/pages/flow/store.ts index f8f51b753..206075269 100644 --- a/web/src/pages/flow/store.ts +++ b/web/src/pages/flow/store.ts @@ -38,6 +38,7 @@ export type RFState = { getNode: (id?: string | null) => Node | undefined; addEdge: (connection: Connection) => void; getEdge: (id: string) => Edge | undefined; + updateFormDataOnConnect: (connection: Connection) => void; deletePreviousEdgeOfClassificationNode: (connection: Connection) => void; duplicateNode: (id: string) => void; deleteEdge: () => void; @@ -71,10 +72,15 @@ const useGraphStore = create()( }); }, onConnect: (connection: Connection) => { + const { + deletePreviousEdgeOfClassificationNode, + updateFormDataOnConnect, + } = get(); set({ edges: addEdge(connection, get().edges), }); - get().deletePreviousEdgeOfClassificationNode(connection); + deletePreviousEdgeOfClassificationNode(connection); + updateFormDataOnConnect(connection); }, onSelectionChange: ({ nodes, edges }: OnSelectionChangeParams) => { set({ @@ -106,9 +112,16 @@ const useGraphStore = create()( getEdge: (id: string) => { return get().edges.find((x) => x.id === id); }, + updateFormDataOnConnect: (connection: Connection) => { + const { getOperatorTypeFromId, updateNodeForm } = get(); + const { source, target, sourceHandle } = connection; + if (source && getOperatorTypeFromId(source) === Operator.Relevant) { + updateNodeForm(source, { [sourceHandle as string]: target }); + } + }, deletePreviousEdgeOfClassificationNode: (connection: Connection) => { // Delete the edge on the classification node or relevant node anchor when the anchor is connected to other nodes - const { edges, getOperatorTypeFromId } = get(); + const { edges, getOperatorTypeFromId, deleteEdgeById } = get(); // the node containing the anchor const anchoredNodes = [Operator.Categorize, Operator.Relevant]; if ( @@ -123,9 +136,7 @@ const useGraphStore = create()( x.target !== connection.target, ); if (previousEdge) { - set({ - edges: edges.filter((edge) => edge !== previousEdge), - }); + deleteEdgeById(previousEdge.id); } } }, @@ -155,7 +166,14 @@ const useGraphStore = create()( }); }, deleteEdgeById: (id: string) => { - const { edges } = get(); + const { edges, updateNodeForm } = get(); + const currentEdge = edges.find((x) => x.id === id); + if (currentEdge) { + // After deleting the edge, set the corresponding field in the node's form field to undefined + updateNodeForm(currentEdge.source, { + [currentEdge.sourceHandle as string]: undefined, + }); + } set({ edges: edges.filter((edge) => edge.id !== id), });