Skip to content

Fix external form model updates without remounting - #120

Merged
lordrip merged 1 commit into
KaotoIO:1.xfrom
lhein:fix/issue-119-external-model-updates
Sep 16, 2026
Merged

lordrip merged 1 commit into
KaotoIO:1.xfrom
lhein:fix/issue-119-external-model-updates

Conversation

@lhein

@lhein lhein commented Sep 16, 2026 •

Copy link
Copy Markdown
Contributor

Closes #119

Updating KaotoForm's model now refreshes the existing fields without remounting the form or emitting another change event. This lets Kaoto's properties panel follow source-editor changes while keeping nested expression forms and input focus intact.

The fix synchronizes string/RAW values, key/value entries and the selected oneOf variant. Local numeric drafts and temporary duplicate map keys remain editable, including when a parent immediately echoes the updated model. Expression selection also handles clearing, subsequent external updates and refreshed schemas.

Targets the 1.x maintenance branch used by Kaoto. This moves the workaround currently carried as a Yarn patch into the library's TypeScript sources, with regression coverage.

Validation

  • yarn build passes.
  • yarn test --runInBand: 407 tests and 21 snapshots pass, including 9 added regression tests.
  • ESLint passes for all changed files; git diff --check passes.
  • Full-repository ESLint reports the same 12 pre-existing formatting errors as the unmodified 1.x branch; the output is unchanged.

Related: KaotoIO/kaoto#3938

Summary by CodeRabbit

  • Bug Fixes
    • External model updates now refresh form values without triggering unnecessary change notifications.
    • Local edits, including numeric drafts and NaN, are preserved correctly during controlled updates.
    • Duplicate map keys and in-progress key-value drafts are retained reliably.
    • RAW values and cleared expressions now maintain the expected state.
    • One-of field selections remain accurate when schemas or external values change.
    • Form fields preserve focus and editing state while parent-controlled values update.

@coderabbitai

coderabbitai Bot commented Sep 16, 2026 •

Copy link
Copy Markdown

Review Change StackReview Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Advanced

Run ID: 9dadd77f-a813-46df-9f8c-4c3bc724f590

📥 Commits

Reviewing files that changed from the base of the PR and between 14aa6b7 and 5bb2c65.

📒 Files selected for processing (8)
  • src/form/KaotoForm.test.tsx
  • src/form/KaotoForm.tsx
  • src/form/KeyValue/KeyValue.test.tsx
  • src/form/KeyValue/KeyValue.tsx
  • src/form/fields/StringField.tsx
  • src/form/hooks/field-value.ts
  • src/form/hooks/one-of-field.test.tsx
  • src/form/hooks/one-of-field.ts

Included review availability: Your plan provides up to 1 included review per hour; 0 remain after this review.


📝 Walkthrough

Walkthrough

The form now refreshes from external models without remounting fields. It separates external updates from local edits, preserves drafts and focus-related field state, avoids refresh callbacks, and synchronizes map entries, RAW values, numeric input, and oneOf selections.

Changes

External form refresh

Layer / File(s) Summary
Form state and notifications
src/form/KaotoForm.tsx, src/form/KaotoForm.test.tsx
KaotoForm tracks source, displayed, and pending local models. External updates refresh fields without emitting onChange. Tests cover string refreshes and controlled callback behavior.
Draft and map preservation
src/form/fields/StringField.tsx, src/form/hooks/field-value.ts, src/form/KeyValue/KeyValue.tsx, src/form/KeyValue/KeyValue.test.tsx, src/form/KaotoForm.test.tsx
Fields preserve local numeric drafts and derive RAW status from the current value. KeyValue preserves local duplicate-key drafts while accepting distinct external updates.
oneOf selection synchronization
src/form/hooks/one-of-field.ts, src/form/hooks/one-of-field.test.tsx, src/form/KaotoForm.test.tsx
useOneOfField tracks selections by schema index and refreshes them from model presets. Tests cover schema replacement, external changes, clearing, and explicit selection changes.

Priority: ➖ Normal

Estimated code review effort: 3 (Moderate) | ~25 minutes

Change: Bug fix · Severity of issue fixed: Medium

Sequence Diagram(s)

sequenceDiagram
  participant Parent
  participant KaotoForm
  participant Field
  Parent->>KaotoForm: provide updated model
  KaotoForm->>Field: refresh displayed value
  Field-->>KaotoForm: emit local edit
  KaotoForm-->>Parent: notify local model change
Loading

Merge Risk: ⚪ Minimal · up to 5bb2c

The form refresh changes are covered across model synchronization, local drafts, maps, RAW values, and oneOf selection behavior. No actionable merge risk remains.

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and concisely describes the main change: fixing external form model updates without remounting the form.
Linked Issues check ✅ Passed The changes satisfy the coding requirements in [#119]. KaotoForm now applies external model updates without remounting fields or emitting an additional change event. Updates cover expression selecti…
Out of Scope Changes check ✅ Passed The changed implementation files directly support [#119]. The added tests provide regression coverage for external refreshes, event suppression, focus and nested-state preservation, numeric drafts, du…
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check. Docstring coverage is scoped to functions touched by this diff. Analyzed 0 functions across 8…
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Warning

Git: CodeRabbit could not clone the repository, so clone-backed analysis was skipped and this review may be incomplete. Verify repository clone access, such as SSH credentials, before requesting another full review. If clone access is intentionally unavailable, use path_filters to narrow the review scope.


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

A rabbit sees the fields refresh,
Drafts stay safe through every test.
Maps keep keys that briefly bend,
OneOf choices follow the trend.
Local edits hop, external echoes rest.

Comment @coderabbitai help to get the list of available commands.

@sonarqubecloud

Copy link
Copy Markdown

@lordrip lordrip left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I don't think this is the way to move forward with this issue.

The problem is that we're fighting and providing workarounds to an architectural flaw from my initial design, I started it as a controlled component, but along the way, I wanted to add additional features, like supporting String and Number in the StringField component and that derived into having a mix between controlled and uncontrolled behaviors.

This is clear when we see we receive data from the parent, plus keep track of the internal state and now we need to capture what each component emitted themselves.

To unblock the current issues, let's move forward with this approach, and then move the main branch of this library to Kaoto directly, that will allow faster iteration cycles and we can fix the issues differently there.

For more information: https://legacy.reactjs.org/docs/uncontrolled-components.html

@lordrip
lordrip merged commit 6704669 into KaotoIO:1.x Sep 16, 2026
7 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.

2 participants