diff --git a/web/app/components/header/account-setting/index.tsx b/web/app/components/header/account-setting/index.tsx
index c530d3268f..9df7065733 100644
--- a/web/app/components/header/account-setting/index.tsx
+++ b/web/app/components/header/account-setting/index.tsx
@@ -199,13 +199,13 @@ export default function AccountSetting({
)}
+ {activeMenu === 'provider' &&
}
{activeMenu === 'members' &&
}
{activeMenu === 'billing' &&
}
- {activeMenu === 'language' &&
}
- {activeMenu === 'provider' &&
}
{activeMenu === 'data-source' &&
}
{activeMenu === 'api-based-extension' &&
}
{activeMenu === 'custom' &&
}
+ {activeMenu === 'language' &&
}
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 e3542bc327..87f7c25b9c 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,13 +1,13 @@
-import { useMemo, useState } from 'react'
+import { useEffect, useMemo, useState } from 'react'
import { useTranslation } from 'react-i18next'
import Link from 'next/link'
+import { useDebounce } from 'ahooks'
import {
RiAlertFill,
RiArrowDownSLine,
RiArrowRightUpLine,
RiBrainLine,
} from '@remixicon/react'
-import { useContext } from 'use-context-selector'
import SystemModelSelector from './system-model-selector'
import ProviderAddedCard, { UPDATE_MODEL_PROVIDER_CUSTOM_MODEL_LIST } from './provider-added-card'
// import ProviderCard from './provider-card'
@@ -26,16 +26,23 @@ import {
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 I18n from '@/context/i18n'
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 cn from '@/utils/classnames'
-import { extensionDallE, modelGPT4, toolNotion } from '@/app/components/plugins/card/card-mock'
+type Props = {
+ searchText: string
+}
-const ModelProviderPage = () => {
+const ModelProviderPage = ({ searchText }: Props) => {
+ const debouncedSearchText = useDebounce(searchText, { wait: 500 })
const { t } = useTranslation()
const { eventEmitter } = useEventEmitterContextContext()
const updateModelProviders = useUpdateModelProviders()
@@ -67,6 +74,18 @@ const ModelProviderPage = () => {
return [configuredProviders, notConfiguredProviders]
}, [providers])
+ const [filteredConfiguredProviders, filteredNotConfiguredProviders] = useMemo(() => {
+ const filteredConfiguredProviders = configuredProviders.filter(
+ provider => provider.provider.toLowerCase().includes(debouncedSearchText.toLowerCase())
+ || Object.values(provider.label).some(text => text.toLowerCase().includes(debouncedSearchText.toLowerCase())),
+ )
+ const filteredNotConfiguredProviders = notConfiguredProviders.filter(
+ provider => provider.provider.toLowerCase().includes(debouncedSearchText.toLowerCase())
+ || Object.values(provider.label).some(text => text.toLowerCase().includes(debouncedSearchText.toLowerCase())),
+ )
+
+ return [filteredConfiguredProviders, filteredNotConfiguredProviders]
+ }, [configuredProviders, debouncedSearchText, notConfiguredProviders])
const handleOpenModal = (
provider: ModelProvider,
@@ -102,10 +121,28 @@ const ModelProviderPage = () => {
}
const [collapse, setCollapse] = useState(false)
- const { locale } = useContext(I18n)
- // TODO #Plugin list API#
- const pluginList = [toolNotion, extensionDallE, modelGPT4]
+ const {
+ plugins,
+ queryPlugins,
+ queryPluginsWithDebounced,
+ isLoading: isPluginsLoading,
+ } = useMarketplacePlugins()
+
+ useEffect(() => {
+ if (searchText) {
+ queryPluginsWithDebounced({
+ query: searchText,
+ category: PluginType.model,
+ })
+ }
+ else {
+ queryPlugins({
+ query: searchText,
+ category: PluginType.model,
+ })
+ }
+ }, [queryPlugins, queryPluginsWithDebounced, searchText])
return (
@@ -132,7 +169,7 @@ const ModelProviderPage = () => {
/>
- {!configuredProviders?.length && (
+ {!filteredConfiguredProviders?.length && (
@@ -141,9 +178,9 @@ const ModelProviderPage = () => {
{t('common.modelProvider.emptyProviderTip')}
)}
- {!!configuredProviders?.length && (
+ {!!filteredConfiguredProviders?.length && (
- {configuredProviders?.map(provider => (
+ {filteredConfiguredProviders?.map(provider => (
{
))}
)}
- {false && !!notConfiguredProviders?.length && (
+ {!!filteredNotConfiguredProviders?.length && (
<>
{t('common.modelProvider.configureRequired')}
- {notConfiguredProviders?.map(provider => (
+ {filteredNotConfiguredProviders?.map(provider => (
{
- {!collapse && (
+ {!collapse && !isPluginsLoading && (
- {pluginList.map((plugin, index) => (
+ {plugins.map((plugin, index) => (
))}
)}
+ {!collapse && isPluginsLoading && }
)
diff --git a/web/app/components/header/account-setting/model-provider-page/system-model-selector/index.tsx b/web/app/components/header/account-setting/model-provider-page/system-model-selector/index.tsx
index d125bd99fb..578fcbe716 100644
--- a/web/app/components/header/account-setting/model-provider-page/system-model-selector/index.tsx
+++ b/web/app/components/header/account-setting/model-provider-page/system-model-selector/index.tsx
@@ -132,6 +132,7 @@ const SystemModel: FC = ({
>
setOpen(v => !v)}>