mirror of
https://github.com/BerriAI/litellm.git
synced 2026-10-04 02:31:27 +00:00
feat(ui): mcp_connection_status to shadcn
- antd Button/Spin/Alert/Collapse + @tremor Card/Title/Text + @ant-design Check/Exclamation/Reload/Tool \u2192 shadcn Card/Button/ Accordion + lucide CheckCircle2/AlertTriangle/RefreshCcw/Wrench/ Loader2. - Error state renders a destructive-tinted panel with Retry button and collapsible stack trace inside an Accordion. - Categorical blue (info/connecting), emerald (connected), and destructive (failed) palettes are already covered by existing overrides. Gates: TS \u2713 | Build \u2713. Co-authored-by: yuneng-jiang <yuneng-berri@users.noreply.github.com>
This commit is contained in:
parent
2b5034cab3
commit
6905f05ef0
1 changed files with 81 additions and 71 deletions
|
|
@ -1,10 +1,24 @@
|
|||
import React from "react";
|
||||
import { Button, Spin, Alert, Collapse } from "antd";
|
||||
import { CheckCircleOutlined, ExclamationCircleOutlined, ReloadOutlined, ToolOutlined } from "@ant-design/icons";
|
||||
import { Card, Title, Text } from "@tremor/react";
|
||||
import {
|
||||
Accordion,
|
||||
AccordionContent,
|
||||
AccordionItem,
|
||||
AccordionTrigger,
|
||||
} from "@/components/ui/accordion";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { Card } from "@/components/ui/card";
|
||||
import {
|
||||
AlertTriangle,
|
||||
CheckCircle2,
|
||||
Loader2,
|
||||
RefreshCcw,
|
||||
Wrench,
|
||||
} from "lucide-react";
|
||||
|
||||
interface MCPConnectionStatusProps {
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
formValues: Record<string, any>;
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
tools: any[];
|
||||
isLoadingTools: boolean;
|
||||
toolsError: string | null;
|
||||
|
|
@ -22,26 +36,26 @@ const MCPConnectionStatus: React.FC<MCPConnectionStatusProps> = ({
|
|||
canFetchTools,
|
||||
fetchTools,
|
||||
}) => {
|
||||
|
||||
// Don't show anything if required fields aren't filled
|
||||
if (!canFetchTools && !formValues.url && !formValues.spec_path) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (
|
||||
<Card>
|
||||
<Card className="p-4">
|
||||
<div className="space-y-4">
|
||||
<div className="flex items-center gap-2">
|
||||
<CheckCircleOutlined className="text-blue-600" />
|
||||
<Title>Connection Status</Title>
|
||||
<CheckCircle2 className="h-4 w-4 text-blue-600 dark:text-blue-400" />
|
||||
<h3 className="text-lg font-semibold">Connection Status</h3>
|
||||
</div>
|
||||
|
||||
{!canFetchTools && (formValues.url || formValues.spec_path) && (
|
||||
<div className="text-center py-6 text-gray-400 border rounded-lg border-dashed">
|
||||
<ToolOutlined className="text-2xl mb-2" />
|
||||
<Text>Complete required fields to test connection</Text>
|
||||
<br />
|
||||
<Text className="text-sm">Fill in URL, Transport, and Authentication to test MCP server connection</Text>
|
||||
<div className="text-center py-6 text-muted-foreground border border-dashed border-border rounded-lg">
|
||||
<Wrench className="h-6 w-6 mx-auto mb-2" />
|
||||
<div>Complete required fields to test connection</div>
|
||||
<div className="text-sm">
|
||||
Fill in URL, Transport, and Authentication to test MCP server
|
||||
connection
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
|
||||
|
|
@ -49,7 +63,7 @@ const MCPConnectionStatus: React.FC<MCPConnectionStatusProps> = ({
|
|||
<div>
|
||||
<div className="flex items-center justify-between mb-4">
|
||||
<div>
|
||||
<Text className="text-gray-700 font-medium">
|
||||
<div className="text-foreground font-medium">
|
||||
{isLoadingTools
|
||||
? "Testing connection to MCP server..."
|
||||
: tools.length > 0
|
||||
|
|
@ -57,91 +71,87 @@ const MCPConnectionStatus: React.FC<MCPConnectionStatusProps> = ({
|
|||
: toolsError
|
||||
? "Connection failed"
|
||||
: "Ready to test connection"}
|
||||
</Text>
|
||||
<br />
|
||||
<Text className="text-gray-500 text-sm">Server: {formValues.url || formValues.spec_path}</Text>
|
||||
</div>
|
||||
<div className="text-muted-foreground text-sm">
|
||||
Server: {formValues.url || formValues.spec_path}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{isLoadingTools && (
|
||||
<div className="flex items-center text-blue-600">
|
||||
<Spin size="small" className="mr-2" />
|
||||
<Text className="text-blue-600">Connecting...</Text>
|
||||
<div className="flex items-center text-blue-600 dark:text-blue-400">
|
||||
<Loader2 className="h-4 w-4 animate-spin mr-2" />
|
||||
<span>Connecting...</span>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{!isLoadingTools && !toolsError && tools.length > 0 && (
|
||||
<div className="flex items-center text-green-600">
|
||||
<CheckCircleOutlined className="mr-1" />
|
||||
<Text className="text-green-600 font-medium">Connected</Text>
|
||||
<div className="flex items-center text-emerald-600 dark:text-emerald-400">
|
||||
<CheckCircle2 className="h-4 w-4 mr-1" />
|
||||
<span className="font-medium">Connected</span>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{toolsError && (
|
||||
<div className="flex items-center text-red-600">
|
||||
<ExclamationCircleOutlined className="mr-1" />
|
||||
<Text className="text-red-600 font-medium">Failed</Text>
|
||||
<div className="flex items-center text-destructive">
|
||||
<AlertTriangle className="h-4 w-4 mr-1" />
|
||||
<span className="font-medium">Failed</span>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
|
||||
{isLoadingTools && (
|
||||
<div className="flex items-center justify-center py-6">
|
||||
<Spin size="large" />
|
||||
<Text className="ml-3">Testing connection and loading tools...</Text>
|
||||
<div className="flex items-center justify-center py-6 gap-3">
|
||||
<Loader2 className="h-6 w-6 animate-spin text-primary" />
|
||||
<span>Testing connection and loading tools...</span>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{toolsError && (
|
||||
<Alert
|
||||
message="Connection Failed"
|
||||
description={
|
||||
<div>
|
||||
<div>{toolsError}</div>
|
||||
{toolsErrorStackTrace && (
|
||||
<Collapse
|
||||
items={[
|
||||
{
|
||||
key: "stack-trace",
|
||||
label: "Stack Trace",
|
||||
children: (
|
||||
<pre style={{
|
||||
whiteSpace: "pre-wrap",
|
||||
wordBreak: "break-word",
|
||||
fontSize: "12px",
|
||||
fontFamily: "monospace",
|
||||
margin: 0,
|
||||
padding: "8px",
|
||||
backgroundColor: "#f5f5f5",
|
||||
borderRadius: "4px",
|
||||
maxHeight: "400px",
|
||||
overflow: "auto"
|
||||
}}>
|
||||
<div className="p-3 bg-destructive/10 border border-destructive/30 rounded-md">
|
||||
<div className="flex justify-between items-start gap-2">
|
||||
<div className="flex gap-2 flex-1">
|
||||
<AlertTriangle className="h-4 w-4 mt-0.5 text-destructive shrink-0" />
|
||||
<div className="flex-1 text-sm">
|
||||
<div className="font-semibold text-destructive">
|
||||
Connection Failed
|
||||
</div>
|
||||
<div>{toolsError}</div>
|
||||
{toolsErrorStackTrace && (
|
||||
<Accordion type="single" collapsible className="mt-3">
|
||||
<AccordionItem value="stack-trace">
|
||||
<AccordionTrigger>Stack Trace</AccordionTrigger>
|
||||
<AccordionContent>
|
||||
<pre className="whitespace-pre-wrap break-words text-xs font-mono m-0 p-2 bg-muted rounded max-h-[400px] overflow-auto">
|
||||
{toolsErrorStackTrace}
|
||||
</pre>
|
||||
),
|
||||
},
|
||||
]}
|
||||
style={{ marginTop: "12px" }}
|
||||
/>
|
||||
)}
|
||||
</AccordionContent>
|
||||
</AccordionItem>
|
||||
</Accordion>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
type="error"
|
||||
showIcon
|
||||
action={
|
||||
<Button icon={<ReloadOutlined />} onClick={fetchTools} size="small">
|
||||
<Button
|
||||
size="sm"
|
||||
variant="outline"
|
||||
onClick={fetchTools}
|
||||
className="shrink-0"
|
||||
>
|
||||
<RefreshCcw className="h-3 w-3" />
|
||||
Retry
|
||||
</Button>
|
||||
}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{!isLoadingTools && tools.length === 0 && !toolsError && (
|
||||
<div className="text-center py-6 text-gray-500 border rounded-lg border-dashed">
|
||||
<CheckCircleOutlined className="text-2xl mb-2 text-green-500" />
|
||||
<Text className="text-green-600 font-medium">Connection successful!</Text>
|
||||
<br />
|
||||
<Text className="text-gray-500">No tools found for this MCP server</Text>
|
||||
<div className="text-center py-6 text-muted-foreground border border-dashed border-border rounded-lg">
|
||||
<CheckCircle2 className="h-6 w-6 mx-auto mb-2 text-emerald-500" />
|
||||
<div className="text-emerald-600 dark:text-emerald-400 font-medium">
|
||||
Connection successful!
|
||||
</div>
|
||||
<div className="text-muted-foreground">
|
||||
No tools found for this MCP server
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue