diff --git a/webui/src/components/InstanceCard.tsx b/webui/src/components/InstanceCard.tsx
index a867dd3..8d15ea9 100644
--- a/webui/src/components/InstanceCard.tsx
+++ b/webui/src/components/InstanceCard.tsx
@@ -2,12 +2,13 @@
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 } from "lucide-react";
+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;
@@ -52,6 +53,36 @@ function InstanceCard({
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 (
@@ -131,6 +162,18 @@ function InstanceCard({
Logs
+
+