feat: add unused drives handling and update device bus modal labels for clarity

This commit is contained in:
2025-12-05 04:28:15 -05:00
parent 3a42c267b0
commit dfb1de9abf
2 changed files with 68 additions and 7 deletions

View File

@@ -15,6 +15,11 @@ class Storage extends Component
*/
public array $drives = [];
/**
* List of detached/unused drives.
*/
public array $unusedDrives = [];
/**
* Total allocated storage size in GB.
*/
@@ -121,6 +126,13 @@ class Storage extends Component
public bool $showDeleteModal = false;
public ?string $deletingDriveKey = null;
/**
* Form state for reattach modal.
*/
public bool $showReattachModal = false;
public ?string $reattachingDriveKey = null;
public string $reattachTargetBus = 'scsi';
/**
* Storage name for cephpool.
*/
@@ -225,6 +237,53 @@ class Storage extends Component
$this->drives = $drives;
$this->totalAllocatedStorage = $totalSize;
// Parse unused/detached drives
$unusedDrives = [];
foreach ($config as $key => $value) {
if (!preg_match('/^unused(\d+)$/', $key, $matches)) {
continue;
}
// Skip excluded disks
if ($this->isExcludedDisk($value)) {
continue;
}
$unusedIndex = (int) $matches[1];
$unusedInfo = $this->parseUnusedDiskString($value, $unusedIndex);
if ($unusedInfo) {
$unusedDrives[$key] = $unusedInfo;
}
}
// Sort unused drives by index
uksort($unusedDrives, function ($a, $b) {
preg_match('/^unused(\d+)$/', $a, $matchA);
preg_match('/^unused(\d+)$/', $b, $matchB);
return (int) $matchA[1] <=> (int) $matchB[1];
});
$this->unusedDrives = $unusedDrives;
}
/**
* Parse an unused disk configuration string.
*/
protected function parseUnusedDiskString(string $value, int $unusedIndex): ?array
{
// Example: cephpool:vm-100-disk-1
// Unused disks typically just have the volume reference
$volume = trim($value);
// Try to extract size from volume name or fetch from storage
// For now, we'll mark size as unknown until reattached
return [
'key' => 'unused' . $unusedIndex,
'index' => $unusedIndex,
'volume' => $volume,
'label' => 'Detached Disk ' . $unusedIndex,
];
}
/**

View File

@@ -280,10 +280,12 @@
<button wire:click="openMoveDriveModal('{{ $driveKey }}')"
class="inline-flex items-center gap-1.5 px-3 py-1.5 text-xs font-medium rounded-lg border border-neutral bg-background hover:bg-background-secondary transition-colors">
<x-ri-arrow-left-right-line class="size-3.5" />
Move
Device Bus
</button>
<button wire:click="openDetachModal('{{ $driveKey }}')"
class="inline-flex items-center gap-1.5 px-3 py-1.5 text-xs font-medium rounded-lg border border-warning/50 bg-warning/10 text-warning hover:bg-warning/20 transition-colors">
style="display: inline-flex; align-items: center; gap: 0.375rem; padding: 0.375rem 0.75rem; font-size: 0.75rem; font-weight: 500; border-radius: 0.5rem; border: 1px solid rgb(234 179 8 / 0.5); background-color: rgb(234 179 8 / 0.1); color: rgb(234 179 8); transition: background-color 0.15s ease;"
onmouseover="this.style.backgroundColor='rgb(234 179 8 / 0.2)'"
onmouseout="this.style.backgroundColor='rgb(234 179 8 / 0.1)'">
<x-ri-eject-line class="size-3.5" />
Detach
</button>
@@ -527,7 +529,7 @@
</div>
@endif
<!-- Move Drive Modal -->
<!-- Change Device Bus Modal -->
@if($showMoveDriveModal && $movingDriveKey && isset($drives[$movingDriveKey]))
@php $moveDrive = $drives[$movingDriveKey]; @endphp
<div class="fixed inset-0 z-50 overflow-y-auto">
@@ -535,7 +537,7 @@
<div class="relative min-h-screen flex items-center justify-center p-4">
<div class="relative w-full max-w-lg bg-background-secondary rounded-xl border border-neutral/20 shadow-2xl">
<div class="flex items-center justify-between p-5 border-b border-neutral">
<h3 class="text-lg font-semibold">Move Drive - {{ $moveDrive['label'] }}</h3>
<h3 class="text-lg font-semibold">Change Device Bus - {{ $moveDrive['label'] }}</h3>
<button wire:click="closeMoveDriveModal" class="text-base/50 hover:text-base transition-colors">
<x-ri-close-line class="size-5" />
</button>
@@ -566,7 +568,7 @@
@if($status && $status->status !== 'stopped')
<div class="flex items-center gap-2 p-3 rounded-lg bg-warning/10 border border-warning/30 text-warning text-sm">
<x-ri-alert-line class="size-4 flex-shrink-0" />
<span>VM must be stopped to move drives.</span>
<span>VM must be stopped to change device bus.</span>
</div>
@endif
</div>
@@ -581,8 +583,8 @@
class="px-4 py-2 text-sm font-medium rounded-lg bg-primary text-white hover:bg-primary/90 disabled:opacity-50 transition-colors"
@if($status && $status->status !== 'stopped') disabled @endif>
<x-loading target="moveDrive" />
<span wire:loading.remove wire:target="moveDrive">Move Drive</span>
<span wire:loading wire:target="moveDrive">Moving...</span>
<span wire:loading.remove wire:target="moveDrive">Change Bus</span>
<span wire:loading wire:target="moveDrive">Changing...</span>
</button>
</div>
</div>