Skip to content

feat(view): add sequential run numbering and sortable table headers t… - #270

Open
Adityakk9031 wants to merge 2 commits into
robocurve:mainfrom
Adityakk9031:feature/247-synced-multicam-player
Open

feat(view): add sequential run numbering and sortable table headers t…#270
Adityakk9031 wants to merge 2 commits into
robocurve:mainfrom
Adityakk9031:feature/247-synced-multicam-player

Conversation

@Adityakk9031

Copy link
Copy Markdown
Contributor

Closes #247.

Enhancements

  1. Sequential Run Numbering: Assigns sequential run numbers (#1, #2, …) by creation order in the directory log index.
  2. Sortable Index Headers: Adds client-side click-to-sort functionality for all index columns with sort direction indicators ( / ).
  3. Filter Expansion: Search filter placeholder and content matching support run numbers (#1, #2).

Verification

  • ruff check . — Passed.
  • ruff format --check . — Passed.
  • pytest tests/test_html_index.py tests/test_html_view.py — 94 passed.

@Adityakk9031

Copy link
Copy Markdown
Contributor Author

@aris-zhu and @jeqcho have a look

@jeqcho jeqcho left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Thanks for picking this up! This lands right on the index wishlist from #247, and the execution shows care: run numbers carry a data-val for correct numeric sorting, the When header starts in the sort-desc state that matches the rendered order, the empty-state colspan and the listener-count test were both updated, and there's a focused new test for the numbering and headers. CI is fully green. A few things to address before merge:

  1. Sorting by When (and Log) is effectively a no-op. The comparator does parseFloat(aVal), and parseFloat("2026-07-29T12:00:00+00:00") returns 2026 — so every same-year timestamp compares equal and the stable sort leaves the order unchanged. Same problem for log filenames that start with a date stamp. Suggested fix: only take the numeric path when the whole value is numeric, e.g. const isNum = v => /^-?\d+(\.\d+)?$/.test(v); and use localeCompare otherwise — ISO 8601 strings sort correctly lexicographically. A quick manual check (click When, confirm the order actually flips with two same-year entries) would have caught this; worth adding to your verification list alongside the pytest run.
  2. Closes #247 will close the whole issue prematurely. #247 also covers the synced multicam player, transcript rail, media serving, and collision-proof run identity. Please change the PR description to something like Part of #247 / Addresses the index portion of #247.
  3. The new IndexEntry.run_number field is dead code. Neither _index_entry nor _unreadable_index_entry in cli.py ever sets it, so the entry.run_number is not None branch in _row is unreachable in practice. Simplest is to drop the field and the fallback entirely and just pass the computed number to _row. (While there, the id(entry) map can go too: enumerate the descending sort directly, e.g. run_num = len(entries) - i.)
  4. Edge case: unreadable logs grab the lowest run numbers. _unreadable_index_entry can produce created="", which sorts before every ISO timestamp, so a corrupt file becomes #1 and shifts every real run's number. Worth deciding how unreadable entries should participate in numbering (or at least sorting them last).
  5. Test name now contradicts its assertion. test_delegated_row_click_listener_is_present_once asserts count == 2 after this change. Please rename it (e.g. ..._click_listeners_are_row_delegation_and_header_sort) or split the assertion so the intent stays readable.
  6. Nice-to-have: set aria-sort="ascending"/"descending" on the active header (and remove it from the others) when sorting — the visual ▲/▼ is already there, this makes it available to screen readers too.

One broader design flag, just so it's on your radar: #247 ultimately wants run identity to be stable and collision-proof, whereas render-time renumbering shifts whenever a log is deleted (a saved filter like #3 would then match a different run). The fixes above stand either way — but the numbering scheme may evolve as the rest of #247 lands.

Happy to take another look once these are in — the overall shape is right and points 2, 3, and 5 are quick fixes; point 1 is the only real behavior bug.

@jeqcho

jeqcho commented Aug 8, 2026

Copy link
Copy Markdown
Collaborator

Thanks for coming back to this, @Adityakk9031! I took another look after your latest push.

Unfortunately, the new commit (f6639ad) is a merge of main into the branch — it updates the branch but doesn't contain any changes to the PR's own code, so all six points from the previous review are still outstanding:

  1. When/Log sorting no-op (the behavior bug) — still unresolved. The comparator in src/inspect_robots/_html_index.py still does parseFloat(aVal), and parseFloat("2026-07-29T12:00:00+00:00") returns 2026, so same-year timestamps all compare equal. The fix is unchanged from last time: only take the numeric path when the whole value is numeric (e.g. /^-?\d+(\.\d+)?$/.test(v)), and use localeCompare otherwise.
  2. Closes #247 — the PR description still says Closes #247; please change it to Part of #247 so merging this doesn't close the whole issue.
  3. Dead IndexEntry.run_number field — still present, still never set by cli.py; the entry.run_number is not None branch in _row remains unreachable. Dropping the field (and the id(entry) map, via enumerating the descending sort) still applies.
  4. Unreadable logs grabbing #1 — unchanged; created="" entries still sort first and shift every real run's number.
  5. Test name vs. assertiontest_delegated_row_click_listener_is_present_once in tests/test_html_index.py still asserts count == 2; please rename or split it.
  6. aria-sort (nice-to-have) — not added.

One important heads-up before you invest more time here: PR #272 ("view: multicam player with synced transcript rail, run numbering, sortable index") is now open and covers this PR's entire scope as part of the larger #247 work — sequential run numbering, sortable headers with persisted state, and run-number filtering, plus the collision-proof run identity that makes the numbering stable. If #272 merges, this PR would be redundant. It may be worth holding off on further changes here until that lands — and thank you again for the contribution and for engaging with #247; the index was a genuinely useful place to start.

@jeqcho

jeqcho commented Aug 9, 2026

Copy link
Copy Markdown
Collaborator

Update, @Adityakk9031 — good news for this PR: #272 has been closed rather than merged. The larger view work was split into focused pieces, and the index slice this PR covers is now tracked by #354 ("view: index UX from #272 — run numbering, sortable headers, richer filter"). Since this PR only touches _html_index.py and its tests, it was not invalidated by the report rewrites that superseded #272 — so the lane is open again and this PR is the active one for #354.

To take it forward:

  1. Re-target the description: change Closes #247 to Closes #354 (view: synced multicam player with live transcript rail, run numbering, sortable index #247 was closed as split, so this PR should close the scoped issue instead).
  2. Address the six points from the 2026-08-02 review — they all still stand, most importantly the parseFloat date-sorting bug. view: multicam player with synced transcript rail, run numbering, sortable index #272's index implementation is linked from view: index UX from #272 — run numbering, sortable headers, richer filter #354 as a reference if it helps (its numeric-vs-string comparator and stable sort are worth a look).
  3. Optional extra scope, entirely your call: view: multicam player with synced transcript rail, run numbering, sortable index #272's index work also included a viewport-fit table layout and a two-line When cell, which this PR doesn't cover. Those can ride along here if you'd like to pick them up, or stay in view: index UX from #272 — run numbering, sortable headers, richer filter #354 as remainder scope for later.

One boundary note: the collision-proof run-identity work is tracked separately in #355 and is out of scope here — no need to touch it.

Happy to re-review as soon as the six points are addressed. Thanks for your patience through the #272 shuffle — the timing was unlucky, but your instinct to start with the index was right, and it's now exactly the piece that's still needed.

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.

view: synced multicam player with live transcript rail, run numbering, sortable index

2 participants