dify/web/app/components/plugins/plugin-page/plugin-tasks/components/error-plugin-item.tsx
Stephen Zhou a84c2d36a3
style: format with vp fmt (#38803)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-07-12 15:57:46 +00:00

152 lines
5.1 KiB
TypeScript

import type { FC } from 'react'
import type { Plugin, PluginStatus } from '@/app/components/plugins/types'
import type { Locale } from '@/i18n-config'
import { Button } from '@langgenius/dify-ui/button'
import { useCallback, useState } from 'react'
import { useTranslation } from 'react-i18next'
import { PluginInstallPermissionProvider } from '@/app/components/plugins/install-plugin/components/plugin-install-permission-provider'
import useWorkspacePluginInstallPermission from '@/app/components/plugins/install-plugin/hooks/use-workspace-plugin-install-permission'
import InstallFromMarketplace from '@/app/components/plugins/install-plugin/install-from-marketplace'
import { PluginSource } from '@/app/components/plugins/types'
import { fetchPluginInfoFromMarketPlace } from '@/service/plugins'
import PluginItem from './plugin-item'
type ErrorPluginItemProps = {
plugin: PluginStatus
getIconUrl: (icon: string) => string
language: Locale
onClear: () => void
}
const ErrorPluginItem: FC<ErrorPluginItemProps> = ({ plugin, getIconUrl, language, onClear }) => {
const { t } = useTranslation()
const source = plugin.source
const [showInstallModal, setShowInstallModal] = useState(false)
const [installPayload, setInstallPayload] = useState<{
uniqueIdentifier: string
manifest: Plugin
} | null>(null)
const [isFetching, setIsFetching] = useState(false)
const { canInstallPlugin, currentDifyVersion } = useWorkspacePluginInstallPermission()
const handleInstallFromMarketplace = useCallback(async () => {
const parts = plugin.plugin_id.split('/')
if (parts.length < 2) return
const [org, name] = parts
setIsFetching(true)
try {
const response = await fetchPluginInfoFromMarketPlace({ org: org!, name: name! })
const info = response.data.plugin
const manifest: Plugin = {
plugin_id: plugin.plugin_id,
type: info.category as Plugin['type'],
category: info.category as Plugin['category'],
name: name!,
org: org!,
version: info.latest_version,
latest_version: info.latest_version,
latest_package_identifier: info.latest_package_identifier,
label: plugin.labels,
brief: {},
description: {},
icon: plugin.icon,
verified: true,
introduction: '',
repository: '',
install_count: 0,
endpoint: { settings: [] },
tags: [],
badges: [],
verification: { authorized_category: 'langgenius' },
from: 'marketplace',
}
setInstallPayload({ uniqueIdentifier: info.latest_package_identifier, manifest })
setShowInstallModal(true)
} catch {
// silently fail
} finally {
setIsFetching(false)
}
}, [plugin.plugin_id, plugin.labels, plugin.icon])
const errorMsgKey:
| 'task.errorMsg.marketplace'
| 'task.errorMsg.github'
| 'task.errorMsg.unknown' =
source === PluginSource.marketplace
? 'task.errorMsg.marketplace'
: source === PluginSource.github
? 'task.errorMsg.github'
: 'task.errorMsg.unknown'
const errorMsg = t(($) => $[errorMsgKey], { ns: 'plugin' })
const renderAction = () => {
if (source === PluginSource.marketplace && canInstallPlugin) {
return (
<div className="pt-1">
<Button
variant="secondary"
size="small"
loading={isFetching}
onClick={handleInstallFromMarketplace}
>
{t(($) => $['task.installFromMarketplace'], { ns: 'plugin' })}
</Button>
</div>
)
}
if (source === PluginSource.github && canInstallPlugin) {
return (
<div className="pt-1">
<Button variant="secondary" size="small">
{t(($) => $['task.installFromGithub'], { ns: 'plugin' })}
</Button>
</div>
)
}
return undefined
}
return (
<>
<PluginItem
plugin={plugin}
getIconUrl={getIconUrl}
language={language}
statusIcon={
<span className="flex size-4 items-center justify-center rounded-full border border-components-panel-bg bg-components-panel-bg">
<span className="i-ri-error-warning-fill size-4 text-text-destructive" />
</span>
}
statusText={
<span className="block max-w-full min-w-0 [overflow-wrap:anywhere] break-words whitespace-pre-wrap">
{plugin.message || errorMsg}
</span>
}
statusClassName="text-text-destructive"
action={renderAction()}
onClear={onClear}
/>
{showInstallModal && installPayload && canInstallPlugin && (
<PluginInstallPermissionProvider
canInstallPlugin={canInstallPlugin}
currentDifyVersion={currentDifyVersion}
>
<InstallFromMarketplace
uniqueIdentifier={installPayload.uniqueIdentifier}
manifest={installPayload.manifest}
onClose={() => setShowInstallModal(false)}
onSuccess={() => {
setShowInstallModal(false)
onClear()
}}
/>
</PluginInstallPermissionProvider>
)}
</>
)
}
export default ErrorPluginItem