Parsers: Add search/filter input to find parsers by domain #40

Closed
opened 2026-06-27 15:41:15 +02:00 by bullitt · 1 comment
Owner

Problem

With 23 parsers and multiple duplicates per domain, there is no way to filter or search the list. Finding a specific domain requires scrolling through all cards.

Implementation

File: frontend/src/pages/Parsers.tsx

Add a search input above the parser list (same pattern as Dashboard search bar):

const [search, setSearch] = useState("")

const filteredParsers = useMemo(() =>
  search.trim() === ""
    ? parsers
    : parsers.filter(p =>
        p.sender_domain.toLowerCase().includes(search.toLowerCase()) ||
        p.subject_keywords?.toLowerCase().includes(search.toLowerCase())
      ),
  [parsers, search]
)

In the JSX, add above the parser cards:

{parsers.length > 5 && (
  <div className="relative mb-4">
    <Search className="absolute left-2.5 top-1/2 -translate-y-1/2 h-3.5 w-3.5 text-muted-foreground pointer-events-none" />
    <Input
      placeholder="Filter by domain or keyword…"
      value={search}
      onChange={e => setSearch(e.target.value)}
      className="pl-8 h-9 text-sm"
    />
  </div>
)}

Only show the input when parsers.length > 5 (no need for search with only a few parsers).

Import Search from lucide-react and useMemo from react.

Acceptance criteria

  • Search input appears when parser count > 5
  • Filters by domain name and keyword content
  • Case-insensitive match
  • Shows "No matches" when filter has no results

Brand identity alignment

Search/filter is an operational affordance for managing source rules. It should be compact, precise, and consistent with Dashboard filtering.

Brand-compliant implementation notes

  • Placeholder copy should be factual: Search domains or keywords.
  • Use a neutral input with a line Search icon; blue only for focus.
  • No matches empty state should be useful and plain: No parser rules match this filter.

Additional acceptance criteria

  • Search supports source-domain and keyword scanning without visual clutter.
  • Empty and filtered states use calm, non-cute product copy.
  • The input does not dominate the page when parser count is low.

Migrated from GitHub issue #19: https://github.com/bullitt186/trackbox/issues/19
Original author: @bullitt186
Original created: 2026-06-27T13:25:09Z
Original labels: ux

## Problem With 23 parsers and multiple duplicates per domain, there is no way to filter or search the list. Finding a specific domain requires scrolling through all cards. ## Implementation File: `frontend/src/pages/Parsers.tsx` Add a search input above the parser list (same pattern as Dashboard search bar): ```tsx const [search, setSearch] = useState("") const filteredParsers = useMemo(() => search.trim() === "" ? parsers : parsers.filter(p => p.sender_domain.toLowerCase().includes(search.toLowerCase()) || p.subject_keywords?.toLowerCase().includes(search.toLowerCase()) ), [parsers, search] ) ``` In the JSX, add above the parser cards: ```tsx {parsers.length > 5 && ( <div className="relative mb-4"> <Search className="absolute left-2.5 top-1/2 -translate-y-1/2 h-3.5 w-3.5 text-muted-foreground pointer-events-none" /> <Input placeholder="Filter by domain or keyword…" value={search} onChange={e => setSearch(e.target.value)} className="pl-8 h-9 text-sm" /> </div> )} ``` Only show the input when `parsers.length > 5` (no need for search with only a few parsers). Import `Search` from lucide-react and `useMemo` from react. ## Acceptance criteria - Search input appears when parser count > 5 - Filters by domain name and keyword content - Case-insensitive match - Shows "No matches" when filter has no results ## Brand identity alignment Search/filter is an operational affordance for managing source rules. It should be compact, precise, and consistent with Dashboard filtering. ## Brand-compliant implementation notes - Placeholder copy should be factual: `Search domains or keywords`. - Use a neutral input with a line `Search` icon; blue only for focus. - No matches empty state should be useful and plain: `No parser rules match this filter.` ## Additional acceptance criteria - Search supports source-domain and keyword scanning without visual clutter. - Empty and filtered states use calm, non-cute product copy. - The input does not dominate the page when parser count is low. --- Migrated from GitHub issue #19: https://github.com/bullitt186/trackbox/issues/19 Original author: @bullitt186 Original created: 2026-06-27T13:25:09Z Original labels: ux
Author
Owner

Implemented in commit bd6b0e7. Added a search input above the parser list that appears only when parsers.length > 5. It filters case-insensitively on sender_domain and subject_keywords. When no results match, shows 'No parser rules match this filter.' Uses the same Search icon + pl-8 h-9 pattern as the Dashboard search bar for visual consistency.

Implemented in commit bd6b0e7. Added a search input above the parser list that appears only when `parsers.length > 5`. It filters case-insensitively on `sender_domain` and `subject_keywords`. When no results match, shows 'No parser rules match this filter.' Uses the same Search icon + `pl-8 h-9` pattern as the Dashboard search bar for visual consistency.
Sign in to join this conversation.
No labels
arch
harness
security
ux
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
bullitt/trackbox#40
No description provided.