From f0eec90e75ba3bc455a19ac67c6eda10220bceef Mon Sep 17 00:00:00 2001 From: samang-dauth Date: Sat, 5 Jul 2025 17:00:21 +0700 Subject: [PATCH] feat: Add system info cards to server detail header Adds small cards in the server detail page header to display server system information. --- .../servers/ServerMetricsOverview.tsx | 6 +- .../servers/ServerSystemInfoCard.tsx | 112 ++++++++++++++++++ application/src/pages/ServerDetail.tsx | 11 +- 3 files changed, 123 insertions(+), 6 deletions(-) create mode 100644 application/src/components/servers/ServerSystemInfoCard.tsx diff --git a/application/src/components/servers/ServerMetricsOverview.tsx b/application/src/components/servers/ServerMetricsOverview.tsx index 34ec57a..e706f5e 100644 --- a/application/src/components/servers/ServerMetricsOverview.tsx +++ b/application/src/components/servers/ServerMetricsOverview.tsx @@ -54,8 +54,8 @@ export const ServerMetricsOverview = ({ server }: ServerMetricsOverviewProps) =>
@@ -64,7 +64,7 @@ export const ServerMetricsOverview = ({ server }: ServerMetricsOverviewProps) =>
{percentage.toFixed(1)}% diff --git a/application/src/components/servers/ServerSystemInfoCard.tsx b/application/src/components/servers/ServerSystemInfoCard.tsx new file mode 100644 index 0000000..893b60d --- /dev/null +++ b/application/src/components/servers/ServerSystemInfoCard.tsx @@ -0,0 +1,112 @@ +import { Card, CardContent } from "@/components/ui/card"; +import { Server, Monitor, Cpu, HardDrive, DatabaseIcon, InfoIcon } from "lucide-react"; +import { Server as ServerType } from "@/types/server.types"; + +interface ServerSystemInfoCardProps { + server: ServerType; +} + +export function ServerSystemInfoCard({ server }: ServerSystemInfoCardProps) { + // Parse system_info if it's a string + let systemInfo: any = {}; + if (server.system_info) { + try { + systemInfo = typeof server.system_info === 'string' + ? JSON.parse(server.system_info) + : server.system_info; + } catch (error) { + console.log('Error parsing system_info:', error); + } + } + + const formatBytes = (bytes: number) => { + if (bytes === 0) return '0 Bytes'; + const k = 1024; + const sizes = ['Bytes', 'KB', 'MB', 'GB', 'TB']; + const i = Math.floor(Math.log(bytes) / Math.log(k)); + return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i]; + }; + + const formatUptime = (uptimeSeconds: string | number) => { + const seconds = typeof uptimeSeconds === 'string' ? parseInt(uptimeSeconds) : uptimeSeconds; + const days = Math.floor(seconds / 86400); + const hours = Math.floor((seconds % 86400) / 3600); + const minutes = Math.floor((seconds % 3600) / 60); + + if (days > 0) return `${days}d ${hours}h`; + if (hours > 0) return `${hours}h ${minutes}m`; + return `${minutes}m`; + }; + + // Format the detailed system info string + const getDetailedSystemInfo = () => { + if (typeof server.system_info === 'string' && server.system_info.includes('|')) { + // If system_info is already in the detailed format, return it + return server.system_info; + } + + // Otherwise, build the detailed string from available data + const parts = []; + + // Basic server info + parts.push(server.hostname || 'Unknown'); + parts.push(server.ip_address || 'Unknown IP'); + parts.push(server.os_type || 'Unknown OS'); + + // Parse additional info from system_info if available + if (systemInfo.OSName) { + parts.push(systemInfo.OSName + (systemInfo.OSVersion ? ` ${systemInfo.OSVersion}` : '')); + } + + if (systemInfo.Architecture) { + parts.push(`| ${systemInfo.Architecture}`); + } + + if (systemInfo.KernelVersion) { + parts.push(`| Kernel: ${systemInfo.KernelVersion}`); + } + + if (systemInfo.CPUModel) { + parts.push(`| CPU: ${systemInfo.CPUModel} (${server.cpu_cores || 0} cores)`); + } else if (server.cpu_cores) { + parts.push(`| CPU: ${server.cpu_cores} cores`); + } + + if (server.ram_total) { + parts.push(`| RAM: ${formatBytes(server.ram_total)}`); + } + + if (systemInfo.GoVersion) { + parts.push(`| Go ${systemInfo.GoVersion}`); + } + + if (systemInfo.IPAddress && systemInfo.IPAddress !== server.ip_address) { + parts.push(`| IP: ${systemInfo.IPAddress}`); + } + + // Check for Docker info + const dockerInfo = server.docker || systemInfo.Docker; + if (dockerInfo !== undefined) { + parts.push(`| Docker: ${dockerInfo}`); + } + + return parts.join(' • ').replace(/• \|/g, '|'); + }; + + return ( + + +
+
+ +
+

System Information

+
+ +
+ {getDetailedSystemInfo()} +
+
+
+ ); +} \ No newline at end of file diff --git a/application/src/pages/ServerDetail.tsx b/application/src/pages/ServerDetail.tsx index 4e7fdd1..6522f3a 100644 --- a/application/src/pages/ServerDetail.tsx +++ b/application/src/pages/ServerDetail.tsx @@ -14,6 +14,7 @@ import { ArrowLeft, Server, Database } from "lucide-react"; import { ServerMetricsCharts } from "@/components/servers/ServerMetricsCharts"; import { ServerMetricsOverview } from "@/components/servers/ServerMetricsOverview"; import { ServerHistoryCharts } from "@/components/servers/ServerHistoryCharts"; +import { ServerSystemInfoCard } from "@/components/servers/ServerSystemInfoCard"; const ServerDetail = () => { const { serverId } = useParams(); @@ -136,14 +137,18 @@ const ServerDetail = () => { Monitor server performance metrics and system health {server && ( - {server.hostname} • {server.ip_address} • {server.os_type} • {server.system_info} + {server.hostname} • {server.ip_address} • {server.os_type} )}

- -
+ {/* System Info Card */} + {server && ( +
+ +
+ )}