mirror of
https://github.com/langgenius/dify.git
synced 2026-05-04 17:38:04 +08:00
Merge branch 'main' into feat/rag-2
This commit is contained in:
@ -8,6 +8,8 @@ import type { AddOAuthButtonProps } from './add-oauth-button'
|
||||
import AddApiKeyButton from './add-api-key-button'
|
||||
import type { AddApiKeyButtonProps } from './add-api-key-button'
|
||||
import type { PluginPayload } from '../types'
|
||||
import cn from '@/utils/classnames'
|
||||
import Tooltip from '@/app/components/base/tooltip'
|
||||
|
||||
type AuthorizeProps = {
|
||||
pluginPayload: PluginPayload
|
||||
@ -17,6 +19,7 @@ type AuthorizeProps = {
|
||||
canApiKey?: boolean
|
||||
disabled?: boolean
|
||||
onUpdate?: () => void
|
||||
notAllowCustomCredential?: boolean
|
||||
}
|
||||
const Authorize = ({
|
||||
pluginPayload,
|
||||
@ -26,6 +29,7 @@ const Authorize = ({
|
||||
canApiKey,
|
||||
disabled,
|
||||
onUpdate,
|
||||
notAllowCustomCredential,
|
||||
}: AuthorizeProps) => {
|
||||
const { t } = useTranslation()
|
||||
const oAuthButtonProps: AddOAuthButtonProps = useMemo(() => {
|
||||
@ -62,18 +66,54 @@ const Authorize = ({
|
||||
}
|
||||
}, [canOAuth, theme, pluginPayload, t])
|
||||
|
||||
const OAuthButton = useMemo(() => {
|
||||
const Item = (
|
||||
<div className={cn('min-w-0 flex-[1]', notAllowCustomCredential && 'opacity-50')}>
|
||||
<AddOAuthButton
|
||||
{...oAuthButtonProps}
|
||||
disabled={disabled || notAllowCustomCredential}
|
||||
onUpdate={onUpdate}
|
||||
/>
|
||||
</div>
|
||||
)
|
||||
|
||||
if (notAllowCustomCredential) {
|
||||
return (
|
||||
<Tooltip popupContent={t('plugin.auth.credentialUnavailable')}>
|
||||
{Item}
|
||||
</Tooltip>
|
||||
)
|
||||
}
|
||||
return Item
|
||||
}, [notAllowCustomCredential, oAuthButtonProps, disabled, onUpdate, t])
|
||||
|
||||
const ApiKeyButton = useMemo(() => {
|
||||
const Item = (
|
||||
<div className={cn('min-w-0 flex-[1]', notAllowCustomCredential && 'opacity-50')}>
|
||||
<AddApiKeyButton
|
||||
{...apiKeyButtonProps}
|
||||
disabled={disabled || notAllowCustomCredential}
|
||||
onUpdate={onUpdate}
|
||||
/>
|
||||
</div>
|
||||
)
|
||||
|
||||
if (notAllowCustomCredential) {
|
||||
return (
|
||||
<Tooltip popupContent={t('plugin.auth.credentialUnavailable')}>
|
||||
{Item}
|
||||
</Tooltip>
|
||||
)
|
||||
}
|
||||
return Item
|
||||
}, [notAllowCustomCredential, apiKeyButtonProps, disabled, onUpdate, t])
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className='flex items-center space-x-1.5'>
|
||||
{
|
||||
canOAuth && (
|
||||
<div className='min-w-0 flex-[1]'>
|
||||
<AddOAuthButton
|
||||
{...oAuthButtonProps}
|
||||
disabled={disabled}
|
||||
onUpdate={onUpdate}
|
||||
/>
|
||||
</div>
|
||||
OAuthButton
|
||||
)
|
||||
}
|
||||
{
|
||||
@ -87,13 +127,7 @@ const Authorize = ({
|
||||
}
|
||||
{
|
||||
canApiKey && (
|
||||
<div className='min-w-0 flex-[1]'>
|
||||
<AddApiKeyButton
|
||||
{...apiKeyButtonProps}
|
||||
disabled={disabled}
|
||||
onUpdate={onUpdate}
|
||||
/>
|
||||
</div>
|
||||
ApiKeyButton
|
||||
)
|
||||
}
|
||||
</div>
|
||||
|
||||
@ -35,10 +35,13 @@ const AuthorizedInNode = ({
|
||||
credentials,
|
||||
disabled,
|
||||
invalidPluginCredentialInfo,
|
||||
notAllowCustomCredential,
|
||||
} = usePluginAuth(pluginPayload, isOpen || !!credentialId)
|
||||
const renderTrigger = useCallback((open?: boolean) => {
|
||||
let label = ''
|
||||
let removed = false
|
||||
let unavailable = false
|
||||
let color = 'green'
|
||||
if (!credentialId) {
|
||||
label = t('plugin.auth.workspaceDefault')
|
||||
}
|
||||
@ -46,6 +49,12 @@ const AuthorizedInNode = ({
|
||||
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 (
|
||||
<Button
|
||||
@ -57,9 +66,12 @@ const AuthorizedInNode = ({
|
||||
>
|
||||
<Indicator
|
||||
className='mr-1.5'
|
||||
color={removed ? 'red' : 'green'}
|
||||
color={color as any}
|
||||
/>
|
||||
{label}
|
||||
{
|
||||
unavailable && t('plugin.auth.unavailable')
|
||||
}
|
||||
<RiArrowDownSLine
|
||||
className={cn(
|
||||
'h-3.5 w-3.5 text-components-button-ghost-text',
|
||||
@ -106,6 +118,7 @@ const AuthorizedInNode = ({
|
||||
showItemSelectedIcon
|
||||
selectedCredentialId={credentialId || '__workspace_default__'}
|
||||
onUpdate={invalidPluginCredentialInfo}
|
||||
notAllowCustomCredential={notAllowCustomCredential}
|
||||
/>
|
||||
)
|
||||
}
|
||||
|
||||
@ -52,6 +52,7 @@ type AuthorizedProps = {
|
||||
showItemSelectedIcon?: boolean
|
||||
selectedCredentialId?: string
|
||||
onUpdate?: () => void
|
||||
notAllowCustomCredential?: boolean
|
||||
}
|
||||
const Authorized = ({
|
||||
pluginPayload,
|
||||
@ -72,6 +73,7 @@ const Authorized = ({
|
||||
showItemSelectedIcon,
|
||||
selectedCredentialId,
|
||||
onUpdate,
|
||||
notAllowCustomCredential,
|
||||
}: AuthorizedProps) => {
|
||||
const { t } = useTranslation()
|
||||
const { notify } = useToastContext()
|
||||
@ -171,6 +173,7 @@ const Authorized = ({
|
||||
handleSetDoingAction(false)
|
||||
}
|
||||
}, [updatePluginCredential, notify, t, handleSetDoingAction, onUpdate])
|
||||
const unavailableCredentials = credentials.filter(credential => credential.not_allowed_to_use)
|
||||
|
||||
return (
|
||||
<>
|
||||
@ -201,6 +204,11 @@ const Authorized = ({
|
||||
? t('plugin.auth.authorizations')
|
||||
: t('plugin.auth.authorization')
|
||||
}
|
||||
{
|
||||
!!unavailableCredentials.length && (
|
||||
` (${unavailableCredentials.length} ${t('plugin.auth.unavailable')})`
|
||||
)
|
||||
}
|
||||
<RiArrowDownSLine className='ml-0.5 h-4 w-4' />
|
||||
</Button>
|
||||
)
|
||||
@ -294,18 +302,24 @@ const Authorized = ({
|
||||
)
|
||||
}
|
||||
</div>
|
||||
<div className='h-px bg-divider-subtle'></div>
|
||||
<div className='p-2'>
|
||||
<Authorize
|
||||
pluginPayload={pluginPayload}
|
||||
theme='secondary'
|
||||
showDivider={false}
|
||||
canOAuth={canOAuth}
|
||||
canApiKey={canApiKey}
|
||||
disabled={disabled}
|
||||
onUpdate={onUpdate}
|
||||
/>
|
||||
</div>
|
||||
{
|
||||
!notAllowCustomCredential && (
|
||||
<>
|
||||
<div className='h-[1px] bg-divider-subtle'></div>
|
||||
<div className='p-2'>
|
||||
<Authorize
|
||||
pluginPayload={pluginPayload}
|
||||
theme='secondary'
|
||||
showDivider={false}
|
||||
canOAuth={canOAuth}
|
||||
canApiKey={canApiKey}
|
||||
disabled={disabled}
|
||||
onUpdate={onUpdate}
|
||||
/>
|
||||
</div>
|
||||
</>
|
||||
)
|
||||
}
|
||||
</div>
|
||||
</PortalToFollowElemContent>
|
||||
</PortalToFollowElem>
|
||||
|
||||
@ -61,14 +61,19 @@ const Item = ({
|
||||
return !(disableRename && disableEdit && disableDelete && disableSetDefault)
|
||||
}, [disableRename, disableEdit, disableDelete, disableSetDefault])
|
||||
|
||||
return (
|
||||
const CredentialItem = (
|
||||
<div
|
||||
key={credential.id}
|
||||
className={cn(
|
||||
'group flex h-8 items-center rounded-lg p-1 hover:bg-state-base-hover',
|
||||
renaming && 'bg-state-base-hover',
|
||||
(disabled || credential.not_allowed_to_use) && 'cursor-not-allowed opacity-50',
|
||||
)}
|
||||
onClick={() => onItemClick?.(credential.id === '__workspace_default__' ? '' : credential.id)}
|
||||
onClick={() => {
|
||||
if (credential.not_allowed_to_use || disabled)
|
||||
return
|
||||
onItemClick?.(credential.id === '__workspace_default__' ? '' : credential.id)
|
||||
}}
|
||||
>
|
||||
{
|
||||
renaming && (
|
||||
@ -121,7 +126,10 @@ const Item = ({
|
||||
</div>
|
||||
)
|
||||
}
|
||||
<Indicator className='ml-2 mr-1.5 shrink-0' />
|
||||
<Indicator
|
||||
className='ml-2 mr-1.5 shrink-0'
|
||||
color={credential.not_allowed_to_use ? 'gray' : 'green'}
|
||||
/>
|
||||
<div
|
||||
className='system-md-regular truncate text-text-secondary'
|
||||
title={credential.name}
|
||||
@ -138,11 +146,18 @@ const Item = ({
|
||||
</div>
|
||||
)
|
||||
}
|
||||
{
|
||||
credential.from_enterprise && (
|
||||
<Badge className='shrink-0'>
|
||||
Enterprise
|
||||
</Badge>
|
||||
)
|
||||
}
|
||||
{
|
||||
showAction && !renaming && (
|
||||
<div className='ml-2 hidden shrink-0 items-center group-hover:flex'>
|
||||
{
|
||||
!credential.is_default && !disableSetDefault && (
|
||||
!credential.is_default && !disableSetDefault && !credential.not_allowed_to_use && (
|
||||
<Button
|
||||
size='small'
|
||||
disabled={disabled}
|
||||
@ -156,7 +171,7 @@ const Item = ({
|
||||
)
|
||||
}
|
||||
{
|
||||
!disableRename && (
|
||||
!disableRename && !credential.from_enterprise && !credential.not_allowed_to_use && (
|
||||
<Tooltip popupContent={t('common.operation.rename')}>
|
||||
<ActionButton
|
||||
disabled={disabled}
|
||||
@ -172,7 +187,7 @@ const Item = ({
|
||||
)
|
||||
}
|
||||
{
|
||||
!isOAuth && !disableEdit && (
|
||||
!isOAuth && !disableEdit && !credential.from_enterprise && !credential.not_allowed_to_use && (
|
||||
<Tooltip popupContent={t('common.operation.edit')}>
|
||||
<ActionButton
|
||||
disabled={disabled}
|
||||
@ -194,7 +209,7 @@ const Item = ({
|
||||
)
|
||||
}
|
||||
{
|
||||
!disableDelete && (
|
||||
!disableDelete && !credential.from_enterprise && (
|
||||
<Tooltip popupContent={t('common.operation.delete')}>
|
||||
<ActionButton
|
||||
className='hover:bg-transparent'
|
||||
@ -214,6 +229,18 @@ const Item = ({
|
||||
}
|
||||
</div>
|
||||
)
|
||||
|
||||
if (credential.not_allowed_to_use) {
|
||||
return (
|
||||
<Tooltip popupContent={t('plugin.auth.customCredentialUnavailable')}>
|
||||
{CredentialItem}
|
||||
</Tooltip>
|
||||
)
|
||||
}
|
||||
|
||||
return (
|
||||
CredentialItem
|
||||
)
|
||||
}
|
||||
|
||||
export default memo(Item)
|
||||
|
||||
@ -87,9 +87,9 @@ export const usePluginAuthAction = (
|
||||
}, [setPluginDefaultCredential, onUpdate, notify, t, handleSetDoingAction])
|
||||
const { mutateAsync: updatePluginCredential } = useUpdatePluginCredentialHook(pluginPayload)
|
||||
const handleRename = useCallback(async (payload: {
|
||||
credential_id: string
|
||||
name: string
|
||||
}) => {
|
||||
credential_id: string
|
||||
name: string
|
||||
}) => {
|
||||
if (doingActionRef.current)
|
||||
return
|
||||
try {
|
||||
|
||||
@ -20,6 +20,7 @@ export const usePluginAuth = (pluginPayload: PluginPayload, enable?: boolean) =>
|
||||
canApiKey,
|
||||
credentials: data?.credentials || [],
|
||||
disabled: !isCurrentWorkspaceManager,
|
||||
notAllowCustomCredential: data?.allow_custom_token === false,
|
||||
invalidPluginCredentialInfo,
|
||||
}
|
||||
}
|
||||
|
||||
@ -35,6 +35,7 @@ const PluginAuthInAgent = ({
|
||||
credentials,
|
||||
disabled,
|
||||
invalidPluginCredentialInfo,
|
||||
notAllowCustomCredential,
|
||||
} = usePluginAuth(pluginPayload, true)
|
||||
|
||||
const extraAuthorizationItems: Credential[] = [
|
||||
@ -58,6 +59,8 @@ const PluginAuthInAgent = ({
|
||||
const renderTrigger = useCallback((isOpen?: boolean) => {
|
||||
let label = ''
|
||||
let removed = false
|
||||
let unavailable = false
|
||||
let color = 'green'
|
||||
if (!credentialId) {
|
||||
label = t('plugin.auth.workspaceDefault')
|
||||
}
|
||||
@ -65,6 +68,11 @@ const PluginAuthInAgent = ({
|
||||
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 (
|
||||
<Button
|
||||
@ -75,9 +83,12 @@ const PluginAuthInAgent = ({
|
||||
)}>
|
||||
<Indicator
|
||||
className='mr-2'
|
||||
color={removed ? 'red' : 'green'}
|
||||
color={color as any}
|
||||
/>
|
||||
{label}
|
||||
{
|
||||
unavailable && t('plugin.auth.unavailable')
|
||||
}
|
||||
<RiArrowDownSLine className='ml-0.5 h-4 w-4' />
|
||||
</Button>
|
||||
)
|
||||
@ -93,6 +104,7 @@ const PluginAuthInAgent = ({
|
||||
canApiKey={canApiKey}
|
||||
disabled={disabled}
|
||||
onUpdate={invalidPluginCredentialInfo}
|
||||
notAllowCustomCredential={notAllowCustomCredential}
|
||||
/>
|
||||
)
|
||||
}
|
||||
@ -113,6 +125,7 @@ const PluginAuthInAgent = ({
|
||||
onOpenChange={setIsOpen}
|
||||
selectedCredentialId={credentialId || '__workspace_default__'}
|
||||
onUpdate={invalidPluginCredentialInfo}
|
||||
notAllowCustomCredential={notAllowCustomCredential}
|
||||
/>
|
||||
)
|
||||
}
|
||||
|
||||
@ -22,6 +22,7 @@ const PluginAuth = ({
|
||||
credentials,
|
||||
disabled,
|
||||
invalidPluginCredentialInfo,
|
||||
notAllowCustomCredential,
|
||||
} = usePluginAuth(pluginPayload, !!pluginPayload.provider)
|
||||
|
||||
return (
|
||||
@ -34,6 +35,7 @@ const PluginAuth = ({
|
||||
canApiKey={canApiKey}
|
||||
disabled={disabled}
|
||||
onUpdate={invalidPluginCredentialInfo}
|
||||
notAllowCustomCredential={notAllowCustomCredential}
|
||||
/>
|
||||
)
|
||||
}
|
||||
@ -46,6 +48,7 @@ const PluginAuth = ({
|
||||
canApiKey={canApiKey}
|
||||
disabled={disabled}
|
||||
onUpdate={invalidPluginCredentialInfo}
|
||||
notAllowCustomCredential={notAllowCustomCredential}
|
||||
/>
|
||||
)
|
||||
}
|
||||
|
||||
@ -25,4 +25,6 @@ export type Credential = {
|
||||
is_default: boolean
|
||||
credentials?: Record<string, any>
|
||||
isWorkspaceDefault?: boolean
|
||||
from_enterprise?: boolean
|
||||
not_allowed_to_use?: boolean
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user