feat(ui): implement filter density tiers, mobile route deduplication, favourites timestamps, and answer notice (#309, #281, #339, #165) - #2074
Conversation
This pull request has been ignored for the connected project Preview Branches by Supabase. |
Warning Review limit reachedYou’ve reached a temporary PR review limit under our Fair Usage Limits Policy. Next review available in:38 minutes Limit details: You’ve used all 1 included review currently available under your plan. You completed 100 included PR reviews in the past 7 days; at that activity level, included reviews refill at 1 review per hour. Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available. How can I continue?After more reviews become available, a review can be triggered using the 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 configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (13)
Comment |
You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard. |
CI triageCI failed on this PR. Automated classification of the 2 failed job(s):
Compared with main CI run #11820 (cancelled). Classification is evidence routing, not permission to ignore a failure. Exact quarantined Playwright identities remain governed by the flake ledger. |
…polish' into gemini/ui-filter-density-mobile-polish-fix-2074
There was a problem hiding this comment.
Pull request overview
This PR extends the search UI/filtering and favourites experience by introducing density tiers for filter facets, a shared filter-sheet export surface, and client-side favourites “last opened” / pinned state, plus a small document viewer anchor adjustment and an answer-mode verification notice.
Changes:
- Add density-tier rendering for filter facet options (chips vs dense full-width rows) and document the contract.
- Introduce favourites localStorage-backed last-opened timestamps + pinned IDs, and integrate them into the favourites command library UI.
- Add contract tests covering filter exports, density tier behavior, and favourites storage behavior.
Reviewed changes
Copilot reviewed 12 out of 12 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
| tests/filter-contract.test.ts | Adds a structural/contract test asserting filter exports, density-tier detection, and documentation text. |
| tests/filter-contract.dom.test.tsx | Adds DOM-level tests for facet density tier rendering, disclosure chrome, and lens radio behavior. |
| tests/favourites.test.ts | Adds unit tests for favourites localStorage persistence, formatting, and scoring. |
| src/components/search/ResultFilterSheet.tsx | Adds a search/-scoped re-export surface for the filter sheet and related helpers/types. |
| src/components/favourites/favourites-storage.ts | Introduces the favourites localStorage store (timestamps + pinned IDs) and subscription mechanism. |
| src/components/clinical-dashboard/favourites-command-library-page.tsx | Integrates favourites store state into command items and records “opened” timestamps on interactions. |
| src/components/clinical-dashboard/result-filter-control.tsx | Implements density tier detection and dense list rendering for 6–20 facet options. |
| docs/filter-contract.md | Updates the documented filter density tiers and thresholds. |
| src/components/DocumentViewer.tsx | Adds a dedicated source-summary-card anchor id and scroll margin for the in-flow summary. |
| src/components/document-viewer/use-section-spy.ts | Adds an anchor alias so the section spy can resolve the correct rendered copy per breakpoint. |
| src/components/document-viewer/document-rail-panels.tsx | Hides the rail summary panel on small screens to avoid duplicate rendered sections. |
| src/components/clinical-dashboard/answer-status.tsx | Adds an answer-mode verification footer (“Verify against cited sources before clinical use”). |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
BigSimmo
commented
Aug 18, 2026
@copilot Fix the code for all comments in this review thread. When a review comment includes a suggested change, apply the suggestion exactly. Do not make changes beyond what is described in the linked review thread. |
…n useSyncExternalStore Co-authored-by: BigSimmo <87357024+BigSimmo@users.noreply.github.com>
Head branch was pushed to by a user without write access
Both issues addressed in commit
|
BigSimmo
commented
Aug 18, 2026
Overlap advisory (part of a cross-PR conflict sweep — no code changes made here beyond syncing this branch with This branch overlaps with #2040: #2040 folds a new service-group facet into This branch was just rebased onto the latest Generated by Claude Code |
CI's format:changed check was failing on this file's useSyncExternalStore formatting.
`max-sm:hidden` (added to dedupe the summary panel on phone viewports) also suppressed it during print emulation at narrow viewport widths, since the print stylesheet only restores overflow/box-shadow and never overrides display:none. Add `print:block`, the pattern already used elsewhere in this codebase (verification-notice.tsx, medication-considerations.tsx) to keep a responsively-hidden element printable. Fixes the "document viewer content disclosures are naturally closed and mutually exclusive by default" Production UI failure, which set a 390px viewport and asserted the high-yield-summary content becomes visible under print media.
The exclusive-accordion assertions after clicking the "High-yield summary" section-nav row assumed the rail's <details id="source-summary"> still opens on a 390px viewport. Since the mobile route-dedup change hides that rail copy (max-sm:hidden) in favour of the always-visible in-flow DocumentClinicalSummary card, jumpToDocumentSection's existing "displayed copy" resolution (use-section-spy.ts's source-summary -> source-summary-card alias) now scrolls to the card instead of toggling the hidden accordion — so `summary.open` never becomes true at this viewport. Assert the visible copy scrolls into view instead, matching the pattern already used for the "Indexed source text" row above it.
Uh oh!
There was an error while loading. Please reload this page.
Summary
ResultFilterFacetChips(src/components/clinical-dashboard/result-filter-control.tsx) now renders three density tiers instead of two: ≤5 options stay as wrapping chips, 6–20 options render as a dense full-width vertical list with a right-aligned count column and group headings, and >3 groups or >20 options additionally add find-a-filter plus collapse-by-default chrome.docs/filter-contract.md§5 is updated to document the new thresholds. Addssrc/components/search/ResultFilterSheet.tsxas a thin client re-export of the shared facet-chip primitives.DocumentViewer.tsxgives the in-flowDocumentClinicalSummarycard a canonicalid="source-summary-card"and scroll-margin offset;document-rail-panels.tsxhides the rail's duplicate high-yield summary panel on phones (max-sm:hidden) so the phone document route no longer renders two clinical-summary surfaces.use-section-spy.tsgets asource-summaryanchor alias so in-page navigation still resolves to the visible copy.src/components/favourites/favourites-storage.tscentralizes "last opened" timestamps and pinned-item ids inlocalStorage, with a single sharedstorage-event listener (avoiding an O(N²) fan-out across subscribers) and safe fallbacks for SSR/quota errors.favourites-command-library-page.tsxconsumes it viauseSyncExternalStore. Covered bytests/favourites.test.ts.answer-status.tsx's shared empty state now renders aModeHomeVerificationFooter("Clinical decision support — verify against cited sources before clinical use") on the answer mode home, replacing a comment that explained why no notice was there.tests/filter-contract.dom.test.tsxandtests/filter-contract.test.tsfor the new density-tier behaviour.Follow-up commits after the initial push (
c132a10,3a6c202,a98c42e) repaired CI blockers, fixed a duplicate DOM id under density tiers, and fixed the favourites O(N²) callback / hydration-mismatch issue. This handoff additionally fixed three problems the mobile-dedup change (#281) left behind, each caught by a subsequent CI run:2b1ba0c):favourites-command-library-page.tsxfailed theStatic PR checksformat:changedjob.09761d8):max-sm:hiddenon the rail's high-yield summary panel also suppressed it during print emulation at phone viewport widths (the print stylesheet only restoresoverflow/box-shadow, neverdisplay). Addedprint:block, the same pattern already used inverification-notice.tsxandmedication-considerations.tsx.fb6bf13): after the print fix let the test proceed further,document viewer content disclosures are naturally closed and mutually exclusive by defaultstill failed one line later — it asserted the rail's<details id="source-summary">opens after clicking the "High-yield summary" nav row at a 390px viewport. That's superseded behaviour:jumpToDocumentSectionalready resolves the displayed copy of a section (via thesource-summary→source-summary-cardalias this same PR added touse-section-spy.ts), so on phones it correctly scrolls to the visible in-flow card instead of toggling the now-hidden rail accordion. Updated the assertion to check the card scrolls into view, matching the pattern already used for the "Indexed source text" row directly above it.Verification
format:changedonfavourites-command-library-page.tsx.Production UIPlaywright failure attests/ui-smoke.spec.ts:4868(print visibility).Production UIPlaywright failure attests/ui-smoke.spec.ts:4889(stale accordion-open assertion), surfaced only after fixBump actions/setup-node from 4 to 6 #2 let the test run further.docs:check-index,docs:check-inventory,docs:check-scripts,docs:check-links,check:type-scale,check:icon-scale, andnpx prettier --checkon every changed file all pass.sitemap:checkcould not be run in this environment (missingtsxdevDependency locally, nonpm ciperformed) — this PR does not add or move any routes, so drift risk is low, but CI's ownSite map driftjob will still catch it if wrong.git merge-tree --write-tree origin/main <head>produces a clean tree with no conflict markers throughout this handoff — no real content conflict at any point; GitHub's "blocked" mergeable state reflected pending/failing required checks, not a merge conflict. The branch was also auto-synced withmainby existing repo automation partway through (merge commit09bb336), which is expected and unrelated to the above.verify:pr-local/verify:cheapwere not re-run locally in this pass (no local toolchain install in this environment); rely on the CI run against the pushed fix commits for that evidence.Risk and rollout
favourites-storage.tsonly touches a namespacedlocalStoragekey, so no server-side state to unwind.Clinical Governance Preflight
Not applicable in the strict sense — no ingestion, answer-generation, retrieval/ranking, or document-access code changed. The one clinical-facing string added (
ModeHomeVerificationFooteron the answer mode home) reinforces, rather than weakens, the existing "verify against cited sources" posture.pr-policydid not classify this diff as clinical-risk.Notes
2b1ba0cand09761d8are non-behavioural (formatting; a one-class print-only CSS addition).fb6bf13only updates a test assertion to match behaviour this PR's ownuse-section-spy.tsalias mechanism already implements — it does not change any production code.