'use client' import type { AgentAppPartial, AgentAppUpdatePayload, } from '@dify/contracts/api/console/agent/types.gen' import type { AgentFormValues, AgentIconSelection } from './agent-form' import { Button } from '@langgenius/dify-ui/button' import { Dialog, DialogCloseButton, DialogContent, DialogDescription, DialogTitle, } from '@langgenius/dify-ui/dialog' import { Form } from '@langgenius/dify-ui/form' import { toast } from '@langgenius/dify-ui/toast' import { useMutation } from '@tanstack/react-query' import { useState } from 'react' import { useTranslation } from 'react-i18next' import AppIconPicker from '@/app/components/base/app-icon-picker' import { consoleQuery } from '@/service/client' import { createAgentIconSelection, getAgentIconKey } from './agent-form' import { AgentFormFields } from './agent-form-fields' type EditAgentDialogProps = { agent: AgentAppPartial formKey: number open: boolean onOpenChange: (open: boolean) => void } const applyIconPayload = (body: AgentAppUpdatePayload, icon: AgentIconSelection) => { if (icon.type === 'emoji') { body.icon_type = icon.type body.icon = icon.icon body.icon_background = icon.background return } body.icon_type = icon.type body.icon = icon.type === 'image' ? icon.fileId : icon.icon body.icon_background = undefined } export function EditAgentDialog({ agent, formKey, open, onOpenChange }: EditAgentDialogProps) { const { t } = useTranslation('agentV2') const { t: tCommon } = useTranslation('common') const [renderedFormKey, setRenderedFormKey] = useState(formKey) const [name, setName] = useState(agent.name) const [description, setDescription] = useState(agent.description ?? '') const [role, setRole] = useState(agent.role ?? '') const [iconPickerOpen, setIconPickerOpen] = useState(false) const [agentIcon, setAgentIcon] = useState(() => createAgentIconSelection(agent), ) const updateAgentMutation = useMutation(consoleQuery.agent.byAgentId.put.mutationOptions()) if (formKey !== renderedFormKey) { setRenderedFormKey(formKey) setName(agent.name) setDescription(agent.description ?? '') setRole(agent.role ?? '') setIconPickerOpen(false) setAgentIcon(createAgentIconSelection(agent)) } const handleOpenChange = (nextOpen: boolean) => { if (nextOpen) { setName(agent.name) setDescription(agent.description ?? '') setRole(agent.role ?? '') setAgentIcon(createAgentIconSelection(agent)) } else { setIconPickerOpen(false) } onOpenChange(nextOpen) } const handleSubmit = (formValues: AgentFormValues) => { const trimmedName = formValues.name?.trim() ?? '' const trimmedDescription = formValues.description?.trim() ?? '' const trimmedRole = formValues.role?.trim() ?? '' const hasIconChanges = getAgentIconKey(agentIcon) !== getAgentIconKey(createAgentIconSelection(agent)) const hasFormChanges = trimmedName !== agent.name.trim() || trimmedDescription !== (agent.description?.trim() ?? '') || trimmedRole !== (agent.role?.trim() ?? '') || hasIconChanges if (updateAgentMutation.isPending) return if (!hasFormChanges) return const body: AgentAppUpdatePayload = { name: trimmedName, description: trimmedDescription, // Keep sending the trimmed role even when empty: omitting the field // preserves the current backing-agent role, while "" intentionally clears it. role: trimmedRole, } applyIconPayload(body, agentIcon) updateAgentMutation.mutate( { params: { agent_id: agent.id, }, body, }, { onSuccess: () => { toast.success(t(($) => $['roster.updateSuccess'])) handleOpenChange(false) }, }, ) } const trimmedName = name.trim() const trimmedDescription = description.trim() const trimmedRole = role.trim() const hasIconChanges = getAgentIconKey(agentIcon) !== getAgentIconKey(createAgentIconSelection(agent)) const hasChanges = trimmedName !== agent.name.trim() || trimmedDescription !== (agent.description?.trim() ?? '') || trimmedRole !== (agent.role?.trim() ?? '') || hasIconChanges return ( <>
{t(($) => $['roster.editDialog.title'])} {t(($) => $['roster.editDialog.description'])}
key={formKey} className="min-h-0 flex-1" onFormSubmit={handleSubmit} > $['roster.editAgent'], { name: agent.name })} name={name} role={role} onDescriptionChange={setDescription} onIconClick={() => setIconPickerOpen(true)} onNameChange={setName} onRoleChange={setRole} />
) }