import { Collapse } from '@/components/collapse'; import { Button, ButtonLoading } from '@/components/ui/button'; import { Dialog, DialogContent, DialogFooter, DialogHeader, DialogTitle, } from '@/components/ui/dialog'; import { useGetMcpServer, useTestMcpServer } from '@/hooks/use-mcp-request'; import { IModalProps } from '@/interfaces/common'; import { IMCPTool, IMCPToolObject } from '@/interfaces/database/mcp'; import { zodResolver } from '@hookform/resolvers/zod'; import { isEmpty, omit, pick } from 'lodash'; import { RefreshCw } from 'lucide-react'; import { MouseEventHandler, useCallback, useMemo, useState } from 'react'; import { useForm } from 'react-hook-form'; import { useTranslation } from 'react-i18next'; import { z } from 'zod'; import { EditMcpForm, FormId, ServerType, useBuildFormSchema, } from './edit-mcp-form'; import { McpToolCard } from './tool-card'; function transferToolToObject(tools: IMCPTool[] = []) { return tools.reduce((pre, tool) => { pre[tool.name] = omit(tool, 'name'); return pre; }, {}); } function transferToolToArray(tools: IMCPToolObject) { return Object.entries(tools).reduce((pre, [name, tool]) => { pre.push({ ...tool, name }); return pre; }, []); } export function EditMcpDialog({ hideModal, loading, onOk, id, }: IModalProps & { id: string }) { const { t } = useTranslation(); const { testMcpServer, data: tools, loading: testLoading, } = useTestMcpServer(); const [isTriggeredBySaving, setIsTriggeredBySaving] = useState(false); const FormSchema = useBuildFormSchema(); const [collapseOpen, setCollapseOpen] = useState(true); const { data } = useGetMcpServer(id); const form = useForm>({ resolver: zodResolver(FormSchema), values: isEmpty(data) ? { name: '', server_type: ServerType.SSE, url: '' } : pick(data, ['name', 'server_type', 'url']), }); console.log('🚀 ~ form:', form.formState.dirtyFields); const handleTest: MouseEventHandler = useCallback((e) => { e.stopPropagation(); setIsTriggeredBySaving(false); }, []); const handleSave: MouseEventHandler = useCallback(() => { setIsTriggeredBySaving(true); }, []); const handleOk = async (values: z.infer) => { if (isTriggeredBySaving) { onOk?.({ ...values, variables: { ...(values?.variables || {}), tools: transferToolToObject(tools), }, }); } else { testMcpServer(values); } }; const nextTools = useMemo(() => { return tools || transferToolToArray(data.variables?.tools || {}); }, [data.variables?.tools, tools]); const dirtyFields = form.formState.dirtyFields; const fieldChanged = 'server_type' in dirtyFields || 'url' in dirtyFields; const disabled = !!!tools?.length || testLoading || fieldChanged; return ( Edit profile {tools?.length || 0} tools available} open={collapseOpen} onOpenChange={setCollapseOpen} rightContent={ } >
{nextTools?.map((x) => ( ))}
{t('common.save')}
); }