| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227 | 'use client'import type { FC } from 'react'import { useEffect } from 'react'import type {  EditorState,} from 'lexical'import {  $getRoot,  TextNode,} from 'lexical'import { CodeNode } from '@lexical/code'import { LexicalComposer } from '@lexical/react/LexicalComposer'import { RichTextPlugin } from '@lexical/react/LexicalRichTextPlugin'import { ContentEditable } from '@lexical/react/LexicalContentEditable'import LexicalErrorBoundary from '@lexical/react/LexicalErrorBoundary'import { OnChangePlugin } from '@lexical/react/LexicalOnChangePlugin'import { HistoryPlugin } from '@lexical/react/LexicalHistoryPlugin'// import TreeView from './plugins/tree-view'import Placeholder from './plugins/placeholder'import ComponentPickerBlock from './plugins/component-picker-block'import {  ContextBlock,  ContextBlockNode,  ContextBlockReplacementBlock,} from './plugins/context-block'import {  QueryBlock,  QueryBlockNode,  QueryBlockReplacementBlock,} from './plugins/query-block'import {  HistoryBlock,  HistoryBlockNode,  HistoryBlockReplacementBlock,} from './plugins/history-block'import {  WorkflowVariableBlock,  WorkflowVariableBlockNode,  WorkflowVariableBlockReplacementBlock,} from './plugins/workflow-variable-block'import VariableBlock from './plugins/variable-block'import VariableValueBlock from './plugins/variable-value-block'import { VariableValueBlockNode } from './plugins/variable-value-block/node'import { CustomTextNode } from './plugins/custom-text/node'import OnBlurBlock from './plugins/on-blur-or-focus-block'import UpdateBlock from './plugins/update-block'import { textToEditorState } from './utils'import type {  ContextBlockType,  ExternalToolBlockType,  HistoryBlockType,  QueryBlockType,  VariableBlockType,  WorkflowVariableBlockType,} from './types'import {  UPDATE_DATASETS_EVENT_EMITTER,  UPDATE_HISTORY_EVENT_EMITTER,} from './constants'import { useEventEmitterContextContext } from '@/context/event-emitter'import cn from '@/utils/classnames'export type PromptEditorProps = {  instanceId?: string  compact?: boolean  className?: string  placeholder?: string  placeholderClassName?: string  style?: React.CSSProperties  value?: string  editable?: boolean  onChange?: (text: string) => void  onBlur?: () => void  onFocus?: () => void  contextBlock?: ContextBlockType  queryBlock?: QueryBlockType  historyBlock?: HistoryBlockType  variableBlock?: VariableBlockType  externalToolBlock?: ExternalToolBlockType  workflowVariableBlock?: WorkflowVariableBlockType  isSupportFileVar?: boolean}const PromptEditor: FC<PromptEditorProps> = ({  instanceId,  compact,  className,  placeholder,  placeholderClassName,  style,  value,  editable = true,  onChange,  onBlur,  onFocus,  contextBlock,  queryBlock,  historyBlock,  variableBlock,  externalToolBlock,  workflowVariableBlock,  isSupportFileVar,}) => {  const { eventEmitter } = useEventEmitterContextContext()  const initialConfig = {    namespace: 'prompt-editor',    nodes: [      CodeNode,      CustomTextNode,      {        replace: TextNode,        with: (node: TextNode) => new CustomTextNode(node.__text),      },      ContextBlockNode,      HistoryBlockNode,      QueryBlockNode,      WorkflowVariableBlockNode,      VariableValueBlockNode,    ],    editorState: textToEditorState(value || ''),    onError: (error: Error) => {      throw error    },  }  const handleEditorChange = (editorState: EditorState) => {    const text = editorState.read(() => {      return $getRoot().getChildren().map(p => p.getTextContent()).join('\n')    })    if (onChange)      onChange(text)  }  useEffect(() => {    eventEmitter?.emit({      type: UPDATE_DATASETS_EVENT_EMITTER,      payload: contextBlock?.datasets,    } as any)  }, [eventEmitter, contextBlock?.datasets])  useEffect(() => {    eventEmitter?.emit({      type: UPDATE_HISTORY_EVENT_EMITTER,      payload: historyBlock?.history,    } as any)  }, [eventEmitter, historyBlock?.history])  return (    <LexicalComposer initialConfig={{ ...initialConfig, editable }}>      <div className='relative min-h-5'>        <RichTextPlugin          contentEditable={<ContentEditable className={`${className} outline-none ${compact ? 'text-[13px] leading-5' : 'text-sm leading-6'} text-text-secondary`} style={style || {}} />}          placeholder={<Placeholder value={placeholder} className={cn('truncate', placeholderClassName)} compact={compact} />}          ErrorBoundary={LexicalErrorBoundary}        />        <ComponentPickerBlock          triggerString='/'          contextBlock={contextBlock}          historyBlock={historyBlock}          queryBlock={queryBlock}          variableBlock={variableBlock}          externalToolBlock={externalToolBlock}          workflowVariableBlock={workflowVariableBlock}          isSupportFileVar={isSupportFileVar}        />        <ComponentPickerBlock          triggerString='{'          contextBlock={contextBlock}          historyBlock={historyBlock}          queryBlock={queryBlock}          variableBlock={variableBlock}          externalToolBlock={externalToolBlock}          workflowVariableBlock={workflowVariableBlock}          isSupportFileVar={isSupportFileVar}        />        {          contextBlock?.show && (            <>              <ContextBlock {...contextBlock} />              <ContextBlockReplacementBlock {...contextBlock} />            </>          )        }        {          queryBlock?.show && (            <>              <QueryBlock {...queryBlock} />              <QueryBlockReplacementBlock />            </>          )        }        {          historyBlock?.show && (            <>              <HistoryBlock {...historyBlock} />              <HistoryBlockReplacementBlock {...historyBlock} />            </>          )        }        {          (variableBlock?.show || externalToolBlock?.show) && (            <>              <VariableBlock />              <VariableValueBlock />            </>          )        }        {          workflowVariableBlock?.show && (            <>              <WorkflowVariableBlock {...workflowVariableBlock} />              <WorkflowVariableBlockReplacementBlock {...workflowVariableBlock} />            </>          )        }        <OnChangePlugin onChange={handleEditorChange} />        <OnBlurBlock onBlur={onBlur} onFocus={onFocus} />        <UpdateBlock instanceId={instanceId} />        <HistoryPlugin />        {/* <TreeView /> */}      </div>    </LexicalComposer>  )}export default PromptEditor
 |