'use client' import { useMemo, useState } from 'react' import { useTranslation } from 'react-i18next' import { RiArrowRightUpLine, RiBugLine, RiClipboardLine, RiDragDropLine, RiEqualizer2Line, } from '@remixicon/react' import { useBoolean } from 'ahooks' import InstallFromLocalPackage from '../install-plugin/install-from-local-package' import { PluginPageContextProvider, usePluginPageContext, } from './context' import InstallPluginDropdown from './install-plugin-dropdown' import { useUploader } from './use-uploader' import usePermission from './use-permission' import { useTabSearchParams } from '@/hooks/use-tab-searchparams' import Button from '@/app/components/base/button' import TabSlider from '@/app/components/base/tab-slider' import ActionButton from '@/app/components/base/action-button' import Tooltip from '@/app/components/base/tooltip' import cn from '@/utils/classnames' import PermissionSetModal from '@/app/components/plugins/permission-setting-modal/modal' export type PluginPageProps = { plugins: React.ReactNode marketplace: React.ReactNode } const PluginPage = ({ plugins, marketplace, }: PluginPageProps) => { const { t } = useTranslation() const { canManagement, canDebugger, canSetPermissions, permissions, setPermissions, } = usePermission() const [showPluginSettingModal, { setTrue: setShowPluginSettingModal, setFalse: setHidePluginSettingModal, }] = useBoolean() const [currentFile, setCurrentFile] = useState(null) const containerRef = usePluginPageContext(v => v.containerRef) const options = useMemo(() => { return [ { value: 'plugins', text: t('common.menus.plugins') }, { value: 'discover', text: 'Explore Marketplace' }, ] }, [t]) const [activeTab, setActiveTab] = useTabSearchParams({ defaultTab: options[0].value, }) const uploaderProps = useUploader({ onFileChange: setCurrentFile, containerRef, enabled: activeTab === 'plugins', }) const { dragging, fileUploader, fileChangeHandle, removeFile } = uploaderProps return (
{canManagement && ( )} { canDebugger && (
Debugging
View docs
{['Port', 'Key'].map((label, index) => (
{label}
{index === 0 ? 'cloud.dify,ai:2048' : 'A1B2C3D4E5F6G7H8'}
))}
} popupClassName='flex flex-col items-start w-[256px] px-4 py-3.5 gap-1 border border-components-panel-border rounded-xl bg-components-tooltip-bg shadows-shadow-lg z-50' asChild={false} position='bottom' >
) } { canSetPermissions && ( ) }
{activeTab === 'plugins' && ( <> {plugins} {dragging && (
)}
Drop plugin package here to install
{currentFile && ( { })} /> )} { })} /> )} { activeTab === 'discover' && marketplace } {showPluginSettingModal && ( )}
) } const PluginPageWithContext = (props: PluginPageProps) => { return ( ) } export default PluginPageWithContext