import { memo, useCallback, useEffect, useMemo, useState, } from 'react' import type { ReactNode } from 'react' import { RiAddLine, RiArrowDownSLine, RiEqualizer2Line, RiKey2Line, RiUserStarLine, } from '@remixicon/react' import { useTranslation } from 'react-i18next' import Authorize from './authorize' import Authorized from './authorized' import AddOAuthButton from './authorize/add-oauth-button' import AddApiKeyButton from './authorize/add-api-key-button' import type { Credential, PluginPayload, } from './types' import { usePluginAuth } from './hooks/use-plugin-auth' import Button from '@/app/components/base/button' import Indicator from '@/app/components/header/indicator' import cn from '@/utils/classnames' import { PortalToFollowElem, PortalToFollowElemContent, PortalToFollowElemTrigger, } from '@/app/components/base/portal-to-follow-elem' import Switch from '@/app/components/base/switch' type PluginAuthInAgentProps = { pluginPayload: PluginPayload credentialId?: string onAuthorizationItemClick?: (id: string) => void useEndUserCredentialEnabled?: boolean endUserCredentialType?: string onEndUserCredentialChange?: (enabled: boolean) => void onEndUserCredentialTypeChange?: (type: string) => void } const PluginAuthInAgent = ({ pluginPayload, credentialId, onAuthorizationItemClick, useEndUserCredentialEnabled, endUserCredentialType, onEndUserCredentialChange, onEndUserCredentialTypeChange, }: PluginAuthInAgentProps) => { const { t } = useTranslation() const [isOpen, setIsOpen] = useState(false) const [showAddMenu, setShowAddMenu] = useState(false) const [showEndUserTypeMenu, setShowEndUserTypeMenu] = useState(false) const { isAuthorized, canOAuth, canApiKey, credentials, disabled, invalidPluginCredentialInfo, notAllowCustomCredential, hasOAuthClientConfigured, } = usePluginAuth(pluginPayload, true) const extraAuthorizationItems: Credential[] = [ { id: '__workspace_default__', name: t('plugin.auth.workspaceDefault'), provider: '', is_default: !credentialId, isWorkspaceDefault: true, }, ] const handleAuthorizationItemClick = useCallback((id: string) => { onAuthorizationItemClick?.(id) setIsOpen(false) }, [ onAuthorizationItemClick, setIsOpen, ]) const renderTrigger = useCallback((isOpen?: boolean) => { let label = '' let removed = false let unavailable = false let color = 'green' if (!credentialId) { label = t('plugin.auth.workspaceDefault') } else { const credential = credentials.find(c => c.id === credentialId) label = credential ? credential.name : t('plugin.auth.authRemoved') removed = !credential unavailable = !!credential?.not_allowed_to_use && !credential?.from_enterprise if (removed) color = 'red' else if (unavailable) color = 'gray' } return ( ) }, [credentialId, credentials, t]) const availableEndUserTypes = useMemo(() => { const list: { value: string; label: string; icon: ReactNode }[] = [] if (canOAuth) { list.push({ value: 'oauth2', label: t('plugin.auth.endUserCredentials.optionOAuth'), icon: , }) } if (canApiKey) { list.push({ value: 'api-key', label: t('plugin.auth.endUserCredentials.optionApiKey'), icon: , }) } return list }, [canOAuth, canApiKey, t]) const endUserCredentialLabel = useMemo(() => { const found = availableEndUserTypes.find(item => item.value === endUserCredentialType) return found?.label || availableEndUserTypes[0]?.label || '-' }, [availableEndUserTypes, endUserCredentialType]) useEffect(() => { if (!useEndUserCredentialEnabled) return if (!availableEndUserTypes.length) return const isValid = availableEndUserTypes.some(item => item.value === endUserCredentialType) if (!isValid) onEndUserCredentialTypeChange?.(availableEndUserTypes[0].value) }, [useEndUserCredentialEnabled, endUserCredentialType, availableEndUserTypes, onEndUserCredentialTypeChange]) const handleSelectEndUserType = useCallback((value: string) => { onEndUserCredentialTypeChange?.(value) setShowEndUserTypeMenu(false) }, [onEndUserCredentialTypeChange]) const shouldShowAuthorizeCard = !credentials.length && (canOAuth || canApiKey || hasOAuthClientConfigured) const endUserSection = (
{t('plugin.auth.endUserCredentials.title')}
{t('plugin.auth.endUserCredentials.desc')}
{ useEndUserCredentialEnabled && availableEndUserTypes.length > 0 && (
{t('plugin.auth.endUserCredentials.typeLabel')}
{canOAuth && ( { handleSelectEndUserType('oauth2') invalidPluginCredentialInfo() }} /> )} {canApiKey && ( { handleSelectEndUserType('api-key') invalidPluginCredentialInfo() }} /> )}
) }
) return (
{t('plugin.auth.configuredCredentials.title')}
{t('plugin.auth.configuredCredentials.desc')}
{ canOAuth && ( { setShowAddMenu(false) invalidPluginCredentialInfo() }} /> ) } { canApiKey && ( { setShowAddMenu(false) invalidPluginCredentialInfo() }} /> ) }
{ !isAuthorized && shouldShowAuthorizeCard && (
) } { !isAuthorized && !shouldShowAuthorizeCard && ( ) } { isAuthorized && ( ) } {endUserSection}
) } export default memo(PluginAuthInAgent)