litellm-mirror/ui/litellm-dashboard/src/components/model_add/credentials.tsx

184 lines
No EOL
5.5 KiB
TypeScript

import React, { useState, useEffect } from "react";
import {
Table,
TableBody,
TableCell,
TableHead,
TableHeaderCell,
TableRow,
Card,
Text,
Badge,
Button
} from "@tremor/react";
import {
InformationCircleIcon,
PencilAltIcon,
PencilIcon,
RefreshIcon,
StatusOnlineIcon,
TrashIcon,
} from "@heroicons/react/outline";
import { UploadProps } from "antd/es/upload";
import { PlusIcon } from "@heroicons/react/solid";
import { credentialListCall, credentialCreateCall, credentialDeleteCall, CredentialItem, CredentialsResponse } from "@/components/networking"; // Assume this is your networking function
import AddCredentialsTab from "./add_credentials_tab";
import { Form, message } from "antd";
interface CredentialsPanelProps {
accessToken: string | null;
uploadProps: UploadProps;
credentialList: CredentialItem[];
fetchCredentials: (accessToken: string) => Promise<void>;
}
const CredentialsPanel: React.FC<CredentialsPanelProps> = ({ accessToken, uploadProps, credentialList, fetchCredentials }) => {
const [isAddModalOpen, setIsAddModalOpen] = useState(false);
const [form] = Form.useForm();
const handleAddCredential = async (values: any) => {
if (!accessToken) {
console.error('No access token found');
return;
}
const filter_credential_values = Object.entries(values)
.filter(([key]) => !['credential_name', 'custom_llm_provider'].includes(key))
.reduce((acc, [key, value]) => ({ ...acc, [key]: value }), {});
// Transform form values into credential structure
const newCredential = {
credential_name: values.credential_name,
credential_values: filter_credential_values,
credential_info: {
custom_llm_provider: values.custom_llm_provider,
}
};
// Add to list and close modal
const response = await credentialCreateCall(accessToken, newCredential);
message.success('Credential added successfully');
console.log(`response: ${JSON.stringify(response)}`);
setIsAddModalOpen(false);
fetchCredentials(accessToken);
};
useEffect(() => {
if (!accessToken) {
return;
}
fetchCredentials(accessToken);
}, [accessToken]);
const renderProviderBadge = (provider: string) => {
const providerColors: Record<string, string> = {
'openai': 'blue',
'azure': 'indigo',
'anthropic': 'purple',
'default': 'gray'
};
const color = providerColors[provider.toLowerCase()] || providerColors['default'];
return (
<Badge color={color as any} size="xs">
{provider}
</Badge>
);
};
const handleDeleteCredential = async (credentialName: string) => {
if (!accessToken) {
console.error('No access token found');
return;
}
const response = await credentialDeleteCall(accessToken, credentialName);
console.log(`response: ${JSON.stringify(response)}`);
message.success('Credential deleted successfully');
fetchCredentials(accessToken);
};
return (
<div className="w-full mx-auto flex-auto overflow-y-auto m-8 p-2">
<div className="flex justify-between items-center mb-4">
<Text>
Configured credentials for different AI providers. Add and manage your API credentials.{" "}
<a
href="https://docs.litellm.ai/docs/credentials"
target="_blank"
rel="noopener noreferrer"
className="text-blue-500 hover:text-blue-700 underline"
>
Docs
</a>
</Text>
</div>
<Card>
<Table>
<TableHead>
<TableRow>
<TableHeaderCell>Credential Name</TableHeaderCell>
<TableHeaderCell>Provider</TableHeaderCell>
<TableHeaderCell>Description</TableHeaderCell>
</TableRow>
</TableHead>
<TableBody>
{(!credentialList || credentialList.length === 0) ? (
<TableRow>
<TableCell colSpan={4} className="text-center py-4 text-gray-500">
No credentials configured
</TableCell>
</TableRow>
) : (
credentialList.map((credential: CredentialItem, index: number) => (
<TableRow key={index}>
<TableCell>{credential.credential_name}</TableCell>
<TableCell>
{renderProviderBadge(credential.credential_info?.custom_llm_provider as string || '-')}
</TableCell>
<TableCell>{credential.credential_info?.description || '-'}</TableCell>
<TableCell>
<Button
icon={PencilAltIcon}
variant="light"
size="sm"
/>
<Button
icon={TrashIcon}
variant="light"
size="sm"
onClick={() => handleDeleteCredential(credential.credential_name)}
/>
</TableCell>
</TableRow>
))
)}
</TableBody>
</Table>
</Card>
<Button
onClick={() => setIsAddModalOpen(true)}
className="mt-4"
>
Add Credential
</Button>
{isAddModalOpen && (
<AddCredentialsTab
form={form}
onAddCredential={handleAddCredential}
isVisible={isAddModalOpen}
onCancel={() => setIsAddModalOpen(false)}
uploadProps={uploadProps}
/>
)}
</div>
);
};
export default CredentialsPanel;