123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134 |
- 'use client'
- import type { FC } from 'react'
- import React, { useEffect, useMemo } 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'
- type Props = {
- className?: string
- payload: ToolWithProvider
- viewType: ViewType
- isShowLetterIndex: boolean
- hasSearchText: boolean
- onSelect: (type: BlockEnum, tool?: ToolDefaultValue) => void
- selectedTools?: ToolValue[]
- }
- const Tool: FC<Props> = ({
- className,
- payload,
- viewType,
- isShowLetterIndex,
- hasSearchText,
- onSelect,
- selectedTools,
- }) => {
- const { t } = useTranslation()
- const language = useGetLanguage()
- const isFlatView = viewType === ViewType.flat
- const actions = payload.tools
- const hasAction = true // Now always support actions
- const [isFold, setFold] = React.useState<boolean>(true)
- const getIsDisabled = (tool: ToolType) => {
- if (!selectedTools || !selectedTools.length) return false
- return selectedTools.some(selectedTool => selectedTool.provider_name === payload.name && selectedTool.tool_name === tool.name)
- }
- 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 (
- <div
- key={payload.id}
- className={cn('mb-1 last-of-type:mb-0', isShowLetterIndex && 'mr-6')}
- >
- <div className={cn(className)}>
- <div
- className='flex items-center justify-between pl-3 pr-1 w-full rounded-lg hover:bg-state-base-hover cursor-pointer select-none'
- onClick={() => {
- if (hasAction)
- setFold(!isFold)
- // Now always support actions
- // if (payload.parameters) {
- // payload.parameters.forEach((item) => {
- // params[item.name] = ''
- // })
- // }
- // onSelect(BlockEnum.Tool, {
- // provider_id: payload.id,
- // provider_type: payload.type,
- // provider_name: payload.name,
- // tool_name: payload.name,
- // tool_label: payload.label[language],
- // title: payload.label[language],
- // params: {},
- // })
- }}
- >
- <div className='flex grow items-center h-8'>
- <BlockIcon
- className='shrink-0'
- type={BlockEnum.Tool}
- toolIcon={payload.icon}
- />
- <div className='ml-2 text-sm text-text-primary flex-1 w-0 grow truncate'>{payload.label[language]}</div>
- </div>
- <div className='flex items-center'>
- {isFlatView && (
- <div className='text-text-tertiary system-xs-regular'>{groupName}</div>
- )}
- {hasAction && (
- <FoldIcon className={cn('w-4 h-4 text-text-quaternary shrink-0', isFold && 'text-text-tertiary')} />
- )}
- </div>
- </div>
- {hasAction && !isFold && (
- actions.map(action => (
- <ActonItem
- key={action.name}
- provider={payload}
- payload={action}
- onSelect={onSelect}
- disabled={getIsDisabled(action)}
- />
- ))
- )}
- </div>
- </div>
- )
- }
- export default React.memo(Tool)
|