mirror of
https://github.com/tiennm99/litellm.git
synced 2026-08-23 18:25:22 +00:00
[Fix] UI: Migrate AntD message API to use context-based MessageManager
AntD v5 static message API doesn't render without an App wrapper or useMessage() context holder. Mirrors the existing notification pattern by adding message.useMessage() to AntdGlobalProvider and routing all calls through a new MessageManager module. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.6
parent
e5baa2232f
commit
34d954f8cb
+3
-2
@@ -1,5 +1,6 @@
|
||||
import React from "react";
|
||||
import { Modal, Form, message } from "antd";
|
||||
import { Modal, Form } from "antd";
|
||||
import MessageManager from "@/components/molecules/message_manager";
|
||||
import {
|
||||
AccessGroupBaseForm,
|
||||
AccessGroupFormValues,
|
||||
@@ -37,7 +38,7 @@ export function AccessGroupCreateModal({
|
||||
|
||||
createMutation.mutate(params, {
|
||||
onSuccess: () => {
|
||||
message.success("Access group created successfully");
|
||||
MessageManager.success("Access group created successfully");
|
||||
form.resetFields();
|
||||
onSuccess?.();
|
||||
onCancel();
|
||||
|
||||
+3
-2
@@ -1,5 +1,6 @@
|
||||
import React, { useEffect } from "react";
|
||||
import { Modal, Form, message } from "antd";
|
||||
import { Modal, Form } from "antd";
|
||||
import MessageManager from "@/components/molecules/message_manager";
|
||||
import {
|
||||
AccessGroupBaseForm,
|
||||
AccessGroupFormValues,
|
||||
@@ -55,7 +56,7 @@ export function AccessGroupEditModal({
|
||||
{ accessGroupId: accessGroup.access_group_id, params },
|
||||
{
|
||||
onSuccess: () => {
|
||||
message.success("Access group updated successfully");
|
||||
MessageManager.success("Access group updated successfully");
|
||||
onSuccess?.();
|
||||
onCancel();
|
||||
},
|
||||
|
||||
@@ -3,7 +3,6 @@ import {
|
||||
Modal,
|
||||
Typography,
|
||||
Divider,
|
||||
message,
|
||||
Table,
|
||||
Select,
|
||||
InputNumber,
|
||||
@@ -14,6 +13,7 @@ import {
|
||||
import { userBulkUpdateUserCall, teamBulkMemberAddCall, Member } from "./networking";
|
||||
import { UserEditView } from "./user_edit_view";
|
||||
import NotificationsManager from "./molecules/notifications_manager";
|
||||
import MessageManager from "@/components/molecules/message_manager";
|
||||
|
||||
const { Text, Title } = Typography;
|
||||
|
||||
@@ -188,7 +188,7 @@ const BulkEditUserModal: React.FC<BulkEditUserModalProps> = ({
|
||||
}
|
||||
|
||||
if (failedTeams.length > 0) {
|
||||
message.warning(`Failed to add users to ${failedTeams.length} team(s)`);
|
||||
MessageManager.warning(`Failed to add users to ${failedTeams.length} team(s)`);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { Form, Modal, Input, message } from "antd";
|
||||
import { Form, Modal, Input } from "antd";
|
||||
import MessageManager from "@/components/molecules/message_manager";
|
||||
import { useEffect } from "react";
|
||||
import useAuthorized from "@/app/(dashboard)/hooks/useAuthorized";
|
||||
import { useCloudZeroCreate } from "@/app/(dashboard)/hooks/cloudzero/useCloudZeroCreate";
|
||||
@@ -31,7 +32,7 @@ export default function CloudZeroCreationModal({ open, onOk, onCancel }: CloudZe
|
||||
},
|
||||
{
|
||||
onSuccess: () => {
|
||||
message.success("CloudZero integration created successfully");
|
||||
MessageManager.success("CloudZero integration created successfully");
|
||||
form.resetFields();
|
||||
onOk();
|
||||
},
|
||||
@@ -39,7 +40,7 @@ export default function CloudZeroCreationModal({ open, onOk, onCancel }: CloudZe
|
||||
if (error?.errorFields) {
|
||||
return;
|
||||
}
|
||||
message.error(error?.message || "Failed to create CloudZero integration");
|
||||
MessageManager.error(error?.message || "Failed to create CloudZero integration");
|
||||
},
|
||||
},
|
||||
);
|
||||
@@ -47,7 +48,7 @@ export default function CloudZeroCreationModal({ open, onOk, onCancel }: CloudZe
|
||||
if (error?.errorFields) {
|
||||
return;
|
||||
}
|
||||
message.error(error?.message || "Failed to create CloudZero integration");
|
||||
MessageManager.error(error?.message || "Failed to create CloudZero integration");
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
+8
-7
@@ -3,7 +3,8 @@ import { useCloudZeroExport } from "@/app/(dashboard)/hooks/cloudzero/useCloudZe
|
||||
import { useCloudZeroDeleteSettings } from "@/app/(dashboard)/hooks/cloudzero/useCloudZeroSettings";
|
||||
import useAuthorized from "@/app/(dashboard)/hooks/useAuthorized";
|
||||
import DeleteResourceModal from "@/components/common_components/DeleteResourceModal";
|
||||
import { Alert, Button, Card, Descriptions, Divider, message, Popconfirm, Tag } from "antd";
|
||||
import { Alert, Button, Card, Descriptions, Divider, Popconfirm, Tag } from "antd";
|
||||
import MessageManager from "@/components/molecules/message_manager";
|
||||
import { CheckCircle, Edit, Play, Trash2, Upload } from "lucide-react";
|
||||
import { useState } from "react";
|
||||
import CloudZeroUpdateModal from "./CloudZeroUpdateModal";
|
||||
@@ -30,10 +31,10 @@ export function CloudZeroIntegrationSettings({ settings, onSettingsUpdated }: Cl
|
||||
{ limit: 10 },
|
||||
{
|
||||
onSuccess: (data) => {
|
||||
message.success("Dry run completed successfully");
|
||||
MessageManager.success("Dry run completed successfully");
|
||||
},
|
||||
onError: (error) => {
|
||||
message.error(error?.message || "Failed to perform dry run");
|
||||
MessageManager.error(error?.message || "Failed to perform dry run");
|
||||
},
|
||||
},
|
||||
);
|
||||
@@ -48,10 +49,10 @@ export function CloudZeroIntegrationSettings({ settings, onSettingsUpdated }: Cl
|
||||
{ operation: "replace_hourly" },
|
||||
{
|
||||
onSuccess: () => {
|
||||
message.success("Data successfully exported to CloudZero");
|
||||
MessageManager.success("Data successfully exported to CloudZero");
|
||||
},
|
||||
onError: (error) => {
|
||||
message.error(error?.message || "Failed to export data");
|
||||
MessageManager.error(error?.message || "Failed to export data");
|
||||
},
|
||||
},
|
||||
);
|
||||
@@ -79,12 +80,12 @@ export function CloudZeroIntegrationSettings({ settings, onSettingsUpdated }: Cl
|
||||
|
||||
deleteMutation.mutate(undefined, {
|
||||
onSuccess: () => {
|
||||
message.success("CloudZero integration deleted successfully");
|
||||
MessageManager.success("CloudZero integration deleted successfully");
|
||||
setIsDeleteModalOpen(false);
|
||||
onSettingsUpdated();
|
||||
},
|
||||
onError: (error) => {
|
||||
message.error(error?.message || "Failed to delete CloudZero integration");
|
||||
MessageManager.error(error?.message || "Failed to delete CloudZero integration");
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import { useCloudZeroUpdateSettings } from "@/app/(dashboard)/hooks/cloudzero/useCloudZeroSettings";
|
||||
import useAuthorized from "@/app/(dashboard)/hooks/useAuthorized";
|
||||
import { Form, Input, message, Modal } from "antd";
|
||||
import { Form, Input, Modal } from "antd";
|
||||
import MessageManager from "@/components/molecules/message_manager";
|
||||
import { useEffect } from "react";
|
||||
import { CloudZeroSettings } from "./types";
|
||||
|
||||
@@ -39,7 +40,7 @@ export default function CloudZeroUpdateModal({ open, onOk, onCancel, settings }:
|
||||
},
|
||||
{
|
||||
onSuccess: () => {
|
||||
message.success("CloudZero integration updated successfully");
|
||||
MessageManager.success("CloudZero integration updated successfully");
|
||||
form.resetFields();
|
||||
onOk();
|
||||
},
|
||||
@@ -47,7 +48,7 @@ export default function CloudZeroUpdateModal({ open, onOk, onCancel, settings }:
|
||||
if (error?.errorFields) {
|
||||
return;
|
||||
}
|
||||
message.error(error?.message || "Failed to update CloudZero integration");
|
||||
MessageManager.error(error?.message || "Failed to update CloudZero integration");
|
||||
},
|
||||
},
|
||||
);
|
||||
@@ -55,7 +56,7 @@ export default function CloudZeroUpdateModal({ open, onOk, onCancel, settings }:
|
||||
if (error?.errorFields) {
|
||||
return;
|
||||
}
|
||||
message.error(error?.message || "Failed to update CloudZero integration");
|
||||
MessageManager.error(error?.message || "Failed to update CloudZero integration");
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { Modal, Form, Button, Typography, message } from "antd";
|
||||
import { Modal, Form, Button, Typography } from "antd";
|
||||
import { FolderAddOutlined } from "@ant-design/icons";
|
||||
import MessageManager from "@/components/molecules/message_manager";
|
||||
import {
|
||||
useCreateProject,
|
||||
ProjectCreateParams,
|
||||
@@ -32,12 +33,12 @@ export function CreateProjectModal({
|
||||
|
||||
createMutation.mutate(params, {
|
||||
onSuccess: () => {
|
||||
message.success("Project created successfully");
|
||||
MessageManager.success("Project created successfully");
|
||||
form.resetFields();
|
||||
onClose();
|
||||
},
|
||||
onError: (error) => {
|
||||
message.error(error.message || "Failed to create project");
|
||||
MessageManager.error(error.message || "Failed to create project");
|
||||
},
|
||||
});
|
||||
} catch (error) {
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import { useEffect } from "react";
|
||||
import { Modal, Form, Button, Typography, message } from "antd";
|
||||
import { Modal, Form, Button, Typography } from "antd";
|
||||
import { SaveOutlined } from "@ant-design/icons";
|
||||
import MessageManager from "@/components/molecules/message_manager";
|
||||
import { ProjectResponse } from "@/app/(dashboard)/hooks/projects/useProjects";
|
||||
import {
|
||||
useUpdateProject,
|
||||
@@ -80,12 +81,12 @@ export function EditProjectModal({
|
||||
{ projectId: project.project_id, params },
|
||||
{
|
||||
onSuccess: () => {
|
||||
message.success("Project updated successfully");
|
||||
MessageManager.success("Project updated successfully");
|
||||
onSuccess?.();
|
||||
onClose();
|
||||
},
|
||||
onError: (error) => {
|
||||
message.error(error.message || "Failed to update project");
|
||||
MessageManager.error(error.message || "Failed to update project");
|
||||
},
|
||||
},
|
||||
);
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import React, { useState } from "react";
|
||||
import { Button, Input, Typography, Spin, message } from "antd";
|
||||
import { Button, Input, Typography, Spin } from "antd";
|
||||
import MessageManager from "@/components/molecules/message_manager";
|
||||
import { SearchOutlined, LoadingOutlined } from "@ant-design/icons";
|
||||
import { searchToolQueryCall } from "../networking";
|
||||
import NotificationsManager from "../molecules/notifications_manager";
|
||||
@@ -39,7 +40,7 @@ export const SearchToolTester: React.FC<SearchToolTesterProps> = ({ searchToolNa
|
||||
|
||||
const handleSearch = async () => {
|
||||
if (!query.trim()) {
|
||||
message.warning("Please enter a search query");
|
||||
MessageManager.warning("Please enter a search query");
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
+3
-2
@@ -5,8 +5,9 @@
|
||||
*/
|
||||
|
||||
import { Button as TremorButton } from "@tremor/react";
|
||||
import { Button, message } from "antd";
|
||||
import { Button } from "antd";
|
||||
import React, { useEffect, useState } from "react";
|
||||
import MessageManager from "@/components/molecules/message_manager";
|
||||
import NotificationManager from "../../../molecules/notifications_manager";
|
||||
import { fetchAvailableModels, ModelGroup } from "../../../playground/llm_calls/fetch_models";
|
||||
import { AddFallbacksModal } from "./AddFallbacksModal";
|
||||
@@ -90,7 +91,7 @@ export default function AddFallbacks({
|
||||
(g) => !g.primaryModel || g.fallbackModels.length === 0,
|
||||
);
|
||||
if (invalidGroups.length > 0) {
|
||||
message.error(
|
||||
MessageManager.error(
|
||||
`Please complete configuration for all groups. ${invalidGroups.length} group(s) incomplete.`,
|
||||
);
|
||||
return;
|
||||
|
||||
+3
-2
@@ -5,9 +5,10 @@
|
||||
*/
|
||||
|
||||
import { Button } from "@tremor/react";
|
||||
import { message, Tabs } from "antd";
|
||||
import { Tabs } from "antd";
|
||||
import { Plus } from "lucide-react";
|
||||
import React, { useEffect, useState } from "react";
|
||||
import MessageManager from "@/components/molecules/message_manager";
|
||||
import { FallbackGroup, FallbackGroupConfig } from "./FallbackGroupConfig";
|
||||
|
||||
interface FallbackSelectionFormProps {
|
||||
@@ -60,7 +61,7 @@ export function FallbackSelectionForm({
|
||||
|
||||
const handleRemoveGroup = (targetId: string) => {
|
||||
if (groups.length === 1) {
|
||||
message.warning("At least one group is required");
|
||||
MessageManager.warning("At least one group is required");
|
||||
return;
|
||||
}
|
||||
const newGroups = groups.filter((g) => g.id !== targetId);
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import React, { useState, useEffect } from "react";
|
||||
import { Modal, Form, message, Select, Input, Steps, Radio, Tag, Divider, Switch, InputNumber, Collapse } from "antd";
|
||||
import { Modal, Form, Select, Input, Steps, Radio, Tag, Divider, Switch, InputNumber, Collapse } from "antd";
|
||||
import MessageManager from "@/components/molecules/message_manager";
|
||||
import { Button } from "@tremor/react";
|
||||
import { CheckCircleFilled, KeyOutlined, RobotOutlined, AppstoreOutlined, InfoCircleOutlined } from "@ant-design/icons";
|
||||
import CreatedKeyDisplay from "../shared/CreatedKeyDisplay";
|
||||
@@ -216,7 +217,7 @@ const AddAgentForm: React.FC<AddAgentFormProps> = ({
|
||||
|
||||
const handleCreateAgent = async () => {
|
||||
if (!accessToken) {
|
||||
message.error("No access token available");
|
||||
MessageManager.error("No access token available");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -226,7 +227,7 @@ const AddAgentForm: React.FC<AddAgentFormProps> = ({
|
||||
const values = { ...form.getFieldsValue(true) };
|
||||
const agentData = buildAgentData(values);
|
||||
if (!agentData) {
|
||||
message.error("Failed to build agent data");
|
||||
MessageManager.error("Failed to build agent data");
|
||||
setIsSubmitting(false);
|
||||
return;
|
||||
}
|
||||
@@ -301,7 +302,7 @@ const AddAgentForm: React.FC<AddAgentFormProps> = ({
|
||||
setCreatedKeyValue(keyResponse.key || null);
|
||||
} else if (keyAssignOption === "existing_key") {
|
||||
if (!selectedExistingKey) {
|
||||
message.error("Please select an existing key to assign");
|
||||
MessageManager.error("Please select an existing key to assign");
|
||||
setIsSubmitting(false);
|
||||
return;
|
||||
}
|
||||
@@ -318,7 +319,7 @@ const AddAgentForm: React.FC<AddAgentFormProps> = ({
|
||||
} catch (error) {
|
||||
console.error("Error creating agent:", error);
|
||||
const errorMessage = error instanceof Error ? error.message : String(error);
|
||||
message.error(errorMessage ? `Failed to create agent: ${errorMessage}` : "Failed to create agent");
|
||||
MessageManager.error(errorMessage ? `Failed to create agent: ${errorMessage}` : "Failed to create agent");
|
||||
} finally {
|
||||
setIsSubmitting(false);
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import React, { useState, useEffect } from "react";
|
||||
import { Card, Title, Text, Button as TremorButton, Tab, TabGroup, TabList, TabPanel, TabPanels} from "@tremor/react";
|
||||
import { Form, Input, InputNumber, Button as AntButton, message, Spin, Descriptions, Divider } from "antd";
|
||||
import { Form, Input, InputNumber, Button as AntButton, Spin, Descriptions, Divider } from "antd";
|
||||
import MessageManager from "@/components/molecules/message_manager";
|
||||
import { ArrowLeftIcon } from "@heroicons/react/outline";
|
||||
import { getAgentInfo, patchAgentCall, getAgentCreateMetadata, AgentCreateInfo } from "../networking";
|
||||
import { Agent } from "./types";
|
||||
@@ -72,7 +73,7 @@ const AgentInfoView: React.FC<AgentInfoViewProps> = ({
|
||||
}
|
||||
} catch (error) {
|
||||
console.error("Error fetching agent info:", error);
|
||||
message.error("Failed to load agent information");
|
||||
MessageManager.error("Failed to load agent information");
|
||||
} finally {
|
||||
setIsLoading(false);
|
||||
}
|
||||
@@ -111,12 +112,12 @@ const AgentInfoView: React.FC<AgentInfoViewProps> = ({
|
||||
}
|
||||
|
||||
await patchAgentCall(accessToken, agentId, updateData);
|
||||
message.success("Agent updated successfully");
|
||||
MessageManager.success("Agent updated successfully");
|
||||
setIsEditing(false);
|
||||
fetchAgentInfo();
|
||||
} catch (error) {
|
||||
console.error("Error updating agent:", error);
|
||||
message.error("Failed to update agent");
|
||||
MessageManager.error("Failed to update agent");
|
||||
} finally {
|
||||
setIsSaving(false);
|
||||
}
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
"use client";
|
||||
|
||||
import React, { useCallback, useEffect, useRef, useState, useLayoutEffect } from "react";
|
||||
import { Tooltip, Skeleton, Popover, message } from "antd";
|
||||
import { Tooltip, Skeleton, Popover } from "antd";
|
||||
import MessageManager from "@/components/molecules/message_manager";
|
||||
import {
|
||||
SettingOutlined,
|
||||
PlusOutlined,
|
||||
@@ -212,7 +213,7 @@ const ChatPage: React.FC<ChatPageProps> = ({ accessToken, userRole, userId, user
|
||||
localStorage.setItem(LOCALSTORAGE_MODEL_KEY, JSON.stringify([names[0]]));
|
||||
}
|
||||
})
|
||||
.catch(() => message.error("Could not load models"))
|
||||
.catch(() => MessageManager.error("Could not load models"))
|
||||
.finally(() => setIsLoadingModels(false));
|
||||
}, [accessToken]);
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@ import { Spin, Input, Button, Skeleton } from "antd";
|
||||
import { SearchOutlined, ArrowLeftOutlined, RightOutlined, ToolOutlined, CheckCircleOutlined } from "@ant-design/icons";
|
||||
import { deleteMCPOAuthUserCredential, fetchMCPServers, getMCPOAuthUserCredentialStatus, listMCPTools } from "../networking";
|
||||
import { AUTH_TYPE, MCPServer, MCPTool, handleTransport } from "../mcp_tools/types";
|
||||
import { message } from "antd";
|
||||
import MessageManager from "@/components/molecules/message_manager";
|
||||
import { useUserMcpOAuthFlow } from "@/hooks/useUserMcpOAuthFlow";
|
||||
|
||||
// ── OAuth2 connect button ─────────────────────────────────────────────────────
|
||||
@@ -198,7 +198,7 @@ const MCPAppsPanel: React.FC<Props> = ({ accessToken, selectedServers, onChange
|
||||
const idToFetch = serverId ?? serverName;
|
||||
const result = await listMCPTools(accessToken, idToFetch);
|
||||
if (result?.error) {
|
||||
message.warning(`Could not load tools for ${serverName}`);
|
||||
MessageManager.warning(`Could not load tools for ${serverName}`);
|
||||
return;
|
||||
}
|
||||
// Use the ref so we read the most up-to-date list; guard against duplicates
|
||||
@@ -207,7 +207,7 @@ const MCPAppsPanel: React.FC<Props> = ({ accessToken, selectedServers, onChange
|
||||
onChange([...selectedServersRef.current, serverName]);
|
||||
}
|
||||
} catch {
|
||||
message.warning(`Could not load tools for ${serverName}`);
|
||||
MessageManager.warning(`Could not load tools for ${serverName}`);
|
||||
} finally {
|
||||
setTogglingOn((prev) => {
|
||||
const next = new Set(prev);
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import React, { useEffect, useState } from "react";
|
||||
import { Switch, Spin, message } from "antd";
|
||||
import { Switch, Spin } from "antd";
|
||||
import MessageManager from "@/components/molecules/message_manager";
|
||||
import { fetchMCPServers, listMCPTools } from "../networking";
|
||||
import { MCPServer } from "../mcp_tools/types";
|
||||
|
||||
@@ -57,7 +58,7 @@ const MCPConnectPicker: React.FC<Props> = ({ accessToken, selectedServers, onCha
|
||||
const result = await listMCPTools(accessToken, serverName);
|
||||
// listMCPTools never throws; it returns { tools, error, message } on failure
|
||||
if (result?.error) {
|
||||
message.warning(
|
||||
MessageManager.warning(
|
||||
`Could not load tools for ${serverName} — it will be excluded from this message.`
|
||||
);
|
||||
// Do not add to selectedServers
|
||||
@@ -65,7 +66,7 @@ const MCPConnectPicker: React.FC<Props> = ({ accessToken, selectedServers, onCha
|
||||
}
|
||||
onChange([...selectedServers, serverName]);
|
||||
} catch {
|
||||
message.warning(
|
||||
MessageManager.warning(
|
||||
`Could not load tools for ${serverName} — it will be excluded from this message.`
|
||||
);
|
||||
// Do not add to selectedServers
|
||||
|
||||
@@ -8,7 +8,8 @@
|
||||
*/
|
||||
|
||||
import React, { useCallback, useEffect, useState } from "react";
|
||||
import { Spin, message } from "antd";
|
||||
import { Spin } from "antd";
|
||||
import MessageManager from "@/components/molecules/message_manager";
|
||||
import { DeleteOutlined, LinkOutlined } from "@ant-design/icons";
|
||||
import { Badge, Table, TableBody, TableCell, TableHead, TableHeaderCell, TableRow } from "@tremor/react";
|
||||
import {
|
||||
@@ -77,7 +78,7 @@ const MCPCredentialsTab: React.FC<Props> = ({ accessToken }) => {
|
||||
await deleteMCPOAuthUserCredential(accessToken, serverId);
|
||||
setCredentials((prev) => prev.filter((c) => c.server_id !== serverId));
|
||||
} catch {
|
||||
message.error("Failed to revoke connection. Please try again.");
|
||||
MessageManager.error("Failed to revoke connection. Please try again.");
|
||||
} finally {
|
||||
setRevoking((prev) => { const n = new Set(prev); n.delete(serverId); return n; });
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import React, { useState } from "react";
|
||||
import { Modal, Form, Input, Select, message } from "antd";
|
||||
import { Modal, Form, Input, Select } from "antd";
|
||||
import MessageManager from "@/components/molecules/message_manager";
|
||||
import { Button } from "@tremor/react";
|
||||
import { registerClaudeCodePlugin } from "../networking";
|
||||
import {
|
||||
@@ -43,13 +44,13 @@ const AddPluginForm: React.FC<AddPluginFormProps> = ({
|
||||
|
||||
const handleSubmit = async (values: any) => {
|
||||
if (!accessToken) {
|
||||
message.error("No access token available");
|
||||
MessageManager.error("No access token available");
|
||||
return;
|
||||
}
|
||||
|
||||
// Validate plugin name
|
||||
if (!validatePluginName(values.name)) {
|
||||
message.error(
|
||||
MessageManager.error(
|
||||
"Plugin name must be kebab-case (lowercase letters, numbers, and hyphens only)"
|
||||
);
|
||||
return;
|
||||
@@ -57,7 +58,7 @@ const AddPluginForm: React.FC<AddPluginFormProps> = ({
|
||||
|
||||
// Validate semantic version if provided
|
||||
if (values.version && !isValidSemanticVersion(values.version)) {
|
||||
message.error(
|
||||
MessageManager.error(
|
||||
"Version must be in semantic versioning format (e.g., 1.0.0)"
|
||||
);
|
||||
return;
|
||||
@@ -65,13 +66,13 @@ const AddPluginForm: React.FC<AddPluginFormProps> = ({
|
||||
|
||||
// Validate email if provided
|
||||
if (values.authorEmail && !isValidEmail(values.authorEmail)) {
|
||||
message.error("Invalid email format");
|
||||
MessageManager.error("Invalid email format");
|
||||
return;
|
||||
}
|
||||
|
||||
// Validate homepage URL if provided
|
||||
if (values.homepage && !isValidUrl(values.homepage)) {
|
||||
message.error("Invalid homepage URL format");
|
||||
MessageManager.error("Invalid homepage URL format");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -119,14 +120,14 @@ const AddPluginForm: React.FC<AddPluginFormProps> = ({
|
||||
}
|
||||
|
||||
await registerClaudeCodePlugin(accessToken, pluginData);
|
||||
message.success("Plugin registered successfully");
|
||||
MessageManager.success("Plugin registered successfully");
|
||||
form.resetFields();
|
||||
setSourceType("github");
|
||||
onSuccess();
|
||||
onClose();
|
||||
} catch (error) {
|
||||
console.error("Error registering plugin:", error);
|
||||
message.error("Failed to register plugin");
|
||||
MessageManager.error("Failed to register plugin");
|
||||
} finally {
|
||||
setIsSubmitting(false);
|
||||
}
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
"use client";
|
||||
|
||||
import React, { useState } from "react";
|
||||
import { Modal, Input, Switch, message } from "antd";
|
||||
import { Modal, Input, Switch } from "antd";
|
||||
import MessageManager from "@/components/molecules/message_manager";
|
||||
import {
|
||||
KeyOutlined,
|
||||
LockOutlined,
|
||||
@@ -46,7 +47,7 @@ export const ByokCredentialModal: React.FC<ByokCredentialModalProps> = ({
|
||||
|
||||
const handleAuthorize = async () => {
|
||||
if (!apiKey.trim()) {
|
||||
message.error("Please enter your API key");
|
||||
MessageManager.error("Please enter your API key");
|
||||
return;
|
||||
}
|
||||
setLoading(true);
|
||||
@@ -63,11 +64,11 @@ export const ByokCredentialModal: React.FC<ByokCredentialModalProps> = ({
|
||||
const err = await response.json();
|
||||
throw new Error(err?.detail?.error || "Failed to save credential");
|
||||
}
|
||||
message.success(`Connected to ${serverDisplayName}`);
|
||||
MessageManager.success(`Connected to ${serverDisplayName}`);
|
||||
onSuccess(server.server_id);
|
||||
handleClose();
|
||||
} catch (e: any) {
|
||||
message.error(e.message || "Failed to connect");
|
||||
MessageManager.error(e.message || "Failed to connect");
|
||||
} finally {
|
||||
setLoading(false);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
import { message as staticMessage } from "antd";
|
||||
import type { MessageInstance } from "antd/es/message/interface";
|
||||
|
||||
let messageInstance: MessageInstance | null = null;
|
||||
|
||||
export const setMessageInstance = (instance: MessageInstance) => {
|
||||
messageInstance = instance;
|
||||
};
|
||||
|
||||
const getMessageApi = () => messageInstance || staticMessage;
|
||||
|
||||
const MessageManager = {
|
||||
success(content: string, duration?: number) {
|
||||
getMessageApi().success(content, duration);
|
||||
},
|
||||
|
||||
error(content: string, duration?: number) {
|
||||
getMessageApi().error(content, duration);
|
||||
},
|
||||
|
||||
warning(content: string, duration?: number) {
|
||||
getMessageApi().warning(content, duration);
|
||||
},
|
||||
|
||||
info(content: string, duration?: number) {
|
||||
getMessageApi().info(content, duration);
|
||||
},
|
||||
|
||||
loading(content: string, duration?: number) {
|
||||
return getMessageApi().loading(content, duration);
|
||||
},
|
||||
|
||||
destroy() {
|
||||
getMessageApi().destroy();
|
||||
},
|
||||
};
|
||||
|
||||
export default MessageManager;
|
||||
@@ -68,7 +68,7 @@ export const getInProductNudgesCall = async (accessToken: string) => {
|
||||
/**
|
||||
* Helper file for calls being made to proxy
|
||||
*/
|
||||
import { message } from "antd";
|
||||
import MessageManager from "@/components/molecules/message_manager";
|
||||
import { clearTokenCookies } from "@/utils/cookieUtils";
|
||||
import { TagNewRequest, TagUpdateRequest, TagListResponse, TagInfoResponse } from "./tag_management/types";
|
||||
import { Team } from "./key_team_helpers/key_list";
|
||||
@@ -555,7 +555,7 @@ export const modelCreateCall = async (accessToken: string, formValues: Model) =>
|
||||
console.log("API Response:", data);
|
||||
|
||||
// Close any existing messages before showing new ones
|
||||
message.destroy();
|
||||
MessageManager.destroy();
|
||||
|
||||
// Sequential success messages
|
||||
NotificationsManager.success(`Model ${formValues.model_name} created successfully`);
|
||||
|
||||
@@ -8,7 +8,7 @@ import { formatNumberWithCommas } from "@/utils/dataUtils";
|
||||
import { InfoCircleOutlined } from "@ant-design/icons";
|
||||
import { useQueryClient } from "@tanstack/react-query";
|
||||
import { Accordion, AccordionBody, AccordionHeader, Button, Col, Grid, Text, TextInput, Title } from "@tremor/react";
|
||||
import { Button as Button2, Form, Input, message, Modal, Radio, Select, Switch, Tag, Tooltip } from "antd";
|
||||
import { Button as Button2, Form, Input, Modal, Radio, Select, Switch, Tag, Tooltip } from "antd";
|
||||
import debounce from "lodash/debounce";
|
||||
import React, { useCallback, useEffect, useState } from "react";
|
||||
import { rolesWithWriteAccess } from "../../utils/roles";
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import React from "react";
|
||||
import { Switch, Tooltip, message } from "antd";
|
||||
import { Switch, Tooltip } from "antd";
|
||||
import MessageManager from "@/components/molecules/message_manager";
|
||||
import { CodeOutlined, InfoCircleOutlined, ExclamationCircleOutlined } from "@ant-design/icons";
|
||||
import { Text } from "@tremor/react";
|
||||
|
||||
@@ -38,7 +39,7 @@ const CodeInterpreterTool: React.FC<CodeInterpreterToolProps> = ({
|
||||
|
||||
const handleToggle = (checked: boolean) => {
|
||||
if (checked && !isOpenAI) {
|
||||
message.warning("Code Interpreter is only available for OpenAI models");
|
||||
MessageManager.warning("Code Interpreter is only available for OpenAI models");
|
||||
return;
|
||||
}
|
||||
onEnabledChange(checked);
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import React, { useState, useEffect, useCallback } from "react";
|
||||
import { Button, TabGroup, TabList, Tab, TabPanels, TabPanel } from "@tremor/react";
|
||||
import { Modal, message, Alert } from "antd";
|
||||
import { Modal, Alert } from "antd";
|
||||
import MessageManager from "@/components/molecules/message_manager";
|
||||
import { ExclamationCircleOutlined, InfoCircleOutlined } from "@ant-design/icons";
|
||||
import { isAdminRole } from "@/utils/roles";
|
||||
import PolicyTable from "./policy_table";
|
||||
@@ -80,7 +81,7 @@ const PoliciesPanel: React.FC<PoliciesPanelProps> = ({
|
||||
setPoliciesList(response.policies || []);
|
||||
} catch (error) {
|
||||
console.error("Error fetching policies:", error);
|
||||
message.error("Failed to fetch policies");
|
||||
MessageManager.error("Failed to fetch policies");
|
||||
} finally {
|
||||
setIsLoading(false);
|
||||
}
|
||||
@@ -95,7 +96,7 @@ const PoliciesPanel: React.FC<PoliciesPanelProps> = ({
|
||||
setAttachmentsList(response.attachments || []);
|
||||
} catch (error) {
|
||||
console.error("Error fetching attachments:", error);
|
||||
message.error("Failed to fetch attachments");
|
||||
MessageManager.error("Failed to fetch attachments");
|
||||
} finally {
|
||||
setIsAttachmentsLoading(false);
|
||||
}
|
||||
@@ -148,11 +149,11 @@ const PoliciesPanel: React.FC<PoliciesPanelProps> = ({
|
||||
setIsDeleting(true);
|
||||
try {
|
||||
await deletePolicyCall(accessToken, policyToDelete.policy_id);
|
||||
message.success(`Policy "${policyToDelete.policy_name}" deleted successfully`);
|
||||
MessageManager.success(`Policy "${policyToDelete.policy_name}" deleted successfully`);
|
||||
await fetchPolicies();
|
||||
} catch (error) {
|
||||
console.error("Error deleting policy:", error);
|
||||
message.error("Failed to delete policy");
|
||||
MessageManager.error("Failed to delete policy");
|
||||
} finally {
|
||||
setIsDeleting(false);
|
||||
setIsDeleteModalOpen(false);
|
||||
@@ -177,11 +178,11 @@ const PoliciesPanel: React.FC<PoliciesPanelProps> = ({
|
||||
if (!accessToken) return;
|
||||
try {
|
||||
await deletePolicyAttachmentCall(accessToken, attachmentId);
|
||||
message.success("Attachment deleted successfully");
|
||||
MessageManager.success("Attachment deleted successfully");
|
||||
fetchAttachments();
|
||||
} catch (error) {
|
||||
console.error("Error deleting attachment:", error);
|
||||
message.error("Failed to delete attachment");
|
||||
MessageManager.error("Failed to delete attachment");
|
||||
}
|
||||
},
|
||||
});
|
||||
@@ -193,7 +194,7 @@ const PoliciesPanel: React.FC<PoliciesPanelProps> = ({
|
||||
|
||||
const handleUseTemplate = async (template: any) => {
|
||||
if (!accessToken) {
|
||||
message.error("Authentication required");
|
||||
MessageManager.error("Authentication required");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -221,7 +222,7 @@ const PoliciesPanel: React.FC<PoliciesPanelProps> = ({
|
||||
setIsGuardrailSelectionModalOpen(true);
|
||||
} catch (error) {
|
||||
console.error("Error fetching guardrails:", error);
|
||||
message.error("Failed to load guardrails. Please try again.");
|
||||
MessageManager.error("Failed to load guardrails. Please try again.");
|
||||
}
|
||||
};
|
||||
|
||||
@@ -271,7 +272,7 @@ const PoliciesPanel: React.FC<PoliciesPanelProps> = ({
|
||||
await proceedWithTemplate(enrichedTemplate);
|
||||
} catch (error) {
|
||||
console.error("Error enriching template:", error);
|
||||
message.error("Failed to configure template. Please try again.");
|
||||
MessageManager.error("Failed to configure template. Please try again.");
|
||||
setIsEnrichingTemplate(false);
|
||||
}
|
||||
};
|
||||
@@ -318,15 +319,15 @@ const PoliciesPanel: React.FC<PoliciesPanelProps> = ({
|
||||
|
||||
// Show success message
|
||||
if (createdGuardrails.length > 0) {
|
||||
message.success(
|
||||
MessageManager.success(
|
||||
`Created ${createdGuardrails.length} guardrail${createdGuardrails.length > 1 ? "s" : ""}! Complete the policy form to save.`
|
||||
);
|
||||
} else {
|
||||
message.success("Template ready! Complete the policy form to save.");
|
||||
MessageManager.success("Template ready! Complete the policy form to save.");
|
||||
}
|
||||
|
||||
if (failedGuardrails.length > 0) {
|
||||
message.warning(
|
||||
MessageManager.warning(
|
||||
`Failed to create ${failedGuardrails.length} guardrail(s): ${failedGuardrails.join(", ")}. You may need to create them manually.`
|
||||
);
|
||||
}
|
||||
@@ -348,7 +349,7 @@ const PoliciesPanel: React.FC<PoliciesPanelProps> = ({
|
||||
setTemplateQueue([]);
|
||||
setTemplateQueueProgress(null);
|
||||
console.error("Error creating guardrails:", error);
|
||||
message.error("Failed to create guardrails. Please try again.");
|
||||
MessageManager.error("Failed to create guardrails. Please try again.");
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import React, { useState } from "react";
|
||||
import { Select, Typography, message, Spin } from "antd";
|
||||
import { Select, Typography, Spin } from "antd";
|
||||
import MessageManager from "@/components/molecules/message_manager";
|
||||
import { Button, TextInput } from "@tremor/react";
|
||||
import { ArrowLeftIcon, PlusIcon } from "@heroicons/react/outline";
|
||||
import { DotsVerticalIcon } from "@heroicons/react/solid";
|
||||
@@ -1385,17 +1386,17 @@ export const FlowBuilderPage: React.FC<FlowBuilderPageProps> = ({
|
||||
|
||||
const handleSave = async () => {
|
||||
if (!policyName.trim()) {
|
||||
message.error("Please enter a policy name");
|
||||
MessageManager.error("Please enter a policy name");
|
||||
return;
|
||||
}
|
||||
if (!accessToken) {
|
||||
message.error("No access token available");
|
||||
MessageManager.error("No access token available");
|
||||
return;
|
||||
}
|
||||
|
||||
const emptySteps = pipeline.steps.filter((s) => !s.guardrail);
|
||||
if (emptySteps.length > 0) {
|
||||
message.error("Please select a guardrail for all steps");
|
||||
MessageManager.error("Please select a guardrail for all steps");
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import React, { useState, useEffect, useMemo } from "react";
|
||||
import { Card, Button, Spin, message, Checkbox } from "antd";
|
||||
import { Card, Button, Spin, Checkbox } from "antd";
|
||||
import MessageManager from "@/components/molecules/message_manager";
|
||||
import {
|
||||
ShieldCheckIcon,
|
||||
ShieldExclamationIcon,
|
||||
@@ -184,7 +185,7 @@ const PolicyTemplates: React.FC<PolicyTemplatesProps> = ({ onUseTemplate, onOpen
|
||||
onTemplatesLoaded?.(data);
|
||||
} catch (error) {
|
||||
console.error("Error fetching policy templates:", error);
|
||||
message.error("Failed to fetch policy templates");
|
||||
MessageManager.error("Failed to fetch policy templates");
|
||||
} finally {
|
||||
setIsLoading(false);
|
||||
}
|
||||
|
||||
@@ -3,15 +3,11 @@ import { render, screen, act } from "@testing-library/react";
|
||||
import userEvent from "@testing-library/user-event";
|
||||
import CreatedKeyDisplay from "./CreatedKeyDisplay";
|
||||
|
||||
vi.mock("antd", async (importOriginal) => {
|
||||
const actual = await importOriginal<typeof import("antd")>();
|
||||
return {
|
||||
...actual,
|
||||
message: { success: vi.fn() },
|
||||
};
|
||||
});
|
||||
vi.mock("@/components/molecules/message_manager", () => ({
|
||||
default: { success: vi.fn(), error: vi.fn(), warning: vi.fn(), info: vi.fn(), loading: vi.fn(), destroy: vi.fn() },
|
||||
}));
|
||||
|
||||
import { message } from "antd";
|
||||
import MessageManager from "@/components/molecules/message_manager";
|
||||
|
||||
describe("CreatedKeyDisplay", () => {
|
||||
beforeEach(() => {
|
||||
@@ -52,7 +48,7 @@ describe("CreatedKeyDisplay", () => {
|
||||
|
||||
await user.click(screen.getByRole("button", { name: /copy virtual key/i }));
|
||||
|
||||
expect(message.success).toHaveBeenCalledWith("Key copied to clipboard");
|
||||
expect(MessageManager.success).toHaveBeenCalledWith("Key copied to clipboard");
|
||||
});
|
||||
|
||||
it("should revert button text back after 2 seconds", async () => {
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import React, { useState } from "react";
|
||||
import { CopyToClipboard } from "react-copy-to-clipboard";
|
||||
import { Button, message } from "antd";
|
||||
import { Button } from "antd";
|
||||
import MessageManager from "@/components/molecules/message_manager";
|
||||
|
||||
interface CreatedKeyDisplayProps {
|
||||
apiKey: string;
|
||||
@@ -15,7 +16,7 @@ const CreatedKeyDisplay: React.FC<CreatedKeyDisplayProps> = ({ apiKey }) => {
|
||||
|
||||
const handleCopy = () => {
|
||||
setCopied(true);
|
||||
message.success("Key copied to clipboard");
|
||||
MessageManager.success("Key copied to clipboard");
|
||||
setTimeout(() => setCopied(false), 2000);
|
||||
};
|
||||
|
||||
|
||||
@@ -20,7 +20,8 @@ import { isProxyAdminRole } from "@/utils/roles";
|
||||
import { EditOutlined, InfoCircleOutlined, SaveOutlined } from "@ant-design/icons";
|
||||
import { ArrowLeftIcon } from "@heroicons/react/outline";
|
||||
import { Badge, Card, Grid, Text, TextInput, Title } from "@tremor/react";
|
||||
import { Button, Form, Input, message, Select, Switch, Tabs, Tooltip } from "antd";
|
||||
import { Button, Form, Input, Select, Switch, Tabs, Tooltip } from "antd";
|
||||
import MessageManager from "@/components/molecules/message_manager";
|
||||
import { CheckIcon, CopyIcon } from "lucide-react";
|
||||
import React, { useEffect, useMemo, useState } from "react";
|
||||
import { copyToClipboard as utilCopyToClipboard } from "../../utils/dataUtils";
|
||||
@@ -366,7 +367,7 @@ const TeamInfoView: React.FC<TeamInfoProps> = ({
|
||||
tpm_limit: values.tpm_limit,
|
||||
rpm_limit: values.rpm_limit,
|
||||
};
|
||||
message.destroy(); // Remove all existing toasts
|
||||
MessageManager.destroy(); // Remove all existing toasts
|
||||
|
||||
await teamMemberUpdateCall(accessToken, teamId, member);
|
||||
|
||||
@@ -388,7 +389,7 @@ const TeamInfoView: React.FC<TeamInfoProps> = ({
|
||||
}
|
||||
setIsEditMemberModalVisible(false);
|
||||
|
||||
message.destroy(); // Remove all existing toasts
|
||||
MessageManager.destroy(); // Remove all existing toasts
|
||||
|
||||
NotificationsManager.fromBackend(errMsg);
|
||||
console.error("Error updating team member:", error);
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import React, { useState } from "react";
|
||||
import { Card, Title, Text } from "@tremor/react";
|
||||
import { Upload, Button, Select, Form, message, Alert, Tooltip, Input } from "antd";
|
||||
import { Upload, Button, Select, Form, Alert, Tooltip, Input } from "antd";
|
||||
import MessageManager from "@/components/molecules/message_manager";
|
||||
import { InboxOutlined, InfoCircleOutlined } from "@ant-design/icons";
|
||||
import type { UploadProps } from "antd";
|
||||
import { ragIngestCall } from "../networking";
|
||||
@@ -47,13 +48,13 @@ const CreateVectorStore: React.FC<CreateVectorStoreProps> = ({ accessToken, onSu
|
||||
].includes(file.type);
|
||||
|
||||
if (!isValidType) {
|
||||
message.error(`${file.name} is not a supported file type. Please upload PDF, TXT, DOCX, or MD files.`);
|
||||
MessageManager.error(`${file.name} is not a supported file type. Please upload PDF, TXT, DOCX, or MD files.`);
|
||||
return Upload.LIST_IGNORE;
|
||||
}
|
||||
|
||||
const isLt50M = file.size / 1024 / 1024 < 50;
|
||||
if (!isLt50M) {
|
||||
message.error(`${file.name} must be smaller than 50MB!`);
|
||||
MessageManager.error(`${file.name} must be smaller than 50MB!`);
|
||||
return Upload.LIST_IGNORE;
|
||||
}
|
||||
|
||||
@@ -87,12 +88,12 @@ const CreateVectorStore: React.FC<CreateVectorStoreProps> = ({ accessToken, onSu
|
||||
|
||||
const handleCreateVectorStore = async () => {
|
||||
if (documents.length === 0) {
|
||||
message.warning("Please upload at least one document");
|
||||
MessageManager.warning("Please upload at least one document");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!selectedProvider) {
|
||||
message.warning("Please select a provider");
|
||||
MessageManager.warning("Please select a provider");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -100,7 +101,7 @@ const CreateVectorStore: React.FC<CreateVectorStoreProps> = ({ accessToken, onSu
|
||||
const requiredFields = getProviderSpecificFields(selectedProvider).filter((field) => field.required);
|
||||
for (const field of requiredFields) {
|
||||
if (!providerParams[field.name]) {
|
||||
message.warning(`Please provide ${field.label}`);
|
||||
MessageManager.warning(`Please provide ${field.label}`);
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -108,17 +109,17 @@ const CreateVectorStore: React.FC<CreateVectorStoreProps> = ({ accessToken, onSu
|
||||
// S3 Vectors specific validation
|
||||
if (selectedProvider === "s3_vectors") {
|
||||
if (providerParams.vector_bucket_name && providerParams.vector_bucket_name.length < 3) {
|
||||
message.warning("Vector bucket name must be at least 3 characters");
|
||||
MessageManager.warning("Vector bucket name must be at least 3 characters");
|
||||
return;
|
||||
}
|
||||
if (providerParams.index_name && providerParams.index_name.length > 0 && providerParams.index_name.length < 3) {
|
||||
message.warning("Index name must be at least 3 characters if provided");
|
||||
MessageManager.warning("Index name must be at least 3 characters if provided");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (!accessToken) {
|
||||
message.error("No access token available");
|
||||
MessageManager.error("No access token available");
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import React from "react";
|
||||
import { Table, Badge, Tooltip, message } from "antd";
|
||||
import { Table, Badge, Tooltip } from "antd";
|
||||
import MessageManager from "@/components/molecules/message_manager";
|
||||
import { EyeOutlined, CopyOutlined, DeleteOutlined } from "@ant-design/icons";
|
||||
import { DocumentUpload } from "./types";
|
||||
|
||||
@@ -11,7 +12,7 @@ interface DocumentsTableProps {
|
||||
const DocumentsTable: React.FC<DocumentsTableProps> = ({ documents, onRemove }) => {
|
||||
const handleCopyId = (uid: string) => {
|
||||
navigator.clipboard.writeText(uid);
|
||||
message.success("Document ID copied to clipboard");
|
||||
MessageManager.success("Document ID copied to clipboard");
|
||||
};
|
||||
|
||||
const getStatusBadge = (status: DocumentUpload["status"]) => {
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import React, { useState } from "react";
|
||||
import { Button, Input, Card, Typography, Spin, message, Divider } from "antd";
|
||||
import { Button, Input, Card, Typography, Spin, Divider } from "antd";
|
||||
import MessageManager from "@/components/molecules/message_manager";
|
||||
import { SendOutlined, DatabaseOutlined, LoadingOutlined, DownOutlined, RightOutlined } from "@ant-design/icons";
|
||||
import { vectorStoreSearchCall } from "../networking";
|
||||
import NotificationsManager from "../molecules/notifications_manager";
|
||||
@@ -46,7 +47,7 @@ export const VectorStoreTester: React.FC<VectorStoreTesterProps> = ({ vectorStor
|
||||
|
||||
const handleSearch = async () => {
|
||||
if (!query.trim()) {
|
||||
message.warning("Please enter a search query");
|
||||
MessageManager.warning("Please enter a search query");
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
*/
|
||||
|
||||
import { useState } from 'react';
|
||||
import { message } from 'antd';
|
||||
import MessageManager from "@/components/molecules/message_manager";
|
||||
import { ParsedMessage } from './prettyMessagesTypes';
|
||||
import { SectionHeader } from './SectionHeader';
|
||||
import { CollapsibleMessage } from './CollapsibleMessage';
|
||||
@@ -33,7 +33,7 @@ export function InputCard({ messages, promptTokens, inputCost }: InputCardProps)
|
||||
const handleCopy = () => {
|
||||
const content = lastMessage?.content || '';
|
||||
navigator.clipboard.writeText(content);
|
||||
message.success('Input copied');
|
||||
MessageManager.success('Input copied');
|
||||
};
|
||||
|
||||
return (
|
||||
|
||||
@@ -4,7 +4,8 @@
|
||||
*/
|
||||
|
||||
import { useState } from 'react';
|
||||
import { Typography, message as antdMessage } from 'antd';
|
||||
import { Typography } from 'antd';
|
||||
import MessageManager from "@/components/molecules/message_manager";
|
||||
import { ParsedMessage } from './prettyMessagesTypes';
|
||||
import { SectionHeader } from './SectionHeader';
|
||||
import { SimpleMessageBlock } from './SimpleMessageBlock';
|
||||
@@ -25,7 +26,7 @@ export function OutputCard({ message, completionTokens, outputCost }: OutputCard
|
||||
|
||||
const content = message.content || '';
|
||||
navigator.clipboard.writeText(content);
|
||||
antdMessage.success('Output copied');
|
||||
MessageManager.success('Output copied');
|
||||
};
|
||||
|
||||
if (!message) {
|
||||
|
||||
@@ -1,23 +1,27 @@
|
||||
"use client";
|
||||
|
||||
import React, { useEffect, useRef } from "react";
|
||||
import { notification } from "antd";
|
||||
import { notification, message } from "antd";
|
||||
import { setNotificationInstance } from "@/components/molecules/notifications_manager";
|
||||
import { setMessageInstance } from "@/components/molecules/message_manager";
|
||||
|
||||
export default function AntdGlobalProvider({ children }: { children: React.ReactNode }) {
|
||||
const [api, contextHolder] = notification.useNotification();
|
||||
const [notificationApi, notificationContextHolder] = notification.useNotification();
|
||||
const [messageApi, messageContextHolder] = message.useMessage();
|
||||
const initialized = useRef(false);
|
||||
|
||||
useEffect(() => {
|
||||
if (!initialized.current) {
|
||||
setNotificationInstance(api);
|
||||
setNotificationInstance(notificationApi);
|
||||
setMessageInstance(messageApi);
|
||||
initialized.current = true;
|
||||
}
|
||||
}, [api]);
|
||||
}, [notificationApi, messageApi]);
|
||||
|
||||
return (
|
||||
<>
|
||||
{contextHolder}
|
||||
{notificationContextHolder}
|
||||
{messageContextHolder}
|
||||
{children}
|
||||
</>
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user