From e7e9f9d45c803dbb073f36e711daf1a34f5a9bc2 Mon Sep 17 00:00:00 2001 From: "Joseph.Rawlings" Date: Thu, 18 Dec 2025 06:03:15 -0500 Subject: [PATCH] Implement feature X to enhance user experience and fix bug Y in module Z --- .../Servers/Proxmox/views/overview.blade.php | 1991 ++++++----------- 1 file changed, 641 insertions(+), 1350 deletions(-) diff --git a/extensions/Servers/Proxmox/views/overview.blade.php b/extensions/Servers/Proxmox/views/overview.blade.php index d167c95ae..e68e6b6f9 100644 --- a/extensions/Servers/Proxmox/views/overview.blade.php +++ b/extensions/Servers/Proxmox/views/overview.blade.php @@ -20,1406 +20,697 @@ @else - - -
-
-
- -
-
-

Cloud-init Configuration Notice

- -
-
-

- Hostname, password, and networking settings are configured automatically via cloud-init. - This applies to standard operating system installations that support cloud-init. However, if you are: -

-
    -
  • Installing from an ISO image
  • -
  • Configuring the operating system manually during installation
  • -
  • Using Windows (which does not support cloud-init)
  • -
-

- You will need to manually configure networking, security settings, and hostname within the operating system, as cloud-init will not be available in these scenarios. -

-
-
-
-
- -
-
-

Server Overview

-
- - - - - -
-
-

- Real-time resource monitoring and server configuration details. -

-
- @php + // Calculate resource metrics $cpuCores = max(1, (int)($status->cpus ?? 1)); $cpuUsagePercent = round(max(0, ($status->cpu ?? 0) * 100), 1); $memoryTotal = (int)($status->maxmem ?? 0); $memoryUsed = (int)($status->mem ?? 0); $memoryPercent = $memoryTotal > 0 ? round(($memoryUsed / $memoryTotal) * 100, 1) : 0; - $manualSnapshotLimit = 5; - $manualSnapshotUsed = $server->statistics()->where('is_automatic', false)->count(); - $manualSnapshotPercent = $manualSnapshotLimit > 0 - ? round(($manualSnapshotUsed / $manualSnapshotLimit) * 100, 1) - : 0; - - $badgeForPercent = function (float $value) { - if ($value >= 100) { - return ['label' => 'Over entitlement', 'class' => 'text-red-600 bg-red-100 dark:text-red-400 dark:bg-red-900']; - } - - if ($value >= 85) { - return ['label' => 'Watchlist', 'class' => 'text-amber-600 bg-amber-100 dark:text-amber-400 dark:bg-amber-900']; - } - - return ['label' => 'Healthy', 'class' => 'text-emerald-600 bg-emerald-100 dark:text-emerald-400 dark:bg-emerald-900']; - }; - - $cpuBadge = $badgeForPercent($cpuUsagePercent); - $memoryBadge = $badgeForPercent($memoryPercent); - $reportedUptime = $this->status && isset($this->status->uptime) - ? $this->formatSeconds($this->status->uptime) - : 'N/A'; - - $powerStats = $this->powerEventStats ?? [ - 'starts' => 0, - 'shutdowns' => 0, - 'reboots' => 0, - 'uptime_percent' => 0, - 'samples' => 0, - ]; - - $resourceAllocations = [ - [ - 'label' => 'CPU Allocation', - 'used_percent' => $cpuUsagePercent, - 'usage_summary' => number_format(($status->cpu ?? 0) * $cpuCores, 2) . ' / ' . $cpuCores . ' vCPU', - 'entitlement_label' => $cpuCores . ' vCPU entitlement', - 'description' => 'Live hypervisor usage sampled directly from the cluster.', - 'gradient' => 'linear-gradient(90deg, #38bdf8 0%, #6366f1 100%)', - 'badge' => $cpuBadge, - ], - [ - 'label' => 'Memory Allocation', - 'used_percent' => $memoryPercent, - 'usage_summary' => ($memoryTotal > 0 - ? \Illuminate\Support\Number::fileSize(bytes: $memoryUsed) . ' / ' . \Illuminate\Support\Number::fileSize(bytes: $memoryTotal) - : \Illuminate\Support\Number::fileSize(bytes: $memoryUsed) . ' / N/A'), - 'entitlement_label' => $memoryTotal > 0 - ? \Illuminate\Support\Number::fileSize(bytes: $memoryTotal) . ' entitlement' - : 'Entitlement unavailable', - 'description' => 'Calculated from the VPS\'s provisioned RAM.', - 'gradient' => 'linear-gradient(90deg, #34d399 0%, #10b981 100%)', - 'badge' => $memoryBadge, - ], - [ - 'label' => 'Hypervisor Uptime', - 'used_percent' => null, - 'usage_summary' => $reportedUptime, - 'entitlement_label' => ($powerStats['starts'] ?? 0) . ' starts • ' . ($powerStats['shutdowns'] ?? 0) . ' shutdowns • ' . ($powerStats['reboots'] ?? 0) . ' reboots', - 'description' => 'Shows the live uptime reported by the hypervisor plus counts from the task history.', - 'gradient' => 'linear-gradient(90deg, #a855f7 0%, #ec4899 100%)', - 'badge' => ['label' => 'Live', 'class' => 'text-blue-600 bg-blue-100 dark:text-blue-400 dark:bg-blue-900'], - ], - ]; - - $networkRates = $this->networkRateStats ?? ['in_rate' => 0, 'out_rate' => 0]; - $formatRate = function ($bytesPerSecond) { - if ($bytesPerSecond >= 1073741824) { - return number_format($bytesPerSecond / 1073741824, 2) . ' GiB/s'; - } - if ($bytesPerSecond >= 1048576) { - return number_format($bytesPerSecond / 1048576, 2) . ' MiB/s'; - } - if ($bytesPerSecond >= 1024) { - return number_format($bytesPerSecond / 1024, 2) . ' KiB/s'; - } - - return number_format($bytesPerSecond, 0) . ' B/s'; - }; - $rateScale = 5 * 1024 * 1024; // 5 MiB/s caps the bar width - $aggregateRate = ($networkRates['in_rate'] ?? 0) + ($networkRates['out_rate'] ?? 0); - $totalNetworkBytes = (int) (($status->netin ?? 0) + ($status->netout ?? 0)); - $totalNetworkFormatted = number_format($totalNetworkBytes / 1024 / 1024, 2); - $lastSampleTimestamp = now()->toIso8601String(); - @endphp - - -
- @foreach($resourceAllocations as $index => $resource) -
-
-

{{ $resource['label'] }}

- @if(isset($resource['badge'])) - - {{ $resource['badge']['label'] }} - - @endif -
-
-
{{ $resource['usage_summary'] }}
-

{{ $resource['entitlement_label'] }}

-
- @if($resource['used_percent'] !== null) -
-
-
-
-
- {{ number_format($resource['used_percent'], 1) }}% - @if($resource['used_percent'] > 100) - Over entitlement - @endif -
-
- @endif -
- @endforeach -
- - -
- -
-
-
- -

Server Information

-
-
-
-
- -
-
- - Status -
-
- @if ($status && $status->status === 'running') - - - Running - - @else - - - Stopped - - @endif -
-
- -
-
- - Operating System -
- {{ $server->os->name }} -
- -
-
- - Hostname -
-
- {{ $server->hostname ?? $status->name ?? 'N/A' }} - -
- - - - -
- - - @if($server->primaryIpv4) -
-
- - IPv4 Address -
-
- {{ $server->primaryIpv4->ip }} - -
-
- @endif - - - @if($server->primaryIpv6) -
-
- - IPv6 Address -
-
- {{ $server->primaryIpv6->ip }} - -
-
- @endif - - -
-
- - Root Password -
-
- - @if(isset($server->password) && $server->password) - •••••••• - @else - Emailed - @endif - - @if(isset($server->password) && $server->password) - - @endif - -
- - - - - - - - -
-
-
-
- - Cancel - - - Save - - - Save & Apply - -
-
- - - - - -
-
- Reinstall Server -

Data permanently deleted. Irreversible.

-
- -
- - - -
-
-
-
- -

DNS Configuration

-
- - - -
-
- -
-
Primary IPv6: {{ $server->primaryIpv6->ip }}
- - -
-
- Virtnet Internal - {{ str_replace(':', '-', $server->primaryIpv6->ip) . '.virtnet.host' }} -
-
- -
-
- - -
-
- nip.io (Public) - {{ str_replace(':', '-', $server->primaryIpv6->ip) . '.nip.io' }} -
-
- -
-
- - -
-
- sslip.io (Public) - {{ str_replace(':', '-', $server->primaryIpv6->ip) . '.sslip.io' }} -
-
- -
-
- - -
-
- backname.io (Public) - {{ str_replace(':', '-', $server->primaryIpv6->ip) . '.backname.io' }} -
-
- -
-
-
-
-
-

- - DNS Resolution -

-

- @ = root domain → {{ $server->primaryIpv6->ip }} | *.@ = wildcard subdomains → same IP -

-

- rDNS PTR: No PTR records via RIR systems except direct contract customers. -

-
-
- - @if(stripos($server->os->name, 'Windows') !== false) -
-
-
-
- -

Windows Server

-
- - - -
-
- -
-
- -
-

IPv4/IPv6 Setup

-

Configure addresses manually within Windows Network Configuration.

-
-
-
- -
-

Licensing Compliance

-

You're responsible for maintaining valid Windows licensing for your installation.

-
-
-
- -
-

Audit Risks

-

Non-compliant installations may be suspended after verification audits.

-
-
-
-
-
- @endif - - - -
-
-
-
- -

Notes

-
- - - -
- (Markdown • Cleared on reinstall) -
- -
- - - - - -
- @if($isEditingNotes) -
- - @if($notesError) -
- - {{ $notesError }} -
- @endif -
- - -
-
- @else -
-
- @if($notes) - {!! \Illuminate\Support\Str::markdown(e($notes), [ - 'allow_unsafe_links' => false, - 'renderer' => ['soft_break' => "
"] - ]) !!} - @else -

No notes yet. Click Edit to add some.

- @endif -
- -
- @endif -
-
-
- - - @php - // Gather comprehensive server information $diskTotal = (int)($status->maxdisk ?? 0); $diskUsed = (int)($status->disk ?? 0); $diskPercent = $diskTotal > 0 ? round(($diskUsed / $diskTotal) * 100, 1) : 0; - // Get product settings for allocated resources + // Uptime + $reportedUptime = $this->status && isset($this->status->uptime) + ? $this->formatSeconds($this->status->uptime) + : 'N/A'; + + // Power stats + $powerStats = $this->powerEventStats ?? [ + 'starts' => 0, + 'shutdowns' => 0, + 'reboots' => 0, + ]; + + // Network + $totalNetIn = (int)($status->netin ?? 0); + $totalNetOut = (int)($status->netout ?? 0); + + // Product/Service info $productSettings = $server->service?->product?->settings ?? collect(); $allocatedCores = $productSettings->where('key', 'cores')->first()?->value ?? $cpuCores; $allocatedMemoryMiB = $productSettings->where('key', 'memory')->first()?->value ?? 0; $allocatedDiskGiB = $productSettings->where('key', 'disk')->first()?->value ?? 0; $allocatedBackups = $productSettings->where('key', 'backups')->first()?->value ?? 0; - - // Network totals - $totalNetIn = (int)($status->netin ?? 0); - $totalNetOut = (int)($status->netout ?? 0); - - // Service/billing info $servicePlan = $server->service?->plan; $serviceExpires = $server->service?->expires_at; $serviceStatus = $server->service?->status ?? 'unknown'; $productName = $server->service?->product?->name ?? 'Unknown Product'; - - // Location info $locationName = $server->node?->location?->name ?? 'Unknown'; $nodeName = $server->node?->name ?? 'Unknown'; + + // Badge helper + $badgeForPercent = function (float $value) { + if ($value >= 100) return ['label' => 'Critical', 'class' => 'bg-error/15 text-error']; + if ($value >= 85) return ['label' => 'Warning', 'class' => 'bg-warning/15 text-warning']; + return ['label' => 'Healthy', 'class' => 'bg-success/15 text-success']; + }; + $cpuBadge = $badgeForPercent($cpuUsagePercent); + $memoryBadge = $badgeForPercent($memoryPercent); @endphp -
-
-
-
-

Server Information

- -

- Comprehensive details about your virtual machine including specifications, billing, and infrastructure information. +

+ + +
+ + + +

+ The Server Overview provides a comprehensive real-time dashboard of your virtual machine's status, resource utilization, and configuration details.

-
-

Specifications: Allocated CPU, RAM, and storage resources.

-

Network: Total bandwidth consumed since VM creation.

-

Billing: Service plan and renewal information.

-

Infrastructure: Datacenter location and node assignment.

+
+

+ Resource Metrics: Live CPU, memory, and storage utilization with health indicators. +

+

+ Server Details: Operating system, hostname, IP addresses, and credentials. +

+

+ DNS Configuration: Available hostname resolution options for your server. +

+

+ Infrastructure: Datacenter location, billing cycle, and service information. +

+
+ + + +
+ + +
+
+ +

Resource Metrics

+ + @if($status && $status->status === 'running') + + Running + @else + + Stopped + @endif + +
+ +
+ +
+
+
+
+ +
+ CPU +
+ {{ $cpuBadge['label'] }} +
+
{{ $cpuUsagePercent }}%
+

{{ number_format(($status->cpu ?? 0) * $cpuCores, 2) }} / {{ $cpuCores }} vCPU

+
+
+
+
+ + +
+
+
+
+ +
+ Memory +
+ {{ $memoryBadge['label'] }} +
+
{{ $memoryPercent }}%
+

{{ \Illuminate\Support\Number::fileSize(bytes: $memoryUsed) }} / {{ \Illuminate\Support\Number::fileSize(bytes: $memoryTotal) }}

+
+
+
+
+ + +
+
+
+
+ +
+ Uptime +
+ Live +
+
{{ $reportedUptime }}
+

{{ $powerStats['starts'] }} starts • {{ $powerStats['shutdowns'] }} shutdowns • {{ $powerStats['reboots'] }} reboots

+
+
+
+ + +
+ + +
+
+ +

Server Details

+
+ +
+ +
+ Status + + @if($status && $status->status === 'running') + + Running + @else + Stopped + @endif + +
+ + +
+ Operating System + {{ $server->os->name }} +
+ + +
+ Hostname +
+ {{ $server->hostname ?? $status->name ?? 'N/A' }} + +
+
+ + + @if($server->primaryIpv4) +
+ IPv4 Address +
+ {{ $server->primaryIpv4->ip }} + +
+
+ @endif + + + @if($server->primaryIpv6) +
+ IPv6 Address +
+ {{ $server->primaryIpv6->ip }} + +
+
+ @endif + + +
+ Root Password +
+ @if(isset($server->password) && $server->password) + •••••••• + + @else + Emailed + @endif + +
+
+
+ + +
+
+ Reinstall Server +

Data permanently deleted. Irreversible.

+
+ +
+
+ + +
+
+ +

DNS Configuration

+ +

+ DNS hostnames that automatically resolve to your server's IP address. These work without any configuration. +

+
+

+ Note: DNS is configured via cloud-init. For Windows or manual configuration, configure DNS directly within the guest OS. +

+ +
+ @if($server->primaryIpv6) + @php + $ipv6Dashed = str_replace(':', '-', $server->primaryIpv6->ip); + $dnsProviders = [ + ['name' => 'Virtnet Internal', 'domain' => $ipv6Dashed . '.virtnet.host', 'badge' => 'Internal'], + ['name' => 'nip.io', 'domain' => $ipv6Dashed . '.nip.io', 'badge' => 'Public'], + ['name' => 'sslip.io', 'domain' => $ipv6Dashed . '.sslip.io', 'badge' => 'Public'], + ['name' => 'backname.io', 'domain' => $ipv6Dashed . '.backname.io', 'badge' => 'Public'], + ]; + @endphp + + @foreach($dnsProviders as $provider) +
+
+
+ {{ $provider['name'] }} + {{ $provider['badge'] }} +
+ {{ $provider['domain'] }} +
+ +
+ @endforeach + @else +
+ +

No IPv6 address assigned

+
+ @endif +
+ +
+

+ + @ = root domain • *.@ = wildcard subdomains +

+
+
+
+ + +
+ + +
+
+ +

Notes

+ (Markdown supported) +
+ +
+
+ +
+ @if($isEditingNotes) +
+ + @if($notesError) +

+ + {{ $notesError }} +

+ @endif +
+ + +
+
+ @else +
+
+ @if($notes) + {!! \Illuminate\Support\Str::markdown(e($notes), ['allow_unsafe_links' => false, 'renderer' => ['soft_break' => "
"]]) !!} + @else +

No notes yet. Click Edit to add some.

+ @endif +
+ +
+ @endif +
+ + +
+
+
+
+ +
+
+ +
+

Export Error

+
+

No notes available to export. Add some notes first.

+ +
+
+
+ + + @if(stripos($server->os->name, 'Windows') !== false) +
+
+ +

Windows Configuration

+
+ +
+

+ Windows doesn't support cloud-init for automated configuration. You'll need to manually configure networking, hostname, and system settings. +

+ +
+
+ +
+

Network Setup

+

Configure IP addresses manually in Windows Network Settings.

+
+
+
+ +
+

Licensing

+

You must maintain valid Windows licensing.

+
+
+
+ +
+

Compliance

+

Non-compliant installations may be suspended.

+
+
+
+
+
+ @endif +
+ + +
+
+ +

Server Information

-
- -
-
-
- +
+
+ +
+
+
+ +
+

Specifications

-

Specifications

-
-
-
- vCPU Cores - {{ $allocatedCores }} cores -
-
- Memory - - @if($allocatedMemoryMiB > 0) - {{ number_format($allocatedMemoryMiB / 1024, 1) }} GiB - @else - {{ \Illuminate\Support\Number::fileSize(bytes: $memoryTotal) }} - @endif - -
-
- Storage - - @if($allocatedDiskGiB > 0) - {{ $allocatedDiskGiB }} GiB - @elseif($diskTotal > 0) - {{ number_format($diskTotal / 1024 / 1024 / 1024, 0) }} GiB - @else - N/A - @endif - -
-
- Backup Slots - {{ $allocatedBackups > 0 ? $allocatedBackups : 'Disabled' }} -
-
- Operating System - {{ $server->os->name ?? 'Unknown' }} -
-
-
- - -
-
-
- -
-

Network Statistics

-
-
-
- Primary IPv4 - {{ $server->primaryIpv4?->address ?? 'Not assigned' }} -
-
- Primary IPv6 - {{ $server->primaryIpv6?->address ? \Illuminate\Support\Str::limit($server->primaryIpv6->address, 20) : 'Not assigned' }} -
-
- Total Inbound - {{ \Illuminate\Support\Number::fileSize(bytes: $totalNetIn) }} -
-
- Total Outbound - {{ \Illuminate\Support\Number::fileSize(bytes: $totalNetOut) }} -
-
- Combined Transfer - {{ \Illuminate\Support\Number::fileSize(bytes: $totalNetIn + $totalNetOut) }} -
-
-
- - -
-
-
- -
-

Billing & Service

-
-
-
- Product - {{ \Illuminate\Support\Str::limit($productName, 20) }} -
-
- Billing Cycle - {{ ucfirst($servicePlan?->billing_period ?? 'N/A') }} -
-
- Service Status - - {{ ucfirst($serviceStatus) }} - -
-
- Next Renewal - - {{ $serviceExpires ? $serviceExpires->format('M d, Y') : 'N/A' }} - -
- @if($serviceExpires) -
- Days Until Renewal - - {{ $serviceExpires->diffInDays(now()) }} days - -
- @endif -
-
- - -
-
-
- -
-

Infrastructure

-
-
-
- Datacenter - {{ $locationName }} -
-
- Hypervisor Node - {{ $nodeName }} -
-
- VM ID - {{ $server->vm_id ?? 'N/A' }} -
-
- VNC Console - - {{ $server->node?->vnc_enabled ? 'Enabled' : 'Disabled' }} - -
-
- Virtualization - KVM/QEMU -
-
-
- - -
-
-
- -
-

Identifiers

-
-
-
- Server ID - {{ $server->id }} -
-
- Service ID - {{ $server->service_id ?? 'N/A' }} -
-
- Hostname - {{ $server->hostname ?? 'N/A' }} -
-
- Created - {{ $server->created_at?->format('M d, Y') ?? 'N/A' }} -
-
- Last Modified - {{ $server->updated_at?->diffForHumans() ?? 'N/A' }} -
-
-
- - -
-
-
- -
-

Current Usage

-
-
-
- CPU Usage -
-
-
-
- {{ $cpuUsagePercent }}% +
+
+ vCPU Cores + {{ $allocatedCores }} cores +
+
+ Memory + + @if($allocatedMemoryMiB > 0) + {{ number_format($allocatedMemoryMiB / 1024, 1) }} GiB + @else + {{ \Illuminate\Support\Number::fileSize(bytes: $memoryTotal) }} + @endif + +
+
+ Storage + + @if($allocatedDiskGiB > 0) + {{ $allocatedDiskGiB }} GiB + @elseif($diskTotal > 0) + {{ number_format($diskTotal / 1024 / 1024 / 1024, 0) }} GiB + @else + N/A + @endif + +
+
+ Backups + {{ $allocatedBackups > 0 ? $allocatedBackups . ' slots' : 'Disabled' }}
-
- Memory Usage -
-
-
-
- {{ $memoryPercent }}% +
+ + +
+
+
+ +
+

Network Transfer

+
+
+
+ Inbound + {{ \Illuminate\Support\Number::fileSize(bytes: $totalNetIn) }} +
+
+ Outbound + {{ \Illuminate\Support\Number::fileSize(bytes: $totalNetOut) }} +
+
+ Total + {{ \Illuminate\Support\Number::fileSize(bytes: $totalNetIn + $totalNetOut) }}
- @if($diskTotal > 0) -
- Disk Usage -
-
-
-
- {{ $diskPercent }}% +
+ + +
+
+
+ +
+

Billing

+
+
+
+ Product + {{ $productName }} +
+
+ Status + {{ ucfirst($serviceStatus) }} +
+
+ Renewal + {{ $serviceExpires ? $serviceExpires->format('M d, Y') : 'N/A' }}
- @endif -
- Uptime - {{ $reportedUptime }} +
+ + +
+
+
+ +
+

Infrastructure

-
- Power State - - {{ $status && $status->status === 'running' ? 'Running' : 'Stopped' }} - +
+
+ Datacenter + {{ $locationName }} +
+
+ Node + {{ $nodeName }} +
+
+ VM ID + {{ $server->vm_id ?? 'N/A' }} +
+
+
+ + +
+
+
+ +
+

Identifiers

+
+
+
+ Server ID + {{ $server->id }} +
+
+ Service ID + {{ $server->service_id ?? 'N/A' }} +
+
+ Created + {{ $server->created_at?->format('M d, Y') ?? 'N/A' }} +
+
+
+ + +
+
+
+ +
+

Live Usage

+
+
+
+ CPU +
+
+
+
+ {{ $cpuUsagePercent }}% +
+
+
+ Memory +
+
+
+
+ {{ $memoryPercent }}% +
+
+ @if($diskTotal > 0) +
+ Disk +
+
+
+
+ {{ $diskPercent }}% +
+
+ @endif
-
+
+
+ @once + -@endonce -@endif + const filename = 'notes-' + new Date().toISOString().split('T')[0] + '.txt'; + window.downloadText(notesText, filename); + }; + + @endonce + @endif