diff --git a/web/src/pages/agent/canvas/node/categorize-node.tsx b/web/src/pages/agent/canvas/node/categorize-node.tsx index 14b7a66db..397ed9eee 100644 --- a/web/src/pages/agent/canvas/node/categorize-node.tsx +++ b/web/src/pages/agent/canvas/node/categorize-node.tsx @@ -1,15 +1,14 @@ import LLMLabel from '@/components/llm-select/llm-label'; -import { useTheme } from '@/components/theme-provider'; import { ICategorizeNode } from '@/interfaces/database/flow'; -import { Handle, NodeProps, Position } from '@xyflow/react'; -import { Flex } from 'antd'; -import classNames from 'classnames'; +import { NodeProps, Position } from '@xyflow/react'; import { get } from 'lodash'; import { memo } from 'react'; +import { CommonHandle } from './handle'; import { RightHandleStyle } from './handle-icon'; -import { useBuildCategorizeHandlePositions } from './hooks'; -import styles from './index.less'; import NodeHeader from './node-header'; +import { NodeWrapper } from './node-wrapper'; +import { ToolBar } from './toolbar'; +import { useBuildCategorizeHandlePositions } from './use-build-categorize-handle-positions'; export function InnerCategorizeNode({ id, @@ -17,54 +16,42 @@ export function InnerCategorizeNode({ selected, }: NodeProps) { const { positions } = useBuildCategorizeHandlePositions({ data, id }); - const { theme } = useTheme(); return ( -
- + + + - + - -
- -
- {positions.map((position, idx) => { - return ( -
-
{position.text}
- -
- ); - })} -
-
+
+
+ +
+ {positions.map((position, idx) => { + return ( +
+
+ {position.text} +
+ +
+ ); + })} +
+ + ); } diff --git a/web/src/pages/agent/canvas/node/node-wrapper.tsx b/web/src/pages/agent/canvas/node/node-wrapper.tsx index 8754cf103..e0010cad2 100644 --- a/web/src/pages/agent/canvas/node/node-wrapper.tsx +++ b/web/src/pages/agent/canvas/node/node-wrapper.tsx @@ -8,7 +8,7 @@ export function NodeWrapper({ return (
diff --git a/web/src/pages/agent/canvas/node/switch-node.tsx b/web/src/pages/agent/canvas/node/switch-node.tsx index 1fbd5919e..6829f792e 100644 --- a/web/src/pages/agent/canvas/node/switch-node.tsx +++ b/web/src/pages/agent/canvas/node/switch-node.tsx @@ -7,10 +7,10 @@ import { SwitchOperatorOptions } from '../../constant'; import { useGetComponentLabelByValue } from '../../hooks/use-get-begin-query'; import { CommonHandle } from './handle'; import { RightHandleStyle } from './handle-icon'; -import { useBuildSwitchHandlePositions } from './hooks'; import NodeHeader from './node-header'; import { NodeWrapper } from './node-wrapper'; import { ToolBar } from './toolbar'; +import { useBuildSwitchHandlePositions } from './use-build-switch-handle-positions'; const getConditionKey = (idx: number, length: number) => { if (idx === 0 && length !== 1) { diff --git a/web/src/pages/agent/canvas/node/use-build-categorize-handle-positions.ts b/web/src/pages/agent/canvas/node/use-build-categorize-handle-positions.ts new file mode 100644 index 000000000..e5249ae56 --- /dev/null +++ b/web/src/pages/agent/canvas/node/use-build-categorize-handle-positions.ts @@ -0,0 +1,45 @@ +import { ICategorizeItemResult } from '@/interfaces/database/agent'; +import { RAGFlowNodeType } from '@/interfaces/database/flow'; +import { useUpdateNodeInternals } from '@xyflow/react'; +import { get } from 'lodash'; +import { useEffect, useMemo } from 'react'; + +export const useBuildCategorizeHandlePositions = ({ + data, + id, +}: { + id: string; + data: RAGFlowNodeType['data']; +}) => { + const updateNodeInternals = useUpdateNodeInternals(); + + const categoryData: ICategorizeItemResult = useMemo(() => { + return get(data, `form.category_description`, {}); + }, [data]); + + const positions = useMemo(() => { + const list: Array<{ + text: string; + top: number; + idx: number; + }> = []; + + Object.keys(categoryData) + .sort((a, b) => categoryData[a].index - categoryData[b].index) + .forEach((x, idx) => { + list.push({ + text: x, + idx, + top: idx === 0 ? 86 : list[idx - 1].top + 8 + 24, + }); + }); + + return list; + }, [categoryData]); + + useEffect(() => { + updateNodeInternals(id); + }, [id, updateNodeInternals, categoryData]); + + return { positions }; +}; diff --git a/web/src/pages/agent/canvas/node/hooks.ts b/web/src/pages/agent/canvas/node/use-build-switch-handle-positions.ts similarity index 56% rename from web/src/pages/agent/canvas/node/hooks.ts rename to web/src/pages/agent/canvas/node/use-build-switch-handle-positions.ts index 116cae119..eb0d0c5f1 100644 --- a/web/src/pages/agent/canvas/node/hooks.ts +++ b/web/src/pages/agent/canvas/node/use-build-switch-handle-positions.ts @@ -1,55 +1,10 @@ +import { ISwitchCondition, RAGFlowNodeType } from '@/interfaces/database/flow'; import { useUpdateNodeInternals } from '@xyflow/react'; import get from 'lodash/get'; import { useEffect, useMemo } from 'react'; import { SwitchElseTo } from '../../constant'; - -import { - ICategorizeItemResult, - ISwitchCondition, - RAGFlowNodeType, -} from '@/interfaces/database/flow'; import { generateSwitchHandleText } from '../../utils'; -export const useBuildCategorizeHandlePositions = ({ - data, - id, -}: { - id: string; - data: RAGFlowNodeType['data']; -}) => { - const updateNodeInternals = useUpdateNodeInternals(); - - const categoryData: ICategorizeItemResult = useMemo(() => { - return get(data, `form.category_description`, {}); - }, [data]); - - const positions = useMemo(() => { - const list: Array<{ - text: string; - top: number; - idx: number; - }> = []; - - Object.keys(categoryData) - .sort((a, b) => categoryData[a].index - categoryData[b].index) - .forEach((x, idx) => { - list.push({ - text: x, - idx, - top: idx === 0 ? 98 + 20 : list[idx - 1].top + 8 + 26, - }); - }); - - return list; - }, [categoryData]); - - useEffect(() => { - updateNodeInternals(id); - }, [id, updateNodeInternals, categoryData]); - - return { positions }; -}; - export const useBuildSwitchHandlePositions = ({ data, id, @@ -63,6 +18,10 @@ export const useBuildSwitchHandlePositions = ({ return get(data, 'form.conditions', []); }, [data]); + useEffect(() => { + console.info('xxx0000'); + }, [conditions]); + const positions = useMemo(() => { const list: Array<{ text: string; @@ -72,12 +31,12 @@ export const useBuildSwitchHandlePositions = ({ }> = []; [...conditions, ''].forEach((x, idx) => { - let top = idx === 0 ? 58 + 20 : list[idx - 1].top + 10; // case number (Case 1) height + flex gap - if (idx - 1 >= 0) { + let top = idx === 0 ? 53 : list[idx - 1].top + 10 + 14; // case number (Case 1) height + flex gap + if (idx >= 1) { const previousItems = conditions[idx - 1]?.items ?? []; if (previousItems.length > 0) { // top += 12; // ConditionBlock padding - top += previousItems.length * 22; // condition variable height + top += previousItems.length * 26; // condition variable height // top += (previousItems.length - 1) * 25; // operator height } } diff --git a/web/src/pages/agent/form/switch-form/index.tsx b/web/src/pages/agent/form/switch-form/index.tsx index e70df46ce..e1f98f352 100644 --- a/web/src/pages/agent/form/switch-form/index.tsx +++ b/web/src/pages/agent/form/switch-form/index.tsx @@ -27,9 +27,9 @@ import { } from '../../constant'; import { useBuildFormSelectOptions } from '../../form-hooks'; import { useBuildComponentIdAndBeginOptions } from '../../hooks/use-get-begin-query'; -import { useWatchFormChange } from '../../hooks/use-watch-form-change'; import { IOperatorForm } from '../../interface'; import { useValues } from './use-values'; +import { useWatchFormChange } from './use-watch-change'; const ConditionKey = 'conditions'; const ItemKey = 'items'; diff --git a/web/src/pages/agent/form/switch-form/use-watch-change.ts b/web/src/pages/agent/form/switch-form/use-watch-change.ts new file mode 100644 index 000000000..c672ad221 --- /dev/null +++ b/web/src/pages/agent/form/switch-form/use-watch-change.ts @@ -0,0 +1,23 @@ +import { ISwitchCondition } from '@/interfaces/database/agent'; +import { useEffect } from 'react'; +import { UseFormReturn, useWatch } from 'react-hook-form'; +import useGraphStore from '../../store'; + +export function useWatchFormChange(id?: string, form?: UseFormReturn) { + let values = useWatch({ control: form?.control }); + const updateNodeForm = useGraphStore((state) => state.updateNodeForm); + + useEffect(() => { + // Manually triggered form updates are synchronized to the canvas + if (id && form?.formState.isDirty) { + values = form?.getValues(); + let nextValues: any = { + ...values, + conditions: + values?.conditions?.map((x: ISwitchCondition) => ({ ...x })) ?? [], // Changing the form value with useFieldArray does not change the array reference + }; + + updateNodeForm(id, nextValues); + } + }, [form?.formState.isDirty, id, updateNodeForm, values]); +}