Skip to content

feat(my-wordpress): add server-side search to entity list views#254

Merged
epeicher merged 1 commit into
trunkfrom
add-search-to-my-wordpress-entity-lists
May 20, 2026
Merged

feat(my-wordpress): add server-side search to entity list views#254
epeicher merged 1 commit into
trunkfrom
add-search-to-my-wordpress-entity-lists

Conversation

@epeicher
Copy link
Copy Markdown
Collaborator

@epeicher epeicher commented May 20, 2026

Summary

Adds a search input above the Posts / Pages / Users / Media (and any plugin-registered) entity list views in the My WordPress window. Mirrors the visual treatment of the Content Graph search input so the two surfaces read as the same control — but the implementation diverges:

  • Server-side, not client-side. Every WP REST collection supports ?search=… natively against indexed columns (post_title + post_content, user_login/email/nicename/display_name, attachment title/filename). Client-side filtering would only match the ~24–48 tiles in memory at any moment, which would be useless for paginated infinite-scroll lists.
  • Atomic swap, not skeleton flash. Previous results stay visible (dimmed) while the new page resolves, then replace in a single frame. No "intermediate page" between keystrokes.

What's in here

  • renderListToolbar — shared helper (300ms debounce, native-X clear, Enter-to-commit) consumed by all three built-in list renderers.
  • REST plumbingfetchEntityList, fetchUserList, fetchMediaPage gain optional search + signal params. No new endpoints, no PHP changes.
  • Race guardsAbortController per page fetch + a stale-query check so fast typing can't paint a previous query's tiles into the current grid.
  • Per-entity remembered query — survives a click-into-detail-and-back round-trip; resets when switching entities (e.g. Posts → Pages).
  • Empty-state copy — `No match "".` for zero-result searches.
  • TileLayout.clear() — small new method so the canvas can be reused for a fresh result set without disposing and rebuilding the layout instance.

UX notes

  • Placement: own row below the breadcrumb header (full width, predictable space, room for future filter / sort controls). The Content Graph toolbar lives in the same spot for the same reasons.
  • Dimming during in-flight searches uses opacity: 0.45 + 120ms ease-out on --searching. The title-bar activity pulse (free from trackedFetch) carries the rest of the "work in progress" feedback.
  • Search query persistence is per-entity, in-memory only. Closing and reopening the window resets it.

Performance

  • One REST round-trip per debounced keystroke, payload shape identical to a normal list fetch.
  • No client-side index, no bundle-size hit beyond the helper (~80 LOC).
  • Caveat: /wp/v2/posts?search=foo searches title + content. post_title is indexed, post_content is not (no FULLTEXT). Fine at typical site sizes; can get slow on very large content. Out of scope for v1.

Test plan

  • Type in the search field on Posts — results refine without skeleton flash.
  • Type fast (race scenario) — only the final query's results paint.
  • Native search-input X clears immediately, no 300ms debounce wait.
  • Empty result — shows `No posts match "xyz".`.
  • Click into a post, back out — search query persists.
  • Switch Posts → Pages — search field resets.
  • Same flow on Users.
  • Same flow on Media.
  • Reorder / dock collapse / window resize while a search is in flight — no stale paints.
Open WordPress Playground Preview

Adds a search input above the Posts / Pages / Users / Media (and any
plugin-registered) entity list views in the My WordPress window.
Search runs server-side via the WP REST `?search=…` param so it scales
across collections of any size without pulling the whole set client-side.

Highlights:
- Shared `renderListToolbar` helper (300ms debounce, native-X clear,
  Enter-to-commit) so all three built-in renderers wire the same chrome.
- `AbortController` per page fetch + a stale-query race guard so fast
  typing can't paint a previous query's tiles into the current grid.
- Atomic swap on search refetch: the previous result set stays visible
  (dimmed via `--searching`) while the new page resolves, then replaces
  in a single frame. No skeleton flash between keystrokes.
- Per-entity remembered query — survives a click-into-detail-and-back
  round-trip, resets when switching entities.
- Empty-state copy "No <entity> match \"<query>\"." when the search
  produces zero results.

Implementation surface:
- New `src/my-wordpress/list-toolbar.ts`.
- `fetchEntityList` / `fetchUserList` / `fetchMediaPage` gain optional
  `search` + `signal` params.
- New `clear()` method on the internal `TileLayout` so the canvas can
  be reused for a fresh result set without disposing and rebuilding the
  layout instance.
- New CSS rules in `my-wordpress.css` for the toolbar + dim-while-
  searching state.
@github-actions
Copy link
Copy Markdown
Contributor

✅ WordPress Plugin Check Report

✅ Status: Passed

📊 Report

All checks passed! No errors or warnings found.


🤖 Generated by WordPress Plugin Check Action • Learn more about Plugin Check

@epeicher epeicher merged commit 2afdb8f into trunk May 20, 2026
5 checks passed
@epeicher epeicher deleted the add-search-to-my-wordpress-entity-lists branch May 20, 2026 15:56
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.

1 participant