import type { PluginPayload } from '../types' import type { FormRefObject, FormSchema } from '@/app/components/base/form/types' import { Button } from '@langgenius/dify-ui/button' import { Dialog, DialogClose, DialogContent, DialogTitle } from '@langgenius/dify-ui/dialog' import { IconButton } from '@langgenius/dify-ui/icon-button' import { toast } from '@langgenius/dify-ui/toast' import { useForm, useStore } from '@tanstack/react-form' import { memo, useCallback, useRef, useState } from 'react' import { useTranslation } from 'react-i18next' import AuthForm from '@/app/components/base/form/form-scenarios/auth' import { ReadmeEntrance } from '../../readme-panel/entrance' import { useDeletePluginOAuthCustomClientHook, useInvalidPluginOAuthClientSchemaHook, useSetPluginOAuthCustomClientHook, } from '../hooks/use-credential' export type OAuthClientSettingsProps = { pluginPayload: PluginPayload open?: boolean onOpenChange?: (open: boolean) => void onClose?: () => void editValues?: Record disabled?: boolean schemas: FormSchema[] onRequestAuthorization?: () => Promise | void hasOriginalClientParams?: boolean onUpdate?: () => void } const OAuthClientSettings = ({ pluginPayload, open = true, onOpenChange, onClose, editValues, disabled, schemas, onRequestAuthorization, hasOriginalClientParams, onUpdate, }: OAuthClientSettingsProps) => { const { t } = useTranslation() const [doingAction, setDoingAction] = useState(false) const doingActionRef = useRef(doingAction) const handleSetDoingAction = useCallback((value: boolean) => { doingActionRef.current = value setDoingAction(value) }, []) const handleOpenChange = useCallback( (nextOpen: boolean) => { onOpenChange?.(nextOpen) if (!nextOpen) onClose?.() }, [onClose, onOpenChange], ) const defaultValues = schemas.reduce( (acc, schema) => { if (schema.default) acc[schema.name] = schema.default return acc }, {} as Record, ) const { mutateAsync: setPluginOAuthCustomClient } = useSetPluginOAuthCustomClientHook(pluginPayload) const invalidPluginOAuthClientSchema = useInvalidPluginOAuthClientSchemaHook(pluginPayload) const formRef = useRef(null) const handleConfirm = useCallback(async () => { if (doingActionRef.current) return false try { const { isCheckValidated, values } = formRef.current?.getFormValues({ needCheckValidatedValues: true, needTransformWhenSecretFieldIsPristine: true, }) || { isCheckValidated: false, values: {} } if (!isCheckValidated) throw new Error('error') const { __oauth_client__, ...restValues } = values handleSetDoingAction(true) await setPluginOAuthCustomClient({ client_params: restValues, enable_oauth_custom_client: __oauth_client__ === 'custom', }) toast.success(t(($) => $['api.actionSuccess'], { ns: 'common' })) onOpenChange?.(false) onClose?.() onUpdate?.() invalidPluginOAuthClientSchema() return true } finally { handleSetDoingAction(false) } }, [ onClose, onOpenChange, onUpdate, invalidPluginOAuthClientSchema, setPluginOAuthCustomClient, t, handleSetDoingAction, ]) const handleConfirmAndAuthorize = useCallback(async () => { try { const isSaved = await handleConfirm() if (isSaved) await onRequestAuthorization?.() } catch { // The request layer reports the save error. Keep settings open and stop // before opening the permission dialog. } }, [handleConfirm, onRequestAuthorization]) const { mutateAsync: deletePluginOAuthCustomClient } = useDeletePluginOAuthCustomClientHook(pluginPayload) const handleRemove = useCallback(async () => { if (doingActionRef.current) return try { handleSetDoingAction(true) await deletePluginOAuthCustomClient() toast.success(t(($) => $['api.actionSuccess'], { ns: 'common' })) onOpenChange?.(false) onClose?.() onUpdate?.() invalidPluginOAuthClientSchema() } finally { handleSetDoingAction(false) } }, [ onUpdate, invalidPluginOAuthClientSchema, deletePluginOAuthCustomClient, t, handleSetDoingAction, onClose, onOpenChange, ]) const form = useForm({ defaultValues: editValues || defaultValues, }) const __oauth_client__ = useStore(form.store, (s) => s.values.__oauth_client__) const isDisabled = disabled || doingAction return (
{t(($) => $['auth.oauthClientSettings'], { ns: 'plugin' })} $['operation.close'], { ns: 'common' })} size="lg" className="absolute top-5 right-5" > } />
{pluginPayload.detail && ( )}
{__oauth_client__ === 'custom' && hasOriginalClientParams && ( )}
) } export default memo(OAuthClientSettings)