Skip to content

org details pending invites - #1862

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

org details pending invites#1862
Shreyag02 wants to merge 8 commits into
mainfrom
feat/org-details-pending-invites

Conversation

@Shreyag02

Copy link
Copy Markdown
Contributor

Summary

Changes

Technical Details

Test Plan

  • Manual testing completed
  • Build and type checking passes

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

  • Values flow through ? placeholders, goqu.Ex{}, or goqu.Record{} — never fmt.Sprintf or + building a query that gets executed.
  • ToSQL() callers capture and forward params (query, params, err := stmt.ToSQL(); db.…Context(ctx, …, query, params...)). Never query, _, err := ….
  • No ? placeholders inside single-quoted SQL literals in goqu.L (use make_interval(hours => ?)-style functions instead).
  • Any //nolint:forbidigo or // #nosec G20x annotation has a one-line justification on the same line that a reviewer can verify.

@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 7, 2026 12:02pm

@coderabbitai

coderabbitai Bot commented Aug 7, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

📝 Walkthrough

Summary by CodeRabbit

  • New Features

    • Added organization invitation management with searchable, sortable pending-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.

Walkthrough

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 invite-specific relative expiry formatting and expired-state detection.
Organization invitation management
web/sdk/admin/views/organizations/details/members/*
Added invitation queries, pending 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
Added invitation retrieval and invitation detail sections to the user side panel.

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

Possibly related PRs

Suggested reviewers: 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 on lines +121 to +134
// Not in the dialog: the toolbar needs the count before it mounts.
const {
data: invitations = NO_INVITATIONS,
isLoading: isInvitationsLoading,
} = useQuery(
FrontierServiceQueries.listOrganizationInvitations,
create(ListOrganizationInvitationsRequestSchema, {
orgId: organizationId,
}),
{
enabled: !!organizationId,
select: data => data?.invitations || NO_INVITATIONS,
},
);

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.

🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Do not render an invitation-query failure as an empty list.

When this query fails, invitations becomes NO_INVITATIONS. showInvitesBtn then hides the only pending-invites entry point. Render an error and retry state, and do not report that no invitations exist until the query succeeds.

>;
}

const seconds = (timestamp?: TimeStamp) => Number(timestamp?.seconds ?? 0);

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.

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

sed -n '1,140p' web/sdk/admin/utils/connect-timestamp.ts
rg -n -C 3 'type TimeStamp|interface TimeStamp|nanos|Timestamp' \
  web/sdk/admin/utils/connect-timestamp.ts \
  web/sdk/admin/views/organizations/details/members/invited-members-columns.tsx

Repository: raystack/frontier

Length of output: 7980


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Inspect the sortable columns and any nearby helper usages without executing repo code.
sed -n '1,95p' web/sdk/admin/views/organizations/details/members/invited-members-columns.tsx

# Programmatically check the exact helper shape and comparator expressions from the file as text.
python3 - <<'PY'
from pathlib import Path
p = Path('web/sdk/admin/views/organizations/details/members/invited-members-columns.tsx')
text = p.read_text()
print('seconds_function:', 'const seconds = (timestamp?: TimeStamp) => Number(timestamp?.seconds ?? 0);' in text)
print('invites_import_statement_count:', text.count('createTableAccessor'))
for field in ['createdAt', 'expiresAt']:
    needle = f'sortingFn: (a, b) =>\n        seconds(a.original.{field}) - seconds(b.original.{field})'
    print(f'sortingFn_{field}:', f'"{field}" sorting uses seconds()' in needle)
# Find any nanoseconds references in the target file to establish whether nanos are already considered.
import re
print('nanos_mentions_in_target:', len(re.findall(r'\bnano[s]?\b', text, re.I)))
PY

Repository: raystack/frontier

Length of output: 3203


🌐 Web query:

@bufbuild/protobuf Timestamp seconds nanos type

💡 Result:

In the @bufbuild/protobuf library (and the underlying Protocol Buffers standard), the google.protobuf.Timestamp message type is defined by two fields that work together to represent a point in time with nanosecond precision [1][2][3]: 1. seconds (int64): Represents the number of seconds of UTC time since the Unix epoch (1970-01-01T00:00:00Z) [2][3]. It must be between -62,135,596,800 and 253,402,300,799 (inclusive), corresponding to dates from 0001-01-01 to 9999-12-31 [2][3][4]. 2. nanos (int32): Represents non-negative fractions of a second in nanosecond resolution [2][3]. This value must be between 0 and 999,999,999 inclusive [2][3][4]. Even when representing negative time (seconds before the epoch), the nanos field must remain non-negative, as it acts as a forward-counting fraction of the specified second [2][3]. Technical usage notes: - Implementation: In @bufbuild/protobuf, Timestamp is considered a "well-known type" [1]. Because this type is standardized, its JSON representation is a string formatted according to RFC 3339 (e.g., "2026-08-07T12:00:00Z") [3][4]. - Library Access: In recent versions of @bufbuild/protobuf (v2.0+), you can access Timestamp-related utilities by importing from @bufbuild/protobuf/wkt (Well-Known Types) rather than the main package entry point [1][5]. - Conversion: The library provides helper functions such as timestampNow, timestampFromDate, timestampFromMs, and their counterparts (timestampDate, timestampMs) to facilitate conversion between Timestamp objects and native JavaScript/TypeScript Date objects [1].

Citations:


Preserve nanosecond precision when sorting createdAt and expiresAt.

seconds() maps any timestamps in the same second to the same value, so the sortable columns can treat distinct invitations as equal. Compare seconds first and nanos second for createdAt and expiresAt.

@coveralls

Copy link
Copy Markdown

Coverage Report for CI Build 31176527885

Coverage remained the same at 47.99%

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: 39850
Covered Lines: 19124
Line Coverage: 47.99%
Coverage Strength: 15.37 hits per line

💛 - Coveralls

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