'use client' import type { Placement } from '@langgenius/dify-ui/popover' import type { ReactElement, Ref } from 'react' import type { Node } from 'reactflow' import type { ToolValue } from '@/app/components/workflow/block-selector/types' import type { NodeOutPutVar } from '@/app/components/workflow/types' import { cn } from '@langgenius/dify-ui/cn' import { Popover, PopoverContent, PopoverTrigger } from '@langgenius/dify-ui/popover' import { memo } from 'react' import { useTranslation } from 'react-i18next' import { CollectionType } from '@/app/components/tools/types' import Link from '@/next/link' import { ToolAuthorizationSection } from './components/tool-authorization-section' import { ToolBaseForm } from './components/tool-base-form' import { ToolItem } from './components/tool-item' import { ToolSettingsPanel } from './components/tool-settings-panel' import { ToolTrigger } from './components/tool-trigger' import { useToolSelector } from './hooks/use-tool-selector' type TriggerProps = | { trigger: ReactElement triggerRef?: never controlledState: boolean onControlledStateChange: (state: boolean) => void } | { trigger?: never triggerRef?: Ref controlledState?: never onControlledStateChange?: never } type Props = Readonly<{ disabled?: boolean placement?: Placement scope?: string value?: ToolValue selectedTools?: ToolValue[] onSelect: (tool: ToolValue) => void onSelectMultiple?: (tool: ToolValue[]) => void isEdit?: boolean onDelete?: () => void supportEnableSwitch?: boolean panelShowState?: boolean onPanelShowStateChange?: (state: boolean) => void nodeOutputVars: NodeOutPutVar[] availableNodes: Node[] nodeId?: string }> & TriggerProps function ToolSelector({ value, selectedTools, isEdit, disabled, placement = 'left', onSelect, onSelectMultiple, onDelete, scope, supportEnableSwitch, trigger, controlledState, onControlledStateChange, panelShowState, onPanelShowStateChange, nodeOutputVars, availableNodes, nodeId = '', triggerRef, }: Props) { const { t } = useTranslation() const { isShow, setIsShow, isShowChooseTool, setIsShowChooseTool, currType, setCurrType, currentProvider, currentTool, settingsFormSchemas, paramsFormSchemas, showTabSlider, userSettingsOnly, reasoningConfigOnly, manifestIcon, inMarketPlace, manifest, handleSelectTool, handleSelectMultipleTool, handleDescriptionChange, handleSettingsFormChange, handleParamsFormChange, handleEnabledChange, handleAuthorizationItemClick, handleInstall, settingsValue, } = useToolSelector({ value, onSelect, onSelectMultiple }) const portalOpen = trigger ? controlledState : isShow const onPortalOpenChange = trigger ? onControlledStateChange : setIsShow const handlePortalOpenChange = (nextOpen: boolean) => { const isConfiguredToolUnavailable = !!value?.provider_name && (!currentProvider || !currentTool) if (nextOpen && (disabled || isConfiguredToolUnavailable)) return onPortalOpenChange?.(nextOpen) } const renderErrorTip = () => (

{currentTool ? t(($) => $['detailPanel.toolSelector.uninstalledTitle'], { ns: 'plugin' }) : t(($) => $['detailPanel.toolSelector.unsupportedTitle'], { ns: 'plugin' })}

{currentTool ? t(($) => $['detailPanel.toolSelector.uninstalledContent'], { ns: 'plugin' }) : t(($) => $['detailPanel.toolSelector.unsupportedContent'], { ns: 'plugin' })}

{t(($) => $['detailPanel.toolSelector.uninstalledLink'], { ns: 'plugin' })}

) return ( {trigger ? : null} {!trigger && !value?.provider_name ? ( } /> ) : null} {!trigger && value?.provider_name ? ( ) : null}
{t(($) => $[`detailPanel.toolSelector.${isEdit ? 'toolSetting' : 'title'}`], { ns: 'plugin', })}
) } export default memo(ToolSelector)