import React, { useEffect, useState } from "react"; import { NetworkGraphView } from "@/ui/desktop/dashboard/network-graph"; import { Auth } from "@/ui/desktop/authentication/Auth.tsx"; import { UpdateLog } from "@/ui/desktop/apps/dashboard/apps/UpdateLog.tsx"; import { AlertManager } from "@/ui/desktop/apps/dashboard/apps/alerts/AlertManager.tsx"; import { Button } from "@/components/ui/button.tsx"; import { getUserInfo, getDatabaseHealth, getCookie, getUptime, getVersionInfo, getSSHHosts, getTunnelStatuses, getCredentials, getRecentActivity, resetRecentActivity, getServerMetricsById, type RecentActivityItem, } from "@/ui/main-axios.ts"; import { useSidebar } from "@/components/ui/sidebar.tsx"; import { Separator } from "@/components/ui/separator.tsx"; import { useTabs } from "@/ui/desktop/navigation/tabs/TabContext.tsx"; import { Kbd, KbdGroup } from "@/components/ui/kbd"; import { ChartLine, Clock, Database, FastForward, History, Key, Network, Server, UserPlus, Settings, User, Loader2, Terminal, FolderOpen, Activity, Container, ArrowDownUp, } from "lucide-react"; import { Status } from "@/components/ui/shadcn-io/status"; import { BsLightning } from "react-icons/bs"; import { useTranslation } from "react-i18next"; interface DashboardProps { onSelectView: (view: string) => void; isAuthenticated: boolean; authLoading: boolean; onAuthSuccess: (authData: { isAdmin: boolean; username: string | null; userId: string | null; }) => void; isTopbarOpen: boolean; rightSidebarOpen?: boolean; rightSidebarWidth?: number; } export function Dashboard({ isAuthenticated, authLoading, onAuthSuccess, isTopbarOpen, rightSidebarOpen = false, rightSidebarWidth = 400, }: DashboardProps): React.ReactElement { const { t } = useTranslation(); const [loggedIn, setLoggedIn] = useState(isAuthenticated); const [isAdmin, setIsAdmin] = useState(false); const [, setUsername] = useState(null); const [userId, setUserId] = useState(null); const [dbError, setDbError] = useState(null); const [uptime, setUptime] = useState("0d 0h 0m"); const [versionStatus, setVersionStatus] = useState< "up_to_date" | "requires_update" >("up_to_date"); const [versionText, setVersionText] = useState("v1.8.0"); const [dbHealth, setDbHealth] = useState<"healthy" | "error">("healthy"); const [totalServers, setTotalServers] = useState(0); const [totalTunnels, setTotalTunnels] = useState(0); const [totalCredentials, setTotalCredentials] = useState(0); const [recentActivity, setRecentActivity] = useState( [], ); const [recentActivityLoading, setRecentActivityLoading] = useState(true); const [serverStats, setServerStats] = useState< Array<{ id: number; name: string; cpu: number | null; ram: number | null }> >([]); const [serverStatsLoading, setServerStatsLoading] = useState(true); const [showNetworkGraph, setShowNetworkGraph] = useState(false); const { addTab, setCurrentTab, tabs: tabList, updateTab } = useTabs(); let sidebarState: "expanded" | "collapsed" = "expanded"; try { const sidebar = useSidebar(); sidebarState = sidebar.state; } catch (error) { console.error("Dashboard operation failed:", error); } const topMarginPx = isTopbarOpen ? 74 : 26; const leftMarginPx = sidebarState === "collapsed" ? 26 : 8; const rightMarginPx = 17; const bottomMarginPx = 8; useEffect(() => { setLoggedIn(isAuthenticated); }, [isAuthenticated]); useEffect(() => { if (isAuthenticated) { if (getCookie("jwt")) { getUserInfo() .then((meRes) => { setIsAdmin(!!meRes.is_admin); setUsername(meRes.username || null); setUserId(meRes.userId || null); setDbError(null); }) .catch((err) => { setIsAdmin(false); setUsername(null); setUserId(null); const errorCode = err?.response?.data?.code; if (errorCode === "SESSION_EXPIRED") { console.warn("Session expired - please log in again"); setDbError("Session expired - please log in again"); } else { setDbError(null); } }); getDatabaseHealth() .then(() => { setDbError(null); }) .catch((err) => { if (err?.response?.data?.error?.includes("Database")) { setDbError( "Could not connect to the database. Please try again later.", ); } }); } } }, [isAuthenticated]); useEffect(() => { if (!loggedIn) return; const fetchDashboardData = async () => { try { const uptimeInfo = await getUptime(); setUptime(uptimeInfo.formatted); const versionInfo = await getVersionInfo(); setVersionText(`v${versionInfo.localVersion}`); if ( versionInfo.status === "up_to_date" || versionInfo.status === "requires_update" ) { setVersionStatus(versionInfo.status); } try { await getDatabaseHealth(); setDbHealth("healthy"); } catch { setDbHealth("error"); } const hostsResponse = await getSSHHosts(); const hosts = Array.isArray(hostsResponse) ? hostsResponse : []; setTotalServers(hosts.length); let totalTunnelsCount = 0; for (const host of hosts) { if (host.tunnelConnections) { try { const tunnelConnections = Array.isArray(host.tunnelConnections) ? host.tunnelConnections : JSON.parse(host.tunnelConnections); if (Array.isArray(tunnelConnections)) { totalTunnelsCount += tunnelConnections.length; } } catch (error) { console.error("Dashboard operation failed:", error); } } } setTotalTunnels(totalTunnelsCount); const credentialsResponse = await getCredentials(); const credentials = Array.isArray(credentialsResponse) ? credentialsResponse : []; setTotalCredentials(credentials.length); setRecentActivityLoading(true); const activityResponse = await getRecentActivity(35); const activity = Array.isArray(activityResponse) ? activityResponse : []; setRecentActivity(activity); setRecentActivityLoading(false); setServerStatsLoading(true); const serversWithStats = await Promise.all( hosts .slice(0, 50) .map( async (host: { id: number; name: string; statsConfig?: string | { metricsEnabled?: boolean }; }) => { try { let statsConfig: { metricsEnabled?: boolean } = { metricsEnabled: true, }; if (host.statsConfig) { if (typeof host.statsConfig === "string") { statsConfig = JSON.parse(host.statsConfig); } else { statsConfig = host.statsConfig; } } if (statsConfig.metricsEnabled === false) { return null; } const metrics = await getServerMetricsById(host.id); return { id: host.id, name: host.name || `Host ${host.id}`, cpu: metrics.cpu.percent, ram: metrics.memory.percent, }; } catch { return { id: host.id, name: host.name || `Host ${host.id}`, cpu: null, ram: null, }; } }, ), ); const validServerStats = serversWithStats.filter( ( server, ): server is { id: number; name: string; cpu: number | null; ram: number | null; } => server !== null && server.cpu !== null && server.ram !== null, ); setServerStats(validServerStats); setServerStatsLoading(false); } catch (error) { console.error("Failed to fetch dashboard data:", error); setRecentActivityLoading(false); setServerStatsLoading(false); } }; fetchDashboardData(); const interval = setInterval(fetchDashboardData, 30000); return () => clearInterval(interval); }, [loggedIn]); const handleResetActivity = async () => { try { await resetRecentActivity(); setRecentActivity([]); } catch (error) { console.error("Failed to reset activity:", error); } }; const handleActivityClick = (item: RecentActivityItem) => { getSSHHosts().then((hosts) => { const host = hosts.find((h: { id: number }) => h.id === item.hostId); if (!host) return; if (item.type === "terminal") { addTab({ type: "terminal", title: item.hostName, hostConfig: host, }); } else if (item.type === "file_manager") { addTab({ type: "file_manager", title: item.hostName, hostConfig: host, }); } else if (item.type === "server_stats") { addTab({ type: "server_stats", title: item.hostName, hostConfig: host, }); } else if (item.type === "tunnel") { addTab({ type: "tunnel", title: item.hostName, hostConfig: host, }); } else if (item.type === "docker") { addTab({ type: "docker", title: item.hostName, hostConfig: host, }); } }); }; const handleServerStatClick = (serverId: number, serverName: string) => { getSSHHosts().then((hosts) => { const host = hosts.find((h: { id: number }) => h.id === serverId); if (!host) return; addTab({ type: "server_stats", title: serverName, hostConfig: host, }); }); }; const handleAddHost = () => { const sshManagerTab = tabList.find((t) => t.type === "ssh_manager"); if (sshManagerTab) { updateTab(sshManagerTab.id, { initialTab: "add_host", hostConfig: undefined, }); setCurrentTab(sshManagerTab.id); } else { const id = addTab({ type: "ssh_manager", title: "Host Manager", initialTab: "add_host", }); setCurrentTab(id); } }; const handleAddCredential = () => { const sshManagerTab = tabList.find((t) => t.type === "ssh_manager"); if (sshManagerTab) { updateTab(sshManagerTab.id, { initialTab: "add_credential", hostConfig: undefined, }); setCurrentTab(sshManagerTab.id); } else { const id = addTab({ type: "ssh_manager", title: "Host Manager", initialTab: "add_credential", }); setCurrentTab(id); } }; const handleOpenAdminSettings = () => { const adminTab = tabList.find((t) => t.type === "admin"); if (adminTab) { setCurrentTab(adminTab.id); } else { const id = addTab({ type: "admin", title: "Admin Settings" }); setCurrentTab(id); } }; const handleOpenUserProfile = () => { const userProfileTab = tabList.find((t) => t.type === "user_profile"); if (userProfileTab) { setCurrentTab(userProfileTab.id); } else { const id = addTab({ type: "user_profile", title: "User Profile" }); setCurrentTab(id); } }; return ( <> {!loggedIn ? (
) : (
{t("dashboard.title")}

Press LShift twice to open the command palette

{t("dashboard.serverOverview")}

{t("dashboard.version")}

{versionText}

{t("dashboard.uptime")}

{uptime}

{t("dashboard.database")}

{dbHealth === "healthy" ? t("dashboard.healthy") : t("dashboard.error")}

{t("dashboard.totalServers")}

{totalServers}

{t("dashboard.totalTunnels")}

{totalTunnels}

{t("dashboard.totalCredentials")}

{totalCredentials}

{showNetworkGraph ? ( <> {t("dashboard.networkGraph", { defaultValue: "Network Graph" })} ) : ( <> {t("dashboard.recentActivity")} )}

{recentActivityLoading ? (
{t("dashboard.loadingRecentActivity")}
) : recentActivity.length === 0 ? (

{t("dashboard.noRecentActivity")}

) : ( recentActivity .filter((item, index, array) => { if (index === 0) return true; const prevItem = array[index - 1]; return !( item.hostId === prevItem.hostId && item.type === prevItem.type ); }) .map((item) => ( )) )}
{showNetworkGraph ? ( ) : (
{recentActivityLoading ? (
{t("dashboard.loadingRecentActivity")}
) : recentActivity.length === 0 ? (

{t("dashboard.noRecentActivity")}

) : ( recentActivity.map((item) => ( )) )}
)}

{t("dashboard.quickActions")}

{isAdmin && ( )}

{t("dashboard.serverStats")}

{serverStatsLoading ? (
{t("dashboard.loadingServerStats")}
) : serverStats.length === 0 ? (

{t("dashboard.noServerData")}

) : ( serverStats.map((server) => ( )) )}
)} ); }