### What problem does this PR solve? Feat: Fixed the issue where the page would refresh continuously when opening the sheet on the right side of the canvas #3221 ### Type of change - [x] New Feature (non-breaking change which adds functionality)tags/v0.19.x
| const formData = node?.data?.form; | const formData = node?.data?.form; | ||||
| if (isPlainObject(formData)) { | if (isPlainObject(formData)) { | ||||
| // form.setFieldsValue({ ...formData, items }); | // form.setFieldsValue({ ...formData, items }); | ||||
| console.info('xxx'); | |||||
| form.reset({ ...formData, items }); | form.reset({ ...formData, items }); | ||||
| } | } | ||||
| } else { | } else { |
| message_history_window_size: 6, | message_history_window_size: 6, | ||||
| }, | }, | ||||
| schema: z.object({ | schema: z.object({ | ||||
| llm_id: z.string(), | |||||
| message_history_window_size: z.number(), | |||||
| language: z.string(), | |||||
| script: z.string(), | |||||
| arguments: z | |||||
| .array(z.object({ name: z.string(), component_id: z.string() })) | |||||
| .optional(), | |||||
| lang: z.string(), | |||||
| }), | }), | ||||
| }, | }, | ||||
| [Operator.Baidu]: { | [Operator.Baidu]: { |
| import Editor, { loader } from '@monaco-editor/react'; | import Editor, { loader } from '@monaco-editor/react'; | ||||
| import { INextOperatorForm } from '../../interface'; | import { INextOperatorForm } from '../../interface'; | ||||
| import { DynamicInputVariable } from './dynamic-input-variable'; | |||||
| import { | import { | ||||
| Form, | Form, | ||||
| import { RAGFlowSelect } from '@/components/ui/select'; | import { RAGFlowSelect } from '@/components/ui/select'; | ||||
| import { ProgrammingLanguage } from '@/constants/agent'; | import { ProgrammingLanguage } from '@/constants/agent'; | ||||
| import { ICodeForm } from '@/interfaces/database/flow'; | import { ICodeForm } from '@/interfaces/database/flow'; | ||||
| import { useTranslation } from 'react-i18next'; | |||||
| import { DynamicInputVariable } from './next-variable'; | |||||
| loader.config({ paths: { vs: '/vs' } }); | loader.config({ paths: { vs: '/vs' } }); | ||||
| const CodeForm = ({ form, node }: INextOperatorForm) => { | const CodeForm = ({ form, node }: INextOperatorForm) => { | ||||
| const formData = node?.data.form as ICodeForm; | const formData = node?.data.form as ICodeForm; | ||||
| const { t } = useTranslation(); | |||||
| // useEffect(() => { | // useEffect(() => { | ||||
| // setTimeout(() => { | // setTimeout(() => { | ||||
| <FormLabel> | <FormLabel> | ||||
| <FormField | <FormField | ||||
| control={form.control} | control={form.control} | ||||
| name="channel" | |||||
| name="lang" | |||||
| render={({ field }) => ( | render={({ field }) => ( | ||||
| <FormItem> | <FormItem> | ||||
| <FormLabel tooltip={t('channelTip')}> | |||||
| {t('channel')} | |||||
| </FormLabel> | |||||
| <FormControl> | <FormControl> | ||||
| <RAGFlowSelect {...field} options={options} /> | <RAGFlowSelect {...field} options={options} /> | ||||
| </FormControl> | </FormControl> |
| 'use client'; | |||||
| import { SideDown } from '@/assets/icon/Icon'; | |||||
| import { Button } from '@/components/ui/button'; | |||||
| import { | |||||
| Collapsible, | |||||
| CollapsibleContent, | |||||
| CollapsibleTrigger, | |||||
| } from '@/components/ui/collapsible'; | |||||
| import { | |||||
| FormControl, | |||||
| FormDescription, | |||||
| FormField, | |||||
| FormItem, | |||||
| FormMessage, | |||||
| } from '@/components/ui/form'; | |||||
| import { Input } from '@/components/ui/input'; | |||||
| import { RAGFlowSelect } from '@/components/ui/select'; | |||||
| import { RAGFlowNodeType } from '@/interfaces/database/flow'; | |||||
| import { Plus, Trash2 } from 'lucide-react'; | |||||
| import { useFieldArray, useFormContext } from 'react-hook-form'; | |||||
| import { useTranslation } from 'react-i18next'; | |||||
| import { useBuildComponentIdSelectOptions } from '../../hooks/use-get-begin-query'; | |||||
| interface IProps { | |||||
| node?: RAGFlowNodeType; | |||||
| name?: string; | |||||
| } | |||||
| export function DynamicVariableForm({ node, name = 'arguments' }: IProps) { | |||||
| const { t } = useTranslation(); | |||||
| const form = useFormContext(); | |||||
| const { fields, remove, append } = useFieldArray({ | |||||
| name: name, | |||||
| control: form.control, | |||||
| }); | |||||
| const valueOptions = useBuildComponentIdSelectOptions( | |||||
| node?.id, | |||||
| node?.parentId, | |||||
| ); | |||||
| return ( | |||||
| <div> | |||||
| {fields.map((field, index) => { | |||||
| const typeField = `${name}.${index}.name`; | |||||
| return ( | |||||
| <div key={field.id} className="flex items-center gap-1"> | |||||
| <FormField | |||||
| control={form.control} | |||||
| name={typeField} | |||||
| render={({ field }) => ( | |||||
| <FormItem className="w-2/5"> | |||||
| <FormDescription /> | |||||
| <FormControl> | |||||
| <Input placeholder={t('common.pleaseInput')} {...field} /> | |||||
| </FormControl> | |||||
| <FormMessage /> | |||||
| </FormItem> | |||||
| )} | |||||
| /> | |||||
| <FormField | |||||
| control={form.control} | |||||
| name={`${name}.${index}.component_id`} | |||||
| render={({ field }) => ( | |||||
| <FormItem className="flex-1"> | |||||
| <FormDescription /> | |||||
| <FormControl> | |||||
| <RAGFlowSelect | |||||
| placeholder={t('common.pleaseSelect')} | |||||
| options={valueOptions} | |||||
| {...field} | |||||
| ></RAGFlowSelect> | |||||
| </FormControl> | |||||
| <FormMessage /> | |||||
| </FormItem> | |||||
| )} | |||||
| /> | |||||
| <Trash2 | |||||
| className="cursor-pointer mx-3 size-4 text-colors-text-functional-danger" | |||||
| onClick={() => remove(index)} | |||||
| /> | |||||
| </div> | |||||
| ); | |||||
| })} | |||||
| <Button onClick={append} className="mt-4" variant={'outline'} size={'sm'}> | |||||
| <Plus /> | |||||
| {t('flow.addVariable')} | |||||
| </Button> | |||||
| </div> | |||||
| ); | |||||
| } | |||||
| export function DynamicInputVariable({ node }: IProps) { | |||||
| const { t } = useTranslation(); | |||||
| return ( | |||||
| <Collapsible defaultOpen className="group/collapsible"> | |||||
| <CollapsibleTrigger className="flex justify-between w-full pb-2"> | |||||
| <span className="font-bold text-2xl text-colors-text-neutral-strong"> | |||||
| {t('flow.input')} | |||||
| </span> | |||||
| <Button variant={'icon'} size={'icon'}> | |||||
| <SideDown /> | |||||
| </Button> | |||||
| </CollapsibleTrigger> | |||||
| <CollapsibleContent> | |||||
| <DynamicVariableForm node={node}></DynamicVariableForm> | |||||
| </CollapsibleContent> | |||||
| </Collapsible> | |||||
| ); | |||||
| } |
| category_description: buildCategorizeObjectFromList(value.items), | category_description: buildCategorizeObjectFromList(value.items), | ||||
| }; | }; | ||||
| } | } | ||||
| updateNodeForm(id, nextValues); | |||||
| if (type) { | |||||
| // Manually triggered form updates are synchronized to the canvas | |||||
| updateNodeForm(id, nextValues); | |||||
| } | |||||
| } | } | ||||
| }); | }); | ||||
| return () => subscription?.unsubscribe(); | return () => subscription?.unsubscribe(); |