Handle duplicate node names in filters (#500)

This commit is contained in:
rcourtman
2025-10-03 11:08:29 +00:00
parent 43bdc05dd6
commit 8acdc3ccb6
6 changed files with 33 additions and 21 deletions
@@ -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,
);
}
}
@@ -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,
);
}
}
@@ -17,12 +17,13 @@ export const DiskList: Component<DiskListProps> = (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,
);
}
}
@@ -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);
});
}
}
@@ -222,7 +222,7 @@ export const NodeSummaryTable: Component<NodeSummaryTableProps> = (props) => {
case 'diskCount':
return diskCountsByNode()[keyId] ?? 0;
case 'backupCount':
return props.backupCounts?.[node.name] ?? 0;
return props.backupCounts?.[node.id] ?? 0;
default:
return null;
}
@@ -65,7 +65,7 @@ export const UnifiedNodeSelector: Component<UnifiedNodeSelectorProps> = (props)
count += state.pveBackups.guestSnapshots.filter((s) => s.instance === node.instance && s.node === node.name).length;
}
counts[node.name] = count;
counts[node.id] = count;
});
}