MembersFilterBar, MembersTable, PendingInvitesTable and InviteMemberDialog from packages/ui, against a 30-person roster with real search, filtering, sorting and paging, permission-shaped rows, and switchable failure.
Roster
An Admin actor: two Owners above their reach, one disabled member, mixed 2FA, their own row unmanageable, and three profile pictures plus one that 404s back to initials. 30 rows at 25 per page, so page 2 is a real 5-row remainder.
30 members, Admin actor
Member
Role
2FA
Status
Last active
Actions
AH
Ada Hopper (you)ada.hopper@acme.co
On
Active
AH
Ada Hopperada.hopper@acme.co
On
Active
AH
Ada Hopperada.hopper@acme.co
On
Active
AL
Alan Liskovalan.liskov@acme.co
On
Active
AL
Alan Liskovalan.liskov@acme.co
On
Active
AL
Alan Liskovalan.liskov@acme.co
On
Active
BT
Barbara Turingbarbara.turing@acme.co2FA unknown
Active
BT
Barbara Turingbarbara.turing@acme.co2FA off
Off
Active
BT
Barbara Turingbarbara.turing@acme.co2FA off
Off
Active
CP
Claude Perlmanclaude.perlman@acme.co
On
Active
CP
Claude Perlmanclaude.perlman@acme.co
On
Active
CP
Claude Perlmanclaude.perlman@acme.co
On
Active
DH
Donald Hamiltondonald.hamilton@acme.co
On
Active
DH
Donald Hamiltondonald.hamilton@acme.co
On
Active
DH
Donald Hamiltondonald.hamilton@acme.co
On
Active
EJ
Edsger Johnsonedsger.johnson@acme.co
On
Active
Never
EJ
Edsger Johnsonedsger.johnson@acme.co
On
Active
EJ
Edsger Johnsonedsger.johnson@acme.co
On
Active
GD
Grace Dijkstragrace.dijkstra@acme.co2FA off
Off
Active
GD
Grace Dijkstragrace.dijkstra@acme.co2FA off
Off
Active
GD
Grace Dijkstragrace.dijkstra@acme.co2FA off
Off
Active
KL
Katherine Lovelacekatherine.lovelace@acme.co2FA off
Off
Active
KL
Katherine Lovelacekatherine.lovelace@acme.co2FA off
Off
Active
KL
Katherine Lovelacekatherine.lovelace@acme.co2FA off
Off
Active
MS
Margaret Shannonmargaret.shannon@acme.co· Disabled2FA off
Off
Disabled
1–25 of 30Page 1 of 2
Search matches name and email; "2FA off" is the filter an access review actually asks for. Filtering resets to page 1 and the count reads "of N matching"; sorting reorders the same set and leaves the count alone.
Empty states
Three different facts, told apart rather than collapsed into one line. Only the no-matches one has a way out of itself.
No matches
Member
Role
2FA
Status
Last active
Actions
No members match these filters.
No members match these filters.
A filter that matched nothing — distinct from an empty workspace, and offering the way back.
No members yet
Member
Role
2FA
Status
Last active
Actions
No members yet.
No members yet.
Nothing is filtered, so there is nothing to clear — the table says so and stops.
Page past the end
Member
Role
2FA
Status
Last active
Actions
No members on this page.
No members on this page.Page 4 of 2
A bookmarked ?page=4 against a roster that has since shrunk. The pager stays, so Previous is reachable.
Permission shapes
The actions column is driven entirely by each row's own assignableRoles / canRemove — a viewer without team/role:w or team/remove:w never receives a row that allows either.
Read-only viewer
Member
Role
2FA
Status
Last active
Actions
AH
Ada Hopper (you)ada.hopper@acme.co
On
Active
GD
Grace Dijkstragrace.dijkstra@acme.co2FA off
Off
Active
AL
Alan Liskovalan.liskov@acme.co
On
Active
KL
Katherine Lovelacekatherine.lovelace@acme.co2FA off
Off
Active
EJ
Edsger Johnsonedsger.johnson@acme.co
On
Active
Never
MS
Margaret Shannonmargaret.shannon@acme.co· Disabled2FA off
Off
Disabled
CP
Claude Perlmanclaude.perlman@acme.co
On
Active
BT
Barbara Turingbarbara.turing@acme.co2FA unknown
Active
1–8 of 8
team:r only — no row has an assignable role or canRemove, so no row renders a menu.
Single member (just you)
Member
Role
2FA
Status
Last active
Actions
AH
Ada Hopper (you)ada.hopper@acme.co
On
Active
1–1 of 1
You can't reassign or remove yourself, so the actions column is empty even though you're an Admin.
Pending invites
No pending invites
PendingInvitesTable renders null — no heading, no empty-state row.
Three pending invites
Email
Role
Expires
Invited by
Actions
sam.rivera@acme.coMember·Expired
Expired
ada.hopper@acme.co
priya.desai@acme.coAdmin·Expired
Expired
ada.hopper@acme.co
morgan.lee@acme.coOwner·Expired
Expired
grace.dijkstra@acme.co
The invite to Owner is above the Admin actor's reach, so it has no Revoke action.
Invite a member
InviteMemberDialog
Try "taken@acme.co" — the fixture rejects it with "That user is already a member."
Failure state
Role change always fails
Member
Role
2FA
Status
Last active
Actions
AH
Ada Hopper (you)ada.hopper@acme.co
On
Active
CP
Claude Perlmanclaude.perlman@acme.co
On
Active
1–2 of 2
Row menu → Change role → Change role — every attempt fails with "Something went wrong — try again."
320px width
MembersTable in a 320px column
Member
Role
2FA
Status
Last active
Actions
AH
Ada Hopper (you)ada.hopper@acme.co
On
Active
GD
Grace Dijkstragrace.dijkstra@acme.co2FA off
Off
Active
AL
Alan Liskovalan.liskov@acme.co
On
Active
KL
Katherine Lovelacekatherine.lovelace@acme.co2FA off
Off
Active
EJ
Edsger Johnsonedsger.johnson@acme.co
On
Active
Never
1–5 of 5
Last active drops first, then 2FA, then role and status. Nothing is lost on the way down: role and status fold into the member's line, and a member without 2FA keeps an explicit "2FA off" there — only the safe default goes unsaid. The actions menu never scrolls off.
Filter bar and table in a 320px column
Member
Role
2FA
Status
Last active
Actions
AH
Ada Hopper (you)ada.hopper@acme.co
On
Active
AH
Ada Hopperada.hopper@acme.co
On
Active
AH
Ada Hopperada.hopper@acme.co
On
Active
AL
Alan Liskovalan.liskov@acme.co
On
Active
AL
Alan Liskovalan.liskov@acme.co
On
Active
1–5 of 30Page 1 of 6
The bar wraps rather than scrolling: the search field takes the first line on its own and the two selects and the direction toggle fall to the second. Filter it down to nothing to see the no-matches state at this width.
No matches in a 320px column
Member
Role
2FA
Status
Last active
Actions
No members match these filters.
No members match these filters.
The message wraps and the Clear filters button stays inside the column.