feat(admin): list pending invites in user details side panel - #1847
feat(admin): list pending invites in user details side panel#1847Shreyag02 wants to merge 1 commit into
Conversation
panel and extract org role fetching into useOrganizationRoles
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
📝 WalkthroughSummary by CodeRabbit
WalkthroughThis PR introduces a ChangesOrganization roles hook and invitation panel
Estimated code review effort: 3 (Moderate) | ~25 minutes Possibly related PRs
Suggested reviewers: 🚥 Pre-merge checks | ✅ 2✅ Passed checks (2 passed)
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. Comment |
There was a problem hiding this comment.
Actionable comments posted: 1
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro Plus
Run ID: 49158fa7-268d-4f6e-adf1-52556c80c8a0
📒 Files selected for processing (4)
web/sdk/admin/hooks/useOrganizationRoles.tsweb/sdk/admin/views/users/details/layout/membership-dropdown.tsxweb/sdk/admin/views/users/details/layout/side-panel-invitation.tsxweb/sdk/admin/views/users/details/layout/side-panel.tsx
Summary
The user details side panel now lists the organizations a user has been invited to but hasn't joined yet, sitting below their existing memberships. Data comes from
FrontierService/ListUserInvitations.Changes
Invitationssection in the user details side panel — one block per invite, showing the org, the role offered, invite status (Pending/Expired), and a relative expiry ("5 days left", flipping to "5 days ago" once lapsed).useOrganizationRoleshook (admin/hooks/) that fetches the platform's default org roles plus the org's custom roles, returning both aroleslist and an id → title map.membership-dropdown.tsxnow uses that hook (−40 lines). It previously had its own copy of the same two queries, so both places resolve role titles identically from here on.Technical Details
ListUserInvitationsis keyed by the invitee's email, not the user uuid — an invitation can exist before the user does. Worth knowing because passing the uuid returns200with an empty list rather than an error, so getting it wrong fails silently. The query usesuser?.emailand is gated on it.expires_atfilter; rows live until the cleanup cron sweeps them. SoPending/Expiredis derived client-side.formatExpirydiffs forwards on either side of "now" and swaps only the suffix, so live and lapsed invites always read consistently.org_idandrole_ids, so the org title/avatar comes from the existinguseOrganizationLookupand role titles from the new hook. react-query caches both per key, so multiple invite blocks share one fetch.useEffectinside the hook. The dropdown previously logged them from the render body, which repeated on every render.Test Plan
Verified so far:
tsc --noEmiterror set is byte-identical before and after the change (21 pre-existing errors, all in untouched files; 0 introduced) — confirmed by stashing the branch and re-running againstmain.eslintclean on all four touched files;pnpm buildsucceeds inweb/sdk.Expiry formatting checked against the real payload (
expires_at``2026-08-11T10:00:21Z) and across the boundaries:6 days left1 day left(singular)3 hours leftLess than an hour left/ago5 days agoSQL Safety (if your PR touches
*_repository.goorgoqu.*)Not applicable — frontend only, no Go or query-builder changes.