From a430284aa21e3ae1f0d5654e55b2ad2852519cc2 Mon Sep 17 00:00:00 2001 From: wwf <yearningwang@iqtogether.com> Date: 星期三, 04 六月 2025 15:17:49 +0800 Subject: [PATCH] 初始化 --- app/components/workflow/block-selector/tools.tsx | 166 ++++++++++++++++++++++++++----------------------------- 1 files changed, 78 insertions(+), 88 deletions(-) diff --git a/app/components/workflow/block-selector/tools.tsx b/app/components/workflow/block-selector/tools.tsx index 2562501..394966f 100644 --- a/app/components/workflow/block-selector/tools.tsx +++ b/app/components/workflow/block-selector/tools.tsx @@ -1,96 +1,106 @@ import { memo, - useMemo, + useCallback, useRef, } from 'react' import { useTranslation } from 'react-i18next' -import type { BlockEnum, ToolWithProvider } from '../types' +import BlockIcon from '../block-icon' +import { BlockEnum } from '../types' +import type { ToolWithProvider } from '../types' import IndexBar, { groupItems } from './index-bar' -import type { ToolDefaultValue, ToolValue } from './types' -import { ViewType } from './view-type-select' +import type { ToolDefaultValue } from './types' +import Tooltip from '@/app/components/base/tooltip' import Empty from '@/app/components/tools/add-tool-modal/empty' import { useGetLanguage } from '@/context/i18n' -import ToolListTreeView from './tool/tool-list-tree-view/list' -import ToolListFlatView from './tool/tool-list-flat-view/list' -import classNames from '@/utils/classnames' type ToolsProps = { showWorkflowEmpty: boolean onSelect: (type: BlockEnum, tool?: ToolDefaultValue) => void tools: ToolWithProvider[] - viewType: ViewType - hasSearchText: boolean - className?: string - indexBarClassName?: string - selectedTools?: ToolValue[] } const Blocks = ({ showWorkflowEmpty, onSelect, tools, - viewType, - hasSearchText, - className, - indexBarClassName, - selectedTools, }: ToolsProps) => { const { t } = useTranslation() const language = useGetLanguage() - const isFlatView = viewType === ViewType.flat - const isShowLetterIndex = isFlatView && tools.length > 10 - /* - treeViewToolsData: - { - A: { - 'google': [ // plugin organize name - ...tools - ], - 'custom': [ // custom tools - ...tools - ], - 'workflow': [ // workflow as tools - ...tools - ] - } - } - */ - const { letters, groups: withLetterAndGroupViewToolsData } = groupItems(tools, tool => tool.label[language][0]) - const treeViewToolsData = useMemo(() => { - const result: Record<string, ToolWithProvider[]> = {} - Object.keys(withLetterAndGroupViewToolsData).forEach((letter) => { - Object.keys(withLetterAndGroupViewToolsData[letter]).forEach((groupName) => { - if (!result[groupName]) - result[groupName] = [] - result[groupName].push(...withLetterAndGroupViewToolsData[letter][groupName]) - }) - }) - return result - }, [withLetterAndGroupViewToolsData]) - - const listViewToolData = useMemo(() => { - const result: ToolWithProvider[] = [] - letters.forEach((letter) => { - Object.keys(withLetterAndGroupViewToolsData[letter]).forEach((groupName) => { - result.push(...withLetterAndGroupViewToolsData[letter][groupName].map((item) => { - return { - ...item, - letter, - } - })) - }) - }) - - return result - }, [withLetterAndGroupViewToolsData, letters]) - + const { letters, groups: groupedTools } = groupItems(tools, tool => tool.label[language][0]) const toolRefs = useRef({}) + const renderGroup = useCallback((toolWithProvider: ToolWithProvider) => { + const list = toolWithProvider.tools + + return ( + <div + key={toolWithProvider.id} + className='mb-1 last-of-type:mb-0' + > + <div className='flex items-start px-3 h-[22px] text-xs font-medium text-gray-500'> + {toolWithProvider.label[language]} + </div> + { + list.map(tool => ( + <Tooltip + key={tool.name} + position='right' + popupClassName='w-[200px]' + popupContent={( + <div> + <BlockIcon + size='md' + className='mb-2' + type={BlockEnum.Tool} + toolIcon={toolWithProvider.icon} + /> + <div className='mb-1 system-md-medium text-text-primary'>{tool.label[language]}</div> + <div className='system-xs-regular text-text-tertiary'>{tool.description[language]}</div> + </div> + )} + > + <div + className='flex items-center px-3 w-full h-8 rounded-lg hover:bg-state-base-hover cursor-pointer' + onClick={() => onSelect(BlockEnum.Tool, { + provider_id: toolWithProvider.id, + provider_type: toolWithProvider.type, + provider_name: toolWithProvider.name, + tool_name: tool.name, + tool_label: tool.label[language], + title: tool.label[language], + })} + > + <BlockIcon + className='mr-2 shrink-0' + type={BlockEnum.Tool} + toolIcon={toolWithProvider.icon} + /> + <div className='text-sm text-text-secondary flex-1 min-w-0 truncate'>{tool.label[language]}</div> + </div> + </Tooltip> + )) + } + </div> + ) + }, [onSelect, language]) + + const renderLetterGroup = (letter) => { + const tools = groupedTools[letter] + return ( + <div + key={letter} + ref={el => (toolRefs.current[letter] = el)} + > + {tools.map(renderGroup)} + </div> + ) + } + return ( - <div className={classNames('p-1 max-w-[320px]', className)}> + <div className='p-1 max-w-[320px] max-h-[464px] overflow-y-auto'> { !tools.length && !showWorkflowEmpty && ( - <div className='flex h-[22px] items-center px-3 text-xs font-medium text-text-tertiary'>{t('workflow.tabs.noResult')}</div> + <div className='flex items-center px-3 h-[22px] text-xs font-medium text-text-tertiary'>{t('workflow.tabs.noResult')}</div> ) } {!tools.length && showWorkflowEmpty && ( @@ -98,28 +108,8 @@ <Empty /> </div> )} - {!!tools.length && ( - isFlatView ? ( - <ToolListFlatView - toolRefs={toolRefs} - letters={letters} - payload={listViewToolData} - isShowLetterIndex={isShowLetterIndex} - hasSearchText={hasSearchText} - onSelect={onSelect} - selectedTools={selectedTools} - /> - ) : ( - <ToolListTreeView - payload={treeViewToolsData} - hasSearchText={hasSearchText} - onSelect={onSelect} - selectedTools={selectedTools} - /> - ) - )} - - {isShowLetterIndex && <IndexBar letters={letters} itemRefs={toolRefs} className={indexBarClassName} />} + {!!tools.length && letters.map(renderLetterGroup)} + {tools.length > 10 && <IndexBar letters={letters} itemRefs={toolRefs} />} </div> ) } -- Gitblit v1.8.0