import React, { useState } from "react"; import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow, Button } from "@/components/ui"; import { Badge } from "@/components/ui"; import { FileText, Terminal, Link, Pencil, Trash2, Zap, Settings } from "lucide-react"; import type { PodInfo } from "@/lib/tauriCommands"; import { deleteResourceCmd, forceDeleteResourceCmd, getResourceYamlCmd } from "@/lib/tauriCommands"; import { ResourceActionMenu } from "./ResourceActionMenu"; import { ConfirmDeleteDialog } from "./ConfirmDeleteDialog"; import { LogStreamPanel } from "./LogStreamPanel"; import { InteractiveShellModal } from "./InteractiveShellModal"; import { InteractiveAttachModal } from "./InteractiveAttachModal"; import { EditResourceModal } from "./EditResourceModal"; import { useColumnConfig } from "@/hooks/useColumnConfig"; import { useMetrics } from "@/hooks/useMetrics"; import { DEFAULT_COLUMNS } from "@/config/defaultColumns"; import { ColumnConfigModal } from "@/components/tables/ColumnConfigModal"; import { QuickActionColumn } from "@/components/tables/QuickActionColumn"; interface PodListProps { pods: PodInfo[]; clusterId: string; namespace: string; onRefresh?: () => void; } type ActiveModal = | { type: "logs"; pod: PodInfo } | { type: "shell"; pod: PodInfo } | { type: "attach"; pod: PodInfo } | { type: "edit"; pod: PodInfo; yaml: string } | { type: "delete"; pod: PodInfo } | { type: "force-delete"; pod: PodInfo } | null; export function PodList({ pods, clusterId, namespace, onRefresh }: PodListProps) { const [activeModal, setActiveModal] = useState(null); const [isDeleting, setIsDeleting] = useState(false); const [editError, setEditError] = useState(null); const [showColumnConfig, setShowColumnConfig] = useState(false); // Configurable columns const columnConfig = useColumnConfig("pods", DEFAULT_COLUMNS.pods); const { isColumnVisible } = columnConfig; // Live pod metrics — only poll when CPU/Memory columns are actually visible. const metricsEnabled = isColumnVisible("cpu") || isColumnVisible("memory"); const { getPodMetrics } = useMetrics( metricsEnabled ? clusterId : null, metricsEnabled ? namespace : null ); const getPodStatusColor = (status: string) => { switch (status.toLowerCase()) { case "running": return "bg-green-500"; case "pending": return "bg-yellow-500"; case "succeeded": case "completed": return "bg-blue-500"; case "failed": case "error": return "bg-red-500"; default: return "bg-gray-500"; } }; const openEdit = async (pod: PodInfo) => { setEditError(null); try { const yaml = await getResourceYamlCmd(clusterId, "pods", pod.namespace, pod.name); setActiveModal({ type: "edit", pod, yaml }); } catch (err) { setEditError(err instanceof Error ? err.message : String(err)); } }; const handleDelete = async (force: boolean) => { const modal = activeModal; if (!modal || (modal.type !== "delete" && modal.type !== "force-delete")) return; setIsDeleting(true); try { if (force) { await forceDeleteResourceCmd(clusterId, "pods", modal.pod.namespace, modal.pod.name); } else { await deleteResourceCmd(clusterId, "pods", modal.pod.namespace, modal.pod.name); } setActiveModal(null); onRefresh?.(); } finally { setIsDeleting(false); } }; const currentPod = activeModal && activeModal.type !== "edit" ? activeModal.pod : null; return ( <> {editError && (

{editError}

)}
{pods.length} {pods.length === 1 ? "pod" : "pods"}
{isColumnVisible("name") && Name} {isColumnVisible("namespace") && Namespace} {isColumnVisible("status") && Status} {isColumnVisible("ready") && Ready} {isColumnVisible("restarts") && Restarts} {isColumnVisible("age") && Age} {isColumnVisible("ip") && IP} {isColumnVisible("node") && Node} {isColumnVisible("cpu") && CPU} {isColumnVisible("memory") && Memory} {isColumnVisible("actions") && Actions} {pods.length === 0 ? ( No pods found ) : ( pods.map((pod) => { const podMetrics = metricsEnabled ? getPodMetrics(pod.name) : undefined; return ( {isColumnVisible("name") && ( {pod.name} )} {isColumnVisible("namespace") && ( {pod.namespace} )} {isColumnVisible("status") && ( {pod.status} )} {isColumnVisible("ready") && {pod.ready}} {isColumnVisible("restarts") && {pod.restarts}} {isColumnVisible("age") && ( {pod.age} )} {isColumnVisible("ip") && ( {pod.ip || "-"} )} {isColumnVisible("node") && ( {pod.node || "-"} )} {isColumnVisible("cpu") && ( {podMetrics?.cpu ?? "-"} )} {isColumnVisible("memory") && ( {podMetrics?.memory ?? "-"} )} {isColumnVisible("actions") && ( setActiveModal({ type: "logs", pod }), }, { label: "Shell", icon: Terminal, onClick: () => setActiveModal({ type: "shell", pod }), }, { label: "Attach", icon: Link, onClick: () => setActiveModal({ type: "attach", pod }), }, { label: "Edit", icon: Pencil, onClick: () => openEdit(pod), }, { label: "Delete", icon: Trash2, variant: "destructive", onClick: () => setActiveModal({ type: "delete", pod }), }, { label: "Force Delete", icon: Zap, variant: "destructive", hidden: !( pod.status.toLowerCase() === "running" || pod.status.toLowerCase() === "pending" ), onClick: () => setActiveModal({ type: "force-delete", pod }), }, ]} /> )} ); }) )}
{activeModal?.type === "logs" && ( { if (!o) setActiveModal(null); }} clusterId={clusterId} namespace={activeModal.pod.namespace} podName={activeModal.pod.name} containers={activeModal.pod.containers} /> )} {activeModal?.type === "shell" && ( setActiveModal(null)} /> )} {activeModal?.type === "attach" && ( setActiveModal(null)} /> )} {activeModal?.type === "edit" && ( { setActiveModal(null); onRefresh?.(); }} /> )} {activeModal?.type === "delete" && currentPod && ( { if (!o) setActiveModal(null); }} resourceType="Pod" resourceName={currentPod.name} isLoading={isDeleting} onConfirm={() => handleDelete(false)} /> )} {activeModal?.type === "force-delete" && currentPod && ( { if (!o) setActiveModal(null); }} resourceType="Pod" resourceName={currentPod.name} variant="force-delete" isLoading={isDeleting} onConfirm={() => handleDelete(true)} /> )} ); }