From 45ee845b8a905e055be4cda6d4ff56b167bc47a2 Mon Sep 17 00:00:00 2001 From: Pulse Monitor Date: Mon, 25 Aug 2025 21:50:47 +0000 Subject: [PATCH] fix: enable node click filtering for any number of nodes addresses #356 - node click filtering now works with: - 1-4 nodes (regular cards - already worked) - 5-9 nodes (compact cards - now fixed) - 10+ nodes (ultra-compact list - now fixed) clicking any node box filters VMs to that node only, regardless of how many nodes are displayed --- .../components/Dashboard/CompactNodeCard.tsx | 28 ++++++---- .../src/components/Dashboard/Dashboard.tsx | 56 ++++++++++++++++++- 2 files changed, 72 insertions(+), 12 deletions(-) diff --git a/frontend-modern/src/components/Dashboard/CompactNodeCard.tsx b/frontend-modern/src/components/Dashboard/CompactNodeCard.tsx index 8f1c434c3..fdcad7b0a 100644 --- a/frontend-modern/src/components/Dashboard/CompactNodeCard.tsx +++ b/frontend-modern/src/components/Dashboard/CompactNodeCard.tsx @@ -8,6 +8,8 @@ import { useWebSocket } from '@/App'; interface CompactNodeCardProps { node: Node; variant: 'compact' | 'ultra-compact'; + onClick?: () => void; + isSelected?: boolean; } const CompactNodeCard: Component = (props) => { @@ -55,11 +57,14 @@ const CompactNodeCard: Component = (props) => { if (props.variant === 'ultra-compact') { // Single line format for 10+ nodes return ( -
+
{/* Status dot */} @@ -101,11 +106,14 @@ const CompactNodeCard: Component = (props) => { // Compact bar format for 5-9 nodes return ( -
+
diff --git a/frontend-modern/src/components/Dashboard/Dashboard.tsx b/frontend-modern/src/components/Dashboard/Dashboard.tsx index 0a821e834..271aff721 100644 --- a/frontend-modern/src/components/Dashboard/Dashboard.tsx +++ b/frontend-modern/src/components/Dashboard/Dashboard.tsx @@ -355,7 +355,33 @@ export function Dashboard(props: DashboardProps) { {(node) => ( - + { + const currentSearch = search(); + const nodeFilter = `node:${node.name}`; + + // Check if this node filter is already in the search + if (currentSearch.includes(nodeFilter)) { + // Remove the node filter + setSearch(currentSearch.replace(nodeFilter, '').trim().replace(/,\s*,/g, ',').replace(/^,|,$/g, '')); + setIsSearchLocked(false); + } else { + // Clear any existing node: filters and add the new one + const cleanedSearch = currentSearch.replace(/node:\w+/g, '').trim().replace(/,\s*,/g, ',').replace(/^,|,$/g, ''); + const newSearch = cleanedSearch ? `${cleanedSearch}, ${nodeFilter}` : nodeFilter; + setSearch(newSearch); + setIsSearchLocked(true); + + // Expand filters if collapsed + if (!showFilters()) { + setShowFilters(true); + } + } + }} + /> )} @@ -368,7 +394,33 @@ export function Dashboard(props: DashboardProps) { {(node) => ( - + { + const currentSearch = search(); + const nodeFilter = `node:${node.name}`; + + // Check if this node filter is already in the search + if (currentSearch.includes(nodeFilter)) { + // Remove the node filter + setSearch(currentSearch.replace(nodeFilter, '').trim().replace(/,\s*,/g, ',').replace(/^,|,$/g, '')); + setIsSearchLocked(false); + } else { + // Clear any existing node: filters and add the new one + const cleanedSearch = currentSearch.replace(/node:\w+/g, '').trim().replace(/,\s*,/g, ',').replace(/^,|,$/g, ''); + const newSearch = cleanedSearch ? `${cleanedSearch}, ${nodeFilter}` : nodeFilter; + setSearch(newSearch); + setIsSearchLocked(true); + + // Expand filters if collapsed + if (!showFilters()) { + setShowFilters(true); + } + } + }} + /> )}