refactor(ui): consolidate Add/Edit credential modals into one CredentialModal - #32572
Conversation
…ialModal AddCredentialModal and EditCredentialModal were ~90% identical: the same provider select, ProviderSpecificFields, and submit/filter logic, differing only in title, button text, edit-mode prefill, and the disabled credential name. Replace both with a single CredentialModal driven by a mode: 'add' | 'edit' prop, and point the two call sites in credentials.tsx at it. Removes ~120 lines of duplication and drops the no-explicit-any and no-restricted-imports baselines. The two per-file tests merge into one CredentialModal.test.tsx covering both modes (add: editable empty name; edit: prefilled, disabled name; provider fields render).
Greptile SummaryThis PR consolidates
Confidence Score: 5/5Safe to merge — this is a pure UI deduplication with no functional changes to credential creation or editing flows. The consolidation is mechanically sound. Both call sites in credentials.tsx conditionally mount/unmount the modal, so initialValues-based form seeding is applied fresh on every open — the same guarantee the old useEffect approach provided. The isEdit flag drives all mode-dependent branches consistently, and the new test suite explicitly covers the edge cases (including the empty-name-in-edit-mode scenario). No logic was changed, only structure. No files require special attention.
|
| Filename | Overview |
|---|---|
| ui/litellm-dashboard/src/components/model_add/CredentialModal.tsx | New unified modal combining AddCredentialModal and EditCredentialModal; uses isEdit for all mode-branching, initialValues for form seeding, and destroyOnHidden preserved for edit mode only — behaviorally equivalent to the two components it replaces. |
| ui/litellm-dashboard/src/components/model_add/credentials.tsx | Call sites updated to use the unified CredentialModal with mode prop and onSubmit; conditional rendering ensures fresh remounts, so initialValues-based form seeding works correctly. |
| ui/litellm-dashboard/src/components/model_add/CredentialModal.test.tsx | New merged test file covers add mode (empty editable name, provider fields) and edit mode (prefill, disabled name, and the "disabled by mode not by name value" edge case that fixed the old bug). |
| ui/litellm-dashboard/eslint-metrics.json | no-explicit-any drops by 4 as expected; local/no-large-inline-object-arg rises by 7, likely from the large mock objects added in CredentialModal.test.tsx. |
| ui/litellm-dashboard/eslint-suppressions.json | Collapses two per-file suppression entries (AddCredentialModal + EditCredentialModal) into one for CredentialModal; also removes the react-hooks/set-state-in-effect entry that was needed for the old useEffect in EditCredentialModal. |
| ui/litellm-dashboard/src/components/model_add/EditCredentialModal.tsx | Deleted; functionality fully absorbed by CredentialModal.tsx. |
Reviews (3): Last reviewed commit: "refactor(ui): prefill credential form de..." | Re-trigger Greptile
Codecov Report✅ All modified and coverable lines are covered by tests. 📢 Thoughts on this report? Let us know! |
The disabled flag on the credential name field was tied to whether existingCredential?.credential_name is truthy, an artifact of the old EditCredentialModal. Drive it from the isEdit flag like the rest of the component so mode='add' with a stray existingCredential can't disable the field and mode='edit' with an empty name can't leave it editable. Behavior is unchanged for real call sites; adds a regression test for the edit-with- empty-name case.
|
@greptileai Addressed the P2: the credential name field's disabled state now derives from the mode (isEdit) instead of existingCredential?.credential_name truthiness, matching the rest of the component. Added a regression test for the edit-with-empty-name case. |
|
The fix looks correct. The consolidated |
|
@greptileai re review |
…itellm_dedup_credential_modal
…eEffect The edit-mode form was seeded with an imperative form.setFieldsValue inside a useEffect that also set React state (setSelectedProvider), an antd anti- pattern carried over from the old EditCredentialModal. Both call sites mount the modal fresh with existingCredential already present (conditional && plus destroyOnHidden), so there is no 'prop arrives after mount' case to handle. Replace it with antd's declarative initialValues on the Form and a lazy useState initializer for the provider. Removes the effect, its react-hooks/set-state-in-effect suppression and exhaustive-deps warning, and one any cast; behavior is unchanged (edit now shows the real provider on first paint instead of flashing the default). Existing tests cover prefill and the disabled name field.
|
@greptileai re review |
QA: consolidated CredentialModal (add + edit)QA'd end to end against a live proxy plus dev server on this branch. Both modes of the merged Add mode (
Edit mode (
Walkthrough One non-blocking note for reviewers: the PR shows a merge conflict against |
…itellm_dedup_credential_modal # Conflicts: # ui/litellm-dashboard/eslint-metrics.json # ui/litellm-dashboard/eslint-suppressions.json
Relevant issues
Linear ticket
Pre-Submission checklist
Please complete all items before asking a LiteLLM maintainer to review your PR
@greptileaito re-request a review after pushing changes)Screenshots / Proof of Fix
This is a behavior-preserving consolidation of two UI modals, so there is no new user-facing behavior; the goal is that Add and Edit credential still work exactly as before. Two ways to confirm
Automated regression coverage: the merged
CredentialModal.test.tsxrenders both modes and pins the differences that used to live in the two separate componentsManual check in the running dashboard
http://localhost:4000/ui/?page=llm-credentialsType
🧹 Refactoring
Changes
AddCredentialModalandEditCredentialModalwere about 90% identical. Both rendered the same providerSelect, the sameProviderSpecificFields, and the same submit-and-filter logic; they diverged only in the modal title, the submit button label, whether the credential name was prefilled and disabled, and the edit-only effect that seeds the form from an existing credentialThey collapse into a single
CredentialModaldriven by amode: "add" | "edit"prop plus an optionalexistingCredential. The two call sites incredentials.tsxpass the mode and their respective submit handler through a unifiedonSubmit. Behavior is preserved down to the small quirks (edit-onlydestroyOnHidden, the disabled name field, and the per-mode default provider), so this is a pure dedup with no functional changeThat removes roughly 120 lines of duplication and lets the two per-file test files merge into one
CredentialModal.test.tsxthat covers both modes: add shows an empty editable name and renders provider fields, edit prefills and disables the name. Consolidating the two copies also drops the dashboardno-explicit-anycount and collapses twono-restricted-importssuppression entries into one, so the lint baselines ratchet down