diff --git a/frontend-modern/src/components/Backups/UnifiedBackups.tsx b/frontend-modern/src/components/Backups/UnifiedBackups.tsx index c4b419a30..c322e35b6 100644 --- a/frontend-modern/src/components/Backups/UnifiedBackups.tsx +++ b/frontend-modern/src/components/Backups/UnifiedBackups.tsx @@ -487,13 +487,13 @@ const UnifiedBackups: Component = () => { ); } - // Node selection filter (using node name for simple matching) + // Node selection filter using both instance and node name for uniqueness if (nodeFilter) { - // Find the node to get its name - const node = state.nodes?.find(n => n.id === nodeFilter); + const node = state.nodes?.find((n) => n.id === nodeFilter); if (node) { - // Filter backups by node name - data = data.filter((item) => item.node === node.name); + data = data.filter( + (item) => item.instance === node.instance && item.node === node.name, + ); } } diff --git a/frontend-modern/src/components/Dashboard/Dashboard.tsx b/frontend-modern/src/components/Dashboard/Dashboard.tsx index 12501721d..acb2ddd8a 100644 --- a/frontend-modern/src/components/Dashboard/Dashboard.tsx +++ b/frontend-modern/src/components/Dashboard/Dashboard.tsx @@ -221,14 +221,15 @@ export function Dashboard(props: DashboardProps) { const filteredGuests = createMemo(() => { let guests = allGuests(); - // Filter by selected node (using node name for simple matching) + // Filter by selected node using both instance and node name for uniqueness const selectedNodeId = selectedNode(); if (selectedNodeId) { - // Find the node to get its name - const node = props.nodes.find(n => n.id === selectedNodeId); + // Find the node to get both instance and name for precise matching + const node = props.nodes.find((n) => n.id === selectedNodeId); if (node) { - // Filter guests by node name (not instance ID) - guests = guests.filter((g) => g.node === node.name); + guests = guests.filter( + (g) => g.instance === node.instance && g.node === node.name, + ); } } diff --git a/frontend-modern/src/components/Storage/DiskList.tsx b/frontend-modern/src/components/Storage/DiskList.tsx index f233c0465..cfad8b751 100644 --- a/frontend-modern/src/components/Storage/DiskList.tsx +++ b/frontend-modern/src/components/Storage/DiskList.tsx @@ -17,12 +17,13 @@ export const DiskList: Component = (props) => { const filteredDisks = createMemo(() => { let disks = props.disks || []; - // Filter by node if selected (using node name for simple matching) + // Filter by node if selected using both instance and node name if (props.selectedNode) { - // Find the node to get its name - const node = state.nodes?.find(n => n.id === props.selectedNode); + const node = state.nodes?.find((n) => n.id === props.selectedNode); if (node) { - disks = disks.filter((d) => d.node === node.name); + disks = disks.filter( + (d) => d.instance === node.instance && d.node === node.name, + ); } } diff --git a/frontend-modern/src/components/Storage/Storage.tsx b/frontend-modern/src/components/Storage/Storage.tsx index cf050406f..a72df0ae7 100644 --- a/frontend-modern/src/components/Storage/Storage.tsx +++ b/frontend-modern/src/components/Storage/Storage.tsx @@ -83,6 +83,7 @@ const Storage: Component = () => { const storageMap = new Map(); storage.forEach((s) => { let key; + const nodeId = `${s.instance}-${s.node}`; // 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 @@ -104,6 +105,7 @@ const Storage: Component = () => { ...s, name: s.type === 'pbs' ? 'PBS Storage' : s.name, // Generic name for PBS nodes: [s.node], + nodeIds: [nodeId], nodeCount: 1, pbsNames: s.type === 'pbs' ? [s.name] : undefined, // Track individual PBS names }); @@ -114,6 +116,11 @@ const Storage: Component = () => { existing.nodes.push(s.node); existing.nodeCount = existing.nodes.length; } + if (!existing.nodeIds) { + existing.nodeIds = [nodeId]; + } else if (!existing.nodeIds.includes(nodeId)) { + existing.nodeIds.push(nodeId); + } // For PBS, collect all namespace names if (s.type === 'pbs' && existing.pbsNames && !existing.pbsNames.includes(s.name)) { existing.pbsNames.push(s.name); @@ -132,14 +139,17 @@ const Storage: Component = () => { const sortedStorage = createMemo(() => { let storage = [...filteredStorage()]; - // Apply node selection filter (using node name for simple matching) + // Apply node selection filter with instance-aware matching const nodeFilter = selectedNode(); if (nodeFilter) { - // Find the node to get its name - const node = state.nodes?.find(n => n.id === nodeFilter); + const node = state.nodes?.find((n) => n.id === nodeFilter); if (node) { - // Filter storage by node name - storage = storage.filter((s) => s.node === node.name); + const nodeId = `${node.instance}-${node.name}`; + storage = storage.filter((s) => { + const belongsToNode = s.instance === node.instance && s.node === node.name; + const aggregatedNodeIds = (s as { nodeIds?: string[] }).nodeIds ?? []; + return belongsToNode || aggregatedNodeIds.includes(nodeId); + }); } } diff --git a/frontend-modern/src/components/shared/NodeSummaryTable.tsx b/frontend-modern/src/components/shared/NodeSummaryTable.tsx index d450fc067..5539f721c 100644 --- a/frontend-modern/src/components/shared/NodeSummaryTable.tsx +++ b/frontend-modern/src/components/shared/NodeSummaryTable.tsx @@ -222,7 +222,7 @@ export const NodeSummaryTable: Component = (props) => { case 'diskCount': return diskCountsByNode()[keyId] ?? 0; case 'backupCount': - return props.backupCounts?.[node.name] ?? 0; + return props.backupCounts?.[node.id] ?? 0; default: return null; } diff --git a/frontend-modern/src/components/shared/UnifiedNodeSelector.tsx b/frontend-modern/src/components/shared/UnifiedNodeSelector.tsx index 46160b5e7..85c2e41e9 100644 --- a/frontend-modern/src/components/shared/UnifiedNodeSelector.tsx +++ b/frontend-modern/src/components/shared/UnifiedNodeSelector.tsx @@ -65,7 +65,7 @@ export const UnifiedNodeSelector: Component = (props) count += state.pveBackups.guestSnapshots.filter((s) => s.instance === node.instance && s.node === node.name).length; } - counts[node.name] = count; + counts[node.id] = count; }); }