From c6da3985743fd0d01bd17416e03fbe4ca21bd70c Mon Sep 17 00:00:00 2001 From: nessi Date: Thu, 12 Feb 2026 12:27:53 +0100 Subject: [PATCH] Add search functionality to the Dashboard targets list Implemented a search input to filter targets based on name, host, or database fields. Updated the UI to show filtered results and display a message if no targets match the search. Adjusted styles for improved responsiveness and usability. --- frontend/src/pages/DashboardPage.jsx | 28 ++++++++++++++-- frontend/src/styles.css | 49 ++++++++++++++++++++++++---- 2 files changed, 67 insertions(+), 10 deletions(-) diff --git a/frontend/src/pages/DashboardPage.jsx b/frontend/src/pages/DashboardPage.jsx index 03cbc03..939a412 100644 --- a/frontend/src/pages/DashboardPage.jsx +++ b/frontend/src/pages/DashboardPage.jsx @@ -6,6 +6,7 @@ import { useAuth } from "../state"; export function DashboardPage() { const { tokens, refresh } = useAuth(); const [targets, setTargets] = useState([]); + const [search, setSearch] = useState(""); const [loading, setLoading] = useState(true); const [error, setError] = useState(""); @@ -31,6 +32,15 @@ export function DashboardPage() { const alerts = targets.filter((t) => !t.host || !t.dbname).length; const okCount = Math.max(0, targets.length - alerts); + const filteredTargets = targets.filter((t) => { + const q = search.trim().toLowerCase(); + if (!q) return true; + return ( + (t.name || "").toLowerCase().includes(q) || + (t.host || "").toLowerCase().includes(q) || + (t.dbname || "").toLowerCase().includes(q) + ); + }); return (
@@ -56,12 +66,21 @@ export function DashboardPage() {
-

Targets

- {targets.length} registered +
+

Targets

+ {filteredTargets.length} shown of {targets.length} registered +
+
+ setSearch(e.target.value)} + placeholder="Search by name, host, or database..." + /> +
- {targets.map((t) => { + {filteredTargets.map((t) => { const hasAlert = !t.host || !t.dbname; return (
@@ -81,6 +100,9 @@ export function DashboardPage() {
); })} + {filteredTargets.length === 0 && ( +
No targets match your search.
+ )}
diff --git a/frontend/src/styles.css b/frontend/src/styles.css index 558626d..7193d38 100644 --- a/frontend/src/styles.css +++ b/frontend/src/styles.css @@ -291,9 +291,10 @@ button { .dashboard-targets-head { display: flex; - align-items: center; + align-items: flex-end; justify-content: space-between; margin-bottom: 12px; + gap: 12px; } .dashboard-targets-head h3 { @@ -305,6 +306,18 @@ button { font-size: 13px; } +.dashboard-target-search { + min-width: 320px; + max-width: 420px; + width: 100%; +} + +.dashboard-target-search input { + width: 100%; + height: 36px; + padding: 8px 10px; +} + .kpi-orb { position: absolute; right: 14px; @@ -334,7 +347,10 @@ button { .dashboard-target-list { display: grid; - gap: 14px; + gap: 10px; + max-height: 460px; + overflow: auto; + padding-right: 2px; } .dashboard-targets-card { @@ -348,7 +364,7 @@ button { align-items: center; border: 1px solid #2b5b8f; border-radius: 12px; - padding: 16px; + padding: 12px 14px; background: linear-gradient(180deg, #143462, #102a4f); box-shadow: inset 0 1px 0 #6fc5ff1a; transition: transform 0.16s ease, border-color 0.16s ease, box-shadow 0.16s ease; @@ -362,15 +378,15 @@ button { .target-main h4 { margin: 0; - font-size: 24px; + font-size: 20px; font-weight: 800; letter-spacing: 0.01em; } .target-main p { - margin: 6px 0 0 0; + margin: 4px 0 0 0; color: #d5e7ff; - font-size: 17px; + font-size: 15px; } .target-title-row { @@ -402,7 +418,7 @@ button { .details-btn { display: inline-block; - padding: 10px 14px; + padding: 7px 12px; border-radius: 10px; font-weight: 700; border: 1px solid #4db8f1; @@ -416,6 +432,14 @@ button { filter: brightness(1.05); } +.dashboard-empty { + border: 1px dashed #34689f; + border-radius: 10px; + padding: 14px; + color: #9fb9d8; + text-align: center; +} + .query-insights-page .query-toolbar { display: grid; grid-template-columns: minmax(220px, 320px) minmax(320px, 1fr); @@ -1020,4 +1044,15 @@ select:-webkit-autofill { height: auto; overflow: visible; } + .dashboard-target-search { + min-width: 0; + } + .dashboard-targets-head { + flex-direction: column; + align-items: stretch; + } + .dashboard-target-list { + max-height: none; + overflow: visible; + } }