new notifications (#13813)

This commit is contained in:
tanjiro
2025-08-21 06:32:04 +09:00
committed by GitHub
parent 6f6fd0de0d
commit f7a3af5cde
71 changed files with 462 additions and 442 deletions
+6 -6
View File
@@ -21,7 +21,7 @@ import {
PlusCircleOutlined
} from "@ant-design/icons";
import { parseErrorMessage } from "./shared/errorUtils";
import NotificationManager from "./molecules/notifications_manager";
import NotificationsManager from "./molecules/notifications_manager";
interface SCIMConfigProps {
accessToken: string | null;
@@ -52,7 +52,7 @@ const SCIMConfig: React.FC<SCIMConfigProps> = ({ accessToken, userID, proxySetti
const handleCreateSCIMToken = async (values: any) => {
if (!accessToken || !userID) {
NotificationManager.fromBackend("You need to be logged in to create a SCIM token");
NotificationsManager.fromBackend("You need to be logged in to create a SCIM token");
return;
}
@@ -68,10 +68,10 @@ const SCIMConfig: React.FC<SCIMConfigProps> = ({ accessToken, userID, proxySetti
const response = await keyCreateCall(accessToken, userID, formData);
setTokenData(response);
message.success("SCIM token created successfully");
NotificationsManager.success("SCIM token created successfully");
} catch (error: any) {
console.error("Error creating SCIM token:", error);
NotificationManager.fromBackend("Failed to create SCIM token: " + parseErrorMessage(error));
NotificationsManager.fromBackend("Failed to create SCIM token: " + parseErrorMessage(error));
} finally {
setIsCreatingToken(false);
}
@@ -112,7 +112,7 @@ const SCIMConfig: React.FC<SCIMConfigProps> = ({ accessToken, userID, proxySetti
/>
<CopyToClipboard
text={scimBaseUrl}
onCopy={() => message.success("URL copied to clipboard")}
onCopy={() => NotificationsManager.success("URL copied to clipboard")}
>
<TremorButton variant="primary" className="ml-2 flex items-center">
<CopyOutlined className="h-4 w-4 mr-1" />
@@ -183,7 +183,7 @@ const SCIMConfig: React.FC<SCIMConfigProps> = ({ accessToken, userID, proxySetti
/>
<CopyToClipboard
text={tokenData.key}
onCopy={() => message.success("Token copied to clipboard")}
onCopy={() => NotificationsManager.success("Token copied to clipboard")}
>
<TremorButton variant="primary" className="flex items-center">
<CopyOutlined className="h-4 w-4 mr-1" />
@@ -2,7 +2,7 @@ import React, { useEffect, useState } from "react";
import { Modal, Form, Input, Button as Button2, Select, message } from "antd";
import { Text, TextInput } from "@tremor/react";
import { getSSOSettings, updateSSOSettings } from "./networking";
import NotificationManager from "./molecules/notifications_manager";
import NotificationsManager from "./molecules/notifications_manager";
interface SSOModalsProps {
isAddSSOModalVisible: boolean;
@@ -162,7 +162,7 @@ const SSOModals: React.FC<SSOModalsProps> = ({
// Enhanced form submission handler
const handleFormSubmit = async (formValues: Record<string, any>) => {
if (!accessToken) {
NotificationManager.fromBackend("No access token available");
NotificationsManager.fromBackend("No access token available");
return;
}
@@ -174,14 +174,14 @@ const SSOModals: React.FC<SSOModalsProps> = ({
handleShowInstructions(formValues);
} catch (error) {
console.error("Failed to save SSO settings:", error);
NotificationManager.fromBackend("Failed to save SSO settings");
NotificationsManager.fromBackend("Failed to save SSO settings");
}
};
// Handle clearing SSO settings
const handleClearSSO = async () => {
if (!accessToken) {
NotificationManager.fromBackend("No access token available");
NotificationsManager.fromBackend("No access token available");
return;
}
@@ -214,10 +214,10 @@ const SSOModals: React.FC<SSOModalsProps> = ({
// Close the main SSO modal and trigger refresh
handleAddSSOOk();
message.success("SSO settings cleared successfully");
NotificationsManager.success("SSO settings cleared successfully");
} catch (error) {
console.error("Failed to clear SSO settings:", error);
NotificationManager.fromBackend("Failed to clear SSO settings");
NotificationsManager.fromBackend("Failed to clear SSO settings");
}
};
@@ -4,7 +4,7 @@ import { Typography, Spin, message, Switch, Select, Form } from "antd";
import { getDefaultTeamSettings, updateDefaultTeamSettings, modelAvailableCall } from "./networking";
import BudgetDurationDropdown, { getBudgetDurationLabel } from "./common_components/budget_duration_dropdown";
import { getModelDisplayName } from "./key_team_helpers/fetch_available_models_team_key";
import NotificationManager from "./molecules/notifications_manager";
import NotificationsManager from "./molecules/notifications_manager";
interface TeamSSOSettingsProps {
accessToken: string | null;
@@ -48,7 +48,7 @@ const TeamSSOSettings: React.FC<TeamSSOSettingsProps> = ({ accessToken, userID,
}
} catch (error) {
console.error("Error fetching team SSO settings:", error);
NotificationManager.fromBackend("Failed to fetch team settings");
NotificationsManager.fromBackend("Failed to fetch team settings");
} finally {
setLoading(false);
}
@@ -65,10 +65,10 @@ const TeamSSOSettings: React.FC<TeamSSOSettingsProps> = ({ accessToken, userID,
const updatedSettings = await updateDefaultTeamSettings(accessToken, editedValues);
setSettings({...settings, values: updatedSettings.settings});
setIsEditing(false);
message.success("Default team settings updated successfully");
NotificationsManager.success("Default team settings updated successfully");
} catch (error) {
console.error("Error updating team settings:", error);
NotificationManager.fromBackend("Failed to update team settings");
NotificationsManager.fromBackend("Failed to update team settings");
} finally {
setSaving(false);
}
@@ -3,7 +3,7 @@ import { Typography, Space, Button, Divider, message } from 'antd';
import { WarningOutlined, InfoCircleOutlined, CopyOutlined } from '@ant-design/icons';
import { testConnectionRequest } from "../networking";
import { prepareModelAddRequest } from "./handle_add_model_submit";
import NotificationsManager from '../molecules/notifications_manager';
const { Text } = Typography;
interface ModelConnectionTestProps {
@@ -59,7 +59,7 @@ const ModelConnectionTest: React.FC<ModelConnectionTestProps> = ({
const response = await testConnectionRequest(accessToken, litellmParamsObj, modelInfoObj?.mode);
if (response.status === "success") {
message.success("Connection test successful!");
NotificationsManager.success("Connection test successful!");
setError(null);
setIsSuccess(true);
} else {
@@ -231,7 +231,7 @@ ${formattedBody}
icon={<CopyOutlined />}
onClick={() => {
navigator.clipboard.writeText(curlCommand || '');
message.success('Copied to clipboard');
NotificationsManager.success('Copied to clipboard');
}}
>
Copy to Clipboard
@@ -28,7 +28,7 @@ import { list } from "postcss";
import KeyValueInput from "./key_value_input";
import { passThroughItem } from "./pass_through_settings";
import RoutePreview from "./route_preview";
import NotificationManager from "./molecules/notifications_manager";
import NotificationsManager from "./molecules/notifications_manager";
const { Option } = Select2;
interface AddFallbacksProps {
@@ -81,14 +81,14 @@ const AddPassThroughEndpoint: React.FC<AddFallbacksProps> = ({
const updatedPassThroughSettings = [...passThroughItems, createdEndpoint]
setPassThroughItems(updatedPassThroughSettings)
message.success("Pass-through endpoint created successfully");
NotificationsManager.success("Pass-through endpoint created successfully");
form.resetFields();
setPathValue("");
setTargetValue("");
setIncludeSubpath(true);
setIsModalVisible(false);
} catch (error) {
NotificationManager.fromBackend("Error creating pass-through endpoint: " + error);
NotificationsManager.fromBackend("Error creating pass-through endpoint: " + error);
} finally {
setIsLoading(false);
}
@@ -96,7 +96,7 @@ const AddPassThroughEndpoint: React.FC<AddFallbacksProps> = ({
const copyToClipboard = (text: string) => {
navigator.clipboard.writeText(text);
message.success('Copied to clipboard!');
NotificationsManager.success('Copied to clipboard!');
};
+14 -14
View File
@@ -46,7 +46,7 @@ import { ssoProviderConfigs } from './SSOModals';
import SCIMConfig from "./SCIM";
import UIAccessControlForm from "./UIAccessControlForm";
import UsefulLinksManagement from "./useful_links_management";
import NotificationManager from "./molecules/notifications_manager";
import NotificationsManager from "./molecules/notifications_manager";
interface AdminPanelProps {
searchParams: any;
@@ -151,7 +151,7 @@ const AdminPanel: React.FC<AdminPanelProps> = ({
const handleShowAllowedIPs = async () => {
try {
if (premiumUser !== true) {
NotificationManager.fromBackend(
NotificationsManager.fromBackend(
"This feature is only available for premium users. Please upgrade your account."
)
return
@@ -164,7 +164,7 @@ const AdminPanel: React.FC<AdminPanelProps> = ({
}
} catch (error) {
console.error("Error fetching allowed IPs:", error);
NotificationManager.fromBackend(`Failed to fetch allowed IPs ${error}`);
NotificationsManager.fromBackend(`Failed to fetch allowed IPs ${error}`);
setAllowedIPs([all_ip_address_allowed]);
} finally {
if (premiumUser === true) {
@@ -180,11 +180,11 @@ const AdminPanel: React.FC<AdminPanelProps> = ({
// Fetch the updated list of IPs
const updatedIPs = await getAllowedIPs(accessToken);
setAllowedIPs(updatedIPs);
message.success('IP address added successfully');
NotificationsManager.success('IP address added successfully');
}
} catch (error) {
console.error("Error adding IP:", error);
NotificationManager.fromBackend(`Failed to add IP address ${error}`);
NotificationsManager.fromBackend(`Failed to add IP address ${error}`);
} finally {
setIsAddIPModalVisible(false);
}
@@ -202,10 +202,10 @@ const AdminPanel: React.FC<AdminPanelProps> = ({
// Fetch the updated list of IPs
const updatedIPs = await getAllowedIPs(accessToken);
setAllowedIPs(updatedIPs.length > 0 ? updatedIPs : [all_ip_address_allowed]);
message.success('IP address deleted successfully');
NotificationsManager.success('IP address deleted successfully');
} catch (error) {
console.error("Error deleting IP:", error);
NotificationManager.fromBackend(`Failed to delete IP address ${error}`);
NotificationsManager.fromBackend(`Failed to delete IP address ${error}`);
} finally {
setIsDeleteIPModalVisible(false);
setIPToDelete(null);
@@ -426,7 +426,7 @@ const AdminPanel: React.FC<AdminPanelProps> = ({
const handleMemberUpdate = async (formValues: Record<string, any>) => {
try {
if (accessToken != null && admins != null) {
message.info("Making API Call");
NotificationsManager.info("Making API Call");
const response: any = await userUpdateUserCall(
accessToken,
formValues,
@@ -447,7 +447,7 @@ const AdminPanel: React.FC<AdminPanelProps> = ({
// If new user is found, update it
setAdmins(admins); // Set the new state
}
message.success("Refresh tab to see updated user role");
NotificationsManager.success("Refresh tab to see updated user role");
setIsUpdateModalModalVisible(false);
}
} catch (error) {
@@ -458,7 +458,7 @@ const AdminPanel: React.FC<AdminPanelProps> = ({
const handleMemberCreate = async (formValues: Record<string, any>) => {
try {
if (accessToken != null && admins != null) {
message.info("Making API Call");
NotificationsManager.info("Making API Call");
const response: any = await userUpdateUserCall(
accessToken,
formValues,
@@ -497,7 +497,7 @@ const AdminPanel: React.FC<AdminPanelProps> = ({
const handleAdminCreate = async (formValues: Record<string, any>) => {
try {
if (accessToken != null && admins != null) {
message.info("Making API Call");
NotificationsManager.info("Making API Call");
const user_role: Member = {
role: "user",
user_email: formValues.user_email,
@@ -565,7 +565,7 @@ const AdminPanel: React.FC<AdminPanelProps> = ({
<div>
<Button
style={{ width: '150px' }}
onClick={() => premiumUser === true ? setIsAddSSOModalVisible(true) : NotificationManager.fromBackend("Only premium users can add SSO")}
onClick={() => premiumUser === true ? setIsAddSSOModalVisible(true) : NotificationsManager.fromBackend("Only premium users can add SSO")}
>
{ssoConfigured ? "Edit SSO Settings" : "Add SSO"}
</Button>
@@ -581,7 +581,7 @@ const AdminPanel: React.FC<AdminPanelProps> = ({
<div>
<Button
style={{ width: '150px' }}
onClick={() => premiumUser === true ? setIsUIAccessControlModalVisible(true) : NotificationManager.fromBackend("Only premium users can configure UI access control")}
onClick={() => premiumUser === true ? setIsUIAccessControlModalVisible(true) : NotificationsManager.fromBackend("Only premium users can configure UI access control")}
>
UI Access Control
</Button>
@@ -691,7 +691,7 @@ const AdminPanel: React.FC<AdminPanelProps> = ({
accessToken={accessToken}
onSuccess={() => {
handleUIAccessControlOk();
message.success("UI Access Control settings updated successfully");
NotificationsManager.success("UI Access Control settings updated successfully");
}}
/>
</Modal>
@@ -18,6 +18,7 @@ import { InputNumber, message } from "antd";
import { alertingSettingsCall, updateConfigFieldSetting } from "../networking";
import { TrashIcon, CheckCircleIcon } from "@heroicons/react/outline";
import DynamicForm from "./dynamic_form";
import NotificationsManager from "../molecules/notifications_manager";
interface alertingSettingsItem {
field_name: string;
field_type: string;
@@ -96,7 +97,7 @@ const AlertingSettings: React.FC<AlertingSettingsProps> = ({
}
}
// update value in state
message.success("Wait 10s for proxy to update.");
NotificationsManager.success("Wait 10s for proxy to update.");
} catch (error) {
// do something
}
@@ -18,7 +18,7 @@ import {
message,
} from "antd";
import { budgetCreateCall } from "../networking";
import NotificationManager from "../molecules/notifications_manager";
import NotificationsManager from "../molecules/notifications_manager";
interface BudgetModalProps {
isModalVisible: boolean;
@@ -48,18 +48,18 @@ const BudgetModal: React.FC<BudgetModalProps> = ({
return;
}
try {
message.info("Making API Call");
NotificationsManager.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("Budget Created");
NotificationsManager.success("Budget Created");
form.resetFields();
} catch (error) {
console.error("Error creating the key:", error);
NotificationManager.fromBackend(`Error creating the key: ${error}`);
NotificationsManager.fromBackend(`Error creating the key: ${error}`);
}
};
@@ -39,7 +39,8 @@ import {
} from "@heroicons/react/outline";
import { Prism as SyntaxHighlighter } from "react-syntax-highlighter";
import { getBudgetList, budgetDeleteCall } from "../networking";
import { message } from "antd";
import NotificationsManager from "../molecules/notifications_manager";
interface BudgetSettingsPageProps {
accessToken: string | null;
}
@@ -84,7 +85,7 @@ const BudgetPanel: React.FC<BudgetSettingsPageProps> = ({ accessToken }) => {
return;
}
message.info("Request made");
NotificationsManager.info("Request made");
await budgetDeleteCall(accessToken, budget_id);
@@ -92,7 +93,7 @@ const BudgetPanel: React.FC<BudgetSettingsPageProps> = ({ accessToken }) => {
newBudgetList.splice(index, 1);
setBudgetList(newBudgetList);
message.success("Budget Deleted.");
NotificationsManager.success("Budget Deleted.");
};
const handleUpdateCall = async () => {
@@ -19,7 +19,7 @@ import {
} from "antd";
import { budgetUpdateCall } from "../networking";
import { budgetItem } from "./budget_panel";
import NotificationManager from "../molecules/notifications_manager";
import NotificationsManager from "../molecules/notifications_manager";
interface BudgetModalProps {
isModalVisible: boolean;
@@ -59,18 +59,18 @@ const EditBudgetModal: React.FC<BudgetModalProps> = ({
return;
}
try {
message.info("Making API Call");
NotificationsManager.info("Making API Call");
setIsModalVisible(true);
const response = await budgetUpdateCall(accessToken, formValues);
setBudgetList((prevData) =>
prevData ? [...prevData, response] : [response]
); // Check if prevData is null
message.success("Budget Updated");
NotificationsManager.success("Budget Updated");
form.resetFields();
handleUpdateCall();
} catch (error) {
console.error("Error creating the key:", error);
NotificationManager.fromBackend(`Error creating the key: ${error}`);
NotificationsManager.fromBackend(`Error creating the key: ${error}`);
}
};
@@ -14,7 +14,7 @@ import Papa from "papaparse"
import { CheckCircleIcon, XCircleIcon, ExclamationIcon } from "@heroicons/react/outline"
import { CopyToClipboard } from "react-copy-to-clipboard"
import { InvitationLink } from "./onboarding_link"
import NotificationManager from "./molecules/notifications_manager"
import NotificationsManager from "./molecules/notifications_manager"
interface BulkCreateUsersProps {
accessToken: string
@@ -111,7 +111,7 @@ const BulkCreateUsersButton: React.FC<BulkCreateUsersProps> = ({
// Check file type
if (file.type !== "text/csv" && !file.name.endsWith(".csv")) {
setFileError(`Invalid file type: ${file.name}. Please upload a CSV file (.csv extension).`)
NotificationManager.fromBackend("Invalid file type. Please upload a CSV file.")
NotificationsManager.fromBackend("Invalid file type. Please upload a CSV file.")
return false
}
@@ -265,7 +265,7 @@ const BulkCreateUsersButton: React.FC<BulkCreateUsersProps> = ({
`Found ${userData.length - validData.length} row(s) with errors out of ${userData.length} total rows. Please correct them before proceeding.`,
)
} else {
message.success(`Successfully parsed ${validData.length} users`)
NotificationsManager.success(`Successfully parsed ${validData.length} users`)
}
} catch (error: unknown) {
const errorMessage = error instanceof Error ? error.message : "Unknown error"
@@ -514,7 +514,7 @@ const BulkCreateUsersButton: React.FC<BulkCreateUsersProps> = ({
<span className="text-xs text-gray-500 truncate max-w-[150px]">{record.invitation_link}</span>
<CopyToClipboard
text={record.invitation_link}
onCopy={() => message.success("Invitation link copied!")}
onCopy={() => NotificationsManager.success("Invitation link copied!")}
>
<button className="ml-1 text-blue-500 text-xs hover:text-blue-700">Copy</button>
</CopyToClipboard>
@@ -16,7 +16,7 @@ import {
import { Button } from '@tremor/react';
import { userBulkUpdateUserCall, teamBulkMemberAddCall, Member } from "./networking";
import { UserEditView } from "./user_edit_view";
import NotificationManager from "./molecules/notifications_manager";
import NotificationsManager from "./molecules/notifications_manager";
const { Text, Title } = Typography;
@@ -81,7 +81,7 @@ const BulkEditUserModal: React.FC<BulkEditUserModalProps> = ({
const handleSubmit = async (formValues: any) => {
console.log("formValues", formValues);
if (!accessToken) {
NotificationManager.fromBackend("Access token not found");
NotificationsManager.fromBackend("Access token not found");
return;
}
@@ -117,7 +117,7 @@ const BulkEditUserModal: React.FC<BulkEditUserModalProps> = ({
const hasTeamAdditions = addToTeams && selectedTeams.length > 0;
if (!hasUserUpdates && !hasTeamAdditions) {
NotificationManager.fromBackend("Please modify at least one field or select teams to add users to");
NotificationsManager.fromBackend("Please modify at least one field or select teams to add users to");
return;
}
@@ -193,7 +193,7 @@ const BulkEditUserModal: React.FC<BulkEditUserModalProps> = ({
}
if (successMessages.length > 0) {
message.success(successMessages.join('. '));
NotificationsManager.success(successMessages.join('. '));
}
// Reset team management state
@@ -206,7 +206,7 @@ const BulkEditUserModal: React.FC<BulkEditUserModalProps> = ({
onCancel();
} catch (error) {
console.error("Bulk operation failed:", error);
NotificationManager.fromBackend("Failed to perform bulk operations");
NotificationsManager.fromBackend("Failed to perform bulk operations");
} finally {
setLoading(false);
}
@@ -23,6 +23,7 @@ import {
Text,
} from "@tremor/react";
import UsageDatePicker from "./shared/usage_date_picker";
import NotificationsManager from "./molecules/notifications_manager";
import {
Button as Button2,
@@ -265,7 +266,7 @@ const handleRefreshClick = () => {
const runCachingHealthCheck = async () => {
try {
message.info("Running cache health check...");
NotificationsManager.info("Running cache health check...");
setHealthCheckResponse("");
const response = await cachingHealthCheckCall(accessToken !== null ? accessToken : "");
console.log("CACHING HEALTH CHECK RESPONSE", response);
@@ -72,7 +72,7 @@ import {
FilePdfOutlined,
ArrowUpOutlined
} from "@ant-design/icons";
import NotificationManager from "./molecules/notifications_manager";
import NotificationsManager from "./molecules/notifications_manager";
const { TextArea } = Input;
const { Dragger } = Upload;
@@ -463,7 +463,7 @@ const ChatUI: React.FC<ChatUIProps> = ({
abortControllerRef.current.abort();
abortControllerRef.current = null;
setIsLoading(false);
message.info("Request cancelled");
NotificationsManager.info("Request cancelled");
}
};
@@ -517,7 +517,7 @@ const ChatUI: React.FC<ChatUIProps> = ({
// For image edits, require both image and prompt
if (endpointType === EndpointType.IMAGE_EDITS && !uploadedImage) {
NotificationManager.fromBackend("Please upload an image for editing");
NotificationsManager.fromBackend("Please upload an image for editing");
return;
}
@@ -528,7 +528,7 @@ const ChatUI: React.FC<ChatUIProps> = ({
const effectiveApiKey = apiKeySource === 'session' ? accessToken : apiKey;
if (!effectiveApiKey) {
NotificationManager.fromBackend("Please provide an API key or select Current UI Session");
NotificationsManager.fromBackend("Please provide an API key or select Current UI Session");
return;
}
@@ -544,7 +544,7 @@ const ChatUI: React.FC<ChatUIProps> = ({
try {
newUserMessage = await createMultimodalMessage(inputMessage, responsesUploadedImage);
} catch (error) {
NotificationManager.fromBackend("Failed to process image. Please try again.");
NotificationsManager.fromBackend("Failed to process image. Please try again.");
return;
}
}
@@ -553,7 +553,7 @@ const ChatUI: React.FC<ChatUIProps> = ({
try {
newUserMessage = await createChatMultimodalMessage(inputMessage, chatUploadedImage);
} catch (error) {
NotificationManager.fromBackend("Failed to process image. Please try again.");
NotificationsManager.fromBackend("Failed to process image. Please try again.");
return;
}
} else {
@@ -714,7 +714,7 @@ const ChatUI: React.FC<ChatUIProps> = ({
sessionStorage.removeItem('chatHistory');
sessionStorage.removeItem('messageTraceId');
sessionStorage.removeItem('responsesSessionId');
message.success("Chat history cleared.");
NotificationsManager.success("Chat history cleared.");
};
if (userRole && userRole === "Admin Viewer") {
@@ -1273,7 +1273,7 @@ const ChatUI: React.FC<ChatUIProps> = ({
<Button
onClick={() => {
navigator.clipboard.writeText(generatedCode);
message.success("Copied to clipboard!");
NotificationsManager.success("Copied to clipboard!");
}}
>
Copy to Clipboard
@@ -1300,7 +1300,7 @@ const ChatUI: React.FC<ChatUIProps> = ({
onCancel={() => setIsMCPToolsModalVisible(false)}
onOk={() => {
setIsMCPToolsModalVisible(false);
message.success('MCP tool selection updated');
NotificationsManager.success('MCP tool selection updated');
}}
width={800}
>
@@ -23,7 +23,7 @@ const SessionManagement: React.FC<SessionManagementProps> = ({
const handleCopySessionId = () => {
if (responsesSessionId) {
navigator.clipboard.writeText(responsesSessionId);
message.success("Response ID copied to clipboard!");
NotificationsManager.success("Response ID copied to clipboard!");
}
};
@@ -8,7 +8,7 @@ import {
TextInput,
} from "@tremor/react";
import { Modal, Form, Input, message, Spin, Select } from "antd";
import NotificationManager from "./molecules/notifications_manager";
import NotificationsManager from "./molecules/notifications_manager";
interface CloudZeroExportModalProps {
isOpen: boolean;
@@ -69,11 +69,11 @@ const CloudZeroExportModal: React.FC<CloudZeroExportModalProps> = ({
} else if (response.status !== 404) {
// 404 means no settings configured yet, which is fine
const errorData = await response.json();
NotificationManager.fromBackend(`Failed to load existing settings: ${errorData.error || 'Unknown error'}`);
NotificationsManager.fromBackend(`Failed to load existing settings: ${errorData.error || 'Unknown error'}`);
}
} catch (error) {
console.error("Error loading CloudZero settings:", error);
NotificationManager.fromBackend("Failed to load existing settings");
NotificationsManager.fromBackend("Failed to load existing settings");
} finally {
setSettingsLoading(false);
}
@@ -81,7 +81,7 @@ const CloudZeroExportModal: React.FC<CloudZeroExportModalProps> = ({
const handleSaveCloudZeroSettings = async (values: CloudZeroSettings) => {
if (!accessToken) {
NotificationManager.fromBackend("No access token available");
NotificationsManager.fromBackend("No access token available");
return;
}
@@ -108,7 +108,7 @@ const CloudZeroExportModal: React.FC<CloudZeroExportModalProps> = ({
const data = await response.json();
if (response.ok) {
message.success(data.message || "CloudZero settings saved successfully");
NotificationsManager.success(data.message || "CloudZero settings saved successfully");
setExistingSettings({
api_key_masked: values.api_key.substring(0, 4) + "****" + values.api_key.slice(-4),
connection_id: values.connection_id,
@@ -116,12 +116,12 @@ const CloudZeroExportModal: React.FC<CloudZeroExportModalProps> = ({
});
return true;
} else {
NotificationManager.fromBackend(data.error || "Failed to save CloudZero settings");
NotificationsManager.fromBackend(data.error || "Failed to save CloudZero settings");
return false;
}
} catch (error) {
console.error("Error saving CloudZero settings:", error);
NotificationManager.fromBackend("Failed to save CloudZero settings");
NotificationsManager.fromBackend("Failed to save CloudZero settings");
return false;
} finally {
setLoading(false);
@@ -130,7 +130,7 @@ const CloudZeroExportModal: React.FC<CloudZeroExportModalProps> = ({
const handleExportCloudZero = async () => {
if (!accessToken) {
NotificationManager.fromBackend("No access token available");
NotificationsManager.fromBackend("No access token available");
return;
}
@@ -151,14 +151,14 @@ const CloudZeroExportModal: React.FC<CloudZeroExportModalProps> = ({
const data = await response.json();
if (response.ok) {
message.success(data.message || "Export to CloudZero completed successfully");
NotificationsManager.success(data.message || "Export to CloudZero completed successfully");
onClose();
} else {
NotificationManager.fromBackend(data.error || "Failed to export to CloudZero");
NotificationsManager.fromBackend(data.error || "Failed to export to CloudZero");
}
} catch (error) {
console.error("Error exporting to CloudZero:", error);
NotificationManager.fromBackend("Failed to export to CloudZero");
NotificationsManager.fromBackend("Failed to export to CloudZero");
} finally {
setExportLoading(false);
}
@@ -168,11 +168,11 @@ const CloudZeroExportModal: React.FC<CloudZeroExportModalProps> = ({
setExportLoading(true);
try {
// TODO: Implement CSV export functionality
message.info("CSV export functionality coming soon!");
NotificationsManager.info("CSV export functionality coming soon!");
onClose();
} catch (error) {
console.error("Error exporting CSV:", error);
NotificationManager.fromBackend("Failed to export CSV");
NotificationsManager.fromBackend("Failed to export CSV");
} finally {
setExportLoading(false);
}
@@ -13,7 +13,7 @@ import {
TableCell
} from "@tremor/react";
import ModelSelector from "./ModelSelector";
import NotificationManager from "../molecules/notifications_manager";
import NotificationsManager from "../molecules/notifications_manager";
interface ModelAliasManagerProps {
accessToken: string;
@@ -50,13 +50,13 @@ const ModelAliasManager: React.FC<ModelAliasManagerProps> = ({
const handleAddAlias = () => {
if (!newAlias.aliasName || !newAlias.targetModel) {
NotificationManager.fromBackend("Please provide both alias name and target model");
NotificationsManager.fromBackend("Please provide both alias name and target model");
return;
}
// Check for duplicate alias names
if (aliases.some(alias => alias.aliasName === newAlias.aliasName)) {
NotificationManager.fromBackend("An alias with this name already exists");
NotificationsManager.fromBackend("An alias with this name already exists");
return;
}
@@ -80,7 +80,7 @@ const ModelAliasManager: React.FC<ModelAliasManagerProps> = ({
onAliasUpdate(aliasObject);
}
message.success("Alias added successfully");
NotificationsManager.success("Alias added successfully");
};
const handleEditAlias = (alias: AliasItem) => {
@@ -91,13 +91,13 @@ const ModelAliasManager: React.FC<ModelAliasManagerProps> = ({
if (!editingAlias) return;
if (!editingAlias.aliasName || !editingAlias.targetModel) {
NotificationManager.fromBackend("Please provide both alias name and target model");
NotificationsManager.fromBackend("Please provide both alias name and target model");
return;
}
// Check for duplicate alias names (excluding current alias)
if (aliases.some(alias => alias.id !== editingAlias.id && alias.aliasName === editingAlias.aliasName)) {
NotificationManager.fromBackend("An alias with this name already exists");
NotificationsManager.fromBackend("An alias with this name already exists");
return;
}
@@ -118,7 +118,7 @@ const ModelAliasManager: React.FC<ModelAliasManagerProps> = ({
onAliasUpdate(aliasObject);
}
message.success("Alias updated successfully");
NotificationsManager.success("Alias updated successfully");
};
const handleCancelEdit = () => {
@@ -139,7 +139,7 @@ const ModelAliasManager: React.FC<ModelAliasManagerProps> = ({
onAliasUpdate(aliasObject);
}
message.success("Alias deleted successfully");
NotificationsManager.success("Alias deleted successfully");
};
// Convert current aliases to object for config example
@@ -26,7 +26,7 @@ import { Tooltip } from "antd"
import { InfoCircleOutlined } from "@ant-design/icons"
import { getModelDisplayName } from "./key_team_helpers/fetch_available_models_team_key"
import { useQueryClient } from "@tanstack/react-query"
import NotificationManager from "./molecules/notifications_manager"
import NotificationsManager from "./molecules/notifications_manager"
// Helper function to generate UUID compatible across all environments
const generateUUID = (): string => {
@@ -121,7 +121,7 @@ const Createuser: React.FC<CreateuserProps> = ({
const handleCreate = async (formValues: { user_id: string; models?: string[]; user_role: string }) => {
try {
message.info("Making API Call")
NotificationsManager.info("Making API Call")
if (!isEmbedded) {
setIsModalVisible(true)
}
@@ -170,12 +170,12 @@ const Createuser: React.FC<CreateuserProps> = ({
setIsInvitationLinkModalVisible(true)
}
message.success("API user Created")
NotificationsManager.success("API user Created")
form.resetFields()
localStorage.removeItem("userData" + userID)
} catch (error: any) {
const errorMessage = error.response?.data?.detail || error?.message || "Error creating the user"
NotificationManager.fromBackend(errorMessage)
NotificationsManager.fromBackend(errorMessage)
console.error("Error creating the user:", error)
}
}
@@ -9,7 +9,7 @@ import {
} from "antd";
import { modelDeleteCall } from "./networking";
import { TrashIcon } from "@heroicons/react/outline";
import NotificationsManager from "./molecules/notifications_manager";
interface DeleteModelProps {
modelID: string;
accessToken: string;
@@ -25,12 +25,12 @@ const DeleteModelButton: React.FC<DeleteModelProps> = ({
const handleDelete = async () => {
try {
message.info("Making API Call");
NotificationsManager.info("Making API Call");
setIsModalVisible(true);
const response = await modelDeleteCall(accessToken, modelID);
console.log("model delete Response:", response);
message.success(`Model ${modelID} deleted successfully`);
NotificationsManager.success(`Model ${modelID} deleted successfully`);
setIsModalVisible(false);
callback && setTimeout(callback, 4000) //added timeout of 4 seconds as deleted model is taking time to reflect in get models
} catch (error) {
@@ -4,7 +4,7 @@ import { Text, TextInput } from "@tremor/react";
import { modelAvailableCall, modelPatchUpdateCall } from "../networking";
import { fetchAvailableModels, ModelGroup } from "../chat_ui/llm_calls/fetch_models";
import RouterConfigBuilder from "../add_model/router_config_builder";
import NotificationManager from "../molecules/notifications_manager";
import NotificationsManager from "../molecules/notifications_manager";
interface EditAutoRouterModalProps {
isVisible: boolean;
@@ -93,7 +93,7 @@ const EditAutoRouterModal: React.FC<EditAutoRouterModalProps> = ({
} catch (error) {
console.error("Error parsing auto router config:", error);
NotificationManager.fromBackend("Error loading auto router configuration");
NotificationsManager.fromBackend("Error loading auto router configuration");
}
};
@@ -131,12 +131,12 @@ const EditAutoRouterModal: React.FC<EditAutoRouterModalProps> = ({
model_info: updatedModelInfo,
};
message.success("Auto router configuration updated successfully");
NotificationsManager.success("Auto router configuration updated successfully");
onSuccess(updatedModelData);
onCancel();
} catch (error) {
console.error("Error updating auto router:", error);
NotificationManager.fromBackend("Failed to update auto router configuration");
NotificationsManager.fromBackend("Failed to update auto router configuration");
} finally {
setLoading(false);
}
@@ -3,7 +3,7 @@ import { Modal, Form, InputNumber, message } from "antd";
import { TextInput } from "@tremor/react";
import { Button as Button2 } from "antd";
import { modelUpdateCall } from "../networking";
import NotificationsManager from "../molecules/notifications_manager";
interface EditModelModalProps {
visible: boolean;
onCancel: () => void;
@@ -55,7 +55,7 @@ export const handleEditModelSubmit = async (formValues: Record<string, any>, acc
try {
let newModelValue = await modelUpdateCall(accessToken, payload);
message.success(
NotificationsManager.success(
"Model updated successfully, restart server to see updates"
);
@@ -63,7 +63,7 @@ import {
import AddFallbacks from "./add_fallbacks";
import openai from "openai";
import Paragraph from "antd/es/skeleton/Paragraph";
import NotificationManager from "./molecules/notifications_manager";
import NotificationsManager from "./molecules/notifications_manager";
interface GeneralSettingsPageProps {
accessToken: string | null;
userRole: string | null;
@@ -103,7 +103,7 @@ async function testFallbackModelResponse(
mock_testing_fallbacks: true,
});
message.success(
NotificationsManager.success(
<span>
Test model=<strong>{selectedModel}</strong>, received model=
<strong>{response.model}</strong>. See{" "}
@@ -122,7 +122,7 @@ async function testFallbackModelResponse(
</span>
);
} catch (error) {
NotificationManager.fromBackend(
NotificationsManager.fromBackend(
`Error occurred while generating model response. Please try again. Error: ${error}`,
);
}
@@ -309,9 +309,9 @@ const GeneralSettings: React.FC<GeneralSettingsPageProps> = ({
try {
await setCallbacksCall(accessToken, payload);
setRouterSettings(updatedSettings);
message.success("Router settings updated successfully");
NotificationsManager.success("Router settings updated successfully");
} catch (error) {
NotificationManager.fromBackend("Failed to update router settings: " + error);
NotificationsManager.fromBackend("Failed to update router settings: " + error);
}
};
@@ -432,10 +432,10 @@ const GeneralSettings: React.FC<GeneralSettingsPageProps> = ({
try {
setCallbacksCall(accessToken, payload);
} catch (error) {
NotificationManager.fromBackend("Failed to update router settings: " + error);
NotificationsManager.fromBackend("Failed to update router settings: " + error);
}
message.success("router settings updated successfully");
NotificationsManager.success("router settings updated successfully");
};
if (!accessToken) {
@@ -7,7 +7,7 @@ import AddGuardrailForm from "./guardrails/add_guardrail_form"
import GuardrailTable from "./guardrails/guardrail_table"
import { isAdminRole } from "@/utils/roles"
import GuardrailInfoView from "./guardrails/guardrail_info"
import NotificationManager from "./molecules/notifications_manager";
import NotificationsManager from "./molecules/notifications_manager";
interface GuardrailsPanelProps {
accessToken: string | null
@@ -88,11 +88,11 @@ const GuardrailsPanel: React.FC<GuardrailsPanelProps> = ({ accessToken, userRole
setIsDeleting(true)
try {
await deleteGuardrailCall(accessToken, guardrailToDelete.id)
message.success(`Guardrail "${guardrailToDelete.name}" deleted successfully`)
NotificationsManager.success(`Guardrail "${guardrailToDelete.name}" deleted successfully`)
fetchGuardrails() // Refresh the list
} catch (error) {
console.error("Error deleting guardrail:", error)
NotificationManager.fromBackend("Failed to delete guardrail")
NotificationsManager.fromBackend("Failed to delete guardrail")
} finally {
setIsDeleting(false)
setGuardrailToDelete(null)
@@ -7,7 +7,7 @@ import { createGuardrailCall, getGuardrailUISettings, getGuardrailProviderSpecif
import PiiConfiguration from './pii_configuration';
import GuardrailProviderFields from './guardrail_provider_fields';
import GuardrailOptionalParams from './guardrail_optional_params';
import NotificationManager from '../molecules/notifications_manager';
import NotificationsManager from '../molecules/notifications_manager';
const { Title, Text, Link } = Typography;
const { Option } = Select;
@@ -104,7 +104,7 @@ const AddGuardrailForm: React.FC<AddGuardrailFormProps> = ({
populateGuardrailProviderMap(providerParamsResp);
} catch (error) {
console.error('Error fetching guardrail data:', error);
NotificationManager.fromBackend('Failed to load guardrail configuration');
NotificationsManager.fromBackend('Failed to load guardrail configuration');
}
};
@@ -187,7 +187,7 @@ const AddGuardrailForm: React.FC<AddGuardrailFormProps> = ({
// Validate configuration steps
if (currentStep === 1) {
if (shouldRenderPIIConfigSettings(selectedProvider) && selectedEntities.length === 0) {
NotificationManager.fromBackend('Please select at least one PII entity to continue');
NotificationsManager.fromBackend('Please select at least one PII entity to continue');
return;
}
}
@@ -275,7 +275,7 @@ const AddGuardrailForm: React.FC<AddGuardrailFormProps> = ({
// For some guardrails, the config values need to be in litellm_params
guardrailData.guardrail_info = configObj;
} catch (error) {
NotificationManager.fromBackend('Invalid JSON in configuration');
NotificationsManager.fromBackend('Invalid JSON in configuration');
setLoading(false);
return;
}
@@ -338,7 +338,7 @@ const AddGuardrailForm: React.FC<AddGuardrailFormProps> = ({
console.log("Sending guardrail data:", JSON.stringify(guardrailData));
await createGuardrailCall(accessToken, guardrailData);
message.success('Guardrail created successfully');
NotificationsManager.success('Guardrail created successfully');
// Reset form and close modal
resetForm();
@@ -346,7 +346,7 @@ const AddGuardrailForm: React.FC<AddGuardrailFormProps> = ({
onClose();
} catch (error) {
console.error("Failed to create guardrail:", error);
NotificationManager.fromBackend('Failed to create guardrail: ' + (error instanceof Error ? error.message : String(error)));
NotificationsManager.fromBackend('Failed to create guardrail: ' + (error instanceof Error ? error.message : String(error)));
} finally {
setLoading(false);
}
@@ -2,6 +2,7 @@ import React, { useState } from 'react';
import { Button, Space, Card, message } from 'antd';
import AzureTextModerationConfiguration from './azure_text_moderation_configuration';
import { AZURE_TEXT_MODERATION_CATEGORIES } from './azure_text_moderation_types';
import NotificationsManager from '../molecules/notifications_manager';
/**
* Example component showing how to use the AzureTextModerationConfiguration
@@ -42,14 +43,14 @@ const AzureTextModerationExample: React.FC = () => {
};
console.log('Azure Text Moderation Configuration:', config);
message.success('Configuration saved successfully!');
NotificationsManager.success('Configuration saved successfully!');
};
const handleReset = () => {
setSelectedCategories(['Hate', 'Violence']);
setGlobalSeverityThreshold(2);
setCategorySpecificThresholds({ 'Hate': 4 });
message.info('Configuration reset to defaults');
NotificationsManager.info('Configuration reset to defaults');
};
return (
@@ -4,7 +4,7 @@ import { Button, TextInput } from '@tremor/react';
import { GuardrailProviders, guardrail_provider_map, guardrailLogoMap, getGuardrailProviders } from './guardrail_info_helpers';
import { getGuardrailUISettings } from '../networking';
import PiiConfiguration from './pii_configuration';
import NotificationManager from '../molecules/notifications_manager';
import NotificationsManager from '../molecules/notifications_manager';
const { Title, Text } = Typography;
const { Option } = Select;
@@ -60,7 +60,7 @@ const EditGuardrailForm: React.FC<EditGuardrailFormProps> = ({
setGuardrailSettings(data);
} catch (error) {
console.error('Error fetching guardrail settings:', error);
NotificationManager.fromBackend('Failed to load guardrail settings');
NotificationsManager.fromBackend('Failed to load guardrail settings');
}
};
@@ -166,7 +166,7 @@ const EditGuardrailForm: React.FC<EditGuardrailFormProps> = ({
guardrailData.guardrail.guardrail_info = configObj;
}
} catch (error) {
NotificationManager.fromBackend('Invalid JSON in configuration');
NotificationsManager.fromBackend('Invalid JSON in configuration');
setLoading(false);
return;
}
@@ -194,14 +194,14 @@ const EditGuardrailForm: React.FC<EditGuardrailFormProps> = ({
throw new Error(errorData || "Failed to update guardrail");
}
message.success('Guardrail updated successfully');
NotificationsManager.success('Guardrail updated successfully');
// Reset and close
onSuccess();
onClose();
} catch (error) {
console.error("Failed to update guardrail:", error);
NotificationManager.fromBackend('Failed to update guardrail: ' + (error instanceof Error ? error.message : String(error)));
NotificationsManager.fromBackend('Failed to update guardrail: ' + (error instanceof Error ? error.message : String(error)));
} finally {
setLoading(false);
}
@@ -28,7 +28,7 @@ import GuardrailOptionalParams from "./guardrail_optional_params"
import { ArrowLeftIcon } from "@heroicons/react/outline"
import { copyToClipboard as utilCopyToClipboard } from "@/utils/dataUtils"
import { CheckIcon, CopyIcon } from "lucide-react"
import NotificationManager from "../molecules/notifications_manager"
import NotificationsManager from "../molecules/notifications_manager"
export interface GuardrailInfoProps {
guardrailId: string
@@ -105,7 +105,7 @@ const GuardrailInfoView: React.FC<GuardrailInfoProps> = ({ guardrailId, onClose,
setSelectedPiiActions({})
}
} catch (error) {
NotificationManager.fromBackend("Failed to load guardrail information")
NotificationsManager.fromBackend("Failed to load guardrail information")
console.error("Error fetching guardrail info:", error)
} finally {
setLoading(false)
@@ -286,18 +286,18 @@ const GuardrailInfoView: React.FC<GuardrailInfoProps> = ({ guardrailId, onClose,
// Only proceed with update if there are actual changes
if (Object.keys(updateData).length === 0) {
message.info("No changes detected")
NotificationsManager.info("No changes detected")
setIsEditing(false)
return
}
await updateGuardrailCall(accessToken, guardrailId, updateData)
message.success("Guardrail updated successfully")
NotificationsManager.success("Guardrail updated successfully")
fetchGuardrailInfo()
setIsEditing(false)
} catch (error) {
console.error("Error updating guardrail:", error)
NotificationManager.fromBackend("Failed to update guardrail")
NotificationsManager.fromBackend("Failed to update guardrail")
}
}
@@ -3,7 +3,7 @@ import { Modal, Form, Steps, Button, message, Checkbox } from "antd";
import { Text, Title, Badge } from "@tremor/react";
import { makeModelGroupPublic } from "./networking";
import ModelFilters from "./model_filters";
import NotificationManager from "./molecules/notifications_manager";
import NotificationsManager from "./molecules/notifications_manager";
const { Step } = Steps;
@@ -57,7 +57,7 @@ const MakeModelPublicForm: React.FC<MakeModelPublicFormProps> = ({
const handleNext = () => {
if (currentStep === 0) {
if (selectedModels.size === 0) {
NotificationManager.fromBackend("Please select at least one model to make public");
NotificationsManager.fromBackend("Please select at least one model to make public");
return;
}
setCurrentStep(1);
@@ -110,7 +110,7 @@ const MakeModelPublicForm: React.FC<MakeModelPublicFormProps> = ({
const handleSubmit = async () => {
if (selectedModels.size === 0) {
NotificationManager.fromBackend("Please select at least one model to make public");
NotificationsManager.fromBackend("Please select at least one model to make public");
return;
}
@@ -119,12 +119,12 @@ const MakeModelPublicForm: React.FC<MakeModelPublicFormProps> = ({
const modelGroupsToMakePublic = Array.from(selectedModels);
await makeModelGroupPublic(accessToken, modelGroupsToMakePublic);
message.success(`Successfully made ${modelGroupsToMakePublic.length} model group(s) public!`);
NotificationsManager.success(`Successfully made ${modelGroupsToMakePublic.length} model group(s) public!`);
handleClose();
onSuccess();
} catch (error) {
console.error("Error making model groups public:", error);
NotificationManager.fromBackend("Failed to make model groups public. Please try again.");
NotificationsManager.fromBackend("Failed to make model groups public. Please try again.");
} finally {
setLoading(false);
}
@@ -2,6 +2,7 @@ import React from 'react';
import { Typography, Space, Button, Divider, message } from 'antd';
import { WarningOutlined, InfoCircleOutlined, CopyOutlined } from '@ant-design/icons';
import { testMCPConnectionRequest } from "./networking";
import NotificationsManager from "./molecules/notifications_manager";
const { Text } = Typography;
@@ -213,7 +214,7 @@ const MCPConnectionTest: React.FC<MCPConnectionTestProps> = ({
icon={<CopyOutlined />}
onClick={() => {
navigator.clipboard.writeText(formatMCPRequest(rawRequest || {}));
message.success('Copied to clipboard');
NotificationsManager.success('Copied to clipboard');
}}
>
Copy Configuration
@@ -3,7 +3,7 @@ import { Button, Callout, TextInput } from "@tremor/react";
import { MCPTool, InputSchema } from "./types";
import { Form, Tooltip, message } from "antd";
import { InfoCircleOutlined, ClockCircleOutlined } from "@ant-design/icons";
import NotificationManager from "../molecules/notifications_manager";
import NotificationsManager from "../molecules/notifications_manager";
export function ToolTestPanel({
tool,
@@ -143,18 +143,18 @@ export function ToolTestPanel({
const handleCopyResult = async () => {
const success = await copyToClipboard(JSON.stringify(result, null, 2));
if (success) {
message.success('Result copied to clipboard');
NotificationsManager.success('Result copied to clipboard');
} else {
NotificationManager.fromBackend('Failed to copy result');
NotificationsManager.fromBackend('Failed to copy result');
}
};
const handleCopyToolName = async () => {
const success = await copyToClipboard(tool.name);
if (success) {
message.success('Tool name copied to clipboard');
NotificationsManager.success('Tool name copied to clipboard');
} else {
NotificationManager.fromBackend('Failed to copy tool name');
NotificationsManager.fromBackend('Failed to copy tool name');
}
};
@@ -9,7 +9,7 @@ import MCPConnectionStatus from "./mcp_connection_status"
import StdioConfiguration from "./StdioConfiguration"
import { isAdminRole } from "@/utils/roles"
import { validateMCPServerUrl, validateMCPServerName } from "./utils"
import NotificationManager from "../molecules/notifications_manager"
import NotificationsManager from "../molecules/notifications_manager"
const asset_logos_folder = "../ui/assets/logos/"
export const mcpLogoImg = `${asset_logos_folder}mcp_logo.png`
@@ -81,7 +81,7 @@ const CreateMCPServer: React.FC<CreateMCPServerProps> = ({
console.log("Parsed stdio config:", stdioFields)
} catch (error) {
NotificationManager.fromBackend("Invalid JSON in stdio configuration")
NotificationsManager.fromBackend("Invalid JSON in stdio configuration")
return
}
}
@@ -106,7 +106,7 @@ const CreateMCPServer: React.FC<CreateMCPServerProps> = ({
if (accessToken != null) {
const response = await createMCPServer(accessToken, payload)
message.success("MCP Server created successfully")
NotificationsManager.success("MCP Server created successfully")
form.resetFields()
setCostConfig({})
setTools([])
@@ -114,7 +114,7 @@ const CreateMCPServer: React.FC<CreateMCPServerProps> = ({
onCreateSuccess(response)
}
} catch (error) {
NotificationManager.fromBackend("Error creating MCP Server: " + error)
NotificationsManager.fromBackend("Error creating MCP Server: " + error)
} finally {
setIsLoading(false)
}
@@ -6,7 +6,7 @@ import { updateMCPServer, testMCPToolsListRequest } from "../networking";
import MCPServerCostConfig from "./mcp_server_cost_config";
import { MinusCircleOutlined, PlusOutlined, InfoCircleOutlined } from "@ant-design/icons";
import { validateMCPServerUrl, validateMCPServerName } from "./utils";
import NotificationManager from "../molecules/notifications_manager";
import NotificationsManager from "../molecules/notifications_manager";
interface MCPServerEditProps {
mcpServer: MCPServer;
@@ -129,10 +129,10 @@ const MCPServerEdit: React.FC<MCPServerEditProps> = ({ mcpServer, accessToken, o
};
const updated = await updateMCPServer(accessToken, payload);
message.success("MCP Server updated successfully");
NotificationsManager.success("MCP Server updated successfully");
onSuccess(updated);
} catch (error: any) {
NotificationManager.fromBackend("Failed to update MCP Server" + (error?.message ? `: ${error.message}` : ""));
NotificationsManager.fromBackend("Failed to update MCP Server" + (error?.message ? `: ${error.message}` : ""));
}
};
@@ -12,6 +12,7 @@ import { MCPServerView } from "./mcp_server_view"
import CreateMCPServer from "./create_mcp_server"
import MCPConnect from "./mcp_connect"
import { QuestionCircleOutlined } from "@ant-design/icons"
import NotificationsManager from "../molecules/notifications_manager"
const { Option } = Select
@@ -150,7 +151,7 @@ const MCPServers: React.FC<MCPServerProps> = ({ accessToken, userRole, userID })
}
try {
await deleteMCPServer(accessToken, serverIdToDelete)
message.success("Deleted MCP Server successfully")
NotificationsManager.success("Deleted MCP Server successfully")
refetch()
} catch (error) {
console.error("Error deleting the mcp server:", error)
@@ -20,6 +20,7 @@ import { Button, Card, Title, Text } from "@tremor/react";
import { RobotOutlined, ApiOutlined, KeyOutlined, SafetyOutlined, ToolOutlined } from "@ant-design/icons";
import { AUTH_TYPE } from "./types";
import NotificationsManager from "../molecules/notifications_manager"
type AuthModalProps = {
visible: boolean;
@@ -189,7 +190,7 @@ const MCPToolsViewer = ({
setMcpAuthValue(authValue);
if (authValue && mcpServerHasAuth(auth_type)) {
setMCPAuthToken(serverId, authValue, auth_type || 'none', serverAlias || undefined);
message.success('Authentication token saved locally');
NotificationsManager.success('Authentication token saved locally');
}
};
@@ -197,7 +198,7 @@ const MCPToolsViewer = ({
const handleClearAuth = () => {
setMcpAuthValue("");
removeMCPAuthToken(serverId);
message.info('Authentication token cleared');
NotificationsManager.info('Authentication token cleared');
};
// Query to fetch MCP tools
@@ -25,6 +25,7 @@ import { credentialListCall, credentialCreateCall, credentialDeleteCall, credent
import AddCredentialsTab from "./add_credentials_tab";
import CredentialDeleteModal from "./CredentialDeleteModal";
import { Form, message } from "antd";
import NotificationsManager from "../molecules/notifications_manager";
interface CredentialsPanelProps {
accessToken: string | null;
uploadProps: UploadProps;
@@ -60,7 +61,7 @@ const CredentialsPanel: React.FC<CredentialsPanelProps> = ({ accessToken, upload
};
const response = await credentialUpdateCall(accessToken, values.credential_name, newCredential);
message.success('Credential updated successfully');
NotificationsManager.success('Credential updated successfully');
setIsUpdateModalOpen(false);
fetchCredentials(accessToken);
}
@@ -84,7 +85,7 @@ const CredentialsPanel: React.FC<CredentialsPanelProps> = ({ accessToken, upload
// Add to list and close modal
const response = await credentialCreateCall(accessToken, newCredential);
message.success('Credential added successfully');
NotificationsManager.success('Credential added successfully');
setIsAddModalOpen(false);
fetchCredentials(accessToken);
};
@@ -120,7 +121,7 @@ const CredentialsPanel: React.FC<CredentialsPanelProps> = ({ accessToken, upload
return;
}
const response = await credentialDeleteCall(accessToken, credentialName);
message.success('Credential deleted successfully');
NotificationsManager.success('Credential deleted successfully');
setCredentialToDelete(null);
fetchCredentials(accessToken);
};
@@ -13,7 +13,7 @@ import {
TableRow,
TableCell
} from "@tremor/react";
import NotificationManager from "./molecules/notifications_manager";
import NotificationsManager from "./molecules/notifications_manager";
interface ModelGroupAliasSettingsProps {
accessToken: string;
@@ -76,20 +76,20 @@ const ModelGroupAliasSettings: React.FC<ModelGroupAliasSettingsProps> = ({
return true;
} catch (error) {
console.error("Failed to save model group alias settings:", error);
NotificationManager.fromBackend("Failed to save model group alias settings");
NotificationsManager.fromBackend("Failed to save model group alias settings");
return false;
}
};
const handleAddAlias = async () => {
if (!newAlias.aliasName || !newAlias.targetModelGroup) {
NotificationManager.fromBackend("Please provide both alias name and target model group");
NotificationsManager.fromBackend("Please provide both alias name and target model group");
return;
}
// Check for duplicate alias names
if (aliases.some(alias => alias.aliasName === newAlias.aliasName)) {
NotificationManager.fromBackend("An alias with this name already exists");
NotificationsManager.fromBackend("An alias with this name already exists");
return;
}
@@ -104,7 +104,7 @@ const ModelGroupAliasSettings: React.FC<ModelGroupAliasSettingsProps> = ({
if (await saveAliasesToBackend(updatedAliases)) {
setAliases(updatedAliases);
setNewAlias({ aliasName: "", targetModelGroup: "" });
message.success("Alias added successfully");
NotificationsManager.success("Alias added successfully");
}
};
@@ -116,13 +116,13 @@ const ModelGroupAliasSettings: React.FC<ModelGroupAliasSettingsProps> = ({
if (!editingAlias) return;
if (!editingAlias.aliasName || !editingAlias.targetModelGroup) {
NotificationManager.fromBackend("Please provide both alias name and target model group");
NotificationsManager.fromBackend("Please provide both alias name and target model group");
return;
}
// Check for duplicate alias names (excluding current alias)
if (aliases.some(alias => alias.id !== editingAlias.id && alias.aliasName === editingAlias.aliasName)) {
NotificationManager.fromBackend("An alias with this name already exists");
NotificationsManager.fromBackend("An alias with this name already exists");
return;
}
@@ -133,7 +133,7 @@ const ModelGroupAliasSettings: React.FC<ModelGroupAliasSettingsProps> = ({
if (await saveAliasesToBackend(updatedAliases)) {
setAliases(updatedAliases);
setEditingAlias(null);
message.success("Alias updated successfully");
NotificationsManager.success("Alias updated successfully");
}
};
@@ -146,7 +146,7 @@ const ModelGroupAliasSettings: React.FC<ModelGroupAliasSettingsProps> = ({
if (await saveAliasesToBackend(updatedAliases)) {
setAliases(updatedAliases);
message.success("Alias deleted successfully");
NotificationsManager.success("Alias deleted successfully");
}
};
@@ -21,6 +21,7 @@ import { Prism as SyntaxHighlighter } from "react-syntax-highlighter";
import { Table as TableInstance } from '@tanstack/react-table';
import { Copy } from "lucide-react";
import { isAdminRole } from "../utils/roles";
import NotificationsManager from "./molecules/notifications_manager";
interface ModelHubTableProps {
accessToken: string | null;
@@ -146,7 +147,7 @@ const ModelHubTable: React.FC<ModelHubTableProps> = ({
const copyToClipboard = (text: string) => {
navigator.clipboard.writeText(text);
message.success("Copied to clipboard!");
NotificationsManager.success("Copied to clipboard!");
};
const formatCapabilityName = (key: string) => {
@@ -38,7 +38,7 @@ import CacheControlSettings from "./add_model/cache_control_settings";
import { CheckIcon, CopyIcon } from "lucide-react";
import { copyToClipboard as utilCopyToClipboard } from "../utils/dataUtils";
import EditAutoRouterModal from "./edit_auto_router/edit_auto_router_modal";
import NotificationManager from "./molecules/notifications_manager";
import NotificationsManager from "./molecules/notifications_manager";
interface ModelInfoViewProps {
modelId: string;
@@ -153,13 +153,13 @@ export default function ModelInfoView({
custom_llm_provider: localModelData.litellm_params?.custom_llm_provider,
},
};
message.info("Storing credential..");
NotificationsManager.info("Storing credential..");
let credentialResponse = await credentialCreateCall(
accessToken,
credentialItem
);
console.log("credentialResponse, ", credentialResponse);
message.success("Credential stored successfully");
NotificationsManager.success("Credential stored successfully");
};
const handleModelUpdate = async (values: any) => {
@@ -212,7 +212,7 @@ export default function ModelInfoView({
};
}
} catch (e) {
NotificationManager.fromBackend("Invalid JSON in Model Info");
NotificationsManager.fromBackend("Invalid JSON in Model Info");
return;
}
@@ -238,12 +238,12 @@ export default function ModelInfoView({
onModelUpdate(updatedModelData);
}
message.success("Model settings updated successfully");
NotificationsManager.success("Model settings updated successfully");
setIsDirty(false);
setIsEditing(false);
} catch (error) {
console.error("Error updating model:", error);
NotificationManager.fromBackend("Failed to update model settings");
NotificationsManager.fromBackend("Failed to update model settings");
} finally {
setIsSaving(false);
}
@@ -269,7 +269,7 @@ export default function ModelInfoView({
try {
if (!accessToken) return;
await modelDeleteCall(accessToken, modelId);
message.success("Model deleted successfully");
NotificationsManager.success("Model deleted successfully");
if (onModelUpdate) {
onModelUpdate({
@@ -281,7 +281,7 @@ export default function ModelInfoView({
onClose();
} catch (error) {
console.error("Error deleting the model:", error);
NotificationManager.fromBackend("Failed to delete model");
NotificationsManager.fromBackend("Failed to delete model");
}
};
@@ -1,17 +1,18 @@
import React from "react"
import { notification } from "antd"
import { parseErrorMessage } from "../shared/errorUtils"
type Placement = "top" | "topLeft" | "topRight" | "bottom" | "bottomLeft" | "bottomRight"
type NotificationConfig = {
message?: string
description?: string
message?: string | React.ReactNode
description?: string | React.ReactNode
duration?: number
placement?: Placement
key?: string
}
type NotificationConfigResolved = Omit<NotificationConfig, "message"> & { message: string }
type NotificationConfigResolved = Omit<NotificationConfig, "message"> & { message: string | React.ReactNode }
function defaultPlacement(): Placement {
return "topRight"
@@ -273,8 +274,17 @@ const NotificationManager = {
})
},
success(input: string | NotificationConfig) {
const cfg = normalize(input, "Success")
success(input: string | React.ReactNode | NotificationConfig) {
if (React.isValidElement(input)) {
notification.success({
message: "Success",
description: input,
placement: defaultPlacement(),
duration: 3.5,
})
return
}
const cfg = normalize(input as string | NotificationConfig, "Success")
notification.success({
...cfg,
placement: cfg.placement ?? defaultPlacement(),
@@ -25,7 +25,7 @@ import {
EmailEventSettingsUpdateRequest,
} from "./email_events/types";
import { jsonFields } from "./common_components/check_openapi_schema"
import NotificationManager from "./molecules/notifications_manager";
import NotificationsManager from "./molecules/notifications_manager";
const isLocal = process.env.NODE_ENV === "development";
export const defaultProxyBaseUrl = isLocal ? "http://localhost:4000" : null;
@@ -167,7 +167,7 @@ const handleError = async (errorData: string) => {
if (currentTime - lastErrorTime > 60000) {
// 60000 milliseconds = 60 seconds
if (errorData.includes("Authentication Error - Expired Key")) {
message.info("UI Session Expired. Logging out.");
NotificationsManager.info("UI Session Expired. Logging out.");
lastErrorTime = currentTime;
document.cookie =
"token=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/;";
@@ -383,7 +383,7 @@ export const modelCreateCall = async (
message.destroy();
// Sequential success messages
message.success(`Model ${formValues.model_name} created successfully`, 2);
NotificationsManager.success(`Model ${formValues.model_name} created successfully`);
return data;
} catch (error) {
@@ -401,7 +401,7 @@ export const modelSettingsCall = async (accessToken: String) => {
? `${proxyBaseUrl}/model/settings`
: `/model/settings`;
//message.info("Requesting model data");
//NotificationsManager.info("Requesting model data");
const response = await fetch(url, {
method: "GET",
headers: {
@@ -419,7 +419,7 @@ export const modelSettingsCall = async (accessToken: String) => {
const data = await response.json();
//message.info("Received model data");
//NotificationsManager.info("Received model data");
return data;
// Handle success - you might want to update some state or UI based on the created key
} catch (error: any) {
@@ -667,7 +667,7 @@ export const alertingSettingsCall = async (accessToken: String) => {
? `${proxyBaseUrl}/alerting/settings`
: `/alerting/settings`;
//message.info("Requesting model data");
//NotificationsManager.info("Requesting model data");
const response = await fetch(url, {
method: "GET",
headers: {
@@ -685,7 +685,7 @@ export const alertingSettingsCall = async (accessToken: String) => {
const data = await response.json();
//message.info("Received model data");
//NotificationsManager.info("Received model data");
return data;
// Handle success - you might want to update some state or UI based on the created key
} catch (error) {
@@ -888,7 +888,7 @@ export const keyDeleteCall = async (accessToken: String, user_key: String) => {
try {
const url = proxyBaseUrl ? `${proxyBaseUrl}/key/delete` : `/key/delete`;
console.log("in keyDeleteCall:", user_key);
//message.info("Making key delete request");
//NotificationsManager.info("Making key delete request");
const response = await fetch(url, {
method: "POST",
headers: {
@@ -910,7 +910,7 @@ export const keyDeleteCall = async (accessToken: String, user_key: String) => {
const data = await response.json();
console.log(data);
//message.success("API Key Deleted");
//NotificationsManager.success("API Key Deleted");
return data;
// Handle success - you might want to update some state or UI based on the created key
} catch (error) {
@@ -948,7 +948,7 @@ export const userDeleteCall = async (
const data = await response.json();
console.log(data);
//message.success("User(s) Deleted");
//NotificationsManager.success("User(s) Deleted");
return data;
} catch (error) {
console.error("Failed to delete user(s):", error);
@@ -1738,7 +1738,7 @@ export const getTotalSpendCall = async (accessToken: String) => {
try {
let url = proxyBaseUrl ? `${proxyBaseUrl}/global/spend` : `/global/spend`;
//message.info("Requesting model data");
//NotificationsManager.info("Requesting model data");
const response = await fetch(url, {
method: "GET",
headers: {
@@ -1894,7 +1894,7 @@ export const modelInfoCall = async (
url += `?${params.toString()}`;
}
//message.info("Requesting model data");
//NotificationsManager.info("Requesting model data");
const response = await fetch(url, {
method: "GET",
headers: {
@@ -1910,7 +1910,7 @@ export const modelInfoCall = async (
if (errorData.includes("No model list passed")) {
errorData = "No Models Exist. Click Add Model to get started.";
}
message.info(errorData, 10);
NotificationsManager.info(errorData);
ModelListerrorShown = true;
if (errorTimer) clearTimeout(errorTimer);
@@ -1924,7 +1924,7 @@ export const modelInfoCall = async (
const data = await response.json();
console.log("modelInfoCall:", data);
//message.info("Received model data");
//NotificationsManager.info("Received model data");
return data;
// Handle success - you might want to update some state or UI based on the created key
} catch (error) {
@@ -1986,7 +1986,7 @@ export const modelHubCall = async (accessToken: String) => {
? `${proxyBaseUrl}/model_group/info`
: `/model_group/info`;
//message.info("Requesting model data");
//NotificationsManager.info("Requesting model data");
const response = await fetch(url, {
method: "GET",
headers: {
@@ -2005,7 +2005,7 @@ export const modelHubCall = async (accessToken: String) => {
const data = await response.json();
console.log("modelHubCall:", data);
//message.info("Received model data");
//NotificationsManager.info("Received model data");
return data;
// Handle success - you might want to update some state or UI based on the created key
} catch (error) {
@@ -2130,7 +2130,7 @@ export const modelMetricsCall = async (
if (modelGroup) {
url = `${url}?_selected_model_group=${modelGroup}&startTime=${startTime}&endTime=${endTime}&api_key=${apiKey}&customer=${customer}`;
}
// message.info("Requesting model data");
// NotificationsManager.info("Requesting model data");
const response = await fetch(url, {
method: "GET",
headers: {
@@ -2147,7 +2147,7 @@ export const modelMetricsCall = async (
}
const data = await response.json();
// message.info("Received model data");
// NotificationsManager.info("Received model data");
return data;
// Handle success - you might want to update some state or UI based on the created key
} catch (error) {
@@ -2171,7 +2171,7 @@ export const streamingModelMetricsCall = async (
if (modelGroup) {
url = `${url}?_selected_model_group=${modelGroup}&startTime=${startTime}&endTime=${endTime}`;
}
// message.info("Requesting model data");
// NotificationsManager.info("Requesting model data");
const response = await fetch(url, {
method: "GET",
headers: {
@@ -2188,7 +2188,7 @@ export const streamingModelMetricsCall = async (
}
const data = await response.json();
// message.info("Received model data");
// NotificationsManager.info("Received model data");
return data;
// Handle success - you might want to update some state or UI based on the created key
} catch (error) {
@@ -2218,7 +2218,7 @@ export const modelMetricsSlowResponsesCall = async (
url = `${url}?_selected_model_group=${modelGroup}&startTime=${startTime}&endTime=${endTime}&api_key=${apiKey}&customer=${customer}`;
}
// message.info("Requesting model data");
// NotificationsManager.info("Requesting model data");
const response = await fetch(url, {
method: "GET",
headers: {
@@ -2235,7 +2235,7 @@ export const modelMetricsSlowResponsesCall = async (
}
const data = await response.json();
// message.info("Received model data");
// NotificationsManager.info("Received model data");
return data;
// Handle success - you might want to update some state or UI based on the created key
} catch (error) {
@@ -2281,7 +2281,7 @@ export const modelExceptionsCall = async (
}
const data = await response.json();
// message.info("Received model data");
// NotificationsManager.info("Received model data");
return data;
// Handle success - you might want to update some state or UI based on the created key
} catch (error) {
@@ -2348,7 +2348,7 @@ export const modelAvailableCall = async (
url += `?${params.toString()}`;
}
//message.info("Requesting model data");
//NotificationsManager.info("Requesting model data");
const response = await fetch(url, {
method: "GET",
headers: {
@@ -2366,7 +2366,7 @@ export const modelAvailableCall = async (
const data = await response.json();
//message.info("Received model data");
//NotificationsManager.info("Received model data");
return data;
// Handle success - you might want to update some state or UI based on the created key
} catch (error) {
@@ -2595,7 +2595,7 @@ export const userSpendLogsCall = async (
} else {
url = `${url}?start_date=${startTime}&end_date=${endTime}`;
}
//message.info("Making spend logs request");
//NotificationsManager.info("Making spend logs request");
const response = await fetch(url, {
method: "GET",
headers: {
@@ -2613,7 +2613,7 @@ export const userSpendLogsCall = async (
const data = await response.json();
console.log(data);
//message.success("Spend Logs received");
//NotificationsManager.success("Spend Logs received");
return data;
} catch (error) {
console.error("Failed to create key:", error);
@@ -2689,7 +2689,7 @@ export const adminSpendLogsCall = async (accessToken: String) => {
? `${proxyBaseUrl}/global/spend/logs`
: `/global/spend/logs`;
//message.info("Making spend logs request");
//NotificationsManager.info("Making spend logs request");
const response = await fetch(url, {
method: "GET",
headers: {
@@ -2707,7 +2707,7 @@ export const adminSpendLogsCall = async (accessToken: String) => {
const data = await response.json();
console.log(data);
//message.success("Spend Logs received");
//NotificationsManager.success("Spend Logs received");
return data;
} catch (error) {
console.error("Failed to create key:", error);
@@ -2721,7 +2721,7 @@ export const adminTopKeysCall = async (accessToken: String) => {
? `${proxyBaseUrl}/global/spend/keys?limit=5`
: `/global/spend/keys?limit=5`;
//message.info("Making spend keys request");
//NotificationsManager.info("Making spend keys request");
const response = await fetch(url, {
method: "GET",
headers: {
@@ -2739,7 +2739,7 @@ export const adminTopKeysCall = async (accessToken: String) => {
const data = await response.json();
console.log(data);
//message.success("Spend Logs received");
//NotificationsManager.success("Spend Logs received");
return data;
} catch (error) {
console.error("Failed to create key:", error);
@@ -2769,7 +2769,7 @@ export const adminTopEndUsersCall = async (
body = JSON.stringify({ startTime: startTime, endTime: endTime });
}
//message.info("Making top end users request");
//NotificationsManager.info("Making top end users request");
// Define requestOptions with body as an optional property
const requestOptions = {
@@ -2792,7 +2792,7 @@ export const adminTopEndUsersCall = async (
const data = await response.json();
console.log(data);
//message.success("Top End users received");
//NotificationsManager.success("Top End users received");
return data;
} catch (error) {
console.error("Failed to create key:", error);
@@ -3056,7 +3056,7 @@ export const adminTopModelsCall = async (accessToken: String) => {
? `${proxyBaseUrl}/global/spend/models?limit=5`
: `/global/spend/models?limit=5`;
//message.info("Making top models request");
//NotificationsManager.info("Making top models request");
const response = await fetch(url, {
method: "GET",
headers: {
@@ -3074,7 +3074,7 @@ export const adminTopModelsCall = async (accessToken: String) => {
const data = await response.json();
console.log(data);
//message.success("Top Models received");
//NotificationsManager.success("Top Models received");
return data;
} catch (error) {
console.error("Failed to create key:", error);
@@ -3199,7 +3199,7 @@ export const keyInfoV1Call = async (accessToken: string, key: string) => {
if (!response.ok) {
const errorData = await response.text();
handleError(errorData);
NotificationManager.fromBackend("Failed to fetch key info - " + errorData);
NotificationsManager.fromBackend("Failed to fetch key info - " + errorData);
}
const data = await response.json();
@@ -3360,7 +3360,7 @@ export const userRequestModelCall = async (
const data = await response.json();
console.log(data);
//message.success("");
//NotificationsManager.success("");
return data;
// Handle success - you might want to update some state or UI based on the created key
} catch (error) {
@@ -3392,7 +3392,7 @@ export const userGetRequesedtModelsCall = async (accessToken: String) => {
const data = await response.json();
console.log(data);
//message.success("");
//NotificationsManager.success("");
return data;
// Handle success - you might want to update some state or UI based on the created key
} catch (error) {
@@ -3485,7 +3485,7 @@ export const userGetAllUsersCall = async (
const data = await response.json();
console.log(data);
//message.success("Got all users");
//NotificationsManager.success("Got all users");
return data;
// Handle success - you might want to update some state or UI based on the created key
} catch (error) {
@@ -3854,7 +3854,7 @@ export const teamUpdateCall = async (
const errorData = await response.text();
handleError(errorData);
console.error("Error response from the server:", errorData);
NotificationManager.fromBackend("Failed to update team settings: " + errorData);
NotificationsManager.fromBackend("Failed to update team settings: " + errorData);
throw new Error(errorData);
}
const data = (await response.json()) as { data: Team; team_id: string };
@@ -4347,7 +4347,7 @@ export const userUpdateUserCall = async (
data: UserInfo;
};
console.log("API Response:", data);
//message.success("User role updated");
//NotificationsManager.success("User role updated");
return data;
// Handle success - you might want to update some state or UI based on the created key
} catch (error) {
@@ -4423,7 +4423,7 @@ export const userBulkUpdateUserCall = async (
failed_updates: number;
};
console.log("API Response:", data);
//message.success("User role updated");
//NotificationsManager.success("User role updated");
return data;
// Handle success - you might want to update some state or UI based on the created key
} catch (error) {
@@ -4441,7 +4441,7 @@ export const PredictedSpendLogsCall = async (
? `${proxyBaseUrl}/global/predict/spend/logs`
: `/global/predict/spend/logs`;
//message.info("Predicting spend logs request");
//NotificationsManager.info("Predicting spend logs request");
const response = await fetch(url, {
method: "POST",
@@ -4464,7 +4464,7 @@ export const PredictedSpendLogsCall = async (
const data = await response.json();
console.log(data);
//message.success("Predicted Logs received");
//NotificationsManager.success("Predicted Logs received");
return data;
} catch (error) {
console.error("Failed to create key:", error);
@@ -4479,7 +4479,7 @@ export const slackBudgetAlertsHealthCheck = async (accessToken: String) => {
: `/health/services?service=slack_budget_alerts`;
console.log("Checking Slack Budget Alerts service health");
//message.info("Sending Test Slack alert...");
//NotificationsManager.info("Sending Test Slack alert...");
const response = await fetch(url, {
method: "GET",
@@ -4497,7 +4497,7 @@ export const slackBudgetAlertsHealthCheck = async (accessToken: String) => {
}
const data = await response.json();
message.success("Test Slack Alert worked - check your Slack!");
NotificationsManager.success("Test Slack Alert worked - check your Slack!");
console.log("Service Health Response:", data);
// You can add additional logic here based on the response if needed
@@ -4551,7 +4551,7 @@ export const getBudgetList = async (accessToken: String) => {
try {
let url = proxyBaseUrl ? `${proxyBaseUrl}/budget/list` : `/budget/list`;
//message.info("Requesting model data");
//NotificationsManager.info("Requesting model data");
const response = await fetch(url, {
method: "GET",
headers: {
@@ -4569,7 +4569,7 @@ export const getBudgetList = async (accessToken: String) => {
const data = await response.json();
//message.info("Received model data");
//NotificationsManager.info("Received model data");
return data;
// Handle success - you might want to update some state or UI based on the created key
} catch (error) {
@@ -4586,7 +4586,7 @@ export const getBudgetSettings = async (accessToken: String) => {
? `${proxyBaseUrl}/budget/settings`
: `/budget/settings`;
//message.info("Requesting model data");
//NotificationsManager.info("Requesting model data");
const response = await fetch(url, {
method: "GET",
headers: {
@@ -4604,7 +4604,7 @@ export const getBudgetSettings = async (accessToken: String) => {
const data = await response.json();
//message.info("Received model data");
//NotificationsManager.info("Received model data");
return data;
// Handle success - you might want to update some state or UI based on the created key
} catch (error) {
@@ -4626,7 +4626,7 @@ export const getCallbacksCall = async (
? `${proxyBaseUrl}/get/config/callbacks`
: `/get/config/callbacks`;
//message.info("Requesting model data");
//NotificationsManager.info("Requesting model data");
const response = await fetch(url, {
method: "GET",
headers: {
@@ -4644,7 +4644,7 @@ export const getCallbacksCall = async (
const data = await response.json();
//message.info("Received model data");
//NotificationsManager.info("Received model data");
return data;
// Handle success - you might want to update some state or UI based on the created key
} catch (error) {
@@ -4659,7 +4659,7 @@ export const getGeneralSettingsCall = async (accessToken: String) => {
? `${proxyBaseUrl}/config/list?config_type=general_settings`
: `/config/list?config_type=general_settings`;
//message.info("Requesting model data");
//NotificationsManager.info("Requesting model data");
const response = await fetch(url, {
method: "GET",
headers: {
@@ -4677,7 +4677,7 @@ export const getGeneralSettingsCall = async (accessToken: String) => {
const data = await response.json();
//message.info("Received model data");
//NotificationsManager.info("Received model data");
return data;
// Handle success - you might want to update some state or UI based on the created key
} catch (error) {
@@ -4692,7 +4692,7 @@ export const getPassThroughEndpointsCall = async (accessToken: String) => {
? `${proxyBaseUrl}/config/pass_through_endpoint`
: `/config/pass_through_endpoint`;
//message.info("Requesting model data");
//NotificationsManager.info("Requesting model data");
const response = await fetch(url, {
method: "GET",
headers: {
@@ -4710,7 +4710,7 @@ export const getPassThroughEndpointsCall = async (accessToken: String) => {
const data = await response.json();
//message.info("Received model data");
//NotificationsManager.info("Received model data");
return data;
// Handle success - you might want to update some state or UI based on the created key
} catch (error) {
@@ -4728,7 +4728,7 @@ export const getConfigFieldSetting = async (
? `${proxyBaseUrl}/config/field/info?field_name=${fieldName}`
: `/config/field/info?field_name=${fieldName}`;
//message.info("Requesting model data");
//NotificationsManager.info("Requesting model data");
const response = await fetch(url, {
method: "GET",
headers: {
@@ -4768,7 +4768,7 @@ export const updatePassThroughFieldSetting = async (
field_name: fieldName,
field_value: fieldValue,
};
//message.info("Requesting model data");
//NotificationsManager.info("Requesting model data");
const response = await fetch(url, {
method: "POST",
headers: {
@@ -4787,8 +4787,8 @@ export const updatePassThroughFieldSetting = async (
const data = await response.json();
//message.info("Received model data");
message.success("Successfully updated value!");
//NotificationsManager.info("Received model data");
NotificationsManager.success("Successfully updated value!");
return data;
// Handle success - you might want to update some state or UI based on the created key
} catch (error) {
@@ -4809,7 +4809,7 @@ export const createPassThroughEndpoint = async (
? `${proxyBaseUrl}/config/pass_through_endpoint`
: `/config/pass_through_endpoint`;
//message.info("Requesting model data");
//NotificationsManager.info("Requesting model data");
const response = await fetch(url, {
method: "POST",
headers: {
@@ -4830,7 +4830,7 @@ export const createPassThroughEndpoint = async (
const data = await response.json();
//message.info("Received model data");
//NotificationsManager.info("Received model data");
return data;
// Handle success - you might want to update some state or UI based on the created key
} catch (error) {
@@ -4854,7 +4854,7 @@ export const updateConfigFieldSetting = async (
field_value: fieldValue,
config_type: "general_settings",
};
//message.info("Requesting model data");
//NotificationsManager.info("Requesting model data");
const response = await fetch(url, {
method: "POST",
headers: {
@@ -4873,8 +4873,8 @@ export const updateConfigFieldSetting = async (
const data = await response.json();
//message.info("Received model data");
message.success("Successfully updated value!");
//NotificationsManager.info("Received model data");
NotificationsManager.success("Successfully updated value!");
return data;
// Handle success - you might want to update some state or UI based on the created key
} catch (error) {
@@ -4896,7 +4896,7 @@ export const deleteConfigFieldSetting = async (
field_name: fieldName,
config_type: "general_settings",
};
//message.info("Requesting model data");
//NotificationsManager.info("Requesting model data");
const response = await fetch(url, {
method: "POST",
headers: {
@@ -4915,7 +4915,7 @@ export const deleteConfigFieldSetting = async (
const data = await response.json();
message.success("Field reset on proxy");
NotificationsManager.success("Field reset on proxy");
return data;
// Handle success - you might want to update some state or UI based on the created key
} catch (error) {
@@ -4933,7 +4933,7 @@ export const deletePassThroughEndpointsCall = async (
? `${proxyBaseUrl}/config/pass_through_endpoint?endpoint_id=${endpointId}`
: `/config/pass_through_endpoint?endpoint_id=${endpointId}`;
//message.info("Requesting model data");
//NotificationsManager.info("Requesting model data");
const response = await fetch(url, {
method: "DELETE",
headers: {
@@ -4951,7 +4951,7 @@ export const deletePassThroughEndpointsCall = async (
const data = await response.json();
//message.info("Received model data");
//NotificationsManager.info("Received model data");
return data;
// Handle success - you might want to update some state or UI based on the created key
} catch (error) {
@@ -4970,7 +4970,7 @@ export const setCallbacksCall = async (
try {
let url = proxyBaseUrl ? `${proxyBaseUrl}/config/update` : `/config/update`;
//message.info("Requesting model data");
//NotificationsManager.info("Requesting model data");
const response = await fetch(url, {
method: "POST",
headers: {
@@ -4991,7 +4991,7 @@ export const setCallbacksCall = async (
const data = await response.json();
//message.info("Received model data");
//NotificationsManager.info("Received model data");
return data;
// Handle success - you might want to update some state or UI based on the created key
} catch (error) {
@@ -5007,7 +5007,7 @@ export const healthCheckCall = async (accessToken: String) => {
try {
let url = proxyBaseUrl ? `${proxyBaseUrl}/health` : `/health`;
//message.info("Requesting model data");
//NotificationsManager.info("Requesting model data");
const response = await fetch(url, {
method: "GET",
headers: {
@@ -5025,7 +5025,7 @@ export const healthCheckCall = async (accessToken: String) => {
const data = await response.json();
//message.info("Received model data");
//NotificationsManager.info("Received model data");
return data;
// Handle success - you might want to update some state or UI based on the created key
} catch (error) {
@@ -5077,7 +5077,7 @@ export const cachingHealthCheckCall = async (accessToken: String) => {
try {
let url = proxyBaseUrl ? `${proxyBaseUrl}/cache/ping` : `/cache/ping`;
//message.info("Requesting model data");
//NotificationsManager.info("Requesting model data");
const response = await fetch(url, {
method: "GET",
headers: {
@@ -5093,7 +5093,7 @@ export const cachingHealthCheckCall = async (accessToken: String) => {
}
const data = await response.json();
//message.info("Received model data");
//NotificationsManager.info("Received model data");
return data;
// Handle success - you might want to update some state or UI based on the created key
} catch (error) {
@@ -5190,7 +5190,7 @@ export const getProxyUISettings = async (accessToken: String) => {
? `${proxyBaseUrl}/sso/get/ui_settings`
: `/sso/get/ui_settings`;
//message.info("Requesting model data");
//NotificationsManager.info("Requesting model data");
const response = await fetch(url, {
method: "GET",
headers: {
@@ -5208,7 +5208,7 @@ export const getProxyUISettings = async (accessToken: String) => {
const data = await response.json();
//message.info("Received model data");
//NotificationsManager.info("Received model data");
return data;
// Handle success - you might want to update some state or UI based on the created key
} catch (error) {
@@ -5600,7 +5600,7 @@ export const updateInternalUserSettings = async (
const data = await response.json();
console.log("Updated internal user settings:", data);
message.success("Internal user settings updated successfully");
NotificationsManager.success("Internal user settings updated successfully");
return data;
} catch (error) {
console.error("Failed to update internal user settings:", error);
@@ -6134,7 +6134,7 @@ export const updateDefaultTeamSettings = async (
const data = await response.json();
console.log("Updated default team settings:", data);
message.success("Default team settings updated successfully");
NotificationsManager.success("Default team settings updated successfully");
return data;
} catch (error) {
console.error("Failed to update default team settings:", error);
@@ -6850,7 +6850,7 @@ export const updatePassThroughEndpoint = async (
const data = await response.json();
message.success("Pass through endpoint updated successfully");
NotificationsManager.success("Pass through endpoint updated successfully");
return data;
} catch (error) {
console.error("Failed to update pass through endpoint:", error);
@@ -2,6 +2,7 @@ import React from "react";
import { Modal, message, Typography } from "antd";
import { CopyToClipboard } from "react-copy-to-clipboard";
import { Text, Button } from "@tremor/react";
import NotificationsManager from "./molecules/notifications_manager";
export interface InvitationLink {
id: string;
@@ -88,7 +89,7 @@ export default function OnboardingModal({
<div className="flex justify-end mt-5">
<CopyToClipboard
text={getInvitationUrl()}
onCopy={() => message.success("Copied!")}
onCopy={() => NotificationsManager.success("Copied!")}
>
<Button variant="primary">
{modalType === "invitation"
@@ -33,7 +33,7 @@ import { formatNumberWithCommas } from "@/utils/dataUtils"
import { callback_map, mapDisplayToInternalNames } from "../callback_info_helpers"
import MCPServerSelector from "../mcp_server_management/MCPServerSelector"
import ModelAliasManager from "../common_components/ModelAliasManager"
import NotificationManager from "../molecules/notifications_manager"
import NotificationsManager from "../molecules/notifications_manager"
const { Option } = Select;
@@ -282,7 +282,7 @@ const CreateKey: React.FC<CreateKeyProps> = ({
);
}
message.info("Making API Call");
NotificationsManager.info("Making API Call");
setIsModalVisible(true);
if(keyOwner === "you"){
@@ -379,18 +379,18 @@ const CreateKey: React.FC<CreateKeyProps> = ({
setApiKey(response["key"]);
setSoftBudget(response["soft_budget"]);
message.success("API Key Created");
NotificationsManager.success("API Key Created");
form.resetFields();
localStorage.removeItem("userData" + userID);
} catch (error) {
console.log("error in create key:", error);
NotificationManager.fromBackend(`Error creating the key: ${error}`);
NotificationsManager.fromBackend(`Error creating the key: ${error}`);
}
};
const handleCopy = () => {
message.success("API Key copied to clipboard");
NotificationsManager.success("API Key copied to clipboard");
};
useEffect(() => {
@@ -435,7 +435,7 @@ const CreateKey: React.FC<CreateKeyProps> = ({
setUserOptions(options);
} catch (error) {
console.error('Error fetching users:', error);
NotificationManager.fromBackend('Failed to search for users');
NotificationsManager.fromBackend('Failed to search for users');
} finally {
setUserSearchLoading(false);
}
@@ -41,7 +41,7 @@ import VectorStoreSelector from "../vector_store_management/VectorStoreSelector"
import MCPServerSelector from "../mcp_server_management/MCPServerSelector"
import { copyToClipboard as utilCopyToClipboard, formatNumberWithCommas } from "@/utils/dataUtils"
import { CheckIcon, CopyIcon } from "lucide-react"
import NotificationManager from "../molecules/notifications_manager"
import NotificationsManager from "../molecules/notifications_manager"
interface OrganizationInfoProps {
organizationId: string
@@ -79,7 +79,7 @@ const OrganizationInfoView: React.FC<OrganizationInfoProps> = ({
const response = await organizationInfoCall(accessToken, organizationId)
setOrgData(response)
} catch (error) {
NotificationManager.fromBackend("Failed to load organization information")
NotificationsManager.fromBackend("Failed to load organization information")
console.error("Error fetching organization info:", error)
} finally {
setLoading(false)
@@ -103,12 +103,12 @@ const OrganizationInfoView: React.FC<OrganizationInfoProps> = ({
}
const response = await organizationMemberAddCall(accessToken, organizationId, member)
message.success("Organization member added successfully")
NotificationsManager.success("Organization member added successfully")
setIsAddMemberModalVisible(false)
form.resetFields()
fetchOrgInfo()
} catch (error) {
NotificationManager.fromBackend("Failed to add organization member")
NotificationsManager.fromBackend("Failed to add organization member")
console.error("Error adding organization member:", error)
}
}
@@ -124,12 +124,12 @@ const OrganizationInfoView: React.FC<OrganizationInfoProps> = ({
}
const response = await organizationMemberUpdateCall(accessToken, organizationId, member)
message.success("Organization member updated successfully")
NotificationsManager.success("Organization member updated successfully")
setIsEditMemberModalVisible(false)
form.resetFields()
fetchOrgInfo()
} catch (error) {
NotificationManager.fromBackend("Failed to update organization member")
NotificationsManager.fromBackend("Failed to update organization member")
console.error("Error updating organization member:", error)
}
}
@@ -139,12 +139,12 @@ const OrganizationInfoView: React.FC<OrganizationInfoProps> = ({
if (!accessToken) return
await organizationMemberDeleteCall(accessToken, organizationId, values.user_id)
message.success("Organization member deleted successfully")
NotificationsManager.success("Organization member deleted successfully")
setIsEditMemberModalVisible(false)
form.resetFields()
fetchOrgInfo()
} catch (error) {
NotificationManager.fromBackend("Failed to delete organization member")
NotificationsManager.fromBackend("Failed to delete organization member")
console.error("Error deleting organization member:", error)
}
}
@@ -189,11 +189,11 @@ const OrganizationInfoView: React.FC<OrganizationInfoProps> = ({
const response = await organizationUpdateCall(accessToken, updateData)
message.success("Organization settings updated successfully")
NotificationsManager.success("Organization settings updated successfully")
setIsEditing(false)
fetchOrgInfo()
} catch (error) {
NotificationManager.fromBackend("Failed to update organization settings")
NotificationsManager.fromBackend("Failed to update organization settings")
console.error("Error updating organization:", error)
}
}
@@ -32,6 +32,7 @@ import { Organization, organizationListCall, organizationCreateCall, organizatio
import VectorStoreSelector from "./vector_store_management/VectorStoreSelector"
import MCPServerSelector from "./mcp_server_management/MCPServerSelector"
import { formatNumberWithCommas } from "../utils/dataUtils"
import NotificationsManager from "./molecules/notifications_manager"
interface OrganizationsTableProps {
organizations: Organization[]
@@ -92,7 +93,7 @@ const OrganizationsTable: React.FC<OrganizationsTableProps> = ({
try {
await organizationDeleteCall(accessToken, orgToDelete)
message.success("Organization deleted successfully")
NotificationsManager.success("Organization deleted successfully")
setIsDeleteModalOpen(false)
setOrgToDelete(null)
@@ -20,7 +20,7 @@ import {
} from "./networking";
import { Eye, EyeOff } from "lucide-react";
import RoutePreview from "./route_preview";
import NotificationManager from "./molecules/notifications_manager";
import NotificationsManager from "./molecules/notifications_manager";
export interface PassThroughInfoProps {
endpointData: PassThroughEndpoint;
@@ -88,7 +88,7 @@ const PassThroughInfoView: React.FC<PassThroughInfoProps> = ({
? JSON.parse(values.headers)
: values.headers;
} catch (e) {
NotificationManager.fromBackend("Invalid JSON format for headers");
NotificationsManager.fromBackend("Invalid JSON format for headers");
return;
}
}
@@ -115,7 +115,7 @@ const PassThroughInfoView: React.FC<PassThroughInfoProps> = ({
}
} catch (error) {
console.error("Error updating endpoint:", error);
NotificationManager.fromBackend("Failed to update pass through endpoint");
NotificationsManager.fromBackend("Failed to update pass through endpoint");
}
};
@@ -124,14 +124,14 @@ const PassThroughInfoView: React.FC<PassThroughInfoProps> = ({
if (!accessToken || !endpointData?.id) return;
await deletePassThroughEndpointsCall(accessToken, endpointData.id);
message.success("Pass through endpoint deleted successfully");
NotificationsManager.success("Pass through endpoint deleted successfully");
onClose();
if (onEndpointUpdated) {
onEndpointUpdated();
}
} catch (error) {
console.error("Error deleting endpoint:", error);
NotificationManager.fromBackend("Failed to delete pass through endpoint");
NotificationsManager.fromBackend("Failed to delete pass through endpoint");
}
};
@@ -45,7 +45,7 @@ import PassThroughInfoView from "./pass_through_info";
import { DataTable } from "./view_logs/table";
import { ColumnDef } from "@tanstack/react-table";
import { Eye, EyeOff } from "lucide-react";
import NotificationManager from "./molecules/notifications_manager";
import NotificationsManager from "./molecules/notifications_manager";
interface GeneralSettingsPageProps {
accessToken: string | null;
@@ -151,10 +151,10 @@ const PassThroughSettings: React.FC<GeneralSettingsPageProps> = ({
const updatedSettings = generalSettings.filter((setting) => setting.id !== endpointToDelete);
setGeneralSettings(updatedSettings);
message.success("Endpoint deleted successfully.");
NotificationsManager.success("Endpoint deleted successfully.");
} catch (error) {
console.error("Error deleting the endpoint:", error);
NotificationManager.fromBackend("Error deleting the endpoint: " + error);
NotificationsManager.fromBackend("Error deleting the endpoint: " + error);
}
// Close the confirmation modal and reset the endpointToDelete
@@ -2,7 +2,7 @@ import React, { useState, useEffect } from "react";
import { Button, Popconfirm, message, Modal, InputNumber, Space, Typography, Tag, Card } from "antd";
import { ReloadOutlined, ClockCircleOutlined, StopOutlined } from "@ant-design/icons";
import { reloadModelCostMap, scheduleModelCostMapReload, cancelModelCostMapReload, getModelCostMapReloadStatus } from "./networking";
import NotificationManager from "./molecules/notifications_manager";
import NotificationsManager from "./molecules/notifications_manager";
const { Text } = Typography;
@@ -78,7 +78,7 @@ const PriceDataReload: React.FC<PriceDataReloadProps> = ({
const handleHardRefresh = async () => {
if (!accessToken) {
NotificationManager.fromBackend("No access token available");
NotificationsManager.fromBackend("No access token available");
return;
}
@@ -87,30 +87,30 @@ const PriceDataReload: React.FC<PriceDataReloadProps> = ({
const response = await reloadModelCostMap(accessToken);
if (response.status === "success") {
message.success(
NotificationsManager.success(
`Price data reloaded successfully! ${response.models_count || 0} models updated.`
);
onReloadSuccess?.();
// Refresh status after successful reload
await fetchReloadStatus();
} else {
NotificationManager.fromBackend("Failed to reload price data");
NotificationsManager.fromBackend("Failed to reload price data");
}
} catch (error) {
console.error("Error reloading price data:", error);
NotificationManager.fromBackend("Failed to reload price data. Please try again.");
NotificationsManager.fromBackend("Failed to reload price data. Please try again.");
} finally {
setIsLoading(false);
}
};
const handleScheduleReload = async () => {
if (!accessToken) {
NotificationManager.fromBackend("No access token available");
NotificationsManager.fromBackend("No access token available");
return;
}
if (hours <= 0) {
NotificationManager.fromBackend("Hours must be greater than 0");
NotificationsManager.fromBackend("Hours must be greater than 0");
return;
}
@@ -119,15 +119,15 @@ const PriceDataReload: React.FC<PriceDataReloadProps> = ({
const response = await scheduleModelCostMapReload(accessToken, hours);
if (response.status === "success") {
message.success(`Periodic reload scheduled for every ${hours} hours`);
NotificationsManager.success(`Periodic reload scheduled for every ${hours} hours`);
setShowScheduleModal(false);
await fetchReloadStatus();
} else {
NotificationManager.fromBackend("Failed to schedule periodic reload");
NotificationsManager.fromBackend("Failed to schedule periodic reload");
}
} catch (error) {
console.error("Error scheduling reload:", error);
NotificationManager.fromBackend("Failed to schedule periodic reload. Please try again.");
NotificationsManager.fromBackend("Failed to schedule periodic reload. Please try again.");
} finally {
setIsScheduling(false);
}
@@ -135,7 +135,7 @@ const PriceDataReload: React.FC<PriceDataReloadProps> = ({
const handleCancelReload = async () => {
if (!accessToken) {
NotificationManager.fromBackend("No access token available");
NotificationsManager.fromBackend("No access token available");
return;
}
@@ -144,14 +144,14 @@ const PriceDataReload: React.FC<PriceDataReloadProps> = ({
const response = await cancelModelCostMapReload(accessToken);
if (response.status === "success") {
message.success("Periodic reload cancelled successfully");
NotificationsManager.success("Periodic reload cancelled successfully");
await fetchReloadStatus();
} else {
NotificationManager.fromBackend("Failed to cancel periodic reload");
NotificationsManager.fromBackend("Failed to cancel periodic reload");
}
} catch (error) {
console.error("Error cancelling reload:", error);
NotificationManager.fromBackend("Failed to cancel periodic reload. Please try again.");
NotificationsManager.fromBackend("Failed to cancel periodic reload. Please try again.");
} finally {
setIsCancelling(false);
}
@@ -6,7 +6,7 @@ import { getPromptsList, PromptSpec, ListPromptsResponse, deletePromptCall } fro
import PromptTable from "./prompts/prompt_table"
import PromptInfoView from "./prompts/prompt_info"
import AddPromptForm from "./prompts/add_prompt_form"
import NotificationManager from "./molecules/notifications_manager"
import NotificationsManager from "./molecules/notifications_manager"
import { isAdminRole } from "@/utils/roles"
interface PromptsProps {
@@ -74,11 +74,11 @@ const PromptsPanel: React.FC<PromptsProps> = ({ accessToken, userRole }) => {
setIsDeleting(true)
try {
await deletePromptCall(accessToken, promptToDelete.id)
message.success(`Prompt "${promptToDelete.name}" deleted successfully`)
NotificationsManager.success(`Prompt "${promptToDelete.name}" deleted successfully`)
fetchPrompts() // Refresh the list
} catch (error) {
console.error("Error deleting prompt:", error)
NotificationManager.fromBackend("Failed to delete prompt")
NotificationsManager.fromBackend("Failed to delete prompt")
} finally {
setIsDeleting(false)
setPromptToDelete(null)
@@ -4,7 +4,7 @@ import { TextInput } from "@tremor/react"
import { UploadOutlined } from "@ant-design/icons"
import type { UploadFile, UploadProps } from "antd"
import { convertPromptFileToJson, createPromptCall } from "../networking"
import NotificationManager from "../molecules/notifications_manager"
import NotificationsManager from "../molecules/notifications_manager"
const { Option } = Select
@@ -45,12 +45,12 @@ const AddPromptForm: React.FC<AddPromptFormProps> = ({
console.log("values: ", values)
if (!accessToken) {
NotificationManager.fromBackend("Access token is required")
NotificationsManager.fromBackend("Access token is required")
return
}
if (promptIntegration === "dotprompt" && fileList.length === 0) {
NotificationManager.fromBackend("Please upload a .prompt file")
NotificationsManager.fromBackend("Please upload a .prompt file")
return
}
@@ -80,7 +80,7 @@ const AddPromptForm: React.FC<AddPromptFormProps> = ({
}
} catch (conversionError) {
console.error("Error converting prompt file:", conversionError)
NotificationManager.fromBackend("Failed to convert prompt file to JSON")
NotificationsManager.fromBackend("Failed to convert prompt file to JSON")
setLoading(false)
return
}
@@ -89,12 +89,12 @@ const AddPromptForm: React.FC<AddPromptFormProps> = ({
// Create the prompt
try {
await createPromptCall(accessToken, promptData)
message.success("Prompt created successfully!")
NotificationsManager.success("Prompt created successfully!")
handleCancel()
onSuccess()
} catch (createError) {
console.error("Error creating prompt:", createError)
NotificationManager.fromBackend("Failed to create prompt")
NotificationsManager.fromBackend("Failed to create prompt")
}
} catch (error) {
@@ -107,7 +107,7 @@ const AddPromptForm: React.FC<AddPromptFormProps> = ({
const uploadProps: UploadProps = {
beforeUpload: (file) => {
if (!file.name.endsWith('.prompt')) {
NotificationManager.fromBackend('Please upload a .prompt file')
NotificationsManager.fromBackend('Please upload a .prompt file')
return false
}
return false // Prevent automatic upload
@@ -17,7 +17,7 @@ import { ArrowLeftIcon, TrashIcon } from "@heroicons/react/outline"
import { getPromptInfo, PromptInfoResponse, PromptSpec, PromptTemplateBase, deletePromptCall } from "@/components/networking"
import { copyToClipboard as utilCopyToClipboard } from "@/utils/dataUtils"
import { CheckIcon, CopyIcon } from "lucide-react"
import NotificationManager from "../molecules/notifications_manager"
import NotificationsManager from "../molecules/notifications_manager"
export interface PromptInfoProps {
promptId: string
@@ -45,7 +45,7 @@ const PromptInfoView: React.FC<PromptInfoProps> = ({ promptId, onClose, accessTo
setPromptTemplate(response.raw_prompt_template)
setRawApiResponse(response) // Store the raw response for the Raw JSON tab
} catch (error) {
NotificationManager.fromBackend("Failed to load prompt information")
NotificationsManager.fromBackend("Failed to load prompt information")
console.error("Error fetching prompt info:", error)
} finally {
setLoading(false)
@@ -91,12 +91,12 @@ const PromptInfoView: React.FC<PromptInfoProps> = ({ promptId, onClose, accessTo
setIsDeleting(true)
try {
await deletePromptCall(accessToken, promptData.prompt_id)
message.success(`Prompt "${promptData.prompt_id}" deleted successfully`)
NotificationsManager.success(`Prompt "${promptData.prompt_id}" deleted successfully`)
onDelete?.() // Call the callback to refresh the parent component
onClose() // Close the info view
} catch (error) {
console.error("Error deleting prompt:", error)
NotificationManager.fromBackend("Failed to delete prompt")
NotificationsManager.fromBackend("Failed to delete prompt")
} finally {
setIsDeleting(false)
setShowDeleteConfirm(false)
@@ -19,6 +19,7 @@ import { MessageType } from "./chat_ui/types";
import { getProviderLogoAndName } from "./provider_info_helpers";
import Navbar from "./navbar";
import { ThemeProvider } from "@/contexts/ThemeContext";
import NotificationsManager from "./molecules/notifications_manager";
// Simple approach without react-markdown dependency
interface ModelGroupInfo {
@@ -223,7 +224,7 @@ const PublicModelHub: React.FC<PublicModelHubProps> = ({ accessToken }) => {
const copyToClipboard = (text: string) => {
navigator.clipboard.writeText(text);
message.success("Copied to clipboard!");
NotificationsManager.success("Copied to clipboard!");
};
const formatCapabilityName = (key: string) => {
@@ -4,6 +4,7 @@ import React, { useState, useEffect, useRef } from "react";
import { Modal, Form, Input, Select, InputNumber, message } from "antd";
import { Button } from "@tremor/react";
import { userRequestModelCall } from "./networking";
import NotificationsManager from "./molecules/notifications_manager";
const { Option } = Select;
@@ -33,7 +34,7 @@ const RequestAccess: React.FC<RequestAccessProps> = ({ userModels, accessToken,
const handleRequestAccess = async (formValues: Record<string, any>) => {
try {
message.info("Requesting access");
NotificationsManager.info("Requesting access");
// Extract form values
const { selectedModel, accessReason } = formValues;
@@ -27,7 +27,7 @@ import { modelInfoCall } from "../networking";
import { tagCreateCall, tagListCall, tagDeleteCall } from "../networking";
import { Tag } from "./types";
import TagTable from "./TagTable";
import NotificationManager from "../molecules/notifications_manager";
import NotificationsManager from "../molecules/notifications_manager";
interface ModelInfo {
model_name: string;
@@ -68,7 +68,7 @@ const TagManagement: React.FC<TagProps> = ({
setTags(Object.values(response));
} catch (error) {
console.error("Error fetching tags:", error);
NotificationManager.fromBackend("Error fetching tags: " + error);
NotificationsManager.fromBackend("Error fetching tags: " + error);
}
};
@@ -86,13 +86,13 @@ const TagManagement: React.FC<TagProps> = ({
description: formValues.description,
models: formValues.allowed_llms,
});
message.success("Tag created successfully");
NotificationsManager.success("Tag created successfully");
setIsCreateModalVisible(false);
form.resetFields();
fetchTags();
} catch (error) {
console.error("Error creating tag:", error);
NotificationManager.fromBackend("Error creating tag: " + error);
NotificationsManager.fromBackend("Error creating tag: " + error);
}
};
@@ -105,11 +105,11 @@ const TagManagement: React.FC<TagProps> = ({
if (!accessToken || !tagToDelete) return;
try {
await tagDeleteCall(accessToken, tagToDelete);
message.success("Tag deleted successfully");
NotificationsManager.success("Tag deleted successfully");
fetchTags();
} catch (error) {
console.error("Error deleting tag:", error);
NotificationManager.fromBackend("Error deleting tag: " + error);
NotificationsManager.fromBackend("Error deleting tag: " + error);
}
setIsDeleteModalOpen(false);
setTagToDelete(null);
@@ -125,7 +125,7 @@ const TagManagement: React.FC<TagProps> = ({
}
} catch (error) {
console.error("Error fetching models:", error);
NotificationManager.fromBackend("Error fetching models: " + error);
NotificationsManager.fromBackend("Error fetching models: " + error);
}
};
fetchModels();
@@ -6,7 +6,7 @@ import { fetchUserModels } from "../organisms/create_key_button"
import { getModelDisplayName } from "../key_team_helpers/fetch_available_models_team_key"
import { tagInfoCall, tagUpdateCall } from "../networking"
import { Tag, TagInfoResponse } from "./types"
import NotificationManager from "../molecules/notifications_manager";
import NotificationsManager from "../molecules/notifications_manager";
interface TagInfoViewProps {
tagId: string
@@ -39,7 +39,7 @@ const TagInfoView: React.FC<TagInfoViewProps> = ({ tagId, onClose, accessToken,
}
} catch (error) {
console.error("Error fetching tag details:", error)
NotificationManager.fromBackend("Error fetching tag details: " + error)
NotificationsManager.fromBackend("Error fetching tag details: " + error)
}
}
@@ -63,12 +63,12 @@ const TagInfoView: React.FC<TagInfoViewProps> = ({ tagId, onClose, accessToken,
description: values.description,
models: values.models,
})
message.success("Tag updated successfully")
NotificationsManager.success("Tag updated successfully")
setIsEditing(false)
fetchTagDetails()
} catch (error) {
console.error("Error updating tag:", error)
NotificationManager.fromBackend("Error updating tag: " + error)
NotificationsManager.fromBackend("Error updating tag: " + error)
}
}
@@ -13,7 +13,7 @@ import {
} from "@tremor/react";
import { message } from 'antd';
import { availableTeamListCall, teamMemberAddCall } from "../networking";
import NotificationManager from "../molecules/notifications_manager";
import NotificationsManager from "../molecules/notifications_manager";
interface AvailableTeam {
team_id: string;
@@ -60,12 +60,12 @@ const AvailableTeamsPanel: React.FC<AvailableTeamsProps> = ({
}
);
message.success('Successfully joined team');
NotificationsManager.success('Successfully joined team');
// Update available teams list
setAvailableTeams(teams => teams.filter(team => team.team_id !== teamId));
} catch (error) {
console.error('Error joining team:', error);
NotificationManager.fromBackend('Failed to join team');
NotificationsManager.fromBackend('Failed to join team');
}
};
@@ -2,7 +2,7 @@ import React, { useState, useEffect } from 'react';
import { Modal, Form, Button as AntButton, message } from 'antd';
import { Select, SelectItem, TextInput } from "@tremor/react";
import { Card, Text } from "@tremor/react";
import NotificationManager from "../molecules/notifications_manager";
import NotificationsManager from "../molecules/notifications_manager";
import NumericalInput from "../shared/numerical_input";
interface BaseMember {
@@ -98,7 +98,7 @@ const MemberModal = <T extends BaseMember>({
console.log("Submitting form data:", formData);
onSubmit(formData);
form.resetFields();
// message.success(`Successfully ${mode === 'add' ? 'added' : 'updated'} member`);
// NotificationsManager.success(`Successfully ${mode === 'add' ? 'added' : 'updated'} member`);
} catch (error) {
// NotificationManager.fromBackend('Failed to submit form');
console.error('Form submission error:', error);
@@ -15,7 +15,7 @@ import { Button, message, Checkbox, Empty } from "antd"
import { ReloadOutlined, SaveOutlined } from "@ant-design/icons"
import { getTeamPermissionsCall, teamPermissionsUpdateCall } from "@/components/networking"
import { getPermissionInfo } from "./permission_definitions"
import NotificationManager from "../molecules/notifications_manager";
import NotificationsManager from "../molecules/notifications_manager";
interface MemberPermissionsProps {
teamId: string
@@ -41,7 +41,7 @@ const MemberPermissions: React.FC<MemberPermissionsProps> = ({ teamId, accessTok
setSelectedPermissions(teamPermissions)
setHasChanges(false)
} catch (error) {
NotificationManager.fromBackend("Failed to load permissions")
NotificationsManager.fromBackend("Failed to load permissions")
console.error("Error fetching permissions:", error)
} finally {
setLoading(false)
@@ -65,10 +65,10 @@ const MemberPermissions: React.FC<MemberPermissionsProps> = ({ teamId, accessTok
if (!accessToken) return
setSaving(true)
await teamPermissionsUpdateCall(accessToken, teamId, selectedPermissions)
message.success("Permissions updated successfully")
NotificationsManager.success("Permissions updated successfully")
setHasChanges(false)
} catch (error) {
NotificationManager.fromBackend("Failed to update permissions")
NotificationsManager.fromBackend("Failed to update permissions")
console.error("Error updating permissions:", error)
} finally {
setSaving(false)
@@ -54,7 +54,7 @@ import LoggingSettingsView from "../logging_settings_view";
import { fetchMCPAccessGroups } from "../networking";
import { CheckIcon, CopyIcon } from "lucide-react";
import { copyToClipboard as utilCopyToClipboard } from "../../utils/dataUtils"
import NotificationManager from "../molecules/notifications_manager";
import NotificationsManager from "../molecules/notifications_manager";
export interface TeamMembership {
user_id: string;
@@ -163,7 +163,7 @@ const TeamInfoView: React.FC<TeamInfoProps> = ({
const response = await teamInfoCall(accessToken, teamId);
setTeamData(response);
} catch (error) {
NotificationManager.fromBackend("Failed to load team information");
NotificationsManager.fromBackend("Failed to load team information");
console.error("Error fetching team info:", error);
} finally {
setLoading(false);
@@ -215,7 +215,7 @@ const TeamInfoView: React.FC<TeamInfoProps> = ({
await teamMemberAddCall(accessToken, teamId, member);
message.success("Team member added successfully");
NotificationsManager.success("Team member added successfully");
setIsAddMemberModalVisible(false);
form.resetFields();
@@ -239,7 +239,7 @@ const TeamInfoView: React.FC<TeamInfoProps> = ({
errMsg = error.message;
}
NotificationManager.fromBackend(errMsg);
NotificationsManager.fromBackend(errMsg);
console.error("Error adding team member:", error);
}
};
@@ -263,7 +263,7 @@ const TeamInfoView: React.FC<TeamInfoProps> = ({
await teamMemberUpdateCall(accessToken, teamId, member);
message.success("Team member updated successfully");
NotificationsManager.success("Team member updated successfully");
setIsEditMemberModalVisible(false);
// Fetch updated team info
@@ -288,7 +288,7 @@ const TeamInfoView: React.FC<TeamInfoProps> = ({
message.destroy(); // Remove all existing toasts
NotificationManager.fromBackend(errMsg);
NotificationsManager.fromBackend(errMsg);
console.error("Error updating team member:", error);
}
};
@@ -301,7 +301,7 @@ const TeamInfoView: React.FC<TeamInfoProps> = ({
await teamMemberDeleteCall(accessToken, teamId, member);
message.success("Team member removed successfully");
NotificationsManager.success("Team member removed successfully");
// Fetch updated team info
const updatedTeamData = await teamInfoCall(accessToken, teamId);
@@ -310,7 +310,7 @@ const TeamInfoView: React.FC<TeamInfoProps> = ({
// Notify parent component of the update
onUpdate(updatedTeamData);
} catch (error) {
NotificationManager.fromBackend("Failed to remove team member");
NotificationsManager.fromBackend("Failed to remove team member");
console.error("Error removing team member:", error);
}
};
@@ -323,7 +323,7 @@ const TeamInfoView: React.FC<TeamInfoProps> = ({
try {
parsedMetadata = values.metadata ? JSON.parse(values.metadata) : {};
} catch (e) {
NotificationManager.fromBackend("Invalid JSON in metadata field");
NotificationsManager.fromBackend("Invalid JSON in metadata field");
return;
}
@@ -381,7 +381,7 @@ const TeamInfoView: React.FC<TeamInfoProps> = ({
const response = await teamUpdateCall(accessToken, updateData);
message.success("Team settings updated successfully");
NotificationsManager.success("Team settings updated successfully");
setIsEditing(false);
fetchTeamInfo();
} catch (error) {
@@ -75,6 +75,7 @@ import { formatNumberWithCommas } from "../utils/dataUtils";
import { AlertTriangleIcon, XIcon } from 'lucide-react';
import MCPServerSelector from "./mcp_server_management/MCPServerSelector";
import ModelAliasManager from "./common_components/ModelAliasManager";
import NotificationsManager from "./molecules/notifications_manager";
interface TeamProps {
teams: Team[] | null;
@@ -111,7 +112,6 @@ import {
v2TeamListCall,
} from "./networking";
import { updateExistingKeys } from "@/utils/dataUtils";
import NotificationManager from "./molecules/notifications_manager";
interface TeamInfo {
members_with_roles: Member[];
@@ -377,7 +377,7 @@ const Teams: React.FC<TeamProps> = ({
);
}
message.info("Creating Team");
NotificationsManager.info("Creating Team");
// Handle logging settings in metadata
if (loggingSettings.length > 0) {
@@ -457,7 +457,7 @@ const Teams: React.FC<TeamProps> = ({
setTeams([response]);
}
console.log(`response for team create call: ${response}`);
message.success("Team created");
NotificationsManager.success("Team created");
form.resetFields();
setLoggingSettings([]);
setModelAliases({});
@@ -465,7 +465,7 @@ const Teams: React.FC<TeamProps> = ({
}
} catch (error) {
console.error("Error creating the team:", error);
NotificationManager.fromBackend("Error creating the team: " + error);
NotificationsManager.fromBackend("Error creating the team: " + error);
}
};
@@ -54,15 +54,15 @@ import { Providers, provider_map, getPlaceholder, getProviderModels } from "../p
import ModelInfoView from "../model_info_view"
import AddModelTab from "../add_model/add_model_tab"
import { ModelDataTable } from "../model_dashboard/table"
import { columns } from "../molecules/models/columns"
import PriceDataReload from "../price_data_reload"
import HealthCheckComponent from "../model_dashboard/HealthCheckComponent"
import PassThroughSettings from "../pass_through_settings"
import ModelGroupAliasSettings from "../model_group_alias_settings"
import { all_admin_roles } from "@/utils/roles"
import { Table as TableInstance } from "@tanstack/react-table"
import NotificationManager from "../molecules/notifications_manager"
import { ModelDataTable } from "../model_dashboard/table";
import { columns } from "../molecules/models/columns";
import PriceDataReload from "../price_data_reload";
import HealthCheckComponent from "../model_dashboard/HealthCheckComponent";
import PassThroughSettings from "../pass_through_settings";
import ModelGroupAliasSettings from "../model_group_alias_settings";
import { all_admin_roles } from "@/utils/roles";
import { Table as TableInstance } from "@tanstack/react-table";
import NotificationsManager from "../molecules/notifications_manager";
interface ModelDashboardProps {
accessToken: string | null
@@ -386,9 +386,9 @@ const ModelDashboard: React.FC<ModelDashboardProps> = ({
console.log(info.file, info.fileList)
}
if (info.file.status === "done") {
message.success(`${info.file.name} file uploaded successfully`)
NotificationsManager.success(`${info.file.name} file uploaded successfully`);
} else if (info.file.status === "error") {
NotificationManager.fromBackend(`${info.file.name} file upload failed.`)
NotificationsManager.fromBackend(`${info.file.name} file upload failed.`);
}
},
}
@@ -416,20 +416,20 @@ const ModelDashboard: React.FC<ModelDashboardProps> = ({
if (globalRetryPolicy) {
payload.router_settings.retry_policy = globalRetryPolicy
}
message.success("Global retry settings saved successfully")
NotificationsManager.success("Global retry settings saved successfully");
} else {
// Only update model group retry policy
console.log("Saving model group retry policy for", selectedModelGroup, ":", modelGroupRetryPolicy)
if (modelGroupRetryPolicy) {
payload.router_settings.model_group_retry_policy = modelGroupRetryPolicy
}
message.success(`Retry settings saved successfully for ${selectedModelGroup}`)
NotificationsManager.success(`Retry settings saved successfully for ${selectedModelGroup}`);
}
await setCallbacksCall(accessToken, payload)
} catch (error) {
console.error("Failed to save retry settings:", error)
NotificationManager.fromBackend("Failed to save retry settings")
console.error("Failed to save retry settings:", error);
NotificationsManager.fromBackend("Failed to save retry settings");
}
}
@@ -719,11 +719,11 @@ const ModelDashboard: React.FC<ModelDashboardProps> = ({
const runHealthCheck = async () => {
try {
message.info("Running health check...")
setIsHealthCheckLoading(true)
setHealthCheckResponse(null)
const response = await healthCheckCall(accessToken)
setHealthCheckResponse(response)
NotificationsManager.info("Running health check...");
setIsHealthCheckLoading(true);
setHealthCheckResponse(null);
const response = await healthCheckCall(accessToken);
setHealthCheckResponse(response);
} catch (error) {
console.error("Error running health check:", error)
setHealthCheckResponse("Error running health check")
@@ -892,17 +892,14 @@ const ModelDashboard: React.FC<ModelDashboardProps> = ({
handleAddModelSubmit(values, accessToken, addModelForm, handleRefreshClick)
})
.catch((error: any) => {
console.error("❌ Validation failed:", error)
console.error("Form errors:", error.errorFields)
const errorMessages =
error.errorFields
?.map((field: any) => {
return `${field.name.join(".")}: ${field.errors.join(", ")}`
})
.join(" | ") || "Unknown validation error"
NotificationManager.fromBackend(`Please fill in the following required fields: ${errorMessages}`)
})
}
console.error("❌ Validation failed:", error);
console.error("Form errors:", error.errorFields);
const errorMessages = error.errorFields?.map((field: any) => {
return `${field.name.join('.')}: ${field.errors.join(', ')}`;
}).join(' | ') || 'Unknown validation error';
NotificationsManager.fromBackend(`Please fill in the following required fields: ${errorMessages}`);
});
};
console.log(`selectedProvider: ${selectedProvider}`)
console.log(`providerModels.length: ${providerModels.length}`)
@@ -3,7 +3,7 @@ import { Button, Select, Tabs, message } from 'antd';
import { CopyOutlined } from '@ant-design/icons';
import { Title } from '@tremor/react';
import { transformRequestCall } from './networking';
import NotificationManager from "./molecules/notifications_manager";
import NotificationsManager from "./molecules/notifications_manager";
interface TransformRequestPanelProps {
accessToken: string | null;
}
@@ -68,7 +68,7 @@ ${formattedBody}
try {
requestBody = JSON.parse(originalRequestJSON);
} catch (e) {
NotificationManager.fromBackend('Invalid JSON in request body');
NotificationsManager.fromBackend('Invalid JSON in request body');
setIsLoading(false);
return;
}
@@ -81,7 +81,7 @@ ${formattedBody}
// Make the API call using fetch
if (!accessToken) {
NotificationManager.fromBackend('No access token found');
NotificationsManager.fromBackend('No access token found');
setIsLoading(false);
return;
}
@@ -99,17 +99,17 @@ ${formattedBody}
// Update state with the formatted curl command
setTransformedResponse(formattedCurl);
message.success('Request transformed successfully');
NotificationsManager.success('Request transformed successfully');
} else {
// Handle the case where the API returns a different format
// Try to extract the parts from a string response if needed
const rawText = typeof data === 'string' ? data : JSON.stringify(data);
setTransformedResponse(rawText);
message.info('Transformed request received in unexpected format');
NotificationsManager.info('Transformed request received in unexpected format');
}
} catch (err) {
console.error('Error transforming request:', err);
NotificationManager.fromBackend('Failed to transform request');
NotificationsManager.fromBackend('Failed to transform request');
} finally {
setIsLoading(false);
}
@@ -258,7 +258,7 @@ ${formattedBody}
size="small"
onClick={() => {
navigator.clipboard.writeText(transformedResponse || '');
message.success('Copied to clipboard');
NotificationsManager.success('Copied to clipboard');
}}
/>
</div>
@@ -9,7 +9,7 @@ import {
import { message } from "antd"
import { useTheme } from "@/contexts/ThemeContext"
import { getProxyBaseUrl } from "@/components/networking"
import NotificationManager from "./molecules/notifications_manager";
import NotificationsManager from "./molecules/notifications_manager";
interface UIThemeSettingsProps {
userID: string | null;
@@ -73,14 +73,14 @@ const UIThemeSettings: React.FC<UIThemeSettingsProps> = ({
});
if (response.ok) {
message.success("Logo settings updated successfully!");
NotificationsManager.success("Logo settings updated successfully!");
setLogoUrl(logoUrlInput || null);
} else {
throw new Error("Failed to update settings");
}
} catch (error) {
console.error("Error updating logo settings:", error);
NotificationManager.fromBackend("Failed to update logo settings");
NotificationsManager.fromBackend("Failed to update logo settings");
} finally {
setLoading(false);
}
@@ -107,13 +107,13 @@ const UIThemeSettings: React.FC<UIThemeSettingsProps> = ({
});
if (response.ok) {
message.success("Logo reset to default!");
NotificationsManager.success("Logo reset to default!");
} else {
throw new Error("Failed to reset logo");
}
} catch (error) {
console.error("Error resetting logo:", error);
NotificationManager.fromBackend("Failed to reset logo");
NotificationsManager.fromBackend("Failed to reset logo");
} finally {
setLoading(false);
}
@@ -14,7 +14,7 @@ import {
TableRow,
TableCell
} from "@tremor/react";
import NotificationManager from "./molecules/notifications_manager";
import NotificationsManager from "./molecules/notifications_manager";
interface UsefulLinksManagementProps {
accessToken: string | null;
@@ -118,7 +118,7 @@ const UsefulLinksManagement: React.FC<UsefulLinksManagementProps> = ({
return true;
} catch (error) {
console.error("Error saving links:", error);
NotificationManager.fromBackend(`Failed to save links - ${error}`);
NotificationsManager.fromBackend(`Failed to save links - ${error}`);
return false;
}
};
@@ -130,13 +130,13 @@ const UsefulLinksManagement: React.FC<UsefulLinksManagementProps> = ({
try {
new URL(newLink.url);
} catch {
NotificationManager.fromBackend("Please enter a valid URL");
NotificationsManager.fromBackend("Please enter a valid URL");
return;
}
// Check for duplicate display names
if (links.some(link => link.displayName === newLink.displayName)) {
NotificationManager.fromBackend("A link with this display name already exists");
NotificationsManager.fromBackend("A link with this display name already exists");
return;
}
@@ -151,7 +151,7 @@ const UsefulLinksManagement: React.FC<UsefulLinksManagementProps> = ({
if (await saveLinksToBackend(updatedLinks)) {
setLinks(updatedLinks);
setNewLink({ url: "", displayName: "" });
message.success("Link added successfully");
NotificationsManager.success("Link added successfully");
}
};
@@ -166,13 +166,13 @@ const UsefulLinksManagement: React.FC<UsefulLinksManagementProps> = ({
try {
new URL(editingLink.url);
} catch {
NotificationManager.fromBackend("Please enter a valid URL");
NotificationsManager.fromBackend("Please enter a valid URL");
return;
}
// Check for duplicate display names (excluding current link)
if (links.some(link => link.id !== editingLink.id && link.displayName === editingLink.displayName)) {
NotificationManager.fromBackend("A link with this display name already exists");
NotificationsManager.fromBackend("A link with this display name already exists");
return;
}
@@ -183,7 +183,7 @@ const UsefulLinksManagement: React.FC<UsefulLinksManagementProps> = ({
if (await saveLinksToBackend(updatedLinks)) {
setLinks(updatedLinks);
setEditingLink(null);
message.success("Link updated successfully");
NotificationsManager.success("Link updated successfully");
}
};
@@ -196,7 +196,7 @@ const UsefulLinksManagement: React.FC<UsefulLinksManagementProps> = ({
if (await saveLinksToBackend(updatedLinks)) {
setLinks(updatedLinks);
message.success("Link deleted successfully");
NotificationsManager.success("Link deleted successfully");
}
};
@@ -17,7 +17,7 @@ import {
import { InfoCircleOutlined } from '@ant-design/icons';
import { CredentialItem, vectorStoreCreateCall } from "../networking";
import { VectorStoreProviders, vectorStoreProviderLogoMap, vectorStoreProviderMap, getProviderSpecificFields, VectorStoreFieldConfig } from "../vector_store_providers";
import NotificationManager from "../molecules/notifications_manager";
import NotificationsManager from "../molecules/notifications_manager";
interface VectorStoreFormProps {
isVisible: boolean;
@@ -46,7 +46,7 @@ const VectorStoreForm: React.FC<VectorStoreFormProps> = ({
try {
metadata = metadataJson.trim() ? JSON.parse(metadataJson) : {};
} catch (e) {
NotificationManager.fromBackend("Invalid JSON in metadata field");
NotificationsManager.fromBackend("Invalid JSON in metadata field");
return;
}
@@ -70,13 +70,13 @@ const VectorStoreForm: React.FC<VectorStoreFormProps> = ({
payload["litellm_params"] = litellmParams;
await vectorStoreCreateCall(accessToken, payload);
message.success("Vector store created successfully");
NotificationsManager.success("Vector store created successfully");
form.resetFields();
setMetadataJson("{}");
onSuccess();
} catch (error) {
console.error("Error creating vector store:", error);
NotificationManager.fromBackend("Error creating vector store: " + error);
NotificationsManager.fromBackend("Error creating vector store: " + error);
}
};
@@ -2,7 +2,7 @@ import React, { useState } from "react";
import { Button, Input, Card, Typography, Spin, message, Divider } from "antd";
import { SendOutlined, DatabaseOutlined, LoadingOutlined, DownOutlined, RightOutlined } from "@ant-design/icons";
import { vectorStoreSearchCall } from "../networking";
import NotificationManager from "../molecules/notifications_manager";
import NotificationsManager from "../molecules/notifications_manager";
const { TextArea } = Input;
const { Text, Title } = Typography;
@@ -67,7 +67,7 @@ export const VectorStoreTester: React.FC<VectorStoreTesterProps> = ({
setQuery("");
} catch (error) {
console.error("Error searching vector store:", error);
NotificationManager.fromBackend("Failed to search vector store");
NotificationsManager.fromBackend("Failed to search vector store");
} finally {
setIsLoading(false);
}
@@ -87,7 +87,7 @@ export const VectorStoreTester: React.FC<VectorStoreTesterProps> = ({
const clearHistory = () => {
setSearchHistory([]);
setExpandedResults({});
message.success("Search history cleared");
NotificationsManager.success("Search history cleared");
};
const toggleResultExpansion = (historyIndex: number, resultIndex: number) => {
@@ -19,7 +19,7 @@ import VectorStoreForm from "./VectorStoreForm";
import DeleteModal from "./DeleteModal";
import VectorStoreInfoView from "./vector_store_info";
import { isAdminRole } from "@/utils/roles";
import NotificationManager from "../molecules/notifications_manager";
import NotificationsManager from "../molecules/notifications_manager";
interface VectorStoreProps {
accessToken: string | null;
@@ -49,7 +49,7 @@ const VectorStoreManagement: React.FC<VectorStoreProps> = ({
setVectorStores(response.data || []);
} catch (error) {
console.error("Error fetching vector stores:", error);
NotificationManager.fromBackend("Error fetching vector stores: " + error);
NotificationsManager.fromBackend("Error fetching vector stores: " + error);
}
};
@@ -61,7 +61,7 @@ const VectorStoreManagement: React.FC<VectorStoreProps> = ({
setCredentials(response.credentials || []);
} catch (error) {
console.error("Error fetching credentials:", error);
NotificationManager.fromBackend("Error fetching credentials: " + error);
NotificationsManager.fromBackend("Error fetching credentials: " + error);
}
};
@@ -97,11 +97,11 @@ const VectorStoreManagement: React.FC<VectorStoreProps> = ({
if (!accessToken || !vectorStoreToDelete) return;
try {
await vectorStoreDeleteCall(accessToken, vectorStoreToDelete);
message.success("Vector store deleted successfully");
NotificationsManager.success("Vector store deleted successfully");
fetchVectorStores();
} catch (error) {
console.error("Error deleting vector store:", error);
NotificationManager.fromBackend("Error deleting vector store: " + error);
NotificationsManager.fromBackend("Error deleting vector store: " + error);
}
setIsDeleteModalOpen(false);
setVectorStoreToDelete(null);
@@ -25,7 +25,7 @@ import { vectorStoreInfoCall, vectorStoreUpdateCall, credentialListCall, Credent
import { VectorStore } from "./types";
import { Providers, providerLogoMap, provider_map } from "../provider_info_helpers";
import VectorStoreTester from "./VectorStoreTester";
import NotificationManager from "../molecules/notifications_manager";
import NotificationsManager from "../molecules/notifications_manager";
interface VectorStoreInfoViewProps {
vectorStoreId: string;
@@ -75,7 +75,7 @@ const VectorStoreInfoView: React.FC<VectorStoreInfoViewProps> = ({
}
} catch (error) {
console.error("Error fetching vector store details:", error);
NotificationManager.fromBackend("Error fetching vector store details: " + error);
NotificationsManager.fromBackend("Error fetching vector store details: " + error);
}
};
@@ -103,7 +103,7 @@ const VectorStoreInfoView: React.FC<VectorStoreInfoViewProps> = ({
try {
metadata = metadataString ? JSON.parse(metadataString) : {};
} catch (e) {
NotificationManager.fromBackend("Invalid JSON in metadata field");
NotificationsManager.fromBackend("Invalid JSON in metadata field");
return;
}
@@ -116,12 +116,12 @@ const VectorStoreInfoView: React.FC<VectorStoreInfoViewProps> = ({
};
await vectorStoreUpdateCall(accessToken, updateData);
message.success("Vector store updated successfully");
NotificationsManager.success("Vector store updated successfully");
setIsEditing(false);
fetchVectorStoreDetails();
} catch (error) {
console.error("Error updating vector store:", error);
NotificationManager.fromBackend("Error updating vector store: " + error);
NotificationsManager.fromBackend("Error updating vector store: " + error);
}
};
@@ -1,6 +1,6 @@
import { LogEntry } from "./columns";
import { message } from "antd";
import NotificationManager from "../molecules/notifications_manager";
import NotificationsManager from "../molecules/notifications_manager";
interface RequestResponsePanelProps {
row: {
@@ -56,18 +56,18 @@ export function RequestResponsePanel({
const handleCopyRequest = async () => {
const success = await copyToClipboard(JSON.stringify(getRawRequest(), null, 2));
if (success) {
message.success('Request copied to clipboard');
NotificationsManager.success('Request copied to clipboard');
} else {
NotificationManager.fromBackend('Failed to copy request');
NotificationsManager.fromBackend('Failed to copy request');
}
};
const handleCopyResponse = async () => {
const success = await copyToClipboard(JSON.stringify(formattedResponse(), null, 2));
if (success) {
message.success('Response copied to clipboard');
NotificationsManager.success('Response copied to clipboard');
} else {
NotificationManager.fromBackend('Failed to copy response');
NotificationsManager.fromBackend('Failed to copy response');
}
};
@@ -29,7 +29,7 @@ import { useQuery, useQueryClient } from "@tanstack/react-query"
import { updateExistingKeys } from "@/utils/dataUtils"
import { useDebouncedState } from "@tanstack/react-pacer/debouncer"
import { isAdminRole } from "@/utils/roles"
import NotificationManager from "./molecules/notifications_manager"
import NotificationsManager from "./molecules/notifications_manager"
interface ViewUserDashboardProps {
accessToken: string | null
@@ -139,16 +139,16 @@ const ViewUserDashboard: React.FC<ViewUserDashboardProps> = ({ accessToken, toke
const handleResetPassword = async (userId: string) => {
if (!accessToken) {
NotificationManager.fromBackend("Access token not found")
NotificationsManager.fromBackend("Access token not found")
return
}
try {
message.success("Generating password reset link...")
NotificationsManager.success("Generating password reset link...")
const data = await invitationCreateCall(accessToken, userId)
setInvitationLinkData(data)
setIsInvitationLinkModalVisible(true)
} catch (error) {
NotificationManager.fromBackend("Failed to generate password reset link")
NotificationsManager.fromBackend("Failed to generate password reset link")
}
}
@@ -164,10 +164,10 @@ const ViewUserDashboard: React.FC<ViewUserDashboardProps> = ({ accessToken, toke
return { ...previousData, users: updatedUsers }
})
message.success("User deleted successfully")
NotificationsManager.success("User deleted successfully")
} catch (error) {
console.error("Error deleting user:", error)
NotificationManager.fromBackend("Failed to delete user")
NotificationsManager.fromBackend("Failed to delete user")
}
}
setIsDeleteModalOpen(false)
@@ -205,7 +205,7 @@ const ViewUserDashboard: React.FC<ViewUserDashboardProps> = ({ accessToken, toke
return { ...previousData, users: updatedUsers }
})
message.success(`User ${editedUser.user_id} updated successfully`)
NotificationsManager.success(`User ${editedUser.user_id} updated successfully`)
} catch (error) {
console.error("There was an error updating the user", error)
}
@@ -229,7 +229,7 @@ const ViewUserDashboard: React.FC<ViewUserDashboardProps> = ({ accessToken, toke
const handleBulkEdit = () => {
if (selectedUsers.length === 0) {
NotificationManager.fromBackend("Please select users to edit")
NotificationsManager.fromBackend("Please select users to edit")
return
}
@@ -15,7 +15,7 @@ import { UserEditView } from "../user_edit_view"
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 NotificationsManager from "../molecules/notifications_manager";
import { getBudgetDurationLabel } from "../common_components/budget_duration_dropdown";
interface UserInfoViewProps {
@@ -86,7 +86,7 @@ export default function UserInfoView({
setUserModels(availableModels)
} catch (error) {
console.error("Error fetching user data:", error)
NotificationManager.fromBackend("Failed to fetch user data")
NotificationsManager.fromBackend("Failed to fetch user data")
} finally {
setIsLoading(false)
}
@@ -97,16 +97,16 @@ export default function UserInfoView({
const handleResetPassword = async () => {
if (!accessToken) {
NotificationManager.fromBackend("Access token not found")
NotificationsManager.fromBackend("Access token not found")
return
}
try {
message.success("Generating password reset link...")
NotificationsManager.success("Generating password reset link...")
const data = await invitationCreateCall(accessToken, userId)
setInvitationLinkData(data)
setIsInvitationLinkModalVisible(true)
} catch (error) {
NotificationManager.fromBackend("Failed to generate password reset link")
NotificationsManager.fromBackend("Failed to generate password reset link")
}
}
@@ -114,14 +114,14 @@ export default function UserInfoView({
try {
if (!accessToken) return
await userDeleteCall(accessToken, [userId])
message.success("User deleted successfully")
NotificationsManager.success("User deleted successfully")
if (onDelete) {
onDelete()
}
onClose()
} catch (error) {
console.error("Error deleting user:", error)
NotificationManager.fromBackend("Failed to delete user")
NotificationsManager.fromBackend("Failed to delete user")
}
}
@@ -144,11 +144,11 @@ export default function UserInfoView({
},
})
message.success("User updated successfully")
NotificationsManager.success("User updated successfully")
setIsEditing(false)
} catch (error) {
console.error("Error updating user:", error)
NotificationManager.fromBackend("Failed to update user")
NotificationsManager.fromBackend("Failed to update user")
}
}
+3 -3
View File
@@ -1,4 +1,4 @@
import NotificationManager from "@/components/molecules/notifications_manager";
import NotificationsManager from "@/components/molecules/notifications_manager";
import { message } from "antd";
export function updateExistingKeys<Source extends Object>(
@@ -33,10 +33,10 @@ export const copyToClipboard = async (
if (!text) return false;
try {
await navigator.clipboard.writeText(text);
message.success(messageText);
NotificationsManager.success(messageText);
return true;
} catch (err) {
NotificationManager.fromBackend("Failed to copy to clipboard");
NotificationsManager.fromBackend("Failed to copy to clipboard");
console.error("Failed to copy: ", err);
return false;
}