diff --git a/ui/litellm-dashboard/eslint-suppressions.json b/ui/litellm-dashboard/eslint-suppressions.json index e467ddc5ec4..bc23c2433d3 100644 --- a/ui/litellm-dashboard/eslint-suppressions.json +++ b/ui/litellm-dashboard/eslint-suppressions.json @@ -16,7 +16,7 @@ }, "src/app/(dashboard)/admin-panel/_components/AdminPanel.tsx": { "no-restricted-imports": { - "count": 2 + "count": 1 }, "react-hooks/set-state-in-effect": { "count": 1 @@ -1647,9 +1647,6 @@ } }, "src/components/SCIM.tsx": { - "no-restricted-imports": { - "count": 2 - }, "react-hooks/set-state-in-effect": { "count": 1 } @@ -1661,7 +1658,7 @@ }, "src/components/SSOModals.tsx": { "no-restricted-imports": { - "count": 2 + "count": 1 } }, "src/components/Settings/AdminSettings/HashicorpVault/EditHashicorpVaultModal.tsx": { @@ -1705,11 +1702,6 @@ "count": 1 } }, - "src/components/Settings/AdminSettings/SSOSettings/Modals/BaseSSOSettingsForm.tsx": { - "no-restricted-imports": { - "count": 2 - } - }, "src/components/Settings/AdminSettings/SSOSettings/Modals/EditSSOSettingsModal.test.tsx": { "max-nested-callbacks": { "count": 1 @@ -1760,7 +1752,7 @@ }, "src/components/Settings/RouterSettings/Fallbacks/FallbackSelectionForm.tsx": { "no-restricted-imports": { - "count": 2 + "count": 1 }, "react-hooks/set-state-in-effect": { "count": 1 @@ -2024,10 +2016,7 @@ "count": 1 }, "no-nested-ternary": { - "count": 4 - }, - "no-restricted-imports": { - "count": 2 + "count": 1 } }, "src/components/bulk_create_users_button.tsx": { @@ -2091,7 +2080,7 @@ "count": 1 }, "no-restricted-imports": { - "count": 2 + "count": 1 }, "no-restricted-syntax": { "count": 3 @@ -2461,7 +2450,7 @@ "count": 1 }, "no-restricted-imports": { - "count": 2 + "count": 1 } }, "src/components/organisms/RegenerateKeyModal.tsx": { diff --git a/ui/litellm-dashboard/src/app/(dashboard)/admin-panel/_components/AdminPanel.tsx b/ui/litellm-dashboard/src/app/(dashboard)/admin-panel/_components/AdminPanel.tsx index 3f3f7fb5db7..48eaa62e37b 100644 --- a/ui/litellm-dashboard/src/app/(dashboard)/admin-panel/_components/AdminPanel.tsx +++ b/ui/litellm-dashboard/src/app/(dashboard)/admin-panel/_components/AdminPanel.tsx @@ -3,18 +3,12 @@ * Use this to avoid sharing master key with others */ import useAuthorized from "@/app/(dashboard)/hooks/useAuthorized"; -import { - Button, - Callout, - Card, - Table, - TableBody, - TableCell, - TableHead, - TableHeaderCell, - TableRow, -} from "@tremor/react"; -import { Alert, Modal, Space, Tabs, Typography } from "antd"; +import { Alert, AlertDescription, AlertTitle } from "@/components/shared/Alert"; +import { Button } from "@/components/ui/button"; +import { Card } from "@/components/ui/card"; +import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from "@/components/ui/table"; +import { Alert as AntdAlert, Modal, Space, Tabs, Typography } from "antd"; +import { Info } from "lucide-react"; import React, { useEffect, useState } from "react"; import NewBadge from "@/components/common_components/NewBadge"; import { useBaseUrl } from "@/components/constants"; @@ -37,7 +31,6 @@ import UIAccessControlForm from "@/components/UIAccessControlForm"; import { z } from "zod/v4"; import { FieldGroup } from "@/components/shared/form/field"; import { FormField } from "@/components/shared/form/FormField"; -import { Button as ShadcnButton } from "@/components/ui/button"; import { Input } from "@/components/ui/input"; import { useZodForm } from "@/lib/forms/useZodForm"; @@ -59,7 +52,7 @@ const AddAllowedIPForm = ({ onSubmit }: { onSubmit: (values: AllowedIPFormValues {({ ref, ...field }) => }
- Add IP Address +
@@ -228,9 +221,9 @@ const AdminPanel: React.FC = ({ proxySettings }) => { label: "Security Settings", children: ( <> - + ✨ Security Settings - = ({ proxySettings }) => { ]} > - + - IP Address - Action + IP Address + Action - + {allowedIPs.map((ip, index) => ( {ip} {ip !== all_ip_address_allowed && ( - )} @@ -365,12 +358,16 @@ const AdminPanel: React.FC = ({ proxySettings }) => { /> - - If you need to login without sso, you can access{" "} - - {nonSssoUrl}{" "} - - + + + Login without SSO + + If you need to login without sso, you can access{" "} + + {nonSssoUrl}{" "} + + + ), }, diff --git a/ui/litellm-dashboard/src/components/SCIM.tsx b/ui/litellm-dashboard/src/components/SCIM.tsx index 4110db4daba..6663ab0aed0 100644 --- a/ui/litellm-dashboard/src/components/SCIM.tsx +++ b/ui/litellm-dashboard/src/components/SCIM.tsx @@ -1,21 +1,17 @@ import React, { useState, useEffect } from "react"; -import { Card, Title, Text, Grid, Callout, Divider } from "@tremor/react"; import { z } from "zod/v4"; import { keyCreateCall } from "./networking"; import { CopyToClipboard } from "react-copy-to-clipboard"; -import { - LinkOutlined, - KeyOutlined, - CopyOutlined, - ExclamationCircleOutlined, - PlusCircleOutlined, -} from "@ant-design/icons"; +import { CircleAlert, CirclePlus, Copy, Info, KeyRound, Link } from "lucide-react"; import { parseErrorMessage } from "./shared/errorUtils"; import { toast } from "@/lib/toast"; +import { Alert, AlertDescription, AlertTitle } from "@/components/shared/Alert"; import { FieldGroup } from "@/components/shared/form/field"; import { FormField } from "@/components/shared/form/FormField"; import { Button } from "@/components/ui/button"; +import { Card, CardContent, CardTitle } from "@/components/ui/card"; import { Input } from "@/components/ui/input"; +import { Separator } from "@/components/ui/separator"; import { UiLoadingSpinner } from "@/components/ui/ui-loading-spinner"; import { useZodForm } from "@/lib/forms/useZodForm"; @@ -80,114 +76,121 @@ const SCIMConfig: React.FC = ({ accessToken, userID, proxySetti }; return ( - +
-
- SCIM Configuration -
- - System for Cross-domain Identity Management (SCIM) allows you to automatically provision and manage users and - groups in LiteLLM. - - - - -
- {/* Step 1: SCIM URL */} -
-
-
- 1 -
- - <LinkOutlined className="h-5 w-5 mr-2" /> - SCIM Tenant URL - -
- - Use this URL in your identity provider SCIM integration settings. - -
- - toast.success("URL copied to clipboard")}> - - -
+ +
+ SCIM Configuration
+

+ System for Cross-domain Identity Management (SCIM) allows you to automatically provision and manage users + and groups in LiteLLM. +

- {/* Step 2: SCIM Token */} -
-
-
- 2 + + +
+ {/* Step 1: SCIM URL */} +
+
+
+ 1 +
+

+ + SCIM Tenant URL +

+
+

+ Use this URL in your identity provider SCIM integration settings. +

+
+ + toast.success("URL copied to clipboard")}> + +
- - <KeyOutlined className="h-5 w-5 mr-2" /> - Authentication Token -
- - You need a SCIM token to authenticate with the SCIM API. Create one below and use it in your SCIM provider - configuration. - + {/* Step 2: SCIM Token */} +
+
+
+ 2 +
+

+ + Authentication Token +

+
- {!tokenData ? ( -
-
- - - {({ ref, ...field }) => } - -
- +
+
+ +
+ ) : ( + +
+ +

Your SCIM Token

+
+

+ Make sure to copy this token now. You will not be able to see it again. +

+
+ + toast.success("Token copied to clipboard")}> + -
- - -
- ) : ( - -
- - Your SCIM Token -
- - Make sure to copy this token now. You will not be able to see it again. - -
- - toast.success("Token copied to clipboard")}> - - -
- -
- )} + +
+ + + )} +
-
+
- +
); }; diff --git a/ui/litellm-dashboard/src/components/SSOModals.tsx b/ui/litellm-dashboard/src/components/SSOModals.tsx index 4a156c3b30a..2bcc7849449 100644 --- a/ui/litellm-dashboard/src/components/SSOModals.tsx +++ b/ui/litellm-dashboard/src/components/SSOModals.tsx @@ -1,7 +1,6 @@ import React, { useEffect, useState } from "react"; import { FormProvider, useWatch, type UseFormReturn } from "react-hook-form"; import { Modal } from "antd"; -import { Text } from "@tremor/react"; import { getSSOSettings, updateSSOSettings } from "./networking"; import { toast } from "@/lib/toast"; import { parseErrorMessage } from "./shared/errorUtils"; @@ -317,10 +316,10 @@ const SSOModals: React.FC = ({ onCancel={handleInstructionsCancel} >

Follow these steps to complete the SSO setup:

- 1. DO NOT Exit this TAB - 2. Open a new tab, visit your proxy base url - 3. Confirm your SSO is configured correctly and you can login on the new Tab - 4. If Step 3 is successful, you can close this tab +

1. DO NOT Exit this TAB

+

2. Open a new tab, visit your proxy base url

+

3. Confirm your SSO is configured correctly and you can login on the new Tab

+

4. If Step 3 is successful, you can close this tab

diff --git a/ui/litellm-dashboard/src/components/alerting/dynamic_form.integration.test.tsx b/ui/litellm-dashboard/src/components/alerting/dynamic_form.integration.test.tsx index 89eee83374a..f9b9765f59e 100644 --- a/ui/litellm-dashboard/src/components/alerting/dynamic_form.integration.test.tsx +++ b/ui/litellm-dashboard/src/components/alerting/dynamic_form.integration.test.tsx @@ -174,9 +174,7 @@ describe("DynamicForm change notifications", () => { const user = userEvent.setup(); const { handleResetField } = renderForm(); - const row = screen.getByText("region_name").closest("tr"); - const reset = row?.querySelector(".tremor-Icon-root"); - await user.click(reset as Element); + await user.click(screen.getByRole("button", { name: "Reset region_name" })); expect(handleResetField).toHaveBeenCalledWith("region_name", 1); }); diff --git a/ui/litellm-dashboard/src/components/alerting/dynamic_form.tsx b/ui/litellm-dashboard/src/components/alerting/dynamic_form.tsx index 1ee3833c1b9..0b7924d5599 100644 --- a/ui/litellm-dashboard/src/components/alerting/dynamic_form.tsx +++ b/ui/litellm-dashboard/src/components/alerting/dynamic_form.tsx @@ -1,8 +1,11 @@ import React from "react"; import { useForm } from "react-hook-form"; -import { TrashIcon, CheckCircleIcon } from "@heroicons/react/outline"; -import { Button, Badge, Icon, Text, TableRow, TableCell, Switch } from "@tremor/react"; +import { CircleCheck, Trash2 } from "lucide-react"; +import { Badge } from "@/components/ui/badge"; +import { Button } from "@/components/ui/button"; import { Input } from "@/components/ui/input"; +import { Switch } from "@/components/ui/switch"; +import { TableCell, TableRow } from "@/components/ui/table"; interface AlertingSetting { field_name: string; @@ -71,7 +74,13 @@ const DynamicForm: React.FC = ({ ); } if (setting.field_type === "Boolean") { - return handleToggle(setting, checked)} />; + return ( + handleToggle(setting, checked)} + /> + ); } return handleTextChange(setting, event)} />; }; @@ -80,8 +89,8 @@ const DynamicForm: React.FC = ({
{alertingSettings.map((value, index) => ( - - {value.field_name} + +

{value.field_name}

{value.field_description}

{value.premium_field && !premiumUser ? ( @@ -97,19 +106,27 @@ const DynamicForm: React.FC = ({ )} {value.stored_in_db == true ? ( - + + In DB ) : value.stored_in_db == false ? ( - In Config + In Config ) : ( - Not Set + Not Set )} - handleResetField(value.field_name, index)}> - Reset - +
))} diff --git a/ui/litellm-dashboard/src/components/cloudzero_export_modal.tsx b/ui/litellm-dashboard/src/components/cloudzero_export_modal.tsx index 7a937d32b3e..24aa0d9d1b8 100644 --- a/ui/litellm-dashboard/src/components/cloudzero_export_modal.tsx +++ b/ui/litellm-dashboard/src/components/cloudzero_export_modal.tsx @@ -1,13 +1,16 @@ import React, { useState, useEffect } from "react"; -import { Text, Button, Callout } from "@tremor/react"; import { Modal, Spin, Select } from "antd"; +import { CircleCheck, FileDown } from "lucide-react"; import { z } from "zod/v4"; import { getGlobalLitellmHeaderName } from "@/components/networking"; import { toast } from "@/lib/toast"; +import { Alert, AlertDescription, AlertTitle } from "@/components/shared/Alert"; import { PasswordInput } from "@/components/shared/PasswordInput"; import { FieldGroup } from "@/components/shared/form/field"; import { FormField } from "@/components/shared/form/FormField"; +import { Button } from "@/components/ui/button"; import { Input } from "@/components/ui/input"; +import { UiLoadingSpinner } from "@/components/ui/ui-loading-spinner"; import { useZodForm } from "@/lib/forms/useZodForm"; const cloudZeroSettingsSchema = z.object({ @@ -242,7 +245,7 @@ const CloudZeroExportModal: React.FC = ({ isOpen, onC
{/* Export Type Selection */}
- Export Destination +

Export Destination