Skip to content

feat(organization): sort, filter and page the org roles table - #1837

Draft
dawsontoth wants to merge 1 commit into
claude/1268-instance-users-tablefrom
claude/1269-org-roles-table
Draft

dawsontoth wants to merge 1 commit into
claude/1268-instance-users-tablefrom
claude/1269-org-roles-table

Conversation

@dawsontoth

@dawsontoth dawsontoth commented Oct 11, 2026 •

Copy link
Copy Markdown
Contributor

⊙ Problem

The organization Roles table can't be sorted (every column sets enableSorting: false), filtered, or paged. #1269 asks for pagination, sorting by different attributes of a role, and filtering "by name, or by something within the role itself".

❓ Your call: is it warranted now? The issue itself doubts long role lists in v1. It is cheap once #1832 exists (a column-definition change plus two props), so it ships with the rest of the stack; dropping it is reverting this one PR.

💡 Solution

Stacked on #1835 and #1832, which add the shared opt-in filter / paginated props to SimpleBrowseDataTable; this PR turns both on for org roles.

  • Every column is sortable: Role Name, ID, and Users Assigned, which becomes an accessor column on the role's userIds count so it sorts numerically. A role nobody holds still reads "No users assigned"; assignedUserCount is shared by the accessor and the cell.
  • The search matches the role name only. ID and the user count are kept out of it (both), since an opaque id or a small number matches many short queries. The placeholder says so: "Filter by role name".

❓ Your call: "filter by something within the role itself" is not done. The obvious candidates are the members' emails (the roles payload carries users) or the role's permissions; each is a product decision about what the box should mean, and a member-email match would make the Roles search behave like the Users page's. Leaving this open is why this PR says Refs #1269, not Closes. If name-only filtering is enough, close the issue on merge.

❓ Your call: the count is userIds.length, as the column showed before, so a dangling id whose user record no longer resolves (orgRoleMembers.ts documents that shape) still counts as assigned, and now also sorts that way (codex flagged it). Counting resolved users instead is a one-line change but would read 0 for any payload that omits users.

✅ Verification

End-to-end route: component integration in jsdom through the real SimpleBrowseDataTable, TanStack row models and these column definitions. Not browser-verified, since the authenticated dev origin was shared with other sessions; no Playwright spec covers this page.

  • src/features/organization/roles/constants/tableDefinition.test.tsx: filters by role name, not by id or user count; sorts by users assigned and shows "No users assigned" for an unheld role; sorts by role name case-insensitively.
  • Mutation check: re-enabling the ID and Users Assigned columns in the search turns the filter test red (then reverted).
  • Gates: full vitest via the pre-commit hook, 398 files, 3678 passed, 11 skipped; tsc -b exit 0; oxlint exit 0; dprint check exit 0; commitlint passed.
  • Cross-model review: one full round, codex (graded) + gemini, base claude/1268-instance-users-table. Codex raised the two calls above. Gemini's nit (read the cell from props.getValue() instead of recounting) was not taken: getValue() is untyped here and needs a cast to save one array-length read. Cursor could not fetch through the 1Password SSH agent and the Harper domain adjudicator failed on an expired Claude OAuth session, so the round was not adjudicated.

Merge after #1835 (and #1832 before it). Its base is claude/1268-instance-users-table, so GitHub retargets it as the stack below merges.

Refs #1269

🤖 Generated with Claude Code; posted via @dawsontoth.

Related PRs: #1832 independent (stacked base: the shared table capability), #1835 independent (stacked base directly below this one)
Complexity: easy

Review-Coverage: authored=claude; ran=gemini,codex; blocked=cursor-composer(no-receipt),domain(auth); declined=cursor-grok,cursor-kimi,cursor-muse; rounds=1; full=1 @ 57ee5a6

Review-Attention: read ~3m (raised: degraded review) @ 57ee5a6

Opts the organization Roles table into SimpleBrowseDataTable's `filter`
and `paginated` props and makes every column sortable. ID and Users
Assigned become accessor columns so they can be sorted (by id, and by
how many users hold the role); the filter matches the role name only,
since the opaque ids and the user counts would match many short queries.

Refs #1269

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

@gemini-code-assist gemini-code-assist 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.

Code Review

This pull request enables sorting and filtering capabilities for the organization roles table. Specifically, it refactors the table column definitions to support sorting on 'Role Name', 'ID', and 'Users Assigned' columns, while disabling global filtering on the latter two. It also updates the table component integration to include pagination and filtering configurations, and introduces a comprehensive test suite to verify these sorting and filtering behaviors. I have no additional feedback to provide as the changes are well-implemented and covered by tests.

@dawsontoth
dawsontoth added this pull request to stack #1913 October 11, 2026 22:28
@github-actions

Copy link
Copy Markdown

Coverage Report

Status Category Percentage Covered / Total
🔵 Lines 67.63% 10123 / 14967
🔵 Statements 67.8% 10806 / 15938
🔵 Functions 61.09% 2618 / 4285
🔵 Branches 62.62% 7703 / 12301
File Coverage
File Stmts Branches Functions Lines Uncovered Lines
Changed Files
src/features/organization/roles/index.tsx 0% 0% 0% 0% 20-121
src/features/organization/roles/constants/tableDefinition.tsx 100% 75% 100% 100%
Generated in workflow #2142 for commit 57ee5a6 by the Vitest Coverage Report Action

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