'use client' import type { AgentAppCopyPayload, AgentAppPartial, } 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 { Field, FieldControl, FieldLabel } from '@langgenius/dify-ui/field' import { Form } from '@langgenius/dify-ui/form' import { Textarea } from '@langgenius/dify-ui/textarea' import { toast } from '@langgenius/dify-ui/toast' import { useMutation, useQueryClient } from '@tanstack/react-query' import { useState } from 'react' import { useTranslation } from 'react-i18next' import AppIcon from '@/app/components/base/app-icon' import AppIconPicker from '@/app/components/base/app-icon-picker' import { consoleQuery } from '@/service/client' import { createAgentIconSelection } from './agent-form' type DuplicateAgentDialogProps = { agent: AgentAppPartial formKey: number open: boolean onOpenChange: (open: boolean) => void } const getDefaultCopyName = (name: string) => { const suffix = ' copy' return `${name.slice(0, 255 - suffix.length)}${suffix}` } export function DuplicateAgentDialog({ agent, formKey, open, onOpenChange, }: DuplicateAgentDialogProps) { const { t } = useTranslation('agentV2') const { t: tCommon } = useTranslation('common') const queryClient = useQueryClient() const latestAgent = queryClient.getQueryData( consoleQuery.agent.byAgentId.get.queryKey({ input: { params: { agent_id: agent.id, }, }, }), ) ?? agent const [renderedFormKey, setRenderedFormKey] = useState(formKey) const [name, setName] = useState('') const [description, setDescription] = useState(latestAgent.description ?? '') const [role, setRole] = useState(latestAgent.role ?? '') const [iconPickerOpen, setIconPickerOpen] = useState(false) const [agentIcon, setAgentIcon] = useState(() => createAgentIconSelection(latestAgent), ) const duplicateAgentMutation = useMutation( consoleQuery.agent.byAgentId.copy.post.mutationOptions(), ) const defaultCopyName = getDefaultCopyName(latestAgent.name) if (formKey !== renderedFormKey) { setRenderedFormKey(formKey) setName('') setDescription(latestAgent.description ?? '') setRole(latestAgent.role ?? '') setIconPickerOpen(false) setAgentIcon(createAgentIconSelection(latestAgent)) } const handleOpenChange = (nextOpen: boolean) => { if (nextOpen) { const currentAgent = queryClient.getQueryData( consoleQuery.agent.byAgentId.get.queryKey({ input: { params: { agent_id: agent.id, }, }, }), ) ?? agent setName('') setDescription(currentAgent.description ?? '') setRole(currentAgent.role ?? '') setAgentIcon(createAgentIconSelection(currentAgent)) } else { setIconPickerOpen(false) } onOpenChange(nextOpen) } const handleSubmit = (formValues: AgentFormValues) => { if (duplicateAgentMutation.isPending) return const trimmedName = formValues.name?.trim() ?? '' const trimmedRole = formValues.role?.trim() ?? '' const body: AgentAppCopyPayload = { description: formValues.description?.trim() ?? '', role: trimmedRole, icon_type: agentIcon.type, icon: agentIcon.type === 'image' ? agentIcon.fileId : agentIcon.icon, icon_background: agentIcon.type === 'emoji' ? agentIcon.background : undefined, ...(trimmedName ? { name: trimmedName } : {}), } duplicateAgentMutation.mutate( { params: { agent_id: agent.id, }, body, }, { onSuccess: () => { toast.success(t(($) => $['roster.duplicateSuccess'])) handleOpenChange(false) }, }, ) } return ( <>
{t(($) => $['roster.duplicateDialog.title'])} {t(($) => $['roster.duplicateDialog.description'], { name: latestAgent.name })}
key={formKey} className="min-h-0 flex-1" onFormSubmit={handleSubmit} >
{t(($) => $['roster.createForm.nameLabel'])} {tCommon(($) => $['label.optional'])} {t(($) => $['roster.createForm.roleLabel'])} {tCommon(($) => $['label.optional'])} $['roster.createForm.rolePlaceholder'])} value={role} />
{t(($) => $['roster.createForm.descriptionLabel'])} {tCommon(($) => $['label.optional'])}