Wire FilterBar to server-side filter query language (ticket 016)

Send the raw filter string to GET /api/logs and GET /api/timeline
instead of doing a naive client-side substring match, surface the
API's 400 parse error inline under the FilterBar input, and drop the
now-dead visibleLogs client-side filtering in App.tsx.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XFUNZwCvz3kcod3352ZR2o
This commit is contained in:
Hugh Kaznowski
2026-09-05 13:18:11 +01:00
co-authored by Claude Sonnet 5
parent 57d23c62e9
commit 10753cc9f8
3 changed files with 55 additions and 26 deletions
+30 -16
View File
@@ -1,32 +1,46 @@
import { useState } from 'react'
/**
* Placeholder for the syntax-aware pest-parsed filter language described in the
* README. For now this only does a plain substring match, applied client-side.
* Input for the syntax-aware pest-parsed filter language described in the
* README (regex + metric comparisons combined with `and`/`or`). The raw
* filter string is sent to the server (`GET /api/logs` / `GET /api/timeline`
* `filter` param) and evaluated there; this component just manages the
* draft text and surfaces any parse error the server reports back.
*/
export function FilterBar({ value, onChange }: { value: string; onChange: (value: string) => void }) {
export function FilterBar({
value,
onChange,
error,
}: {
value: string
onChange: (value: string) => void
error?: string | null
}) {
const [draft, setDraft] = useState(value)
return (
<form
className="flex items-center gap-2 border-b border-neutral-800 px-3 py-2"
className="flex flex-col gap-1 border-b border-neutral-800 px-3 py-2"
onSubmit={(e) => {
e.preventDefault()
onChange(draft)
}}
>
<input
className="flex-1 rounded border border-neutral-700 bg-neutral-900 px-2 py-1 text-sm text-neutral-100 placeholder:text-neutral-500 focus:border-neutral-500 focus:outline-none"
placeholder='regex("error") and sequence<5 or timestamp>12:00'
value={draft}
onChange={(e) => setDraft(e.target.value)}
/>
<button
type="submit"
className="rounded border border-neutral-700 px-3 py-1 text-sm text-neutral-300 hover:bg-neutral-800"
>
Filter
</button>
<div className="flex items-center gap-2">
<input
className="flex-1 rounded border border-neutral-700 bg-neutral-900 px-2 py-1 text-sm text-neutral-100 placeholder:text-neutral-500 focus:border-neutral-500 focus:outline-none"
placeholder='regex("error") and sequence<5 or timestamp>12:00'
value={draft}
onChange={(e) => setDraft(e.target.value)}
/>
<button
type="submit"
className="rounded border border-neutral-700 px-3 py-1 text-sm text-neutral-300 hover:bg-neutral-800"
>
Filter
</button>
</div>
{error && <p className="text-xs text-red-500">{error}</p>}
</form>
)
}