Skip to content

feat(explore): policy feed as wire-service dispatch board#186

Merged
William-Hill merged 5 commits into
mainfrom
feat/policy-feed-wire-service
Apr 13, 2026
Merged

feat(explore): policy feed as wire-service dispatch board#186
William-Hill merged 5 commits into
mainfrom
feat/policy-feed-wire-service

Conversation

@William-Hill

@William-Hill William-Hill commented Apr 13, 2026

Copy link
Copy Markdown
Owner

Summary

Follow-up to #185 addressing feedback that the bills table was hard to use: (1) no way to tell which state a bill belonged to in the unfiltered view, and (2) no search. Committed to a "legislative wire / political desk" aesthetic that extends the existing terminal phrasing on the explore page.

  • Dateline stamp on every rowBillFeedRow now shows a 2-letter state monogram with an accent tick and "DATELINE" caption to the left of each bill. Hidden when a single state is already selected in the filter panel (redundant there).
  • Command-bar search — added a search input to the feed header: > prompt prefix, placeholder shows live dispatch count (filter 1,243 dispatches…), global / keyboard shortcut focuses it, Esc clears it, kbd hints render inline. Filters by title, bill number, summary, state abbrev, and state name.
  • Title promoted as the primary element — bumped from text-sm muted to text-[15px] font-medium text-gray-100. Metadata (bill number, phase, filed date) recedes to uppercase mono.
  • Dispatch link — external link relabeled from "view →" to "dispatch →" with an underlined accent treatment consistent with the wire-service metaphor.
  • ScrollChevron extraction — pulled the duplicated left/right chevron blocks in DataSourceTabs into a single reusable component.

Test plan

  • Load /explore → Policy Bills tab: each row shows a XX · DATELINE stamp to the left of the phase glyph
  • Select a state on the map: dateline stamp disappears on each row (redundant)
  • Press / anywhere on the page: search input receives focus and selects existing text
  • Type in the search box: feed filters in real time; "showing X of Y" updates
  • Press Esc while focused: search clears
  • Click the esc pill with search active: clears and refocuses input
  • With no search: / hint kbd visible; with focus: hint fades out
  • Tab row still renders identically with scroll chevrons (regression check on fix(explore): improve Policy Bills tab discoverability #185)

Summary by CodeRabbit

  • New Features

    • Bill search in the feed with / keyboard shortcut, Escape to clear, inline hint/button, and client-side filtering.
  • UI Improvements

    • Refined bill header spacing, typography, and metadata styling.
    • Action link label changed from "view" to "dispatch" with updated hover/underline behavior.
    • Optional timeline/dateline display (auto-hidden when filtering by state).
    • Improved tab scroll controls with clearer edge fades and chevrons.

William Hill added 3 commits April 13, 2026 16:49
- BillFeedRow now displays a colored state-abbreviation chip alongside
  the bill number so the state is visible even when no state filter is
  active. The chip is de-emphasized when the user has already filtered
  to a single state.
- Added a search input to the policy feed header that filters bills by
  title, bill number, summary, and state. Works alongside the existing
  state/status/topic filters and flows through the same 'showing X of Y'
  counter.
Commits to a distinctive 'legislative wire / political desk' aesthetic
for the Policy Bills feed, extending the existing terminal phrasing.

- BillFeedRow: promote the title to the primary typographic element
  (larger, brighter, heavier). Metadata recedes to muted uppercase mono.
  Replace 'view' link with 'dispatch →' underlined in accent green. Add
  optional dateline stamp (a press-stamp block with the 2-letter state
  monogram, accent tick, and 'DATELINE' caption) for non-grouped views.
- PolicyExploreView: when no state is selected, group the feed by state
  with sticky DATELINE banners above each group. State identity is
  now undeniable at a glance. When a state IS selected, the group
  banner and per-row dateline are both hidden (redundant).
- Upgrade the search input into a command-bar: '>' prompt prefix,
  placeholder shows live dispatch count, global '/' keyboard shortcut
  focuses it, Esc clears it, kbd hints inline.
- Drop the state-grouped feed render. Grouping only-consecutive
  same-state bills after sorting by date produced scattered groups
  (e.g., TX, CA, TX again) that defeated the goal of seeing all bills
  per state together. Revert to the chronological feed with the
  per-row dateline stamp (which already solves state-at-a-glance).
- Extract ScrollChevron from the left/right duplicated blocks in
  DataSourceTabs.
- Drop narration-style comments that described WHAT the code does.
@coderabbitai

coderabbitai Bot commented Apr 13, 2026

Copy link
Copy Markdown
Contributor

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: 5a313521-c2a2-427d-9a63-5675ae68f413

📥 Commits

Reviewing files that changed from the base of the PR and between 6dd16d4 and 0756c45.

📒 Files selected for processing (1)
  • ui-nextjs/components/explore/PolicyExploreView.tsx

📝 Walkthrough

Walkthrough

Adds client-side bill search with a "/" keyboard shortcut and escape-to-clear, refactors tab scroll chevrons into a shared helper, and updates BillFeedRow to accept a hideDateline prop and adjust header/metadata/action typography and spacing.

Changes

Cohort / File(s) Summary
Bill Feed UI
ui-nextjs/components/explore/BillFeedRow.tsx
Added optional hideDateline?: boolean prop (default false) to omit the left-side dateline block; added group class for hover-driven styling; adjusted header spacing, title/metadata typography, and updated action link label/styling (view →dispatch →).
Policy Explore / Search
ui-nextjs/components/explore/PolicyExploreView.tsx
Added searchQuery state and searchRef; global / keyboard shortcut to focus/select search input; case-insensitive filtering across title, bill_number, summary, state, state_name; escape-to-clear and conditional clear UI; updated empty-state logic and pass hideDateline={filters.stateFips !== null} to BillFeedRow.
Tabs Scroll/Edge Fade
ui-nextjs/components/explore/DataSourceTabs.tsx
Introduced non-exported ScrollChevron helper and shared positioning/gradient constants; replaced duplicated left/right scroll JSX with ScrollChevron usage and direction-driven SVG polyline logic; removed per-side inline duplication.

Sequence Diagram(s)

sequenceDiagram
    participant User as User
    participant Browser as Browser/DOM
    participant View as PolicyExploreView
    participant RowList as BillFeedRowList

    User->>Browser: press "/"
    Browser->>View: keydown event
    View->>Browser: focus & select search input
    User->>View: type query
    View->>View: update searchQuery state
    View->>RowList: compute matchingBills (filter by query) and render
    RowList->>Browser: render rows (each with hideDateline as passed)
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately describes the main visual and UX transformation—reframing the policy bills feed as a 'wire-service dispatch board' with datelines, search, and revised terminology, which aligns with the core changes across BillFeedRow, DataSourceTabs, and PolicyExploreView.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/policy-feed-wire-service

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

@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: da87f0802a

ℹ️ 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 ui-nextjs/components/explore/BillFeedRow.tsx
@greptile-apps

greptile-apps Bot commented Apr 13, 2026

Copy link
Copy Markdown

Greptile Summary

This PR redesigns the Policy Bills tab on /explore as a "legislative wire / political desk" dispatch board. The three key additions are: a dateline stamp on each bill row (2-letter state monogram that auto-hides when a state filter is already active), a command-bar search input with a / global shortcut and Esc to clear, and a title promotion that makes the bill title the visual anchor. DataSourceTabs also gets a clean ScrollChevron component extraction to eliminate duplicated chevron markup.

The overall direction is solid and the UX details (keyboard shortcuts, live count feedback, stagger animation, aria-label coverage) are well-executed. One P1 data-display bug needs fixing before merge:

  • BillFeedRow mislabels the dateformatRelativeDate(bill.last_action_date) is formatted but the label reads \"filed\". introduced_date is the actual bill-filing date; last_action_date can be significantly later (amendments, votes, hearings). The fix is a one-liner: either swap in bill.introduced_date, or change the label to \"last action\".
  • Search cap at 50 — the FEED_LIMIT = 50 slice applies to search results too. Matching bills beyond position 50 (ranked by most-recent action) are silently hidden. A load-more or cap-lift while searching would prevent the search bar from appearing unreliable.

Confidence Score: 4/5

Safe to merge after fixing the "filed" label — it's a one-liner in BillFeedRow.tsx and the rest of the PR is well-constructed.

One P1 date-label mislabelling needs a one-line fix; all other changes are clean UX additions with good accessibility hygiene. The ScrollChevron refactor in DataSourceTabs is a straightforward extraction with no logic changes. No security, auth, or data-persistence concerns. The search-cap P2 is a UX follow-up, not a blocker.

ui-nextjs/components/explore/BillFeedRow.tsx — fix last_action_dateintroduced_date (or relabel to "last action").

Important Files Changed

Filename Overview
ui-nextjs/components/explore/BillFeedRow.tsx New component for the wire-service feed row; contains a P1 mislabelling bug where "filed" is rendered alongside last_action_date instead of introduced_date.
ui-nextjs/components/explore/PolicyExploreView.tsx Adds command-bar search with / shortcut and live "showing X of Y" count; search results are still capped at FEED_LIMIT=50 with no load-more affordance, which can silently hide matching bills.
ui-nextjs/components/explore/DataSourceTabs.tsx Clean refactor extracting the duplicated left/right chevron block into a single ScrollChevron component; no behavioural changes, logic is correct.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    A([API fetch – up to 5000 bills]) --> B[allBills state]
    B --> C{matchingBills useMemo}
    
    F1[filters.stateFips] --> C
    F2[filters.statuses] --> C
    F3[filters.topics] --> C
    F4[searchQuery\ntitle · bill_number · summary\nstate · state_name] --> C

    C --> D[sort by last_action_date desc]
    D --> E[filteredBills\nslice 0–50]

    E --> G[BillFeedRow × N]

    G --> H{hideDateline?}
    H -- stateFips !== null --> I[hide dateline stamp]
    H -- stateFips === null --> J[show XX · DATELINE]

    K([/ keydown]) --> L[searchRef.focus + select]
    M([Esc keydown]) --> N[clear searchQuery]
    O([esc pill click]) --> N
Loading

Comments Outside Diff (1)

  1. ui-nextjs/components/explore/PolicyExploreView.tsx, line 137-140 (link)

    P2 Search results silently capped at FEED_LIMIT (50)

    filteredBills always slices to FEED_LIMIT = 50 regardless of whether the user has typed a search query. When a search returns, say, 200 matching bills, only the 50 most-recently-actioned ones are shown — the remaining 150 are invisible with no affordance to load more. The count display (showing 50 of 200) surfaces this, but there is no pagination or "load more" mechanism. A user searching for a specific bill that ranks 51st by last_action_date would never find it through the search box.

    Consider either:

    • Raising or removing the cap while a search query is active (e.g., matchingBills.slice(0, searchQuery ? matchingBills.length : FEED_LIMIT)), or
    • Adding a "load more / show all" affordance when matchingBills.length > filteredBills.length.

    This is a P2 UX concern rather than a data-correctness bug, but it can make the search feel unreliable for users who know a specific bill exists.

Reviews (1): Last reviewed commit: "refactor(explore): simplify policy feed ..." | Re-trigger Greptile

Comment thread ui-nextjs/components/explore/BillFeedRow.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: 2

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
ui-nextjs/components/explore/BillFeedRow.tsx (1)

97-105: ⚠️ Potential issue | 🟡 Minor

Accessible action text is inconsistent with visible link text.

Line 101 uses “View …” while Line 104 says “dispatch →”. Screen reader output should match the visible action copy.

Proposed fix
-          aria-label={`View ${bill.bill_number}: ${bill.title}`}
+          aria-label={`Dispatch ${bill.bill_number}: ${bill.title}`}
As per coding guidelines "ui-nextjs/**/*.tsx: ... Check for proper TypeScript strict mode compliance and accessibility."
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@ui-nextjs/components/explore/BillFeedRow.tsx` around lines 97 - 105, The
anchor in BillFeedRow.tsx has an aria-label "View {bill.bill_number}:
{bill.title}" that doesn't match the visible link text "dispatch →"; update the
aria-label on that <a> (the dispatch link) to match the visible copy (e.g.,
"dispatch" or "dispatch — {bill.bill_number}: {bill.title}" if you need extra
context) so screen reader output matches the visible action text; ensure the
change is made on the anchor with href={bill.url} and preserves target, rel, and
existing classes.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@ui-nextjs/components/explore/BillFeedRow.tsx`:
- Line 22: The "filed" label is using the wrong source date: create a separate
relative date for the filed timestamp instead of reusing relativeDate (which
should reflect last_action_date). In BillFeedRow, add a new variable (e.g.,
filedRelativeDate) computed from bill.filed_date (via formatRelativeDate) and
update the JSX that renders the "filed ..." text to use filedRelativeDate; keep
the existing relativeDate (or rename to lastActionRelativeDate) for
last_action_date usages so each label shows the correct date source.

In `@ui-nextjs/components/explore/PolicyExploreView.tsx`:
- Around line 37-43: The keyboard handler inside PolicyExploreView.tsx (the
const handler in the useEffect) currently ignores INPUT, TEXTAREA, and
contentEditable but not SELECT elements; update the guard to also skip when the
focused element's tagName is 'SELECT' (ensure you check tag === 'SELECT'
alongside 'INPUT' and 'TEXTAREA') so pressing '/' while a select is focused
doesn't hijack focus for the search shortcut.

---

Outside diff comments:
In `@ui-nextjs/components/explore/BillFeedRow.tsx`:
- Around line 97-105: The anchor in BillFeedRow.tsx has an aria-label "View
{bill.bill_number}: {bill.title}" that doesn't match the visible link text
"dispatch →"; update the aria-label on that <a> (the dispatch link) to match the
visible copy (e.g., "dispatch" or "dispatch — {bill.bill_number}: {bill.title}"
if you need extra context) so screen reader output matches the visible action
text; ensure the change is made on the anchor with href={bill.url} and preserves
target, rel, and existing classes.
🪄 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: ASSERTIVE

Plan: Pro

Run ID: 3969d482-e137-4551-ba77-226cc21878d8

📥 Commits

Reviewing files that changed from the base of the PR and between e9db892 and da87f08.

📒 Files selected for processing (3)
  • ui-nextjs/components/explore/BillFeedRow.tsx
  • ui-nextjs/components/explore/DataSourceTabs.tsx
  • ui-nextjs/components/explore/PolicyExploreView.tsx

Comment thread ui-nextjs/components/explore/BillFeedRow.tsx
Comment thread ui-nextjs/components/explore/PolicyExploreView.tsx
- Relabel the timestamp in BillFeedRow from 'filed' to 'last action' so
  it matches the underlying bill.last_action_date value. The feed is
  sorted by most-recent action, so that's the meaningful timestamp.
- Add SELECT to the tag list skipped by the '/' keyboard shortcut in
  PolicyExploreView so pressing '/' while a select is focused doesn't
  hijack focus.

@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

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
ui-nextjs/components/explore/BillFeedRow.tsx (1)

97-105: ⚠️ Potential issue | 🟡 Minor

Update the link’s accessible name to match “dispatch”.

The visible label changed to dispatch →, but aria-label still announces View .... Because aria-label overrides the link text, screen reader users will get the old wording.

Suggested fix
         <a
           href={bill.url}
           target="_blank"
           rel="noopener noreferrer"
-          aria-label={`View ${bill.bill_number}: ${bill.title}`}
+          aria-label={`Dispatch ${bill.bill_number}: ${bill.title}`}
           className="shrink-0 self-center text-[11px] font-mono uppercase tracking-wider text-[`#00ff32`]/80 hover:text-[`#00ff32`] whitespace-nowrap border-b border-[`#00ff32`]/30 hover:border-[`#00ff32`] pb-0.5 transition-colors"
         >
           dispatch →
         </a>

As per coding guidelines ui-nextjs/**/*.tsx: “Check for proper TypeScript strict mode compliance and accessibility.”

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@ui-nextjs/components/explore/BillFeedRow.tsx` around lines 97 - 105, Update
the anchor in BillFeedRow so its ARIA name matches the visible label "dispatch
→": locate the <a> element in the BillFeedRow component that currently sets
aria-label={`View ${bill.bill_number}: ${bill.title}`} and change the aria-label
to "dispatch" (or to include the visible arrow if desired) or remove the
aria-label so the link text is announced; ensure the change references the same
bill prop and preserves target, rel, and styling.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@ui-nextjs/components/explore/PolicyExploreView.tsx`:
- Around line 214-219: The decorative prefix and shortcut hint span elements in
PolicyExploreView.tsx (the spans rendering ">" and the "/" hint) sit over the
input and block clicks—add the CSS utility class pointer-events-none to those
span elements (keep aria-hidden) so they become click-through, and apply the
same change to the second occurrence around lines ~257-265 to ensure clicks
focus the search field.

---

Outside diff comments:
In `@ui-nextjs/components/explore/BillFeedRow.tsx`:
- Around line 97-105: Update the anchor in BillFeedRow so its ARIA name matches
the visible label "dispatch →": locate the <a> element in the BillFeedRow
component that currently sets aria-label={`View ${bill.bill_number}:
${bill.title}`} and change the aria-label to "dispatch" (or to include the
visible arrow if desired) or remove the aria-label so the link text is
announced; ensure the change references the same bill prop and preserves target,
rel, and styling.
🪄 Autofix (Beta)

✅ Autofix completed


ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: 794d3331-4a7d-424a-bd69-f783d42b4672

📥 Commits

Reviewing files that changed from the base of the PR and between da87f08 and 6dd16d4.

📒 Files selected for processing (2)
  • ui-nextjs/components/explore/BillFeedRow.tsx
  • ui-nextjs/components/explore/PolicyExploreView.tsx

Comment thread ui-nextjs/components/explore/PolicyExploreView.tsx
@coderabbitai

coderabbitai Bot commented Apr 13, 2026

Copy link
Copy Markdown
Contributor

Note

Autofix is a beta feature. Expect some limitations and changes as we gather feedback and continue to improve it.

Fixes Applied Successfully

Fixed 1 file(s) based on 1 unresolved review comment.

Files modified:

  • ui-nextjs/components/explore/PolicyExploreView.tsx

Commit: 0756c45a45501040fb120bd70cb7cf7368458344

The changes have been pushed to the feat/policy-feed-wire-service branch.

Time taken: 4m 24s

Fixed 1 file(s) based on 1 unresolved review comment.

Co-authored-by: CodeRabbit <noreply@coderabbit.ai>
@William-Hill William-Hill merged commit 4ac3143 into main Apr 13, 2026
4 checks passed
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.

1 participant