[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
This commit is contained in:
Ishaan Jaff 2025-04-05 12:29:31 -07:00 committed by GitHub
parent 3a7061a05c
commit 80eb1ac8fa
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
9 changed files with 92 additions and 39 deletions

View file

@ -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<CreateKeyProps> = ({
},
]}
>
<InputNumber step={0.01} precision={2} width={200} />
<NumericalInput step={0.01} precision={2} width={200} />
</Form.Item>
<Form.Item
className="mt-4"
@ -605,7 +605,7 @@ const CreateKey: React.FC<CreateKeyProps> = ({
},
]}
>
<InputNumber step={1} width={400} />
<NumericalInput step={1} width={400} />
</Form.Item>
<Form.Item
className="mt-4"
@ -636,7 +636,7 @@ const CreateKey: React.FC<CreateKeyProps> = ({
},
]}
>
<InputNumber step={1} width={400} />
<NumericalInput step={1} width={400} />
</Form.Item>
<Form.Item
label={

View file

@ -17,10 +17,11 @@ import {
Form,
Input,
Select as Select2,
InputNumber,
message,
} from "antd";
import NumericalInput from "./shared/numerical_input";
interface EditUserModalProps {
visible: boolean;
possibleUIRoles: null | Record<string, Record<string, string>>;
@ -112,7 +113,7 @@ const EditUserModal: React.FC<EditUserModalProps> = ({ visible, possibleUIRoles,
tooltip="(float) - Spend of all LLM calls completed by this user"
help="Across all keys (including keys with team_id)."
>
<InputNumber min={0} step={1} />
<NumericalInput min={0} step={1} />
</Form.Item>
<Form.Item
@ -121,7 +122,7 @@ const EditUserModal: React.FC<EditUserModalProps> = ({ visible, possibleUIRoles,
tooltip="(float) - Maximum budget of this user"
help="Maximum budget of this user."
>
<InputNumber min={0} step={1} />
<NumericalInput min={0} step={1} />
</Form.Item>
<div style={{ textAlign: "right", marginTop: "10px" }}>

View file

@ -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({
</Form.Item>
<Form.Item label="Max Budget (USD)" name="max_budget">
<InputNumber step={0.01} precision={2} style={{ width: "100%" }} />
<NumericalInput step={0.01} style={{ width: "100%" }} placeholder="Enter a numerical value"/>
</Form.Item>
<Form.Item label="Reset Budget" name="budget_duration">
@ -138,15 +138,15 @@ export function KeyEditView({
</Form.Item>
<Form.Item label="TPM Limit" name="tpm_limit">
<InputNumber style={{ width: "100%" }} min={0}/>
<NumericalInput min={0}/>
</Form.Item>
<Form.Item label="RPM Limit" name="rpm_limit">
<InputNumber style={{ width: "100%" }} min={0}/>
<NumericalInput min={0}/>
</Form.Item>
<Form.Item label="Max Parallel Requests" name="max_parallel_requests">
<InputNumber style={{ width: "100%" }} min={0}/>
<NumericalInput min={0}/>
</Form.Item>
<Form.Item label="Model TPM Limit" name="model_tpm_limit">

View file

@ -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({
<Text className="font-medium">Input Cost (per 1M tokens)</Text>
{isEditing ? (
<Form.Item name="input_cost" className="mb-0">
<NumberInput placeholder="Enter input cost" />
<NumericalInput placeholder="Enter input cost" />
</Form.Item>
) : (
<div className="mt-1 p-2 bg-gray-50 rounded">
@ -384,7 +384,7 @@ export default function ModelInfoView({
<Text className="font-medium">Output Cost (per 1M tokens)</Text>
{isEditing ? (
<Form.Item name="output_cost" className="mb-0">
<NumberInput placeholder="Enter output cost" />
<NumericalInput placeholder="Enter output cost" />
</Form.Item>
) : (
<div className="mt-1 p-2 bg-gray-50 rounded">
@ -438,7 +438,7 @@ export default function ModelInfoView({
<Text className="font-medium">TPM (Tokens per Minute)</Text>
{isEditing ? (
<Form.Item name="tpm" className="mb-0">
<NumberInput placeholder="Enter TPM" />
<NumericalInput placeholder="Enter TPM" />
</Form.Item>
) : (
<div className="mt-1 p-2 bg-gray-50 rounded">
@ -448,10 +448,10 @@ export default function ModelInfoView({
</div>
<div>
<Text className="font-medium">RPM (Requests per Minute)</Text>
<Text className="font-medium">RPM VVV(Requests per Minute)</Text>
{isEditing ? (
<Form.Item name="rpm" className="mb-0">
<NumberInput placeholder="Enter RPM" />
<NumericalInput placeholder="Enter RPM" />
</Form.Item>
) : (
<div className="mt-1 p-2 bg-gray-50 rounded">
@ -464,7 +464,7 @@ export default function ModelInfoView({
<Text className="font-medium">Max Retries</Text>
{isEditing ? (
<Form.Item name="max_retries" className="mb-0">
<NumberInput placeholder="Enter max retries" />
<NumericalInput placeholder="Enter max retries" />
</Form.Item>
) : (
<div className="mt-1 p-2 bg-gray-50 rounded">
@ -477,7 +477,7 @@ export default function ModelInfoView({
<Text className="font-medium">Timeout (seconds)</Text>
{isEditing ? (
<Form.Item name="timeout" className="mb-0">
<NumberInput placeholder="Enter timeout" />
<NumericalInput placeholder="Enter timeout" />
</Form.Item>
) : (
<div className="mt-1 p-2 bg-gray-50 rounded">
@ -490,7 +490,7 @@ export default function ModelInfoView({
<Text className="font-medium">Stream Timeout (seconds)</Text>
{isEditing ? (
<Form.Item name="stream_timeout" className="mb-0">
<NumberInput placeholder="Enter stream timeout" />
<NumericalInput placeholder="Enter stream timeout" />
</Form.Item>
) : (
<div className="mt-1 p-2 bg-gray-50 rounded">

View file

@ -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<OrganizationInfoProps> = ({
name="organization_alias"
rules={[{ required: true, message: "Please input an organization name" }]}
>
<Input />
<TextInput />
</Form.Item>
<Form.Item label="Models" name="models">
@ -358,7 +360,7 @@ const OrganizationInfoView: React.FC<OrganizationInfoProps> = ({
</Form.Item>
<Form.Item label="Max Budget (USD)" name="max_budget">
<InputNumber step={0.01} precision={2} style={{ width: "100%" }} />
<NumericalInput step={0.01} precision={2} style={{ width: "100%" }} />
</Form.Item>
<Form.Item label="Reset Budget" name="budget_duration">
@ -370,11 +372,11 @@ const OrganizationInfoView: React.FC<OrganizationInfoProps> = ({
</Form.Item>
<Form.Item label="Tokens per minute Limit (TPM)" name="tpm_limit">
<InputNumber step={1} style={{ width: "100%" }} />
<NumericalInput step={1} style={{ width: "100%" }} />
</Form.Item>
<Form.Item label="Requests per minute Limit (RPM)" name="rpm_limit">
<InputNumber step={1} style={{ width: "100%" }} />
<NumericalInput step={1} style={{ width: "100%" }} />
</Form.Item>
<Form.Item label="Metadata" name="metadata">

View file

@ -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<OrganizationsTableProps> = ({
</Form.Item>
<Form.Item label="Max Budget (USD)" name="max_budget">
<InputNumber step={0.01} precision={2} width={200} />
<NumericalInput step={0.01} precision={2} width={200} />
</Form.Item>
<Form.Item label="Reset Budget" name="budget_duration">
<Select2 defaultValue={null} placeholder="n/a">
@ -331,10 +332,10 @@ const OrganizationsTable: React.FC<OrganizationsTableProps> = ({
</Select2>
</Form.Item>
<Form.Item label="Tokens per minute Limit (TPM)" name="tpm_limit">
<InputNumber step={1} width={400} />
<NumericalInput step={1} width={400} />
</Form.Item>
<Form.Item label="Requests per minute Limit (RPM)" name="rpm_limit">
<InputNumber step={1} width={400} />
<NumericalInput step={1} width={400} />
</Form.Item>
<Form.Item label="Metadata" name="metadata">

View file

@ -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<NumericalInputProps> = ({
step = 0.01,
style = { width: "100%" },
placeholder = "Enter a numerical value",
min,
max,
onChange,
...rest
}) => {
return (
<NumberInput
onWheel={ event => event.currentTarget.blur()}
step={step}
style={style}
placeholder={placeholder}
min={min}
max={max}
onChange={onChange}
{...rest}
/>
);
};
export default NumericalInput;

View file

@ -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<TeamInfoProps> = ({
</Form.Item>
<Form.Item label="Max Budget (USD)" name="max_budget">
<InputNumber step={0.01} precision={2} style={{ width: "100%" }} />
<NumericalInput step={0.01} precision={2} style={{ width: "100%" }} />
</Form.Item>
<Form.Item label="Reset Budget" name="budget_duration">
@ -402,11 +403,11 @@ const TeamInfoView: React.FC<TeamInfoProps> = ({
</Form.Item>
<Form.Item label="Tokens per minute Limit (TPM)" name="tpm_limit">
<InputNumber step={1} style={{ width: "100%" }} />
<NumericalInput step={1} style={{ width: "100%" }} />
</Form.Item>
<Form.Item label="Requests per minute Limit (RPM)" name="rpm_limit">
<InputNumber step={1} style={{ width: "100%" }} />
<NumericalInput step={1} style={{ width: "100%" }} />
</Form.Item>
<Form.Item

View file

@ -18,10 +18,10 @@ import {
Form,
Input,
Select as Select2,
InputNumber,
message,
Tooltip
} from "antd";
import NumericalInput from "./shared/numerical_input";
import { fetchAvailableModelsForTeamOrKey, getModelDisplayName, unfurlWildcardModelsInList } from "./key_team_helpers/fetch_available_models_team_key";
import { Select, SelectItem } from "@tremor/react";
import { InfoCircleOutlined } from '@ant-design/icons';
@ -690,7 +690,7 @@ const Teams: React.FC<TeamProps> = ({
</Form.Item>
<Form.Item label="Max Budget (USD)" name="max_budget">
<InputNumber step={0.01} precision={2} width={200} />
<NumericalInput step={0.01} precision={2} width={200} />
</Form.Item>
<Form.Item
className="mt-8"
@ -707,13 +707,13 @@ const Teams: React.FC<TeamProps> = ({
label="Tokens per minute Limit (TPM)"
name="tpm_limit"
>
<InputNumber step={1} width={400} />
<NumericalInput step={1} width={400} />
</Form.Item>
<Form.Item
label="Requests per minute Limit (RPM)"
name="rpm_limit"
>
<InputNumber step={1} width={400} />
<NumericalInput step={1} width={400} />
</Form.Item>
<Accordion className="mt-20 mb-8">