| import InstallMulti from './install-multi' | import InstallMulti from './install-multi' | ||||
| import { useInstallOrUpdate } from '@/service/use-plugins' | import { useInstallOrUpdate } from '@/service/use-plugins' | ||||
| import useRefreshPluginList from '../../hooks/use-refresh-plugin-list' | import useRefreshPluginList from '../../hooks/use-refresh-plugin-list' | ||||
| import { useCanInstallPluginFromMarketplace } from '@/app/components/plugins/plugin-page/use-permission' | |||||
| const i18nPrefix = 'plugin.installModal' | const i18nPrefix = 'plugin.installModal' | ||||
| type Props = { | type Props = { | ||||
| installedInfo: installedInfo!, | installedInfo: installedInfo!, | ||||
| }) | }) | ||||
| } | } | ||||
| const { canInstallPluginFromMarketplace } = useCanInstallPluginFromMarketplace() | |||||
| return ( | return ( | ||||
| <> | <> | ||||
| <div className='flex flex-col items-start justify-center gap-4 self-stretch px-6 py-3'> | <div className='flex flex-col items-start justify-center gap-4 self-stretch px-6 py-3'> | ||||
| <Button | <Button | ||||
| variant='primary' | variant='primary' | ||||
| className='flex min-w-[72px] space-x-0.5' | className='flex min-w-[72px] space-x-0.5' | ||||
| disabled={!canInstall || isInstalling || selectedPlugins.length === 0} | |||||
| disabled={!canInstall || isInstalling || selectedPlugins.length === 0 || !canInstallPluginFromMarketplace} | |||||
| onClick={handleInstall} | onClick={handleInstall} | ||||
| > | > | ||||
| {isInstalling && <RiLoader2Line className='h-4 w-4 animate-spin-slow' />} | {isInstalling && <RiLoader2Line className='h-4 w-4 animate-spin-slow' />} |
| return activeTab === PLUGIN_PAGE_TABS_MAP.marketplace || values.includes(activeTab) | return activeTab === PLUGIN_PAGE_TABS_MAP.marketplace || values.includes(activeTab) | ||||
| }, [activeTab]) | }, [activeTab]) | ||||
| const handleFileChange = (file: File | null) => { | |||||
| if (!file || !file.name.endsWith('.difypkg')) { | |||||
| setCurrentFile(null) | |||||
| return | |||||
| } | |||||
| setCurrentFile(file) | |||||
| } | |||||
| const uploaderProps = useUploader({ | const uploaderProps = useUploader({ | ||||
| onFileChange: setCurrentFile, | |||||
| onFileChange: handleFileChange, | |||||
| containerRef, | containerRef, | ||||
| enabled: isPluginsTab, | |||||
| enabled: isPluginsTab && canManagement, | |||||
| }) | }) | ||||
| const { dragging, fileUploader, fileChangeHandle, removeFile } = uploaderProps | const { dragging, fileUploader, fileChangeHandle, removeFile } = uploaderProps |
| import Toast from '../../base/toast' | import Toast from '../../base/toast' | ||||
| import { useTranslation } from 'react-i18next' | import { useTranslation } from 'react-i18next' | ||||
| import { useInvalidatePermissions, useMutationPermissions, usePermissions } from '@/service/use-plugins' | import { useInvalidatePermissions, useMutationPermissions, usePermissions } from '@/service/use-plugins' | ||||
| import { useSelector as useAppContextSelector } from '@/context/app-context' | |||||
| import { useMemo } from 'react' | |||||
| const hasPermission = (permission: PermissionType | undefined, isAdmin: boolean) => { | const hasPermission = (permission: PermissionType | undefined, isAdmin: boolean) => { | ||||
| if (!permission) | if (!permission) | ||||
| } | } | ||||
| } | } | ||||
| export const useCanInstallPluginFromMarketplace = () => { | |||||
| const { enable_marketplace } = useAppContextSelector(s => s.systemFeatures) | |||||
| const { canManagement } = usePermission() | |||||
| const canInstallPluginFromMarketplace = useMemo(() => { | |||||
| return enable_marketplace && canManagement | |||||
| }, [enable_marketplace, canManagement]) | |||||
| return { | |||||
| canInstallPluginFromMarketplace, | |||||
| } | |||||
| } | |||||
| export default usePermission | export default usePermission |