@@ -10,9 +10,10 @@ import { Button } from '@/components/ui/button'
1010import { ButtonGroup } from ' @/components/ui/button-group'
1111import { Spinner } from ' @/components/ui/spinner'
1212import { Alert , AlertDescription } from ' @/components/ui/alert'
13- import { AlertCircle , Package , CircleCheck , CircleMinus } from ' lucide-vue-next'
13+ import { AlertCircle , Package , CircleCheck , CircleMinus , ChevronRight , ChevronDown } from ' lucide-vue-next'
1414import type { McpInstallation } from ' @/types/mcp-installations'
1515import ToolsMetricsPanel from ' ./ToolsMetricsPanel.vue'
16+ import { CodeHighlight } from ' @/components/ui/code-highlight'
1617
1718interface Props {
1819 installation: McpInstallation
@@ -35,6 +36,18 @@ const error = ref<string | null>(null)
3536const selectedToolIds = ref <string []>([])
3637const isBulkToggling = ref (false )
3738
39+ // Track expanded rows
40+ const expandedRows = ref <Set <string >>(new Set ())
41+
42+ // Toggle row expansion
43+ const toggleRow = (toolId : string ) => {
44+ if (expandedRows .value .has (toolId )) {
45+ expandedRows .value .delete (toolId )
46+ } else {
47+ expandedRows .value .add (toolId )
48+ }
49+ }
50+
3851// Format token count with commas
3952const formatTokenCount = (count : number ) => {
4053 return count .toLocaleString ()
@@ -262,55 +275,92 @@ async function handleBulkToggle(isDisabled: boolean) {
262275 @update:checked =" toggleAllTools"
263276 />
264277 </TableHead >
278+ <TableHead class =" w-12" ></TableHead >
265279 <TableHead >{{ t('mcpInstallations.details.tools.table.columns.status') }}</TableHead >
266280 <TableHead >{{ t('mcpInstallations.details.tools.table.columns.toolName') }}</TableHead >
267- <TableHead >{{ t('mcpInstallations.details.tools.table.columns.description') }}</TableHead >
281+ <TableHead class = " w-96 " >{{ t('mcpInstallations.details.tools.table.columns.description') }}</TableHead >
268282 <TableHead class =" text-right" >{{ t('mcpInstallations.details.tools.table.columns.tokenCount') }}</TableHead >
269283 <TableHead class =" text-right" >{{ t('mcpInstallations.details.tools.table.columns.distribution') }}</TableHead >
270284 </TableRow >
271285 </TableHeader >
272286 <TableBody >
273- <TableRow v-for =" tool in tools.tools" :key =" tool.id" >
274- <TableCell >
275- <Checkbox
276- :checked =" isToolSelected(tool.id)"
277- :disabled =" !props.canEdit"
278- @update:checked =" () => toggleToolSelection(tool.id)"
279- />
280- </TableCell >
281- <TableCell >
282- <div
283- class =" inline-flex items-center justify-center rounded-full border px-1.5 py-0.5 text-xs font-medium text-muted-foreground gap-1"
284- >
285- <CircleCheck
286- v-if =" !tool.is_disabled"
287- class =" size-3 fill-green-500 text-green-500 dark:fill-green-400 dark:text-green-400"
287+ <template v-for =" tool in tools .tools " :key =" tool .id " >
288+ <!-- Main Tool Row (clickable) -->
289+ <TableRow
290+ class =" cursor-pointer hover:bg-muted/50"
291+ @click.stop =" toggleRow(tool.id)"
292+ >
293+ <TableCell @click.stop >
294+ <Checkbox
295+ :checked =" isToolSelected(tool.id)"
296+ :disabled =" !props.canEdit"
297+ @update:checked =" () => toggleToolSelection(tool.id)"
288298 />
289- <CircleMinus
290- v-else
291- class =" size-3 text-muted-foreground"
292- />
293- <span >
294- {{ tool.is_disabled
295- ? t('mcpInstallations.details.tools.table.values.disabled')
296- : t('mcpInstallations.details.tools.table.values.enabled')
297- }}
298- </span >
299- </div >
300- </TableCell >
301- <TableCell class =" text-sm font-medium" >{{ tool.tool_name }}</TableCell >
302- <TableCell class =" text-sm text-muted-foreground max-w-2xl" >
303- <div class =" whitespace-normal wrap-break-word" >
304- {{ tool.description || t('mcpInstallations.details.tools.table.values.noDescription') }}
305- </div >
306- </TableCell >
307- <TableCell class =" text-right whitespace-nowrap text-sm font-medium" >
308- {{ formatTokenCount(tool.token_count) }}
309- </TableCell >
310- <TableCell class =" text-right whitespace-nowrap text-sm text-muted-foreground" >
311- {{ calculateTokenPercentage(tool.token_count) }}
312- </TableCell >
313- </TableRow >
299+ </TableCell >
300+ <TableCell >
301+ <Button variant =" ghost" size =" icon" class =" h-6 w-6" >
302+ <ChevronRight v-if =" !expandedRows.has(tool.id)" class =" h-4 w-4" />
303+ <ChevronDown v-else class =" h-4 w-4" />
304+ </Button >
305+ </TableCell >
306+ <TableCell >
307+ <div
308+ class =" inline-flex items-center justify-center rounded-full border px-1.5 py-0.5 text-xs font-medium text-muted-foreground gap-1"
309+ >
310+ <CircleCheck
311+ v-if =" !tool.is_disabled"
312+ class =" size-3 fill-green-500 text-green-500 dark:fill-green-400 dark:text-green-400"
313+ />
314+ <CircleMinus
315+ v-else
316+ class =" size-3 text-muted-foreground"
317+ />
318+ <span >
319+ {{ tool.is_disabled
320+ ? t('mcpInstallations.details.tools.table.values.disabled')
321+ : t('mcpInstallations.details.tools.table.values.enabled')
322+ }}
323+ </span >
324+ </div >
325+ </TableCell >
326+ <TableCell class =" text-sm font-medium" >{{ tool.tool_name }}</TableCell >
327+ <TableCell class =" text-sm text-muted-foreground w-96" >
328+ <div class =" truncate" >
329+ {{ tool.description || t('mcpInstallations.details.tools.table.values.noDescription') }}
330+ </div >
331+ </TableCell >
332+ <TableCell class =" text-right whitespace-nowrap text-sm font-medium" >
333+ {{ formatTokenCount(tool.token_count) }}
334+ </TableCell >
335+ <TableCell class =" text-right whitespace-nowrap text-sm text-muted-foreground" >
336+ {{ calculateTokenPercentage(tool.token_count) }}
337+ </TableCell >
338+ </TableRow >
339+
340+ <!-- Expanded Detail Row -->
341+ <TableRow v-if =" expandedRows.has(tool.id)" class =" bg-muted/30" >
342+ <TableCell colspan =" 7" class =" p-6" >
343+ <div class =" grid grid-cols-1 md:grid-cols-2 gap-6" >
344+ <!-- Left: Full Description -->
345+ <div >
346+ <h4 class =" text-sm font-semibold mb-2" >{{ t('mcpInstallations.details.tools.detail.description') }}</h4 >
347+ <p class =" text-sm text-muted-foreground" >
348+ {{ tool.description || t('mcpInstallations.details.tools.table.values.noDescription') }}
349+ </p >
350+ </div >
351+
352+ <!-- Right: Input Schema -->
353+ <div >
354+ <h4 class =" text-sm font-semibold mb-2" >{{ t('mcpInstallations.details.tools.detail.inputSchema') }}</h4 >
355+ <CodeHighlight
356+ :code =" JSON.stringify(tool.input_schema, null, 2)"
357+ language =" json"
358+ />
359+ </div >
360+ </div >
361+ </TableCell >
362+ </TableRow >
363+ </template >
314364 </TableBody >
315365 </Table >
316366 </div >
0 commit comments