Merge pull request #13582 from BerriAI/remove-network-response-error

Remove ambiguous network response error
This commit is contained in:
Krish Dholakia
2025-08-13 10:50:05 -07:00
committed by GitHub
68 changed files with 883 additions and 568 deletions
+3 -2
View File
@@ -21,6 +21,7 @@ import {
PlusCircleOutlined
} from "@ant-design/icons";
import { parseErrorMessage } from "./shared/errorUtils";
import NotificationManager from "./molecules/notifications_manager";
interface SCIMConfigProps {
accessToken: string | null;
@@ -51,7 +52,7 @@ const SCIMConfig: React.FC<SCIMConfigProps> = ({ accessToken, userID, proxySetti
const handleCreateSCIMToken = async (values: any) => {
if (!accessToken || !userID) {
message.error("You need to be logged in to create a SCIM token");
NotificationManager.fromBackend("You need to be logged in to create a SCIM token");
return;
}
@@ -70,7 +71,7 @@ const SCIMConfig: React.FC<SCIMConfigProps> = ({ accessToken, userID, proxySetti
message.success("SCIM token created successfully");
} catch (error: any) {
console.error("Error creating SCIM token:", error);
message.error("Failed to create SCIM token: " + parseErrorMessage(error));
NotificationManager.fromBackend("Failed to create SCIM token: " + parseErrorMessage(error));
} finally {
setIsCreatingToken(false);
}
@@ -161,7 +161,7 @@ const SSOModals: React.FC<SSOModalsProps> = ({
// Enhanced form submission handler
const handleFormSubmit = async (formValues: Record<string, any>) => {
if (!accessToken) {
message.error("No access token available");
NotificationManager.fromBackend("No access token available");
return;
}
@@ -173,14 +173,14 @@ const SSOModals: React.FC<SSOModalsProps> = ({
handleShowInstructions(formValues);
} catch (error) {
console.error("Failed to save SSO settings:", error);
message.error("Failed to save SSO settings");
NotificationManager.fromBackend("Failed to save SSO settings");
}
};
// Handle clearing SSO settings
const handleClearSSO = async () => {
if (!accessToken) {
message.error("No access token available");
NotificationManager.fromBackend("No access token available");
return;
}
@@ -216,7 +216,7 @@ const SSOModals: React.FC<SSOModalsProps> = ({
message.success("SSO settings cleared successfully");
} catch (error) {
console.error("Failed to clear SSO settings:", error);
message.error("Failed to clear SSO settings");
NotificationManager.fromBackend("Failed to clear SSO settings");
}
};
@@ -56,7 +56,7 @@ const SSOSettings: React.FC<SSOSettingsProps> = ({ accessToken, possibleUIRoles,
}
} catch (error) {
console.error("Error fetching SSO settings:", error);
message.error("Failed to fetch SSO settings");
NotificationManager.fromBackend("Failed to fetch SSO settings");
} finally {
setLoading(false);
}
@@ -81,7 +81,7 @@ const SSOSettings: React.FC<SSOSettingsProps> = ({ accessToken, possibleUIRoles,
setIsEditing(false);
} catch (error) {
console.error("Error updating SSO settings:", error);
message.error("Failed to update settings: " + error);
NotificationManager.fromBackend("Failed to update settings: " + error);
} finally {
setSaving(false);
}
@@ -4,6 +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";
interface TeamSSOSettingsProps {
accessToken: string | null;
@@ -47,7 +48,7 @@ const TeamSSOSettings: React.FC<TeamSSOSettingsProps> = ({ accessToken, userID,
}
} catch (error) {
console.error("Error fetching team SSO settings:", error);
message.error("Failed to fetch team settings");
NotificationManager.fromBackend("Failed to fetch team settings");
} finally {
setLoading(false);
}
@@ -67,7 +68,7 @@ const TeamSSOSettings: React.FC<TeamSSOSettingsProps> = ({ accessToken, userID,
message.success("Default team settings updated successfully");
} catch (error) {
console.error("Error updating team settings:", error);
message.error("Failed to update team settings");
NotificationManager.fromBackend("Failed to update team settings");
} finally {
setSaving(false);
}
@@ -2,6 +2,7 @@ import React, { useEffect, useState } from "react";
import { Form, Button as Button2, Select, message } from "antd";
import { Text, TextInput } from "@tremor/react";
import { getSSOSettings, updateSSOSettings } from "./networking";
import NotificationManager from "./molecules/notifications_manager";
interface UIAccessControlFormProps {
accessToken: string | null;
@@ -52,7 +53,7 @@ const UIAccessControlForm: React.FC<UIAccessControlFormProps> = ({ accessToken,
const handleUIAccessSubmit = async (formValues: Record<string, any>) => {
if (!accessToken) {
message.error("No access token available");
NotificationManager.fromBackend("No access token available");
return;
}
@@ -71,7 +72,7 @@ const UIAccessControlForm: React.FC<UIAccessControlFormProps> = ({ accessToken,
onSuccess();
} catch (error) {
console.error("Failed to save UI access settings:", error);
message.error("Failed to save UI access settings");
NotificationManager.fromBackend("Failed to save UI access settings");
} finally {
setLoading(false);
}
@@ -14,6 +14,7 @@ import {
message,
} from "antd";
import { fetchAvailableModels, ModelGroup } from "./chat_ui/llm_calls/fetch_models";
import NotificationManager from "./molecules/notifications_manager";
interface AddFallbacksProps {
models?: string[];
@@ -91,10 +92,10 @@ const AddFallbacks: React.FC<AddFallbacksProps> = ({
// Update routerSettings state
setRouterSettings(updatedRouterSettings);
} catch (error) {
message.error("Failed to update router settings: " + error, 20);
NotificationManager.fromBackend("Failed to update router settings: " + error);
}
message.success("router settings updated successfully");
NotificationManager.success("router settings updated successfully");
setIsModalVisible(false);
form.resetFields();
@@ -11,6 +11,7 @@ import { all_admin_roles } from "@/utils/roles";
import { handleAddAutoRouterSubmit } from "./handle_add_auto_router_submit";
import { fetchAvailableModels, ModelGroup } from "../chat_ui/llm_calls/fetch_models";
import RouterConfigBuilder from "./router_config_builder";
import NotificationManager from "../molecules/notifications_manager";
interface AddAutoRouterTabProps {
form: FormInstance;
@@ -79,12 +80,12 @@ const AddAutoRouterTab: React.FC<AddAutoRouterTabProps> = ({
// Check basic required fields first
if (!currentFormValues.auto_router_name) {
message.error("Please enter an Auto Router Name");
NotificationManager.fromBackend("Please enter an Auto Router Name");
return;
}
if (!currentFormValues.auto_router_default_model) {
message.error("Please select a Default Model");
NotificationManager.fromBackend("Please select a Default Model");
return;
}
@@ -98,7 +99,7 @@ const AddAutoRouterTab: React.FC<AddAutoRouterTabProps> = ({
// Custom validation for router config
if (!routerConfig || !routerConfig.routes || routerConfig.routes.length === 0) {
message.error("Please configure at least one route for the auto router");
NotificationManager.fromBackend("Please configure at least one route for the auto router");
return;
}
@@ -108,7 +109,7 @@ const AddAutoRouterTab: React.FC<AddAutoRouterTabProps> = ({
);
if (invalidRoutes.length > 0) {
message.error("Please ensure all routes have a target model, description, and at least one utterance");
NotificationManager.fromBackend("Please ensure all routes have a target model, description, and at least one utterance");
return;
}
@@ -139,9 +140,9 @@ const AddAutoRouterTab: React.FC<AddAutoRouterTabProps> = ({
};
return friendlyNames[fieldName] || fieldName;
});
message.error(`Please fill in the following required fields: ${missingFields.join(', ')}`);
NotificationManager.fromBackend(`Please fill in the following required fields: ${missingFields.join(', ')}`);
} else {
message.error("Please fill in all required fields");
NotificationManager.fromBackend("Please fill in all required fields");
}
});
};
@@ -1,5 +1,6 @@
import { message } from "antd";
import { modelCreateCall, Model } from "../networking";
import NotificationManager from "../molecules/notifications_manager";
export const handleAddAutoRouterSubmit = async (
values: any,
@@ -55,6 +56,6 @@ export const handleAddAutoRouterSubmit = async (
} catch (error) {
console.error("Failed to add auto router:", error);
message.error("Failed to add auto router: " + error, 10);
NotificationManager.fromBackend("Failed to add auto router: " + error);
}
};
@@ -3,6 +3,7 @@ import { provider_map, Providers } from "../provider_info_helpers";
import { modelCreateCall, Model, testConnectionRequest } from "../networking";
import React, { useState } from 'react';
import ConnectionErrorDisplay from './model_connection_test';
import NotificationManager from "../molecules/notifications_manager";
export const prepareModelAddRequest = async (
formValues: Record<string, any>,
@@ -100,9 +101,8 @@ export const prepareModelAddRequest = async (
try {
litellmExtraParams = JSON.parse(value);
} catch (error) {
message.error(
"Failed to parse LiteLLM Extra Params: " + error,
10
NotificationManager.fromBackend(
"Failed to parse LiteLLM Extra Params: " + error
);
throw new Error("Failed to parse litellm_extra_params: " + error);
}
@@ -117,9 +117,8 @@ export const prepareModelAddRequest = async (
try {
modelInfoParams = JSON.parse(value);
} catch (error) {
message.error(
"Failed to parse LiteLLM Extra Params: " + error,
10
NotificationManager.fromBackend(
"Failed to parse LiteLLM Extra Params: " + error
);
throw new Error("Failed to parse litellm_extra_params: " + error);
}
@@ -151,7 +150,7 @@ export const prepareModelAddRequest = async (
return deployments;
} catch (error) {
message.error("Failed to create model: " + error, 10);
NotificationManager.fromBackend("Failed to create model: " + error);
}
};
@@ -185,7 +184,7 @@ export const handleAddModelSubmit = async (
callback && callback();
form.resetFields();
} catch (error) {
message.error("Failed to add model: " + error, 10);
NotificationManager.fromBackend("Failed to add model: " + error);
}
};
@@ -28,6 +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";
const { Option } = Select2;
interface AddFallbacksProps {
@@ -87,7 +88,7 @@ const AddPassThroughEndpoint: React.FC<AddFallbacksProps> = ({
setIncludeSubpath(true);
setIsModalVisible(false);
} catch (error) {
message.error("Error creating pass-through endpoint: " + error, 20);
NotificationManager.fromBackend("Error creating pass-through endpoint: " + error);
} finally {
setIsLoading(false);
}
@@ -46,6 +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";
interface AdminPanelProps {
searchParams: any;
@@ -150,7 +151,7 @@ const AdminPanel: React.FC<AdminPanelProps> = ({
const handleShowAllowedIPs = async () => {
try {
if (premiumUser !== true) {
message.error(
NotificationManager.fromBackend(
"This feature is only available for premium users. Please upgrade your account."
)
return
@@ -163,7 +164,7 @@ const AdminPanel: React.FC<AdminPanelProps> = ({
}
} catch (error) {
console.error("Error fetching allowed IPs:", error);
message.error(`Failed to fetch allowed IPs ${error}`);
NotificationManager.fromBackend(`Failed to fetch allowed IPs ${error}`);
setAllowedIPs([all_ip_address_allowed]);
} finally {
if (premiumUser === true) {
@@ -183,7 +184,7 @@ const AdminPanel: React.FC<AdminPanelProps> = ({
}
} catch (error) {
console.error("Error adding IP:", error);
message.error(`Failed to add IP address ${error}`);
NotificationManager.fromBackend(`Failed to add IP address ${error}`);
} finally {
setIsAddIPModalVisible(false);
}
@@ -204,7 +205,7 @@ const AdminPanel: React.FC<AdminPanelProps> = ({
message.success('IP address deleted successfully');
} catch (error) {
console.error("Error deleting IP:", error);
message.error(`Failed to delete IP address ${error}`);
NotificationManager.fromBackend(`Failed to delete IP address ${error}`);
} finally {
setIsDeleteIPModalVisible(false);
setIPToDelete(null);
@@ -564,7 +565,7 @@ const AdminPanel: React.FC<AdminPanelProps> = ({
<div>
<Button
style={{ width: '150px' }}
onClick={() => premiumUser === true ? setIsAddSSOModalVisible(true) : message.error("Only premium users can add SSO")}
onClick={() => premiumUser === true ? setIsAddSSOModalVisible(true) : NotificationManager.fromBackend("Only premium users can add SSO")}
>
{ssoConfigured ? "Edit SSO Settings" : "Add SSO"}
</Button>
@@ -580,7 +581,7 @@ const AdminPanel: React.FC<AdminPanelProps> = ({
<div>
<Button
style={{ width: '150px' }}
onClick={() => premiumUser === true ? setIsUIAccessControlModalVisible(true) : message.error("Only premium users can configure UI access control")}
onClick={() => premiumUser === true ? setIsUIAccessControlModalVisible(true) : NotificationManager.fromBackend("Only premium users can configure UI access control")}
>
UI Access Control
</Button>
@@ -18,6 +18,7 @@ import {
message,
} from "antd";
import { budgetCreateCall } from "../networking";
import NotificationManager from "../molecules/notifications_manager";
interface BudgetModalProps {
isModalVisible: boolean;
@@ -58,7 +59,7 @@ const BudgetModal: React.FC<BudgetModalProps> = ({
form.resetFields();
} catch (error) {
console.error("Error creating the key:", error);
message.error(`Error creating the key: ${error}`, 20);
NotificationManager.fromBackend(`Error creating the key: ${error}`);
}
};
@@ -19,6 +19,7 @@ import {
} from "antd";
import { budgetUpdateCall } from "../networking";
import { budgetItem } from "./budget_panel";
import NotificationManager from "../molecules/notifications_manager";
interface BudgetModalProps {
isModalVisible: boolean;
@@ -69,7 +70,7 @@ const EditBudgetModal: React.FC<BudgetModalProps> = ({
handleUpdateCall();
} catch (error) {
console.error("Error creating the key:", error);
message.error(`Error creating the key: ${error}`, 20);
NotificationManager.fromBackend(`Error creating the key: ${error}`);
}
};
@@ -14,6 +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"
interface BulkCreateUsersProps {
accessToken: string
@@ -110,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).`)
message.error("Invalid file type. Please upload a CSV file.")
NotificationManager.fromBackend("Invalid file type. Please upload a CSV file.")
return false
}
@@ -16,6 +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";
const { Text, Title } = Typography;
@@ -80,7 +81,7 @@ const BulkEditUserModal: React.FC<BulkEditUserModalProps> = ({
const handleSubmit = async (formValues: any) => {
console.log("formValues", formValues);
if (!accessToken) {
message.error("Access token not found");
NotificationManager.fromBackend("Access token not found");
return;
}
@@ -112,7 +113,7 @@ const BulkEditUserModal: React.FC<BulkEditUserModalProps> = ({
const hasTeamAdditions = addToTeams && selectedTeams.length > 0;
if (!hasUserUpdates && !hasTeamAdditions) {
message.error("Please modify at least one field or select teams to add users to");
NotificationManager.fromBackend("Please modify at least one field or select teams to add users to");
return;
}
@@ -201,7 +202,7 @@ const BulkEditUserModal: React.FC<BulkEditUserModalProps> = ({
onCancel();
} catch (error) {
console.error("Bulk operation failed:", error);
message.error("Failed to perform bulk operations");
NotificationManager.fromBackend("Failed to perform bulk operations");
} finally {
setLoading(false);
}
@@ -72,6 +72,7 @@ import {
FilePdfOutlined,
ArrowUpOutlined
} from "@ant-design/icons";
import NotificationManager from "./molecules/notifications_manager";
const { TextArea } = Input;
const { Dragger } = Upload;
@@ -516,7 +517,7 @@ const ChatUI: React.FC<ChatUIProps> = ({
// For image edits, require both image and prompt
if (endpointType === EndpointType.IMAGE_EDITS && !uploadedImage) {
message.error("Please upload an image for editing");
NotificationManager.fromBackend("Please upload an image for editing");
return;
}
@@ -527,7 +528,7 @@ const ChatUI: React.FC<ChatUIProps> = ({
const effectiveApiKey = apiKeySource === 'session' ? accessToken : apiKey;
if (!effectiveApiKey) {
message.error("Please provide an API key or select Current UI Session");
NotificationManager.fromBackend("Please provide an API key or select Current UI Session");
return;
}
@@ -543,7 +544,7 @@ const ChatUI: React.FC<ChatUIProps> = ({
try {
newUserMessage = await createMultimodalMessage(inputMessage, responsesUploadedImage);
} catch (error) {
message.error("Failed to process image. Please try again.");
NotificationManager.fromBackend("Failed to process image. Please try again.");
return;
}
}
@@ -552,7 +553,7 @@ const ChatUI: React.FC<ChatUIProps> = ({
try {
newUserMessage = await createChatMultimodalMessage(inputMessage, chatUploadedImage);
} catch (error) {
message.error("Failed to process image. Please try again.");
NotificationManager.fromBackend("Failed to process image. Please try again.");
return;
}
} else {
@@ -3,6 +3,7 @@ import Anthropic from "@anthropic-ai/sdk";
import { MessageType } from "../types";
import { TokenUsage } from "../ResponseMetrics";
import { getProxyBaseUrl } from "@/components/networking";
import NotificationManager from "@/components/molecules/notifications_manager";
export async function makeAnthropicMessagesRequest(
messages: MessageType[],
@@ -122,9 +123,8 @@ export async function makeAnthropicMessagesRequest(
if (signal?.aborted) {
console.log("Anthropic messages request was cancelled");
} else {
message.error(
`Error occurred while generating model response. Please try again. Error: ${error}`,
20,
NotificationManager.fromBackend(
`Error occurred while generating model response. Please try again. Error: ${error}`
);
}
throw error;
@@ -1,3 +1,4 @@
import NotificationManager from "@/components/molecules/notifications_manager";
import { mcpToolsCall } from "../../networking";
import { message } from "antd";
@@ -27,7 +28,7 @@ export async function fetchAvailableMCPTools(
return data.tools || [];
} catch (error) {
console.error("Error fetching MCP tools:", error);
message.error("Failed to fetch MCP tools");
NotificationManager.fromBackend("Failed to fetch MCP tools");
return [];
}
}
@@ -1,6 +1,7 @@
import openai from "openai";
import { message } from "antd";
import { getProxyBaseUrl } from "@/components/networking";
import NotificationManager from "@/components/molecules/notifications_manager";
export async function makeOpenAIImageEditsRequest(
imageFile: File,
@@ -54,7 +55,7 @@ export async function makeOpenAIImageEditsRequest(
if (signal?.aborted) {
console.log("Image edits request was cancelled");
} else {
message.error(`Error occurred while editing image. Please try again. Error: ${error}`, 20);
NotificationManager.fromBackend(`Error occurred while editing image. Please try again. Error: ${error}`);
}
throw error; // Re-throw to allow the caller to handle the error
}
@@ -1,6 +1,7 @@
import openai from "openai";
import { message } from "antd";
import { getProxyBaseUrl } from "@/components/networking";
import NotificationManager from "@/components/molecules/notifications_manager";
export async function makeOpenAIImageGenerationRequest(
prompt: string,
@@ -51,7 +52,7 @@ export async function makeOpenAIImageGenerationRequest(
if (signal?.aborted) {
console.log("Image generation request was cancelled");
} else {
message.error(`Error occurred while generating image. Please try again. Error: ${error}`, 20);
NotificationManager.fromBackend(`Error occurred while generating image. Please try again. Error: ${error}`);
}
throw error; // Re-throw to allow the caller to handle the error
}
@@ -4,6 +4,7 @@ import { MessageType } from "../types";
import { TokenUsage } from "../ResponseMetrics";
import { getProxyBaseUrl } from "@/components/networking";
import { MCPTool } from "@/components/chat_ui/llm_calls/fetch_mcp_tools";
import NotificationManager from "@/components/molecules/notifications_manager";
export async function makeOpenAIResponsesRequest(
messages: MessageType[],
@@ -181,7 +182,7 @@ export async function makeOpenAIResponsesRequest(
if (signal?.aborted) {
console.log("Responses API request was cancelled");
} else {
message.error(`Error occurred while generating model response. Please try again. Error: ${error}`, 20);
NotificationManager.fromBackend(`Error occurred while generating model response. Please try again. Error: ${error}`);
}
throw error; // Re-throw to allow the caller to handle the error
}
@@ -8,6 +8,7 @@ import {
TextInput,
} from "@tremor/react";
import { Modal, Form, Input, message, Spin, Select } from "antd";
import NotificationManager from "./molecules/notifications_manager";
interface CloudZeroExportModalProps {
isOpen: boolean;
@@ -68,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();
message.error(`Failed to load existing settings: ${errorData.error || 'Unknown error'}`);
NotificationManager.fromBackend(`Failed to load existing settings: ${errorData.error || 'Unknown error'}`);
}
} catch (error) {
console.error("Error loading CloudZero settings:", error);
message.error("Failed to load existing settings");
NotificationManager.fromBackend("Failed to load existing settings");
} finally {
setSettingsLoading(false);
}
@@ -80,7 +81,7 @@ const CloudZeroExportModal: React.FC<CloudZeroExportModalProps> = ({
const handleSaveCloudZeroSettings = async (values: CloudZeroSettings) => {
if (!accessToken) {
message.error("No access token available");
NotificationManager.fromBackend("No access token available");
return;
}
@@ -115,12 +116,12 @@ const CloudZeroExportModal: React.FC<CloudZeroExportModalProps> = ({
});
return true;
} else {
message.error(data.error || "Failed to save CloudZero settings");
NotificationManager.fromBackend(data.error || "Failed to save CloudZero settings");
return false;
}
} catch (error) {
console.error("Error saving CloudZero settings:", error);
message.error("Failed to save CloudZero settings");
NotificationManager.fromBackend("Failed to save CloudZero settings");
return false;
} finally {
setLoading(false);
@@ -129,7 +130,7 @@ const CloudZeroExportModal: React.FC<CloudZeroExportModalProps> = ({
const handleExportCloudZero = async () => {
if (!accessToken) {
message.error("No access token available");
NotificationManager.fromBackend("No access token available");
return;
}
@@ -153,11 +154,11 @@ const CloudZeroExportModal: React.FC<CloudZeroExportModalProps> = ({
message.success(data.message || "Export to CloudZero completed successfully");
onClose();
} else {
message.error(data.error || "Failed to export to CloudZero");
NotificationManager.fromBackend(data.error || "Failed to export to CloudZero");
}
} catch (error) {
console.error("Error exporting to CloudZero:", error);
message.error("Failed to export to CloudZero");
NotificationManager.fromBackend("Failed to export to CloudZero");
} finally {
setExportLoading(false);
}
@@ -171,7 +172,7 @@ const CloudZeroExportModal: React.FC<CloudZeroExportModalProps> = ({
onClose();
} catch (error) {
console.error("Error exporting CSV:", error);
message.error("Failed to export CSV");
NotificationManager.fromBackend("Failed to export CSV");
} finally {
setExportLoading(false);
}
@@ -13,6 +13,7 @@ import {
TableCell
} from "@tremor/react";
import ModelSelector from "./ModelSelector";
import NotificationManager from "../molecules/notifications_manager";
interface ModelAliasManagerProps {
accessToken: string;
@@ -49,13 +50,13 @@ const ModelAliasManager: React.FC<ModelAliasManagerProps> = ({
const handleAddAlias = () => {
if (!newAlias.aliasName || !newAlias.targetModel) {
message.error("Please provide both alias name and target model");
NotificationManager.fromBackend("Please provide both alias name and target model");
return;
}
// Check for duplicate alias names
if (aliases.some(alias => alias.aliasName === newAlias.aliasName)) {
message.error("An alias with this name already exists");
NotificationManager.fromBackend("An alias with this name already exists");
return;
}
@@ -90,13 +91,13 @@ const ModelAliasManager: React.FC<ModelAliasManagerProps> = ({
if (!editingAlias) return;
if (!editingAlias.aliasName || !editingAlias.targetModel) {
message.error("Please provide both alias name and target model");
NotificationManager.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)) {
message.error("An alias with this name already exists");
NotificationManager.fromBackend("An alias with this name already exists");
return;
}
@@ -26,6 +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"
// Helper function to generate UUID compatible across all environments
const generateUUID = (): string => {
@@ -174,7 +175,7 @@ const Createuser: React.FC<CreateuserProps> = ({
localStorage.removeItem("userData" + userID)
} catch (error: any) {
const errorMessage = error.response?.data?.detail || error?.message || "Error creating the user"
message.error(errorMessage)
NotificationManager.fromBackend(errorMessage)
console.error("Error creating the user:", error)
}
}
@@ -4,6 +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";
interface EditAutoRouterModalProps {
isVisible: boolean;
@@ -92,7 +93,7 @@ const EditAutoRouterModal: React.FC<EditAutoRouterModalProps> = ({
} catch (error) {
console.error("Error parsing auto router config:", error);
message.error("Error loading auto router configuration");
NotificationManager.fromBackend("Error loading auto router configuration");
}
};
@@ -135,7 +136,7 @@ const EditAutoRouterModal: React.FC<EditAutoRouterModalProps> = ({
onCancel();
} catch (error) {
console.error("Error updating auto router:", error);
message.error("Failed to update auto router configuration");
NotificationManager.fromBackend("Failed to update auto router configuration");
} finally {
setLoading(false);
}
@@ -8,7 +8,7 @@ import {
TableCell,
} from "@tremor/react";
import { Typography } from "antd";
import NotificationsManager from "./molecules/notifications_manager";
import NotificationManager from "./molecules/notifications_manager";
import { serviceHealthCheck, setCallbacksCall } from "./networking";
import { EmailEventSettings } from "./email_events";
@@ -54,9 +54,9 @@ const EmailSettings: React.FC<EmailSettingsProps> = ({
};
try {
await setCallbacksCall(accessToken, payload);
NotificationsManager.success("Email settings updated successfully");
NotificationManager.success("Email settings updated successfully");
} catch (error) {
NotificationsManager.fromBackend(error);
NotificationManager.fromBackend(error);
}
}
@@ -195,9 +195,9 @@ const EmailSettings: React.FC<EmailSettingsProps> = ({
if (!accessToken) return;
try {
await serviceHealthCheck(accessToken, "email");
NotificationsManager.success("Email test triggered. Check your configured email inbox/logs.");
NotificationManager.success("Email test triggered. Check your configured email inbox/logs.");
} catch (error) {
NotificationsManager.fromBackend(error);
NotificationManager.fromBackend(error);
}
}}
className="mx-2"
@@ -63,6 +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";
interface GeneralSettingsPageProps {
accessToken: string | null;
userRole: string | null;
@@ -121,9 +122,8 @@ async function testFallbackModelResponse(
</span>
);
} catch (error) {
message.error(
NotificationManager.fromBackend(
`Error occurred while generating model response. Please try again. Error: ${error}`,
20
);
}
}
@@ -311,7 +311,7 @@ const GeneralSettings: React.FC<GeneralSettingsPageProps> = ({
setRouterSettings(updatedSettings);
message.success("Router settings updated successfully");
} catch (error) {
message.error("Failed to update router settings: " + error, 20);
NotificationManager.fromBackend("Failed to update router settings: " + error);
}
};
@@ -432,7 +432,7 @@ const GeneralSettings: React.FC<GeneralSettingsPageProps> = ({
try {
setCallbacksCall(accessToken, payload);
} catch (error) {
message.error("Failed to update router settings: " + error, 20);
NotificationManager.fromBackend("Failed to update router settings: " + error);
}
message.success("router settings updated successfully");
@@ -13,6 +13,7 @@ import {
import { message, Input } from "antd";
import { EditOutlined, DeleteOutlined, SaveOutlined, CloseOutlined } from "@ant-design/icons";
import { ChevronDownIcon, ChevronRightIcon, PlusCircleIcon } from "@heroicons/react/outline";
import NotificationManager from "./molecules/notifications_manager";
interface KeyValueItem {
id?: string;
@@ -73,7 +74,7 @@ const GenericKeyValueManager: React.FC<GenericKeyValueManagerProps> = ({
setNewKey("");
setNewValue("");
} else {
message.error(`Please provide both ${keyLabel.toLowerCase()} and ${valueLabel.toLowerCase()}`);
NotificationManager.fromBackend(`Please provide both ${keyLabel.toLowerCase()} and ${valueLabel.toLowerCase()}`);
}
}, [newKey, newValue, items, onItemsChange, keyLabel, valueLabel]);
@@ -93,7 +94,7 @@ const GenericKeyValueManager: React.FC<GenericKeyValueManagerProps> = ({
setEditingKey("");
setEditingValue("");
} else {
message.error(`Please provide both ${keyLabel.toLowerCase()} and ${valueLabel.toLowerCase()}`);
NotificationManager.fromBackend(`Please provide both ${keyLabel.toLowerCase()} and ${valueLabel.toLowerCase()}`);
}
}, [editingKey, editingValue, items, editingItem, onItemsChange, keyLabel, valueLabel]);
@@ -7,6 +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";
interface GuardrailsPanelProps {
accessToken: string | null
@@ -91,7 +92,7 @@ const GuardrailsPanel: React.FC<GuardrailsPanelProps> = ({ accessToken, userRole
fetchGuardrails() // Refresh the list
} catch (error) {
console.error("Error deleting guardrail:", error)
message.error("Failed to delete guardrail")
NotificationManager.fromBackend("Failed to delete guardrail")
} finally {
setIsDeleting(false)
setGuardrailToDelete(null)
@@ -7,6 +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';
const { Title, Text, Link } = Typography;
const { Option } = Select;
@@ -103,7 +104,7 @@ const AddGuardrailForm: React.FC<AddGuardrailFormProps> = ({
populateGuardrailProviderMap(providerParamsResp);
} catch (error) {
console.error('Error fetching guardrail data:', error);
message.error('Failed to load guardrail configuration');
NotificationManager.fromBackend('Failed to load guardrail configuration');
}
};
@@ -186,7 +187,7 @@ const AddGuardrailForm: React.FC<AddGuardrailFormProps> = ({
// Validate configuration steps
if (currentStep === 1) {
if (shouldRenderPIIConfigSettings(selectedProvider) && selectedEntities.length === 0) {
message.error('Please select at least one PII entity to continue');
NotificationManager.fromBackend('Please select at least one PII entity to continue');
return;
}
}
@@ -274,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) {
message.error('Invalid JSON in configuration');
NotificationManager.fromBackend('Invalid JSON in configuration');
setLoading(false);
return;
}
@@ -345,7 +346,7 @@ const AddGuardrailForm: React.FC<AddGuardrailFormProps> = ({
onClose();
} catch (error) {
console.error("Failed to create guardrail:", error);
message.error('Failed to create guardrail: ' + (error instanceof Error ? error.message : String(error)));
NotificationManager.fromBackend('Failed to create guardrail: ' + (error instanceof Error ? error.message : String(error)));
} finally {
setLoading(false);
}
@@ -4,6 +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';
const { Title, Text } = Typography;
const { Option } = Select;
@@ -59,7 +60,7 @@ const EditGuardrailForm: React.FC<EditGuardrailFormProps> = ({
setGuardrailSettings(data);
} catch (error) {
console.error('Error fetching guardrail settings:', error);
message.error('Failed to load guardrail settings');
NotificationManager.fromBackend('Failed to load guardrail settings');
}
};
@@ -165,7 +166,7 @@ const EditGuardrailForm: React.FC<EditGuardrailFormProps> = ({
guardrailData.guardrail.guardrail_info = configObj;
}
} catch (error) {
message.error('Invalid JSON in configuration');
NotificationManager.fromBackend('Invalid JSON in configuration');
setLoading(false);
return;
}
@@ -200,7 +201,7 @@ const EditGuardrailForm: React.FC<EditGuardrailFormProps> = ({
onClose();
} catch (error) {
console.error("Failed to update guardrail:", error);
message.error('Failed to update guardrail: ' + (error instanceof Error ? error.message : String(error)));
NotificationManager.fromBackend('Failed to update guardrail: ' + (error instanceof Error ? error.message : String(error)));
} finally {
setLoading(false);
}
@@ -28,6 +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"
export interface GuardrailInfoProps {
guardrailId: string
@@ -104,7 +105,7 @@ const GuardrailInfoView: React.FC<GuardrailInfoProps> = ({ guardrailId, onClose,
setSelectedPiiActions({})
}
} catch (error) {
message.error("Failed to load guardrail information")
NotificationManager.fromBackend("Failed to load guardrail information")
console.error("Error fetching guardrail info:", error)
} finally {
setLoading(false)
@@ -296,7 +297,7 @@ const GuardrailInfoView: React.FC<GuardrailInfoProps> = ({ guardrailId, onClose,
setIsEditing(false)
} catch (error) {
console.error("Error updating guardrail:", error)
message.error("Failed to update guardrail")
NotificationManager.fromBackend("Failed to update guardrail")
}
}
@@ -3,6 +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";
const { Step } = Steps;
@@ -56,7 +57,7 @@ const MakeModelPublicForm: React.FC<MakeModelPublicFormProps> = ({
const handleNext = () => {
if (currentStep === 0) {
if (selectedModels.size === 0) {
message.error("Please select at least one model to make public");
NotificationManager.fromBackend("Please select at least one model to make public");
return;
}
setCurrentStep(1);
@@ -109,7 +110,7 @@ const MakeModelPublicForm: React.FC<MakeModelPublicFormProps> = ({
const handleSubmit = async () => {
if (selectedModels.size === 0) {
message.error("Please select at least one model to make public");
NotificationManager.fromBackend("Please select at least one model to make public");
return;
}
@@ -123,7 +124,7 @@ const MakeModelPublicForm: React.FC<MakeModelPublicFormProps> = ({
onSuccess();
} catch (error) {
console.error("Error making model groups public:", error);
message.error("Failed to make model groups public. Please try again.");
NotificationManager.fromBackend("Failed to make model groups public. Please try again.");
} finally {
setLoading(false);
}
@@ -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";
export function ToolTestPanel({
tool,
@@ -145,7 +145,7 @@ export function ToolTestPanel({
if (success) {
message.success('Result copied to clipboard');
} else {
message.error('Failed to copy result');
NotificationManager.fromBackend('Failed to copy result');
}
};
@@ -154,7 +154,7 @@ export function ToolTestPanel({
if (success) {
message.success('Tool name copied to clipboard');
} else {
message.error('Failed to copy tool name');
NotificationManager.fromBackend('Failed to copy tool name');
}
};
@@ -9,6 +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"
const asset_logos_folder = "../ui/assets/logos/"
export const mcpLogoImg = `${asset_logos_folder}mcp_logo.png`
@@ -80,7 +81,7 @@ const CreateMCPServer: React.FC<CreateMCPServerProps> = ({
console.log("Parsed stdio config:", stdioFields)
} catch (error) {
message.error("Invalid JSON in stdio configuration")
NotificationManager.fromBackend("Invalid JSON in stdio configuration")
return
}
}
@@ -113,7 +114,7 @@ const CreateMCPServer: React.FC<CreateMCPServerProps> = ({
onCreateSuccess(response)
}
} catch (error) {
message.error("Error creating MCP Server: " + error, 20)
NotificationManager.fromBackend("Error creating MCP Server: " + error)
} finally {
setIsLoading(false)
}
@@ -6,6 +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";
interface MCPServerEditProps {
mcpServer: MCPServer;
@@ -131,7 +132,7 @@ const MCPServerEdit: React.FC<MCPServerEditProps> = ({ mcpServer, accessToken, o
message.success("MCP Server updated successfully");
onSuccess(updated);
} catch (error: any) {
message.error("Failed to update MCP Server" + (error?.message ? `: ${error.message}` : ""));
NotificationManager.fromBackend("Failed to update MCP Server" + (error?.message ? `: ${error.message}` : ""));
}
};
@@ -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 NotificationManager from "../molecules/notifications_manager";
type AuthModalProps = {
visible: boolean;
@@ -77,6 +77,7 @@ 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";
interface ModelDashboardProps {
accessToken: string | null;
@@ -439,7 +440,7 @@ const ModelDashboard: React.FC<ModelDashboardProps> = ({
if (info.file.status === "done") {
message.success(`${info.file.name} file uploaded successfully`);
} else if (info.file.status === "error") {
message.error(`${info.file.name} file upload failed.`);
NotificationManager.fromBackend(`${info.file.name} file upload failed.`);
}
},
};
@@ -480,7 +481,7 @@ const ModelDashboard: React.FC<ModelDashboardProps> = ({
await setCallbacksCall(accessToken, payload);
} catch (error) {
console.error("Failed to save retry settings:", error);
message.error("Failed to save retry settings");
NotificationManager.fromBackend("Failed to save retry settings");
}
};
@@ -1003,7 +1004,7 @@ const ModelDashboard: React.FC<ModelDashboardProps> = ({
const errorMessages = error.errorFields?.map((field: any) => {
return `${field.name.join('.')}: ${field.errors.join(', ')}`;
}).join(' | ') || 'Unknown validation error';
message.error(`Please fill in the following required fields: ${errorMessages}`);
NotificationManager.fromBackend(`Please fill in the following required fields: ${errorMessages}`);
});
};
@@ -13,6 +13,7 @@ import {
TableRow,
TableCell
} from "@tremor/react";
import NotificationManager from "./molecules/notifications_manager";
interface ModelGroupAliasSettingsProps {
accessToken: string;
@@ -75,20 +76,20 @@ const ModelGroupAliasSettings: React.FC<ModelGroupAliasSettingsProps> = ({
return true;
} catch (error) {
console.error("Failed to save model group alias settings:", error);
message.error("Failed to save model group alias settings");
NotificationManager.fromBackend("Failed to save model group alias settings");
return false;
}
};
const handleAddAlias = async () => {
if (!newAlias.aliasName || !newAlias.targetModelGroup) {
message.error("Please provide both alias name and target model group");
NotificationManager.fromBackend("Please provide both alias name and target model group");
return;
}
// Check for duplicate alias names
if (aliases.some(alias => alias.aliasName === newAlias.aliasName)) {
message.error("An alias with this name already exists");
NotificationManager.fromBackend("An alias with this name already exists");
return;
}
@@ -115,13 +116,13 @@ const ModelGroupAliasSettings: React.FC<ModelGroupAliasSettingsProps> = ({
if (!editingAlias) return;
if (!editingAlias.aliasName || !editingAlias.targetModelGroup) {
message.error("Please provide both alias name and target model group");
NotificationManager.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)) {
message.error("An alias with this name already exists");
NotificationManager.fromBackend("An alias with this name already exists");
return;
}
@@ -38,6 +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";
interface ModelInfoViewProps {
modelId: string;
@@ -211,7 +212,7 @@ export default function ModelInfoView({
};
}
} catch (e) {
message.error("Invalid JSON in Model Info");
NotificationManager.fromBackend("Invalid JSON in Model Info");
return;
}
@@ -242,7 +243,7 @@ export default function ModelInfoView({
setIsEditing(false);
} catch (error) {
console.error("Error updating model:", error);
message.error("Failed to update model settings");
NotificationManager.fromBackend("Failed to update model settings");
} finally {
setIsSaving(false);
}
@@ -280,7 +281,7 @@ export default function ModelInfoView({
onClose();
} catch (error) {
console.error("Error deleting the model:", error);
message.error("Failed to delete model");
NotificationManager.fromBackend("Failed to delete model");
}
};
File diff suppressed because it is too large Load Diff
@@ -33,6 +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"
const { Option } = Select;
@@ -384,7 +385,7 @@ const CreateKey: React.FC<CreateKeyProps> = ({
} catch (error) {
console.log("error in create key:", error);
message.error(`Error creating the key: ${error}`);
NotificationManager.fromBackend(`Error creating the key: ${error}`);
}
};
@@ -434,7 +435,7 @@ const CreateKey: React.FC<CreateKeyProps> = ({
setUserOptions(options);
} catch (error) {
console.error('Error fetching users:', error);
message.error('Failed to search for users');
NotificationManager.fromBackend('Failed to search for users');
} finally {
setUserSearchLoading(false);
}
@@ -41,6 +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"
interface OrganizationInfoProps {
organizationId: string
@@ -78,7 +79,7 @@ const OrganizationInfoView: React.FC<OrganizationInfoProps> = ({
const response = await organizationInfoCall(accessToken, organizationId)
setOrgData(response)
} catch (error) {
message.error("Failed to load organization information")
NotificationManager.fromBackend("Failed to load organization information")
console.error("Error fetching organization info:", error)
} finally {
setLoading(false)
@@ -107,7 +108,7 @@ const OrganizationInfoView: React.FC<OrganizationInfoProps> = ({
form.resetFields()
fetchOrgInfo()
} catch (error) {
message.error("Failed to add organization member")
NotificationManager.fromBackend("Failed to add organization member")
console.error("Error adding organization member:", error)
}
}
@@ -128,7 +129,7 @@ const OrganizationInfoView: React.FC<OrganizationInfoProps> = ({
form.resetFields()
fetchOrgInfo()
} catch (error) {
message.error("Failed to update organization member")
NotificationManager.fromBackend("Failed to update organization member")
console.error("Error updating organization member:", error)
}
}
@@ -143,7 +144,7 @@ const OrganizationInfoView: React.FC<OrganizationInfoProps> = ({
form.resetFields()
fetchOrgInfo()
} catch (error) {
message.error("Failed to delete organization member")
NotificationManager.fromBackend("Failed to delete organization member")
console.error("Error deleting organization member:", error)
}
}
@@ -192,7 +193,7 @@ const OrganizationInfoView: React.FC<OrganizationInfoProps> = ({
setIsEditing(false)
fetchOrgInfo()
} catch (error) {
message.error("Failed to update organization settings")
NotificationManager.fromBackend("Failed to update organization settings")
console.error("Error updating organization:", error)
}
}
@@ -20,6 +20,7 @@ import {
} from "./networking";
import { Eye, EyeOff } from "lucide-react";
import RoutePreview from "./route_preview";
import NotificationManager from "./molecules/notifications_manager";
export interface PassThroughInfoProps {
endpointData: PassThroughEndpoint;
@@ -87,7 +88,7 @@ const PassThroughInfoView: React.FC<PassThroughInfoProps> = ({
? JSON.parse(values.headers)
: values.headers;
} catch (e) {
message.error("Invalid JSON format for headers");
NotificationManager.fromBackend("Invalid JSON format for headers");
return;
}
}
@@ -114,7 +115,7 @@ const PassThroughInfoView: React.FC<PassThroughInfoProps> = ({
}
} catch (error) {
console.error("Error updating endpoint:", error);
message.error("Failed to update pass through endpoint");
NotificationManager.fromBackend("Failed to update pass through endpoint");
}
};
@@ -130,7 +131,7 @@ const PassThroughInfoView: React.FC<PassThroughInfoProps> = ({
}
} catch (error) {
console.error("Error deleting endpoint:", error);
message.error("Failed to delete pass through endpoint");
NotificationManager.fromBackend("Failed to delete pass through endpoint");
}
};
@@ -45,6 +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";
interface GeneralSettingsPageProps {
accessToken: string | null;
@@ -153,7 +154,7 @@ const PassThroughSettings: React.FC<GeneralSettingsPageProps> = ({
message.success("Endpoint deleted successfully.");
} catch (error) {
console.error("Error deleting the endpoint:", error);
message.error("Error deleting the endpoint: " + error);
NotificationManager.fromBackend("Error deleting the endpoint: " + error);
}
// Close the confirmation modal and reset the endpointToDelete
@@ -2,6 +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";
const { Text } = Typography;
@@ -77,7 +78,7 @@ const PriceDataReload: React.FC<PriceDataReloadProps> = ({
const handleHardRefresh = async () => {
if (!accessToken) {
message.error("No access token available");
NotificationManager.fromBackend("No access token available");
return;
}
@@ -93,23 +94,23 @@ const PriceDataReload: React.FC<PriceDataReloadProps> = ({
// Refresh status after successful reload
await fetchReloadStatus();
} else {
message.error("Failed to reload price data");
NotificationManager.fromBackend("Failed to reload price data");
}
} catch (error) {
console.error("Error reloading price data:", error);
message.error("Failed to reload price data. Please try again.");
NotificationManager.fromBackend("Failed to reload price data. Please try again.");
} finally {
setIsLoading(false);
}
};
const handleScheduleReload = async () => {
if (!accessToken) {
message.error("No access token available");
NotificationManager.fromBackend("No access token available");
return;
}
if (hours <= 0) {
message.error("Hours must be greater than 0");
NotificationManager.fromBackend("Hours must be greater than 0");
return;
}
@@ -122,11 +123,11 @@ const PriceDataReload: React.FC<PriceDataReloadProps> = ({
setShowScheduleModal(false);
await fetchReloadStatus();
} else {
message.error("Failed to schedule periodic reload");
NotificationManager.fromBackend("Failed to schedule periodic reload");
}
} catch (error) {
console.error("Error scheduling reload:", error);
message.error("Failed to schedule periodic reload. Please try again.");
NotificationManager.fromBackend("Failed to schedule periodic reload. Please try again.");
} finally {
setIsScheduling(false);
}
@@ -134,7 +135,7 @@ const PriceDataReload: React.FC<PriceDataReloadProps> = ({
const handleCancelReload = async () => {
if (!accessToken) {
message.error("No access token available");
NotificationManager.fromBackend("No access token available");
return;
}
@@ -146,11 +147,11 @@ const PriceDataReload: React.FC<PriceDataReloadProps> = ({
message.success("Periodic reload cancelled successfully");
await fetchReloadStatus();
} else {
message.error("Failed to cancel periodic reload");
NotificationManager.fromBackend("Failed to cancel periodic reload");
}
} catch (error) {
console.error("Error cancelling reload:", error);
message.error("Failed to cancel periodic reload. Please try again.");
NotificationManager.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 { isAdminRole } from "@/utils/roles"
interface PromptsProps {
@@ -78,7 +78,7 @@ const PromptsPanel: React.FC<PromptsProps> = ({ accessToken, userRole }) => {
fetchPrompts() // Refresh the list
} catch (error) {
console.error("Error deleting prompt:", error)
message.error("Failed to delete prompt")
NotificationManager.fromBackend("Failed to delete prompt")
} finally {
setIsDeleting(false)
setPromptToDelete(null)
@@ -4,6 +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"
const { Option } = Select
@@ -44,12 +45,12 @@ const AddPromptForm: React.FC<AddPromptFormProps> = ({
console.log("values: ", values)
if (!accessToken) {
message.error("Access token is required")
NotificationManager.fromBackend("Access token is required")
return
}
if (promptIntegration === "dotprompt" && fileList.length === 0) {
message.error("Please upload a .prompt file")
NotificationManager.fromBackend("Please upload a .prompt file")
return
}
@@ -79,7 +80,7 @@ const AddPromptForm: React.FC<AddPromptFormProps> = ({
}
} catch (conversionError) {
console.error("Error converting prompt file:", conversionError)
message.error("Failed to convert prompt file to JSON")
NotificationManager.fromBackend("Failed to convert prompt file to JSON")
setLoading(false)
return
}
@@ -93,7 +94,7 @@ const AddPromptForm: React.FC<AddPromptFormProps> = ({
onSuccess()
} catch (createError) {
console.error("Error creating prompt:", createError)
message.error("Failed to create prompt")
NotificationManager.fromBackend("Failed to create prompt")
}
} catch (error) {
@@ -106,7 +107,7 @@ const AddPromptForm: React.FC<AddPromptFormProps> = ({
const uploadProps: UploadProps = {
beforeUpload: (file) => {
if (!file.name.endsWith('.prompt')) {
message.error('Please upload a .prompt file')
NotificationManager.fromBackend('Please upload a .prompt file')
return false
}
return false // Prevent automatic upload
@@ -17,6 +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"
export interface PromptInfoProps {
promptId: string
@@ -44,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) {
message.error("Failed to load prompt information")
NotificationManager.fromBackend("Failed to load prompt information")
console.error("Error fetching prompt info:", error)
} finally {
setLoading(false)
@@ -95,7 +96,7 @@ const PromptInfoView: React.FC<PromptInfoProps> = ({ promptId, onClose, accessTo
onClose() // Close the info view
} catch (error) {
console.error("Error deleting prompt:", error)
message.error("Failed to delete prompt")
NotificationManager.fromBackend("Failed to delete prompt")
} finally {
setIsDeleting(false)
setShowDeleteConfirm(false)
@@ -1,5 +1,6 @@
import OpenAI from "openai";
import React from "react";
import NotificationManager from "./molecules/notifications_manager";
export enum Providers {
Bedrock = "Amazon Bedrock",
@@ -27,6 +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";
interface ModelInfo {
model_name: string;
@@ -67,7 +68,7 @@ const TagManagement: React.FC<TagProps> = ({
setTags(Object.values(response));
} catch (error) {
console.error("Error fetching tags:", error);
message.error("Error fetching tags: " + error);
NotificationManager.fromBackend("Error fetching tags: " + error);
}
};
@@ -91,7 +92,7 @@ const TagManagement: React.FC<TagProps> = ({
fetchTags();
} catch (error) {
console.error("Error creating tag:", error);
message.error("Error creating tag: " + error);
NotificationManager.fromBackend("Error creating tag: " + error);
}
};
@@ -108,7 +109,7 @@ const TagManagement: React.FC<TagProps> = ({
fetchTags();
} catch (error) {
console.error("Error deleting tag:", error);
message.error("Error deleting tag: " + error);
NotificationManager.fromBackend("Error deleting tag: " + error);
}
setIsDeleteModalOpen(false);
setTagToDelete(null);
@@ -124,7 +125,7 @@ const TagManagement: React.FC<TagProps> = ({
}
} catch (error) {
console.error("Error fetching models:", error);
message.error("Error fetching models: " + error);
NotificationManager.fromBackend("Error fetching models: " + error);
}
};
fetchModels();
@@ -6,6 +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";
interface TagInfoViewProps {
tagId: string
@@ -38,7 +39,7 @@ const TagInfoView: React.FC<TagInfoViewProps> = ({ tagId, onClose, accessToken,
}
} catch (error) {
console.error("Error fetching tag details:", error)
message.error("Error fetching tag details: " + error)
NotificationManager.fromBackend("Error fetching tag details: " + error)
}
}
@@ -67,7 +68,7 @@ const TagInfoView: React.FC<TagInfoViewProps> = ({ tagId, onClose, accessToken,
fetchTagDetails()
} catch (error) {
console.error("Error updating tag:", error)
message.error("Error updating tag: " + error)
NotificationManager.fromBackend("Error updating tag: " + error)
}
}
@@ -13,6 +13,7 @@ import {
} from "@tremor/react";
import { message } from 'antd';
import { availableTeamListCall, teamMemberAddCall } from "../networking";
import NotificationManager from "../molecules/notifications_manager";
interface AvailableTeam {
team_id: string;
@@ -64,7 +65,7 @@ const AvailableTeamsPanel: React.FC<AvailableTeamsProps> = ({
setAvailableTeams(teams => teams.filter(team => team.team_id !== teamId));
} catch (error) {
console.error('Error joining team:', error);
message.error('Failed to join team');
NotificationManager.fromBackend('Failed to join team');
}
};
@@ -2,6 +2,7 @@ import React, { useState, useEffect } from 'react';
import { Modal, Form, Input, Select as AntSelect, Button as AntButton, message } from 'antd';
import { Select, SelectItem } from "@tremor/react";
import { Card, Text } from "@tremor/react";
import NotificationManager from "../molecules/notifications_manager";
interface BaseMember {
user_email?: string;
@@ -80,7 +81,7 @@ const MemberModal = <T extends BaseMember>({
form.resetFields();
// message.success(`Successfully ${mode === 'add' ? 'added' : 'updated'} member`);
} catch (error) {
// message.error('Failed to submit form');
// NotificationManager.fromBackend('Failed to submit form');
console.error('Form submission error:', error);
}
};
@@ -15,6 +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";
interface MemberPermissionsProps {
teamId: string
@@ -40,7 +41,7 @@ const MemberPermissions: React.FC<MemberPermissionsProps> = ({ teamId, accessTok
setSelectedPermissions(teamPermissions)
setHasChanges(false)
} catch (error) {
message.error("Failed to load permissions")
NotificationManager.fromBackend("Failed to load permissions")
console.error("Error fetching permissions:", error)
} finally {
setLoading(false)
@@ -67,7 +68,7 @@ const MemberPermissions: React.FC<MemberPermissionsProps> = ({ teamId, accessTok
message.success("Permissions updated successfully")
setHasChanges(false)
} catch (error) {
message.error("Failed to update permissions")
NotificationManager.fromBackend("Failed to update permissions")
console.error("Error updating permissions:", error)
} finally {
setSaving(false)
@@ -54,6 +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";
export interface TeamMembership {
user_id: string;
@@ -160,7 +161,7 @@ const TeamInfoView: React.FC<TeamInfoProps> = ({
const response = await teamInfoCall(accessToken, teamId);
setTeamData(response);
} catch (error) {
message.error("Failed to load team information");
NotificationManager.fromBackend("Failed to load team information");
console.error("Error fetching team info:", error);
} finally {
setLoading(false);
@@ -236,7 +237,7 @@ const TeamInfoView: React.FC<TeamInfoProps> = ({
errMsg = error.message;
}
message.error(errMsg);
NotificationManager.fromBackend(errMsg);
console.error("Error adding team member:", error);
}
};
@@ -281,7 +282,7 @@ const TeamInfoView: React.FC<TeamInfoProps> = ({
message.destroy(); // Remove all existing toasts
message.error(errMsg);
NotificationManager.fromBackend(errMsg);
console.error("Error updating team member:", error);
}
};
@@ -303,7 +304,7 @@ const TeamInfoView: React.FC<TeamInfoProps> = ({
// Notify parent component of the update
onUpdate(updatedTeamData);
} catch (error) {
message.error("Failed to remove team member");
NotificationManager.fromBackend("Failed to remove team member");
console.error("Error removing team member:", error);
}
};
@@ -316,7 +317,7 @@ const TeamInfoView: React.FC<TeamInfoProps> = ({
try {
parsedMetadata = values.metadata ? JSON.parse(values.metadata) : {};
} catch (e) {
message.error("Invalid JSON in metadata field");
NotificationManager.fromBackend("Invalid JSON in metadata field");
return;
}
@@ -464,7 +464,7 @@ const Teams: React.FC<TeamProps> = ({
}
} catch (error) {
console.error("Error creating the team:", error);
message.error("Error creating the team: " + error, 20);
NotificationManager.fromBackend("Error creating the team: " + error, 20);
}
};
@@ -3,6 +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";
interface TransformRequestPanelProps {
accessToken: string | null;
}
@@ -67,7 +68,7 @@ ${formattedBody}
try {
requestBody = JSON.parse(originalRequestJSON);
} catch (e) {
message.error('Invalid JSON in request body');
NotificationManager.fromBackend('Invalid JSON in request body');
setIsLoading(false);
return;
}
@@ -80,7 +81,7 @@ ${formattedBody}
// Make the API call using fetch
if (!accessToken) {
message.error('No access token found');
NotificationManager.fromBackend('No access token found');
setIsLoading(false);
return;
}
@@ -108,7 +109,7 @@ ${formattedBody}
}
} catch (err) {
console.error('Error transforming request:', err);
message.error('Failed to transform request');
NotificationManager.fromBackend('Failed to transform request');
} finally {
setIsLoading(false);
}
@@ -9,6 +9,7 @@ import {
import { message } from "antd"
import { useTheme } from "@/contexts/ThemeContext"
import { getProxyBaseUrl } from "@/components/networking"
import NotificationManager from "./molecules/notifications_manager";
interface UIThemeSettingsProps {
userID: string | null;
@@ -79,7 +80,7 @@ const UIThemeSettings: React.FC<UIThemeSettingsProps> = ({
}
} catch (error) {
console.error("Error updating logo settings:", error);
message.error("Failed to update logo settings");
NotificationManager.fromBackend("Failed to update logo settings");
} finally {
setLoading(false);
}
@@ -112,7 +113,7 @@ const UIThemeSettings: React.FC<UIThemeSettingsProps> = ({
}
} catch (error) {
console.error("Error resetting logo:", error);
message.error("Failed to reset logo");
NotificationManager.fromBackend("Failed to reset logo");
} finally {
setLoading(false);
}
@@ -14,6 +14,7 @@ import {
TableRow,
TableCell
} from "@tremor/react";
import NotificationManager from "./molecules/notifications_manager";
interface UsefulLinksManagementProps {
accessToken: string | null;
@@ -117,7 +118,7 @@ const UsefulLinksManagement: React.FC<UsefulLinksManagementProps> = ({
return true;
} catch (error) {
console.error("Error saving links:", error);
message.error(`Failed to save links - ${error}`);
NotificationManager.fromBackend(`Failed to save links - ${error}`);
return false;
}
};
@@ -129,13 +130,13 @@ const UsefulLinksManagement: React.FC<UsefulLinksManagementProps> = ({
try {
new URL(newLink.url);
} catch {
message.error("Please enter a valid URL");
NotificationManager.fromBackend("Please enter a valid URL");
return;
}
// Check for duplicate display names
if (links.some(link => link.displayName === newLink.displayName)) {
message.error("A link with this display name already exists");
NotificationManager.fromBackend("A link with this display name already exists");
return;
}
@@ -165,13 +166,13 @@ const UsefulLinksManagement: React.FC<UsefulLinksManagementProps> = ({
try {
new URL(editingLink.url);
} catch {
message.error("Please enter a valid URL");
NotificationManager.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)) {
message.error("A link with this display name already exists");
NotificationManager.fromBackend("A link with this display name already exists");
return;
}
@@ -17,6 +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";
interface VectorStoreFormProps {
isVisible: boolean;
@@ -45,7 +46,7 @@ const VectorStoreForm: React.FC<VectorStoreFormProps> = ({
try {
metadata = metadataJson.trim() ? JSON.parse(metadataJson) : {};
} catch (e) {
message.error("Invalid JSON in metadata field");
NotificationManager.fromBackend("Invalid JSON in metadata field");
return;
}
@@ -75,7 +76,7 @@ const VectorStoreForm: React.FC<VectorStoreFormProps> = ({
onSuccess();
} catch (error) {
console.error("Error creating vector store:", error);
message.error("Error creating vector store: " + error);
NotificationManager.fromBackend("Error creating vector store: " + error);
}
};
@@ -2,6 +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";
const { TextArea } = Input;
const { Text, Title } = Typography;
@@ -66,7 +67,7 @@ export const VectorStoreTester: React.FC<VectorStoreTesterProps> = ({
setQuery("");
} catch (error) {
console.error("Error searching vector store:", error);
message.error("Failed to search vector store");
NotificationManager.fromBackend("Failed to search vector store");
} finally {
setIsLoading(false);
}
@@ -19,6 +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";
interface VectorStoreProps {
accessToken: string | null;
@@ -48,7 +49,7 @@ const VectorStoreManagement: React.FC<VectorStoreProps> = ({
setVectorStores(response.data || []);
} catch (error) {
console.error("Error fetching vector stores:", error);
message.error("Error fetching vector stores: " + error);
NotificationManager.fromBackend("Error fetching vector stores: " + error);
}
};
@@ -60,7 +61,7 @@ const VectorStoreManagement: React.FC<VectorStoreProps> = ({
setCredentials(response.credentials || []);
} catch (error) {
console.error("Error fetching credentials:", error);
message.error("Error fetching credentials: " + error);
NotificationManager.fromBackend("Error fetching credentials: " + error);
}
};
@@ -100,7 +101,7 @@ const VectorStoreManagement: React.FC<VectorStoreProps> = ({
fetchVectorStores();
} catch (error) {
console.error("Error deleting vector store:", error);
message.error("Error deleting vector store: " + error);
NotificationManager.fromBackend("Error deleting vector store: " + error);
}
setIsDeleteModalOpen(false);
setVectorStoreToDelete(null);
@@ -25,6 +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";
interface VectorStoreInfoViewProps {
vectorStoreId: string;
@@ -74,7 +75,7 @@ const VectorStoreInfoView: React.FC<VectorStoreInfoViewProps> = ({
}
} catch (error) {
console.error("Error fetching vector store details:", error);
message.error("Error fetching vector store details: " + error);
NotificationManager.fromBackend("Error fetching vector store details: " + error);
}
};
@@ -102,7 +103,7 @@ const VectorStoreInfoView: React.FC<VectorStoreInfoViewProps> = ({
try {
metadata = metadataString ? JSON.parse(metadataString) : {};
} catch (e) {
message.error("Invalid JSON in metadata field");
NotificationManager.fromBackend("Invalid JSON in metadata field");
return;
}
@@ -120,7 +121,7 @@ const VectorStoreInfoView: React.FC<VectorStoreInfoViewProps> = ({
fetchVectorStoreDetails();
} catch (error) {
console.error("Error updating vector store:", error);
message.error("Error updating vector store: " + error);
NotificationManager.fromBackend("Error updating vector store: " + error);
}
};
@@ -1,5 +1,6 @@
import { LogEntry } from "./columns";
import { message } from "antd";
import NotificationManager from "../molecules/notifications_manager";
interface RequestResponsePanelProps {
row: {
@@ -57,7 +58,7 @@ export function RequestResponsePanel({
if (success) {
message.success('Request copied to clipboard');
} else {
message.error('Failed to copy request');
NotificationManager.fromBackend('Failed to copy request');
}
};
@@ -66,7 +67,7 @@ export function RequestResponsePanel({
if (success) {
message.success('Response copied to clipboard');
} else {
message.error('Failed to copy response');
NotificationManager.fromBackend('Failed to copy response');
}
};
@@ -29,6 +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"
interface ViewUserDashboardProps {
accessToken: string | null
@@ -138,7 +139,7 @@ const ViewUserDashboard: React.FC<ViewUserDashboardProps> = ({ accessToken, toke
const handleResetPassword = async (userId: string) => {
if (!accessToken) {
message.error("Access token not found")
NotificationManager.fromBackend("Access token not found")
return
}
try {
@@ -147,7 +148,7 @@ const ViewUserDashboard: React.FC<ViewUserDashboardProps> = ({ accessToken, toke
setInvitationLinkData(data)
setIsInvitationLinkModalVisible(true)
} catch (error) {
message.error("Failed to generate password reset link")
NotificationManager.fromBackend("Failed to generate password reset link")
}
}
@@ -166,7 +167,7 @@ const ViewUserDashboard: React.FC<ViewUserDashboardProps> = ({ accessToken, toke
message.success("User deleted successfully")
} catch (error) {
console.error("Error deleting user:", error)
message.error("Failed to delete user")
NotificationManager.fromBackend("Failed to delete user")
}
}
setIsDeleteModalOpen(false)
@@ -228,7 +229,7 @@ const ViewUserDashboard: React.FC<ViewUserDashboardProps> = ({ accessToken, toke
const handleBulkEdit = () => {
if (selectedUsers.length === 0) {
message.error("Please select users to edit")
NotificationManager.fromBackend("Please select users to edit")
return
}
@@ -15,6 +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";
interface UserInfoViewProps {
userId: string
@@ -83,7 +84,7 @@ export default function UserInfoView({
setUserModels(availableModels)
} catch (error) {
console.error("Error fetching user data:", error)
message.error("Failed to fetch user data")
NotificationManager.fromBackend("Failed to fetch user data")
} finally {
setIsLoading(false)
}
@@ -94,7 +95,7 @@ export default function UserInfoView({
const handleResetPassword = async () => {
if (!accessToken) {
message.error("Access token not found")
NotificationManager.fromBackend("Access token not found")
return
}
try {
@@ -103,7 +104,7 @@ export default function UserInfoView({
setInvitationLinkData(data)
setIsInvitationLinkModalVisible(true)
} catch (error) {
message.error("Failed to generate password reset link")
NotificationManager.fromBackend("Failed to generate password reset link")
}
}
@@ -118,7 +119,7 @@ export default function UserInfoView({
onClose()
} catch (error) {
console.error("Error deleting user:", error)
message.error("Failed to delete user")
NotificationManager.fromBackend("Failed to delete user")
}
}
@@ -144,7 +145,7 @@ export default function UserInfoView({
setIsEditing(false)
} catch (error) {
console.error("Error updating user:", error)
message.error("Failed to update user")
NotificationManager.fromBackend("Failed to update user")
}
}
+2 -1
View File
@@ -1,3 +1,4 @@
import NotificationManager from "@/components/molecules/notifications_manager";
import { message } from "antd";
export function updateExistingKeys<Source extends Object>(
@@ -35,7 +36,7 @@ export const copyToClipboard = async (
message.success(messageText);
return true;
} catch (err) {
message.error("Failed to copy to clipboard");
NotificationManager.fromBackend("Failed to copy to clipboard");
console.error("Failed to copy: ", err);
return false;
}