diff --git a/web/app/components/plugins/plugin-detail-panel/action-list.tsx b/web/app/components/plugins/plugin-detail-panel/action-list.tsx index 609e7d1306..2d440c2702 100644 --- a/web/app/components/plugins/plugin-detail-panel/action-list.tsx +++ b/web/app/components/plugins/plugin-detail-panel/action-list.tsx @@ -1,6 +1,5 @@ import React, { useState } from 'react' import { useTranslation } from 'react-i18next' -import { usePluginPageContext } from '@/app/components/plugins/plugin-page/context' import { useAppContext } from '@/context/app-context' import Button from '@/app/components/base/button' import Toast from '@/app/components/base/toast' @@ -14,19 +13,25 @@ import { useRemoveProviderCredentials, useUpdateProviderCredentials, } from '@/service/use-tools' +import type { PluginDetail } from '@/app/components/plugins/types' -const ActionList = () => { +type Props = { + detail: PluginDetail +} + +const ActionList = ({ + detail, +}: Props) => { const { t } = useTranslation() const { isCurrentWorkspaceManager } = useAppContext() - const currentPluginDetail = usePluginPageContext(v => v.currentPluginDetail) - const { data: provider } = useBuiltinProviderInfo(`${currentPluginDetail.plugin_id}/${currentPluginDetail.name}`) + const { data: provider } = useBuiltinProviderInfo(`${detail.plugin_id}/${detail.name}`) const invalidateProviderInfo = useInvalidateBuiltinProviderInfo() - const { data } = useBuiltinTools(`${currentPluginDetail.plugin_id}/${currentPluginDetail.name}`) + const { data } = useBuiltinTools(`${detail.plugin_id}/${detail.name}`) const [showSettingAuth, setShowSettingAuth] = useState(false) const handleCredentialSettingUpdate = () => { - invalidateProviderInfo(`${currentPluginDetail.plugin_id}/${currentPluginDetail.name}`) + invalidateProviderInfo(`${detail.plugin_id}/${detail.name}`) Toast.notify({ type: 'success', message: t('common.api.actionSuccess'), @@ -74,7 +79,7 @@ const ActionList = () => {
{data.map(tool => ( { +const EndpointList = ({ detail }: Props) => { const { t } = useTranslation() - const pluginDetail = usePluginPageContext(v => v.currentPluginDetail) - const pluginUniqueID = pluginDetail.plugin_unique_identifier - const declaration = pluginDetail.declaration.endpoint - const { data } = useEndpointList(pluginDetail.plugin_id) + const pluginUniqueID = detail.plugin_unique_identifier + const declaration = detail.declaration.endpoint + const showTopBorder = detail.declaration.tool + const { data } = useEndpointList(detail.plugin_id) const invalidateEndpointList = useInvalidateEndpointList() const [isShowEndpointModal, { @@ -43,7 +43,7 @@ const EndpointList = ({ showTopBorder }: Props) => { const { mutate: createEndpoint } = useCreateEndpoint({ onSuccess: async () => { - await invalidateEndpointList(pluginDetail.plugin_id) + await invalidateEndpointList(detail.plugin_id) hideEndpointModal() }, onError: () => { @@ -101,7 +101,7 @@ const EndpointList = ({ showTopBorder }: Props) => { invalidateEndpointList(pluginDetail.plugin_id)} + handleChange={() => invalidateEndpointList(detail.plugin_id)} /> ))}
diff --git a/web/app/components/plugins/plugin-detail-panel/index.tsx b/web/app/components/plugins/plugin-detail-panel/index.tsx index cda554099b..c9e4213137 100644 --- a/web/app/components/plugins/plugin-detail-panel/index.tsx +++ b/web/app/components/plugins/plugin-detail-panel/index.tsx @@ -7,19 +7,21 @@ import ActionList from './action-list' import ModelList from './model-list' import Drawer from '@/app/components/base/drawer' import { usePluginPageContext } from '@/app/components/plugins/plugin-page/context' +import type { PluginDetail } from '@/app/components/plugins/types' import cn from '@/utils/classnames' type Props = { + detail?: PluginDetail onUpdate: () => void } const PluginDetailPanel: FC = ({ + detail, onUpdate, }) => { - const pluginDetail = usePluginPageContext(v => v.currentPluginDetail) - const setCurrentPluginDetail = usePluginPageContext(v => v.setCurrentPluginDetail) + const setCurrentPluginID = usePluginPageContext(v => v.setCurrentPluginID) - const handleHide = () => setCurrentPluginDetail(undefined) + const handleHide = () => setCurrentPluginID(undefined) const handleUpdate = (isDelete = false) => { if (isDelete) @@ -27,12 +29,12 @@ const PluginDetailPanel: FC = ({ onUpdate() } - if (!pluginDetail) + if (!detail) return null return ( = ({ positionCenter={false} panelClassname={cn('justify-start mt-[64px] mr-2 mb-2 !w-[420px] !max-w-[420px] !p-0 !bg-components-panel-bg rounded-2xl border-[0.5px] border-components-panel-border shadow-xl')} > - {pluginDetail && ( + {detail && ( <>
- {!!pluginDetail.declaration.tool && } - {!!pluginDetail.declaration.endpoint && } - {!!pluginDetail.declaration.model && } + {!!detail.declaration.tool && } + {!!detail.declaration.endpoint && } + {!!detail.declaration.model && }
)} diff --git a/web/app/components/plugins/plugin-detail-panel/model-list.tsx b/web/app/components/plugins/plugin-detail-panel/model-list.tsx index 7592126867..5989a75945 100644 --- a/web/app/components/plugins/plugin-detail-panel/model-list.tsx +++ b/web/app/components/plugins/plugin-detail-panel/model-list.tsx @@ -1,14 +1,19 @@ import React from 'react' import { useTranslation } from 'react-i18next' -import { usePluginPageContext } from '@/app/components/plugins/plugin-page/context' import ModelIcon from '@/app/components/header/account-setting/model-provider-page/model-icon' import ModelName from '@/app/components/header/account-setting/model-provider-page/model-name' import { useModelProviderModelList } from '@/service/use-models' +import type { PluginDetail } from '@/app/components/plugins/types' -const ModelList = () => { +type Props = { + detail: PluginDetail +} + +const ModelList = ({ + detail, +}: Props) => { const { t } = useTranslation() - const currentPluginDetail = usePluginPageContext(v => v.currentPluginDetail) - const { data: res } = useModelProviderModelList(`${currentPluginDetail.plugin_id}/${currentPluginDetail.name}`) + const { data: res } = useModelProviderModelList(`${detail.plugin_id}/${detail.name}`) if (!res) return null diff --git a/web/app/components/plugins/plugin-item/index.tsx b/web/app/components/plugins/plugin-item/index.tsx index 13c8797358..d8bc72c158 100644 --- a/web/app/components/plugins/plugin-item/index.tsx +++ b/web/app/components/plugins/plugin-item/index.tsx @@ -37,8 +37,8 @@ const PluginItem: FC = ({ const locale = useLanguage() const { t } = useTranslation() const { categoriesMap } = useCategories() - const currentPluginDetail = usePluginPageContext(v => v.currentPluginDetail) - const setCurrentPluginDetail = usePluginPageContext(v => v.setCurrentPluginDetail) + const currentPluginID = usePluginPageContext(v => v.currentPluginID) + const setCurrentPluginID = usePluginPageContext(v => v.setCurrentPluginID) const invalidateInstalledPluginList = useInvalidateInstalledPluginList() const { refreshModelProviders } = useProviderContext() @@ -66,13 +66,13 @@ const PluginItem: FC = ({
{ - setCurrentPluginDetail(plugin) + setCurrentPluginID(plugin.plugin_id) }} >
diff --git a/web/app/components/plugins/plugin-page/context.tsx b/web/app/components/plugins/plugin-page/context.tsx index e9e66849e9..6363bcae69 100644 --- a/web/app/components/plugins/plugin-page/context.tsx +++ b/web/app/components/plugins/plugin-page/context.tsx @@ -11,15 +11,14 @@ import { useContextSelector, } from 'use-context-selector' import { useSelector as useAppContextSelector } from '@/context/app-context' -import type { PluginDetail } from '../types' import type { FilterState } from './filter-management' import { useTranslation } from 'react-i18next' import { useTabSearchParams } from '@/hooks/use-tab-searchparams' export type PluginPageContextValue = { containerRef: React.RefObject - currentPluginDetail: PluginDetail | undefined - setCurrentPluginDetail: (plugin: PluginDetail) => void + currentPluginID: string | undefined + setCurrentPluginID: (pluginID?: string) => void filters: FilterState setFilters: (filter: FilterState) => void activeTab: string @@ -29,8 +28,8 @@ export type PluginPageContextValue = { export const PluginPageContext = createContext({ containerRef: { current: null }, - currentPluginDetail: undefined, - setCurrentPluginDetail: () => { }, + currentPluginID: undefined, + setCurrentPluginID: () => { }, filters: { categories: [], tags: [], @@ -60,7 +59,7 @@ export const PluginPageContextProvider = ({ tags: [], searchQuery: '', }) - const [currentPluginDetail, setCurrentPluginDetail] = useState() + const [currentPluginID, setCurrentPluginID] = useState() const { enable_marketplace } = useAppContextSelector(s => s.systemFeatures) const options = useMemo(() => { @@ -81,8 +80,8 @@ export const PluginPageContextProvider = ({ { const [filters, setFilters] = usePluginPageContext(v => [v.filters, v.setFilters]) as [FilterState, (filter: FilterState) => void] const { data: pluginList, isLoading: isPluginListLoading } = useInstalledPluginList() const invalidateInstalledPluginList = useInvalidateInstalledPluginList() + const currentPluginID = usePluginPageContext(v => v.currentPluginID) const { run: handleFilterChange } = useDebounceFn((filters: FilterState) => { setFilters(filters) @@ -31,6 +32,11 @@ const PluginsPanel = () => { return filteredList }, [pluginList, filters]) + const currentPluginDetail = useMemo(() => { + const detail = pluginList?.plugins.find(plugin => plugin.plugin_id === currentPluginID) + return detail + }, [currentPluginID, pluginList?.plugins]) + return ( <>
@@ -40,7 +46,7 @@ const PluginsPanel = () => { />
{isPluginListLoading ? : (filteredList?.length ?? 0) > 0 ? ( -
+
@@ -48,7 +54,7 @@ const PluginsPanel = () => { ) : ( )} - invalidateInstalledPluginList()}/> + invalidateInstalledPluginList()}/> ) }