fix: tolerate Proxmox numeric string APIs and refine VM list
This commit is contained in:
@@ -70,7 +70,7 @@ export function StorageDetail({ connectionId, storage, node, onBack }: StorageDe
|
||||
node,
|
||||
storage
|
||||
)
|
||||
const { data: contentList, isLoading: contentLoading } = useStorageContent(
|
||||
const { data: contentList, isLoading: contentLoading, error: contentError } = useStorageContent(
|
||||
connectionId,
|
||||
node,
|
||||
storage
|
||||
@@ -237,7 +237,13 @@ export function StorageDetail({ connectionId, storage, node, onBack }: StorageDe
|
||||
</CardTitle>
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
{!contentList || contentList.length === 0 ? (
|
||||
{contentError ? (
|
||||
<EmptyState
|
||||
icon={File}
|
||||
title="Failed to load content"
|
||||
description={contentError.message}
|
||||
/>
|
||||
) : !contentList || contentList.length === 0 ? (
|
||||
<EmptyState icon={File} title="No content found" />
|
||||
) : (
|
||||
<div className="space-y-4">
|
||||
|
||||
@@ -14,22 +14,22 @@ interface VMListProps {
|
||||
onVMClick?: (vm: ProxmoxVM) => void
|
||||
}
|
||||
|
||||
type VMTypeFilter = 'all' | 'qemu' | 'lxc'
|
||||
type VMStatusFilter = 'all' | ProxmoxVM['status']
|
||||
|
||||
export function VMList({ connectionId, onVMClick }: VMListProps) {
|
||||
const { data: vms, isLoading: vmsLoading, error: vmsError } = useVMs(connectionId)
|
||||
|
||||
const [search, setSearch] = useState('')
|
||||
const [typeFilter, setTypeFilter] = useState<VMTypeFilter>('all')
|
||||
const [statusFilter, setStatusFilter] = useState<VMStatusFilter>('all')
|
||||
const [nodeFilter, setNodeFilter] = useState<string>('all')
|
||||
|
||||
// Filter to only QEMU VMs — LXC containers have their own view.
|
||||
const vmsOnly = useMemo(() => {
|
||||
return vms?.filter((vm) => vm.type === 'qemu') ?? []
|
||||
}, [vms])
|
||||
|
||||
const filteredVMs = useMemo(() => {
|
||||
if (!vms) return []
|
||||
return vms.filter((vm) => {
|
||||
// Type filter
|
||||
if (typeFilter !== 'all' && vm.type !== typeFilter) return false
|
||||
return vmsOnly.filter((vm) => {
|
||||
// Status filter
|
||||
if (statusFilter !== 'all' && vm.status !== statusFilter) return false
|
||||
// Node filter
|
||||
@@ -43,12 +43,11 @@ export function VMList({ connectionId, onVMClick }: VMListProps) {
|
||||
}
|
||||
return true
|
||||
})
|
||||
}, [vms, typeFilter, statusFilter, nodeFilter, search])
|
||||
}, [vmsOnly, statusFilter, nodeFilter, search])
|
||||
|
||||
const uniqueNodes = useMemo(() => {
|
||||
if (!vms) return []
|
||||
return [...new Set(vms.map((vm) => vm.node))].sort()
|
||||
}, [vms])
|
||||
return [...new Set(vmsOnly.map((vm) => vm.node))].sort()
|
||||
}, [vmsOnly])
|
||||
|
||||
if (vmsLoading) {
|
||||
return (
|
||||
@@ -73,7 +72,7 @@ export function VMList({ connectionId, onVMClick }: VMListProps) {
|
||||
<div>
|
||||
<h2 className="text-2xl font-semibold tracking-tight">Virtual Machines</h2>
|
||||
<p className="text-muted-foreground">
|
||||
{vms?.length ?? 0} total VMs across the cluster
|
||||
{vmsOnly.length} total VMs across the cluster
|
||||
</p>
|
||||
</div>
|
||||
|
||||
@@ -89,16 +88,6 @@ export function VMList({ connectionId, onVMClick }: VMListProps) {
|
||||
/>
|
||||
</div>
|
||||
|
||||
<select
|
||||
value={typeFilter}
|
||||
onChange={(e) => setTypeFilter(e.target.value as VMTypeFilter)}
|
||||
className="flex h-9 rounded-md border border-input bg-transparent px-3 py-1 text-sm shadow-sm transition-colors focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring"
|
||||
>
|
||||
<option value="all">All Types</option>
|
||||
<option value="qemu">VM (QEMU)</option>
|
||||
<option value="lxc">Container (LXC)</option>
|
||||
</select>
|
||||
|
||||
<select
|
||||
value={statusFilter}
|
||||
onChange={(e) => setStatusFilter(e.target.value as VMStatusFilter)}
|
||||
@@ -129,7 +118,7 @@ export function VMList({ connectionId, onVMClick }: VMListProps) {
|
||||
<Card>
|
||||
<CardContent className="p-0">
|
||||
{filteredVMs.length === 0 ? (
|
||||
vms?.length === 0 ? (
|
||||
vmsOnly.length === 0 ? (
|
||||
<EmptyState icon={Box} title="No VMs found" />
|
||||
) : (
|
||||
<EmptyState icon={Search} title="No VMs match your filters" />
|
||||
|
||||
Reference in New Issue
Block a user