fix: model provider page marketplace

pull/12372/head
StyleZhang 1 year ago
parent 99942b26e6
commit 37eee7be24

@ -11,6 +11,7 @@ import type {
DefaultModel, DefaultModel,
DefaultModelResponse, DefaultModelResponse,
Model, Model,
ModelProvider,
ModelTypeEnum, ModelTypeEnum,
} from './declarations' } from './declarations'
import { import {
@ -26,6 +27,12 @@ import {
getPayUrl, getPayUrl,
} from '@/service/common' } from '@/service/common'
import { useProviderContext } from '@/context/provider-context' import { useProviderContext } from '@/context/provider-context'
import {
useMarketplaceCollectionsAndPlugins,
useMarketplacePlugins,
} from '@/app/components/plugins/marketplace/hooks'
import { PluginType } from '@/app/components/plugins/types'
import { getMarketplaceListCondition } from '@/app/components/plugins/marketplace/utils'
type UseDefaultModelAndModelList = ( type UseDefaultModelAndModelList = (
defaultModel: DefaultModelResponse | undefined, defaultModel: DefaultModelResponse | undefined,
@ -233,3 +240,46 @@ export const useUpdateModelProviders = () => {
return updateModelProviders return updateModelProviders
} }
export const useMarketplace = (providers: ModelProvider[], searchText: string) => {
const exclude = useMemo(() => {
return providers.map(provider => provider.provider.replace(/(.+)\/([^/]+)$/, '$1'))
}, [providers])
const {
isLoading,
marketplaceCollections,
marketplaceCollectionPluginsMap,
queryMarketplaceCollectionsAndPlugins,
} = useMarketplaceCollectionsAndPlugins()
const {
plugins,
resetPlugins,
queryPluginsWithDebounced,
isLoading: isPluginsLoading,
} = useMarketplacePlugins()
useEffect(() => {
if (searchText) {
queryPluginsWithDebounced({
query: searchText,
category: PluginType.model,
exclude,
})
}
else {
queryMarketplaceCollectionsAndPlugins({
category: PluginType.model,
condition: getMarketplaceListCondition(PluginType.model),
exclude,
})
resetPlugins()
}
}, [searchText, queryMarketplaceCollectionsAndPlugins, queryPluginsWithDebounced, resetPlugins, exclude])
return {
isLoading: isLoading || isPluginsLoading,
marketplaceCollections,
marketplaceCollectionPluginsMap,
plugins: plugins?.filter(plugin => plugin.type !== 'bundle'),
}
}

@ -1,4 +1,4 @@
import { useEffect, useMemo, useState } from 'react' import { useCallback, useMemo, useState } from 'react'
import { useTranslation } from 'react-i18next' import { useTranslation } from 'react-i18next'
import Link from 'next/link' import Link from 'next/link'
import { useDebounce } from 'ahooks' import { useDebounce } from 'ahooks'
@ -21,21 +21,21 @@ import {
} from './declarations' } from './declarations'
import { import {
useDefaultModel, useDefaultModel,
useMarketplace,
useUpdateModelList, useUpdateModelList,
useUpdateModelProviders, useUpdateModelProviders,
} from './hooks' } from './hooks'
import Divider from '@/app/components/base/divider' import Divider from '@/app/components/base/divider'
import Loading from '@/app/components/base/loading' import Loading from '@/app/components/base/loading'
import ProviderCard from '@/app/components/plugins/provider-card' import ProviderCard from '@/app/components/plugins/provider-card'
import List from '@/app/components/plugins/marketplace/list'
import { useProviderContext } from '@/context/provider-context' import { useProviderContext } from '@/context/provider-context'
import { useModalContextSelector } from '@/context/modal-context' import { useModalContextSelector } from '@/context/modal-context'
import { useEventEmitterContextContext } from '@/context/event-emitter' import { useEventEmitterContextContext } from '@/context/event-emitter'
import { import type { Plugin } from '@/app/components/plugins/types'
useMarketplacePlugins,
} from '@/app/components/plugins/marketplace/hooks'
import { PluginType } from '@/app/components/plugins/types'
import { MARKETPLACE_URL_PREFIX } from '@/config' import { MARKETPLACE_URL_PREFIX } from '@/config'
import cn from '@/utils/classnames' import cn from '@/utils/classnames'
import { getLocaleOnClient } from '@/i18n'
type Props = { type Props = {
searchText: string searchText: string
@ -121,28 +121,20 @@ const ModelProviderPage = ({ searchText }: Props) => {
} }
const [collapse, setCollapse] = useState(false) const [collapse, setCollapse] = useState(false)
const locale = getLocaleOnClient()
const { const {
plugins = [], plugins,
queryPlugins, marketplaceCollections,
queryPluginsWithDebounced, marketplaceCollectionPluginsMap,
isLoading: isPluginsLoading, isLoading: isPluginsLoading,
} = useMarketplacePlugins() } = useMarketplace(providers, searchText)
useEffect(() => { const cardRender = useCallback((plugin: Plugin) => {
if (searchText) { if (plugin.type === 'bundle')
queryPluginsWithDebounced({ return null
query: searchText,
category: PluginType.model, return <ProviderCard key={plugin.plugin_id} payload={plugin} />
}) }, [])
}
else {
queryPlugins({
query: searchText,
category: PluginType.model,
})
}
}, [queryPlugins, queryPluginsWithDebounced, searchText])
return ( return (
<div className='relative pt-1 -mt-2'> <div className='relative pt-1 -mt-2'>
@ -219,14 +211,20 @@ const ModelProviderPage = ({ searchText }: Props) => {
</Link> </Link>
</div> </div>
</div> </div>
{!collapse && !isPluginsLoading && (
<div className='grid grid-cols-2 gap-2'>
{plugins.map(plugin => (
<ProviderCard key={plugin.plugin_id} payload={plugin} />
))}
</div>
)}
{!collapse && isPluginsLoading && <Loading type='area' />} {!collapse && isPluginsLoading && <Loading type='area' />}
{
!isPluginsLoading && (
<List
marketplaceCollections={marketplaceCollections || []}
marketplaceCollectionPluginsMap={marketplaceCollectionPluginsMap || {}}
plugins={plugins}
showInstallButton
locale={locale}
cardContainerClassName='grid grid-cols-2 gap-2'
cardRender={cardRender}
/>
)
}
</div> </div>
</div> </div>
) )

@ -4,6 +4,7 @@ import type { MarketplaceCollection } from '../types'
import ListWithCollection from './list-with-collection' import ListWithCollection from './list-with-collection'
import CardWrapper from './card-wrapper' import CardWrapper from './card-wrapper'
import Empty from '../empty' import Empty from '../empty'
import cn from '@/utils/classnames'
type ListProps = { type ListProps = {
marketplaceCollections: MarketplaceCollection[] marketplaceCollections: MarketplaceCollection[]
@ -11,6 +12,8 @@ type ListProps = {
plugins?: Plugin[] plugins?: Plugin[]
showInstallButton?: boolean showInstallButton?: boolean
locale: string locale: string
cardContainerClassName?: string
cardRender?: (plugin: Plugin) => JSX.Element | null
} }
const List = ({ const List = ({
marketplaceCollections, marketplaceCollections,
@ -18,6 +21,8 @@ const List = ({
plugins, plugins,
showInstallButton, showInstallButton,
locale, locale,
cardContainerClassName,
cardRender,
}: ListProps) => { }: ListProps) => {
return ( return (
<> <>
@ -28,21 +33,31 @@ const List = ({
marketplaceCollectionPluginsMap={marketplaceCollectionPluginsMap} marketplaceCollectionPluginsMap={marketplaceCollectionPluginsMap}
showInstallButton={showInstallButton} showInstallButton={showInstallButton}
locale={locale} locale={locale}
cardContainerClassName={cardContainerClassName}
cardRender={cardRender}
/> />
) )
} }
{ {
plugins && !!plugins.length && ( plugins && !!plugins.length && (
<div className='grid grid-cols-4 gap-3'> <div className={cn(
'grid grid-cols-4 gap-3',
cardContainerClassName,
)}>
{ {
plugins.map(plugin => ( plugins.map((plugin) => {
<CardWrapper if (cardRender)
key={plugin.name} return cardRender(plugin)
plugin={plugin}
showInstallButton={showInstallButton} return (
locale={locale} <CardWrapper
/> key={plugin.name}
)) plugin={plugin}
showInstallButton={showInstallButton}
locale={locale}
/>
)
})
} }
</div> </div>
) )

@ -3,18 +3,23 @@ import type { MarketplaceCollection } from '../types'
import CardWrapper from './card-wrapper' import CardWrapper from './card-wrapper'
import type { Plugin } from '@/app/components/plugins/types' import type { Plugin } from '@/app/components/plugins/types'
import { getLanguage } from '@/i18n/language' import { getLanguage } from '@/i18n/language'
import cn from '@/utils/classnames'
type ListWithCollectionProps = { type ListWithCollectionProps = {
marketplaceCollections: MarketplaceCollection[] marketplaceCollections: MarketplaceCollection[]
marketplaceCollectionPluginsMap: Record<string, Plugin[]> marketplaceCollectionPluginsMap: Record<string, Plugin[]>
showInstallButton?: boolean showInstallButton?: boolean
locale: string locale: string
cardContainerClassName?: string
cardRender?: (plugin: Plugin) => JSX.Element | null
} }
const ListWithCollection = ({ const ListWithCollection = ({
marketplaceCollections, marketplaceCollections,
marketplaceCollectionPluginsMap, marketplaceCollectionPluginsMap,
showInstallButton, showInstallButton,
locale, locale,
cardContainerClassName,
cardRender,
}: ListWithCollectionProps) => { }: ListWithCollectionProps) => {
return ( return (
<> <>
@ -26,16 +31,24 @@ const ListWithCollection = ({
> >
<div className='title-xl-semi-bold text-text-primary'>{collection.label[getLanguage(locale)]}</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 className='system-xs-regular text-text-tertiary'>{collection.description[getLanguage(locale)]}</div>
<div className='grid grid-cols-4 gap-3 mt-2'> <div className={cn(
'grid grid-cols-4 gap-3 mt-2',
cardContainerClassName,
)}>
{ {
marketplaceCollectionPluginsMap[collection.name].map(plugin => ( marketplaceCollectionPluginsMap[collection.name].map((plugin) => {
<CardWrapper if (cardRender)
key={plugin.name} return cardRender(plugin)
plugin={plugin}
showInstallButton={showInstallButton} return (
locale={locale} <CardWrapper
/> key={plugin.name}
)) plugin={plugin}
showInstallButton={showInstallButton}
locale={locale}
/>
)
})
} }
</div> </div>
</div> </div>

Loading…
Cancel
Save