Enhance Proxmox views with improved loading states and UI updates
- Updated serverplaceholder.blade.php to enhance loading skeletons for server details. - Added navigation breadcrumbs to statistics, subdomain, and system views for better user experience. - Improved loading indicators for CPU, network, memory, and disk charts in statistics.blade.php. - Refined storage.blade.php layout with section dividers and improved drive display, including bus type indicators and quota usage. - Enhanced VNC and Xterm popups with a new header design, loading animations, and reconnect functionality. - Added error handling for VNC and Xterm connections to inform users when unable to connect.
This commit is contained in:
@@ -1,37 +1,4 @@
|
||||
<x-proxmox::layout :server="$server" view="storage" :status="$status" :status-polling="true" :status-polling-interval="'2s'">
|
||||
<style>
|
||||
/* Hide sidebar in problematic resolution range (768px - 1023px) */
|
||||
@media screen and (min-width: 768px) and (max-width: 1023px) {
|
||||
html body > div.w-full.flex.flex-grow > aside.w-64.h-screen,
|
||||
html body > div.w-full.flex > aside.w-64.h-screen,
|
||||
html body aside.w-64.h-screen.mt-14,
|
||||
html body aside.w-64.h-screen.mt-24,
|
||||
body aside.w-64[class*="md:flex"] {
|
||||
display: none !important;
|
||||
visibility: hidden !important;
|
||||
opacity: 0 !important;
|
||||
pointer-events: none !important;
|
||||
width: 0 !important;
|
||||
max-width: 0 !important;
|
||||
overflow: hidden !important;
|
||||
position: absolute !important;
|
||||
left: -9999px !important;
|
||||
}
|
||||
html body > div.w-full.flex.flex-grow > div[class*="md:ml-64"],
|
||||
html body > div.w-full.flex > div[class*="md:ml-64"],
|
||||
body > div > div[class*="md:ml-64"],
|
||||
div[class*="md:ml-64"] {
|
||||
margin-left: 0 !important;
|
||||
}
|
||||
html body > div.w-full.flex.flex-grow > div[class*="rtl:md:mr-64"],
|
||||
html body > div.w-full.flex > div[class*="rtl:md:mr-64"],
|
||||
body > div > div[class*="rtl:md:mr-64"],
|
||||
div[class*="rtl:md:mr-64"] {
|
||||
margin-right: 0 !important;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
@php
|
||||
$vmRunning = $status && $status->status !== 'stopped';
|
||||
@endphp
|
||||
@@ -181,6 +148,9 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Section Divider -->
|
||||
<div class="border-t border-neutral/20"></div>
|
||||
|
||||
<!-- SCSI Controller Configuration -->
|
||||
<div class="bg-background-secondary border border-neutral rounded-lg p-5 space-y-4">
|
||||
<div class="flex items-center justify-between">
|
||||
@@ -269,6 +239,9 @@
|
||||
@endif
|
||||
</div>
|
||||
|
||||
<!-- Section Divider -->
|
||||
<div class="border-t border-neutral/20"></div>
|
||||
|
||||
<!-- Drives List -->
|
||||
<div class="bg-background-secondary border border-neutral rounded-lg overflow-hidden">
|
||||
<div class="p-5 border-b border-neutral">
|
||||
@@ -277,30 +250,55 @@
|
||||
</div>
|
||||
|
||||
@if(count($drives) === 0)
|
||||
<div class="p-8 text-center">
|
||||
<x-ri-hard-drive-2-line class="size-12 mx-auto text-base/30 mb-3" />
|
||||
<p class="text-base/60">No drives attached to this VM.</p>
|
||||
<div class="flex flex-col items-center justify-center py-12 text-center">
|
||||
<div class="flex items-center justify-center w-16 h-16 rounded-2xl bg-base/5 mb-4">
|
||||
<x-ri-hard-drive-2-line class="size-8 text-base/20" />
|
||||
</div>
|
||||
<h3 class="text-sm font-semibold text-base/70 mb-1">No drives attached</h3>
|
||||
<p class="text-xs text-base/50 max-w-sm">Virtual hard disks store your operating system, applications, and data. Add a drive to get started.</p>
|
||||
@if($this->remainingStorage > 0 && !$vmRunning)
|
||||
<button wire:click="openAddDriveModal" class="mt-4 text-primary hover:text-primary/80 text-sm font-medium">
|
||||
Add your first drive →
|
||||
<button wire:click="openAddDriveModal" class="mt-4 inline-flex items-center gap-1.5 text-primary hover:text-primary/80 text-sm font-medium transition-colors">
|
||||
<x-ri-add-line class="size-4" />
|
||||
Add your first drive
|
||||
</button>
|
||||
@elseif($this->remainingStorage > 0 && $vmRunning)
|
||||
<p class="mt-4 text-base/50 text-sm">Power off server to add drives</p>
|
||||
<p class="mt-3 text-base/50 text-xs">Power off server to add drives</p>
|
||||
@endif
|
||||
</div>
|
||||
@else
|
||||
<div class="divide-y divide-neutral">
|
||||
@foreach($drives as $driveKey => $drive)
|
||||
<div wire:key="drive-{{ $driveKey }}" class="p-4 hover:bg-background/50 transition-colors">
|
||||
<div wire:key="drive-{{ $driveKey }}" class="group p-4 hover:bg-background/50 transition-all duration-300 hover:shadow-sm">
|
||||
<div class="flex flex-col lg:flex-row lg:items-center justify-between gap-4">
|
||||
<div class="flex items-start gap-4">
|
||||
<div class="flex items-center justify-center w-10 h-10 rounded-lg bg-primary/10 flex-shrink-0">
|
||||
<x-ri-hard-drive-2-fill class="size-5 text-primary" />
|
||||
@if($drive['bus'] === 'scsi')
|
||||
<x-ri-database-2-line class="size-5 text-primary" />
|
||||
@elseif($drive['bus'] === 'virtio')
|
||||
<x-ri-speed-line class="size-5 text-primary" />
|
||||
@elseif($drive['bus'] === 'sata')
|
||||
<x-ri-hard-drive-2-fill class="size-5 text-primary" />
|
||||
@elseif($drive['bus'] === 'ide')
|
||||
<x-ri-hard-drive-line class="size-5 text-primary" />
|
||||
@else
|
||||
<x-ri-hard-drive-2-fill class="size-5 text-primary" />
|
||||
@endif
|
||||
</div>
|
||||
<div class="min-w-0">
|
||||
<div class="flex items-center gap-2 flex-wrap">
|
||||
<h4 class="font-semibold text-base">{{ $drive['label'] }}</h4>
|
||||
<span class="px-2 py-0.5 text-xs font-medium rounded bg-neutral/30 text-base/70">{{ $driveKey }}</span>
|
||||
@php
|
||||
$busLabel = $busTypes[$drive['bus']]['label'] ?? strtoupper($drive['bus']);
|
||||
$busColor = match($drive['bus']) {
|
||||
'scsi' => 'bg-primary/15 text-primary',
|
||||
'virtio' => 'bg-success/15 text-success',
|
||||
'sata' => 'bg-info/15 text-info',
|
||||
'ide' => 'bg-warning/15 text-warning',
|
||||
default => 'bg-neutral/20 text-base/70',
|
||||
};
|
||||
@endphp
|
||||
<span class="px-2 py-0.5 text-xs font-medium rounded {{ $busColor }}">{{ $busLabel }}</span>
|
||||
@if($drive['ssd'])
|
||||
<span class="px-2 py-0.5 text-xs font-medium rounded bg-success/20 text-success">SSD</span>
|
||||
@endif
|
||||
@@ -308,6 +306,18 @@
|
||||
<span class="px-2 py-0.5 text-xs font-medium rounded bg-info/20 text-info">IO Thread</span>
|
||||
@endif
|
||||
</div>
|
||||
<!-- Drive size relative to quota -->
|
||||
@if($maxAllowedStorage > 0)
|
||||
<div class="w-full max-w-[200px] mt-2">
|
||||
<div class="w-full bg-neutral/20 rounded-full h-1.5 overflow-hidden">
|
||||
@php
|
||||
$drivePercent = min(100, ($drive['size'] / $maxAllowedStorage) * 100);
|
||||
@endphp
|
||||
<div class="bg-primary/60 h-1.5 rounded-full transition-all duration-500" style="width: {{ $drivePercent }}%"></div>
|
||||
</div>
|
||||
<p class="text-[10px] text-base/40 mt-0.5">{{ number_format($drivePercent, 1) }}% of quota</p>
|
||||
</div>
|
||||
@endif
|
||||
<div class="flex flex-wrap gap-2 mt-2">
|
||||
<span class="px-2 py-0.5 text-xs font-medium rounded bg-neutral/20 text-foreground-secondary">{{ number_format($drive['size'], 1) }} GB</span>
|
||||
<span class="px-2 py-0.5 text-xs font-medium rounded bg-neutral/20 text-foreground-secondary">Cache: {{ ucfirst($drive['cache']) }}</span>
|
||||
@@ -316,6 +326,15 @@
|
||||
<span class="px-2 py-0.5 text-xs font-medium rounded bg-success/20 text-success">Discard</span>
|
||||
@endif
|
||||
</div>
|
||||
<!-- Hover-reveal extra details -->
|
||||
<div class="opacity-0 group-hover:opacity-100 max-h-0 group-hover:max-h-40 transition-all duration-300 overflow-hidden">
|
||||
<div class="flex flex-wrap gap-x-4 gap-y-1 mt-2 pt-2 border-t border-neutral/10 text-[11px] text-base/50">
|
||||
<span>Bus: <strong class="text-base/70">{{ strtoupper($drive['bus']) }}{{ $drive['bus_index'] }}</strong></span>
|
||||
<span>SSD Emulation: <strong class="text-base/70">{{ $drive['ssd'] ? 'Yes' : 'No' }}</strong></span>
|
||||
<span>IO Thread: <strong class="text-base/70">{{ $drive['iothread'] ? 'Enabled' : 'Disabled' }}</strong></span>
|
||||
<span>Discard: <strong class="text-base/70">{{ $drive['discard'] ? 'On' : 'Off' }}</strong></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user