From 9bdb96ad9cf383d8635595bec97afbdb4c1692eb Mon Sep 17 00:00:00 2001 From: Ishaan Jaff Date: Fri, 6 Sep 2024 10:19:37 -0700 Subject: [PATCH] allow correct fields on regenerate key --- .../src/components/view_key_table.tsx | 143 +++++++++++++++--- 1 file changed, 125 insertions(+), 18 deletions(-) diff --git a/ui/litellm-dashboard/src/components/view_key_table.tsx b/ui/litellm-dashboard/src/components/view_key_table.tsx index 70e8c520459..659567949e3 100644 --- a/ui/litellm-dashboard/src/components/view_key_table.tsx +++ b/ui/litellm-dashboard/src/components/view_key_table.tsx @@ -22,6 +22,7 @@ import { Subtitle, Icon, BarChart, + TextInput, } from "@tremor/react"; import { Select as Select3, SelectItem, MultiSelect, MultiSelectItem } from "@tremor/react"; import { @@ -33,7 +34,8 @@ import { InputNumber, message, Select, - Tooltip + Tooltip, + DatePicker, } from "antd"; import { CopyToClipboard } from "react-copy-to-clipboard"; @@ -120,6 +122,7 @@ const ViewKeyTable: React.FC = ({ const [modelLimitModalVisible, setModelLimitModalVisible] = useState(false); const [regenerateDialogVisible, setRegenerateDialogVisible] = useState(false); const [regeneratedKey, setRegeneratedKey] = useState(null); + const [regenerateFormData, setRegenerateFormData] = useState(null); const [knownTeamIDs, setKnownTeamIDs] = useState(initialKnownTeamIDs); @@ -146,6 +149,42 @@ const ViewKeyTable: React.FC = ({ fetchUserModels(); }, [accessToken, userID, userRole]); + const [newExpiryTime, setNewExpiryTime] = useState(null); + + useEffect(() => { + if (regenerateFormData?.duration) { + try { + const now = new Date(); + const duration = regenerateFormData.duration; + let newExpiry: Date; + + if (duration.endsWith('s')) { + newExpiry = add(now, { seconds: parseInt(duration) }); + } else if (duration.endsWith('h')) { + newExpiry = add(now, { hours: parseInt(duration) }); + } else if (duration.endsWith('d')) { + newExpiry = add(now, { days: parseInt(duration) }); + } else { + throw new Error('Invalid duration format'); + } + + setNewExpiryTime(newExpiry.toLocaleString('en-US', { + year: 'numeric', + month: 'numeric', + day: 'numeric', + hour: 'numeric', + minute: 'numeric', + second: 'numeric', + hour12: true + })); + } catch (error) { + setNewExpiryTime(null); + } + } else { + setNewExpiryTime(null); + } + }, [regenerateFormData?.duration]); + const handleModelLimitClick = (token: ItemData) => { setSelectedToken(token); setModelLimitModalVisible(true); @@ -678,6 +717,22 @@ const ViewKeyTable: React.FC = ({ setKeyToDelete(null); }; + const handleRegenerateClick = (token: any) => { + setSelectedToken(token); + setRegenerateFormData({ + ...token, + duration: token.duration || 'none', // Set a default value if duration is not present + }); + setRegenerateDialogVisible(true); + }; + + const handleRegenerateFormChange = (field: string, value: any) => { + setRegenerateFormData((prev: any) => ({ + ...prev, + [field]: value, + })); + }; + const handleRegenerateKey = async () => { if (!premiumUser) { message.error("Regenerate API Key is an Enterprise feature. Please upgrade to use this feature."); @@ -685,24 +740,25 @@ const ViewKeyTable: React.FC = ({ } try { - if (selectedToken == null) { - message.error("Please select a key to regenerate"); + if (regenerateFormData == null) { + message.error("Please fill in the key details"); return; } - const response = await regenerateKeyCall(accessToken, selectedToken.token); + const response = await regenerateKeyCall(accessToken, regenerateFormData); setRegeneratedKey(response.key); // Update the data state with the new key_name if (data) { const updatedData = data.map(item => - item.token === selectedToken.token - ? { ...item, key_name: response.key_name } + item.token === selectedToken?.token + ? { ...item, key_name: response.key_name, ...regenerateFormData } : item ); setData(updatedData); } setRegenerateDialogVisible(false); + setRegenerateFormData(null); message.success("API Key regenerated successfully"); } catch (error) { console.error("Error regenerating key:", error); @@ -997,10 +1053,7 @@ const ViewKeyTable: React.FC = ({ onClick={() => handleEditClick(item)} /> { - setSelectedToken(item); - setRegenerateDialogVisible(true); - }} + onClick={() => handleRegenerateClick(item)} icon={RefreshIcon} size="sm" /> @@ -1080,13 +1133,19 @@ const ViewKeyTable: React.FC = ({ /> )} - {/* Regenerate Key Confirmation Dialog */} + {/* Regenerate Key Form Modal */} setRegenerateDialogVisible(false)} + onCancel={() => { + setRegenerateDialogVisible(false); + setRegenerateFormData(null); + }} footer={[ - ,