Skip to content

feat(web): session search/filter with improved UX - #2528

Open
ozanonurtek wants to merge 9 commits into
warp-tech:mainfrom
ozanonurtek:feat/session-search
Open

feat(web): session search/filter with improved UX#2528
ozanonurtek wants to merge 9 commits into
warp-tech:mainfrom
ozanonurtek:feat/session-search

Conversation

@ozanonurtek

@ozanonurtek ozanonurtek commented Aug 31, 2026

Copy link
Copy Markdown

Summary

Implements session search and filtering on the sessions page, addressing #2418.

Changes

Filter bar layout (Sessions.svelte)

  • Search input on its own full-width row
  • Protocol, From date, and To date filters in a 3-column grid below the search
  • Active only / Logged in only toggles on a third row with a Clear filters button that resets all filters in one click (only shown when any filter is active)

Search input focus fix (ItemList.svelte)

  • Moved the search <Input> outside the {#await $items} reactive block so it is never destroyed/recreated when data reloads — fixes focus loss on every keystroke
  • Added hasItems state variable tracked via the RxJS pipeline to control search input visibility without depending on the async block scope

Backend compatibility

The backend query layer uses SeaORM's abstract query builder with no raw SQL — fully compatible with SQLite (default), PostgreSQL, and MySQL.

AI disclosure

This PR was authored with AI assistance (OpenCode / Claude). The contributor reviewed all changes, verified the build and biome CI, and tested the UX fixes. Architectural decisions (keeping the query layer backend-agnostic, the ItemList reactive structure fix) were guided by the contributor.

AI Usage

Choose the level of AI involvement for this PR.

  • Fully vibe coded
  • AI-designed, AI-coded, manually checked
  • Human-designed, AI-coded
  • Human-designed, human-coded (includes AI autocompletions and boilerplate gen)

Closes #2418

GET /sessions gains optional search (username OR target name, via a
subquery over the target snapshot JSON), from/to (session start range)
and protocol (case-insensitive exact) filters. Filter composition lives
in a sessions_query helper so it can be tested without HTTP.

Part of warp-tech#2418
The sessions page gets ItemList's debounced free-text search (matches
username or target name server-side) plus protocol, from/to and the
existing toggles. Every filter persists via autosave and re-triggers
the query through the existing rxjs pipeline.

Part of warp-tech#2418
The terminal player toolbar gains a search box (terminal recordings
only). Submitting streams the whole data.ndjson through a second
RangeStream — memory-bounded, abortable, works for disk/S3/live —
strips ANSI escapes, and collects line-based matches with timestamps.
Clicking a match seeks playback to it via the existing keyframe seek
path.

Client-side scan over the existing range stream (no new endpoint) was
chosen for v1; a server-side search endpoint is the alternative if the
maintainer prefers.

Part of warp-tech#2418
The SSH command detector's output is now persisted instead of only
logged: a session_commands row per detected command, written once a
target session exists (menu interactions stay log-only). A failed
insert falls back to log-only for the rest of the session, mirroring
how recorder write errors are handled — persistence must never break
the session.

New admin endpoint GET /commands/search (q/user/target/from/to) joins
through the parent target and user sessions, and a Commands page under
Status links each hit back to its session.

Caveats: SSH-only, heuristic detection (see command_detector docs), no
retroactive indexing of sessions recorded before this change; rows are
removed with their target session (FK cascade, like recordings).

Part of warp-tech#2418
…us loss

- Restructure filter bar into a 3-column grid (protocol, from-date,
  to-date) with toggles and a 'Clear filters' button on a separate row
- Move search input outside the {#await} reactive block in ItemList so
  it is never destroyed/recreated on data reloads, fixing focus loss on
  every keystroke

Closes warp-tech#2418
The compile-time check in copy_database.rs ensures every entity in
with_every_entity! is also listed in with_every_table_in_order!.
SessionCommand (added with the m00083 migration) was missing, breaking
cargo build/test/clippy.

Placed after TargetSession, which it references via FK.
The OpenAPI coverage guard requires every operationId in the admin
schema to have a permission enforcement test case. search_session_commands
(added with the command search API) was missing, failing all 101
parametrized cases.
# Conflicts:
#	warpgate-web/src/admin/lib/openapi-schema.json
@Eugeny

Eugeny commented Sep 2, 2026

Copy link
Copy Markdown
Member

Thank you for the PR! For the sake of transparency, I'm currently low on time and it will take me a bit to review & merge this

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Feature] Ability to search/filters in the sessions page

2 participants