Conversation
Generated by 🚫 Danger |
There was a problem hiding this comment.
Copilot review overview
🟡 Changes recommended
Out-of-range paginated pages can report incorrect row counts and footer indices.
Get a fresh assessment by requesting another Copilot review.
Review effort: Lite
Findings: 1
Open (1)
What changed in this PR
Adds ARIA row counts and indices to Border Box tables, including sortable-list reindexing and test/documentation coverage.
Changes:
- Adds pagination-aware
aria-rowcountandaria-rowindex. - Reindexes rows after sorting and rollback.
- Updates component, frontend, feature, and LookBook coverage.
| File | Description |
|---|---|
spec/features/roles/index_spec.rb |
Verifies accessible row indices. |
spec/components/op_primer/border_box_table_component_spec.rb |
Tests ARIA table semantics and pagination. |
lookbook/docs/10-components/tables/border-box-table.md.erb |
Documents ARIA indexing support. |
frontend/src/stimulus/controllers/dynamic/sortable-lists/list-dom.ts |
Integrates row reindexing with sorting. |
frontend/src/stimulus/controllers/dynamic/sortable-lists/list-dom.spec.ts |
Tests reorder and rollback behavior. |
frontend/src/stimulus/controllers/dynamic/sortable-lists/aria-row-indices.ts |
Provides sortable-row reindexing. |
app/components/op_primer/border_box_table_component.rb |
Calculates row counts and pagination offsets. |
app/components/op_primer/border_box_table_component.html.erb |
Renders ARIA row attributes. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
084a13d to
e25645b
Compare
e25645b to
d0ab302
Compare
d0ab302 to
7382936
Compare
49f765b to
a27a663
Compare
| end | ||
|
|
||
| def body_row_count | ||
| [paginated? ? rows.total_entries : rows.size, 1].max |
There was a problem hiding this comment.
Could we use rows.length for the non-paginated case? We render all these records anyway, so this would avoid a separate count query before loading them.
There was a problem hiding this comment.
size should take care of that automatically - calling length if the collection is loaded and count if not.
Rows of the shared table carried no aria-rowindex, so assistive technology could not announce a row's position within a paginated collection and specs could not address rows by position through the accessible :row selector's rowindex filter. Sets aria-rowcount on the table and aria-rowindex on every row, offset by the current page. Both header rows share index 1 because only one is displayed per breakpoint. https://community.openproject.org/wp/DREAM-858
sortable-lists moves rows on the client before the server answers, and the Roles table keeps a 204 response, so the server-rendered aria-rowindex stayed with the moved record and the table announced positions out of order. Captures the first index of every touched rows container before a move or rollback and renumbers the indexed rows in DOM order afterwards, which keeps the page offset. The Roles feature spec asserts row indices whenever it checks the listing. https://community.openproject.org/wp/DREAM-858
Replaces the link-text scrape in Pages::Admin::Statuses#expect_listed with the accessible :row selector's rowindex filter, so the listing checks the announced positions too. Page-two examples pass the first row's index, which proves the page offset in the live table.
Clears the token association cache before the API and iCalendar meeting creation requests in DREAM-858 specs. ARIA row counting calls size, which marks empty associations as loaded, while login_as reuses the same user across requests. Reloading matches production request boundaries and preserves the post-creation table assertions.
a27a663 to
dd4be4d
Compare
Asserts the document types order through the `:row` selector's `rowindex:` filter now that Border Box Table rows carry `aria-rowindex`, and drops the `position:` expression filter patched onto `:row` for lack of it. https://community.openproject.org/wp/DREAM-858
|
Warning Flaky specs
🤖 Ask Copilot to investigateCopy the prompt below into a new comment on this PR to delegate the investigation to GitHub Copilot. It will look into the flakiness and open a separate pull request with you as reviewer. |
|
@bsatarnejad I've also pushed one new commit that needs review: 1773d47) (it's just spec cleanup left over from #25468, so I went ahead and did it in this PR) |

Ticket
https://community.openproject.org/wp/DREAM-858
What are you trying to accomplish?
OpPrimer::BorderBoxTableComponentrenders an ARIA table with column indices but no row indices, so screen readers cannot announce a row's position within a paginated collection and specs cannot address rows through the accessible:rowselector'srowindex:filter.The table now sets
aria-rowcountand every row carriesaria-rowindex: both header rows share index 1 (only one is displayed per breakpoint), body rows start at 2 offset by the current page, and the footer row is last.What approach did you choose and why?
The attributes are additive, so consumers need no change.
aria-rowcountusestotal_entriesfor paginated collections and the rendered size otherwise; the page offset comes fromcurrent_pageandper_page, which bothWillPaginate::Collectionand paginated relations expose.sortable-lists moves rows on the client before the server answers (the Roles table keeps a 204 response), so
reorderRowsandrestoreRowPositionsnow run throughreindexAriaRowsAfterin the newsortable-lists/aria-row-indices.ts, which renumbers the indexed rows of a container in DOM order after a move or rollback. Scoped to reordering within one table; lists withoutaria-rowindexare untouched.Pages::Admin::Statuses#expect_listedandPages::Admin::DocumentTypes#expect_orderassert throughrowindex:, which replaces the:rowposition:patch added in #25468.AI involvement
Collaborative – AI generated a substantial part of the code; I reviewed and understand every line.
Merge checklist