mirror of
https://git.mirrors.martin98.com/https://github.com/infiniflow/ragflow.git
synced 2025-08-15 18:55:57 +08:00
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:
parent
4326873af6
commit
a54843cc65
@ -65,12 +65,15 @@ const FormSheet = ({
|
|||||||
|
|
||||||
const { t } = useTranslate('flow');
|
const { t } = useTranslate('flow');
|
||||||
|
|
||||||
const { handleValuesChange } = useHandleFormValuesChange(node?.id);
|
const { handleValuesChange } = useHandleFormValuesChange(
|
||||||
|
operatorName,
|
||||||
|
node?.id,
|
||||||
|
form,
|
||||||
|
);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (visible) {
|
if (visible && !form.formState.isDirty) {
|
||||||
if (node?.id !== previousId.current) {
|
if (node?.id !== previousId.current) {
|
||||||
// form.resetFields();
|
|
||||||
form.reset();
|
form.reset();
|
||||||
form.clearErrors();
|
form.clearErrors();
|
||||||
}
|
}
|
||||||
|
@ -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 };
|
|
||||||
};
|
|
@ -6,17 +6,8 @@ import { DynamicInputVariable } from '../components/next-dynamic-input-variable'
|
|||||||
import DynamicCategorize from './dynamic-categorize';
|
import DynamicCategorize from './dynamic-categorize';
|
||||||
|
|
||||||
const CategorizeForm = ({ form, node }: INextOperatorForm) => {
|
const CategorizeForm = ({ form, node }: INextOperatorForm) => {
|
||||||
// const { handleValuesChange } = useHandleFormValuesChange({
|
|
||||||
// form,
|
|
||||||
// nodeId: node?.id,
|
|
||||||
// onValuesChange,
|
|
||||||
// });
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Form
|
<Form {...form}>
|
||||||
// onValuesChange={handleValuesChange}
|
|
||||||
{...form}
|
|
||||||
>
|
|
||||||
<form
|
<form
|
||||||
className="space-y-6 p-5 overflow-auto max-h-[76vh]"
|
className="space-y-6 p-5 overflow-auto max-h-[76vh]"
|
||||||
onSubmit={(e) => {
|
onSubmit={(e) => {
|
||||||
|
@ -23,8 +23,9 @@ import {
|
|||||||
} from '@/interfaces/database/flow';
|
} from '@/interfaces/database/flow';
|
||||||
import { message } from 'antd';
|
import { message } from 'antd';
|
||||||
import { humanId } from 'human-id';
|
import { humanId } from 'human-id';
|
||||||
import { get, lowerFirst } from 'lodash';
|
import { get, lowerFirst, omit } from 'lodash';
|
||||||
import trim from 'lodash/trim';
|
import trim from 'lodash/trim';
|
||||||
|
import { UseFormReturn } from 'react-hook-form';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
import { v4 as uuid } from 'uuid';
|
import { v4 as uuid } from 'uuid';
|
||||||
import {
|
import {
|
||||||
@ -69,6 +70,7 @@ import {
|
|||||||
} from './constant';
|
} from './constant';
|
||||||
import useGraphStore, { RFState } from './store';
|
import useGraphStore, { RFState } from './store';
|
||||||
import {
|
import {
|
||||||
|
buildCategorizeObjectFromList,
|
||||||
generateNodeNamesWithIncreasingIndex,
|
generateNodeNamesWithIncreasingIndex,
|
||||||
generateSwitchHandleText,
|
generateSwitchHandleText,
|
||||||
getNodeDragHandle,
|
getNodeDragHandle,
|
||||||
@ -258,7 +260,11 @@ export const useHandleDrop = () => {
|
|||||||
return { onDrop, onDragOver, setReactFlowInstance };
|
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 updateNodeForm = useGraphStore((state) => state.updateNodeForm);
|
||||||
const handleValuesChange = useCallback(
|
const handleValuesChange = useCallback(
|
||||||
(changedValues: any, values: any) => {
|
(changedValues: any, values: any) => {
|
||||||
@ -283,6 +289,41 @@ export const useHandleFormValuesChange = (id?: string) => {
|
|||||||
[updateNodeForm, id],
|
[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 };
|
return { handleValuesChange };
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -8,7 +8,7 @@ import { removeUselessFieldsFromValues } from '@/utils/form';
|
|||||||
import { Edge, Node, Position, XYPosition } from '@xyflow/react';
|
import { Edge, Node, Position, XYPosition } from '@xyflow/react';
|
||||||
import { FormInstance, FormListFieldData } from 'antd';
|
import { FormInstance, FormListFieldData } from 'antd';
|
||||||
import { humanId } from 'human-id';
|
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 pipe from 'lodash/fp/pipe';
|
||||||
import isObject from 'lodash/isObject';
|
import isObject from 'lodash/isObject';
|
||||||
import { v4 as uuidv4 } from 'uuid';
|
import { v4 as uuidv4 } from 'uuid';
|
||||||
@ -416,3 +416,25 @@ export const buildCategorizeListFromObject = (
|
|||||||
}, [])
|
}, [])
|
||||||
.sort((a, b) => a.index - b.index);
|
.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;
|
||||||
|
}, {});
|
||||||
|
};
|
||||||
|
Loading…
x
Reference in New Issue
Block a user