feat: add unused drives handling and update device bus modal labels for clarity
This commit is contained in:
@@ -15,6 +15,11 @@ class Storage extends Component
|
|||||||
*/
|
*/
|
||||||
public array $drives = [];
|
public array $drives = [];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* List of detached/unused drives.
|
||||||
|
*/
|
||||||
|
public array $unusedDrives = [];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Total allocated storage size in GB.
|
* Total allocated storage size in GB.
|
||||||
*/
|
*/
|
||||||
@@ -121,6 +126,13 @@ class Storage extends Component
|
|||||||
public bool $showDeleteModal = false;
|
public bool $showDeleteModal = false;
|
||||||
public ?string $deletingDriveKey = null;
|
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.
|
* Storage name for cephpool.
|
||||||
*/
|
*/
|
||||||
@@ -225,6 +237,53 @@ class Storage extends Component
|
|||||||
|
|
||||||
$this->drives = $drives;
|
$this->drives = $drives;
|
||||||
$this->totalAllocatedStorage = $totalSize;
|
$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,
|
||||||
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -280,10 +280,12 @@
|
|||||||
<button wire:click="openMoveDriveModal('{{ $driveKey }}')"
|
<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">
|
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" />
|
<x-ri-arrow-left-right-line class="size-3.5" />
|
||||||
Move
|
Device Bus
|
||||||
</button>
|
</button>
|
||||||
<button wire:click="openDetachModal('{{ $driveKey }}')"
|
<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" />
|
<x-ri-eject-line class="size-3.5" />
|
||||||
Detach
|
Detach
|
||||||
</button>
|
</button>
|
||||||
@@ -527,7 +529,7 @@
|
|||||||
</div>
|
</div>
|
||||||
@endif
|
@endif
|
||||||
|
|
||||||
<!-- Move Drive Modal -->
|
<!-- Change Device Bus Modal -->
|
||||||
@if($showMoveDriveModal && $movingDriveKey && isset($drives[$movingDriveKey]))
|
@if($showMoveDriveModal && $movingDriveKey && isset($drives[$movingDriveKey]))
|
||||||
@php $moveDrive = $drives[$movingDriveKey]; @endphp
|
@php $moveDrive = $drives[$movingDriveKey]; @endphp
|
||||||
<div class="fixed inset-0 z-50 overflow-y-auto">
|
<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 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="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">
|
<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">
|
<button wire:click="closeMoveDriveModal" class="text-base/50 hover:text-base transition-colors">
|
||||||
<x-ri-close-line class="size-5" />
|
<x-ri-close-line class="size-5" />
|
||||||
</button>
|
</button>
|
||||||
@@ -566,7 +568,7 @@
|
|||||||
@if($status && $status->status !== 'stopped')
|
@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">
|
<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" />
|
<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>
|
</div>
|
||||||
@endif
|
@endif
|
||||||
</div>
|
</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"
|
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>
|
@if($status && $status->status !== 'stopped') disabled @endif>
|
||||||
<x-loading target="moveDrive" />
|
<x-loading target="moveDrive" />
|
||||||
<span wire:loading.remove wire:target="moveDrive">Move Drive</span>
|
<span wire:loading.remove wire:target="moveDrive">Change Bus</span>
|
||||||
<span wire:loading wire:target="moveDrive">Moving...</span>
|
<span wire:loading wire:target="moveDrive">Changing...</span>
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
Reference in New Issue
Block a user