Skip to content

fix(tui): distinguish dialog empty states#36727

Open
kitlangton wants to merge 1 commit into
v2from
dialog-empty-states
Open

fix(tui): distinguish dialog empty states#36727
kitlangton wants to merge 1 commit into
v2from
dialog-empty-states

Conversation

@kitlangton

Copy link
Copy Markdown
Contributor

What

Give DialogSelect explicit empty-state semantics so loading, an empty collection, and a filtered miss no longer all read as No results found.

Sessions now says No sessions yet when the collection is empty. Skills says No skills available when no skills load, while preserving its existing inline load error. Both resource-backed dialogs show Loading... while appropriate, and filtered misses use the existing app convention No matching results.

Before / After

Before: Opening an empty Sessions dialog immediately showed No results found. Searching Sessions or Skills for a missing item showed the same copy, including while a debounced remote session query had not completed, so users could not tell whether the collection was empty, the filter missed, or data was still loading.

After: An unfiltered empty collection uses the consumer's domain copy, a pending empty result uses Loading..., and a non-empty filter with no visible options uses No matching results. Session search ties loading to the visible query as well as the debounced resource key, so stale results cannot briefly claim there are no matches.

How

  • Add an optional loading prop to DialogSelect and resolve empty content in this order: loading, filtered miss, consumer emptyView, generic No items fallback.
  • Track the Sessions dialog's visible filter separately from its debounced request query and accept resource data only when its query identity matches the visible filter.
  • Pass resource loading and domain empty views from Sessions and Skills; pass the clear initial resource loading state from file autocomplete.
  • Add focused @opentui/solid testRender coverage for loading, custom unfiltered empty/error content, filtered no-match content, and the generic fallback.
flowchart TD
  A[No visible options] --> B{loading?}
  B -->|yes| C[Loading...]
  B -->|no| D{filter non-empty?}
  D -->|yes| E[No matching results]
  D -->|no| F[Consumer emptyView or No items]
Loading

Scope

  • V2 packages/tui only. packages/opencode V1 is unchanged.
  • Existing dialogs that already model loading/error rows explicitly are unchanged.
  • No server, protocol, or resource API changes.

Testing

  • bun run test test/ui/dialog-select.test.tsx from packages/tui (2 passed)
  • bun typecheck from packages/tui
  • Push hook: bun turbo typecheck --concurrency=3 (32 tasks passed)
  • opencode-drive check ./dialog-empty-states.drive.ts before each recording
  • Same isolated Sessions/Skills walkthrough recorded against unmodified origin/v2 and this branch

Demo

Left: unmodified origin/v2. Right: this branch. The drive fixture has no user sessions. V2 always contributes the built-in OpenCode and Report skills, so the Skills segment honestly demonstrates a filtered miss; the Sessions Loading... frame is the real 150 ms debounce/resource transition, not an artificial delay.

dialog-empty-before-after.mp4

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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant