fix: tool list

pull/12372/head
StyleZhang 1 year ago
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…
Cancel
Save