FIX: Connection Name and Description Losing Last Character When Editing#57
Conversation
- Replace controlled inputs (value prop) with Form-managed inputs (name prop) - Use Form.useForm() hook and form.setFieldsValue() to set values when editing existing connections - Remove getValueFromEvent which conflicted with controlled input pattern - Move collapseSpaces transformation to onChange handler This fixes the issue where the form fields wouldn't properly display values when editing existing connections. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
- Add debounced state update for name and description fields (300ms) - Prevents the handleCreateOrUpdate callback from capturing stale dbSelectionInfo values during rapid typing - Ensures the last character is not lost when updating a connection This fixes the bug where editing connection name from "test_pg" to "test_pg_edited" would save as "test_pg_edite" (missing last character). 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
|
| Filename | Overview |
|---|---|
| frontend/src/base/components/environment/ConnectionDetailsSection.jsx | Migrated from controlled inputs with manual onChange/value to AntD Form-managed fields using name prop and normalize; receives form instance from parent and uses setFieldsValue via useEffect to seed values on load. |
| frontend/src/base/components/environment/CreateConnection.jsx | Creates shared form instance with Form.useForm(), reads name/description via getFieldsValue() on submit, and uses Form.useWatch for reactive hasDetailsChanged; two P2 issues: missing validateFields() before submit, and a one-render undefined flash in hasDetailsChanged when loading. |
Sequence Diagram
sequenceDiagram
participant U as User
participant CC as CreateConnection
participant CDS as ConnectionDetailsSection
participant ADF as AntD Form (shared instance)
participant API as Backend API
Note over CC,ADF: Form.useForm() creates shared instance
CC->>API: fetchSingleConnection(connectionId)
API-->>CC: { name, description, ... }
CC->>CC: setDbSelectionInfo / setOriginalDbSelectionInfo
CC->>CDS: pass connectionDetailsForm instance
CDS->>ADF: setFieldsValue({ name, description }) via useEffect
ADF-->>CC: Form.useWatch → formName, formDescription updated
U->>ADF: types in Name field
ADF->>CC: Form.useWatch → formName updates → hasDetailsChanged recalculated
U->>CC: clicks Update
CC->>ADF: getFieldsValue() → { name, description }
CC->>API: updateConnectionApi({ ...dbSelectionInfo, name, description, ... })
API-->>CC: success
Prompt To Fix All With AI
This is a comment left during a code review.
Path: frontend/src/base/components/environment/CreateConnection.jsx
Line: 128-132
Comment:
**Validation rules bypassed on submit**
`getFieldsValue()` returns the current field values without triggering the form's validation rules. The `required` rule and `validateFormFieldName` validator on the `name` field will not block submission of an empty or invalid name — users can submit a blank connection name and the API call will proceed.
Since `Form.Item` now has a `name` prop and is wired to `connectionDetailsForm`, a simple `await connectionDetailsForm.validateFields()` call before reading values would enforce all declared rules and surface errors inline.
```suggestion
const handleCreateOrUpdate = useCallback(async () => {
setIsCreateOrUpdateLoading(true);
try {
// Validate fields first, then read values
const { name, description } = await connectionDetailsForm.validateFields();
```
How can I resolve this? If you propose a fix, please make it concise.
---
This is a comment left during a code review.
Path: frontend/src/base/components/environment/CreateConnection.jsx
Line: 411-417
Comment:
**One-render flash where `hasDetailsChanged` is incorrectly `true`**
When `getSingleConnectionDetails` resolves, `setOriginalDbSelectionInfo` is called synchronously (in the same state batch). At that point `originalDbSelectionInfo` is no longer `null`, but `formName`/`formDescription` are still `undefined` — `setFieldsValue` hasn't run yet because it lives in `ConnectionDetailsSection`'s `useEffect`, which fires *after* the render caused by the state update. For that one render cycle, `formName !== originalDbSelectionInfo.name` evaluates to `undefined !== "test_pg"` → `true`, so any UI driven by `hasDetailsChanged` briefly shows the wrong state.
A guard for `undefined` removes the flicker:
```suggestion
const hasDetailsChanged = useMemo(() => {
if (!connectionId || !originalDbSelectionInfo) return false;
if (formName === undefined && formDescription === undefined) return false;
return (
formName !== originalDbSelectionInfo.name ||
formDescription !== originalDbSelectionInfo.description
);
}, [connectionId, formName, formDescription, originalDbSelectionInfo]);
```
How can I resolve this? If you propose a fix, please make it concise.Reviews (10): Last reviewed commit: "fix: add hasDetailsChanged to deps and n..." | Re-trigger Greptile
The debounce was introduced to fix stale closure issues, but it actually creates a worse bug - a 300ms window where clicking Update could submit pre-edit values. The root cause is already fixed in ConnectionDetailsSection.jsx by using Ant Design's Form pattern (Form.useForm + form.setFieldsValue). With uncontrolled inputs, the direct state update works correctly. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
Debounce the handleConnectionNameDesc callback (300ms) to ensure the parent's handleCreateOrUpdate closure captures the latest state value. The form input remains responsive since Ant Design manages the input internally, while the parent state update is debounced. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
Update form value synchronously with collapsed spaces so the validator always sees the processed value, preventing spurious validation errors when consecutive spaces are typed. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
Change useEffect dependency from dbSelectionInfo fields to connectionId to prevent form values from being overwritten during typing due to debounced state updates. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
- Restore debounce for parent state updates - Add isUserEditingRef to track when user is actively editing - Only populate form values when not in editing mode - Reset editing flag when connectionId changes (new connection loaded) This ensures: 1. Form populates correctly when async connection data arrives 2. User edits are not overwritten by the useEffect 3. Parent state updates are debounced to prevent stale closure issues 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
Replace manual form.setFieldValue with normalize prop on Form.Item. This ensures collapseSpaces is applied before storage and validation, preventing false validation errors when consecutive spaces are typed. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
setFieldsValue bypasses the normalize prop, so apply collapseSpaces manually when loading connection data to ensure consistent formatting. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
There was a problem hiding this comment.
Good fix for the root cause — switching to Ant Design's Form pattern (Form.useForm + name prop + normalize) is the right approach.
One concern — debounce race condition:
The 300ms debounce on debouncedHandleConnectionNameDesc means if a user types and clicks "Update" within 300ms, dbSelectionInfo in the parent still has the old value. Since handleCreateOrUpdate reads from dbSelectionInfo, the last few characters could still be lost — which is essentially the same bug with a different timing window.
Two options to fix:
- Flush on submit — call
debouncedHandleConnectionNameDesc.flush()at the start ofhandleCreateOrUpdateinCreateConnection.jsx - Read from form directly — use
form.getFieldsValue()in the submit handler instead of relying ondbSelectionInfofor name/description
Option 2 would be cleaner since the form already has the correct value at all times.
- Move Form.useForm() to CreateConnection.jsx and pass form as prop - Remove debounce logic from ConnectionDetailsSection (no longer needed) - Read name/description directly from form in handleCreateOrUpdate - Use Form.useWatch to reactively track form values for hasDetailsChanged - This eliminates the race condition and fixes Update button not enabling 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
- Add hasDetailsChanged to handleCreateOrUpdate dependency array to fix stale closure issue - Apply collapseSpaces when storing originalDbSelectionInfo.name to ensure consistent comparison with form values 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
@wicky-zipstack Done. I went with Option 2. The submit handler now reads directly from the form using For Thanks for the suggestion! |
What
Why
valueprop) that conflicted with Ant Design Form's internal state managementgetValueFromEventprop on Form.Item interfering with the onChange flowHow
CreateConnection.jsx:
Form.useForm()hook to create form instance and pass it to childconnectionDetailsForm.getFieldsValue()in submit handlerForm.useWatchto reactively track form values forhasDetailsChangedcomparisonConnectionDetailsSection.jsx:
namepropform.setFieldsValue()to populate fields when editing existing connectionsgetValueFromEventpropnormalize={collapseSpaces}on name field for space collapsingCan this PR break any existing features. If yes, please list possible items. If no, please explain why. (PS: Admins do not merge the PR without this section filled)
Database Migrations
Env Config
Relevant Docs
Related Issues or PRs
Dependencies Versions
Notes on Testing
Screenshots
The "name" field value modified but yet to click on the "Update" button

After clicking on the "Update" button

Checklist
I have read and understood the Contribution Guidelines.