mirror of
https://github.com/Dokploy/dokploy
synced 2025-06-26 18:27:59 +00:00
feat: add loading spinner when logs are being loaded
This commit is contained in:
@@ -9,7 +9,7 @@ import {
|
||||
SelectValue,
|
||||
} from "@/components/ui/select";
|
||||
import { api } from "@/utils/api";
|
||||
import { Download as DownloadIcon } from "lucide-react";
|
||||
import { Download as DownloadIcon, Loader2 } from "lucide-react";
|
||||
import React, { useEffect, useRef } from "react";
|
||||
import { TerminalLine } from "./terminal-line";
|
||||
import { type LogLine, getLogType, parseLogs } from "./utils";
|
||||
@@ -30,7 +30,7 @@ export const DockerLogsId: React.FC<Props> = ({ containerId, serverId }) => {
|
||||
},
|
||||
{
|
||||
enabled: !!containerId,
|
||||
},
|
||||
}
|
||||
);
|
||||
|
||||
const [rawLogs, setRawLogs] = React.useState("");
|
||||
@@ -41,6 +41,7 @@ export const DockerLogsId: React.FC<Props> = ({ containerId, serverId }) => {
|
||||
const [since, setSince] = React.useState<TimeFilter>("all");
|
||||
const [typeFilter, setTypeFilter] = React.useState<TypeFilter>("all");
|
||||
const scrollRef = useRef<HTMLDivElement>(null);
|
||||
const [isLoading, setIsLoading] = React.useState(false);
|
||||
|
||||
const scrollToBottom = () => {
|
||||
if (autoScroll && scrollRef.current) {
|
||||
@@ -85,6 +86,7 @@ export const DockerLogsId: React.FC<Props> = ({ containerId, serverId }) => {
|
||||
|
||||
useEffect(() => {
|
||||
if (!containerId) return;
|
||||
setIsLoading(true);
|
||||
|
||||
const protocol = window.location.protocol === "https:" ? "wss:" : "ws:";
|
||||
const params = new globalThis.URLSearchParams({
|
||||
@@ -106,19 +108,22 @@ export const DockerLogsId: React.FC<Props> = ({ containerId, serverId }) => {
|
||||
|
||||
ws.onopen = () => {
|
||||
console.log("WebSocket connected");
|
||||
setIsLoading(false)
|
||||
};
|
||||
|
||||
ws.onmessage = (e) => {
|
||||
// console.log("Received message:", e.data);
|
||||
setRawLogs((prev) => prev + e.data);
|
||||
setIsLoading(false);
|
||||
};
|
||||
|
||||
ws.onerror = (error) => {
|
||||
console.error("WebSocket error:", error);
|
||||
setIsLoading(false);
|
||||
};
|
||||
|
||||
ws.onclose = (e) => {
|
||||
console.log("WebSocket closed:", e.reason);
|
||||
setIsLoading(false);
|
||||
};
|
||||
|
||||
return () => {
|
||||
@@ -132,7 +137,7 @@ export const DockerLogsId: React.FC<Props> = ({ containerId, serverId }) => {
|
||||
const logContent = filteredLogs
|
||||
.map(
|
||||
({ timestamp, message }: { timestamp: Date | null; message: string }) =>
|
||||
`${timestamp?.toISOString() || "No timestamp"} ${message}`,
|
||||
`${timestamp?.toISOString() || "No timestamp"} ${message}`
|
||||
)
|
||||
.join("\n");
|
||||
|
||||
@@ -142,7 +147,9 @@ export const DockerLogsId: React.FC<Props> = ({ containerId, serverId }) => {
|
||||
const appName = data.Name.replace("/", "") || "app";
|
||||
const isoDate = new Date().toISOString();
|
||||
a.href = url;
|
||||
a.download = `${appName}-${isoDate.slice(0, 10).replace(/-/g, "")}_${isoDate.slice(11, 19).replace(/:/g, "")}.log.txt`;
|
||||
a.download = `${appName}-${isoDate.slice(0, 10).replace(/-/g, "")}_${isoDate
|
||||
.slice(11, 19)
|
||||
.replace(/:/g, "")}.log.txt`;
|
||||
document.body.appendChild(a);
|
||||
a.click();
|
||||
document.body.removeChild(a);
|
||||
@@ -262,6 +269,10 @@ export const DockerLogsId: React.FC<Props> = ({ containerId, serverId }) => {
|
||||
searchTerm={search}
|
||||
/>
|
||||
))
|
||||
) : isLoading ? (
|
||||
<div className="flex justify-center items-center h-full text-muted-foreground">
|
||||
<Loader2 className="h-6 w-6 animate-spin" />
|
||||
</div>
|
||||
) : (
|
||||
<div className="flex justify-center items-center h-full text-muted-foreground">
|
||||
No logs found
|
||||
|
||||
Reference in New Issue
Block a user