'use client' import type { FC } from 'react' import React, { useCallback, useEffect, useMemo, useRef } from 'react' import cn from '@/utils/classnames' import { RiArrowDownSLine, RiArrowRightSLine } from '@remixicon/react' import { useGetLanguage } from '@/context/i18n' import type { Tool as ToolType } from '../../../tools/types' import { CollectionType } from '../../../tools/types' import type { ToolWithProvider } from '../../types' import { BlockEnum } from '../../types' import type { ToolDefaultValue, ToolValue } from '../types' import { ViewType } from '../view-type-select' import ActonItem from './action-item' import BlockIcon from '../../block-icon' import { useTranslation } from 'react-i18next' import { useHover } from 'ahooks' type Props = { className?: string payload: ToolWithProvider viewType: ViewType isShowLetterIndex: boolean hasSearchText: boolean onSelect: (type: BlockEnum, tool?: ToolDefaultValue) => void canNotSelectMultiple?: boolean onSelectMultiple?: (type: BlockEnum, tools: ToolDefaultValue[]) => void selectedTools?: ToolValue[] } const Tool: FC = ({ className, payload, viewType, isShowLetterIndex, hasSearchText, onSelect, canNotSelectMultiple, onSelectMultiple, selectedTools, }) => { const { t } = useTranslation() const language = useGetLanguage() const isFlatView = viewType === ViewType.flat const notShowProvider = payload.type === CollectionType.workflow const actions = payload.tools const hasAction = !notShowProvider const [isFold, setFold] = React.useState(true) const ref = useRef(null) const isHovering = useHover(ref) const getIsDisabled = useCallback((tool: ToolType) => { if (!selectedTools || !selectedTools.length) return false return selectedTools.some(selectedTool => (selectedTool.provider_name === payload.name || selectedTool.provider_name === payload.id) && selectedTool.tool_name === tool.name) }, [payload.id, payload.name, selectedTools]) const totalToolsNum = actions.length const selectedToolsNum = actions.filter(action => getIsDisabled(action)).length const isAllSelected = selectedToolsNum === totalToolsNum const notShowProviderSelectInfo = useMemo(() => { if (isAllSelected) { return ( {t('tools.addToolModal.added')} ) } }, [isAllSelected, t]) const selectedInfo = useMemo(() => { if (isHovering && !isAllSelected) { return ( { onSelectMultiple?.(BlockEnum.Tool, actions.filter(action => !getIsDisabled(action)).map((tool) => { const params: Record = {} if (tool.parameters) { tool.parameters.forEach((item) => { params[item.name] = '' }) } return { provider_id: payload.id, provider_type: payload.type, provider_name: payload.name, tool_name: tool.name, tool_label: tool.label[language], tool_description: tool.description[language], title: tool.label[language], is_team_authorization: payload.is_team_authorization, output_schema: tool.output_schema, paramSchemas: tool.parameters, params, } })) }} > {t('workflow.tabs.addAll')} ) } if (selectedToolsNum === 0) return <> return ( {isAllSelected ? t('workflow.tabs.allAdded') : `${selectedToolsNum} / ${totalToolsNum}` } ) }, [actions, getIsDisabled, isAllSelected, isHovering, language, onSelectMultiple, payload.id, payload.is_team_authorization, payload.name, payload.type, selectedToolsNum, t, totalToolsNum]) useEffect(() => { if (hasSearchText && isFold) { setFold(false) return } if (!hasSearchText && !isFold) setFold(true) // eslint-disable-next-line react-hooks/exhaustive-deps }, [hasSearchText]) const FoldIcon = isFold ? RiArrowRightSLine : RiArrowDownSLine const groupName = useMemo(() => { if (payload.type === CollectionType.builtIn) return payload.author if (payload.type === CollectionType.custom) return t('workflow.tabs.customTool') if (payload.type === CollectionType.workflow) return t('workflow.tabs.workflowTool') return '' }, [payload.author, payload.type, t]) return (
{ if (hasAction) { setFold(!isFold) return } const tool = actions[0] const params: Record = {} if (tool.parameters) { tool.parameters.forEach((item) => { params[item.name] = '' }) } onSelect(BlockEnum.Tool, { provider_id: payload.id, provider_type: payload.type, provider_name: payload.name, tool_name: tool.name, tool_label: tool.label[language], tool_description: tool.description[language], title: tool.label[language], is_team_authorization: payload.is_team_authorization, output_schema: tool.output_schema, paramSchemas: tool.parameters, params, }) }} >
{notShowProvider ? actions[0]?.label[language] : payload.label[language]} {isFlatView && ( {groupName} )}
{!canNotSelectMultiple && (notShowProvider ? notShowProviderSelectInfo : selectedInfo)} {hasAction && ( )}
{!notShowProvider && hasAction && !isFold && ( actions.map(action => ( )) )}
) } export default React.memo(Tool)