From 6d113a3a5479bdbee2ab537b26fa67fd204faf20 Mon Sep 17 00:00:00 2001 From: Kavirubc Date: Thu, 18 Dec 2025 08:18:14 +0530 Subject: [PATCH 1/9] feat(shared-component): add notification provider infrastructure Add global notification system with: - NotificationContext for type definitions - NotificationProvider component with Snackbar/Alert UI - useNotification hook for accessing notify function - Auto-dismiss notifications after 5 seconds --- .../libs/shared-component/src/index.ts | 1 + .../src/providers/NotificationContext.ts | 30 ++++++++ .../src/providers/NotificationProvider.tsx | 74 +++++++++++++++++++ .../shared-component/src/providers/index.ts | 21 ++++++ .../src/providers/useNotification.ts | 34 +++++++++ 5 files changed, 160 insertions(+) create mode 100644 console/workspaces/libs/shared-component/src/providers/NotificationContext.ts create mode 100644 console/workspaces/libs/shared-component/src/providers/NotificationProvider.tsx create mode 100644 console/workspaces/libs/shared-component/src/providers/index.ts create mode 100644 console/workspaces/libs/shared-component/src/providers/useNotification.ts diff --git a/console/workspaces/libs/shared-component/src/index.ts b/console/workspaces/libs/shared-component/src/index.ts index 700fb529c..efa59110e 100644 --- a/console/workspaces/libs/shared-component/src/index.ts +++ b/console/workspaces/libs/shared-component/src/index.ts @@ -17,3 +17,4 @@ */ export * from './components'; +export * from './providers'; diff --git a/console/workspaces/libs/shared-component/src/providers/NotificationContext.ts b/console/workspaces/libs/shared-component/src/providers/NotificationContext.ts new file mode 100644 index 000000000..6c30dd277 --- /dev/null +++ b/console/workspaces/libs/shared-component/src/providers/NotificationContext.ts @@ -0,0 +1,30 @@ +/** + * Copyright (c) 2025, WSO2 LLC. (https://www.wso2.com). + * + * WSO2 LLC. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import { createContext } from 'react'; + +// Notification severity types matching MUI Alert +export type NotificationType = 'success' | 'error' | 'warning' | 'info'; + +// Shape of the context value +export interface NotificationContextType { + notify: (type: NotificationType, message: string) => void; +} + +// Context with null default - useNotification hook will throw if used outside provider +export const NotificationContext = createContext(null); diff --git a/console/workspaces/libs/shared-component/src/providers/NotificationProvider.tsx b/console/workspaces/libs/shared-component/src/providers/NotificationProvider.tsx new file mode 100644 index 000000000..6d37ef32b --- /dev/null +++ b/console/workspaces/libs/shared-component/src/providers/NotificationProvider.tsx @@ -0,0 +1,74 @@ +/** + * Copyright (c) 2025, WSO2 LLC. (https://www.wso2.com). + * + * WSO2 LLC. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import React, { useCallback, useMemo, useState } from 'react'; +import { Alert, Snackbar } from '@wso2/oxygen-ui'; +import { NotificationContext, NotificationType } from './NotificationContext'; + +interface Notification { + id: string; + type: NotificationType; + message: string; +} + +interface NotificationProviderProps { + children: React.ReactNode; +} + +const AUTO_HIDE_DURATION = 5000; + +export function NotificationProvider({ children }: NotificationProviderProps) { + const [notifications, setNotifications] = useState([]); + + // Add a new notification + const notify = useCallback((type: NotificationType, message: string) => { + const id = Date.now().toString(); + setNotifications((prev) => [...prev, { id, type, message }]); + }, []); + + // Remove a notification by id + const removeNotification = useCallback((id: string) => { + setNotifications((prev) => prev.filter((n) => n.id !== id)); + }, []); + + // Memoize context value to prevent unnecessary re-renders + const contextValue = useMemo(() => ({ notify }), [notify]); + + return ( + + {children} + {/* Render notifications - show only the first one, queue the rest */} + {notifications.length > 0 && ( + removeNotification(notifications[0].id)} + anchorOrigin={{ vertical: 'bottom', horizontal: 'left' }} + > + removeNotification(notifications[0].id)} + sx={{ width: '100%' }} + > + {notifications[0].message} + + + )} + + ); +} diff --git a/console/workspaces/libs/shared-component/src/providers/index.ts b/console/workspaces/libs/shared-component/src/providers/index.ts new file mode 100644 index 000000000..6d78f3af6 --- /dev/null +++ b/console/workspaces/libs/shared-component/src/providers/index.ts @@ -0,0 +1,21 @@ +/** + * Copyright (c) 2025, WSO2 LLC. (https://www.wso2.com). + * + * WSO2 LLC. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +export * from './NotificationContext'; +export * from './NotificationProvider'; +export * from './useNotification'; diff --git a/console/workspaces/libs/shared-component/src/providers/useNotification.ts b/console/workspaces/libs/shared-component/src/providers/useNotification.ts new file mode 100644 index 000000000..04838bebd --- /dev/null +++ b/console/workspaces/libs/shared-component/src/providers/useNotification.ts @@ -0,0 +1,34 @@ +/** + * Copyright (c) 2025, WSO2 LLC. (https://www.wso2.com). + * + * WSO2 LLC. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import { useContext } from 'react'; +import { NotificationContext } from './NotificationContext'; + +/** + * Hook to access notification functions. + * Must be used within a NotificationProvider. + */ +export function useNotification() { + const context = useContext(NotificationContext); + + if (!context) { + throw new Error('useNotification must be used within a NotificationProvider'); + } + + return context; +} From ef9b1e7c1e3e06def3847b70326d0a500fb71a72 Mon Sep 17 00:00:00 2001 From: Kavirubc Date: Thu, 18 Dec 2025 08:18:47 +0530 Subject: [PATCH 2/9] feat(webapp): integrate NotificationProvider into global providers Wrap app with NotificationProvider to enable global notifications --- .../Providers/GlobalProviders/GlobalProviders.tsx | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/console/apps/webapp/src/Providers/GlobalProviders/GlobalProviders.tsx b/console/apps/webapp/src/Providers/GlobalProviders/GlobalProviders.tsx index 97ccd3e9a..a3691286d 100644 --- a/console/apps/webapp/src/Providers/GlobalProviders/GlobalProviders.tsx +++ b/console/apps/webapp/src/Providers/GlobalProviders/GlobalProviders.tsx @@ -18,8 +18,8 @@ import { AuthProvider } from "@agent-management-platform/auth"; import { ClientProvider } from "@agent-management-platform/api-client"; +import { NotificationProvider, ConfirmationDialogProvider } from "@agent-management-platform/shared-component"; import { OxygenUIThemeProvider } from "@wso2/oxygen-ui"; -import { ConfirmationDialogProvider } from "@agent-management-platform/shared-component"; export const GlobalProviders = ({ children, @@ -28,11 +28,13 @@ export const GlobalProviders = ({ }) => { return ( - - - {children} - - + + + + {children} + + + ); }; From 1c708e2a8e8fc27b9ab649112377d163838266b6 Mon Sep 17 00:00:00 2001 From: Kavirubc Date: Thu, 18 Dec 2025 08:19:32 +0530 Subject: [PATCH 3/9] feat(shared-component): add notifications to BuildPanel - Show success notification when build is triggered - Show error notification on build failure - Remove console.error logging --- .../src/components/BuildPanel.tsx | 51 ++++++++++--------- 1 file changed, 26 insertions(+), 25 deletions(-) diff --git a/console/workspaces/libs/shared-component/src/components/BuildPanel.tsx b/console/workspaces/libs/shared-component/src/components/BuildPanel.tsx index 944eea0af..5f8e8d76e 100644 --- a/console/workspaces/libs/shared-component/src/components/BuildPanel.tsx +++ b/console/workspaces/libs/shared-component/src/components/BuildPanel.tsx @@ -21,6 +21,7 @@ import { Wrench } from "@wso2/oxygen-ui-icons-react"; import { Box, Button, Typography } from "@wso2/oxygen-ui"; import { FormProvider, useForm } from "react-hook-form"; import { TextInput, DrawerHeader, DrawerContent } from "@agent-management-platform/views"; +import { useNotification } from "../providers"; interface BuildPanelProps { onClose: () => void; @@ -41,41 +42,41 @@ export function BuildPanel({ agentName, }: BuildPanelProps) { const { mutate: buildAgent, isPending } = useBuildAgent(); + const { notify } = useNotification(); const { data: agent, isLoading: isLoadingAgent } = useGetAgent({ orgName, projName, agentName, - }); const methods = useForm({ + }); + + const methods = useForm({ defaultValues: { branch: "main", commitId: "", }, }); - const handleBuild = async () => { - try { - const formData = methods.getValues(); - buildAgent({ - params: { - orgName, - projName, - agentName, - }, - query: { - commitId: formData.commitId || "", - }, - }, { - onSuccess: () => { - onClose(); - }, - onError: (error) => { - console.error("Build trigger failed:", error); - }, - }); - } - catch (error) { - console.error("Build trigger failed:", error); - } + const handleBuild = () => { + const formData = methods.getValues(); + buildAgent({ + params: { + orgName, + projName, + agentName, + }, + query: { + commitId: formData.commitId || "", + }, + }, { + onSuccess: () => { + notify('success', 'Build triggered successfully'); + onClose(); + }, + onError: (error) => { + const message = error instanceof Error ? error.message : 'Build trigger failed'; + notify('error', message); + }, + }); }; return ( From 6e8cb8175fec6936c3fc85f52da123df5220beb4 Mon Sep 17 00:00:00 2001 From: Kavirubc Date: Thu, 18 Dec 2025 08:20:27 +0530 Subject: [PATCH 4/9] feat(shared-component): add notifications to DeploymentConfig - Show success notification when deployment starts - Show error notification on deployment failure - Remove empty catch block --- .../src/components/DeploymentConfig.tsx | 58 ++++++++++--------- 1 file changed, 31 insertions(+), 27 deletions(-) diff --git a/console/workspaces/libs/shared-component/src/components/DeploymentConfig.tsx b/console/workspaces/libs/shared-component/src/components/DeploymentConfig.tsx index 7c3567fdf..33124bee7 100644 --- a/console/workspaces/libs/shared-component/src/components/DeploymentConfig.tsx +++ b/console/workspaces/libs/shared-component/src/components/DeploymentConfig.tsx @@ -24,6 +24,7 @@ import { EnvironmentVariable } from "./EnvironmentVariable"; import type { Environment, EnvironmentVariable as EnvVar } from "@agent-management-platform/types"; import { useEffect } from "react"; import { TextInput, DrawerHeader, DrawerContent } from "@agent-management-platform/views"; +import { useNotification } from "../providers"; interface DeploymentConfigProps { onClose: () => void; @@ -49,6 +50,7 @@ export function DeploymentConfig({ imageId, }: DeploymentConfigProps) { const { mutate: deployAgent, isPending } = useDeployAgent(); + const { notify } = useNotification(); const { data: agent, isLoading: isLoadingAgent } = useGetAgent({ orgName, projName, @@ -77,34 +79,36 @@ export function DeploymentConfig({ }); }, [configurations, methods]); - const handleDeploy = async () => { - try { - const formData = methods.getValues(); + const handleDeploy = () => { + const formData = methods.getValues(); - const envVariables: EnvVar[] = formData.env - .filter((envVar: { key: string; value: string }) => envVar.key && envVar.value) - .map((envVar: { key: string; value: string }) => ({ - key: envVar.key, - value: envVar.value, - })); - deployAgent({ - params: { - orgName, - projName, - agentName, - }, - body: { - imageId: imageId, - env: envVariables.length > 0 ? envVariables : undefined, - }, - }, { - onSuccess: () => { - onClose(); - }, - }); - } catch { - // Error handling is done by the mutation - } + const envVariables: EnvVar[] = formData.env + .filter((envVar: { key: string; value: string }) => envVar.key && envVar.value) + .map((envVar: { key: string; value: string }) => ({ + key: envVar.key, + value: envVar.value, + })); + + deployAgent({ + params: { + orgName, + projName, + agentName, + }, + body: { + imageId: imageId, + env: envVariables.length > 0 ? envVariables : undefined, + }, + }, { + onSuccess: () => { + notify('success', 'Deployment started successfully'); + onClose(); + }, + onError: (error) => { + const message = error instanceof Error ? error.message : 'Deployment failed'; + notify('error', message); + }, + }); }; From 835417fa379aa8a739935d14ac5a6d3ed8fc79e3 Mon Sep 17 00:00:00 2001 From: Kavirubc Date: Thu, 18 Dec 2025 08:21:16 +0530 Subject: [PATCH 5/9] feat(add-new-agent): add notifications for agent creation - Show success notification when agent is created - Show error notification on creation failure - Remove TODO comment and console.error --- .../workspaces/pages/add-new-agent/src/AddNewAgent.tsx | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/console/workspaces/pages/add-new-agent/src/AddNewAgent.tsx b/console/workspaces/pages/add-new-agent/src/AddNewAgent.tsx index b99895e64..287f67b01 100644 --- a/console/workspaces/pages/add-new-agent/src/AddNewAgent.tsx +++ b/console/workspaces/pages/add-new-agent/src/AddNewAgent.tsx @@ -25,6 +25,7 @@ import { useForm } from 'react-hook-form'; import { yupResolver } from '@hookform/resolvers/yup'; import { addAgentSchema, type AddAgentFormValues } from './form/schema'; import { useCreateAgent, useListAgents } from '@agent-management-platform/api-client'; +import { useNotification } from '@agent-management-platform/shared-component'; import { AgentFlowRouter } from './components/AgentFlowRouter'; import { CreateButtons } from './components/CreateButtons'; import { useAgentFlow } from './hooks/useAgentFlow'; @@ -32,6 +33,7 @@ import { buildAgentCreationPayload } from './utils/buildAgentPayload'; export const AddNewAgent: React.FC = () => { const navigate = useNavigate(); + const { notify } = useNotification(); const { orgId, projectId } = useParams<{ orgId: string; projectId?: string }>(); const methods = useForm({ resolver: yupResolver(addAgentSchema), @@ -80,6 +82,7 @@ export const AddNewAgent: React.FC = () => { createAgent(payload, { onSuccess: () => { + notify('success', 'Agent created successfully'); navigate(generatePath( absoluteRouteMap.children.org.children.projects.children.agents.path, { @@ -91,12 +94,11 @@ export const AddNewAgent: React.FC = () => { ); }, onError: (e: unknown) => { - // TODO: Show error toast/notification to user - // eslint-disable-next-line no-console - console.error('Failed to create agent:', e); + const message = e instanceof Error ? e.message : 'Failed to create agent'; + notify('error', message); } }); - }, [createAgent, navigate, params]); + }, [createAgent, navigate, notify, params]); const handleAddAgent = useMemo(() => methods.handleSubmit(onSubmit), [methods, onSubmit]); From 1a718edb9a4db38e41a638cb97117ac74e4aa08c Mon Sep 17 00:00:00 2001 From: Kavirubc Date: Thu, 18 Dec 2025 08:23:59 +0530 Subject: [PATCH 6/9] chore(add-new-agent): add shared-component dependency Required for useNotification hook --- console/common/config/rush/pnpm-lock.yaml | 3 +++ console/workspaces/pages/add-new-agent/package.json | 1 + 2 files changed, 4 insertions(+) diff --git a/console/common/config/rush/pnpm-lock.yaml b/console/common/config/rush/pnpm-lock.yaml index 03713b39d..4593afd8a 100644 --- a/console/common/config/rush/pnpm-lock.yaml +++ b/console/common/config/rush/pnpm-lock.yaml @@ -718,6 +718,9 @@ importers: '@agent-management-platform/api-client': specifier: workspace:* version: link:../../libs/api-client + '@agent-management-platform/shared-component': + specifier: workspace:* + version: link:../../libs/shared-component '@agent-management-platform/types': specifier: workspace:* version: link:../../libs/types diff --git a/console/workspaces/pages/add-new-agent/package.json b/console/workspaces/pages/add-new-agent/package.json index 8391b1761..f13a0f497 100644 --- a/console/workspaces/pages/add-new-agent/package.json +++ b/console/workspaces/pages/add-new-agent/package.json @@ -48,6 +48,7 @@ "@wso2/oxygen-ui-icons-react": "0.0.1-alpha.9", "@agent-management-platform/views": "workspace:*", "@agent-management-platform/api-client": "workspace:*", + "@agent-management-platform/shared-component": "workspace:*", "@agent-management-platform/types": "workspace:*", "dayjs": "1.11.18", "yup": "1.4.0", From 993031e8cc3997231b3a3bbbbfe65269083d3778 Mon Sep 17 00:00:00 2001 From: Kavirubc Date: Thu, 18 Dec 2025 08:34:36 +0530 Subject: [PATCH 7/9] style(shared-component): move toast notifications to right side --- .../shared-component/src/providers/NotificationProvider.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/console/workspaces/libs/shared-component/src/providers/NotificationProvider.tsx b/console/workspaces/libs/shared-component/src/providers/NotificationProvider.tsx index 6d37ef32b..50dbf7186 100644 --- a/console/workspaces/libs/shared-component/src/providers/NotificationProvider.tsx +++ b/console/workspaces/libs/shared-component/src/providers/NotificationProvider.tsx @@ -58,7 +58,7 @@ export function NotificationProvider({ children }: NotificationProviderProps) { open autoHideDuration={AUTO_HIDE_DURATION} onClose={() => removeNotification(notifications[0].id)} - anchorOrigin={{ vertical: 'bottom', horizontal: 'left' }} + anchorOrigin={{ vertical: 'bottom', horizontal: 'right' }} > Date: Thu, 18 Dec 2025 08:35:57 +0530 Subject: [PATCH 8/9] feat(shared-component): add reusable ConfirmDialog component Reusable confirmation dialog for destructive actions. Props: title, message, confirmLabel, cancelLabel, confirmColor, isLoading --- .../src/components/ConfirmDialog.tsx | 85 +++++++++++++++++++ .../shared-component/src/components/index.ts | 1 + 2 files changed, 86 insertions(+) create mode 100644 console/workspaces/libs/shared-component/src/components/ConfirmDialog.tsx diff --git a/console/workspaces/libs/shared-component/src/components/ConfirmDialog.tsx b/console/workspaces/libs/shared-component/src/components/ConfirmDialog.tsx new file mode 100644 index 000000000..fe37cd4c5 --- /dev/null +++ b/console/workspaces/libs/shared-component/src/components/ConfirmDialog.tsx @@ -0,0 +1,85 @@ +/** + * Copyright (c) 2025, WSO2 LLC. (https://www.wso2.com). + * + * WSO2 LLC. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import React from 'react'; +import { + Dialog, + DialogTitle, + DialogContent, + DialogActions, + Button, + Typography, + CircularProgress, +} from '@wso2/oxygen-ui'; + +export interface ConfirmDialogProps { + open: boolean; + title: string; + message: string; + confirmLabel?: string; + cancelLabel?: string; + confirmColor?: 'error' | 'primary' | 'secondary'; + onConfirm: () => void; + onCancel: () => void; + isLoading?: boolean; +} + +/** + * Reusable confirmation dialog for destructive or important actions. + * Use for delete confirmations, irreversible operations, etc. + */ +export function ConfirmDialog({ + open, + title, + message, + confirmLabel = 'Confirm', + cancelLabel = 'Cancel', + confirmColor = 'error', + onConfirm, + onCancel, + isLoading = false, +}: ConfirmDialogProps) { + return ( + + {title} + + + {message} + + + + + + + + ); +} diff --git a/console/workspaces/libs/shared-component/src/components/index.ts b/console/workspaces/libs/shared-component/src/components/index.ts index efe169801..a1812ef69 100644 --- a/console/workspaces/libs/shared-component/src/components/index.ts +++ b/console/workspaces/libs/shared-component/src/components/index.ts @@ -18,6 +18,7 @@ export * from './BuildLogs'; export * from './BuildPanel'; +export * from './ConfirmDialog'; export * from './BuildSteps'; export * from './CodeBlock'; export * from './DeploymentConfig'; From 4ba2d88ea2e517468dc45d8f243be5e5bae8c5d2 Mon Sep 17 00:00:00 2001 From: Kavirubc Date: Thu, 18 Dec 2025 08:37:36 +0530 Subject: [PATCH 9/9] feat(overview): add delete confirmation dialog for agents - Show confirmation dialog before deleting an agent - Display success/error notifications after deletion --- .../src/components/ConfirmDialog.tsx | 1 - .../overview/src/AgentsList/AgentsList.tsx | 48 ++++++++++++------- 2 files changed, 30 insertions(+), 19 deletions(-) diff --git a/console/workspaces/libs/shared-component/src/components/ConfirmDialog.tsx b/console/workspaces/libs/shared-component/src/components/ConfirmDialog.tsx index fe37cd4c5..69b5b40da 100644 --- a/console/workspaces/libs/shared-component/src/components/ConfirmDialog.tsx +++ b/console/workspaces/libs/shared-component/src/components/ConfirmDialog.tsx @@ -16,7 +16,6 @@ * under the License. */ -import React from 'react'; import { Dialog, DialogTitle, diff --git a/console/workspaces/pages/overview/src/AgentsList/AgentsList.tsx b/console/workspaces/pages/overview/src/AgentsList/AgentsList.tsx index fdb151bea..f7500368d 100644 --- a/console/workspaces/pages/overview/src/AgentsList/AgentsList.tsx +++ b/console/workspaces/pages/overview/src/AgentsList/AgentsList.tsx @@ -61,10 +61,10 @@ import { useDeleteAgent, useGetProject, } from "@agent-management-platform/api-client"; +import { useConfirmationDialog, useNotification } from "@agent-management-platform/shared-component"; import dayjs from "dayjs"; import relativeTime from "dayjs/plugin/relativeTime"; import { AgentTypeSummery } from "./subComponents/AgentTypeSummery"; -import { useConfirmationDialog } from "@agent-management-platform/shared-component"; dayjs.extend(relativeTime); @@ -123,20 +123,42 @@ export const AgentsList: React.FC = () => { projName: projectId, }); const { mutate: deleteAgent, isPending: isDeletingAgent } = useDeleteAgent(); + const { notify } = useNotification(); const { data: project, isLoading: isProjectLoading } = useGetProject({ orgName: orgId, projName: projectId, }); const { addConfirmation } = useConfirmationDialog(); + const handleDeleteAgent = useCallback( - (agentId: string) => { - deleteAgent({ - orgName: orgId, - projName: projectId, - agentName: agentId, + (agentId: string, agentName: string) => { + addConfirmation({ + title: "Delete Agent?", + description: `Are you sure you want to delete the agent "${agentName}"? This action cannot be undone.`, + onConfirm: () => { + deleteAgent( + { + orgName: orgId, + projName: projectId, + agentName: agentId, + }, + { + onSuccess: () => { + notify("success", `Agent "${agentName}" deleted successfully`); + }, + onError: (err) => { + const message = err instanceof Error ? err.message : "Failed to delete agent"; + notify("error", message); + }, + } + ); + }, + confirmButtonColor: "error", + confirmButtonIcon: , + confirmButtonText: "Delete", }); }, - [deleteAgent, orgId, projectId] + [addConfirmation, deleteAgent, orgId, projectId, notify] ); const handleRowMouseEnter = useCallback( @@ -300,16 +322,7 @@ export const AgentsList: React.FC = () => { size="small" onClick={(e) => { e.stopPropagation(); // Prevent row click if any - addConfirmation({ - title: "Delete Agent?", - description: `Are you sure you want to delete the agent "${row.displayName}"? This action cannot be undone.`, - onConfirm: () => { - handleDeleteAgent(row.name); - }, - confirmButtonColor: "error", - confirmButtonIcon: , - confirmButtonText: "Delete", - }); + handleDeleteAgent(row.name, row.displayName); }} > Delete @@ -333,7 +346,6 @@ export const AgentsList: React.FC = () => { theme.palette.primary.main, hoveredAgentId, isTouchDevice, - addConfirmation, handleDeleteAgent, ] );