fix: replace native confirm dialog with React dialog for agent deletion

- Replace synchronous confirm() with proper React Dialog component
- Add state management for delete confirmation dialog
- Prevent immediate deletion before user confirmation
- Add loading states and proper error handling
- Improve UX with clear confirmation message and responsive design
This commit is contained in:
Vivek R
2025-06-24 01:10:26 +05:30
parent 00cd299c2b
commit e0a0ddf6ba

View File

@@ -30,6 +30,14 @@ import {
DropdownMenuItem,
DropdownMenuTrigger,
} from "@/components/ui/dropdown-menu";
import {
Dialog,
DialogContent,
DialogDescription,
DialogFooter,
DialogHeader,
DialogTitle,
} from "@/components/ui/dialog";
import { api, type Agent, type AgentRunWithMetrics } from "@/lib/api";
import { save, open } from "@tauri-apps/plugin-dialog";
import { invoke } from "@tauri-apps/api/core";
@@ -87,6 +95,9 @@ export const CCAgents: React.FC<CCAgentsProps> = ({ onBack, className }) => {
const [selectedAgent, setSelectedAgent] = useState<Agent | null>(null);
const [selectedRunId, setSelectedRunId] = useState<number | null>(null);
const [showGitHubBrowser, setShowGitHubBrowser] = useState(false);
const [showDeleteDialog, setShowDeleteDialog] = useState(false);
const [agentToDelete, setAgentToDelete] = useState<Agent | null>(null);
const [isDeleting, setIsDeleting] = useState(false);
const AGENTS_PER_PAGE = 9; // 3x3 grid
@@ -122,20 +133,46 @@ export const CCAgents: React.FC<CCAgentsProps> = ({ onBack, className }) => {
}
};
const handleDeleteAgent = async (id: number) => {
if (!confirm("Are you sure you want to delete this agent?")) return;
/**
* Initiates the delete agent process by showing the confirmation dialog
* @param agent - The agent to be deleted
*/
const handleDeleteAgent = (agent: Agent) => {
setAgentToDelete(agent);
setShowDeleteDialog(true);
};
/**
* Confirms and executes the agent deletion
* Only called when user explicitly confirms the deletion
*/
const confirmDeleteAgent = async () => {
if (!agentToDelete?.id) return;
try {
await api.deleteAgent(id);
setIsDeleting(true);
await api.deleteAgent(agentToDelete.id);
setToast({ message: "Agent deleted successfully", type: "success" });
await loadAgents();
await loadRuns(); // Reload runs as they might be affected
} catch (err) {
console.error("Failed to delete agent:", err);
setToast({ message: "Failed to delete agent", type: "error" });
} finally {
setIsDeleting(false);
setShowDeleteDialog(false);
setAgentToDelete(null);
}
};
/**
* Cancels the delete operation and closes the dialog
*/
const cancelDeleteAgent = () => {
setShowDeleteDialog(false);
setAgentToDelete(null);
};
const handleEditAgent = (agent: Agent) => {
setSelectedAgent(agent);
setView("edit");
@@ -473,7 +510,7 @@ export const CCAgents: React.FC<CCAgentsProps> = ({ onBack, className }) => {
<Button
size="sm"
variant="ghost"
onClick={() => handleDeleteAgent(agent.id!)}
onClick={() => handleDeleteAgent(agent)}
className="flex items-center gap-1 text-destructive hover:text-destructive"
title="Delete agent"
>
@@ -571,6 +608,50 @@ export const CCAgents: React.FC<CCAgentsProps> = ({ onBack, className }) => {
setToast({ message: "Agent imported successfully from GitHub", type: "success" });
}}
/>
{/* Delete Confirmation Dialog */}
<Dialog open={showDeleteDialog} onOpenChange={setShowDeleteDialog}>
<DialogContent className="sm:max-w-md">
<DialogHeader>
<DialogTitle className="flex items-center gap-2">
<Trash2 className="h-5 w-5 text-destructive" />
Delete Agent
</DialogTitle>
<DialogDescription>
Are you sure you want to delete the agent "{agentToDelete?.name}"?
This action cannot be undone and will permanently remove the agent and all its associated data.
</DialogDescription>
</DialogHeader>
<DialogFooter className="flex flex-col-reverse sm:flex-row sm:justify-end gap-2">
<Button
variant="outline"
onClick={cancelDeleteAgent}
disabled={isDeleting}
className="w-full sm:w-auto"
>
Cancel
</Button>
<Button
variant="destructive"
onClick={confirmDeleteAgent}
disabled={isDeleting}
className="w-full sm:w-auto"
>
{isDeleting ? (
<>
<div className="animate-spin rounded-full h-4 w-4 border-b-2 border-white mr-2" />
Deleting...
</>
) : (
<>
<Trash2 className="h-4 w-4 mr-2" />
Delete Agent
</>
)}
</Button>
</DialogFooter>
</DialogContent>
</Dialog>
</div>
);
};