From fa9d5ae6d93a8dde09c7da4d7b65857727b441db Mon Sep 17 00:00:00 2001 From: Cursor Agent Date: Thu, 23 Apr 2026 12:38:58 +0000 Subject: [PATCH] feat(ui): SearchResultsDisplay + PromptMessagesCard + LoggingCallbacksTable - SearchResultsDisplay: antd Button + @ant-design Database/FileText/ Chevrons \u2192 shadcn Button/Badge + lucide equivalents. Blue score chip added to categorical overrides. - PromptMessagesCard: @tremor Card/Text + antd Select \u2192 shadcn Card + Select. Drag-and-drop reorder preserved (pure HTML5 drag handlers, no antd dependency). - LoggingCallbacksTable: @tremor Button + antd Table/Title \u2192 shadcn Button + shadcn Table + plain h3. Categorical success/failure/info badges added to overrides. Gates: TS \u2713 | Build \u2713. Co-authored-by: yuneng-jiang --- ui/litellm-dashboard/.eslintrc.json | 2 + .../LoggingCallbacksTable.tsx | 177 ++++++++++-------- .../chat_ui/SearchResultsDisplay.tsx | 129 ++++++++----- .../prompt_editor_view/PromptMessagesCard.tsx | 77 +++++--- 4 files changed, 234 insertions(+), 151 deletions(-) diff --git a/ui/litellm-dashboard/.eslintrc.json b/ui/litellm-dashboard/.eslintrc.json index 4bb5c20ef67..7a9954200cc 100644 --- a/ui/litellm-dashboard/.eslintrc.json +++ b/ui/litellm-dashboard/.eslintrc.json @@ -62,6 +62,8 @@ "src/app/(dashboard)/teams/components/TeamsTable/ModelsCell.tsx", "src/components/prompts/prompt_editor_view/conversation_panel/MessageBubble.tsx", "src/components/playground/chat_ui/SessionManagement.tsx", + "src/components/playground/chat_ui/SearchResultsDisplay.tsx", + "src/components/Settings/LoggingAndAlerts/LoggingCallbacks/LoggingCallbacksTable.tsx", "src/components/policies/impact_preview_alert.tsx", "src/components/policies/impact_popover.tsx", "src/components/DeletedKeysPage/DeletedKeysPage.tsx", diff --git a/ui/litellm-dashboard/src/components/Settings/LoggingAndAlerts/LoggingCallbacks/LoggingCallbacksTable.tsx b/ui/litellm-dashboard/src/components/Settings/LoggingAndAlerts/LoggingCallbacks/LoggingCallbacksTable.tsx index 8f332d0317a..b67f13b4c8f 100644 --- a/ui/litellm-dashboard/src/components/Settings/LoggingAndAlerts/LoggingCallbacks/LoggingCallbacksTable.tsx +++ b/ui/litellm-dashboard/src/components/Settings/LoggingAndAlerts/LoggingCallbacks/LoggingCallbacksTable.tsx @@ -1,7 +1,13 @@ -import { Button } from "@tremor/react"; -import type { TableProps } from "antd"; -import { Table } from "antd"; -import Title from "antd/es/typography/Title"; +import { Button } from "@/components/ui/button"; +import { cn } from "@/lib/utils"; +import { + Table, + TableBody, + TableCell, + TableHead, + TableHeader, + TableRow, +} from "@/components/ui/table"; import React from "react"; import TableIconActionButton from "../../../common_components/IconActionButton/TableIconActionButtons/TableIconActionButton"; import { AlertingObject } from "./types"; @@ -41,81 +47,96 @@ export const LoggingCallbacksTable: React.FC = ({ onDelete = () => {}, onAdd = () => {}, }) => { - const columns: TableProps["columns"] = [ - { - title: Callback Name, - dataIndex: "name", - key: "name", - render: (_: string, record: CallbackRow) => { - const id = record.name; - console.log("availableCallbacks", availableCallbacks); - const displayName = availableCallbacks[id]?.ui_callback_name || id; - return
{displayName}
; - }, - }, - { - title: Mode, - key: "mode", - render: (_: unknown, record: CallbackRow) => { - const mode = record.mode || "success"; - const label = CALLBACK_MODES.find((m) => m.value === mode)?.label || mode; - const badgeClass = - mode === "success" - ? "bg-green-100 text-green-800" - : mode === "failure" - ? "bg-red-100 text-red-800" - : "bg-blue-100 text-blue-800"; - return ( - - {label} - - ); - }, - width: 240, - }, - { - title: Actions, - key: "actions", - align: "right", - render: (_: unknown, record: CallbackRow) => ( -
- onTest(record)} /> - onEdit(record)} /> - onDelete(record)} /> -
- ), - width: 240, - }, - ]; return ( - <> -
- -
- Active Logging Callbacks -
- {/* Empty state */} - {callbacks.length === 0 ? ( -
-
-

No callbacks configured

-

Add your first callback to start logging data to external services.

-
-
- ) : ( -
- record.name} - pagination={false} - rowClassName={() => "hover:bg-gray-50"} - /> - - )} +
+ +
+

Active Logging Callbacks

- + {callbacks.length === 0 ? ( +
+
+

+ No callbacks configured +

+

+ Add your first callback to start logging data to external + services. +

+
+
+ ) : ( +
+
+ + + Callback Name + Mode + + Actions + + + + + {callbacks.map((cb) => { + const record = cb as CallbackRow; + const id = record.name; + const displayName = + availableCallbacks[id]?.ui_callback_name || id; + const mode = record.mode || "success"; + const label = + CALLBACK_MODES.find((m) => m.value === mode)?.label || mode; + const badgeClass = + mode === "success" + ? "bg-emerald-100 text-emerald-800 dark:bg-emerald-950 dark:text-emerald-300" + : mode === "failure" + ? "bg-red-100 text-red-800 dark:bg-red-950 dark:text-red-300" + : "bg-blue-100 text-blue-800 dark:bg-blue-950 dark:text-blue-300"; + return ( + + +
+ {displayName} +
+
+ + + {label} + + + +
+ onTest(record)} + /> + onEdit(record)} + /> + onDelete(record)} + /> +
+
+
+ ); + })} +
+
+
+ )} +
); }; diff --git a/ui/litellm-dashboard/src/components/playground/chat_ui/SearchResultsDisplay.tsx b/ui/litellm-dashboard/src/components/playground/chat_ui/SearchResultsDisplay.tsx index 14ea470c5d3..d3795cf68db 100644 --- a/ui/litellm-dashboard/src/components/playground/chat_ui/SearchResultsDisplay.tsx +++ b/ui/litellm-dashboard/src/components/playground/chat_ui/SearchResultsDisplay.tsx @@ -1,15 +1,26 @@ import React, { useState } from "react"; -import { Button } from "antd"; +import { Button } from "@/components/ui/button"; +import { Badge } from "@/components/ui/badge"; +import { + ChevronDown, + ChevronRight, + Database, + FileText, +} from "lucide-react"; +import { cn } from "@/lib/utils"; import { VectorStoreSearchResponse } from "./types"; -import { DatabaseOutlined, FileTextOutlined, DownOutlined, RightOutlined } from "@ant-design/icons"; interface SearchResultsDisplayProps { searchResults: VectorStoreSearchResponse[]; } -export function SearchResultsDisplay({ searchResults }: SearchResultsDisplayProps) { +export function SearchResultsDisplay({ + searchResults, +}: SearchResultsDisplayProps) { const [isExpanded, setIsExpanded] = useState(true); - const [expandedResults, setExpandedResults] = useState>({}); + const [expandedResults, setExpandedResults] = useState< + Record + >({}); if (!searchResults || searchResults.length === 0) { return null; @@ -23,85 +34,114 @@ export function SearchResultsDisplay({ searchResults }: SearchResultsDisplayProp })); }; - const totalResults = searchResults.reduce((sum, page) => sum + page.data.length, 0); + const totalResults = searchResults.reduce( + (sum, page) => sum + page.data.length, + 0, + ); return (
{isExpanded && ( -
+
{searchResults.map((resultPage, pageIndex) => (
-
+
Query: - "{resultPage.search_query}" - • - {resultPage.data.length} result{resultPage.data.length !== 1 ? 's' : ''} + + "{resultPage.search_query}" + + • + + {resultPage.data.length} result + {resultPage.data.length !== 1 ? "s" : ""} +
{resultPage.data.map((result, resultIndex) => { - const isResultExpanded = expandedResults[`${pageIndex}-${resultIndex}`] || false; + const isResultExpanded = + expandedResults[`${pageIndex}-${resultIndex}`] || false; return ( -
+
toggleResult(pageIndex, resultIndex)} >
- - - - - - {result.filename || result.file_id || `Result ${resultIndex + 1}`} + + + + {result.filename || + result.file_id || + `Result ${resultIndex + 1}`} - + {result.score.toFixed(3)} - +
{isResultExpanded && ( -
+
{result.content.map((content, contentIndex) => (
-
+
{content.text}
))} - {result.attributes && Object.keys(result.attributes).length > 0 && ( -
-
Metadata:
-
- {Object.entries(result.attributes).map(([key, value]) => ( -
- {key}: - {String(value)} -
- ))} + {result.attributes && + Object.keys(result.attributes).length > 0 && ( +
+
+ Metadata: +
+
+ {Object.entries(result.attributes).map( + ([key, value]) => ( +
+ + {key}: + + + {String(value)} + +
+ ), + )} +
-
- )} + )}
)} @@ -117,4 +157,3 @@ export function SearchResultsDisplay({ searchResults }: SearchResultsDisplayProp
); } - diff --git a/ui/litellm-dashboard/src/components/prompts/prompt_editor_view/PromptMessagesCard.tsx b/ui/litellm-dashboard/src/components/prompts/prompt_editor_view/PromptMessagesCard.tsx index eb037ff5fc1..5d52cb289ad 100644 --- a/ui/litellm-dashboard/src/components/prompts/prompt_editor_view/PromptMessagesCard.tsx +++ b/ui/litellm-dashboard/src/components/prompts/prompt_editor_view/PromptMessagesCard.tsx @@ -1,16 +1,25 @@ import React, { useState } from "react"; -import { Card, Text } from "@tremor/react"; -import { Select } from "antd"; -import { PlusIcon, TrashIcon, GripVerticalIcon } from "lucide-react"; +import { Card } from "@/components/ui/card"; +import { + Select, + SelectContent, + SelectItem, + SelectTrigger, + SelectValue, +} from "@/components/ui/select"; +import { GripVertical, Plus, Trash } from "lucide-react"; +import { cn } from "@/lib/utils"; import VariableTextArea from "../variable_textarea"; import { Message } from "./types"; -const { Option } = Select; - interface PromptMessagesCardProps { messages: Message[]; onAddMessage: () => void; - onUpdateMessage: (index: number, field: "role" | "content", value: string) => void; + onUpdateMessage: ( + index: number, + field: "role" | "content", + value: string, + ) => void; onRemoveMessage: (index: number) => void; onMoveMessage: (fromIndex: number, toIndex: number) => void; } @@ -51,10 +60,14 @@ const PromptMessagesCard: React.FC = ({ return (
- Prompt messages - - Use {'{{variable}}'} syntax for template variables - +
Prompt messages
+
+ Use{" "} + + {"{{variable}}"} + {" "} + syntax for template variables +
{messages.map((message, index) => ( @@ -65,33 +78,41 @@ const PromptMessagesCard: React.FC = ({ onDragOver={(e) => handleDragOver(e, index)} onDrop={(e) => handleDrop(e, index)} onDragEnd={handleDragEnd} - className={`border border-gray-300 rounded overflow-hidden bg-white transition-all ${ - draggedIndex === index ? "opacity-50" : "" - } ${dragOverIndex === index && draggedIndex !== index ? "border-blue-500 border-2" : ""}`} + className={cn( + "border border-border rounded overflow-hidden bg-background transition-all", + draggedIndex === index && "opacity-50", + dragOverIndex === index && + draggedIndex !== index && + "border-primary border-2", + )} > -
+
{messages.length > 1 && ( )} -
- +
+
@@ -107,10 +128,11 @@ const PromptMessagesCard: React.FC = ({ ))}
@@ -118,4 +140,3 @@ const PromptMessagesCard: React.FC = ({ }; export default PromptMessagesCard; -