Skip to content

analytics: make table sorting consistent (default direction, keyboard access, locale compare, one shared helper) #236

Description

@dborup

Relates to #226, #230

Problem

The #230 review found that the analytics page now has three local table sorts that behave differently:

  1. Default direction (UX).
    • Hash Stats starts every column ascending, so a first click on Adverts shows the fewest first, and a first click on Last Seen shows the oldest first.
    • The channel table (analytics.js ~1462: name/hash asc, otherwise desc) and Areas (ascByDefault, desc by default) start numeric and time columns descending.
  2. Keyboard access and a11y.
    • The sortable <th> headers in the channel table and in Hash Stats have no tabindex and no <button>, so they cannot be reached by keyboard.
    • The ⇅/↑/↓ span from channelSortArrow has no aria-hidden="true", so the glyph becomes part of each header's accessible name. aria-sort is set in Hash Stats, which makes the glyph redundant there.
  3. Locale-aware compare. Node and Role names are compared as lower-cased strings by code point. Names starting with Æ/Ø/Å, accented letters or emoji therefore sort after z. localeCompare (or Intl.Collator) would place them naturally.
  4. DRY. The fix(analytics): sort the Hash Stats adopters table by the clicked column, with direction (#226) #230 comparator is stable through an index tie-break and puts NaN last in both directions, which makes it the most complete of the three. It is a good candidate for a shared helper.

Proposed fix

  • Extract one shared sort helper (comparator plus header state) and use it for the channel table, Areas and Hash Stats.
  • Give each column a default direction: text ascending, numbers and times descending.
  • Render sortable headers as <button>s inside <th>, or make them focusable with Enter/Space handling. Keep aria-sort, and mark the arrow glyph aria-hidden="true".
  • Use localeCompare / Intl.Collator for text columns.
  • Keep the existing deep links (mbsort=/mbdir= and any channel-table params) working unchanged.

Acceptance

  • The same column types start in the same direction in all three tables, and unit tests pin the first-click direction per column type.
  • Every sortable header can be reached with Tab and sorted with Enter/Space, with no glyph in the accessible name. Covered by an E2E.
  • Names starting with Æ/Ø/Å sort in locale order, with a unit test.
  • There is one comparator implementation. No hardcoded colours, and scripts/check-xss-sinks.sh --diff is clean.

Activity

  1. added a commit that references this issue on Oct 7, 2026
  2. dborup commented on Oct 7, 2026

    @dborup
    OwnerAuthor

    Fixed by #347 (merged as e8e99c4a2c7db986a10bf7ff1a642a94e62b913b).

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions