diff --git a/web/app/components/plugins/card/index.tsx b/web/app/components/plugins/card/index.tsx
index 1cc18ac24f..7f7cc79021 100644
--- a/web/app/components/plugins/card/index.tsx
+++ b/web/app/components/plugins/card/index.tsx
@@ -28,6 +28,7 @@ export type Props = {
isLoading?: boolean
loadingFileName?: string
locale?: string
+ showLimitWarning?: boolean
}
const Card = ({
@@ -42,6 +43,7 @@ const Card = ({
isLoading = false,
loadingFileName,
locale: localeFromProps,
+ showLimitWarning = false,
}: Props) => {
const defaultLocale = useGetLanguage()
const locale = localeFromProps ? getLanguage(localeFromProps) : defaultLocale
@@ -89,6 +91,7 @@ const Card = ({
text={getLocalizedText(brief)}
descriptionLineRows={descriptionLineRows}
/>
+ {showLimitWarning &&
{t('plugin.installModal.installWarning')}
}
{footer && {footer}
}
)
diff --git a/web/app/components/plugins/install-plugin/hooks/use-install-plugin-limit.tsx b/web/app/components/plugins/install-plugin/hooks/use-install-plugin-limit.tsx
new file mode 100644
index 0000000000..6618dceb91
--- /dev/null
+++ b/web/app/components/plugins/install-plugin/hooks/use-install-plugin-limit.tsx
@@ -0,0 +1,39 @@
+import { useGlobalPublicStore } from '@/context/global-public-context'
+import { InstallationScope } from '@/types/feature'
+import type { Plugin, PluginManifestInMarket } from '../../types'
+
+export default function usePluginInstallLimit(plugin: Plugin | PluginManifestInMarket) {
+ const systemFeatures = useGlobalPublicStore(s => s.systemFeatures)
+ if (systemFeatures.plugin_installation_permission.restrict_to_marketplace_only) {
+ return { canInstall: false }
+ }
+ else {
+ if (systemFeatures.plugin_installation_permission.plugin_installation_scope === InstallationScope.ALL) {
+ return {
+ canInstall: true,
+ }
+ }
+ if (systemFeatures.plugin_installation_permission.plugin_installation_scope === InstallationScope.NONE) {
+ return {
+ canInstall: false,
+ }
+ }
+ const verification = plugin.verification
+ if (plugin.verification && !plugin.verification.authorized_category)
+ verification.authorized_category = 'langgenius'
+
+ if (systemFeatures.plugin_installation_permission.plugin_installation_scope === InstallationScope.OFFICIAL_ONLY) {
+ return {
+ canInstall: verification.authorized_category === 'langgenius',
+ }
+ }
+ if (systemFeatures.plugin_installation_permission.plugin_installation_scope === InstallationScope.OFFICIAL_AND_PARTNER) {
+ return {
+ canInstall: verification.authorized_category === 'langgenius' || verification.authorized_category === 'partner',
+ }
+ }
+ return {
+ canInstall: true,
+ }
+ }
+}
diff --git a/web/app/components/plugins/install-plugin/install-from-marketplace/steps/install.tsx b/web/app/components/plugins/install-plugin/install-from-marketplace/steps/install.tsx
index 13d4f88fbc..70a37b27a4 100644
--- a/web/app/components/plugins/install-plugin/install-from-marketplace/steps/install.tsx
+++ b/web/app/components/plugins/install-plugin/install-from-marketplace/steps/install.tsx
@@ -1,6 +1,5 @@
'use client'
import type { FC } from 'react'
-import { useState } from 'react'
import React, { useEffect, useMemo } from 'react'
// import { RiInformation2Line } from '@remixicon/react'
import { type Plugin, type PluginManifestInMarket, TaskStatus } from '../../../types'
@@ -8,7 +7,7 @@ import Card from '../../../card'
import { pluginManifestInMarketToPluginProps } from '../../utils'
import Button from '@/app/components/base/button'
import { useTranslation } from 'react-i18next'
-import { RiLoader2Line, RiProhibitedLine } from '@remixicon/react'
+import { RiLoader2Line } from '@remixicon/react'
import { useInstallPackageFromMarketPlace, usePluginDeclarationFromMarketPlace, useUpdatePackageFromMarketPlace } from '@/service/use-plugins'
import checkTaskStatus from '../../base/check-task-status'
import useCheckInstalled from '@/app/components/plugins/install-plugin/hooks/use-check-installed'
@@ -16,9 +15,7 @@ import Version from '../../base/version'
import { usePluginTaskList } from '@/service/use-plugins'
import { gte } from 'semver'
import { useAppContext } from '@/context/app-context'
-import { useGlobalPublicStore } from '@/context/global-public-context'
-import { isEmpty } from 'lodash-es'
-import { InstallationScope } from '@/types/feature'
+import useInstallPluginLimit from '../../hooks/use-install-plugin-limit'
const i18nPrefix = 'plugin.installModal'
@@ -130,21 +127,7 @@ const Installed: FC = ({
return gte(langeniusVersionInfo.current_version, pluginDeclaration?.manifest.meta.minimum_dify_version ?? '0.0.0')
}, [langeniusVersionInfo.current_version, pluginDeclaration])
- const systemFeatures = useGlobalPublicStore(s => s.systemFeatures)
-
- const [canInstallPlugin, setCanInstallPlugin] = useState(true)
-
- useEffect(() => {
- const verification = (isEmpty(payload.verification) ? { authorized_category: 'langgenius' } : payload.verification) as { authorized_category: string }
- if (systemFeatures.plugin_installation_permission.plugin_installation_scope === InstallationScope.ALL) setCanInstallPlugin(true)
- else if (systemFeatures.plugin_installation_permission.plugin_installation_scope === InstallationScope.NONE) setCanInstallPlugin(false)
- else if (systemFeatures.plugin_installation_permission.plugin_installation_scope === InstallationScope.OFFICIAL_ONLY)
- setCanInstallPlugin(verification.authorized_category === 'langgenius')
- else if (systemFeatures.plugin_installation_permission.plugin_installation_scope === InstallationScope.OFFICIAL_AND_PARTNER)
- setCanInstallPlugin(verification.authorized_category === 'langgenius' || verification.authorized_category === 'partner')
- else
- setCanInstallPlugin(false)
- }, [systemFeatures, payload])
+ const { canInstall } = useInstallPluginLimit(payload)
return (
<>
@@ -166,12 +149,9 @@ const Installed: FC = ({
installedVersion={installedVersion}
toInstallVersion={toInstallVersion}
/>}
+ showLimitWarning={!canInstall}
/>
- {!canInstallPlugin &&
-
- {t('plugin.installModal.installWarning')}
-
}
{/* Action Buttons */}
@@ -183,7 +163,7 @@ const Installed: FC
= ({