Feat: Use react-hook-form to synchronize the data of the categorize form to the agent node. #3221 (#5665)

### What problem does this PR solve?

Feat: Use react-hook-form to synchronize the data of the categorize form
to the agent node. #3221

### Type of change

- [x] New Feature (non-breaking change which adds functionality)
This commit is contained in:
balibabu 2025-03-05 19:43:08 +08:00 committed by GitHub
parent 4326873af6
commit a54843cc65
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 73 additions and 61 deletions

View File

@ -65,12 +65,15 @@ const FormSheet = ({
const { t } = useTranslate('flow');
const { handleValuesChange } = useHandleFormValuesChange(node?.id);
const { handleValuesChange } = useHandleFormValuesChange(
operatorName,
node?.id,
form,
);
useEffect(() => {
if (visible) {
if (visible && !form.formState.isDirty) {
if (node?.id !== previousId.current) {
// form.resetFields();
form.reset();
form.clearErrors();
}

View File

@ -1,45 +0,0 @@
import {
ICategorizeItem,
ICategorizeItemResult,
} from '@/interfaces/database/flow';
import omit from 'lodash/omit';
import { useCallback } from 'react';
import { IOperatorForm } from '../../interface';
/**
* Convert the list in the following form into an object
* {
"items": [
{
"name": "Categorize 1",
"description": "111",
"examples": "ddd",
"to": "Retrieval:LazyEelsStick"
}
]
}
*/
const buildCategorizeObjectFromList = (list: Array<ICategorizeItem>) => {
return list.reduce<ICategorizeItemResult>((pre, cur) => {
if (cur?.name) {
pre[cur.name] = omit(cur, 'name');
}
return pre;
}, {});
};
export const useHandleFormValuesChange = ({
onValuesChange,
}: IOperatorForm) => {
const handleValuesChange = useCallback(
(changedValues: any, values: any) => {
onValuesChange?.(changedValues, {
...omit(values, 'items'),
category_description: buildCategorizeObjectFromList(values.items),
});
},
[onValuesChange],
);
return { handleValuesChange };
};

View File

@ -6,17 +6,8 @@ import { DynamicInputVariable } from '../components/next-dynamic-input-variable'
import DynamicCategorize from './dynamic-categorize';
const CategorizeForm = ({ form, node }: INextOperatorForm) => {
// const { handleValuesChange } = useHandleFormValuesChange({
// form,
// nodeId: node?.id,
// onValuesChange,
// });
return (
<Form
// onValuesChange={handleValuesChange}
{...form}
>
<Form {...form}>
<form
className="space-y-6 p-5 overflow-auto max-h-[76vh]"
onSubmit={(e) => {

View File

@ -23,8 +23,9 @@ import {
} from '@/interfaces/database/flow';
import { message } from 'antd';
import { humanId } from 'human-id';
import { get, lowerFirst } from 'lodash';
import { get, lowerFirst, omit } from 'lodash';
import trim from 'lodash/trim';
import { UseFormReturn } from 'react-hook-form';
import { useTranslation } from 'react-i18next';
import { v4 as uuid } from 'uuid';
import {
@ -69,6 +70,7 @@ import {
} from './constant';
import useGraphStore, { RFState } from './store';
import {
buildCategorizeObjectFromList,
generateNodeNamesWithIncreasingIndex,
generateSwitchHandleText,
getNodeDragHandle,
@ -258,7 +260,11 @@ export const useHandleDrop = () => {
return { onDrop, onDragOver, setReactFlowInstance };
};
export const useHandleFormValuesChange = (id?: string) => {
export const useHandleFormValuesChange = (
operatorName: Operator,
id?: string,
form?: UseFormReturn,
) => {
const updateNodeForm = useGraphStore((state) => state.updateNodeForm);
const handleValuesChange = useCallback(
(changedValues: any, values: any) => {
@ -283,6 +289,41 @@ export const useHandleFormValuesChange = (id?: string) => {
[updateNodeForm, id],
);
useEffect(() => {
const subscription = form?.watch((value, { name, type, values }) => {
if (id && name) {
console.log('🚀 ~ useEffect ~ value:', type, values);
let nextValues: any = value;
// Fixed the issue that the related form value does not change after selecting the freedom field of the model
if (
name === 'parameter' &&
value['parameter'] in settledModelVariableMap
) {
nextValues = {
...value,
...settledModelVariableMap[
value['parameter'] as keyof typeof settledModelVariableMap
],
};
}
const categoryDescriptionRegex = /items\.\d+\.name/g;
if (
operatorName === Operator.Categorize &&
categoryDescriptionRegex.test(name)
) {
nextValues = {
...omit(value, 'items'),
category_description: buildCategorizeObjectFromList(value.items),
};
}
updateNodeForm(id, nextValues);
}
});
return () => subscription?.unsubscribe();
}, [form, form?.watch, id, operatorName, updateNodeForm]);
return { handleValuesChange };
};

View File

@ -8,7 +8,7 @@ import { removeUselessFieldsFromValues } from '@/utils/form';
import { Edge, Node, Position, XYPosition } from '@xyflow/react';
import { FormInstance, FormListFieldData } from 'antd';
import { humanId } from 'human-id';
import { curry, get, intersectionWith, isEqual, sample } from 'lodash';
import { curry, get, intersectionWith, isEqual, omit, sample } from 'lodash';
import pipe from 'lodash/fp/pipe';
import isObject from 'lodash/isObject';
import { v4 as uuidv4 } from 'uuid';
@ -416,3 +416,25 @@ export const buildCategorizeListFromObject = (
}, [])
.sort((a, b) => a.index - b.index);
};
/**
* Convert the list in the following form into an object
* {
"items": [
{
"name": "Categorize 1",
"description": "111",
"examples": "ddd",
"to": "Retrieval:LazyEelsStick"
}
]
}
*/
export const buildCategorizeObjectFromList = (list: Array<ICategorizeItem>) => {
return list.reduce<ICategorizeItemResult>((pre, cur) => {
if (cur?.name) {
pre[cur.name] = omit(cur, 'name');
}
return pre;
}, {});
};