mirror of
https://github.com/langgenius/dify.git
synced 2026-04-29 04:26:30 +08:00
fix: tool list
This commit is contained in:
parent
d6dea67947
commit
ca3d96e5f4
@ -218,7 +218,7 @@ const ModelProviderPage = ({ searchText }: Props) => {
|
|||||||
</div>
|
</div>
|
||||||
{!collapse && (isPluginsLoading || isAllPluginsLoading) && <Loading type='area' />}
|
{!collapse && (isPluginsLoading || isAllPluginsLoading) && <Loading type='area' />}
|
||||||
{
|
{
|
||||||
!isPluginsLoading && (
|
!isPluginsLoading && !collapse && (
|
||||||
<List
|
<List
|
||||||
marketplaceCollections={marketplaceCollections || []}
|
marketplaceCollections={marketplaceCollections || []}
|
||||||
marketplaceCollectionPluginsMap={marketplaceCollectionPluginsMap || {}}
|
marketplaceCollectionPluginsMap={marketplaceCollectionPluginsMap || {}}
|
||||||
@ -231,7 +231,7 @@ const ModelProviderPage = ({ searchText }: Props) => {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
!isAllPluginsLoading && (
|
!isAllPluginsLoading && !collapse && (
|
||||||
<List
|
<List
|
||||||
marketplaceCollections={[]}
|
marketplaceCollections={[]}
|
||||||
marketplaceCollectionPluginsMap={{}}
|
marketplaceCollectionPluginsMap={{}}
|
||||||
|
|||||||
@ -29,20 +29,24 @@ const Empty = ({
|
|||||||
'mr-3 mb-3 h-[144px] w-[calc((100%-36px)/4)] rounded-xl bg-background-section-burn',
|
'mr-3 mb-3 h-[144px] w-[calc((100%-36px)/4)] rounded-xl bg-background-section-burn',
|
||||||
index % 4 === 3 && 'mr-0',
|
index % 4 === 3 && 'mr-0',
|
||||||
index > 11 && 'mb-0',
|
index > 11 && 'mb-0',
|
||||||
lightCard && 'bg-background-default-lighter',
|
lightCard && 'bg-background-default-lighter opacity-75',
|
||||||
)}
|
)}
|
||||||
>
|
>
|
||||||
</div>
|
</div>
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
<div
|
{
|
||||||
className='absolute inset-0 bg-marketplace-plugin-empty z-[1]'
|
!lightCard && (
|
||||||
></div>
|
<div
|
||||||
|
className='absolute inset-0 bg-marketplace-plugin-empty z-[1]'
|
||||||
|
></div>
|
||||||
|
)
|
||||||
|
}
|
||||||
<div className='absolute top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2 z-[2] flex flex-col items-center'>
|
<div className='absolute top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2 z-[2] flex flex-col items-center'>
|
||||||
<div className='relative flex items-center justify-center mb-3 w-14 h-14 rounded-xl border border-dashed border-divider-deep bg-components-card-bg shadow-lg'>
|
<div className='relative flex items-center justify-center mb-3 w-14 h-14 rounded-xl border border-dashed border-divider-deep bg-components-card-bg shadow-lg'>
|
||||||
<Group className='w-5 h-5' />
|
<Group className='w-5 h-5' />
|
||||||
<Line className='absolute -right-[1px] top-1/2 -translate-y-1/2' />
|
<Line className='absolute right-[-1px] top-1/2 -translate-y-1/2' />
|
||||||
<Line className='absolute -left-[1px] top-1/2 -translate-y-1/2' />
|
<Line className='absolute left-[-1px] top-1/2 -translate-y-1/2' />
|
||||||
<Line className='absolute top-0 left-1/2 -translate-x-1/2 -translate-y-1/2 rotate-90' />
|
<Line className='absolute top-0 left-1/2 -translate-x-1/2 -translate-y-1/2 rotate-90' />
|
||||||
<Line className='absolute top-full left-1/2 -translate-x-1/2 -translate-y-1/2 rotate-90' />
|
<Line className='absolute top-full left-1/2 -translate-x-1/2 -translate-y-1/2 rotate-90' />
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -14,6 +14,7 @@ type ListProps = {
|
|||||||
locale: string
|
locale: string
|
||||||
cardContainerClassName?: string
|
cardContainerClassName?: string
|
||||||
cardRender?: (plugin: Plugin) => JSX.Element | null
|
cardRender?: (plugin: Plugin) => JSX.Element | null
|
||||||
|
onMoreClick?: () => void
|
||||||
}
|
}
|
||||||
const List = ({
|
const List = ({
|
||||||
marketplaceCollections,
|
marketplaceCollections,
|
||||||
@ -23,6 +24,7 @@ const List = ({
|
|||||||
locale,
|
locale,
|
||||||
cardContainerClassName,
|
cardContainerClassName,
|
||||||
cardRender,
|
cardRender,
|
||||||
|
onMoreClick,
|
||||||
}: ListProps) => {
|
}: ListProps) => {
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
@ -35,6 +37,7 @@ const List = ({
|
|||||||
locale={locale}
|
locale={locale}
|
||||||
cardContainerClassName={cardContainerClassName}
|
cardContainerClassName={cardContainerClassName}
|
||||||
cardRender={cardRender}
|
cardRender={cardRender}
|
||||||
|
onMoreClick={onMoreClick}
|
||||||
/>
|
/>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -12,6 +12,7 @@ type ListWithCollectionProps = {
|
|||||||
locale: string
|
locale: string
|
||||||
cardContainerClassName?: string
|
cardContainerClassName?: string
|
||||||
cardRender?: (plugin: Plugin) => JSX.Element | null
|
cardRender?: (plugin: Plugin) => JSX.Element | null
|
||||||
|
onMoreClick?: () => void
|
||||||
}
|
}
|
||||||
const ListWithCollection = ({
|
const ListWithCollection = ({
|
||||||
marketplaceCollections,
|
marketplaceCollections,
|
||||||
@ -20,6 +21,7 @@ const ListWithCollection = ({
|
|||||||
locale,
|
locale,
|
||||||
cardContainerClassName,
|
cardContainerClassName,
|
||||||
cardRender,
|
cardRender,
|
||||||
|
// onMoreClick,
|
||||||
}: ListWithCollectionProps) => {
|
}: ListWithCollectionProps) => {
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
@ -29,8 +31,16 @@ const ListWithCollection = ({
|
|||||||
key={collection.name}
|
key={collection.name}
|
||||||
className='py-3'
|
className='py-3'
|
||||||
>
|
>
|
||||||
<div className='title-xl-semi-bold text-text-primary'>{collection.label[getLanguage(locale)]}</div>
|
<div className='flex justify-between'>
|
||||||
<div className='system-xs-regular text-text-tertiary'>{collection.description[getLanguage(locale)]}</div>
|
<div>
|
||||||
|
<div className='title-xl-semi-bold text-text-primary'>{collection.label[getLanguage(locale)]}</div>
|
||||||
|
<div className='system-xs-regular text-text-tertiary'>{collection.description[getLanguage(locale)]}</div>
|
||||||
|
</div>
|
||||||
|
{/* <div
|
||||||
|
className='system-xs-regular text-text-tertiary cursor-pointer hover:underline'
|
||||||
|
onClick={() => onMoreClick?.()}
|
||||||
|
>more</div> */}
|
||||||
|
</div>
|
||||||
<div className={cn(
|
<div className={cn(
|
||||||
'grid grid-cols-4 gap-3 mt-2',
|
'grid grid-cols-4 gap-3 mt-2',
|
||||||
cardContainerClassName,
|
cardContainerClassName,
|
||||||
|
|||||||
@ -1,6 +1,9 @@
|
|||||||
import {
|
import {
|
||||||
|
useCallback,
|
||||||
useEffect,
|
useEffect,
|
||||||
useMemo,
|
useMemo,
|
||||||
|
useRef,
|
||||||
|
useState,
|
||||||
} from 'react'
|
} from 'react'
|
||||||
import {
|
import {
|
||||||
useMarketplaceCollectionsAndPlugins,
|
useMarketplaceCollectionsAndPlugins,
|
||||||
@ -28,10 +31,22 @@ export const useMarketplace = (searchPluginText: string, filterPluginTags: strin
|
|||||||
queryPlugins,
|
queryPlugins,
|
||||||
queryPluginsWithDebounced,
|
queryPluginsWithDebounced,
|
||||||
isLoading: isPluginsLoading,
|
isLoading: isPluginsLoading,
|
||||||
|
total: pluginsTotal,
|
||||||
} = useMarketplacePlugins()
|
} = useMarketplacePlugins()
|
||||||
|
const [page, setPage] = useState(1)
|
||||||
|
const pageRef = useRef(page)
|
||||||
|
const searchPluginTextRef = useRef(searchPluginText)
|
||||||
|
const filterPluginTagsRef = useRef(filterPluginTags)
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
searchPluginTextRef.current = searchPluginText
|
||||||
|
filterPluginTagsRef.current = filterPluginTags
|
||||||
|
}, [searchPluginText, filterPluginTags])
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if ((searchPluginText || filterPluginTags.length) && isSuccess) {
|
if ((searchPluginText || filterPluginTags.length) && isSuccess) {
|
||||||
|
setPage(1)
|
||||||
|
pageRef.current = 1
|
||||||
|
|
||||||
if (searchPluginText) {
|
if (searchPluginText) {
|
||||||
queryPluginsWithDebounced({
|
queryPluginsWithDebounced({
|
||||||
category: PluginType.tool,
|
category: PluginType.tool,
|
||||||
@ -39,6 +54,7 @@ export const useMarketplace = (searchPluginText: string, filterPluginTags: strin
|
|||||||
tags: filterPluginTags,
|
tags: filterPluginTags,
|
||||||
exclude,
|
exclude,
|
||||||
type: 'plugin',
|
type: 'plugin',
|
||||||
|
page: pageRef.current,
|
||||||
})
|
})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -48,6 +64,7 @@ export const useMarketplace = (searchPluginText: string, filterPluginTags: strin
|
|||||||
tags: filterPluginTags,
|
tags: filterPluginTags,
|
||||||
exclude,
|
exclude,
|
||||||
type: 'plugin',
|
type: 'plugin',
|
||||||
|
page: pageRef.current,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@ -63,10 +80,38 @@ export const useMarketplace = (searchPluginText: string, filterPluginTags: strin
|
|||||||
}
|
}
|
||||||
}, [searchPluginText, filterPluginTags, queryPlugins, queryMarketplaceCollectionsAndPlugins, queryPluginsWithDebounced, resetPlugins, exclude, isSuccess])
|
}, [searchPluginText, filterPluginTags, queryPlugins, queryMarketplaceCollectionsAndPlugins, queryPluginsWithDebounced, resetPlugins, exclude, isSuccess])
|
||||||
|
|
||||||
|
const handleScroll = useCallback((e: Event) => {
|
||||||
|
const target = e.target as HTMLDivElement
|
||||||
|
const {
|
||||||
|
scrollTop,
|
||||||
|
scrollHeight,
|
||||||
|
clientHeight,
|
||||||
|
} = target
|
||||||
|
if (scrollTop + clientHeight >= scrollHeight - 5 && scrollTop > 0) {
|
||||||
|
const searchPluginText = searchPluginTextRef.current
|
||||||
|
const filterPluginTags = filterPluginTagsRef.current
|
||||||
|
if (pluginsTotal && plugins && pluginsTotal > plugins.length && (!!searchPluginText || !!filterPluginTags.length)) {
|
||||||
|
setPage(pageRef.current + 1)
|
||||||
|
pageRef.current++
|
||||||
|
|
||||||
|
queryPlugins({
|
||||||
|
category: PluginType.tool,
|
||||||
|
query: searchPluginText,
|
||||||
|
tags: filterPluginTags,
|
||||||
|
exclude,
|
||||||
|
type: 'plugin',
|
||||||
|
page: pageRef.current,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, [exclude, plugins, pluginsTotal, queryPlugins])
|
||||||
|
|
||||||
return {
|
return {
|
||||||
isLoading: isLoading || isPluginsLoading,
|
isLoading: isLoading || isPluginsLoading,
|
||||||
marketplaceCollections,
|
marketplaceCollections,
|
||||||
marketplaceCollectionPluginsMap,
|
marketplaceCollectionPluginsMap,
|
||||||
plugins,
|
plugins,
|
||||||
|
handleScroll,
|
||||||
|
page,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,3 +1,7 @@
|
|||||||
|
import {
|
||||||
|
useEffect,
|
||||||
|
useRef,
|
||||||
|
} from 'react'
|
||||||
import {
|
import {
|
||||||
RiArrowRightUpLine,
|
RiArrowRightUpLine,
|
||||||
RiArrowUpDoubleLine,
|
RiArrowUpDoubleLine,
|
||||||
@ -21,15 +25,33 @@ const Marketplace = ({
|
|||||||
}: MarketplaceProps) => {
|
}: MarketplaceProps) => {
|
||||||
const locale = getLocaleOnClient()
|
const locale = getLocaleOnClient()
|
||||||
const { t } = useTranslation()
|
const { t } = useTranslation()
|
||||||
|
|
||||||
const {
|
const {
|
||||||
isLoading,
|
isLoading,
|
||||||
marketplaceCollections,
|
marketplaceCollections,
|
||||||
marketplaceCollectionPluginsMap,
|
marketplaceCollectionPluginsMap,
|
||||||
plugins,
|
plugins,
|
||||||
|
handleScroll,
|
||||||
|
page,
|
||||||
} = useMarketplace(searchPluginText, filterPluginTags)
|
} = useMarketplace(searchPluginText, filterPluginTags)
|
||||||
|
const containerRef = useRef<HTMLDivElement>(null)
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
const container = containerRef.current
|
||||||
|
if (container)
|
||||||
|
container.addEventListener('scroll', handleScroll)
|
||||||
|
|
||||||
|
return () => {
|
||||||
|
if (container)
|
||||||
|
container.removeEventListener('scroll', handleScroll)
|
||||||
|
}
|
||||||
|
}, [handleScroll])
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className='flex flex-col shrink-0 sticky bottom-[-442px] h-[530px] overflow-y-auto px-12 py-2 pt-0 bg-background-default-subtle'>
|
<div
|
||||||
|
ref={containerRef}
|
||||||
|
className='grow flex flex-col shrink-0 sticky bottom-[-442px] h-[530px] overflow-y-auto px-12 py-2 pt-0 bg-background-default-subtle'
|
||||||
|
>
|
||||||
<RiArrowUpDoubleLine
|
<RiArrowUpDoubleLine
|
||||||
className='absolute top-2 left-1/2 -translate-x-1/2 w-4 h-4 text-text-quaternary cursor-pointer'
|
className='absolute top-2 left-1/2 -translate-x-1/2 w-4 h-4 text-text-quaternary cursor-pointer'
|
||||||
onClick={() => onMarketplaceScroll()}
|
onClick={() => onMarketplaceScroll()}
|
||||||
@ -67,14 +89,14 @@ const Marketplace = ({
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{
|
{
|
||||||
isLoading && (
|
isLoading && page === 1 && (
|
||||||
<div className='absolute top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2'>
|
<div className='absolute top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2'>
|
||||||
<Loading />
|
<Loading />
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
!isLoading && (
|
(!isLoading || page > 1) && (
|
||||||
<List
|
<List
|
||||||
marketplaceCollections={marketplaceCollections || []}
|
marketplaceCollections={marketplaceCollections || []}
|
||||||
marketplaceCollectionPluginsMap={marketplaceCollectionPluginsMap || {}}
|
marketplaceCollectionPluginsMap={marketplaceCollectionPluginsMap || {}}
|
||||||
|
|||||||
@ -95,7 +95,7 @@ const ProviderList = () => {
|
|||||||
</div>
|
</div>
|
||||||
{(filteredCollectionList.length > 0 || activeTab !== 'builtin') && (
|
{(filteredCollectionList.length > 0 || activeTab !== 'builtin') && (
|
||||||
<div className={cn(
|
<div className={cn(
|
||||||
'relative grid content-start grid-cols-1 gap-4 px-12 pt-2 pb-4 sm:grid-cols-2 md:grid-cols-3 lg:grid-cols-4 grow shrink-0',
|
'relative grid content-start grid-cols-1 gap-4 px-12 pt-2 pb-4 sm:grid-cols-2 md:grid-cols-3 lg:grid-cols-4 shrink-0',
|
||||||
)}>
|
)}>
|
||||||
{activeTab === 'api' && <CustomCreateCard onRefreshData={refetch} />}
|
{activeTab === 'api' && <CustomCreateCard onRefreshData={refetch} />}
|
||||||
{filteredCollectionList.map(collection => (
|
{filteredCollectionList.map(collection => (
|
||||||
@ -125,7 +125,7 @@ const ProviderList = () => {
|
|||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
{!filteredCollectionList.length && activeTab === 'builtin' && (
|
{!filteredCollectionList.length && activeTab === 'builtin' && (
|
||||||
<Empty lightCard text={t('tools.noTools')} className='px-12' />
|
<Empty lightCard text={t('tools.noTools')} className='px-12 h-[224px]' />
|
||||||
)}
|
)}
|
||||||
{
|
{
|
||||||
enable_marketplace && activeTab === 'builtin' && (
|
enable_marketplace && activeTab === 'builtin' && (
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user