Skip to content

[Feature] UI - Projects: Add Project Details Page#22360

Merged
yuneng-jiang merged 2 commits intomainfrom
litellm_ui_project_info
Feb 28, 2026
Merged

[Feature] UI - Projects: Add Project Details Page#22360
yuneng-jiang merged 2 commits intomainfrom
litellm_ui_project_info

Conversation

@yuneng-jiang
Copy link
Collaborator

Relevant issues

Summary

Problem

The Projects page only had a list view with no way to inspect or edit individual project details.

Fix

Added a Project Details page following the Access Groups detail page pattern, with:

  • Header with back navigation, project name, status tag, and Edit button
  • Project details card (description, created/updated timestamps with user attribution)
  • Spend/budget section with progress bar and model spend bar chart (tremor)
  • Team info card with compact spend/budget display
  • Keys placeholder card (for future use)
  • Edit Project modal with pre-filled form data
  • Refactored Create/Edit modals to share a base form (ProjectBaseForm)
  • Duplicate key validation on model limits and metadata fields

Testing

  • Manually tested create, edit, and detail view flows
  • Verified model limits and metadata correctly round-trip through the backend
  • Tested team info resolution from nested API response

Type

🆕 New Feature
🧹 Refactoring

- Add ProjectDetailsPage with header, details card, spend/budget progress,
  model spend bar chart, keys placeholder, and team info card
- Refactor CreateProjectModal into base form pattern (ProjectBaseForm)
  shared between Create and Edit flows
- Add EditProjectModal with pre-filled form data from backend
- Add useProjectDetails and useUpdateProject hooks
- Add duplicate key validation for model limits and metadata
- Wire project ID click in table to navigate to detail view
- Move pagination inline with search bar

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@vercel
Copy link

vercel bot commented Feb 28, 2026

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

Project Deployment Actions Updated (UTC)
litellm Ready Ready Preview, Comment Feb 28, 2026 6:12am

Request Review

@greptile-apps
Copy link
Contributor

greptile-apps bot commented Feb 28, 2026

Greptile Summary

This PR adds a Project Details page to the UI, following the Access Groups detail page pattern. It introduces a detail view with project info, spend/budget visualization (with tremor BarChart), team info card, and a keys placeholder. The create/edit modal logic is refactored to share a ProjectBaseForm component and a buildProjectApiParams utility, reducing duplication. New React Query hooks (useProjectDetails, useUpdateProject) follow existing codebase conventions.

  • Bug: Edit modal doesn't pre-fill model limitsEditProjectModal reads model_rpm_limit/model_tpm_limit from project.metadata, but the backend stores these as top-level fields on LiteLLM_ProjectTable. This means existing model-specific RPM/TPM limits will appear empty when editing a project.
  • Good refactoring of shared form logic into ProjectBaseForm and projectFormUtils, with added duplicate-key validation on model limits and metadata fields.
  • Minor inconsistency: CreateProjectModal uses the deprecated destroyOnClose prop while EditProjectModal uses the newer destroyOnHidden.

Confidence Score: 3/5

  • Mostly safe UI-only changes but has a data-binding bug in the edit modal that will cause model limits to not load correctly
  • The PR is a well-structured frontend feature addition that follows existing codebase patterns. However, the EditProjectModal reads model RPM/TPM limits from the wrong location (project.metadata instead of top-level fields), which means editing a project will lose its model-specific limits. This is a functional bug that affects the edit workflow.
  • Pay close attention to EditProjectModal.tsx — the model limits data binding reads from the wrong field on the project response object.

Important Files Changed

Filename Overview
ui/litellm-dashboard/src/app/(dashboard)/hooks/projects/useProjectDetails.ts New hook for fetching project details with React Query. Clean implementation using projectKeys.detail(), seeding from list cache via initialData. No issues found.
ui/litellm-dashboard/src/app/(dashboard)/hooks/projects/useUpdateProject.ts New mutation hook for updating projects via POST to /project/update. Follows existing codebase patterns with proper cache invalidation. No issues found.
ui/litellm-dashboard/src/components/Projects/ProjectDetailsPage.tsx New project details page with header, spend/budget display, team info card, and edit modal. Fragile team data type-casting via as unknown as but follows existing patterns in the codebase.
ui/litellm-dashboard/src/components/Projects/ProjectModals/CreateProjectModal.tsx Refactored to use shared ProjectBaseForm and buildProjectApiParams. Uses deprecated destroyOnClose instead of destroyOnHidden.
ui/litellm-dashboard/src/components/Projects/ProjectModals/EditProjectModal.tsx New edit modal with a bug: reads model RPM/TPM limits from project.metadata instead of the top-level project.model_rpm_limit/project.model_tpm_limit fields, causing limits to not pre-fill on edit.
ui/litellm-dashboard/src/components/Projects/ProjectModals/ProjectBaseForm.tsx Shared form component extracted from CreateProjectModal with team sync, model fetching, duplicate key validation. Clean refactor with no issues.
ui/litellm-dashboard/src/components/Projects/ProjectModals/projectFormUtils.ts Utility to transform form values to API params. Shared by create and update flows. Correctly sends model limits as top-level fields.
ui/litellm-dashboard/src/components/Projects/ProjectsPage.tsx Added project detail navigation via selectedProjectId state, moved pagination outside table for a cleaner layout, added team loading spinner. No issues found.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    A[ProjectsPage] -->|click project ID| B[ProjectDetail]
    B -->|useProjectDetails| C[GET /project/info]
    B -->|useTeam| D[GET /team/info]
    B -->|click Edit| E[EditProjectModal]
    E -->|ProjectBaseForm| F[Shared Form Component]
    E -->|useUpdateProject| G[POST /project/update]
    G -->|invalidateQueries| H[Refresh project cache]
    A -->|click Create| I[CreateProjectModal]
    I -->|ProjectBaseForm| F
    I -->|useCreateProject| J[POST /project/new]
    J -->|invalidateQueries| H
    F -->|buildProjectApiParams| K[projectFormUtils]
Loading

Last reviewed commit: 061703a

Copy link
Contributor

@greptile-apps greptile-apps bot left a comment

Choose a reason for hiding this comment

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

8 files reviewed, 2 comments

Edit Code Review Agent Settings | Greptile

Comment on lines +32 to +34
const metadataObj = (project.metadata ?? {}) as Record<string, unknown>;
const rpmLimits = (metadataObj.model_rpm_limit ?? {}) as Record<string, number>;
const tpmLimits = (metadataObj.model_tpm_limit ?? {}) as Record<string, number>;
Copy link
Contributor

Choose a reason for hiding this comment

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

Model limits read from wrong field

The edit form reads model_rpm_limit and model_tpm_limit from project.metadata, but the backend stores these as top-level fields on LiteLLM_ProjectTable (see litellm/proxy/_types.py:2662-2663), not inside metadata. The ProjectResponse type also defines them at the top level (model_rpm_limit, model_tpm_limit).

As a result, when editing an existing project the model-specific RPM/TPM limits will always appear empty in the form, even if the project has limits set.

Suggested change
const metadataObj = (project.metadata ?? {}) as Record<string, unknown>;
const rpmLimits = (metadataObj.model_rpm_limit ?? {}) as Record<string, number>;
const tpmLimits = (metadataObj.model_tpm_limit ?? {}) as Record<string, number>;
const rpmLimits = (project.model_rpm_limit ?? {}) as Record<string, number>;
const tpmLimits = (project.model_tpm_limit ?? {}) as Record<string, number>;

…ateProjectModal.tsx

Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
@yuneng-jiang yuneng-jiang merged commit a4b7a93 into main Feb 28, 2026
10 of 13 checks passed
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.

1 participant