Skip to content

Commit 415b243

Browse files
author
Lasim
committed
refactor: enhance server selection step with automatic progression and improve localization for server details
1 parent af20218 commit 415b243

File tree

3 files changed

+63
-66
lines changed

3 files changed

+63
-66
lines changed

services/frontend/src/components/mcp-server/wizard/McpServerInstallWizard.vue

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -313,6 +313,7 @@ onMounted(async () => {
313313
v-if="currentStep === 0"
314314
v-model="formData.server.server_id"
315315
@server-selected="handleServerSelected"
316+
@next-step="nextStep"
316317
/>
317318

318319
<!-- Environment Variables Step -->

services/frontend/src/components/mcp-server/wizard/McpServerSelectionStep.vue

Lines changed: 56 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ const modelValue = defineModel<string>({ required: true })
1313
const emit = defineEmits<{
1414
// eslint-disable-next-line @typescript-eslint/no-explicit-any
1515
serverSelected: [serverData: any]
16+
nextStep: []
1617
}>()
1718
1819
const { t } = useI18n()
@@ -64,6 +65,9 @@ const handleInstallClick = (server: any) => {
6465
6566
// Emit server data to parent
6667
emit('serverSelected', server)
68+
69+
// Automatically advance to next step
70+
emit('nextStep')
6771
}
6872
6973
// eslint-disable-next-line @typescript-eslint/no-explicit-any
@@ -75,18 +79,7 @@ const performSearch = () => {
7579
searchQuery.value = searchTerm.value
7680
}
7781
78-
const getStatusClasses = (status: string) => {
79-
switch (status?.toLowerCase()) {
80-
case 'active':
81-
return 'text-green-700 bg-green-50 ring-green-600/20'
82-
case 'deprecated':
83-
return 'text-red-700 bg-red-50 ring-red-600/20'
84-
case 'beta':
85-
return 'text-yellow-800 bg-yellow-50 ring-yellow-600/20'
86-
default:
87-
return 'text-gray-600 bg-gray-50 ring-gray-500/10'
88-
}
89-
}
82+
9083
9184
// Lifecycle
9285
onMounted(() => {
@@ -156,61 +149,59 @@ onMounted(() => {
156149
</div>
157150

158151
<!-- Server List (only show when there's a search query) -->
159-
<div v-else-if="searchQuery.trim() && filteredServers.length > 0">
160-
<ul role="list" class="divide-y divide-gray-100">
161-
<li
162-
v-for="server in filteredServers"
163-
:key="server.id"
164-
class="flex items-center justify-between gap-x-6 py-5"
165-
>
166-
<div class="min-w-0">
167-
<div class="flex items-start gap-x-3">
168-
<p class="text-sm/6 font-semibold text-gray-900">{{ server.name }}</p>
169-
<p :class="[getStatusClasses(server.status || 'Active'), 'mt-0.5 rounded-md px-1.5 py-0.5 text-xs font-medium whitespace-nowrap ring-1 ring-inset']">
170-
{{ server.status || 'Active' }}
171-
</p>
172-
</div>
173-
<div class="mt-1 flex items-center gap-x-2 text-xs/5 text-gray-500">
174-
<p class="truncate">{{ server.description }}</p>
175-
<svg v-if="server.author_name" viewBox="0 0 2 2" class="size-0.5 fill-current">
176-
<circle cx="1" cy="1" r="1" />
177-
</svg>
178-
<p v-if="server.author_name" class="whitespace-nowrap">{{ server.author_name }}</p>
179-
<svg v-if="server.language" viewBox="0 0 2 2" class="size-0.5 fill-current">
180-
<circle cx="1" cy="1" r="1" />
181-
</svg>
182-
<p v-if="server.language" class="whitespace-nowrap">{{ server.language }}</p>
183-
</div>
152+
<div v-else-if="searchQuery.trim() && filteredServers.length > 0" class="space-y-4">
153+
<div
154+
v-for="server in filteredServers"
155+
:key="server.id"
156+
class="bg-gray-50 px-4 py-6 sm:rounded-lg sm:p-6 md:flex md:items-center md:justify-between md:space-x-6 lg:space-x-8"
157+
>
158+
<dl class="flex-auto divide-y divide-gray-200 text-sm text-gray-600 md:grid md:grid-cols-3 md:gap-x-6 md:divide-y-0 lg:w-1/2 lg:flex-none lg:gap-x-8">
159+
<div class="max-md:flex max-md:justify-between max-md:py-4 max-md:first:pt-0 max-md:last:pb-0">
160+
<dt class="font-medium text-gray-900">{{ t('mcpInstallations.wizard.server.name') }}</dt>
161+
<dd class="md:mt-1">{{ server.name }}</dd>
184162
</div>
185-
186-
<!-- Button Group -->
187-
<div class="flex flex-none items-center gap-x-4">
188-
<span class="isolate inline-flex rounded-md shadow-xs">
189-
<button
190-
type="button"
191-
@click="handleDetailsClick(server)"
192-
class="relative inline-flex items-center gap-x-1.5 rounded-l-md bg-white px-3 py-2 text-sm font-semibold text-gray-900 ring-1 ring-gray-300 ring-inset hover:bg-gray-50 focus:z-10"
193-
>
194-
<Info class="-ml-0.5 size-4 text-gray-400" aria-hidden="true" />
195-
{{ t('mcpInstallations.wizard.server.details') }}
196-
</button>
197-
<button
198-
type="button"
199-
@click="handleInstallClick(server)"
200-
:class="[
201-
'relative -ml-px inline-flex items-center gap-x-1.5 rounded-r-md px-3 py-2 text-sm font-semibold ring-1 ring-inset focus:z-10',
202-
selectedServerId === server.id
203-
? 'bg-blue-600 text-white ring-blue-600 hover:bg-blue-700'
204-
: 'bg-white text-gray-900 ring-gray-300 hover:bg-gray-50'
205-
]"
206-
>
207-
<Download class="-ml-0.5 size-4" :class="selectedServerId === server.id ? 'text-white' : 'text-gray-400'" aria-hidden="true" />
208-
{{ t('mcpInstallations.wizard.server.install') }}
209-
</button>
210-
</span>
163+
<div class="max-md:flex max-md:justify-between max-md:py-4 max-md:first:pt-0 max-md:last:pb-0">
164+
<dt class="font-medium text-gray-900">{{ t('mcpInstallations.wizard.server.author') }}</dt>
165+
<dd class="md:mt-1">{{ server.author_name || t('mcpInstallations.wizard.server.unknownAuthor') }}</dd>
211166
</div>
212-
</li>
213-
</ul>
167+
<div class="max-md:flex max-md:justify-between max-md:py-4 max-md:first:pt-0 max-md:last:pb-0">
168+
<dt class="font-medium text-gray-900">{{ t('mcpInstallations.wizard.server.language') }}</dt>
169+
<dd class="md:mt-1">{{ server.language || t('mcpInstallations.wizard.server.unknownLanguage') }}</dd>
170+
</div>
171+
</dl>
172+
173+
<!-- Description -->
174+
<div v-if="server.description" class="mt-4 md:mt-0 md:ml-6 lg:w-1/2">
175+
<p class="text-sm text-gray-600">{{ server.description }}</p>
176+
</div>
177+
178+
<!-- Action Buttons -->
179+
<div class="mt-6 space-y-4 sm:flex sm:space-y-0 sm:space-x-4 md:mt-0">
180+
<Button
181+
variant="outline"
182+
@click="handleDetailsClick(server)"
183+
class="flex w-full items-center justify-center border border-gray-300 bg-white px-4 py-2 text-sm font-medium text-gray-700 shadow-xs hover:bg-gray-50 md:w-auto"
184+
>
185+
<Info class="h-4 w-4 mr-2" />
186+
{{ t('mcpInstallations.wizard.server.details') }}
187+
<span class="sr-only">{{ server.name }}</span>
188+
</Button>
189+
<Button
190+
@click="handleInstallClick(server)"
191+
:variant="selectedServerId === server.id ? 'default' : 'outline'"
192+
:class="[
193+
'flex w-full items-center justify-center px-4 py-2 text-sm font-medium shadow-xs md:w-auto',
194+
selectedServerId === server.id
195+
? 'border border-indigo-600 bg-indigo-600 text-white hover:bg-indigo-700'
196+
: 'border border-gray-300 bg-white text-gray-700 hover:bg-gray-50'
197+
]"
198+
>
199+
<Download class="h-4 w-4 mr-2" />
200+
{{ t('mcpInstallations.wizard.server.install') }}
201+
<span class="sr-only">{{ server.name }}</span>
202+
</Button>
203+
</div>
204+
</div>
214205
</div>
215206

216207
<!-- No Results -->

services/frontend/src/i18n/locales/en/mcp-installations.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,12 @@ export default {
7474
noServersAvailable: 'No MCP servers are currently available',
7575
requiredEnvVars: 'Required Environment Variables',
7676
details: 'Details',
77-
install: 'Install'
77+
install: 'Install',
78+
name: 'Server Name',
79+
author: 'Author',
80+
language: 'Language',
81+
unknownAuthor: 'Unknown Author',
82+
unknownLanguage: 'Not Specified'
7883
},
7984

8085
environment: {

0 commit comments

Comments
 (0)