Skip to content

fix(sdk): polish views-new empty states, menus and add member flow#1626

Open
rohanchkrabrty wants to merge 4 commits into
mainfrom
fix-frontier-bugs
Open

fix(sdk): polish views-new empty states, menus and add member flow#1626
rohanchkrabrty wants to merge 4 commits into
mainfrom
fix-frontier-bugs

Conversation

@rohanchkrabrty
Copy link
Copy Markdown
Contributor

Summary

  • Standardized row action menus in views-new to use DotsHorizontalIcon + IconButton size={2}, visible only on row hover.
  • Reworked top-level empty states (projects, teams, plans, service accounts, pat, billing, subscribe) to the empty2 design with SVG icons and accent CTA; CTA is omitted (not just disabled) when the user lacks permission.
  • Added top-level "no teams yet" empty state to teams-view, mirroring projects-view, and a my/all filter Select in projects-view with isFetched-based initial-skeleton handling.
  • Added an "Add a member" submenu to the projects row action menu by extracting AddMemberMenuContent and rendering it as a Menu.Submenu (no handle indirection).
  • Dropped privacy column and the privacy field in the edit-project dialog (no longer supported by the backend); painted destructive menu items danger-colored with the right SVG icons.

@vercel
Copy link
Copy Markdown

vercel Bot commented May 19, 2026

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

Project Deployment Actions Updated (UTC)
frontier Ready Ready Preview, Comment May 19, 2026 10:59am

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 19, 2026

Review Change Stack

📝 Walkthrough

Summary by CodeRabbit

  • New Features

    • Added organization-level project visibility toggle between "My Projects" and "All Projects" view.
    • Added "Add a member" submenu option to the projects dropdown menu.
  • Bug Fixes

    • Improved initial loading state handling with skeleton displays during data fetches.
    • Enhanced table action button visibility with hover-reveal behavior.
  • Improvements

    • Updated UI icons and empty state visuals for consistency.
    • Removed privacy settings from project editor dialog.
    • Standardized table cell padding across views.

Walkthrough

This PR enhances organization management UI with better load state tracking, org-level project filtering, simplified project editing, and consistent table action styling across teams and projects views.

Changes

Hook Infrastructure for Load State Tracking

Layer / File(s) Summary
useOrganizationProjects isFetched support
web/sdk/react/hooks/useOrganizationProjects.ts
Return type updated to include isFetched; both organization and user project queries destructure and OR their isFetched flags to indicate when any relevant data has been fetched.
useOrganizationTeams isFetched support
web/sdk/react/hooks/useOrganizationTeams.ts
Return type updated to include isFetched; both organization and user team queries destructure and OR their isFetched flags for load state tracking.

Projects Feature Expansion

Layer / File(s) Summary
Project dialog privacy removal
web/sdk/react/views-new/projects/components/edit-project-dialog.tsx, edit-project-dialog.module.css
Edit project form simplified: privacy field removed from Yup schema, form state no longer tracks privacy, and privacy radio-group UI removed from dialog body; form now manages only title.
AddMemberMenuContent extraction
web/sdk/react/views-new/projects/components/add-member-menu.tsx
New exported component AddMemberMenuContent encapsulates menu body logic for selecting users or teams; supports both regular and submenu rendering with conditional alignment and search text.
Projects view filtering and member menu
web/sdk/react/views-new/projects/projects-view.tsx, projects-view.module.css
ProjectsView introduces org-level project visibility toggle via showOrgProjects state and filter Select; improved empty state with inbox icon and conditional create button; row actions dropdown extended with member-add submenu when user has update permission; uses isFetched to control initial skeleton display.
Project columns actions and styling
web/sdk/react/views-new/projects/components/project-columns.tsx, project-columns.module.css
Horizontal dots icon replaces vertical in actions menu; new CSS module implements action cell hover-reveal; privacy column removed entirely.
Project details table styling
web/sdk/react/views-new/projects/project-details-view.tsx, project-details-view.module.css
DataTable row styling enhanced with consistent cell padding via CSS variable.

Teams View Load State and Polish

Layer / File(s) Summary
Teams view initial skeleton and empty state
web/sdk/react/views-new/teams/teams-view.tsx
TeamsView consumes isFetched from hook to distinguish initial loading phase from subsequent refreshes; showInitialSkeleton controls skeleton vs interactive toolbar display; early-return empty state with conditional create action based on GroupCreate permission; controlled filter Select with disable logic tied to loading state.
Team columns actions and styling
web/sdk/react/views-new/teams/components/team-columns.tsx, member-columns.tsx, team-columns.module.css, member-columns.module.css
All team/member table columns updated to use horizontal dots icon and smaller button size; CSS modules added for action cell hover-reveal styling across both table types; layout gap adjusted in name cell.
Team details table and member actions
web/sdk/react/views-new/teams/team-details-view.tsx, team-details-view.module.css
DataTable styling enhanced with root and row CSS classes for consistent layout; user-minus SVG icon replaces delete icon in member remove action; cell padding rule added to CSS module.

Icon Standardization and Table UX Polish

Layer / File(s) Summary
Empty state icon standardization via SVG assets
web/sdk/react/views-new/billing/billing-view.tsx, web/sdk/react/views-new/pat/pat-view.tsx, web/sdk/react/views-new/service-accounts/service-accounts-view.tsx
Billing, PAT, and service-accounts views updated to render empty-state icons using local SVG assets via Image component instead of Radix icons; button styling updated for action CTAs.
Members table icon and styling updates
web/sdk/react/views-new/members/components/member-columns.tsx, web/sdk/react/views-new/members/members-view.tsx, member-columns.tsx, members-view.module.css
Members table updated to use horizontal dots icon for actions; CSS module added for action cell hover-reveal; delete action rendered via SVG Image with danger color; table row styling with consistent cell padding.
Service accounts actions icon update
web/sdk/react/views-new/service-accounts/components/service-account-columns.tsx
Service account table columns updated to use horizontal dots icon with adjusted button sizing.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related PRs

  • raystack/frontier#1607: Both PRs modify edit-project-dialog.tsx to change project submission logic—main PR removes privacy form field while retrieved PR fixes update request to preserve existing project name.
  • raystack/frontier#1566: Both PRs refactor ProjectsView—main PR introduces org-level filtering and improved empty state while retrieved PR also modifies projects page permission gating and CTA rendering.
  • raystack/frontier#1510: Both PRs enhance TeamsView using isFetched for load state control—main PR exposes isFetched in hook and uses it for skeleton logic while retrieved PR revamps teams view with similar initialization patterns.

Suggested reviewers

  • rsbh
  • paanSinghCoder
  • rohilsurana
🚥 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.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.


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 and usage tips.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 6

🧹 Nitpick comments (1)
web/sdk/react/views-new/plans/plans-view.tsx (1)

153-158: ⚡ Quick win

Inconsistent icon migration compared to other empty states.

This EmptyState updates to variant="empty2" but still uses the Radix ExclamationTriangleIcon component, while other views (billing, PAT, service-accounts) migrated to local SVG assets via the Image component. Per the PR objectives, the standardization effort aims to systematically replace Radix icons with local SVG assets in empty states. The exclamation-triangle.svg asset is already available and used in billing-view, so this can be a quick migration to align with the pattern.


ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: e46f3d90-cdec-4c38-b3f8-b6781089121e

📥 Commits

Reviewing files that changed from the base of the PR and between adb9deb and b9e8edc.

⛔ Files ignored due to path filters (2)
  • web/sdk/react/assets/inbox-stack.svg is excluded by !**/*.svg
  • web/sdk/react/assets/user-minus.svg is excluded by !**/*.svg
📒 Files selected for processing (28)
  • web/sdk/react/hooks/useOrganizationProjects.ts
  • web/sdk/react/hooks/useOrganizationTeams.ts
  • web/sdk/react/views-new/billing/billing-view.tsx
  • web/sdk/react/views-new/members/components/member-columns.tsx
  • web/sdk/react/views-new/members/members-view.module.css
  • web/sdk/react/views-new/members/members-view.tsx
  • web/sdk/react/views-new/pat/pat-view.tsx
  • web/sdk/react/views-new/plans/plans-view.tsx
  • web/sdk/react/views-new/projects/components/add-member-menu.tsx
  • web/sdk/react/views-new/projects/components/edit-project-dialog.module.css
  • web/sdk/react/views-new/projects/components/edit-project-dialog.tsx
  • web/sdk/react/views-new/projects/components/member-columns.module.css
  • web/sdk/react/views-new/projects/components/member-columns.tsx
  • web/sdk/react/views-new/projects/components/project-columns.module.css
  • web/sdk/react/views-new/projects/components/project-columns.tsx
  • web/sdk/react/views-new/projects/project-details-view.module.css
  • web/sdk/react/views-new/projects/project-details-view.tsx
  • web/sdk/react/views-new/projects/projects-view.module.css
  • web/sdk/react/views-new/projects/projects-view.tsx
  • web/sdk/react/views-new/service-accounts/components/service-account-columns.tsx
  • web/sdk/react/views-new/service-accounts/service-accounts-view.tsx
  • web/sdk/react/views-new/teams/components/member-columns.module.css
  • web/sdk/react/views-new/teams/components/member-columns.tsx
  • web/sdk/react/views-new/teams/components/team-columns.module.css
  • web/sdk/react/views-new/teams/components/team-columns.tsx
  • web/sdk/react/views-new/teams/team-details-view.module.css
  • web/sdk/react/views-new/teams/team-details-view.tsx
  • web/sdk/react/views-new/teams/teams-view.tsx
💤 Files with no reviewable changes (1)
  • web/sdk/react/views-new/projects/components/edit-project-dialog.module.css

variant="empty2"
icon={
<Image
src={exclamationTriangleIcon as unknown as string}
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.

🛠️ Refactor suggestion | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Check the type definition of Image src prop and SVG import handling
rg -n "src\s*:\s*" --type=ts -A2 -g '*apsara*' -g '*Image*' | head -20

# Check bundler configuration for SVG handling
fd -e json -e js -e ts 'vite.config|webpack.config|next.config' --exec cat {}

Repository: raystack/frontier

Length of output: 3435


🏁 Script executed:

# Find the Image component definition from apsara-v1 in the project
rg -n "interface\s+Image|type\s+Image|function\s+Image" --type=ts --type=tsx | grep -i "src\|prop" | head -20

# Check the actual billing-view file to understand the imports
cat -n web/sdk/react/views-new/billing/billing-view.tsx | head -30

# Search for other similar double type casts in the codebase
rg "as unknown as string" --type=ts --type=tsx -n | head -30

# Check if there are type definitions or other Image usages
rg -n "from.*apsara.*Image" --type=ts --type=tsx | head -20

Repository: raystack/frontier

Length of output: 1695


🏁 Script executed:

# Check TypeScript configuration for SVG handling
find . -name "tsconfig*.json" -type f | head -5 | xargs cat

# Search for other Image component usages to see patterns
rg "Image" --type ts -A2 -B2 | grep -A3 "src=" | head -40

# Check other SVG imports and how they're used
rg "from.*\.svg" --type ts -B2 -A2 | head -50

# Look for similar double type casts elsewhere
rg "as unknown as" --type ts -B2 -A2 | head -40

Repository: raystack/frontier

Length of output: 12410


Add TypeScript type declarations for SVG imports to eliminate the double type cast.

The pattern as unknown as string appears in 10+ files across the codebase and indicates a type mismatch between SVG imports and the Image component's src prop. Add a module declaration (e.g., src/vite-env.d.ts) to properly type SVG imports:

declare module '*.svg' {
  const content: string;
  export default content;
}

This eliminates the need for the workaround cast throughout the codebase and provides type safety.

Comment on lines +1 to +7
.actionsCell {
visibility: hidden;
}

tr:hover .actionsCell {
visibility: visible;
}
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.

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Add keyboard accessibility support for hidden action cells.

The current CSS only reveals .actionsCell on :hover, which prevents keyboard-only users from accessing row action buttons. Elements with visibility: hidden are removed from the accessibility tree and cannot receive focus, so users navigating with Tab will not be able to access these actions.

Add :focus-within to ensure the actions are revealed when any element inside the row receives keyboard focus.

♿ Proposed fix to restore keyboard navigation
 .actionsCell {
   visibility: hidden;
 }
 
-tr:hover .actionsCell {
+tr:hover .actionsCell,
+tr:focus-within .actionsCell {
   visibility: visible;
 }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
.actionsCell {
visibility: hidden;
}
tr:hover .actionsCell {
visibility: visible;
}
.actionsCell {
visibility: hidden;
}
tr:hover .actionsCell,
tr:focus-within .actionsCell {
visibility: visible;
}

Comment on lines +1 to +7
.actionsCell {
visibility: hidden;
}

tr:hover .actionsCell {
visibility: visible;
}
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.

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Hover-only action visibility blocks non-mouse users.

Row actions are hidden unless hovered, so keyboard and touch users may not be able to discover/operate them reliably.

Suggested fix
 .actionsCell {
   visibility: hidden;
 }

-tr:hover .actionsCell {
+tr:hover .actionsCell,
+tr:focus-within .actionsCell {
   visibility: visible;
 }
+
+@media (hover: none) {
+  .actionsCell {
+    visibility: visible;
+  }
+}

Comment on lines +131 to 132
const hasNoProjects = !isLoading && (projects?.length ?? 0) === 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.

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Top-level empty-state guard blocks the org filter path.

When showOrgProjects is false and “My Projects” is empty, the early return fires before the filter renders. Users who can list org projects can get stuck on the top-level empty state and cannot switch to “All Projects”.

Suggested fix
-  const hasNoProjects = !isLoading && (projects?.length ?? 0) === 0;
+  const hasNoProjects =
+    !isLoading &&
+    (projects?.length ?? 0) === 0 &&
+    (!canListOrgProjects || showOrgProjects);

Also applies to: 142-177

Comment on lines +293 to +297
<AddMemberMenuContent
projectId={payload.projectId}
canUpdateProject={payload.canUpdate}
members={[]}
refetch={refetch}
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.

⚠️ Potential issue | 🟠 Major | 🏗️ Heavy lift

members={[]} makes existing project users appear as addable.

This bypasses the duplicate filter in AddMemberMenuContent, so existing members are shown in “Add a member”. That causes redundant writes and can potentially reset roles to viewer via setProjectMemberRole.

Comment on lines +1 to +7
.actionsCell {
visibility: hidden;
}

tr:hover .actionsCell {
visibility: visible;
}
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.

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Hover-only reveal blocks non-mouse access to row actions.

The actions trigger is hidden unless a row is hovered, which can prevent keyboard and touch users from reaching the menu.

💡 Suggested CSS fix
 .actionsCell {
   visibility: hidden;
 }
 
-tr:hover .actionsCell {
+tr:hover .actionsCell,
+tr:focus-within .actionsCell {
   visibility: visible;
 }
+
+@media (hover: none) {
+  .actionsCell {
+    visibility: visible;
+  }
+}
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
.actionsCell {
visibility: hidden;
}
tr:hover .actionsCell {
visibility: visible;
}
.actionsCell {
visibility: hidden;
}
tr:hover .actionsCell,
tr:focus-within .actionsCell {
visibility: visible;
}
`@media` (hover: none) {
.actionsCell {
visibility: visible;
}
}

@coveralls
Copy link
Copy Markdown

coveralls commented May 19, 2026

Coverage Report for CI Build 26092878965

Coverage remained the same at 42.472%

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: 37907
Covered Lines: 16100
Line Coverage: 42.47%
Coverage Strength: 11.91 hits per line

💛 - Coveralls


import { useMemo, useState } from 'react';
import { ExclamationTriangleIcon, TrashIcon, UpdateIcon } from '@radix-ui/react-icons';
import { ExclamationTriangleIcon, UpdateIcon } from '@radix-ui/react-icons';
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should import exclamation icon from assets as before in billingview.tsx

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I didn't get your comment. Can you help me understand?

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.

3 participants