forked from phoenix/litellm-mirror
build: allow resetting customer budget weekly + edit customer budget panel
This commit is contained in:
parent
84d70d75cc
commit
38fd203acd
4 changed files with 183 additions and 11 deletions
|
@ -122,6 +122,7 @@ const BudgetModal: React.FC<BudgetModalProps> = ({
|
||||||
>
|
>
|
||||||
<Select defaultValue={null} placeholder="n/a">
|
<Select defaultValue={null} placeholder="n/a">
|
||||||
<Select.Option value="24h">daily</Select.Option>
|
<Select.Option value="24h">daily</Select.Option>
|
||||||
|
<Select.Option value="7d">weekly</Select.Option>
|
||||||
<Select.Option value="30d">monthly</Select.Option>
|
<Select.Option value="30d">monthly</Select.Option>
|
||||||
</Select>
|
</Select>
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
import React, { useState, useEffect } from "react";
|
import React, { useState, useEffect } from "react";
|
||||||
import BudgetSettings from "./budget_settings";
|
import BudgetSettings from "./budget_settings";
|
||||||
import BudgetModal from "./budget_modal";
|
import BudgetModal from "./budget_modal";
|
||||||
|
import EditBudgetModal from "./edit_budget_modal";
|
||||||
import {
|
import {
|
||||||
Table,
|
Table,
|
||||||
TableBody,
|
TableBody,
|
||||||
|
@ -43,7 +44,7 @@ interface BudgetSettingsPageProps {
|
||||||
accessToken: string | null;
|
accessToken: string | null;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface budgetItem {
|
export interface budgetItem {
|
||||||
budget_id: string;
|
budget_id: string;
|
||||||
max_budget: string | null;
|
max_budget: string | null;
|
||||||
rpm_limit: number | null;
|
rpm_limit: number | null;
|
||||||
|
@ -52,6 +53,8 @@ interface budgetItem {
|
||||||
|
|
||||||
const BudgetPanel: React.FC<BudgetSettingsPageProps> = ({ accessToken }) => {
|
const BudgetPanel: React.FC<BudgetSettingsPageProps> = ({ accessToken }) => {
|
||||||
const [isModalVisible, setIsModalVisible] = useState(false);
|
const [isModalVisible, setIsModalVisible] = useState(false);
|
||||||
|
const [isEditModalVisible, setIsEditModalVisible] = useState(false);
|
||||||
|
const [selectedBudget, setSelectedBudget] = useState<budgetItem | null>(null);
|
||||||
const [budgetList, setBudgetList] = useState<budgetItem[]>([]);
|
const [budgetList, setBudgetList] = useState<budgetItem[]>([]);
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!accessToken) {
|
if (!accessToken) {
|
||||||
|
@ -62,6 +65,15 @@ const BudgetPanel: React.FC<BudgetSettingsPageProps> = ({ accessToken }) => {
|
||||||
});
|
});
|
||||||
}, [accessToken]);
|
}, [accessToken]);
|
||||||
|
|
||||||
|
|
||||||
|
const handleEditCall = async (budget_id: string, index: number) => {
|
||||||
|
if (accessToken == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
setSelectedBudget(budgetList[index])
|
||||||
|
setIsEditModalVisible(true)
|
||||||
|
};
|
||||||
|
|
||||||
const handleDeleteCall = async (budget_id: string, index: number) => {
|
const handleDeleteCall = async (budget_id: string, index: number) => {
|
||||||
if (accessToken == null) {
|
if (accessToken == null) {
|
||||||
return;
|
return;
|
||||||
|
@ -94,6 +106,15 @@ const BudgetPanel: React.FC<BudgetSettingsPageProps> = ({ accessToken }) => {
|
||||||
setIsModalVisible={setIsModalVisible}
|
setIsModalVisible={setIsModalVisible}
|
||||||
setBudgetList={setBudgetList}
|
setBudgetList={setBudgetList}
|
||||||
/>
|
/>
|
||||||
|
{
|
||||||
|
selectedBudget && <EditBudgetModal
|
||||||
|
accessToken={accessToken}
|
||||||
|
isModalVisible={isEditModalVisible}
|
||||||
|
setIsModalVisible={setIsEditModalVisible}
|
||||||
|
setBudgetList={setBudgetList}
|
||||||
|
existingBudget={selectedBudget}
|
||||||
|
/>
|
||||||
|
}
|
||||||
<Card>
|
<Card>
|
||||||
<Text>Create a budget to assign to customers.</Text>
|
<Text>Create a budget to assign to customers.</Text>
|
||||||
<Table>
|
<Table>
|
||||||
|
@ -119,6 +140,11 @@ const BudgetPanel: React.FC<BudgetSettingsPageProps> = ({ accessToken }) => {
|
||||||
<TableCell>
|
<TableCell>
|
||||||
{value.rpm_limit ? value.rpm_limit : "n/a"}
|
{value.rpm_limit ? value.rpm_limit : "n/a"}
|
||||||
</TableCell>
|
</TableCell>
|
||||||
|
<Icon
|
||||||
|
icon={PencilAltIcon}
|
||||||
|
size="sm"
|
||||||
|
onClick={() => handleEditCall(value.budget_id, index)}
|
||||||
|
/>
|
||||||
<Icon
|
<Icon
|
||||||
icon={TrashIcon}
|
icon={TrashIcon}
|
||||||
size="sm"
|
size="sm"
|
||||||
|
|
|
@ -0,0 +1,145 @@
|
||||||
|
import React from "react";
|
||||||
|
import {
|
||||||
|
Button,
|
||||||
|
TextInput,
|
||||||
|
Grid,
|
||||||
|
Col,
|
||||||
|
Accordion,
|
||||||
|
AccordionHeader,
|
||||||
|
AccordionBody,
|
||||||
|
} from "@tremor/react";
|
||||||
|
import {
|
||||||
|
Button as Button2,
|
||||||
|
Modal,
|
||||||
|
Form,
|
||||||
|
Input,
|
||||||
|
InputNumber,
|
||||||
|
Select,
|
||||||
|
message,
|
||||||
|
} from "antd";
|
||||||
|
import { budgetCreateCall } from "../networking";
|
||||||
|
import { budgetItem } from "./budget_panel";
|
||||||
|
|
||||||
|
interface BudgetModalProps {
|
||||||
|
isModalVisible: boolean;
|
||||||
|
accessToken: string | null;
|
||||||
|
setIsModalVisible: React.Dispatch<React.SetStateAction<boolean>>;
|
||||||
|
setBudgetList: React.Dispatch<React.SetStateAction<any[]>>;
|
||||||
|
existingBudget: budgetItem
|
||||||
|
}
|
||||||
|
const EditBudgetModal: React.FC<BudgetModalProps> = ({
|
||||||
|
isModalVisible,
|
||||||
|
accessToken,
|
||||||
|
setIsModalVisible,
|
||||||
|
setBudgetList,
|
||||||
|
existingBudget
|
||||||
|
}) => {
|
||||||
|
const [form] = Form.useForm();
|
||||||
|
const handleOk = () => {
|
||||||
|
setIsModalVisible(false);
|
||||||
|
form.resetFields();
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleCancel = () => {
|
||||||
|
setIsModalVisible(false);
|
||||||
|
form.resetFields();
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleCreate = async (formValues: Record<string, any>) => {
|
||||||
|
if (accessToken == null || accessToken == undefined) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
message.info("Making API Call");
|
||||||
|
// setIsModalVisible(true);
|
||||||
|
const response = await budgetCreateCall(accessToken, formValues);
|
||||||
|
console.log("key create Response:", response);
|
||||||
|
setBudgetList((prevData) =>
|
||||||
|
prevData ? [...prevData, response] : [response]
|
||||||
|
); // Check if prevData is null
|
||||||
|
message.success("API Key Created");
|
||||||
|
form.resetFields();
|
||||||
|
} catch (error) {
|
||||||
|
console.error("Error creating the key:", error);
|
||||||
|
message.error(`Error creating the key: ${error}`, 20);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Modal
|
||||||
|
title="Edit Budget"
|
||||||
|
visible={isModalVisible}
|
||||||
|
width={800}
|
||||||
|
footer={null}
|
||||||
|
onOk={handleOk}
|
||||||
|
onCancel={handleCancel}
|
||||||
|
>
|
||||||
|
<Form
|
||||||
|
form={form}
|
||||||
|
onFinish={handleCreate}
|
||||||
|
labelCol={{ span: 8 }}
|
||||||
|
wrapperCol={{ span: 16 }}
|
||||||
|
labelAlign="left"
|
||||||
|
initialValues={existingBudget}
|
||||||
|
>
|
||||||
|
<>
|
||||||
|
<Form.Item
|
||||||
|
label="Budget ID"
|
||||||
|
name="budget_id"
|
||||||
|
rules={[
|
||||||
|
{
|
||||||
|
required: true,
|
||||||
|
message: "Please input a human-friendly name for the budget",
|
||||||
|
},
|
||||||
|
]}
|
||||||
|
help="A human-friendly name for the budget"
|
||||||
|
>
|
||||||
|
<TextInput placeholder="" />
|
||||||
|
</Form.Item>
|
||||||
|
<Form.Item
|
||||||
|
label="Max Tokens per minute"
|
||||||
|
name="tpm_limit"
|
||||||
|
help="Default is model limit."
|
||||||
|
>
|
||||||
|
<InputNumber step={1} precision={2} width={200} />
|
||||||
|
</Form.Item>
|
||||||
|
<Form.Item
|
||||||
|
label="Max Requests per minute"
|
||||||
|
name="rpm_limit"
|
||||||
|
help="Default is model limit."
|
||||||
|
>
|
||||||
|
<InputNumber step={1} precision={2} width={200} />
|
||||||
|
</Form.Item>
|
||||||
|
|
||||||
|
<Accordion className="mt-20 mb-8">
|
||||||
|
<AccordionHeader>
|
||||||
|
<b>Optional Settings</b>
|
||||||
|
</AccordionHeader>
|
||||||
|
<AccordionBody>
|
||||||
|
<Form.Item label="Max Budget (USD)" name="max_budget">
|
||||||
|
<InputNumber step={0.01} precision={2} width={200} />
|
||||||
|
</Form.Item>
|
||||||
|
<Form.Item
|
||||||
|
className="mt-8"
|
||||||
|
label="Reset Budget"
|
||||||
|
name="budget_duration"
|
||||||
|
>
|
||||||
|
<Select defaultValue={null} placeholder="n/a">
|
||||||
|
<Select.Option value="24h">daily</Select.Option>
|
||||||
|
<Select.Option value="7d">weekly</Select.Option>
|
||||||
|
<Select.Option value="30d">monthly</Select.Option>
|
||||||
|
</Select>
|
||||||
|
</Form.Item>
|
||||||
|
</AccordionBody>
|
||||||
|
</Accordion>
|
||||||
|
</>
|
||||||
|
|
||||||
|
<div style={{ textAlign: "right", marginTop: "10px" }}>
|
||||||
|
<Button2 htmlType="submit">Edit Budget</Button2>
|
||||||
|
</div>
|
||||||
|
</Form>
|
||||||
|
</Modal>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default EditBudgetModal;
|
|
@ -152,16 +152,16 @@ const Team: React.FC<TeamProps> = ({
|
||||||
<InputNumber step={0.01} precision={2} width={200} />
|
<InputNumber step={0.01} precision={2} width={200} />
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
<Form.Item
|
<Form.Item
|
||||||
className="mt-8"
|
className="mt-8"
|
||||||
label="Reset Budget"
|
label="Reset Budget"
|
||||||
name="budget_duration"
|
name="budget_duration"
|
||||||
>
|
>
|
||||||
<Select2 defaultValue={null} placeholder="n/a">
|
<Select2 defaultValue={null} placeholder="n/a">
|
||||||
<Select2.Option value="24h">daily</Select2.Option>
|
<Select2.Option value="24h">daily</Select2.Option>
|
||||||
<Select2.Option value="7d">weekly</Select2.Option>
|
<Select2.Option value="7d">weekly</Select2.Option>
|
||||||
<Select2.Option value="30d">monthly</Select2.Option>
|
<Select2.Option value="30d">monthly</Select2.Option>
|
||||||
</Select2>
|
</Select2>
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
<Form.Item label="Tokens per minute Limit (TPM)" name="tpm_limit">
|
<Form.Item label="Tokens per minute Limit (TPM)" name="tpm_limit">
|
||||||
<InputNumber step={1} width={400} />
|
<InputNumber step={1} width={400} />
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue