Spaces:
				
			
			
	
			
			
		Paused
		
	
	
	
			
			
	
	
	
	
		
		
		Paused
		
	| import { | |
| memo, | |
| useCallback, | |
| } from 'react' | |
| import { useTranslation } from 'react-i18next' | |
| import { | |
| RiAddLine, | |
| } from '@remixicon/react' | |
| import cn from '@/utils/classnames' | |
| import { ArrowUpRight } from '@/app/components/base/icons/src/vender/line/arrows' | |
| import { Check } from '@/app/components/base/icons/src/vender/line/general' | |
| import { Tag01 } from '@/app/components/base/icons/src/vender/line/financeAndECommerce' | |
| import type { ToolWithProvider } from '@/app/components/workflow/types' | |
| import { BlockEnum } from '@/app/components/workflow/types' | |
| import BlockIcon from '@/app/components/workflow/block-icon' | |
| import Tooltip from '@/app/components/base/tooltip' | |
| import Button from '@/app/components/base/button' | |
| import { useGetLanguage } from '@/context/i18n' | |
| import { useStore as useLabelStore } from '@/app/components/tools/labels/store' | |
| import Empty from '@/app/components/tools/add-tool-modal/empty' | |
| import type { Tool } from '@/app/components/tools/types' | |
| import { CollectionType } from '@/app/components/tools/types' | |
| import type { AgentTool } from '@/types/app' | |
| import { MAX_TOOLS_NUM } from '@/config' | |
| type ToolsProps = { | |
| showWorkflowEmpty: boolean | |
| tools: ToolWithProvider[] | |
| addedTools: AgentTool[] | |
| onSelect: (provider: ToolWithProvider, tool: Tool) => void | |
| onAuthSetup: (provider: ToolWithProvider) => void | |
| } | |
| const Blocks = ({ | |
| showWorkflowEmpty, | |
| tools, | |
| addedTools, | |
| onSelect, | |
| onAuthSetup, | |
| }: ToolsProps) => { | |
| const { t } = useTranslation() | |
| const language = useGetLanguage() | |
| const labelList = useLabelStore(s => s.labelList) | |
| const addable = addedTools.length < MAX_TOOLS_NUM | |
| const renderGroup = useCallback((toolWithProvider: ToolWithProvider) => { | |
| const list = toolWithProvider.tools | |
| const needAuth = toolWithProvider.allow_delete && !toolWithProvider.is_team_authorization && toolWithProvider.type === CollectionType.builtIn | |
| return ( | |
| <div | |
| key={toolWithProvider.id} | |
| className='group mb-1 last-of-type:mb-0' | |
| > | |
| <div className='flex items-center justify-between w-full pl-3 pr-1 h-[22px] text-xs font-medium text-gray-500'> | |
| {toolWithProvider.label[language]} | |
| <a className='hidden cursor-pointer items-center group-hover:flex' href={`/tools?category=${toolWithProvider.type}`} target='_blank'>{t('tools.addToolModal.manageInTools')}<ArrowUpRight className='ml-0.5 w-3 h-3' /></a> | |
| </div> | |
| {list.map((tool) => { | |
| const labelContent = (() => { | |
| if (!tool.labels) | |
| return '' | |
| return tool.labels.map((name) => { | |
| const label = labelList.find(item => item.name === name) | |
| return label?.label[language] | |
| }).filter(Boolean).join(', ') | |
| })() | |
| const added = !!addedTools?.find(v => v.provider_id === toolWithProvider.id && v.provider_type === toolWithProvider.type && v.tool_name === tool.name) | |
| return ( | |
| <Tooltip | |
| key={tool.name} | |
| position='bottom' | |
| popupClassName='!p-0 !px-3 !py-2.5 !w-[210px] !leading-[18px] !text-xs !text-gray-700 !border-[0.5px] !border-black/5 !bg-transparent !rounded-xl !shadow-lg translate-x-[108px]' | |
| popupContent={( | |
| <div> | |
| <BlockIcon | |
| size='md' | |
| className='mb-2' | |
| type={BlockEnum.Tool} | |
| toolIcon={toolWithProvider.icon} | |
| /> | |
| <div className='mb-1 text-sm leading-5 text-gray-900'>{tool.label[language]}</div> | |
| <div className='text-xs text-gray-700 leading-[18px]'>{tool.description[language]}</div> | |
| {tool.labels?.length > 0 && ( | |
| <div className='flex items-center shrink-0 mt-1'> | |
| <div className='relative w-full flex items-center gap-1 py-1 rounded-md text-gray-500' title={labelContent}> | |
| <Tag01 className='shrink-0 w-3 h-3 text-gray-500' /> | |
| <div className='grow text-xs text-start leading-[18px] font-normal truncate'>{labelContent}</div> | |
| </div> | |
| </div> | |
| )} | |
| </div> | |
| )} | |
| > | |
| <div className='group/item flex items-center w-full pl-3 pr-1 h-8 rounded-lg hover:bg-gray-50 cursor-pointer'> | |
| <BlockIcon | |
| className={cn('mr-2 shrink-0', needAuth && 'opacity-30')} | |
| type={BlockEnum.Tool} | |
| toolIcon={toolWithProvider.icon} | |
| /> | |
| <div className={cn('grow text-sm text-gray-900 truncate', needAuth && 'opacity-30')}>{tool.label[language]}</div> | |
| {!needAuth && added && ( | |
| <div className='flex items-center gap-1 rounded-[6px] border border-gray-100 px-2 py-[3px] bg-white text-gray-300 text-xs font-medium leading-[18px]'> | |
| <Check className='w-3 h-3' /> | |
| {t('tools.addToolModal.added').toLocaleUpperCase()} | |
| </div> | |
| )} | |
| {!needAuth && !added && addable && ( | |
| <Button | |
| variant='secondary-accent' | |
| size='small' | |
| className={cn('hidden shrink-0 items-center group-hover/item:flex')} | |
| onClick={() => onSelect(toolWithProvider, tool)} | |
| > | |
| <RiAddLine className='w-3 h-3' /> | |
| {t('tools.addToolModal.add').toLocaleUpperCase()} | |
| </Button> | |
| )} | |
| {needAuth && ( | |
| <Button | |
| variant='secondary-accent' | |
| size='small' | |
| className={cn('hidden shrink-0 group-hover/item:flex')} | |
| onClick={() => onAuthSetup(toolWithProvider)} | |
| >{t('tools.auth.setup')}</Button> | |
| )} | |
| </div> | |
| </Tooltip> | |
| ) | |
| })} | |
| </div> | |
| ) | |
| }, [addable, language, t, labelList, addedTools, onAuthSetup, onSelect]) | |
| return ( | |
| <div className='p-1 pb-6 max-w-[440px]'> | |
| {!tools.length && !showWorkflowEmpty && ( | |
| <div className='flex items-center px-3 h-[22px] text-xs font-medium text-gray-500'>{t('workflow.tabs.noResult')}</div> | |
| )} | |
| {!tools.length && showWorkflowEmpty && ( | |
| <div className='pt-[280px]'> | |
| <Empty /> | |
| </div> | |
| )} | |
| {!!tools.length && tools.map(renderGroup)} | |
| </div> | |
| ) | |
| } | |
| export default memo(Blocks) | |
