Skip to content

Commit a546d47

Browse files
authored
feat(mcp): align feedback on custom server installation (#651)
* feat(mcp): align feedback on custom server installation * refactor: move the from console.log to log * refactor: use _ for unused param
1 parent 762e961 commit a546d47

File tree

13 files changed

+1094
-1249
lines changed

13 files changed

+1094
-1249
lines changed

renderer/src/features/registry-servers/components/loading-state-alert.tsx renamed to renderer/src/common/components/secrets/loading-state-alert.tsx

File renamed without changes.

renderer/src/features/registry-servers/components/alert-error-form-submission.tsx renamed to renderer/src/common/components/workloads/alert-error-form-submission.tsx

File renamed without changes.

renderer/src/features/mcp-servers/components/__tests__/dialog-form-run-mcp-command.test.tsx

Lines changed: 389 additions & 429 deletions
Large diffs are not rendered by default.

renderer/src/features/mcp-servers/components/dialog-form-run-mcp-command.tsx

Lines changed: 97 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,14 @@
1+
import { useState } from 'react'
2+
import { useForm } from 'react-hook-form'
3+
import { useQuery } from '@tanstack/react-query'
4+
import log from 'electron-log/renderer'
15
import { Form } from '@/common/components/ui/form'
26
import {
37
getFormSchemaRunMcpCommand,
48
type FormSchemaRunMcpCommand,
59
} from '../lib/form-schema-run-mcp-server-with-command'
6-
import { useForm } from 'react-hook-form'
7-
810
import { FormFieldsRunMcpCommand } from './form-fields-run-mcp-command'
11+
import { getApiV1BetaWorkloadsOptions } from '@/common/api/generated/@tanstack/react-query.gen'
912
import {
1013
Dialog,
1114
DialogContent,
@@ -18,18 +21,43 @@ import { Button } from '@/common/components/ui/button'
1821
import { zodV4Resolver } from '@/common/lib/zod-v4-resolver'
1922
import { FormFieldsArrayCustomEnvVars } from './form-fields-array-custom-env-vars'
2023
import { FormFieldsArrayCustomSecrets } from './form-fields-array-custom-secrets'
21-
import { useQuery } from '@tanstack/react-query'
22-
import { getApiV1BetaWorkloadsOptions } from '@/common/api/generated/@tanstack/react-query.gen'
24+
import { useRunCustomServer } from '../hooks/use-run-custom-server'
25+
import { LoadingStateAlert } from '@/common/components/secrets/loading-state-alert'
26+
import { AlertErrorFormSubmission } from '@/common/components/workloads/alert-error-form-submission'
2327

2428
export function DialogFormRunMcpServerWithCommand({
25-
onSubmit,
2629
isOpen,
2730
onOpenChange,
2831
}: {
29-
onSubmit: (data: FormSchemaRunMcpCommand) => void
3032
isOpen: boolean
3133
onOpenChange: (open: boolean) => void
3234
}) {
35+
const [error, setError] = useState<string | null>(null)
36+
const [isSubmitting, setIsSubmitting] = useState(false)
37+
const [loadingSecrets, setLoadingSecrets] = useState<{
38+
text: string
39+
completedCount: number
40+
secretsCount: number
41+
} | null>(null)
42+
const {
43+
installServerMutation,
44+
checkServerStatus,
45+
isErrorSecrets,
46+
isPendingSecrets,
47+
} = useRunCustomServer({
48+
onSecretSuccess: (completedCount, secretsCount) => {
49+
setLoadingSecrets((prev) => ({
50+
...prev,
51+
text: `Encrypting secrets (${completedCount} of ${secretsCount})...`,
52+
completedCount,
53+
secretsCount,
54+
}))
55+
},
56+
onSecretError: (error, variables) => {
57+
log.error('onSecretError', error, variables)
58+
},
59+
})
60+
3361
const { data } = useQuery({
3462
...getApiV1BetaWorkloadsOptions({ query: { all: true } }),
3563
})
@@ -44,6 +72,32 @@ export function DialogFormRunMcpServerWithCommand({
4472
},
4573
})
4674

75+
const onSubmitForm = (data: FormSchemaRunMcpCommand) => {
76+
setIsSubmitting(true)
77+
if (error) {
78+
setError(null)
79+
}
80+
81+
installServerMutation(
82+
{ data },
83+
{
84+
onSuccess: () => {
85+
checkServerStatus(data)
86+
onOpenChange(false)
87+
},
88+
onSettled: (_, error) => {
89+
setIsSubmitting(false)
90+
if (!error) {
91+
form.reset()
92+
}
93+
},
94+
onError: (error) => {
95+
setError(typeof error === 'string' ? error : error.message)
96+
},
97+
}
98+
)
99+
}
100+
47101
return (
48102
<Dialog open={isOpen} onOpenChange={onOpenChange}>
49103
<DialogContent
@@ -54,31 +108,52 @@ export function DialogFormRunMcpServerWithCommand({
54108
}}
55109
>
56110
<Form {...form}>
57-
<form
58-
onSubmit={form.handleSubmit((data) => {
59-
onSubmit(data)
60-
form.reset()
61-
onOpenChange(false)
62-
})}
63-
>
111+
<form onSubmit={form.handleSubmit(onSubmitForm)}>
64112
<DialogHeader className="mb-4 p-6">
65113
<DialogTitle>Custom MCP server</DialogTitle>
66114
<DialogDescription>
67115
ToolHive allows you to securely run a custom MCP server from a
68116
Docker image or a package manager command.
69117
</DialogDescription>
70118
</DialogHeader>
71-
72-
<div
73-
className="relative max-h-[65dvh] space-y-4 overflow-y-auto px-6"
74-
>
75-
<FormFieldsRunMcpCommand form={form} />
76-
<FormFieldsArrayCustomSecrets form={form} />
77-
<FormFieldsArrayCustomEnvVars form={form} />
78-
</div>
119+
{isSubmitting && (
120+
<LoadingStateAlert
121+
isPendingSecrets={isPendingSecrets}
122+
loadingSecrets={loadingSecrets}
123+
/>
124+
)}
125+
{!isSubmitting && (
126+
<div
127+
className="relative max-h-[65dvh] space-y-4 overflow-y-auto
128+
px-6"
129+
>
130+
{error && (
131+
<AlertErrorFormSubmission
132+
error={error}
133+
isErrorSecrets={isErrorSecrets}
134+
onDismiss={() => setError(null)}
135+
/>
136+
)}
137+
<FormFieldsRunMcpCommand form={form} />
138+
<FormFieldsArrayCustomSecrets form={form} />
139+
<FormFieldsArrayCustomEnvVars form={form} />
140+
</div>
141+
)}
79142

80143
<DialogFooter className="p-6">
81-
<Button type="submit">Install server</Button>
144+
<Button
145+
type="button"
146+
variant="outline"
147+
disabled={isSubmitting}
148+
onClick={() => {
149+
onOpenChange(false)
150+
}}
151+
>
152+
Cancel
153+
</Button>
154+
<Button disabled={isSubmitting} type="submit">
155+
Install server
156+
</Button>
82157
</DialogFooter>
83158
</form>
84159
</Form>

renderer/src/features/mcp-servers/hooks/use-run-custom-server.ts

Lines changed: 0 additions & 53 deletions
This file was deleted.

0 commit comments

Comments
 (0)