dify/web/app/components/plugins/plugin-detail-panel/detail-header/hooks/use-plugin-operations.ts
Jingyi 9b74df21d0
feat(web): refine onboarding UI (#37433)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: yyh <yuanyouhuilyz@gmail.com>
Co-authored-by: Joel <iamjoel007@gmail.com>
Co-authored-by: hjlarry <hjlarry@163.com>
Co-authored-by: fatelei <fatelei@gmail.com>
Co-authored-by: Asuka Minato <i@asukaminato.eu.org>
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Xiyuan Chen <52963600+GareArc@users.noreply.github.com>
Co-authored-by: gigglewang <gigglewang@dify.ai>
Co-authored-by: Yunlu Wen <yunlu.wen@dify.ai>
Co-authored-by: chariri <w@chariri.moe>
Co-authored-by: Evan <2869018789@qq.com>
Co-authored-by: yyh <92089059+lyzno1@users.noreply.github.com>
2026-06-15 08:47:15 +00:00

141 lines
4.0 KiB
TypeScript

'use client'
import type { PluginDetail } from '../../../types'
import type { ModalStates, VersionTarget } from './use-detail-header-state'
import { toast } from '@langgenius/dify-ui/toast'
import { useCallback } from 'react'
import { useTranslation } from 'react-i18next'
import { trackEvent } from '@/app/components/base/amplitude'
import useRefreshPluginList from '@/app/components/plugins/install-plugin/hooks/use-refresh-plugin-list'
import { useModalContext } from '@/context/modal-context'
import { uninstallPlugin } from '@/service/plugins'
import { useInvalidateCheckInstalled } from '@/service/use-plugins'
import { checkForUpdates, fetchReleases } from '../../../install-plugin/hooks'
import { PluginSource } from '../../../types'
type UsePluginOperationsParams = {
detail: PluginDetail
modalStates: ModalStates
versionPicker: {
setTargetVersion: (version: VersionTarget) => void
setIsDowngrade: (downgrade: boolean) => void
}
isFromMarketplace: boolean
onUpdate?: (isDelete?: boolean) => void
}
type UsePluginOperationsReturn = {
handleUpdate: (isDowngrade?: boolean) => Promise<void>
handleUpdatedFromMarketplace: () => void
handleDelete: () => Promise<void>
}
export const usePluginOperations = ({
detail,
modalStates,
versionPicker,
isFromMarketplace,
onUpdate,
}: UsePluginOperationsParams): UsePluginOperationsReturn => {
const { t } = useTranslation()
const { setShowUpdatePluginModal } = useModalContext()
const { refreshPluginList } = useRefreshPluginList()
const invalidateCheckInstalled = useInvalidateCheckInstalled()
const { id, meta, plugin_id } = detail
const { author, category, name } = detail.declaration || detail
const handlePluginUpdated = useCallback((isDelete?: boolean) => {
invalidateCheckInstalled()
onUpdate?.(isDelete)
}, [invalidateCheckInstalled, onUpdate])
const handleUpdate = useCallback(async (isDowngrade?: boolean) => {
if (isFromMarketplace) {
versionPicker.setIsDowngrade(!!isDowngrade)
modalStates.showUpdateModal()
return
}
if (!meta?.repo || !meta?.version || !meta?.package) {
toast.error('Missing plugin metadata for GitHub update')
return
}
const owner = meta.repo.split('/')[0] || author
const repo = meta.repo.split('/')[1] || name
const fetchedReleases = await fetchReleases(owner, repo)
if (fetchedReleases.length === 0)
return
const { needUpdate, toastProps } = checkForUpdates(fetchedReleases, meta.version)
toast(toastProps.message, { type: toastProps.type })
if (needUpdate) {
setShowUpdatePluginModal({
onSaveCallback: () => {
handlePluginUpdated()
},
payload: {
type: PluginSource.github,
category,
github: {
originalPackageInfo: {
id: detail.plugin_unique_identifier,
repo: meta.repo,
version: meta.version,
package: meta.package,
releases: fetchedReleases,
},
},
},
})
}
}, [
isFromMarketplace,
meta,
author,
name,
fetchReleases,
checkForUpdates,
setShowUpdatePluginModal,
detail,
handlePluginUpdated,
modalStates,
versionPicker,
])
const handleUpdatedFromMarketplace = useCallback(() => {
handlePluginUpdated()
modalStates.hideUpdateModal()
}, [handlePluginUpdated, modalStates])
const handleDelete = useCallback(async () => {
modalStates.showDeleting()
const res = await uninstallPlugin(id)
modalStates.hideDeleting()
if (res.success) {
modalStates.hideDeleteConfirm()
toast.success(t('action.deleteSuccess', { ns: 'plugin' }))
handlePluginUpdated(true)
refreshPluginList({ category })
trackEvent('plugin_uninstalled', { plugin_id, plugin_name: name })
}
}, [
id,
category,
plugin_id,
name,
modalStates,
handlePluginUpdated,
refreshPluginList,
])
return {
handleUpdate,
handleUpdatedFromMarketplace,
handleDelete,
}
}