'use client' import React, { useEffect, useMemo, useRef, useState } from 'react' import { MagicBox } from '@/app/components/base/icons/src/vender/solid/mediaAndDevices' import { FileZip } from '@/app/components/base/icons/src/vender/solid/files' import { Github } from '@/app/components/base/icons/src/vender/solid/general' import InstallFromGitHub from '@/app/components/plugins/install-plugin/install-from-github' import InstallFromLocalPackage from '@/app/components/plugins/install-plugin/install-from-local-package' import { usePluginPageContext } from '../context' import { Group } from '@/app/components/base/icons/src/vender/other' import Line from '../../marketplace/empty/line' import { useInstalledPluginList } from '@/service/use-plugins' import { useTranslation } from 'react-i18next' import { SUPPORT_INSTALL_LOCAL_FILE_EXTENSIONS } from '@/config' import { noop } from 'lodash-es' import { useGlobalPublicStore } from '@/context/global-public-context' import Button from '@/app/components/base/button' type InstallMethod = { icon: React.FC<{ className?: string }> text: string action: string } const Empty = () => { const { t } = useTranslation() const fileInputRef = useRef(null) const [selectedAction, setSelectedAction] = useState(null) const [selectedFile, setSelectedFile] = useState(null) const { enable_marketplace, plugin_installation_permission } = useGlobalPublicStore(s => s.systemFeatures) const setActiveTab = usePluginPageContext(v => v.setActiveTab) const handleFileChange = (event: React.ChangeEvent) => { const file = event.target.files?.[0] if (file) { setSelectedFile(file) setSelectedAction('local') } } const filters = usePluginPageContext(v => v.filters) const { data: pluginList } = useInstalledPluginList() const text = useMemo(() => { if (pluginList?.plugins.length === 0) return t('plugin.list.noInstalled') if (filters.categories.length > 0 || filters.tags.length > 0 || filters.searchQuery) return t('plugin.list.notFound') }, [pluginList?.plugins.length, t, filters.categories.length, filters.tags.length, filters.searchQuery]) const [installMethods, setInstallMethods] = useState([]) useEffect(() => { const methods = [] if (enable_marketplace) methods.push({ icon: MagicBox, text: t('plugin.source.marketplace'), action: 'marketplace' }) if (plugin_installation_permission.restrict_to_marketplace_only) { setInstallMethods(methods) } else { methods.push({ icon: Github, text: t('plugin.source.github'), action: 'github' }) methods.push({ icon: FileZip, text: t('plugin.source.local'), action: 'local' }) setInstallMethods(methods) } }, [plugin_installation_permission, enable_marketplace, t]) return (
{/* skeleton */}
{Array.from({ length: 20 }).fill(0).map((_, i) => (
))}
{/* mask */}
{text}
{installMethods.map(({ icon: Icon, text, action }) => ( ))}
{selectedAction === 'github' && setSelectedAction(null)} />} {selectedAction === 'local' && selectedFile && ( setSelectedAction(null)} onSuccess={noop} /> ) }
) } Empty.displayName = 'Empty' export default React.memo(Empty)