fix: replace loading/searched booleans with searchStatus enum in page search (#162)#164
Merged
zacharias-ona merged 1 commit intomainfrom Apr 17, 2026
Merged
Conversation
… search (#162) The search empty state ('No pages match your search') never rendered reliably because two independent boolean flags (loading, searched) could get out of sync across async operations. This was the root cause of issues #118, #126, #136, #144, and #162 — each previous fix addressed a specific race condition but the underlying state machine remained fragile. Replace the independent loading and searched booleans with a single SearchStatus discriminated union ('idle' | 'loading' | 'done'). This makes it impossible for the flags to desynchronize because there is only one state variable to transition. Key changes: - searchStatus='done' is set in both the early return path (when workspaceId is null) and the finally block, closing the gap where searched was never set to true - Render conditions (showSkeleton, showEmpty) are computed from searchStatus + workspaceResolved, making the logic explicit - AbortErrors are no longer sent to Sentry (they are expected during rapid typing) Co-authored-by: Ona <no-reply@ona.com>
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
Collaborator
Author
|
✅ UI verification passed — design spec compliance confirmed. Static analysis — all changed UI in
Visual verification — Playwright screenshots of the workspace route (desktop dark + mobile) confirmed:
|
4 tasks
Collaborator
Author
|
❌ Post-merge verification failed. E2E suite: 41/42 passed, 1 failed
Ad-hoc smoke tests: all passed
See #166. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #162
What
The search empty state ("No pages match your search") never rendered reliably. This is the 5th occurrence of the same bug (previously #118, #126, #136, #144). Each previous fix addressed a specific race condition, but the underlying state machine — two independent boolean flags (
loadingandsearched) coordinated across async operations — remained fragile. The flags could desynchronize in timing windows involving workspace resolution, debounce resets, and fetch abort/retry cycles.How
Replace the independent
loadingandsearchedbooleans with a singleSearchStatusdiscriminated union ("idle" | "loading" | "done"). A single state variable cannot desynchronize with itself, eliminating the entire class of race conditions.Key changes:
searchStatus="done"is now set in both the early return path (whenworkspaceIdis null) and thefinallyblock. The old code only setsearched=truein thefinallyblock, which the early return bypassed entirely — leavingsearched=falsepermanently in certain timing windows.showSkeleton,showEmpty) are computed fromsearchStatus+workspaceResolved, making the display logic explicit and auditable.AbortErrorexceptions are no longer sent to Sentry (they are expected during rapid typing).Testing
searchStatus="done"so the empty state renders whenworkspaceIdis null andworkspaceResolvedis true.pnpm lint && pnpm typecheck && pnpm test).pnpm test:e2e -- e2e/search.spec.ts).