From 80eb1ac8fa65effa4a130eb96adf475aa1ea96d0 Mon Sep 17 00:00:00 2001 From: Ishaan Jaff Date: Sat, 5 Apr 2025 12:29:31 -0700 Subject: [PATCH] [UI QA/Bug Fix] - Don't change team, key, org, model values on scroll (#9776) * UI - use 1 component for numerical input * disable scroll number values on models page * team edit - disable numerical value scroll * fix numerical input view * use numerical component on create key * add NumericalInput * ui fix org numerical input * remove file in incorrect location * fix NumericalInput --- .../src/components/create_key_button.tsx | 8 ++-- .../src/components/edit_user.tsx | 7 +-- .../src/components/key_edit_view.tsx | 12 ++--- .../src/components/model_info_view.tsx | 18 +++---- .../organization/organization_view.tsx | 12 +++-- .../src/components/organizations.tsx | 9 ++-- .../src/components/shared/numerical_input.tsx | 48 +++++++++++++++++++ .../src/components/team/team_info.tsx | 9 ++-- ui/litellm-dashboard/src/components/teams.tsx | 8 ++-- 9 files changed, 92 insertions(+), 39 deletions(-) create mode 100644 ui/litellm-dashboard/src/components/shared/numerical_input.tsx diff --git a/ui/litellm-dashboard/src/components/create_key_button.tsx b/ui/litellm-dashboard/src/components/create_key_button.tsx index b3a4ed3265..41ea266d1b 100644 --- a/ui/litellm-dashboard/src/components/create_key_button.tsx +++ b/ui/litellm-dashboard/src/components/create_key_button.tsx @@ -17,11 +17,11 @@ import { Modal, Form, Input, - InputNumber, Select, message, Radio, } from "antd"; +import NumericalInput from "./shared/numerical_input"; import { unfurlWildcardModelsInList, getModelDisplayName } from "./key_team_helpers/fetch_available_models_team_key"; import SchemaFormFields from './common_components/check_openapi_schema'; import { @@ -559,7 +559,7 @@ const CreateKey: React.FC = ({ }, ]} > - + = ({ }, ]} > - + = ({ }, ]} > - + >; @@ -112,7 +113,7 @@ const EditUserModal: React.FC = ({ visible, possibleUIRoles, tooltip="(float) - Spend of all LLM calls completed by this user" help="Across all keys (including keys with team_id)." > - + = ({ visible, possibleUIRoles, tooltip="(float) - Maximum budget of this user" help="Maximum budget of this user." > - +
diff --git a/ui/litellm-dashboard/src/components/key_edit_view.tsx b/ui/litellm-dashboard/src/components/key_edit_view.tsx index bbe75e0d0e..fad03700bf 100644 --- a/ui/litellm-dashboard/src/components/key_edit_view.tsx +++ b/ui/litellm-dashboard/src/components/key_edit_view.tsx @@ -1,10 +1,10 @@ import React, { useState, useEffect } from "react"; -import { Form, Input, InputNumber, Select } from "antd"; +import { Form, Input, Select } from "antd"; import { Button, TextInput } from "@tremor/react"; import { KeyResponse } from "./key_team_helpers/key_list"; import { fetchTeamModels } from "../components/create_key_button"; import { modelAvailableCall } from "./networking"; - +import NumericalInput from "./shared/numerical_input"; interface KeyEditViewProps { keyData: KeyResponse; onCancel: () => void; @@ -126,7 +126,7 @@ export function KeyEditView({ - + @@ -138,15 +138,15 @@ export function KeyEditView({ - + - + - + diff --git a/ui/litellm-dashboard/src/components/model_info_view.tsx b/ui/litellm-dashboard/src/components/model_info_view.tsx index 7a1c9a7abc..6c626300a3 100644 --- a/ui/litellm-dashboard/src/components/model_info_view.tsx +++ b/ui/litellm-dashboard/src/components/model_info_view.tsx @@ -12,8 +12,8 @@ import { Badge, Button as TremorButton, TextInput, - NumberInput, } from "@tremor/react"; +import NumericalInput from "./shared/numerical_input"; import { ArrowLeftIcon, TrashIcon, KeyIcon } from "@heroicons/react/outline"; import { modelDeleteCall, modelUpdateCall, CredentialItem, credentialGetCall, credentialCreateCall, modelInfoCall, modelInfoV1Call } from "./networking"; import { Button, Form, Input, InputNumber, message, Select, Modal } from "antd"; @@ -369,7 +369,7 @@ export default function ModelInfoView({ Input Cost (per 1M tokens) {isEditing ? ( - + ) : (
@@ -384,7 +384,7 @@ export default function ModelInfoView({ Output Cost (per 1M tokens) {isEditing ? ( - + ) : (
@@ -438,7 +438,7 @@ export default function ModelInfoView({ TPM (Tokens per Minute) {isEditing ? ( - + ) : (
@@ -448,10 +448,10 @@ export default function ModelInfoView({
- RPM (Requests per Minute) + RPM VVV(Requests per Minute) {isEditing ? ( - + ) : (
@@ -464,7 +464,7 @@ export default function ModelInfoView({ Max Retries {isEditing ? ( - + ) : (
@@ -477,7 +477,7 @@ export default function ModelInfoView({ Timeout (seconds) {isEditing ? ( - + ) : (
@@ -490,7 +490,7 @@ export default function ModelInfoView({ Stream Timeout (seconds) {isEditing ? ( - + ) : (
diff --git a/ui/litellm-dashboard/src/components/organization/organization_view.tsx b/ui/litellm-dashboard/src/components/organization/organization_view.tsx index 00e9941976..076e1481ee 100644 --- a/ui/litellm-dashboard/src/components/organization/organization_view.tsx +++ b/ui/litellm-dashboard/src/components/organization/organization_view.tsx @@ -3,6 +3,7 @@ import { Card, Title, Text, + TextInput, Tab, TabList, TabGroup, @@ -19,7 +20,8 @@ import { Button as TremorButton, Icon } from "@tremor/react"; -import { Button, Form, Input, Select, message, InputNumber, Tooltip } from "antd"; +import NumericalInput from "../shared/numerical_input"; +import { Button, Form, Input, Select, message, Tooltip } from "antd"; import { InfoCircleOutlined } from '@ant-design/icons'; import { PencilAltIcon, TrashIcon } from "@heroicons/react/outline"; import { getModelDisplayName } from "../key_team_helpers/fetch_available_models_team_key"; @@ -338,7 +340,7 @@ const OrganizationInfoView: React.FC = ({ name="organization_alias" rules={[{ required: true, message: "Please input an organization name" }]} > - + @@ -358,7 +360,7 @@ const OrganizationInfoView: React.FC = ({ - + @@ -370,11 +372,11 @@ const OrganizationInfoView: React.FC = ({ - + - + diff --git a/ui/litellm-dashboard/src/components/organizations.tsx b/ui/litellm-dashboard/src/components/organizations.tsx index 400c53f31e..8242049530 100644 --- a/ui/litellm-dashboard/src/components/organizations.tsx +++ b/ui/litellm-dashboard/src/components/organizations.tsx @@ -19,8 +19,9 @@ import { TabPanels, TabPanel, } from "@tremor/react"; +import NumericalInput from "./shared/numerical_input"; import { Input } from "antd"; -import { Modal, Form, InputNumber, Tooltip, Select as Select2 } from "antd"; +import { Modal, Form, Tooltip, Select as Select2 } from "antd"; import { InfoCircleOutlined } from '@ant-design/icons'; import { PencilAltIcon, TrashIcon, RefreshIcon } from "@heroicons/react/outline"; import { TextInput } from "@tremor/react"; @@ -321,7 +322,7 @@ const OrganizationsTable: React.FC = ({ - + @@ -331,10 +332,10 @@ const OrganizationsTable: React.FC = ({ - + - + diff --git a/ui/litellm-dashboard/src/components/shared/numerical_input.tsx b/ui/litellm-dashboard/src/components/shared/numerical_input.tsx new file mode 100644 index 0000000000..fb3bc804f5 --- /dev/null +++ b/ui/litellm-dashboard/src/components/shared/numerical_input.tsx @@ -0,0 +1,48 @@ +import React from "react"; +import { NumberInput } from "@tremor/react"; + +interface NumericalInputProps { + step?: number; + style?: React.CSSProperties; + placeholder?: string; + min?: number; + max?: number; + onChange?: any; // Using any to avoid type conflicts with Tremor's NumberInput + [key: string]: any; +} + +/** + * A reusable numerical input component + * @param {Object} props - Component props + * @param {number} [props.step=0.01] - Step increment for the input + * @param {Object} [props.style] - Custom styles to apply + * @param {string} [props.placeholder="Enter a numerical value"] - Placeholder text + * @param {number} [props.min] - Minimum value + * @param {number} [props.max] - Maximum value + * @param {Function} [props.onChange] - On change handler + * @param {any} props.rest - Additional props passed to NumberInput + */ +const NumericalInput: React.FC = ({ + step = 0.01, + style = { width: "100%" }, + placeholder = "Enter a numerical value", + min, + max, + onChange, + ...rest +}) => { + return ( + event.currentTarget.blur()} + step={step} + style={style} + placeholder={placeholder} + min={min} + max={max} + onChange={onChange} + {...rest} + /> + ); +}; + +export default NumericalInput; \ No newline at end of file diff --git a/ui/litellm-dashboard/src/components/team/team_info.tsx b/ui/litellm-dashboard/src/components/team/team_info.tsx index 34bb9d0251..e04680b53a 100644 --- a/ui/litellm-dashboard/src/components/team/team_info.tsx +++ b/ui/litellm-dashboard/src/components/team/team_info.tsx @@ -1,4 +1,5 @@ import React, { useState, useEffect } from "react"; +import NumericalInput from "../shared/numerical_input"; import { Card, Title, @@ -20,7 +21,7 @@ import { Icon } from "@tremor/react"; import { teamInfoCall, teamMemberDeleteCall, teamMemberAddCall, teamMemberUpdateCall, Member, teamUpdateCall } from "@/components/networking"; -import { Button, Form, Input, Select, message, InputNumber, Tooltip } from "antd"; +import { Button, Form, Input, Select, message, Tooltip } from "antd"; import { InfoCircleOutlined } from '@ant-design/icons'; import { Select as Select2, @@ -390,7 +391,7 @@ const TeamInfoView: React.FC = ({ - + @@ -402,11 +403,11 @@ const TeamInfoView: React.FC = ({ - + - + = ({ - + = ({ label="Tokens per minute Limit (TPM)" name="tpm_limit" > - + - +