You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

tools.tsx 4.5KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149
  1. import {
  2. memo,
  3. useMemo,
  4. useRef,
  5. } from 'react'
  6. import { useTranslation } from 'react-i18next'
  7. import type { BlockEnum, ToolWithProvider } from '../types'
  8. import IndexBar, { groupItems } from './index-bar'
  9. import type { ToolDefaultValue, ToolValue } from './types'
  10. import type { ToolTypeEnum } from './types'
  11. import { ViewType } from './view-type-select'
  12. import Empty from '@/app/components/tools/add-tool-modal/empty'
  13. import { useGetLanguage } from '@/context/i18n'
  14. import ToolListTreeView from './tool/tool-list-tree-view/list'
  15. import ToolListFlatView from './tool/tool-list-flat-view/list'
  16. import classNames from '@/utils/classnames'
  17. type ToolsProps = {
  18. onSelect: (type: BlockEnum, tool?: ToolDefaultValue) => void
  19. canNotSelectMultiple?: boolean
  20. onSelectMultiple?: (type: BlockEnum, tools: ToolDefaultValue[]) => void
  21. tools: ToolWithProvider[]
  22. viewType: ViewType
  23. hasSearchText: boolean
  24. toolType?: ToolTypeEnum
  25. isAgent?: boolean
  26. className?: string
  27. indexBarClassName?: string
  28. selectedTools?: ToolValue[]
  29. canChooseMCPTool?: boolean
  30. isShowRAGRecommendations?: boolean
  31. }
  32. const Blocks = ({
  33. onSelect,
  34. canNotSelectMultiple,
  35. onSelectMultiple,
  36. tools,
  37. viewType,
  38. hasSearchText,
  39. toolType,
  40. isAgent,
  41. className,
  42. indexBarClassName,
  43. selectedTools,
  44. canChooseMCPTool,
  45. isShowRAGRecommendations = false,
  46. }: ToolsProps) => {
  47. // const tools: any = []
  48. const { t } = useTranslation()
  49. const language = useGetLanguage()
  50. const isFlatView = viewType === ViewType.flat
  51. const isShowLetterIndex = isFlatView && tools.length > 10
  52. /*
  53. treeViewToolsData:
  54. {
  55. A: {
  56. 'google': [ // plugin organize name
  57. ...tools
  58. ],
  59. 'custom': [ // custom tools
  60. ...tools
  61. ],
  62. 'workflow': [ // workflow as tools
  63. ...tools
  64. ]
  65. }
  66. }
  67. */
  68. const { letters, groups: withLetterAndGroupViewToolsData } = groupItems(tools, tool => tool.label[language][0])
  69. const treeViewToolsData = useMemo(() => {
  70. const result: Record<string, ToolWithProvider[]> = {}
  71. Object.keys(withLetterAndGroupViewToolsData).forEach((letter) => {
  72. Object.keys(withLetterAndGroupViewToolsData[letter]).forEach((groupName) => {
  73. if (!result[groupName])
  74. result[groupName] = []
  75. result[groupName].push(...withLetterAndGroupViewToolsData[letter][groupName])
  76. })
  77. })
  78. return result
  79. }, [withLetterAndGroupViewToolsData])
  80. const listViewToolData = useMemo(() => {
  81. const result: ToolWithProvider[] = []
  82. letters.forEach((letter) => {
  83. Object.keys(withLetterAndGroupViewToolsData[letter]).forEach((groupName) => {
  84. result.push(...withLetterAndGroupViewToolsData[letter][groupName].map((item) => {
  85. return {
  86. ...item,
  87. letter,
  88. }
  89. }))
  90. })
  91. })
  92. return result
  93. }, [withLetterAndGroupViewToolsData, letters])
  94. const toolRefs = useRef({})
  95. return (
  96. <div className={classNames('max-w-[100%] p-1', className)}>
  97. {
  98. !tools.length && hasSearchText && (
  99. <div className='mt-2 flex h-[22px] items-center px-3 text-xs font-medium text-text-secondary'>{t('workflow.tabs.noResult')}</div>
  100. )
  101. }
  102. {!tools.length && !hasSearchText && (
  103. <div className='py-10'>
  104. <Empty type={toolType!} isAgent={isAgent} />
  105. </div>
  106. )}
  107. {!!tools.length && isShowRAGRecommendations && (
  108. <div className='system-xs-medium px-3 pb-0.5 pt-1 text-text-tertiary'>
  109. {t('tools.allTools')}
  110. </div>
  111. )}
  112. {!!tools.length && (
  113. isFlatView ? (
  114. <ToolListFlatView
  115. toolRefs={toolRefs}
  116. letters={letters}
  117. payload={listViewToolData}
  118. isShowLetterIndex={isShowLetterIndex}
  119. hasSearchText={hasSearchText}
  120. onSelect={onSelect}
  121. canNotSelectMultiple={canNotSelectMultiple}
  122. onSelectMultiple={onSelectMultiple}
  123. selectedTools={selectedTools}
  124. canChooseMCPTool={canChooseMCPTool}
  125. indexBar={<IndexBar letters={letters} itemRefs={toolRefs} className={indexBarClassName} />}
  126. />
  127. ) : (
  128. <ToolListTreeView
  129. payload={treeViewToolsData}
  130. hasSearchText={hasSearchText}
  131. onSelect={onSelect}
  132. canNotSelectMultiple={canNotSelectMultiple}
  133. onSelectMultiple={onSelectMultiple}
  134. selectedTools={selectedTools}
  135. canChooseMCPTool={canChooseMCPTool}
  136. />
  137. )
  138. )}
  139. </div>
  140. )
  141. }
  142. export default memo(Blocks)