Conversation
…uth bootstrap, map and dialog fixes, source link on every page
…ard rows, honest picker copy
…l, refresh errors keep the loaded org
…lidated bags, debounced picker
…acts, duplicate reply guard
…onest counts and formatting, keyboard rows
…hared source footer
…s; errors survive a pane switch
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.
What changed
Correctness and accessibility fixes across the operator dashboard.
Errors
Selection
Keyboard
Everywhere
Section-by-section fixes
Visible in: admin.
Before you start
admin.civfix.dev, once Admin test harness and characterization safety net #38, Admin security, crash and data-loss fixes #39 and this PR have merged to main.Verify
[Admin]
Error toasts
Keyboard rows
4. On "Users", press Tab to reach a second account row, then press Enter. Expect: that account opens.
5. Repeat with Space on "Reports", "Events", "Moderation" (including "Gov claims"), "Mail" (Outreach and Inbox), "Jurisdictions", "Organizations", "Host messaging" and "Signup pages". Expect: the row opens and the page does not scroll.
Deep links
6. Open
#/reports/<id of an old report>. Expect: that report opens, pinned above the list as "Linked report"; the first row does not take over.7. Repeat with
#/users/<id>,#/events/<id>and#/moderation/<id>for items that are not on page 1. Expect: each item opens.8. Open
#/users/<made-up uuid>. Expect: "User not found" / "No account has this ID.", with no "Try again".Filters keep the pick
9. On "Reports", under "In progress", click the second row, then the "Completed" chip. Expect: the same report stays open, pinned as "Selected report".
10. On "Users", pick an account and type a search that matches nothing. Expect: "Nothing matches" appears in the list and the account stays open.
11. On "Host messaging", pick a host and search for a name that does not match. Expect: the pane clears to "No host selected" (hosts cannot be reopened by id).
After an action
12. On "Users" under the "Active" chip, pick the test account, click "Ban account" and then "Ban". Expect: the toast " · account banned". Once the list refreshes, the detail reads "No user selected" and no other account opens. Undo with "Un-ban" under the "All" chip.
13. On "Moderation", pick an item under "All" and click "Keep". Expect: a dialog titled "Keep ". After you submit, the buttons stay busy until the list refreshes, then the toast " · kept" appears and the detail reads "No item selected".
14. On "Mail", switch to "Inbox", click the "Unread" chip and open a message. Expect: the message stays open and readable even though it leaves the Unread list.
Organizations
15. Click the "Pending review" chip. Expect: the detail opens on the Verification tab with the "Verify as ..." and "Reject" buttons.
16. Pick a verified org and open Verification. Expect: no decision buttons, and the note "No application is awaiting a decision."
17. On the tab list, press the Left, Right, Home and End keys. Expect: the selected tab moves.
Source link
18. Open any section and scroll to the bottom. Expect: "Source code (AGPL-3.0)" with the short commit hash. The Dashboard shows the same footer once.
Home and analytics
19. In DevTools block the request whose URL contains
/admin/home/summaryand reload the Dashboard. Expect: only the analytics cell shows "Could not load the dashboard summary"; the other tiles still list their preview rows. Unblock it and click "Try again".20. On the Dashboard, check the Mail tile. Expect: ages read like "5m" or "2h". Populations on the Jurisdictions tile read like "3.9M".
21. Open "Analytics". Expect: "Median resolution time" never shows "24h" or "1d 24h". Click "Export": in the CSV, Resolved reads like "42%", and accented names open correctly in Excel.
Mail and Jurisdictions
22. "Mail" → Outreach → "Needs attention" → open a bounced thread → "Fix routing contact". Expect: "Jurisdictions" opens on "All" with the GEOID in the search box and that jurisdiction open.
23. In that jurisdiction, empty a " contact email" field and click "Save draft". Expect: the toast "Draft saved for ", and after a reload that category has no contact.
24. Type "@ SF" in the discussion handle. Expect: the hint shows "@sf". Typing just "a" shows "Handle must be 2-40 characters using lowercase letters, numbers, or underscores." and disables saving.
25. Open a mail thread, type a reply, and press Ctrl+Enter (Cmd+Enter on Mac) three times quickly. Expect: exactly one reply is sent.
Reports and events
26. Open a report with a long chat. Expect: the chat count reads "50+". Click "Load older messages" and older messages appear.
27. Open a completed cleanup and type 2.5 in "Bags collected". Expect: "Log outcome" is disabled. Type 1 and save. Expect: the toast "Outcome logged · 1 bag".
Signup pages
28. Open "Signup pages". Expect: rows, the detail and the toasts show "/e/".
People and moderation dialogs
29. "Organizations" → Members → "Add member". Expect: the placeholder "Search by name, handle or city…". Searching for an existing member shows "Everyone matching is already a member."
30. On "Moderation", open a user report and click "Hold". Expect: a dialog titled "Hold for review".
Regression
Success toasts: [Admin]
First load: [Admin]
Dashboard: [Admin]
Signing out: [Admin]
Not covered
aria-current, accessible names) need a screen reader; automated tests assert the attributes.Findings addressed
The per-row verdicts (FIXED, REFUTED, DEFER) are in the campaign ledger. The main themes:
unknown.MutationCachehandler shows one error toast per failure, with per-mutation copy and inline field errors never toasting.ErrorStateand the user picker go througherrorMessage.aria-current(ADM-A11Y-002).aria-invalidandaria-describedby(A11Y-007)./e/slug.--ink-1variable; it now darkens to--ink(ADM-CSS-004).Decisions for the reviewer
RATE_LIMITEDorCONFLICTresponses.charset=utf-8.User-visible copy changes
Tests changed
nav("home", x), which now keep no focus;errorMessagequirks: a non-Error value gives the fallback, and thetoStringfield bug is fixed.text/csv;charset=utf-8.Verification
pnpm lint,pnpm typecheck,pnpm buildandpnpm testpass: 98 files, 1,056 tests, 3 consecutive runs.🤖 Generated with Claude Code