From fad91b64ab48221ff90abd0ea9e361e0ba6a179f Mon Sep 17 00:00:00 2001 From: zhaoying Date: Wed, 4 Feb 2026 11:52:34 +0800 Subject: [PATCH] fix(web): prompt add disabled --- .../components/Editor/index.tsx | 11 ++++- .../Editor/plugin/EditablePlugin.tsx | 48 +++++++++++++++++++ web/src/views/Prompt/Prompt.tsx | 6 +-- .../Workflow/components/Editor/index.tsx | 2 +- .../Editor/plugin/InitialValuePlugin.tsx | 12 +++-- .../views/Workflow/hooks/useWorkflowGraph.ts | 4 +- 6 files changed, 71 insertions(+), 12 deletions(-) create mode 100644 web/src/views/ApplicationConfig/components/Editor/plugin/EditablePlugin.tsx diff --git a/web/src/views/ApplicationConfig/components/Editor/index.tsx b/web/src/views/ApplicationConfig/components/Editor/index.tsx index 0c5e2a86..bd6c6733 100644 --- a/web/src/views/ApplicationConfig/components/Editor/index.tsx +++ b/web/src/views/ApplicationConfig/components/Editor/index.tsx @@ -9,6 +9,7 @@ import { useLexicalComposerContext } from '@lexical/react/LexicalComposerContext import InitialValuePlugin from './plugin/InitialValuePlugin' import LineBreakPlugin from './plugin/LineBreakPlugin'; import InsertTextPlugin from './plugin/InsertTextPlugin'; +import EditablePlugin from './plugin/EditablePlugin'; export interface EditorRef { insertText: (text: string) => void; @@ -23,6 +24,7 @@ interface LexicalEditorProps { value?: string; onChange?: (value: string) => void; height?: number; + disabled?: boolean; } const theme = { @@ -38,6 +40,7 @@ const EditorContent = forwardRef(({ value, placeholder = "请输入内容...", onChange, + disabled }, ref) => { const [editor] = useLexicalComposerContext(); @@ -92,7 +95,11 @@ const EditorContent = forwardRef(({ } placeholder={ @@ -105,6 +112,7 @@ const EditorContent = forwardRef(({ + ); }); @@ -114,6 +122,7 @@ const Editor = forwardRef((props, ref) => { namespace: 'Editor', theme, nodes: [], + editable: !props.disabled, onError: (error: Error) => { console.error(error); }, diff --git a/web/src/views/ApplicationConfig/components/Editor/plugin/EditablePlugin.tsx b/web/src/views/ApplicationConfig/components/Editor/plugin/EditablePlugin.tsx new file mode 100644 index 00000000..6c237f01 --- /dev/null +++ b/web/src/views/ApplicationConfig/components/Editor/plugin/EditablePlugin.tsx @@ -0,0 +1,48 @@ +/* + * @Author: ZhaoYing + * @Date: 2026-02-04 11:20:49 + * @Last Modified by: ZhaoYing + * @Last Modified time: 2026-02-04 11:20:49 + */ +import { useEffect } from 'react'; +import { useLexicalComposerContext } from '@lexical/react/LexicalComposerContext'; + +/** + * Props for the EditablePlugin component + */ +interface EditablePluginProps { + /** Whether the editor should be disabled (read-only mode) */ + disabled?: boolean; +} + +/** + * EditablePlugin - A Lexical editor plugin that controls the editable state of the editor + * + * This plugin allows you to dynamically toggle between editable and read-only modes. + * When disabled is true, the editor becomes read-only and users cannot modify content. + * When disabled is false or undefined, the editor is fully editable. + * + * @param {EditablePluginProps} props - Component props + * @param {boolean} [props.disabled] - Controls whether the editor is in read-only mode + * @returns {null} This plugin doesn't render any UI elements + * + * @example + * ```tsx + * + * + * + * ``` + */ +export default function EditablePlugin({ disabled }: EditablePluginProps) { + // Get the editor instance from Lexical composer context + const [editor] = useLexicalComposerContext(); + + // Update editor's editable state whenever the disabled prop changes + useEffect(() => { + // Set editor to editable when disabled is false, read-only when disabled is true + editor.setEditable(!disabled); + }, [editor, disabled]); + + // This plugin doesn't render any UI, it only manages editor state + return null; +} diff --git a/web/src/views/Prompt/Prompt.tsx b/web/src/views/Prompt/Prompt.tsx index 90b1c3a6..69a597db 100644 --- a/web/src/views/Prompt/Prompt.tsx +++ b/web/src/views/Prompt/Prompt.tsx @@ -140,7 +140,6 @@ const Prompt: FC<{ editVo: HistoryItem | null; refresh: () => void; }> = ({ edit refresh() } - console.log(values) return ( <>
@@ -199,12 +198,13 @@ const Prompt: FC<{ editVo: HistoryItem | null; refresh: () => void; }> = ({ edit ref={editorRef} placeholder={t('prompt.promptPlaceholder')} className="rb:h-[calc(100vh-260px)]" + disabled={loading} // onChange={(value) => form.setFieldValue('current_prompt', value)} />
- - + +
diff --git a/web/src/views/Workflow/components/Editor/index.tsx b/web/src/views/Workflow/components/Editor/index.tsx index e37c71de..362e1c81 100644 --- a/web/src/views/Workflow/components/Editor/index.tsx +++ b/web/src/views/Workflow/components/Editor/index.tsx @@ -242,7 +242,7 @@ const Editor: FC =({ {enableLineNumbers && } { setCount(count) }} onChange={onChange} /> - + {enableLineNumbers && } diff --git a/web/src/views/Workflow/components/Editor/plugin/InitialValuePlugin.tsx b/web/src/views/Workflow/components/Editor/plugin/InitialValuePlugin.tsx index 22de9592..4021a9ee 100644 --- a/web/src/views/Workflow/components/Editor/plugin/InitialValuePlugin.tsx +++ b/web/src/views/Workflow/components/Editor/plugin/InitialValuePlugin.tsx @@ -8,12 +8,13 @@ import { type Suggestion } from '../plugin/AutocompletePlugin' interface InitialValuePluginProps { value: string; options?: Suggestion[]; - enableJinja2?: boolean; + enableLineNumbers?: boolean; } -const InitialValuePlugin: React.FC = ({ value, options = [], enableJinja2 = false }) => { +const InitialValuePlugin: React.FC = ({ value, options = [], enableLineNumbers = false }) => { const [editor] = useLexicalComposerContext(); const prevValueRef = useRef(''); + const prevEnableLineNumbersRef = useRef(enableLineNumbers); const isUserInputRef = useRef(false); useEffect(() => { @@ -32,7 +33,7 @@ const InitialValuePlugin: React.FC = ({ value, options }, [editor]); useEffect(() => { - if (value !== prevValueRef.current && !isUserInputRef.current) { + if ((value !== prevValueRef.current || enableLineNumbers !== prevEnableLineNumbersRef.current) && !isUserInputRef.current) { queueMicrotask(() => { editor.update(() => { const root = $getRoot(); @@ -40,7 +41,7 @@ const InitialValuePlugin: React.FC = ({ value, options const parts = value.split(/(\{\{[^}]+\}\})/); - if (enableJinja2) { + if (enableLineNumbers) { // Handle newlines properly in Jinja2 mode const lines = value.split('\n'); lines.forEach((line) => { @@ -104,8 +105,9 @@ const InitialValuePlugin: React.FC = ({ value, options } prevValueRef.current = value; + prevEnableLineNumbersRef.current = enableLineNumbers; isUserInputRef.current = false; - }, [value, options, editor, enableJinja2]); + }, [value, options, editor, enableLineNumbers]); return null; }; diff --git a/web/src/views/Workflow/hooks/useWorkflowGraph.ts b/web/src/views/Workflow/hooks/useWorkflowGraph.ts index 4c010de0..48cd6652 100644 --- a/web/src/views/Workflow/hooks/useWorkflowGraph.ts +++ b/web/src/views/Workflow/hooks/useWorkflowGraph.ts @@ -111,7 +111,7 @@ export const useWorkflowGraph = ({ nodeLibraryConfig.config[key].defaultValue = Object.entries(config[key]).map(([name, value]) => ({ name, value })) } else if (type === 'code' && key === 'code' && config[key] && nodeLibraryConfig.config && nodeLibraryConfig.config[key]) { try { - nodeLibraryConfig.config[key].defaultValue = atob(config[key] as string) + nodeLibraryConfig.config[key].defaultValue = decodeURIComponent(atob(config[key] as string)) } catch { nodeLibraryConfig.config[key].defaultValue = config[key] } @@ -851,7 +851,7 @@ export const useWorkflowGraph = ({ const code = data.config[key].defaultValue || '' itemConfig = { ...itemConfig, - code: btoa(code || '') + code: btoa(encodeURIComponent(code || '')) } } else if (key === 'memory' && data.config[key] && 'defaultValue' in data.config[key]) { const { messages, ...rest } = data.config[key].defaultValue