Merge pull request #13629 from BerriAI/budget-duration

Edit Budget Duration + Other Improvements in User Settings
This commit is contained in:
Krish Dholakia 2025-08-16 11:19:07 -07:00 • committed by GitHub
commit 73f89d51a1
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
6 changed files with 42 additions and 4 deletions

View file

@ -104,6 +104,10 @@ const BulkEditUserModal: React.FC<BulkEditUserModalProps> = ({
updatePayload.models = formValues.models;
}
if (formValues.budget_duration && formValues.budget_duration !== "") {
updatePayload.budget_duration = formValues.budget_duration;
}
if (formValues.metadata && Object.keys(formValues.metadata).length > 0) {
updatePayload.metadata = formValues.metadata;
}

View file

@ -5,7 +5,7 @@ const { Option } = Select;
interface BudgetDurationDropdownProps {
value?: string | null;
onChange: (value: string) => void;
onChange?: (value: string) => void;
className?: string;
style?: React.CSSProperties;
}

View file

@ -22,6 +22,7 @@ import {
} from "antd";
import NumericalInput from "./shared/numerical_input";
import BudgetDurationDropdown from "./common_components/budget_duration_dropdown";
interface EditUserModalProps {
visible: boolean;
@ -126,6 +127,14 @@ const EditUserModal: React.FC<EditUserModalProps> = ({ visible, possibleUIRoles,
<NumericalInput min={0} step={0.01} />
</Form.Item>
<Form.Item label="Reset Budget" name="budget_duration">
<BudgetDurationDropdown />
</Form.Item>
<div style={{ textAlign: "right", marginTop: "10px" }}>
<Button2 htmlType="submit">Save</Button2>
</div>
<div style={{ textAlign: "right", marginTop: "10px" }}>
<Button2 htmlType="submit">Save</Button2>
</div>

View file

@ -5,6 +5,8 @@ import { Button } from "@tremor/react";
import { getModelDisplayName } from "./key_team_helpers/fetch_available_models_team_key";
import { all_admin_roles } from "../utils/roles";
import { InfoCircleOutlined } from "@ant-design/icons";
import BudgetDurationDropdown from "./common_components/budget_duration_dropdown";
interface UserEditViewProps {
userData: any;
onCancel: () => void;
@ -40,6 +42,7 @@ export function UserEditView({
user_role: userData.user_info?.user_role,
models: userData.user_info?.models || [],
max_budget: userData.user_info?.max_budget,
budget_duration: userData.user_info?.budget_duration,
metadata: userData.user_info?.metadata ? JSON.stringify(userData.user_info.metadata, null, 2) : undefined,
});
}, [userData, form]);
@ -154,6 +157,10 @@ export function UserEditView({
/>
</Form.Item>
<Form.Item label="Reset Budget" name="budget_duration">
<BudgetDurationDropdown />
</Form.Item>
<Form.Item
label="Metadata"
name="metadata"

View file

@ -8,4 +8,5 @@ export interface UserInfo {
created_at: string;
updated_at: string;
sso_user_id: string | null;
}
budget_duration: string | null;
}

View file

@ -16,6 +16,7 @@ import OnboardingModal, { InvitationLink } from "../onboarding_link"
import { formatNumberWithCommas, copyToClipboard as utilCopyToClipboard } from "@/utils/dataUtils"
import { CopyIcon, CheckIcon } from "lucide-react";
import NotificationManager from "../molecules/notifications_manager";
import { getBudgetDurationLabel } from "../common_components/budget_duration_dropdown";
interface UserInfoViewProps {
userId: string
@ -36,6 +37,7 @@ interface UserInfo {
teams: any[] | null
models: string[] | null
max_budget: number | null
budget_duration: string | null
spend: number | null
metadata: Record<string, any> | null
created_at: string | null
@ -137,6 +139,7 @@ export default function UserInfoView({
user_email: formValues.user_email,
models: formValues.models,
max_budget: formValues.max_budget,
budget_duration: formValues.budget_duration,
metadata: formValues.metadata,
},
})
@ -355,7 +358,7 @@ export default function UserInfoView({
</div>
<div>
<Text className="font-medium">Role</Text>
<Text className="font-medium">Global Proxy Role</Text>
<Text>{userData.user_info?.user_role || "Not Set"}</Text>
</div>
@ -393,7 +396,7 @@ export default function UserInfoView({
</div>
<div>
<Text className="font-medium">Models</Text>
<Text className="font-medium">Personal Models</Text>
<div className="flex flex-wrap gap-2 mt-1">
{userData.user_info?.models?.length && userData.user_info?.models?.length > 0 ? (
userData.user_info?.models?.map((model, index) => (
@ -422,6 +425,20 @@ export default function UserInfoView({
</div>
</div>
<div>
<Text className="font-medium">Max Budget</Text>
<Text>
{userData.user_info?.max_budget !== null && userData.user_info?.max_budget !== undefined
? `$${formatNumberWithCommas(userData.user_info.max_budget, 4)}`
: "Unlimited"}
</Text>
</div>
<div>
<Text className="font-medium">Budget Reset</Text>
<Text>{getBudgetDurationLabel(userData.user_info?.budget_duration ?? null)}</Text>
</div>
<div>
<Text className="font-medium">Metadata</Text>
<pre className="bg-gray-100 p-2 rounded text-xs overflow-auto mt-1">