// ui/src/components/InstanceCard.tsx import { Button } from "@/components/ui/button"; import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card"; import type { Instance } from "@/types/instance"; import { Edit, FileText, Play, Square, Trash2, MoreHorizontal, Download } from "lucide-react"; import LogsDialog from "@/components/LogDialog"; import HealthBadge from "@/components/HealthBadge"; import BackendBadge from "@/components/BackendBadge"; import { useState } from "react"; import { useInstanceHealth } from "@/hooks/useInstanceHealth"; import { instancesApi } from "@/lib/api"; interface InstanceCardProps { instance: Instance; startInstance: (name: string) => void; stopInstance: (name: string) => void; deleteInstance: (name: string) => void; editInstance: (instance: Instance) => void; } function InstanceCard({ instance, startInstance, stopInstance, deleteInstance, editInstance, }: InstanceCardProps) { const [isLogsOpen, setIsLogsOpen] = useState(false); const [showAllActions, setShowAllActions] = useState(false); const health = useInstanceHealth(instance.name, instance.status); const handleStart = () => { startInstance(instance.name); }; const handleStop = () => { stopInstance(instance.name); }; const handleDelete = () => { if ( confirm(`Are you sure you want to delete instance "${instance.name}"?`) ) { deleteInstance(instance.name); } }; const handleEdit = () => { editInstance(instance); }; const handleLogs = () => { setIsLogsOpen(true); }; const handleExport = () => { void (async () => { try { // Fetch the most up-to-date instance data from the backend const instanceData = await instancesApi.get(instance.name); // Convert to JSON string with pretty formatting (matching backend format) const jsonString = JSON.stringify(instanceData, null, 2); // Create a blob and download link const blob = new Blob([jsonString], { type: "application/json" }); const url = URL.createObjectURL(blob); const link = document.createElement("a"); link.href = url; link.download = `${instance.name}.json`; // Trigger download document.body.appendChild(link); link.click(); // Cleanup document.body.removeChild(link); URL.revokeObjectURL(url); } catch (error) { console.error("Failed to export instance:", error); alert(`Failed to export instance: ${error instanceof Error ? error.message : "Unknown error"}`); } })(); }; const running = instance.status === "running"; return ( <> {/* Header with instance name and status badges */}
{instance.name} {/* Badges row */}
{running && }
{/* Primary actions - always visible */}
{/* Secondary actions - collapsible */} {showAllActions && (
)}
); } export default InstanceCard;