Yeuoly b76e17b25d
feat: introduce trigger functionality (#27644)
Signed-off-by: lyzno1 <yuanyouhuilyz@gmail.com>
Co-authored-by: Stream <Stream_2@qq.com>
Co-authored-by: lyzno1 <92089059+lyzno1@users.noreply.github.com>
Co-authored-by: zhsama <torvalds@linux.do>
Co-authored-by: Harry <xh001x@hotmail.com>
Co-authored-by: lyzno1 <yuanyouhuilyz@gmail.com>
Co-authored-by: yessenia <yessenia.contact@gmail.com>
Co-authored-by: hjlarry <hjlarry@163.com>
Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com>
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
Co-authored-by: WTW0313 <twwu@dify.ai>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-11-12 17:59:37 +08:00

127 lines
4.1 KiB
TypeScript

import {
useCallback,
useEffect,
useMemo,
useRef,
} from 'react'
import { BlockEnum } from '../types'
import type {
OnSelectBlock,
ToolWithProvider,
} from '../types'
import type { DataSourceDefaultValue, ToolDefaultValue } from './types'
import Tools from './tools'
import { ViewType } from './view-type-select'
import cn from '@/utils/classnames'
import PluginList, { type ListRef } from '@/app/components/workflow/block-selector/market-place-plugin/list'
import { useGlobalPublicStore } from '@/context/global-public-context'
import { DEFAULT_FILE_EXTENSIONS_IN_LOCAL_FILE_DATA_SOURCE } from './constants'
import { useMarketplacePlugins } from '../../plugins/marketplace/hooks'
import { PluginCategoryEnum } from '../../plugins/types'
import { useGetLanguage } from '@/context/i18n'
type AllToolsProps = {
className?: string
toolContentClassName?: string
searchText: string
onSelect: OnSelectBlock
dataSources: ToolWithProvider[]
}
const DataSources = ({
className,
toolContentClassName,
searchText,
onSelect,
dataSources,
}: AllToolsProps) => {
const language = useGetLanguage()
const pluginRef = useRef<ListRef>(null)
const wrapElemRef = useRef<HTMLDivElement>(null)
const isMatchingKeywords = (text: string, keywords: string) => {
return text.toLowerCase().includes(keywords.toLowerCase())
}
const filteredDatasources = useMemo(() => {
const hasFilter = searchText
if (!hasFilter)
return dataSources.filter(toolWithProvider => toolWithProvider.tools.length > 0)
return dataSources.filter((toolWithProvider) => {
return isMatchingKeywords(toolWithProvider.name, searchText) || toolWithProvider.tools.some((tool) => {
return tool.label[language].toLowerCase().includes(searchText.toLowerCase()) || tool.name.toLowerCase().includes(searchText.toLowerCase())
})
})
}, [searchText, dataSources, language])
const handleSelect = useCallback((_: BlockEnum, toolDefaultValue: ToolDefaultValue) => {
let defaultValue: DataSourceDefaultValue = {
plugin_id: toolDefaultValue?.provider_id,
provider_type: toolDefaultValue?.provider_type,
provider_name: toolDefaultValue?.provider_name,
datasource_name: toolDefaultValue?.tool_name,
datasource_label: toolDefaultValue?.tool_label,
title: toolDefaultValue?.title,
plugin_unique_identifier: toolDefaultValue?.plugin_unique_identifier,
}
// Update defaultValue with fileExtensions if this is the local file data source
if (toolDefaultValue?.provider_id === 'langgenius/file' && toolDefaultValue?.provider_name === 'file') {
defaultValue = {
...defaultValue,
fileExtensions: DEFAULT_FILE_EXTENSIONS_IN_LOCAL_FILE_DATA_SOURCE,
}
}
onSelect(BlockEnum.DataSource, toolDefaultValue && defaultValue)
}, [onSelect])
const { enable_marketplace } = useGlobalPublicStore(s => s.systemFeatures)
const {
queryPluginsWithDebounced: fetchPlugins,
plugins: notInstalledPlugins = [],
} = useMarketplacePlugins()
useEffect(() => {
if (!enable_marketplace) return
if (searchText) {
fetchPlugins({
query: searchText,
category: PluginCategoryEnum.datasource,
})
}
}, [searchText, enable_marketplace])
return (
<div className={cn('w-[400px] min-w-0 max-w-full', className)}>
<div
ref={wrapElemRef}
className='max-h-[464px] overflow-y-auto overflow-x-hidden'
onScroll={pluginRef.current?.handleScroll}
>
<Tools
className={toolContentClassName}
tools={filteredDatasources}
onSelect={handleSelect as OnSelectBlock}
viewType={ViewType.flat}
hasSearchText={!!searchText}
canNotSelectMultiple
/>
{/* Plugins from marketplace */}
{enable_marketplace && (
<PluginList
ref={pluginRef}
wrapElemRef={wrapElemRef}
list={notInstalledPlugins}
tags={[]}
searchText={searchText}
toolContentClassName={toolContentClassName}
/>
)}
</div>
</div>
)
}
export default DataSources