mirror of
https://github.com/BerriAI/litellm.git
synced 2026-10-06 02:48:13 +00:00
feat(ui): SearchTools/SearchTools to shadcn
- @tremor Button/Text/Title + antd Modal/Spin/Input + @ant-design LoadingOutlined \u2192 shadcn Button/Dialog/Input + lucide Loader2 + native headings. - antd Form/Form.Item/Select/AntInput.Password/AntInput.TextArea preserved (form context + rules). antd Table kept. Gates: TS \u2713 | Build \u2713. Co-authored-by: yuneng-jiang <yuneng-berri@users.noreply.github.com>
This commit is contained in:
parent
facac907d1
commit
331a1fe752
1 changed files with 85 additions and 37 deletions
|
|
@ -1,8 +1,20 @@
|
||||||
import { isAdminRole } from "@/utils/roles";
|
import { isAdminRole } from "@/utils/roles";
|
||||||
import { LoadingOutlined } from "@ant-design/icons";
|
|
||||||
import { useQuery } from "@tanstack/react-query";
|
import { useQuery } from "@tanstack/react-query";
|
||||||
import { Button, Text, Title } from "@tremor/react";
|
import { Button } from "@/components/ui/button";
|
||||||
import { Form, Input, Modal, Select, Spin, Table } from "antd";
|
import {
|
||||||
|
Dialog,
|
||||||
|
DialogContent,
|
||||||
|
DialogFooter,
|
||||||
|
DialogHeader,
|
||||||
|
DialogTitle,
|
||||||
|
} from "@/components/ui/dialog";
|
||||||
|
import { Loader2 } from "lucide-react";
|
||||||
|
import {
|
||||||
|
Form,
|
||||||
|
Input as AntInput,
|
||||||
|
Select,
|
||||||
|
Table,
|
||||||
|
} from "antd";
|
||||||
import React, { useState } from "react";
|
import React, { useState } from "react";
|
||||||
import DeleteResourceModal from "../common_components/DeleteResourceModal";
|
import DeleteResourceModal from "../common_components/DeleteResourceModal";
|
||||||
import NotificationsManager from "../molecules/notifications_manager";
|
import NotificationsManager from "../molecules/notifications_manager";
|
||||||
|
|
@ -168,7 +180,7 @@ const SearchTools: React.FC<SearchToolsProps> = ({ accessToken, userRole, userID
|
||||||
label="Search Tool Name"
|
label="Search Tool Name"
|
||||||
rules={[{ required: true, message: "Please enter a search tool name" }]}
|
rules={[{ required: true, message: "Please enter a search tool name" }]}
|
||||||
>
|
>
|
||||||
<Input placeholder="e.g., my-perplexity-search" />
|
<AntInput placeholder="e.g., my-perplexity-search" />
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
|
|
||||||
<Form.Item
|
<Form.Item
|
||||||
|
|
@ -185,19 +197,29 @@ const SearchTools: React.FC<SearchToolsProps> = ({ accessToken, userRole, userID
|
||||||
</Select>
|
</Select>
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
|
|
||||||
<Form.Item name="api_key" label="API Key" extra="API key for the search provider">
|
<Form.Item
|
||||||
<Input.Password placeholder="Enter API key" />
|
name="api_key"
|
||||||
|
label="API Key"
|
||||||
|
extra="API key for the search provider"
|
||||||
|
>
|
||||||
|
<AntInput.Password placeholder="Enter API key" />
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
|
|
||||||
<Form.Item name="description" label="Description">
|
<Form.Item name="description" label="Description">
|
||||||
<Input.TextArea rows={3} placeholder="Description of this search tool" />
|
<AntInput.TextArea
|
||||||
|
rows={3}
|
||||||
|
placeholder="Description of this search tool"
|
||||||
|
/>
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
</Form>
|
</Form>
|
||||||
);
|
);
|
||||||
|
|
||||||
if (!accessToken || !userRole || !userID) {
|
if (!accessToken || !userRole || !userID) {
|
||||||
console.log("Missing required authentication parameters", { accessToken, userRole, userID });
|
return (
|
||||||
return <div className="p-6 text-center text-gray-500">Missing required authentication parameters.</div>;
|
<div className="p-6 text-center text-muted-foreground">
|
||||||
|
Missing required authentication parameters.
|
||||||
|
</div>
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
const ToolsTab = () =>
|
const ToolsTab = () =>
|
||||||
|
|
@ -222,21 +244,25 @@ const SearchTools: React.FC<SearchToolsProps> = ({ accessToken, userRole, userID
|
||||||
availableProviders={availableProviders}
|
availableProviders={availableProviders}
|
||||||
/>
|
/>
|
||||||
) : (
|
) : (
|
||||||
<div className="w-full h-full">
|
<div className="w-full h-full relative">
|
||||||
<Spin spinning={isLoadingTools} indicator={<LoadingOutlined spin />} size="large">
|
{isLoadingTools && (
|
||||||
<Table
|
<div className="absolute inset-0 flex items-center justify-center bg-background/50 z-10">
|
||||||
bordered
|
<Loader2 className="h-8 w-8 animate-spin text-primary" />
|
||||||
dataSource={searchTools || []}
|
</div>
|
||||||
columns={columns}
|
)}
|
||||||
rowKey={(record) => record.search_tool_id || record.search_tool_name}
|
<Table
|
||||||
pagination={false}
|
bordered
|
||||||
locale={{
|
dataSource={searchTools || []}
|
||||||
emptyText: "No search tools configured",
|
columns={columns}
|
||||||
}}
|
rowKey={(record) =>
|
||||||
size="small"
|
record.search_tool_id || record.search_tool_name
|
||||||
/>
|
}
|
||||||
</Spin>
|
pagination={false}
|
||||||
|
locale={{
|
||||||
|
emptyText: "No search tools configured",
|
||||||
|
}}
|
||||||
|
size="small"
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
@ -274,24 +300,46 @@ const SearchTools: React.FC<SearchToolsProps> = ({ accessToken, userRole, userID
|
||||||
/>
|
/>
|
||||||
|
|
||||||
{/* Edit Modal */}
|
{/* Edit Modal */}
|
||||||
<Modal
|
<Dialog
|
||||||
title="Edit Search Tool"
|
|
||||||
open={isEditModalVisible}
|
open={isEditModalVisible}
|
||||||
onOk={handleEditSubmit}
|
onOpenChange={(o) => {
|
||||||
onCancel={() => {
|
if (!o) {
|
||||||
setEditModalVisible(false);
|
setEditModalVisible(false);
|
||||||
form.resetFields();
|
form.resetFields();
|
||||||
setSelectedToolId(null);
|
setSelectedToolId(null);
|
||||||
|
}
|
||||||
}}
|
}}
|
||||||
width={600}
|
|
||||||
>
|
>
|
||||||
{renderEditForm()}
|
<DialogContent className="max-w-[600px]">
|
||||||
</Modal>
|
<DialogHeader>
|
||||||
|
<DialogTitle>Edit Search Tool</DialogTitle>
|
||||||
|
</DialogHeader>
|
||||||
|
{renderEditForm()}
|
||||||
|
<DialogFooter>
|
||||||
|
<Button
|
||||||
|
variant="outline"
|
||||||
|
onClick={() => {
|
||||||
|
setEditModalVisible(false);
|
||||||
|
form.resetFields();
|
||||||
|
setSelectedToolId(null);
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
Cancel
|
||||||
|
</Button>
|
||||||
|
<Button onClick={handleEditSubmit}>OK</Button>
|
||||||
|
</DialogFooter>
|
||||||
|
</DialogContent>
|
||||||
|
</Dialog>
|
||||||
|
|
||||||
<Title>Search Tools</Title>
|
<h1 className="text-2xl font-semibold">Search Tools</h1>
|
||||||
<Text className="text-tremor-content mt-2">Configure and manage your search providers</Text>
|
<p className="text-muted-foreground mt-2">
|
||||||
|
Configure and manage your search providers
|
||||||
|
</p>
|
||||||
{isAdminRole(userRole) && (
|
{isAdminRole(userRole) && (
|
||||||
<Button className="mt-4 mb-4" onClick={() => setCreateModalVisible(true)}>
|
<Button
|
||||||
|
className="mt-4 mb-4"
|
||||||
|
onClick={() => setCreateModalVisible(true)}
|
||||||
|
>
|
||||||
+ Add New Search Tool
|
+ Add New Search Tool
|
||||||
</Button>
|
</Button>
|
||||||
)}
|
)}
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue