From 8c6df92fe7ac6eac935e9e7a00ff8be8bedc7a17 Mon Sep 17 00:00:00 2001 From: "Joseph.Rawlings" Date: Sun, 1 Mar 2026 03:47:26 -0500 Subject: [PATCH] Increase status polling interval to 5 seconds across Proxmox views; update layout styles and add new CSS for improved UI elements and animations. --- .../Servers/Proxmox/Livewire/Component.php | 33 +- .../Servers/Proxmox/Livewire/Server.php | 58 +- .../Servers/Proxmox/views/backups.blade.php | 2 +- .../Proxmox/views/backups/create.blade.php | 2 +- .../Proxmox/views/boot-order.blade.php | 2 +- .../Proxmox/views/cloud-init.blade.php | 2 +- .../Proxmox/views/components/layout.blade.php | 1048 +---------------- .../Servers/Proxmox/views/display.blade.php | 2 +- .../Servers/Proxmox/views/firewall.blade.php | 56 +- .../Servers/Proxmox/views/help.blade.php | 2 +- .../Servers/Proxmox/views/network.blade.php | 2 +- .../Servers/Proxmox/views/overview.blade.php | 116 +- .../Servers/Proxmox/views/server.blade.php | 2 +- .../Proxmox/views/statistics.blade.php | 41 +- .../Servers/Proxmox/views/storage.blade.php | 2 +- .../Servers/Proxmox/views/subdomain.blade.php | 2 +- .../Servers/Proxmox/views/system.blade.php | 2 +- .../Servers/Proxmox/views/vnc.blade.php | 2 +- .../Servers/Proxmox/views/xterm.blade.php | 2 +- public/assets/images/bg-blobs.svg | 18 + public/css/proxmox.css | 592 ++++++++++ themes/lucentui/views/layouts/app.blade.php | 37 +- 22 files changed, 712 insertions(+), 1313 deletions(-) create mode 100644 public/assets/images/bg-blobs.svg create mode 100644 public/css/proxmox.css diff --git a/extensions/Servers/Proxmox/Livewire/Component.php b/extensions/Servers/Proxmox/Livewire/Component.php index 20b2ae83e..ae78da73e 100644 --- a/extensions/Servers/Proxmox/Livewire/Component.php +++ b/extensions/Servers/Proxmox/Livewire/Component.php @@ -4,6 +4,7 @@ namespace Paymenter\Extensions\Servers\Proxmox\Livewire; use App\Helpers\ExtensionHelper; use App\Livewire\Component as BaseComponent; +use Illuminate\Support\Facades\Cache; use Paymenter\Extensions\Servers\Proxmox\Models\Server; use Paymenter\Extensions\Servers\Proxmox\Proxmox; @@ -72,7 +73,7 @@ class Component extends BaseComponent } catch (\Throwable $e) { $this->notify('Action failed: ' . $e->getMessage(), 'error'); } finally { - $this->loadVmStatus(); + $this->forceLoadVmStatus(); } } @@ -246,20 +247,27 @@ class Component extends BaseComponent /** * Refresh the cached VM status from Proxmox. + * Cached for 5 seconds to reduce redundant API calls from polling. */ public function loadVmStatus(): void { + $cacheKey = 'proxmox-vm-status-' . $this->server->id; + try { - $proxmox = new Proxmox; - $response = $proxmox->request( - '/nodes/' . $this->server->node->name . '/qemu/' . $this->server->vm_id . '/status/current' - ); - - $data = $response->json()['data'] ?? null; + $data = Cache::remember($cacheKey, 5, function () { + $proxmox = new Proxmox; + $response = $proxmox->request( + '/nodes/' . $this->server->node->name . '/qemu/' . $this->server->vm_id . '/status/current' + ); + + return $response->json()['data'] ?? null; + }); + $this->status = $data ? (object) $data : null; } catch (\Illuminate\Http\Client\ConnectionException $e) { // Timeout or connection error - don't log as error, just set status to null \Log::info('Connection timeout loading VM status for server ' . $this->server->id); + Cache::forget($cacheKey); $this->status = null; } catch (\Throwable $e) { \Log::error('Exception loading VM status for server ' . $this->server->id, [ @@ -268,7 +276,18 @@ class Component extends BaseComponent 'node' => $this->server->node->name ?? 'unknown', 'error' => $e->getMessage(), ]); + Cache::forget($cacheKey); $this->status = null; } } + + /** + * Force-refresh VM status by busting the cache. + * Called after lifecycle actions (start/stop) for immediate feedback. + */ + public function forceLoadVmStatus(): void + { + Cache::forget('proxmox-vm-status-' . $this->server->id); + $this->loadVmStatus(); + } } diff --git a/extensions/Servers/Proxmox/Livewire/Server.php b/extensions/Servers/Proxmox/Livewire/Server.php index aacf7338c..876877034 100644 --- a/extensions/Servers/Proxmox/Livewire/Server.php +++ b/extensions/Servers/Proxmox/Livewire/Server.php @@ -57,48 +57,46 @@ class Server extends Component // Cache for 15 minutes to avoid recalculating for every server return Cache::remember('bandwidth_threshold_95_' . Carbon::now()->format('Y-m'), 900, function () { $startOfMonth = Carbon::now()->startOfMonth(); - - // Get all servers - $allServers = ServerModel::all(); - - if ($allServers->isEmpty()) { + + // Use 2 aggregate queries instead of N+1 (was 2*N+1 queries) + $firstStats = ServerStatistics::selectRaw('server_id, MIN(netin) as first_netin, MIN(netout) as first_netout') + ->where('DateTime', '>=', $startOfMonth) + ->groupBy('server_id') + ->pluck(null, 'server_id'); + + $latestStats = ServerStatistics::selectRaw('server_id, MAX(netin) as last_netin, MAX(netout) as last_netout') + ->where('DateTime', '>=', $startOfMonth) + ->groupBy('server_id') + ->pluck(null, 'server_id'); + + if ($firstStats->isEmpty()) { return 10; // Minimum threshold of 10 GiB } - + $trafficValues = []; - - foreach ($allServers as $server) { - // Get the earliest and latest statistics for this month for each server - $firstStat = ServerStatistics::where('server_id', $server->id) - ->where('DateTime', '>=', $startOfMonth) - ->orderBy('DateTime', 'asc') - ->first(); - - $latestStat = ServerStatistics::where('server_id', $server->id) - ->where('DateTime', '>=', $startOfMonth) - ->orderBy('DateTime', 'desc') - ->first(); - - if ($firstStat && $latestStat) { - // Calculate total traffic (in + out) for the month - $netinDiff = max(0, $latestStat->netin - $firstStat->netin); - $netoutDiff = max(0, $latestStat->netout - $firstStat->netout); - $totalBytes = $netinDiff + $netoutDiff; - - // Convert to GiB and collect - $trafficValues[] = $totalBytes / (1024 * 1024 * 1024); + + foreach ($firstStats as $serverId => $first) { + $latest = $latestStats->get($serverId); + if (!$latest) { + continue; } + + $netinDiff = max(0, $latest->last_netin - $first->first_netin); + $netoutDiff = max(0, $latest->last_netout - $first->first_netout); + $totalBytes = $netinDiff + $netoutDiff; + + $trafficValues[] = $totalBytes / (1024 * 1024 * 1024); } - + if (empty($trafficValues)) { return 10; // Minimum threshold of 10 GiB } - + // Calculate actual 95th percentile by sorting and taking the value at the 95th rank sort($trafficValues); $index = (int) ceil(0.95 * count($trafficValues)) - 1; $threshold95Percent = $trafficValues[$index]; - + // Return the maximum of 95th percentile or 10 GiB minimum return round(max($threshold95Percent, 10), 2); }); diff --git a/extensions/Servers/Proxmox/views/backups.blade.php b/extensions/Servers/Proxmox/views/backups.blade.php index 78d3d0571..fe8da858c 100644 --- a/extensions/Servers/Proxmox/views/backups.blade.php +++ b/extensions/Servers/Proxmox/views/backups.blade.php @@ -1,4 +1,4 @@ - +
diff --git a/extensions/Servers/Proxmox/views/backups/create.blade.php b/extensions/Servers/Proxmox/views/backups/create.blade.php index 381ede8b6..832733a39 100644 --- a/extensions/Servers/Proxmox/views/backups/create.blade.php +++ b/extensions/Servers/Proxmox/views/backups/create.blade.php @@ -1,4 +1,4 @@ -
+
+
Overview diff --git a/extensions/Servers/Proxmox/views/cloud-init.blade.php b/extensions/Servers/Proxmox/views/cloud-init.blade.php index f7e944af8..03fe78813 100644 --- a/extensions/Servers/Proxmox/views/cloud-init.blade.php +++ b/extensions/Servers/Proxmox/views/cloud-init.blade.php @@ -1,4 +1,4 @@ - + +