diff --git a/web/app/components/app/configuration/config-prompt/simple-prompt-input.tsx b/web/app/components/app/configuration/config-prompt/simple-prompt-input.tsx index 5bc923e040..c92a43515f 100644 --- a/web/app/components/app/configuration/config-prompt/simple-prompt-input.tsx +++ b/web/app/components/app/configuration/config-prompt/simple-prompt-input.tsx @@ -166,6 +166,7 @@ const Prompt: FC = ({ > = ({ instanceId, + compact, className, placeholder, placeholderClassName, @@ -101,6 +107,7 @@ const PromptEditor: FC = ({ namespace: 'prompt-editor', nodes: [ CodeNode, + CodeHighlightNode, CustomTextNode, { replace: TextNode, @@ -141,8 +148,8 @@ const PromptEditor: FC = ({
} - placeholder={} + contentEditable={} + placeholder={} ErrorBoundary={LexicalErrorBoundary} /> = ({ + {/* */}
diff --git a/web/app/components/base/prompt-editor/plugins/code-highlight-block.tsx b/web/app/components/base/prompt-editor/plugins/code-highlight-block.tsx new file mode 100644 index 0000000000..2c584e70c3 --- /dev/null +++ b/web/app/components/base/prompt-editor/plugins/code-highlight-block.tsx @@ -0,0 +1,13 @@ +import { useEffect } from 'react' +import { registerCodeHighlighting } from '@lexical/code' +import { useLexicalComposerContext } from '@lexical/react/LexicalComposerContext' + +export default function CodeHighlightPlugin() { + const [editor] = useLexicalComposerContext() + + useEffect(() => { + return registerCodeHighlighting(editor) + }, [editor]) + + return null +} diff --git a/web/app/components/base/prompt-editor/plugins/component-picker-block/hooks.tsx b/web/app/components/base/prompt-editor/plugins/component-picker-block/hooks.tsx index 0b1cc3ce7b..bb21a46366 100644 --- a/web/app/components/base/prompt-editor/plugins/component-picker-block/hooks.tsx +++ b/web/app/components/base/prompt-editor/plugins/component-picker-block/hooks.tsx @@ -195,7 +195,7 @@ export const useOptions = ( variableOptions, externalToolOptions, workflowVariableOptions, - allOptions: [...promptOptions, ...variableOptions, ...externalToolOptions, ...workflowVariableOptions], + allOptions: [...promptOptions, ...variableOptions, ...externalToolOptions], } }, [promptOptions, variableOptions, externalToolOptions, workflowVariableOptions]) } diff --git a/web/app/components/base/prompt-editor/plugins/component-picker-block/index.tsx b/web/app/components/base/prompt-editor/plugins/component-picker-block/index.tsx index 6ecae1d07c..befef7ff09 100644 --- a/web/app/components/base/prompt-editor/plugins/component-picker-block/index.tsx +++ b/web/app/components/base/prompt-editor/plugins/component-picker-block/index.tsx @@ -82,11 +82,12 @@ const ComponentPicker = ({ matchingString: string, ) => { editor.update(() => { - if (nodeToRemove) + if (nodeToRemove && selectedOption?.key) nodeToRemove.remove() if (selectedOption?.onSelect) selectedOption.onSelect(matchingString) + closeMenu() }) }, @@ -104,9 +105,9 @@ const ComponentPicker = ({ anchorElementRef, { selectedIndex, selectOptionAndCleanUp, setHighlightedIndex }, ) => { - if (anchorElementRef.current && allOptions.length) { + if (anchorElementRef.current && (allOptions.length || workflowVariableOptions.length)) { return ReactDOM.createPortal( -
+
{ !!promptOptions.length && ( <> @@ -196,8 +197,7 @@ const ComponentPicker = ({ { - selectOptionAndCleanUp(item) + onChange={(variables: string[]) => { handleSelectWorkflowVariable(variables) }} /> diff --git a/web/app/components/base/prompt-editor/plugins/placeholder.tsx b/web/app/components/base/prompt-editor/plugins/placeholder.tsx index 83bf069883..b9db0617bf 100644 --- a/web/app/components/base/prompt-editor/plugins/placeholder.tsx +++ b/web/app/components/base/prompt-editor/plugins/placeholder.tsx @@ -1,20 +1,27 @@ +import { memo } from 'react' import { useTranslation } from 'react-i18next' import cn from 'classnames' const Placeholder = ({ + compact, value, className, }: { + compact?: boolean value?: string className?: string }) => { const { t } = useTranslation() return ( -
+
{value || t('common.promptEditor.placeholder')}
) } -export default Placeholder +export default memo(Placeholder) diff --git a/web/app/components/base/prompt-editor/plugins/update-block.tsx b/web/app/components/base/prompt-editor/plugins/update-block.tsx index b629537ed9..3d349ee69d 100644 --- a/web/app/components/base/prompt-editor/plugins/update-block.tsx +++ b/web/app/components/base/prompt-editor/plugins/update-block.tsx @@ -1,8 +1,11 @@ +import { $insertNodes } from 'lexical' import { useLexicalComposerContext } from '@lexical/react/LexicalComposerContext' import { textToEditorState } from '../utils' +import { CustomTextNode } from './custom-text/node' import { useEventEmitterContextContext } from '@/context/event-emitter' export const PROMPT_EDITOR_UPDATE_VALUE_BY_EVENT_EMITTER = 'PROMPT_EDITOR_UPDATE_VALUE_BY_EVENT_EMITTER' +export const PROMPT_EDITOR_INSERT_QUICKLY = 'PROMPT_EDITOR_INSERT_QUICKLY' type UpdateBlockProps = { instanceId?: string @@ -20,6 +23,16 @@ const UpdateBlock = ({ } }) + eventEmitter?.useSubscription((v: any) => { + if (v.type === PROMPT_EDITOR_INSERT_QUICKLY && v.instanceId === instanceId) { + editor.focus() + editor.update(() => { + const textNode = new CustomTextNode('/') + $insertNodes([textNode]) + }) + } + }) + return null } diff --git a/web/app/components/base/prompt-editor/plugins/workflow-variable-block/component.tsx b/web/app/components/base/prompt-editor/plugins/workflow-variable-block/component.tsx index 78d14b6711..39a46611e6 100644 --- a/web/app/components/base/prompt-editor/plugins/workflow-variable-block/component.tsx +++ b/web/app/components/base/prompt-editor/plugins/workflow-variable-block/component.tsx @@ -27,7 +27,7 @@ const WorkflowVariableBlockComponent: FC = return (
{ - const contextBlockNode = $createWorkflowVariableBlockNode(variables, getWorkflowNode) + const workflowVariableBlockNode = $createWorkflowVariableBlockNode(variables, getWorkflowNode) + const prevNodeKey = ($getPreviousSelection() as any)?.anchor?.key - $insertNodes([contextBlockNode]) + if (prevNodeKey) { + const prevNode = $getNodeByKey(prevNodeKey) + + prevNode?.remove() + } + + $insertNodes([workflowVariableBlockNode]) if (onInsert) onInsert() diff --git a/web/app/components/workflow/nodes/_base/components/prompt/editor.tsx b/web/app/components/workflow/nodes/_base/components/prompt/editor.tsx index e5e10f724b..70f8f6d62e 100644 --- a/web/app/components/workflow/nodes/_base/components/prompt/editor.tsx +++ b/web/app/components/workflow/nodes/_base/components/prompt/editor.tsx @@ -15,8 +15,11 @@ import { Clipboard, ClipboardCheck } from '@/app/components/base/icons/src/vende import s from '@/app/components/app/configuration/config-prompt/style.module.css' import { Trash03 } from '@/app/components/base/icons/src/vender/line/general' import TooltipPlus from '@/app/components/base/tooltip-plus' +import { useEventEmitterContextContext } from '@/context/event-emitter' +import { PROMPT_EDITOR_INSERT_QUICKLY } from '@/app/components/base/prompt-editor/plugins/update-block' type Props = { + instanceId?: string title: string | JSX.Element value: string onChange: (value: string) => void @@ -36,6 +39,7 @@ type Props = { } const Editor: FC = ({ + instanceId, title, value, onChange, @@ -51,6 +55,7 @@ const Editor: FC = ({ }) => { const { t } = useTranslation() const { getNode } = useWorkflow() + const { eventEmitter } = useEventEmitterContextContext() const isShowHistory = !isChatModel && isChatApp const isShowQuery = isShowHistory @@ -75,6 +80,11 @@ const Editor: FC = ({ setFalse: setBlur, }] = useBoolean(false) + const handleInsertVariable = () => { + setFocus() + eventEmitter?.emit({ type: PROMPT_EDITOR_INSERT_QUICKLY, instanceId } as any) + } + return (
@@ -114,7 +124,10 @@ const Editor: FC = ({ -
{'{x} '}{t('workflow.nodes.common.insertVarTip')}
+
{'{x} '}{t('workflow.nodes.common.insertVarTip')}
) :
}
@@ -123,7 +136,9 @@ const Editor: FC = ({ > <> = ({ (payload as PromptItem[]).map((item, index) => { return ( @@ -160,6 +161,7 @@ const ConfigPrompt: FC = ({ : (
{t(`${i18nPrefix}.prompt`)}} value={(payload as PromptItem).text} onChange={handleCompletionPromptChange}