| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283 | 
							- import {
 -   memo,
 -   useCallback,
 -   useState,
 - } from 'react'
 - import ReactDOM from 'react-dom'
 - import {
 -   FloatingPortal,
 -   flip,
 -   offset,
 -   shift,
 -   useFloating,
 - } from '@floating-ui/react'
 - import type { TextNode } from 'lexical'
 - import type { MenuRenderFn } from '@lexical/react/LexicalTypeaheadMenuPlugin'
 - import { useLexicalComposerContext } from '@lexical/react/LexicalComposerContext'
 - import { LexicalTypeaheadMenuPlugin } from '@lexical/react/LexicalTypeaheadMenuPlugin'
 - import type {
 -   ContextBlockType,
 -   ExternalToolBlockType,
 -   HistoryBlockType,
 -   QueryBlockType,
 -   VariableBlockType,
 -   WorkflowVariableBlockType,
 - } from '../../types'
 - import { useBasicTypeaheadTriggerMatch } from '../../hooks'
 - import { INSERT_WORKFLOW_VARIABLE_BLOCK_COMMAND } from '../workflow-variable-block'
 - import { INSERT_VARIABLE_VALUE_BLOCK_COMMAND } from '../variable-block'
 - import { $splitNodeContainingQuery } from '../../utils'
 - import type { PromptOption } from './prompt-option'
 - import PromptMenu from './prompt-menu'
 - import VariableMenu from './variable-menu'
 - import type { VariableOption } from './variable-option'
 - import { useOptions } from './hooks'
 - import VarReferenceVars from '@/app/components/workflow/nodes/_base/components/variable/var-reference-vars'
 - import { useEventEmitterContextContext } from '@/context/event-emitter'
 - 
 - type ComponentPickerProps = {
 -   triggerString: string
 -   contextBlock?: ContextBlockType
 -   queryBlock?: QueryBlockType
 -   historyBlock?: HistoryBlockType
 -   variableBlock?: VariableBlockType
 -   externalToolBlock?: ExternalToolBlockType
 -   workflowVariableBlock?: WorkflowVariableBlockType
 - }
 - const ComponentPicker = ({
 -   triggerString,
 -   contextBlock,
 -   queryBlock,
 -   historyBlock,
 -   variableBlock,
 -   externalToolBlock,
 -   workflowVariableBlock,
 - }: ComponentPickerProps) => {
 -   const { eventEmitter } = useEventEmitterContextContext()
 -   const { refs, floatingStyles, elements } = useFloating({
 -     placement: 'bottom-start',
 -     middleware: [
 -       offset(0), // fix hide cursor
 -       shift(),
 -       flip(),
 -     ],
 -   })
 -   const [editor] = useLexicalComposerContext()
 -   const checkForTriggerMatch = useBasicTypeaheadTriggerMatch(triggerString, {
 -     minLength: 0,
 -     maxLength: 0,
 -   })
 - 
 -   const [queryString, setQueryString] = useState<string | null>(null)
 - 
 -   eventEmitter?.useSubscription((v: any) => {
 -     if (v.type === INSERT_VARIABLE_VALUE_BLOCK_COMMAND)
 -       editor.dispatchCommand(INSERT_VARIABLE_VALUE_BLOCK_COMMAND, `{{${v.payload}}}`)
 -   })
 - 
 -   const {
 -     allOptions,
 -     promptOptions,
 -     variableOptions,
 -     externalToolOptions,
 -     workflowVariableOptions,
 -   } = useOptions(
 -     contextBlock,
 -     queryBlock,
 -     historyBlock,
 -     variableBlock,
 -     externalToolBlock,
 -     workflowVariableBlock,
 -   )
 - 
 -   const onSelectOption = useCallback(
 -     (
 -       selectedOption: PromptOption | VariableOption,
 -       nodeToRemove: TextNode | null,
 -       closeMenu: () => void,
 -       matchingString: string,
 -     ) => {
 -       editor.update(() => {
 -         if (nodeToRemove && selectedOption?.key)
 -           nodeToRemove.remove()
 - 
 -         if (selectedOption?.onSelect)
 -           selectedOption.onSelect(matchingString)
 - 
 -         closeMenu()
 -       })
 -     },
 -     [editor],
 -   )
 - 
 -   const handleSelectWorkflowVariable = useCallback((variables: string[]) => {
 -     editor.update(() => {
 -       const needRemove = $splitNodeContainingQuery(checkForTriggerMatch(triggerString, editor)!)
 -       if (needRemove)
 -         needRemove.remove()
 -     })
 - 
 -     if (variables[1] === 'sys.query' || variables[1] === 'sys.files')
 -       editor.dispatchCommand(INSERT_WORKFLOW_VARIABLE_BLOCK_COMMAND, [variables[1]])
 -     else
 -       editor.dispatchCommand(INSERT_WORKFLOW_VARIABLE_BLOCK_COMMAND, variables)
 -   }, [editor, checkForTriggerMatch, triggerString])
 - 
 -   const renderMenu = useCallback<MenuRenderFn<PromptOption | VariableOption>>((
 -     anchorElementRef,
 -     { selectedIndex, selectOptionAndCleanUp, setHighlightedIndex },
 -   ) => {
 -     if (anchorElementRef.current && (allOptions.length || workflowVariableBlock?.show)) {
 -       return (
 -         <>
 -           {
 -             ReactDOM.createPortal(
 -               <div ref={refs.setReference}></div>,
 -               anchorElementRef.current,
 -             )
 -           }
 -           {
 -             elements.reference && (
 -               <FloatingPortal id='typeahead-menu'>
 -                 <div
 -                   className='w-[260px] bg-white rounded-lg border-[0.5px] border-gray-200 shadow-lg overflow-y-auto'
 -                   style={{
 -                     ...floatingStyles,
 -                     maxHeight: 'calc(1 / 3 * 100vh)',
 -                   }}
 -                   ref={refs.setFloating}
 -                 >
 -                   {
 -                     !!promptOptions.length && (
 -                       <>
 -                         <PromptMenu
 -                           startIndex={0}
 -                           selectedIndex={selectedIndex}
 -                           options={promptOptions}
 -                           onClick={(index, option) => {
 -                             if (option.disabled)
 -                               return
 -                             setHighlightedIndex(index)
 -                             selectOptionAndCleanUp(option)
 -                           }}
 -                           onMouseEnter={(index, option) => {
 -                             if (option.disabled)
 -                               return
 -                             setHighlightedIndex(index)
 -                           }}
 -                         />
 -                       </>
 -                     )
 -                   }
 -                   {
 -                     !!variableOptions.length && (
 -                       <>
 -                         {
 -                           !!promptOptions.length && (
 -                             <div className='h-[1px] bg-gray-100'></div>
 -                           )
 -                         }
 -                         <VariableMenu
 -                           startIndex={promptOptions.length}
 -                           selectedIndex={selectedIndex}
 -                           options={variableOptions}
 -                           onClick={(index, option) => {
 -                             if (option.disabled)
 -                               return
 -                             setHighlightedIndex(index)
 -                             selectOptionAndCleanUp(option)
 -                           }}
 -                           onMouseEnter={(index, option) => {
 -                             if (option.disabled)
 -                               return
 -                             setHighlightedIndex(index)
 -                           }}
 -                           queryString={queryString}
 -                         />
 -                       </>
 -                     )
 -                   }
 -                   {
 -                     !!externalToolOptions.length && (
 -                       <>
 -                         {
 -                           (!!promptOptions.length || !!variableOptions.length) && (
 -                             <div className='h-[1px] bg-gray-100'></div>
 -                           )
 -                         }
 -                         <VariableMenu
 -                           startIndex={promptOptions.length + variableOptions.length}
 -                           selectedIndex={selectedIndex}
 -                           options={externalToolOptions}
 -                           onClick={(index, option) => {
 -                             if (option.disabled)
 -                               return
 -                             setHighlightedIndex(index)
 -                             selectOptionAndCleanUp(option)
 -                           }}
 -                           onMouseEnter={(index, option) => {
 -                             if (option.disabled)
 -                               return
 -                             setHighlightedIndex(index)
 -                           }}
 -                           queryString={queryString}
 -                         />
 -                       </>
 -                     )
 -                   }
 -                   {
 -                     workflowVariableBlock?.show && (
 -                       <>
 -                         {
 -                           (!!promptOptions.length || !!variableOptions.length || !!externalToolOptions.length) && (
 -                             <div className='h-[1px] bg-gray-100'></div>
 -                           )
 -                         }
 -                         <div className='p-1'>
 -                           <VarReferenceVars
 -                             hideSearch
 -                             vars={workflowVariableOptions}
 -                             onChange={(variables: string[]) => {
 -                               handleSelectWorkflowVariable(variables)
 -                             }}
 -                           />
 -                         </div>
 -                       </>
 -                     )
 -                   }
 -                 </div>
 -               </FloatingPortal>
 -             )
 -           }
 -         </>
 -       )
 -     }
 - 
 -     return null
 -   }, [
 -     allOptions,
 -     promptOptions,
 -     variableOptions,
 -     externalToolOptions,
 -     queryString,
 -     workflowVariableBlock?.show,
 -     workflowVariableOptions,
 -     handleSelectWorkflowVariable,
 -     elements,
 -     floatingStyles,
 -     refs,
 -   ])
 - 
 -   return (
 -     <LexicalTypeaheadMenuPlugin
 -       options={allOptions as any}
 -       onQueryChange={setQueryString}
 -       onSelectOption={onSelectOption}
 -       anchorClassName='z-[999999]'
 -       menuRenderFn={renderMenu}
 -       triggerFn={checkForTriggerMatch}
 -     />
 -   )
 - }
 - 
 - export default memo(ComponentPicker)
 
 
  |