Skip to content

feat(admin): list and revoke pending invites from organization members - #1862

Open
Shreyag02 wants to merge 12 commits into
mainfrom
feat/org-details-pending-invites
Open

feat(admin): list and revoke pending invites from organization members#1862
Shreyag02 wants to merge 12 commits into
mainfrom
feat/org-details-pending-invites

Conversation

@Shreyag02

@Shreyag02 Shreyag02 commented Aug 7, 2026

Copy link
Copy Markdown
Contributor

Stacked on #1847 — merge after it. The user-details side panel, useOrganizationRoles
and connect-timestamp.ts in this diff come from there; this PR's own change is the
organization members side.

Summary

Adds a way to view and manage an organization's pending invites from the Members page.
An "N Invites" button sits next to Display in the members toolbar and opens a modal
listing every invitation sent for that org, where an invite can be revoked.

Changes

  • Members toolbar: "N Invites" trigger, shown only when the org has invites
  • "Invited members" modal listing email, role, status, invited on and expiry, with search
  • Remove action per invite, behind a confirmation dialog
  • "Invite member" button in the modal, reusing the existing invite dialog
  • useOrganizationRoles (added in feat(admin): list pending invites in user details side panel #1847) now takes an enabled option and is reused by
    organization details

Technical Details

  • Toolbar is rebuilt from DataTable.Filters + DataTable.DisplayControls rather than
    DataTable.Toolbar, which accepts no children — the design places the invites trigger to
    the left of Display. Visibility matches the rule DataTable.Toolbar applies internally.
    (DataView.Toolbar does take children, but this table is on DataTable.)
  • The table runs in mode="client". ListOrganizationInvitations takes no query
    parameters and returns every row, so there's no server-side search or pagination to hook
    into. Search is TanStack's global filter; it lands on email only, because the default
    getColumnCanGlobalFilter admits string/number cells and role ids (array) and the
    timestamp columns aren't, while the action column is opted out explicitly — its id
    accessor would otherwise make invite uuids searchable.
  • Status and expiry are derived from expires_at — the API doesn't filter lapsed
    invites, so both Pending and Expired rows come back and are labelled client-side.
    For the same reason the trigger reads "N Invites", not "N Pending": the count covers
    every row in the modal, and Status distinguishes them. Both derive isExpired at render,
    so neither ticks over on its own when an invite lapses mid-session.
  • Removal calls DeleteOrganizationInvitation and invalidates the list query, which
    refreshes both the modal table and the toolbar count. The confirmation wording differs for
    live vs expired invites.
  • Invitations are fetched on the members page rather than inside the modal, since the toolbar
    needs the count before the modal mounts. The trigger is the count, so a failed fetch
    leaves nothing to label — it stays hidden and logs, rather than carrying its own error
    surface.
  • useOrganizationRoles needs the enabled option because the org-roles half already gates
    itself on orgId but the platform-defaults half doesn't; the option keeps that fetch gated
    as organization details had it.

Not included, both blocked rather than skipped:

  • Invited by column from the design — no invitation API exposes the inviter. It's only
    recoverable by joining the organization.invited audit record, which needs a backend change.
  • Resend — resending doesn't extend expiry with the current upsert, and re-inviting an
    expired address creates a second row. Needs a product decision first.

Test Plan

  • Manual testing completed
    • Toolbar count appears with invites, hidden when there are none
    • Count matches the number of rows in the modal, expired ones included
    • Modal lists invites with correct role titles, dates and relative expiry
    • Search filters by email; a pasted invite id matches nothing; clear button resets it
    • Remove revokes the invite; list and toolbar count both update
    • Confirmation shows the expired wording for lapsed invites
    • Invite member opens the existing dialog and the new invite appears in the list
  • Build and type checking passes
    • tsc --noEmit: 0 errors in the files this PR touches; the remainder are pre-existing and
      in untouched files
    • eslint clean on the touched files apart from a pre-existing userToRemove unused-arg
      warning in members/index.tsx; pnpm build succeeds in web/sdk

SQL Safety (if your PR touches *_repository.go or goqu.*)

Not applicable — frontend only, no Go or query changes.

@vercel

vercel Bot commented Aug 7, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
frontier Ready Ready Preview Aug 10, 2026 8:45pm

@coderabbitai

coderabbitai Bot commented Aug 7, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 9ca41263-d02a-4387-a77c-558b229c7aa8

📥 Commits

Reviewing files that changed from the base of the PR and between 21d8997 and 99025f3.

📒 Files selected for processing (2)
  • web/sdk/admin/views/organizations/details/members/index.tsx
  • web/sdk/admin/views/organizations/details/members/invited-members-columns.tsx
🚧 Files skipped from review as they are similar to previous changes (2)
  • web/sdk/admin/views/organizations/details/members/index.tsx
  • web/sdk/admin/views/organizations/details/members/invited-members-columns.tsx

📝 Walkthrough

Summary by CodeRabbit

  • New Features

    • Added organization invitation management with searchable, sortable invitation listings.
    • Added invitation details including email, assigned roles, status, invitation date, and expiry information.
    • Added options to invite users and remove pending or expired invitations with confirmation and feedback.
    • Added invitation details to the user side panel alongside organization memberships.
    • Improved organization role loading and display across organization and user views.
  • Bug Fixes

    • Improved invitation expiry formatting and status presentation, including handling missing expiration dates.
    • Added clearer loading, empty, error, and success feedback throughout invitation management.

Walkthrough

The change centralizes organization-role loading and adds invitation retrieval, display, expiry formatting, and removal flows for organization members and user detail panels.

Changes

Organization invitation flows

Layer / File(s) Summary
Shared organization-role loading
web/sdk/admin/hooks/useOrganizationRoles.ts, web/sdk/admin/views/organizations/details/index.tsx, web/sdk/admin/views/users/details/layout/membership-dropdown.tsx
Added shared loading for default and organization-specific roles. Updated organization and membership views to use the hook.
Invitation expiry formatting
web/sdk/admin/utils/connect-timestamp.ts
Added relative expiry formatting and expired-state detection for invitations.
Organization invitation management
web/sdk/admin/views/organizations/details/members/*
Added organization-scoped invitation queries, invitation counts, searchable and sortable invitation tables, invitation dialogs, removal handling, and related styles.
User invitation details
web/sdk/admin/views/users/details/layout/side-panel.tsx, web/sdk/admin/views/users/details/layout/side-panel-invitation.tsx, web/sdk/admin/views/users/details/layout/side-panel-details.tsx, web/sdk/admin/views/users/details/layout/side-panel-membership.tsx, web/sdk/admin/views/users/details/layout/side-panel.module.css
Added invitation sections to the user side panel and updated list-header styling.

Estimated code review effort: 4 (Complex) | ~45 minutes

Possibly related PRs

Suggested reviewers: rohanchkrabrty, paansinghcoder

🚥 Pre-merge checks | ✅ 2
✅ Passed checks (2 passed)
Check name Status Explanation
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai 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.

Actionable comments posted: 2


ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: c5ddb944-9e6a-49ab-b1dc-2266b50a17c5

📥 Commits

Reviewing files that changed from the base of the PR and between c294c5f and 91a64ee.

📒 Files selected for processing (11)
  • web/sdk/admin/hooks/useOrganizationRoles.ts
  • web/sdk/admin/utils/connect-timestamp.ts
  • web/sdk/admin/views/organizations/details/index.tsx
  • web/sdk/admin/views/organizations/details/members/index.tsx
  • web/sdk/admin/views/organizations/details/members/invited-members-columns.tsx
  • web/sdk/admin/views/organizations/details/members/invited-members-dialog.tsx
  • web/sdk/admin/views/organizations/details/members/members.module.css
  • web/sdk/admin/views/organizations/details/members/remove-invite-dialog.tsx
  • web/sdk/admin/views/users/details/layout/membership-dropdown.tsx
  • web/sdk/admin/views/users/details/layout/side-panel-invitation.tsx
  • web/sdk/admin/views/users/details/layout/side-panel.tsx

Comment thread web/sdk/admin/views/organizations/details/members/index.tsx
@coveralls

coveralls commented Aug 7, 2026

Copy link
Copy Markdown

Coverage Report for CI Build 31430567552

Coverage remained the same at 48.097%

Details

  • Coverage remained the same as the base build.
  • Patch coverage: No coverable lines changed in this PR.
  • No coverage regressions found.

Uncovered Changes

No uncovered changes found.

Coverage Regressions

No coverage regressions found.


Coverage Stats

Coverage Status
Relevant Lines: 39919
Covered Lines: 19200
Line Coverage: 48.1%
Coverage Strength: 15.37 hits per line

💛 - Coveralls

@Shreyag02 Shreyag02 changed the title org details pending invites feat(admin): list and revoke pending invites from organization members Aug 10, 2026
…h to email

- the list API returns lapsed invites, so "N Pending invite" overstated the
  count; the trigger now reads "N Invites" and Status labels each row
- log a failed invitations fetch instead of silently hiding the trigger
- exclude the action column from the client global filter, which otherwise
  matched invite ids
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.

2 participants