From ae3bb554a09f15150104e4ae4ddadb6cb3a9f4e4 Mon Sep 17 00:00:00 2001 From: Pulse Monitor Date: Thu, 4 Sep 2025 16:14:52 +0000 Subject: [PATCH] feat: deduplicate identical storage entries in 'by storage' view The storage view now deduplicates identical storage entries (like PBS storage that appears on multiple nodes). Instead of showing pbs-pve1 three times, it shows it once with all nodes listed (pve1, pve2, pve3). This provides a cleaner view of actual storage resources. --- .../src/components/Storage/Storage.tsx | 34 +++++++++++++++++-- frontend-modern/src/types/api.ts | 3 ++ 2 files changed, 34 insertions(+), 3 deletions(-) diff --git a/frontend-modern/src/components/Storage/Storage.tsx b/frontend-modern/src/components/Storage/Storage.tsx index 922e44041..9a645e5a4 100644 --- a/frontend-modern/src/components/Storage/Storage.tsx +++ b/frontend-modern/src/components/Storage/Storage.tsx @@ -44,13 +44,41 @@ const Storage: Component = () => { }); - // Filter storage - in storage view, filter out 0 capacity + // Filter storage - in storage view, filter out 0 capacity and deduplicate const filteredStorage = createMemo(() => { let storage = state.storage || []; - // In storage view, filter out 0 capacity + // In storage view, deduplicate identical storage and filter out 0 capacity if (viewMode() === 'storage') { + // 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 + 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}`; + + if (!storageMap.has(key)) { + // First occurrence - store it with node list + storageMap.set(key, { + ...s, + nodes: [s.node], + nodeCount: 1 + }); + } else { + // Duplicate - just add to node list + const existing = storageMap.get(key); + if (!existing.nodes.includes(s.node)) { + existing.nodes.push(s.node); + existing.nodeCount = existing.nodes.length; + } + } + }); + + // Convert back to array + storage = Array.from(storageMap.values()); } return storage; @@ -311,7 +339,7 @@ const Storage: Component = () => { - ({storage.node}) + ({storage.nodes ? storage.nodes.join(', ') : storage.node}) diff --git a/frontend-modern/src/types/api.ts b/frontend-modern/src/types/api.ts index b40fc2da7..9bc76bd09 100644 --- a/frontend-modern/src/types/api.ts +++ b/frontend-modern/src/types/api.ts @@ -102,6 +102,9 @@ export interface Storage { shared: boolean; enabled: boolean; active: boolean; + // Added for deduplication in storage view + nodes?: string[]; + nodeCount?: number; } export interface PBSInstance {