From 2cede40509abf0baffd3611d35259a769e1db6e6 Mon Sep 17 00:00:00 2001 From: Pulse Monitor Date: Thu, 4 Sep 2025 16:18:18 +0000 Subject: [PATCH] fix: properly deduplicate PBS storage in 'by storage' view PBS storage entries pointing to the same server (same capacity) are now truly deduplicated. Instead of showing 3 entries for pbs-pve1, pbs-pve2, and pbs-pve3, it now shows a single 'PBS Storage' entry with all namespaces listed. This provides actual deduplication for identical storage resources. --- .../src/components/Storage/Storage.tsx | 40 +++++++++++++++---- frontend-modern/src/types/api.ts | 1 + 2 files changed, 33 insertions(+), 8 deletions(-) diff --git a/frontend-modern/src/components/Storage/Storage.tsx b/frontend-modern/src/components/Storage/Storage.tsx index 9a645e5a4..d498d36ef 100644 --- a/frontend-modern/src/components/Storage/Storage.tsx +++ b/frontend-modern/src/components/Storage/Storage.tsx @@ -53,19 +53,32 @@ const Storage: Component = () => { // Filter out 0 capacity first storage = storage.filter(s => s.total > 0); - // Deduplicate storage entries that are identical (same name, type, total, used) - // Keep the first occurrence and add node count info + // Deduplicate storage entries that are identical const storageMap = new Map(); storage.forEach(s => { - // Create a key based on storage name and type (PBS storage with same name is the same storage) - const key = `${s.name}-${s.type}`; + let key; + + // For PBS storage, group by capacity since they're the same PBS server + // PBS namespaces (pbs-node1, pbs-node2) pointing to same server should be grouped + if (s.type === 'pbs') { + // Group PBS by type, total size, and usage (same PBS server = same capacity) + key = `pbs-${s.total}-${s.used}`; + } else if (s.shared) { + // Shared storage should only appear once + key = `${s.name}-${s.type}`; + } else { + // Regular storage - deduplicate by name and type + key = `${s.name}-${s.type}`; + } if (!storageMap.has(key)) { // First occurrence - store it with node list storageMap.set(key, { ...s, + name: s.type === 'pbs' ? 'PBS Storage' : s.name, // Generic name for PBS nodes: [s.node], - nodeCount: 1 + nodeCount: 1, + pbsNames: s.type === 'pbs' ? [s.name] : undefined // Track individual PBS names }); } else { // Duplicate - just add to node list @@ -74,6 +87,10 @@ const Storage: Component = () => { existing.nodes.push(s.node); existing.nodeCount = existing.nodes.length; } + // For PBS, collect all namespace names + if (s.type === 'pbs' && existing.pbsNames && !existing.pbsNames.includes(s.name)) { + existing.pbsNames.push(s.name); + } } }); @@ -338,9 +355,16 @@ const Storage: Component = () => { {storage.name} - - ({storage.nodes ? storage.nodes.join(', ') : storage.node}) - + + + ({storage.pbsNames.sort().join(', ')}) + + + + + ({storage.nodes ? storage.nodes.join(', ') : storage.node}) + + diff --git a/frontend-modern/src/types/api.ts b/frontend-modern/src/types/api.ts index 9bc76bd09..03ed448a0 100644 --- a/frontend-modern/src/types/api.ts +++ b/frontend-modern/src/types/api.ts @@ -105,6 +105,7 @@ export interface Storage { // Added for deduplication in storage view nodes?: string[]; nodeCount?: number; + pbsNames?: string[]; } export interface PBSInstance {