From 37eee7be24d8c3a3f585d994a43b434d33e4ff29 Mon Sep 17 00:00:00 2001 From: StyleZhang Date: Thu, 28 Nov 2024 11:26:24 +0800 Subject: [PATCH] fix: model provider page marketplace --- .../model-provider-page/hooks.ts | 50 ++++++++++++++++ .../model-provider-page/index.tsx | 60 +++++++++---------- .../plugins/marketplace/list/index.tsx | 33 +++++++--- .../marketplace/list/list-with-collection.tsx | 31 +++++++--- 4 files changed, 125 insertions(+), 49 deletions(-) diff --git a/web/app/components/header/account-setting/model-provider-page/hooks.ts b/web/app/components/header/account-setting/model-provider-page/hooks.ts index 54396cc538..7d1d2b6877 100644 --- a/web/app/components/header/account-setting/model-provider-page/hooks.ts +++ b/web/app/components/header/account-setting/model-provider-page/hooks.ts @@ -11,6 +11,7 @@ import type { DefaultModel, DefaultModelResponse, Model, + ModelProvider, ModelTypeEnum, } from './declarations' import { @@ -26,6 +27,12 @@ import { getPayUrl, } from '@/service/common' 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 = ( defaultModel: DefaultModelResponse | undefined, @@ -233,3 +240,46 @@ export const useUpdateModelProviders = () => { 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'), + } +} diff --git a/web/app/components/header/account-setting/model-provider-page/index.tsx b/web/app/components/header/account-setting/model-provider-page/index.tsx index 7faf3f3de7..8eea7d3472 100644 --- a/web/app/components/header/account-setting/model-provider-page/index.tsx +++ b/web/app/components/header/account-setting/model-provider-page/index.tsx @@ -1,4 +1,4 @@ -import { useEffect, useMemo, useState } from 'react' +import { useCallback, useMemo, useState } from 'react' import { useTranslation } from 'react-i18next' import Link from 'next/link' import { useDebounce } from 'ahooks' @@ -21,21 +21,21 @@ import { } from './declarations' import { useDefaultModel, + useMarketplace, useUpdateModelList, useUpdateModelProviders, } from './hooks' import Divider from '@/app/components/base/divider' import Loading from '@/app/components/base/loading' import ProviderCard from '@/app/components/plugins/provider-card' +import List from '@/app/components/plugins/marketplace/list' import { useProviderContext } from '@/context/provider-context' import { useModalContextSelector } from '@/context/modal-context' import { useEventEmitterContextContext } from '@/context/event-emitter' -import { - useMarketplacePlugins, -} from '@/app/components/plugins/marketplace/hooks' -import { PluginType } from '@/app/components/plugins/types' +import type { Plugin } from '@/app/components/plugins/types' import { MARKETPLACE_URL_PREFIX } from '@/config' import cn from '@/utils/classnames' +import { getLocaleOnClient } from '@/i18n' type Props = { searchText: string @@ -121,28 +121,20 @@ const ModelProviderPage = ({ searchText }: Props) => { } const [collapse, setCollapse] = useState(false) - + const locale = getLocaleOnClient() const { - plugins = [], - queryPlugins, - queryPluginsWithDebounced, + plugins, + marketplaceCollections, + marketplaceCollectionPluginsMap, isLoading: isPluginsLoading, - } = useMarketplacePlugins() + } = useMarketplace(providers, searchText) - useEffect(() => { - if (searchText) { - queryPluginsWithDebounced({ - query: searchText, - category: PluginType.model, - }) - } - else { - queryPlugins({ - query: searchText, - category: PluginType.model, - }) - } - }, [queryPlugins, queryPluginsWithDebounced, searchText]) + const cardRender = useCallback((plugin: Plugin) => { + if (plugin.type === 'bundle') + return null + + return + }, []) return (
@@ -219,14 +211,20 @@ const ModelProviderPage = ({ searchText }: Props) => {
- {!collapse && !isPluginsLoading && ( -
- {plugins.map(plugin => ( - - ))} -
- )} {!collapse && isPluginsLoading && } + { + !isPluginsLoading && ( + + ) + } ) diff --git a/web/app/components/plugins/marketplace/list/index.tsx b/web/app/components/plugins/marketplace/list/index.tsx index 9dec49fc70..05abd04653 100644 --- a/web/app/components/plugins/marketplace/list/index.tsx +++ b/web/app/components/plugins/marketplace/list/index.tsx @@ -4,6 +4,7 @@ import type { MarketplaceCollection } from '../types' import ListWithCollection from './list-with-collection' import CardWrapper from './card-wrapper' import Empty from '../empty' +import cn from '@/utils/classnames' type ListProps = { marketplaceCollections: MarketplaceCollection[] @@ -11,6 +12,8 @@ type ListProps = { plugins?: Plugin[] showInstallButton?: boolean locale: string + cardContainerClassName?: string + cardRender?: (plugin: Plugin) => JSX.Element | null } const List = ({ marketplaceCollections, @@ -18,6 +21,8 @@ const List = ({ plugins, showInstallButton, locale, + cardContainerClassName, + cardRender, }: ListProps) => { return ( <> @@ -28,21 +33,31 @@ const List = ({ marketplaceCollectionPluginsMap={marketplaceCollectionPluginsMap} showInstallButton={showInstallButton} locale={locale} + cardContainerClassName={cardContainerClassName} + cardRender={cardRender} /> ) } { plugins && !!plugins.length && ( -
+
{ - plugins.map(plugin => ( - - )) + plugins.map((plugin) => { + if (cardRender) + return cardRender(plugin) + + return ( + + ) + }) }
) diff --git a/web/app/components/plugins/marketplace/list/list-with-collection.tsx b/web/app/components/plugins/marketplace/list/list-with-collection.tsx index f60e056ed2..512a34c383 100644 --- a/web/app/components/plugins/marketplace/list/list-with-collection.tsx +++ b/web/app/components/plugins/marketplace/list/list-with-collection.tsx @@ -3,18 +3,23 @@ import type { MarketplaceCollection } from '../types' import CardWrapper from './card-wrapper' import type { Plugin } from '@/app/components/plugins/types' import { getLanguage } from '@/i18n/language' +import cn from '@/utils/classnames' type ListWithCollectionProps = { marketplaceCollections: MarketplaceCollection[] marketplaceCollectionPluginsMap: Record showInstallButton?: boolean locale: string + cardContainerClassName?: string + cardRender?: (plugin: Plugin) => JSX.Element | null } const ListWithCollection = ({ marketplaceCollections, marketplaceCollectionPluginsMap, showInstallButton, locale, + cardContainerClassName, + cardRender, }: ListWithCollectionProps) => { return ( <> @@ -26,16 +31,24 @@ const ListWithCollection = ({ >
{collection.label[getLanguage(locale)]}
{collection.description[getLanguage(locale)]}
-
+
{ - marketplaceCollectionPluginsMap[collection.name].map(plugin => ( - - )) + marketplaceCollectionPluginsMap[collection.name].map((plugin) => { + if (cardRender) + return cardRender(plugin) + + return ( + + ) + }) }