Skip to content

fix: search empty state never renders for no-match queries (#126)#135

Merged
zacharias-ona merged 1 commit into
mainfrom
fix/126-search-empty-state
Apr 16, 2026
Merged

fix: search empty state never renders for no-match queries (#126)#135
zacharias-ona merged 1 commit into
mainfrom
fix/126-search-empty-state

Conversation

@zacharias-ona
Copy link
Copy Markdown
Collaborator

Closes #126

What

After PR #123 added a workspaceResolved guard to the search debounce effect, the "No pages match your search" empty state stopped appearing for zero-result queries. The debounce effect's early return when !workspaceResolved set loading = true without starting a timer, and a race condition between workspaceResolved and search dependency changes could leave loading stuck at true — preventing the empty-state condition (!loading && results.length === 0) from ever becoming true.

How

Moved the workspaceResolved check from the debounce effect to the rendering layer. The debounce timer now always fires; the search callback handles workspaceId === null by clearing loading. The skeleton/empty-state rendering conditions use workspaceResolved directly:

Also added a cleanup function to the workspace resolution effect to prevent stale callbacks in Strict Mode, and removed a redundant setLoading(true) from the search callback.

Testing

  • Added 3 unit tests in page-search.test.tsx:
    • Empty state renders after search returns no results
    • Skeleton loaders show while search is in progress
    • Skeletons persist while workspace is resolving (not the empty state)
  • All 107 unit tests pass (pnpm test)
  • All 42 E2E tests pass (pnpm test:e2e), including the previously failing search with no matches shows empty state
  • pnpm lint && pnpm typecheck clean

@vercel
Copy link
Copy Markdown

vercel Bot commented Apr 16, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
memo Ready Ready Preview, Comment Apr 16, 2026 11:33pm

Request Review

@zacharias-ona zacharias-ona merged commit f8a08fd into main Apr 16, 2026
6 checks passed
@zacharias-ona zacharias-ona deleted the fix/126-search-empty-state branch April 16, 2026 23:37
@zacharias-ona
Copy link
Copy Markdown
Collaborator Author

✅ UI verification passed — design spec compliance confirmed.

Static analysis: No violations found. All changed rendering conditions in page-search.tsx use existing design tokens (text-xs text-muted-foreground, bg-white/[0.08] animate-pulse, border-white/[0.06], bg-muted rounded-sm). No new colors, typography, spacing, or components introduced.

Visual verification (production):

  • Desktop (1280×800, dark): empty state "No pages match your search" renders correctly for no-match queries. Skeleton loaders display during loading. Search dropdown uses rounded-sm per floating element exception.
  • Mobile (375×812): empty state renders correctly after opening sidebar sheet. No horizontal scroll, layout intact.

@zacharias-ona
Copy link
Copy Markdown
Collaborator Author

✅ Post-merge verification passed.

E2E suite: 37/42 passed. The 5 failures are pre-existing editor test flakiness (strict mode violations from leftover content) — unrelated to this PR's search changes. Tracked in #140.

Key result: The search with no matches shows empty state test now passes — confirming the fix works in production.

Ad-hoc smoke tests — all passed:

Route Result
/ (landing page) ✅ Title present, 200 OK
/sign-in ✅ Email input rendered
/api/health ✅ Status OK
Authenticated login ✅ Redirected to workspace
Workspace load ✅ Page fully loaded
Editor navigation ✅ Editor element rendered

No routes skipped.

Also closed #136 — both failures it tracked (search empty state, re-invite toast) now pass.

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.

bug: UI regression after PR #123 — search empty state never renders for no-match queries

1 participant