| 
									
										
										
										
											2024-05-27 21:57:08 +08:00
										 |  |  | import { | 
					
						
							| 
									
										
										
										
											2025-02-17 17:05:13 +08:00
										 |  |  |   useEffect, | 
					
						
							| 
									
										
										
										
											2024-05-27 21:57:08 +08:00
										 |  |  |   useMemo, | 
					
						
							| 
									
										
										
										
											2025-02-17 17:05:13 +08:00
										 |  |  |   useRef, | 
					
						
							| 
									
										
										
										
											2024-05-27 21:57:08 +08:00
										 |  |  |   useState, | 
					
						
							|  |  |  | } from 'react' | 
					
						
							|  |  |  | import type { | 
					
						
							|  |  |  |   OnSelectBlock, | 
					
						
							|  |  |  |   ToolWithProvider, | 
					
						
							|  |  |  | } from '../types' | 
					
						
							| 
									
										
										
										
											2025-02-17 17:05:13 +08:00
										 |  |  | import type { ToolValue } from './types' | 
					
						
							| 
									
										
										
										
											2024-05-27 21:57:08 +08:00
										 |  |  | import { ToolTypeEnum } from './types' | 
					
						
							|  |  |  | import Tools from './tools' | 
					
						
							|  |  |  | import { useToolTabs } from './hooks' | 
					
						
							| 
									
										
										
										
											2025-02-17 17:05:13 +08:00
										 |  |  | import ViewTypeSelect, { ViewType } from './view-type-select' | 
					
						
							| 
									
										
										
										
											2024-07-09 15:05:40 +08:00
										 |  |  | import cn from '@/utils/classnames' | 
					
						
							| 
									
										
										
										
											2025-02-17 17:05:13 +08:00
										 |  |  | import { useGetLanguage } from '@/context/i18n' | 
					
						
							|  |  |  | import PluginList from '@/app/components/workflow/block-selector/market-place-plugin/list' | 
					
						
							|  |  |  | import ActionButton from '../../base/action-button' | 
					
						
							|  |  |  | import { RiAddLine } from '@remixicon/react' | 
					
						
							|  |  |  | import { PluginType } from '../../plugins/types' | 
					
						
							|  |  |  | import { useMarketplacePlugins } from '../../plugins/marketplace/hooks' | 
					
						
							| 
									
										
										
										
											2024-05-27 21:57:08 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | type AllToolsProps = { | 
					
						
							| 
									
										
										
										
											2025-02-17 17:05:13 +08:00
										 |  |  |   className?: string | 
					
						
							|  |  |  |   toolContentClassName?: string | 
					
						
							| 
									
										
										
										
											2024-05-27 21:57:08 +08:00
										 |  |  |   searchText: string | 
					
						
							| 
									
										
										
										
											2025-02-17 17:05:13 +08:00
										 |  |  |   tags: string[] | 
					
						
							|  |  |  |   buildInTools: ToolWithProvider[] | 
					
						
							|  |  |  |   customTools: ToolWithProvider[] | 
					
						
							|  |  |  |   workflowTools: ToolWithProvider[] | 
					
						
							| 
									
										
										
										
											2024-05-27 21:57:08 +08:00
										 |  |  |   onSelect: OnSelectBlock | 
					
						
							| 
									
										
										
										
											2025-02-17 17:05:13 +08:00
										 |  |  |   supportAddCustomTool?: boolean | 
					
						
							|  |  |  |   onAddedCustomTool?: () => void | 
					
						
							|  |  |  |   onShowAddCustomCollectionModal?: () => void | 
					
						
							|  |  |  |   selectedTools?: ToolValue[] | 
					
						
							| 
									
										
										
										
											2024-05-27 21:57:08 +08:00
										 |  |  | } | 
					
						
							|  |  |  | const AllTools = ({ | 
					
						
							| 
									
										
										
										
											2025-02-17 17:05:13 +08:00
										 |  |  |   className, | 
					
						
							|  |  |  |   toolContentClassName, | 
					
						
							| 
									
										
										
										
											2024-05-27 21:57:08 +08:00
										 |  |  |   searchText, | 
					
						
							| 
									
										
										
										
											2025-02-17 17:05:13 +08:00
										 |  |  |   tags = [], | 
					
						
							| 
									
										
										
										
											2024-05-27 21:57:08 +08:00
										 |  |  |   onSelect, | 
					
						
							| 
									
										
										
										
											2025-02-17 17:05:13 +08:00
										 |  |  |   buildInTools, | 
					
						
							|  |  |  |   workflowTools, | 
					
						
							|  |  |  |   customTools, | 
					
						
							|  |  |  |   supportAddCustomTool, | 
					
						
							|  |  |  |   onShowAddCustomCollectionModal, | 
					
						
							|  |  |  |   selectedTools, | 
					
						
							| 
									
										
										
										
											2024-05-27 21:57:08 +08:00
										 |  |  | }: AllToolsProps) => { | 
					
						
							| 
									
										
										
										
											2025-02-17 17:05:13 +08:00
										 |  |  |   const language = useGetLanguage() | 
					
						
							| 
									
										
										
										
											2024-05-27 21:57:08 +08:00
										 |  |  |   const tabs = useToolTabs() | 
					
						
							|  |  |  |   const [activeTab, setActiveTab] = useState(ToolTypeEnum.All) | 
					
						
							| 
									
										
										
										
											2025-02-17 17:05:13 +08:00
										 |  |  |   const [activeView, setActiveView] = useState<ViewType>(ViewType.flat) | 
					
						
							|  |  |  |   const hasFilter = searchText || tags.length > 0 | 
					
						
							| 
									
										
										
										
											2024-11-11 11:32:41 +08:00
										 |  |  |   const isMatchingKeywords = (text: string, keywords: string) => { | 
					
						
							|  |  |  |     return text.toLowerCase().includes(keywords.toLowerCase()) | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2024-05-27 21:57:08 +08:00
										 |  |  |   const tools = useMemo(() => { | 
					
						
							|  |  |  |     let mergedTools: ToolWithProvider[] = [] | 
					
						
							|  |  |  |     if (activeTab === ToolTypeEnum.All) | 
					
						
							| 
									
										
										
										
											2024-05-29 13:04:23 +08:00
										 |  |  |       mergedTools = [...buildInTools, ...customTools, ...workflowTools] | 
					
						
							| 
									
										
										
										
											2024-05-27 21:57:08 +08:00
										 |  |  |     if (activeTab === ToolTypeEnum.BuiltIn) | 
					
						
							|  |  |  |       mergedTools = buildInTools | 
					
						
							|  |  |  |     if (activeTab === ToolTypeEnum.Custom) | 
					
						
							|  |  |  |       mergedTools = customTools | 
					
						
							|  |  |  |     if (activeTab === ToolTypeEnum.Workflow) | 
					
						
							|  |  |  |       mergedTools = workflowTools | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-02-17 17:05:13 +08:00
										 |  |  |     if (!hasFilter) | 
					
						
							|  |  |  |       return mergedTools.filter(toolWithProvider => toolWithProvider.tools.length > 0) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-05-27 21:57:08 +08:00
										 |  |  |     return mergedTools.filter((toolWithProvider) => { | 
					
						
							| 
									
										
										
										
											2025-02-17 17:05:13 +08:00
										 |  |  |       return isMatchingKeywords(toolWithProvider.name, searchText) || toolWithProvider.tools.some((tool) => { | 
					
						
							|  |  |  |         return tool.label[language].toLowerCase().includes(searchText.toLowerCase()) || tool.name.toLowerCase().includes(searchText.toLowerCase()) | 
					
						
							|  |  |  |       }) | 
					
						
							| 
									
										
										
										
											2024-05-27 21:57:08 +08:00
										 |  |  |     }) | 
					
						
							| 
									
										
										
										
											2025-02-17 17:05:13 +08:00
										 |  |  |   }, [activeTab, buildInTools, customTools, workflowTools, searchText, language, hasFilter]) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   const { | 
					
						
							|  |  |  |     queryPluginsWithDebounced: fetchPlugins, | 
					
						
							|  |  |  |     plugins: notInstalledPlugins = [], | 
					
						
							|  |  |  |   } = useMarketplacePlugins() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   useEffect(() => { | 
					
						
							|  |  |  |     if (searchText || tags.length > 0) { | 
					
						
							|  |  |  |       fetchPlugins({ | 
					
						
							|  |  |  |         query: searchText, | 
					
						
							|  |  |  |         tags, | 
					
						
							|  |  |  |         category: PluginType.tool, | 
					
						
							|  |  |  |       }) | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     // eslint-disable-next-line react-hooks/exhaustive-deps
 | 
					
						
							|  |  |  |   }, [searchText, tags]) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   const pluginRef = useRef(null) | 
					
						
							|  |  |  |   const wrapElemRef = useRef<HTMLDivElement>(null) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-05-27 21:57:08 +08:00
										 |  |  |   return ( | 
					
						
							| 
									
										
										
										
											2025-02-17 17:05:13 +08:00
										 |  |  |     <div className={cn(className)}> | 
					
						
							|  |  |  |       <div className='flex items-center justify-between px-3 bg-background-default-hover border-b-[0.5px] border-divider-subtle shadow-xs'> | 
					
						
							|  |  |  |         <div className='flex items-center h-8 space-x-1'> | 
					
						
							|  |  |  |           { | 
					
						
							|  |  |  |             tabs.map(tab => ( | 
					
						
							|  |  |  |               <div | 
					
						
							|  |  |  |                 className={cn( | 
					
						
							|  |  |  |                   'flex items-center px-2 h-6 rounded-md hover:bg-state-base-hover cursor-pointer', | 
					
						
							|  |  |  |                   'text-xs font-medium text-text-secondary', | 
					
						
							|  |  |  |                   activeTab === tab.key && 'bg-state-base-hover-alt', | 
					
						
							|  |  |  |                 )} | 
					
						
							|  |  |  |                 key={tab.key} | 
					
						
							|  |  |  |                 onClick={() => setActiveTab(tab.key)} | 
					
						
							|  |  |  |               > | 
					
						
							|  |  |  |                 {tab.name} | 
					
						
							|  |  |  |               </div> | 
					
						
							|  |  |  |             )) | 
					
						
							|  |  |  |           } | 
					
						
							|  |  |  |         </div> | 
					
						
							|  |  |  |         <ViewTypeSelect viewType={activeView} onChange={setActiveView} /> | 
					
						
							|  |  |  |         {supportAddCustomTool && ( | 
					
						
							|  |  |  |           <div className='flex items-center'> | 
					
						
							|  |  |  |             <div className='mr-1.5 w-px h-3.5  bg-divider-regular'></div> | 
					
						
							|  |  |  |             <ActionButton | 
					
						
							|  |  |  |               className='bg-components-button-primary-bg hover:bg-components-button-primary-bg text-components-button-primary-text hover:text-components-button-primary-text' | 
					
						
							|  |  |  |               onClick={onShowAddCustomCollectionModal} | 
					
						
							| 
									
										
										
										
											2024-05-27 21:57:08 +08:00
										 |  |  |             > | 
					
						
							| 
									
										
										
										
											2025-02-17 17:05:13 +08:00
										 |  |  |               <RiAddLine className='w-4 h-4' /> | 
					
						
							|  |  |  |             </ActionButton> | 
					
						
							|  |  |  |           </div> | 
					
						
							|  |  |  |         )} | 
					
						
							|  |  |  |       </div> | 
					
						
							|  |  |  |       <div | 
					
						
							|  |  |  |         ref={wrapElemRef} | 
					
						
							|  |  |  |         className='max-h-[464px] overflow-y-auto' | 
					
						
							|  |  |  |         onScroll={(pluginRef.current as any)?.handleScroll} | 
					
						
							|  |  |  |       > | 
					
						
							|  |  |  |         <Tools | 
					
						
							|  |  |  |           className={toolContentClassName} | 
					
						
							|  |  |  |           showWorkflowEmpty={activeTab === ToolTypeEnum.Workflow} | 
					
						
							|  |  |  |           tools={tools} | 
					
						
							|  |  |  |           onSelect={onSelect} | 
					
						
							|  |  |  |           viewType={activeView} | 
					
						
							|  |  |  |           hasSearchText={!!searchText} | 
					
						
							|  |  |  |           selectedTools={selectedTools} | 
					
						
							|  |  |  |         /> | 
					
						
							|  |  |  |         {/* Plugins from marketplace */} | 
					
						
							|  |  |  |         <PluginList | 
					
						
							|  |  |  |           wrapElemRef={wrapElemRef} | 
					
						
							|  |  |  |           list={notInstalledPlugins as any} ref={pluginRef} | 
					
						
							|  |  |  |           searchText={searchText} | 
					
						
							|  |  |  |           toolContentClassName={toolContentClassName} | 
					
						
							|  |  |  |           tags={tags} | 
					
						
							|  |  |  |         /> | 
					
						
							| 
									
										
										
										
											2024-05-27 21:57:08 +08:00
										 |  |  |       </div> | 
					
						
							|  |  |  |     </div> | 
					
						
							|  |  |  |   ) | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | export default AllTools |