mirror of
https://github.com/BerriAI/litellm.git
synced 2026-09-07 08:26:10 +00:00
parent
6fff77d131
commit
503b38e609
3 changed files with 224 additions and 240 deletions
|
|
@ -20,17 +20,15 @@ import Usage from "../components/usage";
|
|||
import CacheDashboard from "@/components/cache_dashboard";
|
||||
import { jwtDecode } from "jwt-decode";
|
||||
import { Typography } from "antd";
|
||||
import { setGlobalLitellmHeaderName } from "../components/networking"
|
||||
import { setGlobalLitellmHeaderName } from "../components/networking";
|
||||
|
||||
function getCookie(name: string) {
|
||||
console.log("COOKIES", document.cookie)
|
||||
const cookieValue = document.cookie
|
||||
.split('; ')
|
||||
.find(row => row.startsWith(name + '='));
|
||||
return cookieValue ? cookieValue.split('=')[1] : null;
|
||||
.split("; ")
|
||||
.find((row) => row.startsWith(name + "="));
|
||||
return cookieValue ? cookieValue.split("=")[1] : null;
|
||||
}
|
||||
|
||||
|
||||
function formatUserRole(userRole: string) {
|
||||
if (!userRole) {
|
||||
return "Undefined Role";
|
||||
|
|
@ -68,7 +66,8 @@ const CreateKeyPage = () => {
|
|||
const { Title, Paragraph } = Typography;
|
||||
const [userRole, setUserRole] = useState("");
|
||||
const [premiumUser, setPremiumUser] = useState(false);
|
||||
const [disabledPersonalKeyCreation, setDisabledPersonalKeyCreation] = useState(false);
|
||||
const [disabledPersonalKeyCreation, setDisabledPersonalKeyCreation] =
|
||||
useState(false);
|
||||
const [userEmail, setUserEmail] = useState<null | string>(null);
|
||||
const [teams, setTeams] = useState<null | any[]>(null);
|
||||
const [keys, setKeys] = useState<null | any[]>(null);
|
||||
|
|
@ -80,244 +79,244 @@ const CreateKeyPage = () => {
|
|||
const [showSSOBanner, setShowSSOBanner] = useState<boolean>(true);
|
||||
const searchParams = useSearchParams()!;
|
||||
const [modelData, setModelData] = useState<any>({ data: [] });
|
||||
const [token, setToken] = useState<string | null>(null);
|
||||
|
||||
const userID = searchParams.get("userID");
|
||||
const invitation_id = searchParams.get("invitation_id");
|
||||
const token = getCookie('token');
|
||||
|
||||
// Get page from URL, default to 'api-keys' if not present
|
||||
const [page, setPage] = useState(() => {
|
||||
return searchParams.get('page') || 'api-keys';
|
||||
return searchParams.get("page") || "api-keys";
|
||||
});
|
||||
|
||||
// Custom setPage function that updates URL
|
||||
const updatePage = (newPage: string) => {
|
||||
// Update URL without full page reload
|
||||
const newSearchParams = new URLSearchParams(searchParams);
|
||||
newSearchParams.set('page', newPage);
|
||||
|
||||
newSearchParams.set("page", newPage);
|
||||
|
||||
// Use Next.js router to update URL
|
||||
window.history.pushState(
|
||||
null,
|
||||
'',
|
||||
`?${newSearchParams.toString()}`
|
||||
);
|
||||
|
||||
window.history.pushState(null, "", `?${newSearchParams.toString()}`);
|
||||
|
||||
setPage(newPage);
|
||||
};
|
||||
|
||||
const [accessToken, setAccessToken] = useState<string | null>(null);
|
||||
|
||||
useEffect(() => {
|
||||
if (token) {
|
||||
const decoded = jwtDecode(token) as { [key: string]: any };
|
||||
if (decoded) {
|
||||
// cast decoded to dictionary
|
||||
console.log("Decoded token:", decoded);
|
||||
const token = getCookie("token");
|
||||
setToken(token);
|
||||
}, []);
|
||||
|
||||
console.log("Decoded key:", decoded.key);
|
||||
// set accessToken
|
||||
setAccessToken(decoded.key);
|
||||
useEffect(() => {
|
||||
if (!token) {
|
||||
return;
|
||||
}
|
||||
|
||||
setDisabledPersonalKeyCreation(decoded.disabled_non_admin_personal_key_creation);
|
||||
const decoded = jwtDecode(token) as { [key: string]: any };
|
||||
if (decoded) {
|
||||
// cast decoded to dictionary
|
||||
console.log("Decoded token:", decoded);
|
||||
|
||||
// check if userRole is defined
|
||||
if (decoded.user_role) {
|
||||
const formattedUserRole = formatUserRole(decoded.user_role);
|
||||
console.log("Decoded user_role:", formattedUserRole);
|
||||
setUserRole(formattedUserRole);
|
||||
if (formattedUserRole == "Admin Viewer") {
|
||||
setPage("usage");
|
||||
}
|
||||
} else {
|
||||
console.log("User role not defined");
|
||||
console.log("Decoded key:", decoded.key);
|
||||
// set accessToken
|
||||
setAccessToken(decoded.key);
|
||||
|
||||
setDisabledPersonalKeyCreation(
|
||||
decoded.disabled_non_admin_personal_key_creation,
|
||||
);
|
||||
|
||||
// check if userRole is defined
|
||||
if (decoded.user_role) {
|
||||
const formattedUserRole = formatUserRole(decoded.user_role);
|
||||
console.log("Decoded user_role:", formattedUserRole);
|
||||
setUserRole(formattedUserRole);
|
||||
if (formattedUserRole == "Admin Viewer") {
|
||||
setPage("usage");
|
||||
}
|
||||
} else {
|
||||
console.log("User role not defined");
|
||||
}
|
||||
|
||||
if (decoded.user_email) {
|
||||
setUserEmail(decoded.user_email);
|
||||
} else {
|
||||
console.log(`User Email is not set ${decoded}`);
|
||||
}
|
||||
if (decoded.user_email) {
|
||||
setUserEmail(decoded.user_email);
|
||||
} else {
|
||||
console.log(`User Email is not set ${decoded}`);
|
||||
}
|
||||
|
||||
if (decoded.login_method) {
|
||||
setShowSSOBanner(
|
||||
decoded.login_method == "username_password" ? true : false
|
||||
);
|
||||
} else {
|
||||
console.log(`User Email is not set ${decoded}`);
|
||||
}
|
||||
if (decoded.login_method) {
|
||||
setShowSSOBanner(
|
||||
decoded.login_method == "username_password" ? true : false,
|
||||
);
|
||||
} else {
|
||||
console.log(`User Email is not set ${decoded}`);
|
||||
}
|
||||
|
||||
if (decoded.premium_user) {
|
||||
setPremiumUser(decoded.premium_user);
|
||||
}
|
||||
if (decoded.premium_user) {
|
||||
setPremiumUser(decoded.premium_user);
|
||||
}
|
||||
|
||||
if (decoded.auth_header_name) {
|
||||
setGlobalLitellmHeaderName(decoded.auth_header_name);
|
||||
}
|
||||
|
||||
if (decoded.auth_header_name) {
|
||||
setGlobalLitellmHeaderName(decoded.auth_header_name);
|
||||
}
|
||||
}
|
||||
}, [token]);
|
||||
|
||||
return (
|
||||
<Suspense fallback={<div>Loading...</div>}>
|
||||
{
|
||||
invitation_id ? (
|
||||
<UserDashboard
|
||||
userID={userID}
|
||||
userRole={userRole}
|
||||
premiumUser={premiumUser}
|
||||
teams={teams}
|
||||
keys={keys}
|
||||
setUserRole={setUserRole}
|
||||
userEmail={userEmail}
|
||||
setUserEmail={setUserEmail}
|
||||
setTeams={setTeams}
|
||||
setKeys={setKeys}
|
||||
/>
|
||||
) : (
|
||||
<div className="flex flex-col min-h-screen">
|
||||
<Navbar
|
||||
{invitation_id ? (
|
||||
<UserDashboard
|
||||
userID={userID}
|
||||
userRole={userRole}
|
||||
userEmail={userEmail}
|
||||
premiumUser={premiumUser}
|
||||
setProxySettings={setProxySettings}
|
||||
proxySettings={proxySettings}
|
||||
teams={teams}
|
||||
keys={keys}
|
||||
setUserRole={setUserRole}
|
||||
userEmail={userEmail}
|
||||
setUserEmail={setUserEmail}
|
||||
setTeams={setTeams}
|
||||
setKeys={setKeys}
|
||||
/>
|
||||
<div className="flex flex-1 overflow-auto">
|
||||
<div className="mt-8">
|
||||
) : (
|
||||
<div className="flex flex-col min-h-screen">
|
||||
<Navbar
|
||||
userID={userID}
|
||||
userRole={userRole}
|
||||
userEmail={userEmail}
|
||||
premiumUser={premiumUser}
|
||||
setProxySettings={setProxySettings}
|
||||
proxySettings={proxySettings}
|
||||
/>
|
||||
<div className="flex flex-1 overflow-auto">
|
||||
<div className="mt-8">
|
||||
<Sidebar
|
||||
setPage={updatePage}
|
||||
userRole={userRole}
|
||||
defaultSelectedKey={page}
|
||||
/>
|
||||
</div>
|
||||
/>
|
||||
</div>
|
||||
|
||||
{page == "api-keys" ? (
|
||||
<UserDashboard
|
||||
userID={userID}
|
||||
userRole={userRole}
|
||||
premiumUser={premiumUser}
|
||||
teams={teams}
|
||||
keys={keys}
|
||||
setUserRole={setUserRole}
|
||||
userEmail={userEmail}
|
||||
setUserEmail={setUserEmail}
|
||||
setTeams={setTeams}
|
||||
setKeys={setKeys}
|
||||
/>
|
||||
) : page == "models" ? (
|
||||
<ModelDashboard
|
||||
userID={userID}
|
||||
userRole={userRole}
|
||||
token={token}
|
||||
keys={keys}
|
||||
accessToken={accessToken}
|
||||
modelData={modelData}
|
||||
setModelData={setModelData}
|
||||
premiumUser={premiumUser}
|
||||
/>
|
||||
) : page == "llm-playground" ? (
|
||||
<ChatUI
|
||||
userID={userID}
|
||||
userRole={userRole}
|
||||
token={token}
|
||||
accessToken={accessToken}
|
||||
disabledPersonalKeyCreation={disabledPersonalKeyCreation}
|
||||
/>
|
||||
) : page == "users" ? (
|
||||
<ViewUserDashboard
|
||||
userID={userID}
|
||||
userRole={userRole}
|
||||
token={token}
|
||||
keys={keys}
|
||||
teams={teams}
|
||||
accessToken={accessToken}
|
||||
setKeys={setKeys}
|
||||
/>
|
||||
) : page == "teams" ? (
|
||||
<Teams
|
||||
teams={teams}
|
||||
setTeams={setTeams}
|
||||
searchParams={searchParams}
|
||||
accessToken={accessToken}
|
||||
userID={userID}
|
||||
userRole={userRole}
|
||||
/>
|
||||
) : page == "organizations" ? (
|
||||
<Organizations
|
||||
teams={teams}
|
||||
setTeams={setTeams}
|
||||
searchParams={searchParams}
|
||||
accessToken={accessToken}
|
||||
userID={userID}
|
||||
userRole={userRole}
|
||||
premiumUser={premiumUser}
|
||||
/>
|
||||
) : page == "admin-panel" ? (
|
||||
<AdminPanel
|
||||
setTeams={setTeams}
|
||||
searchParams={searchParams}
|
||||
accessToken={accessToken}
|
||||
showSSOBanner={showSSOBanner}
|
||||
premiumUser={premiumUser}
|
||||
/>
|
||||
) : page == "api_ref" ? (
|
||||
<APIRef
|
||||
proxySettings={proxySettings}
|
||||
/>
|
||||
) : page == "settings" ? (
|
||||
<Settings
|
||||
userID={userID}
|
||||
userRole={userRole}
|
||||
accessToken={accessToken}
|
||||
premiumUser={premiumUser}
|
||||
/>
|
||||
) : page == "budgets" ? (
|
||||
<BudgetPanel accessToken={accessToken} />
|
||||
) : page == "general-settings" ? (
|
||||
<GeneralSettings
|
||||
userID={userID}
|
||||
userRole={userRole}
|
||||
accessToken={accessToken}
|
||||
modelData={modelData}
|
||||
/>
|
||||
) : page == "model-hub" ? (
|
||||
<ModelHub
|
||||
accessToken={accessToken}
|
||||
publicPage={false}
|
||||
premiumUser={premiumUser}
|
||||
/>
|
||||
) : page == "caching" ? (
|
||||
<CacheDashboard
|
||||
userID={userID}
|
||||
userRole={userRole}
|
||||
token={token}
|
||||
accessToken={accessToken}
|
||||
premiumUser={premiumUser}
|
||||
/>
|
||||
) : page == "pass-through-settings" ? (
|
||||
<PassThroughSettings
|
||||
userID={userID}
|
||||
userRole={userRole}
|
||||
accessToken={accessToken}
|
||||
modelData={modelData}
|
||||
/>
|
||||
) : (
|
||||
<Usage
|
||||
userID={userID}
|
||||
userRole={userRole}
|
||||
token={token}
|
||||
accessToken={accessToken}
|
||||
keys={keys}
|
||||
premiumUser={premiumUser}
|
||||
/>
|
||||
)}
|
||||
{page == "api-keys" ? (
|
||||
<UserDashboard
|
||||
userID={userID}
|
||||
userRole={userRole}
|
||||
premiumUser={premiumUser}
|
||||
teams={teams}
|
||||
keys={keys}
|
||||
setUserRole={setUserRole}
|
||||
userEmail={userEmail}
|
||||
setUserEmail={setUserEmail}
|
||||
setTeams={setTeams}
|
||||
setKeys={setKeys}
|
||||
/>
|
||||
) : page == "models" ? (
|
||||
<ModelDashboard
|
||||
userID={userID}
|
||||
userRole={userRole}
|
||||
token={token}
|
||||
keys={keys}
|
||||
accessToken={accessToken}
|
||||
modelData={modelData}
|
||||
setModelData={setModelData}
|
||||
premiumUser={premiumUser}
|
||||
/>
|
||||
) : page == "llm-playground" ? (
|
||||
<ChatUI
|
||||
userID={userID}
|
||||
userRole={userRole}
|
||||
token={token}
|
||||
accessToken={accessToken}
|
||||
disabledPersonalKeyCreation={disabledPersonalKeyCreation}
|
||||
/>
|
||||
) : page == "users" ? (
|
||||
<ViewUserDashboard
|
||||
userID={userID}
|
||||
userRole={userRole}
|
||||
token={token}
|
||||
keys={keys}
|
||||
teams={teams}
|
||||
accessToken={accessToken}
|
||||
setKeys={setKeys}
|
||||
/>
|
||||
) : page == "teams" ? (
|
||||
<Teams
|
||||
teams={teams}
|
||||
setTeams={setTeams}
|
||||
searchParams={searchParams}
|
||||
accessToken={accessToken}
|
||||
userID={userID}
|
||||
userRole={userRole}
|
||||
/>
|
||||
) : page == "organizations" ? (
|
||||
<Organizations
|
||||
teams={teams}
|
||||
setTeams={setTeams}
|
||||
searchParams={searchParams}
|
||||
accessToken={accessToken}
|
||||
userID={userID}
|
||||
userRole={userRole}
|
||||
premiumUser={premiumUser}
|
||||
/>
|
||||
) : page == "admin-panel" ? (
|
||||
<AdminPanel
|
||||
setTeams={setTeams}
|
||||
searchParams={searchParams}
|
||||
accessToken={accessToken}
|
||||
showSSOBanner={showSSOBanner}
|
||||
premiumUser={premiumUser}
|
||||
/>
|
||||
) : page == "api_ref" ? (
|
||||
<APIRef proxySettings={proxySettings} />
|
||||
) : page == "settings" ? (
|
||||
<Settings
|
||||
userID={userID}
|
||||
userRole={userRole}
|
||||
accessToken={accessToken}
|
||||
premiumUser={premiumUser}
|
||||
/>
|
||||
) : page == "budgets" ? (
|
||||
<BudgetPanel accessToken={accessToken} />
|
||||
) : page == "general-settings" ? (
|
||||
<GeneralSettings
|
||||
userID={userID}
|
||||
userRole={userRole}
|
||||
accessToken={accessToken}
|
||||
modelData={modelData}
|
||||
/>
|
||||
) : page == "model-hub" ? (
|
||||
<ModelHub
|
||||
accessToken={accessToken}
|
||||
publicPage={false}
|
||||
premiumUser={premiumUser}
|
||||
/>
|
||||
) : page == "caching" ? (
|
||||
<CacheDashboard
|
||||
userID={userID}
|
||||
userRole={userRole}
|
||||
token={token}
|
||||
accessToken={accessToken}
|
||||
premiumUser={premiumUser}
|
||||
/>
|
||||
) : page == "pass-through-settings" ? (
|
||||
<PassThroughSettings
|
||||
userID={userID}
|
||||
userRole={userRole}
|
||||
accessToken={accessToken}
|
||||
modelData={modelData}
|
||||
/>
|
||||
) : (
|
||||
<Usage
|
||||
userID={userID}
|
||||
userRole={userRole}
|
||||
token={token}
|
||||
accessToken={accessToken}
|
||||
keys={keys}
|
||||
premiumUser={premiumUser}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
)}
|
||||
</Suspense>
|
||||
);
|
||||
};
|
||||
|
|
|
|||
|
|
@ -53,11 +53,9 @@ const Createuser: React.FC<CreateuserProps> = ({
|
|||
useState<InvitationLink | null>(null);
|
||||
const router = useRouter();
|
||||
const isLocal = process.env.NODE_ENV === "development";
|
||||
if (isLocal != true) {
|
||||
console.log = function() {};
|
||||
}
|
||||
|
||||
const [baseUrl, setBaseUrl] = useState(
|
||||
isLocal ? "http://localhost:4000" : ""
|
||||
isLocal ? "http://localhost:4000" : "",
|
||||
);
|
||||
// get all models
|
||||
useEffect(() => {
|
||||
|
|
@ -67,7 +65,7 @@ const Createuser: React.FC<CreateuserProps> = ({
|
|||
const modelDataResponse = await modelAvailableCall(
|
||||
accessToken,
|
||||
userID,
|
||||
userRole
|
||||
userRole,
|
||||
);
|
||||
// Assuming modelDataResponse.data contains an array of model objects with a 'model_name' property
|
||||
const availableModels = [];
|
||||
|
|
@ -81,27 +79,26 @@ const Createuser: React.FC<CreateuserProps> = ({
|
|||
// Assuming modelDataResponse.data contains an array of model names
|
||||
setUserModels(availableModels);
|
||||
|
||||
// get ui settings
|
||||
// get ui settings
|
||||
const uiSettingsResponse = await getProxyUISettings(accessToken);
|
||||
console.log("uiSettingsResponse:", uiSettingsResponse);
|
||||
|
||||
|
||||
setUISettings(uiSettingsResponse);
|
||||
} catch (error) {
|
||||
console.error("Error fetching model data:", error);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
fetchData(); // Call the function to fetch model data when the component mounts
|
||||
}, []); // Empty dependency array to run only once
|
||||
|
||||
useEffect(() => {
|
||||
if (router) {
|
||||
const { protocol, host } = window.location;
|
||||
const baseUrl = `${protocol}/${host}`;
|
||||
setBaseUrl(baseUrl);
|
||||
if (!router) {
|
||||
return;
|
||||
}
|
||||
|
||||
const base = new URL("/", window.location.href);
|
||||
setBaseUrl(base.toString());
|
||||
}, [router]);
|
||||
const handleOk = () => {
|
||||
setIsModalVisible(false);
|
||||
|
|
@ -123,7 +120,7 @@ const Createuser: React.FC<CreateuserProps> = ({
|
|||
console.log("user create Response:", response);
|
||||
setApiuser(response["key"]);
|
||||
const user_id = response.data?.user_id || response.user_id;
|
||||
|
||||
|
||||
// only do invite link flow if sso is not enabled
|
||||
if (!uiSettings?.SSO_ENABLED) {
|
||||
invitationCreateCall(accessToken, user_id).then((data) => {
|
||||
|
|
@ -132,7 +129,7 @@ const Createuser: React.FC<CreateuserProps> = ({
|
|||
setIsInvitationLinkModalVisible(true);
|
||||
});
|
||||
} else {
|
||||
// create an InvitationLink Object for this user for the SSO flow
|
||||
// create an InvitationLink Object for this user for the SSO flow
|
||||
// for SSO the invite link is the proxy base url since the User just needs to login
|
||||
const invitationLink: InvitationLink = {
|
||||
id: crypto.randomUUID(), // Generate a unique ID
|
||||
|
|
@ -198,7 +195,7 @@ const Createuser: React.FC<CreateuserProps> = ({
|
|||
</p>
|
||||
</div>
|
||||
</SelectItem>
|
||||
)
|
||||
),
|
||||
)}
|
||||
</Select2>
|
||||
</Form.Item>
|
||||
|
|
|
|||
|
|
@ -1,16 +1,8 @@
|
|||
import React, { useState, useEffect } from "react";
|
||||
import {
|
||||
Button as Button2,
|
||||
Modal,
|
||||
Form,
|
||||
Input,
|
||||
Select as Select2,
|
||||
InputNumber,
|
||||
message,
|
||||
Typography,
|
||||
} from "antd";
|
||||
import React from "react";
|
||||
import { Modal, message, Typography } from "antd";
|
||||
import { CopyToClipboard } from "react-copy-to-clipboard";
|
||||
import { Text, Button } from "@tremor/react";
|
||||
|
||||
export interface InvitationLink {
|
||||
id: string;
|
||||
user_id: string;
|
||||
|
|
@ -33,12 +25,12 @@ interface OnboardingProps {
|
|||
invitationLinkData: InvitationLink | null;
|
||||
}
|
||||
|
||||
const OnboardingModal: React.FC<OnboardingProps> = ({
|
||||
export default function OnboardingModal({
|
||||
isInvitationLinkModalVisible,
|
||||
setIsInvitationLinkModalVisible,
|
||||
baseUrl,
|
||||
invitationLinkData,
|
||||
}) => {
|
||||
}: OnboardingProps) {
|
||||
const { Title, Paragraph } = Typography;
|
||||
const handleInvitationOk = () => {
|
||||
setIsInvitationLinkModalVisible(false);
|
||||
|
|
@ -50,9 +42,9 @@ const OnboardingModal: React.FC<OnboardingProps> = ({
|
|||
|
||||
const getInvitationUrl = () => {
|
||||
if (invitationLinkData?.has_user_setup_sso) {
|
||||
return `${baseUrl}/ui`;
|
||||
return new URL("/ui", baseUrl).toString();
|
||||
}
|
||||
return `${baseUrl}/ui?invitation_id=${invitationLinkData?.id}`;
|
||||
return new URL(`/ui?invitation_id=${invitationLinkData?.id}`, baseUrl).toString();
|
||||
};
|
||||
|
||||
return (
|
||||
|
|
@ -64,7 +56,6 @@ const OnboardingModal: React.FC<OnboardingProps> = ({
|
|||
onOk={handleInvitationOk}
|
||||
onCancel={handleInvitationCancel}
|
||||
>
|
||||
{/* {JSON.stringify(invitationLinkData)} */}
|
||||
<Paragraph>
|
||||
Copy and send the generated link to onboard this user to the proxy.
|
||||
</Paragraph>
|
||||
|
|
@ -75,11 +66,10 @@ const OnboardingModal: React.FC<OnboardingProps> = ({
|
|||
<div className="flex justify-between pt-5 pb-2">
|
||||
<Text>Invitation Link</Text>
|
||||
<Text>
|
||||
<Text>{getInvitationUrl()}</Text>
|
||||
<Text>{getInvitationUrl()}</Text>
|
||||
</Text>
|
||||
</div>
|
||||
<div className="flex justify-end mt-5">
|
||||
<div></div>
|
||||
<CopyToClipboard
|
||||
text={getInvitationUrl()}
|
||||
onCopy={() => message.success("Copied!")}
|
||||
|
|
@ -89,6 +79,4 @@ const OnboardingModal: React.FC<OnboardingProps> = ({
|
|||
</div>
|
||||
</Modal>
|
||||
);
|
||||
};
|
||||
|
||||
export default OnboardingModal;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue