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:
balibabu 2025-02-08 18:25:25 +08:00 committed by GitHub
parent bfcc2abe47
commit a357190eff
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
7 changed files with 63 additions and 20 deletions

View File

@ -0,0 +1 @@
export const ProgrammaticTag = 'programmatic';

View File

@ -1,13 +1,10 @@
import { CodeHighlightNode, CodeNode } from '@lexical/code';
import { AutoFocusPlugin } from '@lexical/react/LexicalAutoFocusPlugin';
import {
InitialConfigType,
LexicalComposer,
} from '@lexical/react/LexicalComposer';
import { ContentEditable } from '@lexical/react/LexicalContentEditable';
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 { HeadingNode, QuoteNode } from '@lexical/rich-text';
import {
@ -18,9 +15,11 @@ import {
LexicalNode,
} from 'lexical';
import { useCallback } from 'react';
import { useTranslation } from 'react-i18next';
import theme from './theme';
import { VariableNode } from './variable-node';
import { VariableOnChangePlugin } from './variable-on-change-plugin';
import VariablePickerMenuPlugin from './variable-picker-plugin';
// Catch any errors that occur during Lexical updates and log them
@ -52,16 +51,20 @@ export function PromptEditor({ value, onChange }: IProps) {
nodes: Nodes,
};
function onValueChange(editorState: EditorState) {
editorState?.read(() => {
const listNodes = $nodesOfType(VariableNode); // to be removed
// const allNodes = $dfs();
console.log('🚀 ~ onChange ~ allNodes:', listNodes);
const onValueChange = useCallback(
(editorState: EditorState) => {
editorState?.read(() => {
const listNodes = $nodesOfType(VariableNode); // to be removed
// const allNodes = $dfs();
console.log('🚀 ~ onChange ~ allNodes:', listNodes);
const text = $getRoot().getTextContent();
onChange?.(text);
});
}
const text = $getRoot().getTextContent();
onChange?.(text);
});
},
[onChange],
);
return (
<LexicalComposer initialConfig={initialConfig}>
@ -74,10 +77,8 @@ export function PromptEditor({ value, onChange }: IProps) {
}
ErrorBoundary={LexicalErrorBoundary}
/>
<HistoryPlugin />
<AutoFocusPlugin />
<VariablePickerMenuPlugin value={value}></VariablePickerMenuPlugin>
<OnChangePlugin onChange={onValueChange}></OnChangePlugin>
<VariableOnChangePlugin onChange={onValueChange}></VariableOnChangePlugin>
</LexicalComposer>
);
}

View File

@ -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;
}

View File

@ -33,6 +33,7 @@ import { FlowFormContext } from '@/pages/flow/context';
import { useBuildComponentIdSelectOptions } from '@/pages/flow/hooks/use-get-begin-query';
import { $createVariableNode } from './variable-node';
import { ProgrammaticTag } from './constant';
import './index.css';
class VariableInnerOption extends MenuOption {
label: string;
@ -215,9 +216,12 @@ export default function VariablePickerMenuPlugin({
useEffect(() => {
if (editor && value && isFirstRender.current) {
isFirstRender.current = false;
editor.update(() => {
parseTextToVariableNodes(value);
});
editor.update(
() => {
parseTextToVariableNodes(value);
},
{ tag: ProgrammaticTag },
);
}
}, [parseTextToVariableNodes, editor, value]);

View File

@ -3,6 +3,7 @@ import { DSL, IFlow, IFlowTemplate } from '@/interfaces/database/flow';
import { IDebugSingleRequestBody } from '@/interfaces/request/flow';
import i18n from '@/locales/config';
import { useGetSharedChatSearchParams } from '@/pages/chat/shared-hooks';
import { BeginId } from '@/pages/flow/constant';
import flowService from '@/services/flow-service';
import { buildMessageListWithUuid } from '@/utils/chat';
import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query';
@ -16,7 +17,7 @@ export const EmptyDsl = {
graph: {
nodes: [
{
id: 'begin',
id: BeginId,
type: 'beginNode',
position: {
x: 50,

View File

@ -35,6 +35,7 @@ const GenerateForm = ({ onValuesChange, form }: IOperatorForm) => {
},
]}
>
{/* <Input.TextArea rows={8}></Input.TextArea> */}
<PromptEditor></PromptEditor>
</Form.Item>
<Form.Item

View File

@ -73,7 +73,7 @@ export const useWatchAgentChange = (chatDrawerVisible: boolean) => {
useDebounceEffect(
() => {
saveAgent();
// saveAgent();
},
[nodes, edges],
{