diff --git a/web/app/components/plugins/plugin-detail-panel/detail-header.tsx b/web/app/components/plugins/plugin-detail-panel/detail-header.tsx index 5e1b0770f7..2a489d0bf9 100644 --- a/web/app/components/plugins/plugin-detail-panel/detail-header.tsx +++ b/web/app/components/plugins/plugin-detail-panel/detail-header.tsx @@ -9,7 +9,7 @@ import { RiVerifiedBadgeLine, } from '@remixicon/react' import type { PluginDetail } from '../types' -import { PluginSource } from '../types' +import { PluginSource, PluginType } from '../types' import Description from '../card/base/description' import Icon from '../card/base/card-icon' import Title from '../card/base/title' @@ -30,6 +30,7 @@ import { Github } from '@/app/components/base/icons/src/public/common' import { uninstallPlugin } from '@/service/plugins' import { useGetLanguage } from '@/context/i18n' import { useModalContext } from '@/context/modal-context' +import { useProviderContext } from '@/context/provider-context' import { API_PREFIX, MARKETPLACE_URL_PREFIX } from '@/config' import cn from '@/utils/classnames' @@ -38,7 +39,7 @@ const i18nPrefix = 'plugin.action' type Props = { detail: PluginDetail onHide: () => void - onUpdate: () => void + onUpdate: (isDelete?: boolean) => void } const DetailHeader = ({ @@ -50,6 +51,7 @@ const DetailHeader = ({ const locale = useGetLanguage() const { checkForUpdates, fetchReleases } = useGitHubReleases() const { setShowUpdatePluginModal } = useModalContext() + const { refreshModelProviders } = useProviderContext() const { installation_id, @@ -61,7 +63,7 @@ const DetailHeader = ({ meta, plugin_id, } = detail - const { author, name, label, description, icon, verified } = detail.declaration + const { author, category, name, label, description, icon, verified } = detail.declaration const isFromGitHub = source === PluginSource.github const isFromMarketplace = source === PluginSource.marketplace @@ -139,9 +141,11 @@ const DetailHeader = ({ hideDeleting() if (res.success) { hideDeleteConfirm() - onUpdate() + onUpdate(true) + if (category === PluginType.model) + refreshModelProviders() } - }, [hideDeleteConfirm, hideDeleting, installation_id, showDeleting, onUpdate]) + }, [showDeleting, installation_id, hideDeleting, hideDeleteConfirm, onUpdate, category, refreshModelProviders]) // #plugin TODO# used in apps // const usedInApps = 3 diff --git a/web/app/components/plugins/plugin-detail-panel/index.tsx b/web/app/components/plugins/plugin-detail-panel/index.tsx index da8c23a93f..cda554099b 100644 --- a/web/app/components/plugins/plugin-detail-panel/index.tsx +++ b/web/app/components/plugins/plugin-detail-panel/index.tsx @@ -21,6 +21,12 @@ const PluginDetailPanel: FC = ({ const handleHide = () => setCurrentPluginDetail(undefined) + const handleUpdate = (isDelete = false) => { + if (isDelete) + handleHide() + onUpdate() + } + if (!pluginDetail) return null @@ -39,7 +45,7 @@ const PluginDetailPanel: FC = ({
{!!pluginDetail.declaration.tool && } diff --git a/web/app/components/plugins/plugin-item/index.tsx b/web/app/components/plugins/plugin-item/index.tsx index eb833e0781..fa97e2e586 100644 --- a/web/app/components/plugins/plugin-item/index.tsx +++ b/web/app/components/plugins/plugin-item/index.tsx @@ -12,7 +12,7 @@ import { useTranslation } from 'react-i18next' import { usePluginPageContext } from '../plugin-page/context' import { Github } from '../../base/icons/src/public/common' import Badge from '../../base/badge' -import { type PluginDetail, PluginSource } from '../types' +import { type PluginDetail, PluginSource, PluginType } from '../types' import CornerMark from '../card/base/corner-mark' import Description from '../card/base/description' import OrgInfo from '../card/base/org-info' @@ -23,6 +23,7 @@ import { API_PREFIX, MARKETPLACE_URL_PREFIX } from '@/config' import { useLanguage } from '../../header/account-setting/model-provider-page/hooks' import { useInvalidateInstalledPluginList } from '@/service/use-plugins' import { useCategories } from '../hooks' +import { useProviderContext } from '@/context/provider-context' type Props = { className?: string @@ -39,6 +40,7 @@ const PluginItem: FC = ({ const currentPluginDetail = usePluginPageContext(v => v.currentPluginDetail) const setCurrentPluginDetail = usePluginPageContext(v => v.setCurrentPluginDetail) const invalidateInstalledPluginList = useInvalidateInstalledPluginList() + const { refreshModelProviders } = useProviderContext() const { source, @@ -54,6 +56,12 @@ const PluginItem: FC = ({ const orgName = useMemo(() => { return [PluginSource.github, PluginSource.marketplace].includes(source) ? author : '' }, [source, author]) + + const handleDelete = () => { + invalidateInstalledPluginList() + if (category === PluginType.model) + refreshModelProviders() + } return (
= ({ isShowInfo={source === PluginSource.github} isShowDelete meta={meta} - onDelete={() => { - invalidateInstalledPluginList() - }} + onDelete={handleDelete} />
diff --git a/web/context/provider-context.tsx b/web/context/provider-context.tsx index 814792ef0e..83039ca7a0 100644 --- a/web/context/provider-context.tsx +++ b/web/context/provider-context.tsx @@ -21,6 +21,7 @@ import { defaultPlan } from '@/app/components/billing/config' type ProviderContextState = { modelProviders: ModelProvider[] + refreshModelProviders: () => void textGenerationModelList: Model[] supportRetrievalMethods: RETRIEVE_METHOD[] isAPIKeySet: boolean @@ -38,6 +39,7 @@ type ProviderContextState = { } const ProviderContext = createContext({ modelProviders: [], + refreshModelProviders: () => { }, textGenerationModelList: [], supportRetrievalMethods: [], isAPIKeySet: true, @@ -79,7 +81,7 @@ type ProviderContextProviderProps = { export const ProviderContextProvider = ({ children, }: ProviderContextProviderProps) => { - const { data: providersData } = useSWR('/workspaces/current/model-providers', fetchModelProviders) + const { data: providersData, mutate: refreshModelProviders } = useSWR('/workspaces/current/model-providers', fetchModelProviders) const fetchModelListUrlPrefix = '/workspaces/current/models/model-types/' const { data: textGenerationModelList } = useSWR(`${fetchModelListUrlPrefix}${ModelTypeEnum.textGeneration}`, fetchModelList) const { data: supportRetrievalMethods } = useSWR('/datasets/retrieval-setting', fetchSupportRetrievalMethods) @@ -112,6 +114,7 @@ export const ProviderContextProvider = ({ return ( model.status === ModelStatusEnum.active), supportRetrievalMethods: supportRetrievalMethods?.retrieval_method || [],