Skip to content

feat(dsm): compact category dropdown filter, more prominent results - #675

Merged
BigSimmo merged 4 commits into
mainfrom
claude/filter-layout-search-prominence-kwrbwl
Jul 14, 2026
Merged

feat(dsm): compact category dropdown filter, more prominent results#675
BigSimmo merged 4 commits into
mainfrom
claude/filter-layout-search-prominence-kwrbwl

Conversation

@BigSimmo

@BigSimmo BigSimmo commented Jul 14, 2026

Copy link
Copy Markdown
Owner

Summary

  • Replace the multi-row wall of category filter pills on the DSM search results page (/dsm/search) with a single compact dropdown menu, reclaiming ~3 rows of vertical space so results sit higher on the page.
  • Add a new CategoryFilterDropdown — an anchored menuitemradio menu of category links. Server-driven filtering is preserved (each option is a real navigation <Link>), the active category renders as the checked option with its count, and it supports keyboard navigation (Arrow/Home/End/Escape), outside-click + Escape dismissal via useDismissableLayer, and roving focus across options.
  • Collapse the filter into one toolbar row with an inline "Clear filter" affordance shown only when a category is active.
  • Add a prominent "Matching diagnoses / N results" header band to the results card so the result list is clearly anchored and emphasised.

Files changed:

  • src/components/dsm/dsm-search-page.tsx

Verification

  • npm run verify:pr-local
  • npm run verify:ui when UI, routing, styling, browser behavior, reduced-motion, or forced-colors behavior changed
  • npm run verify:release before release or handoff confidence claims

What was actually run in this session (UI-only change, demo mode):

  • npm run typecheck — no errors in src/ (pre-existing failures are all in tests/** from uninstalled test-only dev deps: @testing-library/*, @axe-core/playwright).
  • npx eslint src/components/dsm/dsm-search-page.tsx — clean.
  • Browser QA against the local server (npm run ensure, Chromium): desktop + mobile (390px), dropdown open/closed, and a functional click-through. Verified: selecting a category navigates to ?category=… and filters results, the trigger reflects the active category, aria-checked tracks the active option, "Clear filter" appears when active, Escape closes and restores focus, and there is 0px horizontal overflow at 390px.
  • The verify:pr-local / verify:ui gates were not run here — please run before merge.

Clinical Governance Preflight

Not applicable — this is a presentational change to the local DSM catalogue search UI. It does not touch ingestion, answer generation, search/ranking, source rendering, document access, privacy, production env, or clinical output. No Supabase, provider, or governance surface is affected.

Notes

  • Behaviour is unchanged: filtering is still URL/server-driven and the existing dsm-search-page / dsm-search-result test selectors are preserved. A stable data-testid="dsm-category-filter" was added to the dropdown trigger.

🤖 Generated with Claude Code


Generated by Claude Code

Summary by CodeRabbit

  • New Features
    • Added an accessible DSM category filter dropdown with active-state indicators, per-category counts, and keyboard navigation.
    • Added a conditional “Clear filter” link when a category is selected.
    • Added a results summary bar showing the current view (“Matching diagnoses” or “Diagnosis catalogue”) and the results count.
  • UI Improvements
    • Replaced the previous category link layout with a compact dropdown menu.
  • Tests
    • Added a UI smoke test covering keyboard opening, navigation, dismissal (Escape/Tab), and focus restoration.

Replace the multi-row wall of category filter pills on the DSM search
results page with a single compact dropdown menu, and give the results
list a prominent header band so it dominates the page.

- Add CategoryFilterDropdown: an anchored menuitemradio menu of category
  links (server-driven filtering preserved) with the active category
  shown as the checked option. Keyboard support (arrow/Home/End/Escape),
  outside-click + Escape dismissal via useDismissableLayer, and roving
  focus across options.
- Collapse the filter into one toolbar row with a "Clear filter"
  affordance when a category is active, reclaiming ~3 rows of vertical
  space so results sit higher.
- Add a "Matching diagnoses / N results" header band to the results card
  to anchor and emphasise the result list.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VnTrYkS5MjsB9JoA2bF4TH
@coderabbitai

coderabbitai Bot commented Jul 14, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Warning

Review limit reached

@BigSimmo, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 33 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 105ddbf1-c568-4b39-8137-5282d2300098

📥 Commits

Reviewing files that changed from the base of the PR and between 0ff0179 and 0241389.

📒 Files selected for processing (2)
  • src/components/dsm/dsm-search-page.tsx
  • tests/ui-smoke.spec.ts
📝 Walkthrough

Walkthrough

The DSM search page replaces category filter pills with a keyboard-navigable dropdown, adds conditional filter clearing, and displays the current results context with a computed diagnosis count.

Changes

DSM search interface

Layer / File(s) Summary
Category filter dropdown
src/components/dsm/dsm-search-page.tsx, tests/ui-smoke.spec.ts
Adds an anchored category menu with active-state indicators, dismissal handling, focus management, keyboard navigation, and smoke-test coverage.
Search page filter and results integration
src/components/dsm/dsm-search-page.tsx
Replaces the pill-based filter layout with the dropdown and conditional “Clear filter” link, then adds contextual results text and count above the results table.

Estimated code review effort: 4 (Complex) | ~45 minutes

Sequence Diagram(s)

sequenceDiagram
  participant User
  participant CategoryFilterDropdown
  participant CategoryLink
  participant DSMResults
  User->>CategoryFilterDropdown: Open category filter
  CategoryFilterDropdown->>CategoryLink: Focus active category option
  User->>CategoryLink: Select category
  CategoryLink->>DSMResults: Apply category navigation
  DSMResults-->>User: Show context label and result count
Loading
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 33.33% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title is concise and accurately summarizes the main UI change to a compact category dropdown with more prominent results.
Description check ✅ Passed The description matches the template sections and includes a clear summary, verification notes, governance note, and additional implementation notes.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch claude/filter-layout-search-prominence-kwrbwl

Comment @coderabbitai help to get the list of available commands.

@supabase

supabase Bot commented Jul 14, 2026

Copy link
Copy Markdown

This pull request has been ignored for the connected project sjrfecxgysukkwxsowpy because there are no changes detected in supabase directory. You can change this behaviour in Project Integrations Settings ↗︎.


Preview Branches by Supabase.
Learn more about Supabase Branching ↗︎.

@BigSimmo
BigSimmo marked this pull request as ready for review July 14, 2026 18:53
@BigSimmo
BigSimmo enabled auto-merge July 14, 2026 18:55

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 59ced590a9

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/components/dsm/dsm-search-page.tsx Outdated
@BigSimmo

Copy link
Copy Markdown
Owner Author

@codex resolve actionable Codex review findings for this pull request and current head using the repository instructions. This is the pull request's single automatic repair pass: do not perform a fresh review, create new standalone findings, or request another review. Work only the existing unresolved Codex threads on the current head. Always fix P0 and P1 findings. For P2 and lower findings, fix only clear, scoped, low-risk issues; otherwise disposition them with a concise reason. After fixing or dispositioning a thread, reply in that thread with as the first line, followed by a concise summary; that marker authorizes the workflow to close that exact thread. If human input or new authorization is required, do not use the marker and leave the thread open with the blocker. Finish only after every actionable thread is fixed or dispositioned and closed, or explicitly left open for a human decision. Do not update the branch from main, address unrelated reviews, broaden scope, or create more than one scoped fix commit. Do not use external APIs, paid services, credentials, dependency changes, or broad refactors unless explicitly authorized. Add targeted tests where behavior changes and run the narrowest relevant validation.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 59ced590a9

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/components/dsm/dsm-search-page.tsx
Address two keyboard-interaction defects in the new CategoryFilterDropdown
raised in review:

- ArrowUp reverse-entry: a focus-on-open effect and the trigger key
  handler both scheduled focus when the menu opened, racing each other so
  ArrowUp could land on the active item instead of the last option.
  Collapse to a single source of truth — openMenu(focusIndex) picks the
  target and schedules the one focus call.
- Tab focus-out: the menu stayed open (aria-expanded true) after a
  keyboard user tabbed off the last option, letting it linger over the
  results. Add a root focus-out handler that closes only when focus leaves
  the widget, without preventing the focus move or closing while focus
  travels between the trigger and its options.

Add a targeted ui-smoke test covering ArrowDown/ArrowUp entry points,
Escape restore-to-trigger, and Tab-to-close.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VnTrYkS5MjsB9JoA2bF4TH

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 0ff0179c6e

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/components/dsm/dsm-search-page.tsx

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/components/dsm/dsm-search-page.tsx`:
- Around line 100-118: Remove the Escape branch from handleOptionKeyDown and let
useDismissableLayer handle dismissal and focus restoration. Demote the
per-result headings near the results rendering from h2 to h3 so the section
header remains the sole h2. Optionally extract CategoryFilterDropdown into its
own module, then run verify:ui and check:production-readiness before merge.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 30bd633a-22b2-46dc-b173-500456fa4a01

📥 Commits

Reviewing files that changed from the base of the PR and between e75fad9 and 59ced59.

📒 Files selected for processing (1)
  • src/components/dsm/dsm-search-page.tsx

Comment thread src/components/dsm/dsm-search-page.tsx
Follow-up review fixes for the category filter dropdown:

- Give each menu option tabIndex={-1} (roving focus via the arrow keys), so a
  single Tab press leaves the whole widget instead of stepping through every
  category link, matching the ARIA menu-button pattern. The existing focus-out
  handler then closes the menu.
- Drop the duplicate Escape branch in the option key handler; useDismissableLayer
  already owns Escape dismissal and focus restoration, so this avoided calling
  focus() on the trigger twice.
- Demote per-result titles from h2 to h3 so the new "Matching diagnoses" section
  header is the sole h2 in the results region (h1 -> h2 -> h3).

Extend the ui-smoke keyboard test to assert Tab from a non-final option closes
the menu in one step.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VnTrYkS5MjsB9JoA2bF4TH

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: a6ff1b4700

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/components/dsm/dsm-search-page.tsx
Options are exposed as menuitemradio, where Space is an expected activation
key, but the underlying element is an anchor (Space scrolls / does nothing).
Handle Space in the option key handler with preventDefault() and route it
through the same activation path as click/Enter so keyboard users can apply the
announced radio menu item. Extend the ui-smoke keyboard test to assert Space
navigates to the focused category.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VnTrYkS5MjsB9JoA2bF4TH
@BigSimmo
BigSimmo merged commit f5888ff into main Jul 14, 2026
20 checks passed
@BigSimmo
BigSimmo deleted the claude/filter-layout-search-prominence-kwrbwl branch July 17, 2026 05:45
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.

2 participants