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 { 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>
); );
} }

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 { 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]);

View File

@ -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,

View File

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

View File

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