import { Badge } from "@/components/ui/badge"; import { Checkbox } from "@/components/ui/checkbox"; import { Dialog, DialogContent, DialogDescription, DialogHeader, DialogTitle, } from "@/components/ui/dialog"; import { Loader2 } from "lucide-react"; import { useEffect, useRef, useState } from "react"; import { TerminalLine } from "../../docker/logs/terminal-line"; import { type LogLine, parseLogs } from "../../docker/logs/utils"; interface Props { logPath: string | null; serverId?: string; open: boolean; onClose: () => void; } export const ShowDeploymentCompose = ({ logPath, open, onClose, serverId, }: Props) => { const [data, setData] = useState(""); const [filteredLogs, setFilteredLogs] = useState([]); const [showExtraLogs, setShowExtraLogs] = useState(false); const wsRef = useRef(null); // Ref to hold WebSocket instance const [autoScroll, setAutoScroll] = useState(true); const scrollRef = useRef(null); const scrollToBottom = () => { if (autoScroll && scrollRef.current) { scrollRef.current.scrollTop = scrollRef.current.scrollHeight; } }; const handleScroll = () => { if (!scrollRef.current) return; const { scrollTop, scrollHeight, clientHeight } = scrollRef.current; const isAtBottom = Math.abs(scrollHeight - scrollTop - clientHeight) < 10; setAutoScroll(isAtBottom); }; useEffect(() => { if (!open || !logPath) return; setData(""); const protocol = window.location.protocol === "https:" ? "wss:" : "ws:"; const wsUrl = `${protocol}//${window.location.host}/listen-deployment?logPath=${logPath}&serverId=${serverId}`; const ws = new WebSocket(wsUrl); wsRef.current = ws; // Store WebSocket instance in ref ws.onmessage = (e) => { setData((currentData) => currentData + e.data); }; ws.onerror = (error) => { console.error("WebSocket error: ", error); }; ws.onclose = () => { wsRef.current = null; }; return () => { if (wsRef.current?.readyState === WebSocket.OPEN) { ws.close(); wsRef.current = null; } }; }, [logPath, open]); useEffect(() => { const logs = parseLogs(data); let filteredLogsResult = logs; if (serverId) { let hideSubsequentLogs = false; filteredLogsResult = logs.filter((log) => { if ( log.message.includes( "===================================EXTRA LOGS============================================", ) ) { hideSubsequentLogs = true; return showExtraLogs; } return showExtraLogs ? true : !hideSubsequentLogs; }); } setFilteredLogs(filteredLogsResult); }, [data, showExtraLogs]); useEffect(() => { scrollToBottom(); if (autoScroll && scrollRef.current) { scrollRef.current.scrollTop = scrollRef.current.scrollHeight; } }, [filteredLogs, autoScroll]); return ( { onClose(); if (!e) { setData(""); } if (wsRef.current) { if (wsRef.current.readyState === WebSocket.OPEN) { wsRef.current.close(); } } }} > Deployment See all the details of this deployment |{" "} {filteredLogs.length} lines {serverId && (
setShowExtraLogs(checked as boolean) } />
)}
{filteredLogs.length > 0 ? ( filteredLogs.map((log: LogLine, index: number) => ( )) ) : (
)}
); };