mirror of
https://github.com/infiniflow/ragflow.git
synced 2025-12-22 06:06:40 +08:00
Feat: Fixed the issue where the cursor would go to the end when changing its own data #9869 (#10316)
### What problem does this PR solve? Feat: Fixed the issue where the cursor would go to the end when changing its own data #9869 ### Type of change - [x] New Feature (non-breaking change which adds functionality)
This commit is contained in:
@ -1,3 +1,4 @@
|
||||
import { ConfirmDeleteDialog } from '@/components/confirm-delete-dialog';
|
||||
import { LargeModelFormField } from '@/components/large-model-form-field';
|
||||
import { LlmSettingSchema } from '@/components/llm-setting-items/next';
|
||||
import { SelectWithSearch } from '@/components/originui/select-with-search';
|
||||
@ -6,7 +7,7 @@ import { Form } from '@/components/ui/form';
|
||||
import { PromptEditor } from '@/pages/agent/form/components/prompt-editor';
|
||||
import { buildOptions } from '@/utils/form';
|
||||
import { zodResolver } from '@hookform/resolvers/zod';
|
||||
import { memo, useCallback } from 'react';
|
||||
import { memo } from 'react';
|
||||
import { useForm } from 'react-hook-form';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { z } from 'zod';
|
||||
@ -19,6 +20,7 @@ import { useFormValues } from '../../hooks/use-form-values';
|
||||
import { useWatchFormChange } from '../../hooks/use-watch-form-change';
|
||||
import { INextOperatorForm } from '../../interface';
|
||||
import { FormWrapper } from '../components/form-wrapper';
|
||||
import { useSwitchPrompt } from './use-switch-prompt';
|
||||
|
||||
export const FormSchema = z.object({
|
||||
field_name: z.string(),
|
||||
@ -43,25 +45,13 @@ const ExtractorForm = ({ node }: INextOperatorForm) => {
|
||||
|
||||
const options = buildOptions(ContextGeneratorFieldName, t, 'dataflow');
|
||||
|
||||
const setPromptValue = useCallback(
|
||||
(field: keyof ExtractorFormSchemaType, key: string, value: string) => {
|
||||
form.setValue(field, t(`dataflow.prompts.${key}.${value}`), {
|
||||
shouldDirty: true,
|
||||
shouldValidate: true,
|
||||
});
|
||||
},
|
||||
[form, t],
|
||||
);
|
||||
|
||||
const handleFieldNameChange = useCallback(
|
||||
(value: string) => {
|
||||
if (value) {
|
||||
setPromptValue('sys_prompt', 'system', value);
|
||||
setPromptValue('prompts', 'user', value);
|
||||
}
|
||||
},
|
||||
[setPromptValue],
|
||||
);
|
||||
const {
|
||||
handleFieldNameChange,
|
||||
confirmSwitch,
|
||||
hideModal,
|
||||
visible,
|
||||
cancelSwitch,
|
||||
} = useSwitchPrompt(form);
|
||||
|
||||
useWatchFormChange(node?.id, form);
|
||||
|
||||
@ -96,6 +86,15 @@ const ExtractorForm = ({ node }: INextOperatorForm) => {
|
||||
></PromptEditor>
|
||||
</RAGFlowFormItem>
|
||||
</FormWrapper>
|
||||
{visible && (
|
||||
<ConfirmDeleteDialog
|
||||
title={t('dataflow.switchPromptMessage')}
|
||||
open
|
||||
onOpenChange={hideModal}
|
||||
onOk={confirmSwitch}
|
||||
onCancel={cancelSwitch}
|
||||
></ConfirmDeleteDialog>
|
||||
)}
|
||||
</Form>
|
||||
);
|
||||
};
|
||||
|
||||
@ -0,0 +1,69 @@
|
||||
import { LlmSettingSchema } from '@/components/llm-setting-items/next';
|
||||
import { useSetModalState } from '@/hooks/common-hooks';
|
||||
import { useCallback, useRef } from 'react';
|
||||
import { UseFormReturn } from 'react-hook-form';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { z } from 'zod';
|
||||
|
||||
export const FormSchema = z.object({
|
||||
field_name: z.string(),
|
||||
sys_prompt: z.string(),
|
||||
prompts: z.string().optional(),
|
||||
...LlmSettingSchema,
|
||||
});
|
||||
|
||||
export type ExtractorFormSchemaType = z.infer<typeof FormSchema>;
|
||||
|
||||
export function useSwitchPrompt(form: UseFormReturn<ExtractorFormSchemaType>) {
|
||||
const { visible, showModal, hideModal } = useSetModalState();
|
||||
const { t } = useTranslation();
|
||||
const previousFieldNames = useRef<string[]>([form.getValues('field_name')]);
|
||||
|
||||
const setPromptValue = useCallback(
|
||||
(field: keyof ExtractorFormSchemaType, key: string, value: string) => {
|
||||
form.setValue(field, t(`dataflow.prompts.${key}.${value}`), {
|
||||
shouldDirty: true,
|
||||
shouldValidate: true,
|
||||
});
|
||||
},
|
||||
[form, t],
|
||||
);
|
||||
|
||||
const handleFieldNameChange = useCallback(
|
||||
(value: string) => {
|
||||
if (value) {
|
||||
const names = previousFieldNames.current;
|
||||
if (names.length > 1) {
|
||||
names.shift();
|
||||
}
|
||||
names.push(value);
|
||||
showModal();
|
||||
}
|
||||
},
|
||||
[showModal],
|
||||
);
|
||||
|
||||
const confirmSwitch = useCallback(() => {
|
||||
const value = form.getValues('field_name');
|
||||
setPromptValue('sys_prompt', 'system', value);
|
||||
setPromptValue('prompts', 'user', value);
|
||||
}, [form, setPromptValue]);
|
||||
|
||||
const cancelSwitch = useCallback(() => {
|
||||
const previousValue = previousFieldNames.current.at(-2);
|
||||
if (previousValue) {
|
||||
form.setValue('field_name', previousValue, {
|
||||
shouldDirty: true,
|
||||
shouldValidate: true,
|
||||
});
|
||||
}
|
||||
}, [form]);
|
||||
|
||||
return {
|
||||
handleFieldNameChange,
|
||||
confirmSwitch,
|
||||
hideModal,
|
||||
visible,
|
||||
cancelSwitch,
|
||||
};
|
||||
}
|
||||
@ -4,11 +4,9 @@ import { useCallback } from 'react';
|
||||
export function useCancelCurrentDataflow({
|
||||
messageId,
|
||||
setMessageId,
|
||||
hideLogSheet,
|
||||
}: {
|
||||
messageId: string;
|
||||
setMessageId: (messageId: string) => void;
|
||||
hideLogSheet(): void;
|
||||
}) {
|
||||
const { cancelDataflow } = useCancelDataflow();
|
||||
|
||||
@ -16,9 +14,8 @@ export function useCancelCurrentDataflow({
|
||||
const code = await cancelDataflow(messageId);
|
||||
if (code === 0) {
|
||||
setMessageId('');
|
||||
hideLogSheet();
|
||||
}
|
||||
}, [cancelDataflow, hideLogSheet, messageId, setMessageId]);
|
||||
}, [cancelDataflow, messageId, setMessageId]);
|
||||
|
||||
return { handleCancel };
|
||||
}
|
||||
|
||||
@ -4,10 +4,6 @@ import useGraphStore from '../store';
|
||||
|
||||
export function useWatchFormChange(id?: string, form?: UseFormReturn<any>) {
|
||||
let values = useWatch({ control: form?.control });
|
||||
console.log(
|
||||
'🚀 ~ useWatchFormChange ~ values:',
|
||||
JSON.stringify(values, null, 2),
|
||||
);
|
||||
|
||||
const updateNodeForm = useGraphStore((state) => state.updateNodeForm);
|
||||
|
||||
|
||||
@ -103,7 +103,6 @@ export default function DataFlow() {
|
||||
const { handleCancel } = useCancelCurrentDataflow({
|
||||
messageId,
|
||||
setMessageId,
|
||||
hideLogSheet,
|
||||
});
|
||||
|
||||
const time = useWatchAgentChange(chatDrawerVisible);
|
||||
|
||||
@ -57,16 +57,16 @@ export function LogSheet({
|
||||
</section>
|
||||
{isParsing ? (
|
||||
<Button
|
||||
className="w-full mt-8 bg-state-error/10 text-state-error"
|
||||
className="w-full mt-8 bg-state-error/10 text-state-error hover:bg-state-error hover:text-bg-base"
|
||||
onClick={handleCancel}
|
||||
>
|
||||
<CirclePause /> Cancel
|
||||
<CirclePause /> {t('dataflow.cancel')}
|
||||
</Button>
|
||||
) : (
|
||||
<Button
|
||||
onClick={handleDownloadJson}
|
||||
disabled={isEndOutputEmpty(logs)}
|
||||
className="w-full mt-8"
|
||||
className="w-full mt-8 bg-accent-primary-5 text-text-secondary hover:bg-accent-primary-5 hover:text-accent-primary hover:border-accent-primary hover:border"
|
||||
>
|
||||
<SquareArrowOutUpRight />
|
||||
{t('dataflow.exportJson')}
|
||||
|
||||
Reference in New Issue
Block a user