import type { FC, MouseEventHandler, } from 'react' import { memo, useCallback, useMemo, useState, } from 'react' import { useTranslation } from 'react-i18next' import type { OffsetOptions, Placement, } from '@floating-ui/react' import type { BlockEnum, OnSelectBlock } from '../types' import Tabs from './tabs' import { TabsEnum } from './types' import { PortalToFollowElem, PortalToFollowElemContent, PortalToFollowElemTrigger, } from '@/app/components/base/portal-to-follow-elem' import Input from '@/app/components/base/input' import { Plus02, } from '@/app/components/base/icons/src/vender/line/general' type NodeSelectorProps = { open?: boolean onOpenChange?: (open: boolean) => void onSelect: OnSelectBlock trigger?: (open: boolean) => React.ReactNode placement?: Placement offset?: OffsetOptions triggerStyle?: React.CSSProperties triggerClassName?: (open: boolean) => string triggerInnerClassName?: string popupClassName?: string asChild?: boolean availableBlocksTypes?: BlockEnum[] disabled?: boolean noBlocks?: boolean } const NodeSelector: FC = ({ open: openFromProps, onOpenChange, onSelect, trigger, placement = 'right', offset = 6, triggerClassName, triggerInnerClassName, triggerStyle, popupClassName, asChild, availableBlocksTypes, disabled, noBlocks = false, }) => { const { t } = useTranslation() const [searchText, setSearchText] = useState('') const [localOpen, setLocalOpen] = useState(false) const open = openFromProps === undefined ? localOpen : openFromProps const handleOpenChange = useCallback((newOpen: boolean) => { setLocalOpen(newOpen) if (!newOpen) setSearchText('') if (onOpenChange) onOpenChange(newOpen) }, [onOpenChange]) const handleTrigger = useCallback>((e) => { if (disabled) return e.stopPropagation() handleOpenChange(!open) }, [handleOpenChange, open, disabled]) const handleSelect = useCallback((type, toolDefaultValue) => { handleOpenChange(false) onSelect(type, toolDefaultValue) }, [handleOpenChange, onSelect]) const [activeTab, setActiveTab] = useState(noBlocks ? TabsEnum.Tools : TabsEnum.Blocks) const handleActiveTabChange = useCallback((newActiveTab: TabsEnum) => { setActiveTab(newActiveTab) }, []) const searchPlaceholder = useMemo(() => { if (activeTab === TabsEnum.Blocks) return t('workflow.tabs.searchBlock') if (activeTab === TabsEnum.Tools) return t('workflow.tabs.searchTool') return '' }, [activeTab, t]) return ( { trigger ? trigger(open) : (
) }
e.stopPropagation()}> setSearchText(e.target.value)} onClear={() => setSearchText('')} />
) } export default memo(NodeSelector)