mirror of
https://git.mirrors.martin98.com/https://github.com/infiniflow/ragflow.git
synced 2025-08-14 03:35:52 +08:00
Feat: Fixed the issue where the prompt always displayed the initial value when switching between different generate operators #4764 (#4808)
### What problem does this PR solve? Feat: Fixed the issue where the prompt always displayed the initial value when switching between different generate operators #4764 ### Type of change - [x] New Feature (non-breaking change which adds functionality)
This commit is contained in:
parent
bfcc2abe47
commit
a357190eff
1
web/src/components/prompt-editor/constant.ts
Normal file
1
web/src/components/prompt-editor/constant.ts
Normal file
@ -0,0 +1 @@
|
|||||||
|
export const ProgrammaticTag = 'programmatic';
|
@ -1,13 +1,10 @@
|
|||||||
import { CodeHighlightNode, CodeNode } from '@lexical/code';
|
import { CodeHighlightNode, CodeNode } from '@lexical/code';
|
||||||
import { AutoFocusPlugin } from '@lexical/react/LexicalAutoFocusPlugin';
|
|
||||||
import {
|
import {
|
||||||
InitialConfigType,
|
InitialConfigType,
|
||||||
LexicalComposer,
|
LexicalComposer,
|
||||||
} from '@lexical/react/LexicalComposer';
|
} from '@lexical/react/LexicalComposer';
|
||||||
import { ContentEditable } from '@lexical/react/LexicalContentEditable';
|
import { ContentEditable } from '@lexical/react/LexicalContentEditable';
|
||||||
import { LexicalErrorBoundary } from '@lexical/react/LexicalErrorBoundary';
|
import { LexicalErrorBoundary } from '@lexical/react/LexicalErrorBoundary';
|
||||||
import { HistoryPlugin } from '@lexical/react/LexicalHistoryPlugin';
|
|
||||||
import { OnChangePlugin } from '@lexical/react/LexicalOnChangePlugin';
|
|
||||||
import { RichTextPlugin } from '@lexical/react/LexicalRichTextPlugin';
|
import { RichTextPlugin } from '@lexical/react/LexicalRichTextPlugin';
|
||||||
import { HeadingNode, QuoteNode } from '@lexical/rich-text';
|
import { HeadingNode, QuoteNode } from '@lexical/rich-text';
|
||||||
import {
|
import {
|
||||||
@ -18,9 +15,11 @@ import {
|
|||||||
LexicalNode,
|
LexicalNode,
|
||||||
} from 'lexical';
|
} from 'lexical';
|
||||||
|
|
||||||
|
import { useCallback } from 'react';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
import theme from './theme';
|
import theme from './theme';
|
||||||
import { VariableNode } from './variable-node';
|
import { VariableNode } from './variable-node';
|
||||||
|
import { VariableOnChangePlugin } from './variable-on-change-plugin';
|
||||||
import VariablePickerMenuPlugin from './variable-picker-plugin';
|
import VariablePickerMenuPlugin from './variable-picker-plugin';
|
||||||
|
|
||||||
// Catch any errors that occur during Lexical updates and log them
|
// Catch any errors that occur during Lexical updates and log them
|
||||||
@ -52,16 +51,20 @@ export function PromptEditor({ value, onChange }: IProps) {
|
|||||||
nodes: Nodes,
|
nodes: Nodes,
|
||||||
};
|
};
|
||||||
|
|
||||||
function onValueChange(editorState: EditorState) {
|
const onValueChange = useCallback(
|
||||||
editorState?.read(() => {
|
(editorState: EditorState) => {
|
||||||
const listNodes = $nodesOfType(VariableNode); // to be removed
|
editorState?.read(() => {
|
||||||
// const allNodes = $dfs();
|
const listNodes = $nodesOfType(VariableNode); // to be removed
|
||||||
console.log('🚀 ~ onChange ~ allNodes:', listNodes);
|
// const allNodes = $dfs();
|
||||||
|
console.log('🚀 ~ onChange ~ allNodes:', listNodes);
|
||||||
|
|
||||||
const text = $getRoot().getTextContent();
|
const text = $getRoot().getTextContent();
|
||||||
onChange?.(text);
|
|
||||||
});
|
onChange?.(text);
|
||||||
}
|
});
|
||||||
|
},
|
||||||
|
[onChange],
|
||||||
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<LexicalComposer initialConfig={initialConfig}>
|
<LexicalComposer initialConfig={initialConfig}>
|
||||||
@ -74,10 +77,8 @@ export function PromptEditor({ value, onChange }: IProps) {
|
|||||||
}
|
}
|
||||||
ErrorBoundary={LexicalErrorBoundary}
|
ErrorBoundary={LexicalErrorBoundary}
|
||||||
/>
|
/>
|
||||||
<HistoryPlugin />
|
|
||||||
<AutoFocusPlugin />
|
|
||||||
<VariablePickerMenuPlugin value={value}></VariablePickerMenuPlugin>
|
<VariablePickerMenuPlugin value={value}></VariablePickerMenuPlugin>
|
||||||
<OnChangePlugin onChange={onValueChange}></OnChangePlugin>
|
<VariableOnChangePlugin onChange={onValueChange}></VariableOnChangePlugin>
|
||||||
</LexicalComposer>
|
</LexicalComposer>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,35 @@
|
|||||||
|
import { useLexicalComposerContext } from '@lexical/react/LexicalComposerContext';
|
||||||
|
import { EditorState, LexicalEditor } from 'lexical';
|
||||||
|
import { useEffect } from 'react';
|
||||||
|
import { ProgrammaticTag } from './constant';
|
||||||
|
|
||||||
|
interface IProps {
|
||||||
|
onChange: (
|
||||||
|
editorState: EditorState,
|
||||||
|
editor?: LexicalEditor,
|
||||||
|
tags?: Set<string>,
|
||||||
|
) => void;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function VariableOnChangePlugin({ onChange }: IProps) {
|
||||||
|
// Access the editor through the LexicalComposerContext
|
||||||
|
const [editor] = useLexicalComposerContext();
|
||||||
|
// Wrap our listener in useEffect to handle the teardown and avoid stale references.
|
||||||
|
useEffect(() => {
|
||||||
|
// most listeners return a teardown function that can be called to clean them up.
|
||||||
|
return editor.registerUpdateListener(
|
||||||
|
({ editorState, tags, dirtyElements }) => {
|
||||||
|
// Check if there is a "programmatic" tag
|
||||||
|
const isProgrammaticUpdate = tags.has(ProgrammaticTag);
|
||||||
|
|
||||||
|
// The onchange event is only triggered when the data is manually updated
|
||||||
|
// Otherwise, the content will be displayed incorrectly.
|
||||||
|
if (dirtyElements.size > 0 && !isProgrammaticUpdate) {
|
||||||
|
onChange(editorState);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}, [editor, onChange]);
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
@ -33,6 +33,7 @@ import { FlowFormContext } from '@/pages/flow/context';
|
|||||||
import { useBuildComponentIdSelectOptions } from '@/pages/flow/hooks/use-get-begin-query';
|
import { useBuildComponentIdSelectOptions } from '@/pages/flow/hooks/use-get-begin-query';
|
||||||
import { $createVariableNode } from './variable-node';
|
import { $createVariableNode } from './variable-node';
|
||||||
|
|
||||||
|
import { ProgrammaticTag } from './constant';
|
||||||
import './index.css';
|
import './index.css';
|
||||||
class VariableInnerOption extends MenuOption {
|
class VariableInnerOption extends MenuOption {
|
||||||
label: string;
|
label: string;
|
||||||
@ -215,9 +216,12 @@ export default function VariablePickerMenuPlugin({
|
|||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (editor && value && isFirstRender.current) {
|
if (editor && value && isFirstRender.current) {
|
||||||
isFirstRender.current = false;
|
isFirstRender.current = false;
|
||||||
editor.update(() => {
|
editor.update(
|
||||||
parseTextToVariableNodes(value);
|
() => {
|
||||||
});
|
parseTextToVariableNodes(value);
|
||||||
|
},
|
||||||
|
{ tag: ProgrammaticTag },
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}, [parseTextToVariableNodes, editor, value]);
|
}, [parseTextToVariableNodes, editor, value]);
|
||||||
|
|
||||||
|
@ -3,6 +3,7 @@ import { DSL, IFlow, IFlowTemplate } from '@/interfaces/database/flow';
|
|||||||
import { IDebugSingleRequestBody } from '@/interfaces/request/flow';
|
import { IDebugSingleRequestBody } from '@/interfaces/request/flow';
|
||||||
import i18n from '@/locales/config';
|
import i18n from '@/locales/config';
|
||||||
import { useGetSharedChatSearchParams } from '@/pages/chat/shared-hooks';
|
import { useGetSharedChatSearchParams } from '@/pages/chat/shared-hooks';
|
||||||
|
import { BeginId } from '@/pages/flow/constant';
|
||||||
import flowService from '@/services/flow-service';
|
import flowService from '@/services/flow-service';
|
||||||
import { buildMessageListWithUuid } from '@/utils/chat';
|
import { buildMessageListWithUuid } from '@/utils/chat';
|
||||||
import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query';
|
import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query';
|
||||||
@ -16,7 +17,7 @@ export const EmptyDsl = {
|
|||||||
graph: {
|
graph: {
|
||||||
nodes: [
|
nodes: [
|
||||||
{
|
{
|
||||||
id: 'begin',
|
id: BeginId,
|
||||||
type: 'beginNode',
|
type: 'beginNode',
|
||||||
position: {
|
position: {
|
||||||
x: 50,
|
x: 50,
|
||||||
|
@ -35,6 +35,7 @@ const GenerateForm = ({ onValuesChange, form }: IOperatorForm) => {
|
|||||||
},
|
},
|
||||||
]}
|
]}
|
||||||
>
|
>
|
||||||
|
{/* <Input.TextArea rows={8}></Input.TextArea> */}
|
||||||
<PromptEditor></PromptEditor>
|
<PromptEditor></PromptEditor>
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
<Form.Item
|
<Form.Item
|
||||||
|
@ -73,7 +73,7 @@ export const useWatchAgentChange = (chatDrawerVisible: boolean) => {
|
|||||||
|
|
||||||
useDebounceEffect(
|
useDebounceEffect(
|
||||||
() => {
|
() => {
|
||||||
saveAgent();
|
// saveAgent();
|
||||||
},
|
},
|
||||||
[nodes, edges],
|
[nodes, edges],
|
||||||
{
|
{
|
||||||
|
Loading…
x
Reference in New Issue
Block a user