Skip to content

Conversation

@senithkay
Copy link
Contributor

@senithkay senithkay commented Dec 23, 2025

Purpose

The Create Function form did not persist function parameters when saving. This issue was caused by parts of the save logic still relying on the legacy property model that existed prior to the recent refactoring, leading to a mismatch between the expected and provided request objects.

Resolves issue: wso2/product-ballerina-integrator#2117

Goals

  • Ensure function parameters entered in the Create Function form are correctly saved.
  • Align the save logic with the newly refactored property model.

Approach

  • Identified sections of the save logic that were still referencing the old property model.
  • Updated the implementation to fully rely on the new, refactored property model when collecting and persisting function parameters.
  • Verified that parameters are correctly preserved across function save and automation configuration forms.

Summary by CodeRabbit

  • Bug Fixes

    • Fixed inconsistent behavior for repeatable/template-based properties so repeated inputs now initialize and validate consistently.
  • Refactor

    • Consolidated editor selection and repeatable-property handling to base rendering and value cloning on template-type detection, improving predictability when adding/removing repeated items.

✏️ Tip: You can customize this high-level summary in your review settings.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Dec 23, 2025

Walkthrough

The changes refactor handling of repeatable properties with template types: EditorFactory conditionally routes template-based repeatable properties to ParamManagerEditor; the visualizer stops auto-assigning PARAM_MANAGER; FunctionForm uses the template constraint for per-iteration values instead of ballerinaType.

Changes

Cohort / File(s) Summary
Conditional Routing for Repeatable Properties
workspaces/ballerina/ballerina-side-panel/src/components/editors/EditorFactory.tsx
Added isTemplateType import and replaced the direct PARAM_MANAGER branch. Now when field.type is REPEATABLE_PROPERTY, it renders ParamManagerEditor only if isTemplateType(getPrimaryInputType(field.types)) is true; otherwise renders FormMapEditor.
PARAM_MANAGER Type Assignment Removal
workspaces/ballerina/ballerina-visualizer/src/utils/bi.tsx
Removed automatic assignment of PARAM_MANAGER for repeatable properties (formField.types[0].fieldType = "PARAM_MANAGER" and formField.type = "PARAM_MANAGER"). Other repeatable-property handling and param value creation remain.
Template-Based Constraint Construction
workspaces/ballerina/ballerina-visualizer/src/views/BI/FunctionForm/index.tsx
Updated repeatable-property handling to require isTemplateType and to use primaryType.template (deep-cloned) as the base constraint for each iteration, replacing use of primaryType.ballerinaType when populating per-parameter values.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Poem

I’m a rabbit in code, hopping through template light,
Repeatable fields choose their editor just right.
No more forced PARAM_MANAGER lanes,
Templates now guide the per-iteration chains.
🐇✨

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The title 'fix function form saving without entered parameters' clearly and specifically describes the main bug fix being addressed in the changeset.
Description check ✅ Passed The PR description includes Purpose (with issue link), Goals, and Approach sections, but is missing several template sections including UI Component Development, Icons, User stories, Release notes, Documentation, and others.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

📜 Recent review details

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 62c6528 and 17791be.

📒 Files selected for processing (1)
  • workspaces/ballerina/ballerina-side-panel/src/components/editors/EditorFactory.tsx
🧰 Additional context used
🧠 Learnings (7)
📚 Learning: 2025-11-24T22:16:28.380Z
Learnt from: dan-niles
Repo: wso2/vscode-extensions PR: 980
File: workspaces/ballerina/ballerina-side-panel/src/components/editors/MultiModeExpressionEditor/RichTextTemplateEditor/RichTextTemplateEditor.tsx:384-412
Timestamp: 2025-11-24T22:16:28.380Z
Learning: In the RichTextTemplateEditor component (workspaces/ballerina/ballerina-side-panel/src/components/editors/MultiModeExpressionEditor/RichTextTemplateEditor/RichTextTemplateEditor.tsx), token fetching on external `value` prop changes is intentionally disabled. Users cannot edit both the minimized and expanded editors simultaneously, so tokens only need to be generated based on user typing in the expanded editor view, not on external prop updates.

Applied to files:

  • workspaces/ballerina/ballerina-side-panel/src/components/editors/EditorFactory.tsx
📚 Learning: 2025-11-25T06:34:10.812Z
Learnt from: CR
Repo: wso2/vscode-extensions PR: 0
File: workspaces/ballerina/component-diagram/AGENTS.md:0-0
Timestamp: 2025-11-25T06:34:10.812Z
Learning: Applies to workspaces/ballerina/component-diagram/src/**/*.{ts,tsx} : Define all constants (node types, sizing, spacing) in src/resources/constants.ts and import them where needed instead of hardcoding values

Applied to files:

  • workspaces/ballerina/ballerina-side-panel/src/components/editors/EditorFactory.tsx
📚 Learning: 2025-11-25T06:34:10.812Z
Learnt from: CR
Repo: wso2/vscode-extensions PR: 0
File: workspaces/ballerina/component-diagram/AGENTS.md:0-0
Timestamp: 2025-11-25T06:34:10.812Z
Learning: Applies to workspaces/ballerina/component-diagram/src/components/**/*.tsx : Use React 18.2.0 features including concurrent rendering and automatic batching; avoid class components in favor of functional components with hooks

Applied to files:

  • workspaces/ballerina/ballerina-side-panel/src/components/editors/EditorFactory.tsx
📚 Learning: 2025-12-16T13:47:11.133Z
Learnt from: kanushka
Repo: wso2/vscode-extensions PR: 1117
File: workspaces/ballerina/ballerina-visualizer/src/views/BI/Forms/FormGenerator/index.tsx:1183-1184
Timestamp: 2025-12-16T13:47:11.133Z
Learning: In workspaces/ballerina/ballerina-visualizer/src/views/BI/Forms/FormGenerator/index.tsx, the findMatchedType function intentionally uses module?.split('.').pop() to handle simple cases where the last segment of the module name is used for matching. Wildcard imports should be used for collision cases (when different modules have the same last segment), but this is not currently implemented as the code only handles the simple case for now.

Applied to files:

  • workspaces/ballerina/ballerina-side-panel/src/components/editors/EditorFactory.tsx
📚 Learning: 2025-11-25T06:34:10.812Z
Learnt from: CR
Repo: wso2/vscode-extensions PR: 0
File: workspaces/ballerina/component-diagram/AGENTS.md:0-0
Timestamp: 2025-11-25T06:34:10.812Z
Learning: Applies to workspaces/ballerina/component-diagram/src/**/*.{ts,tsx} : Use TypeScript 5.8.3 with strict type checking enabled for all source files

Applied to files:

  • workspaces/ballerina/ballerina-side-panel/src/components/editors/EditorFactory.tsx
📚 Learning: 2025-11-25T06:34:10.812Z
Learnt from: CR
Repo: wso2/vscode-extensions PR: 0
File: workspaces/ballerina/component-diagram/AGENTS.md:0-0
Timestamp: 2025-11-25T06:34:10.812Z
Learning: Applies to workspaces/ballerina/component-diagram/src/components/nodes/**/!(*Widget|*Model).tsx : Implement the factory pattern for node instantiation: each node type (Listener, Entry, Connection) must have a corresponding Factory class that extends the appropriate factory interface

Applied to files:

  • workspaces/ballerina/ballerina-side-panel/src/components/editors/EditorFactory.tsx
📚 Learning: 2025-11-25T06:34:10.812Z
Learnt from: CR
Repo: wso2/vscode-extensions PR: 0
File: workspaces/ballerina/component-diagram/AGENTS.md:0-0
Timestamp: 2025-11-25T06:34:10.812Z
Learning: Applies to workspaces/ballerina/component-diagram/src/components/nodes/**/*.{ts,tsx} : Each node type must have a Model class extending NodeModel, a Factory class implementing the factory pattern, and a Widget React component for visual representation

Applied to files:

  • workspaces/ballerina/ballerina-side-panel/src/components/editors/EditorFactory.tsx
🧬 Code graph analysis (1)
workspaces/ballerina/ballerina-side-panel/src/components/editors/EditorFactory.tsx (1)
workspaces/ballerina/ballerina-core/src/utils/form-property-utils.ts (2)
  • isTemplateType (26-30)
  • getPrimaryInputType (21-24)
🔇 Additional comments (2)
workspaces/ballerina/ballerina-side-panel/src/components/editors/EditorFactory.tsx (2)

21-21: LGTM! Import aligns with refactored property model.

The isTemplateType utility is correctly imported and supports the new template-based routing logic for repeatable properties.


206-212: No changes needed — the conditional routing is safe and backward compatible.

The implementation correctly handles all concerns:

  • PARAM_MANAGER is explicitly checked first (line 207), ensuring all existing forms continue routing to ParamManagerEditor without breaking changes
  • Template-based REPEATABLE_PROPERTY fields route to ParamManagerEditor, while non-template ones use FormMapEditor — this pattern already exists in FunctionForm/index.tsx:247, confirming API support
  • Edge cases are handled safely: getPrimaryInputType returns undefined for null/empty field.types, and isTemplateType safely evaluates undefined (it checks value !== null && typeof value === "object" before accessing properties)

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
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: 0

🧹 Nitpick comments (1)
workspaces/ballerina/ballerina-visualizer/src/views/BI/FunctionForm/index.tsx (1)

246-259: Core fix correctly aligns with the refactored property model.

This change properly addresses the bug by using primaryType.template from the new types array instead of the legacy ballerinaType property. The deep clone via JSON.parse(JSON.stringify(template)) is appropriate for this template structure.

Minor: repeatKey on line 251 is declared but unused. Consider using an underscore prefix to indicate intentional discard:

🔎 Optional: Mark unused variable
-                        for (const [repeatKey, repeatValue] of Object.entries(dataValue)) {
+                        for (const [_repeatKey, repeatValue] of Object.entries(dataValue)) {
📜 Review details

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 034ceeb and 62c6528.

📒 Files selected for processing (3)
  • workspaces/ballerina/ballerina-side-panel/src/components/editors/EditorFactory.tsx
  • workspaces/ballerina/ballerina-visualizer/src/utils/bi.tsx
  • workspaces/ballerina/ballerina-visualizer/src/views/BI/FunctionForm/index.tsx
💤 Files with no reviewable changes (1)
  • workspaces/ballerina/ballerina-visualizer/src/utils/bi.tsx
🧰 Additional context used
🧠 Learnings (9)
📚 Learning: 2025-12-16T13:47:11.133Z
Learnt from: kanushka
Repo: wso2/vscode-extensions PR: 1117
File: workspaces/ballerina/ballerina-visualizer/src/views/BI/Forms/FormGenerator/index.tsx:1183-1184
Timestamp: 2025-12-16T13:47:11.133Z
Learning: In workspaces/ballerina/ballerina-visualizer/src/views/BI/Forms/FormGenerator/index.tsx, the findMatchedType function intentionally uses module?.split('.').pop() to handle simple cases where the last segment of the module name is used for matching. Wildcard imports should be used for collision cases (when different modules have the same last segment), but this is not currently implemented as the code only handles the simple case for now.

Applied to files:

  • workspaces/ballerina/ballerina-visualizer/src/views/BI/FunctionForm/index.tsx
  • workspaces/ballerina/ballerina-side-panel/src/components/editors/EditorFactory.tsx
📚 Learning: 2025-11-25T06:34:10.812Z
Learnt from: CR
Repo: wso2/vscode-extensions PR: 0
File: workspaces/ballerina/component-diagram/AGENTS.md:0-0
Timestamp: 2025-11-25T06:34:10.812Z
Learning: Applies to workspaces/ballerina/component-diagram/src/components/**/*.tsx : Use React 18.2.0 features including concurrent rendering and automatic batching; avoid class components in favor of functional components with hooks

Applied to files:

  • workspaces/ballerina/ballerina-visualizer/src/views/BI/FunctionForm/index.tsx
  • workspaces/ballerina/ballerina-side-panel/src/components/editors/EditorFactory.tsx
📚 Learning: 2025-11-25T06:34:10.812Z
Learnt from: CR
Repo: wso2/vscode-extensions PR: 0
File: workspaces/ballerina/component-diagram/AGENTS.md:0-0
Timestamp: 2025-11-25T06:34:10.812Z
Learning: Applies to workspaces/ballerina/component-diagram/src/components/nodes/EntryNode/components/**/*.tsx : Implement lazy expansion of functions: only render function items when they are visible to improve performance for large function lists

Applied to files:

  • workspaces/ballerina/ballerina-visualizer/src/views/BI/FunctionForm/index.tsx
📚 Learning: 2025-11-25T06:34:10.812Z
Learnt from: CR
Repo: wso2/vscode-extensions PR: 0
File: workspaces/ballerina/component-diagram/AGENTS.md:0-0
Timestamp: 2025-11-25T06:34:10.812Z
Learning: Applies to workspaces/ballerina/component-diagram/src/**/*.{ts,tsx} : Define all constants (node types, sizing, spacing) in src/resources/constants.ts and import them where needed instead of hardcoding values

Applied to files:

  • workspaces/ballerina/ballerina-visualizer/src/views/BI/FunctionForm/index.tsx
  • workspaces/ballerina/ballerina-side-panel/src/components/editors/EditorFactory.tsx
📚 Learning: 2025-11-27T07:59:33.534Z
Learnt from: KCSAbeywickrama
Repo: wso2/vscode-extensions PR: 897
File: workspaces/ballerina/data-mapper/src/components/DataMapper/SidePanel/QueryClauses/ClausesPanel.tsx:50-59
Timestamp: 2025-11-27T07:59:33.534Z
Learning: In workspaces/ballerina/data-mapper/src/components/DataMapper/SidePanel/QueryClauses/ClausesPanel.tsx, the `clause.properties.expression` property in the `fillDefaults` function does not require defensive null/undefined checks because it's a required property enforced by form validation in ClauseEditor.

Applied to files:

  • workspaces/ballerina/ballerina-visualizer/src/views/BI/FunctionForm/index.tsx
📚 Learning: 2025-11-25T06:34:10.812Z
Learnt from: CR
Repo: wso2/vscode-extensions PR: 0
File: workspaces/ballerina/component-diagram/AGENTS.md:0-0
Timestamp: 2025-11-25T06:34:10.812Z
Learning: Applies to workspaces/ballerina/component-diagram/src/**/*.{ts,tsx} : Use TypeScript 5.8.3 with strict type checking enabled for all source files

Applied to files:

  • workspaces/ballerina/ballerina-visualizer/src/views/BI/FunctionForm/index.tsx
  • workspaces/ballerina/ballerina-side-panel/src/components/editors/EditorFactory.tsx
📚 Learning: 2025-11-24T22:16:28.380Z
Learnt from: dan-niles
Repo: wso2/vscode-extensions PR: 980
File: workspaces/ballerina/ballerina-side-panel/src/components/editors/MultiModeExpressionEditor/RichTextTemplateEditor/RichTextTemplateEditor.tsx:384-412
Timestamp: 2025-11-24T22:16:28.380Z
Learning: In the RichTextTemplateEditor component (workspaces/ballerina/ballerina-side-panel/src/components/editors/MultiModeExpressionEditor/RichTextTemplateEditor/RichTextTemplateEditor.tsx), token fetching on external `value` prop changes is intentionally disabled. Users cannot edit both the minimized and expanded editors simultaneously, so tokens only need to be generated based on user typing in the expanded editor view, not on external prop updates.

Applied to files:

  • workspaces/ballerina/ballerina-side-panel/src/components/editors/EditorFactory.tsx
📚 Learning: 2025-11-25T06:34:10.812Z
Learnt from: CR
Repo: wso2/vscode-extensions PR: 0
File: workspaces/ballerina/component-diagram/AGENTS.md:0-0
Timestamp: 2025-11-25T06:34:10.812Z
Learning: Applies to workspaces/ballerina/component-diagram/src/components/nodes/**/!(*Widget|*Model).tsx : Implement the factory pattern for node instantiation: each node type (Listener, Entry, Connection) must have a corresponding Factory class that extends the appropriate factory interface

Applied to files:

  • workspaces/ballerina/ballerina-side-panel/src/components/editors/EditorFactory.tsx
📚 Learning: 2025-11-25T06:34:10.812Z
Learnt from: CR
Repo: wso2/vscode-extensions PR: 0
File: workspaces/ballerina/component-diagram/AGENTS.md:0-0
Timestamp: 2025-11-25T06:34:10.812Z
Learning: Applies to workspaces/ballerina/component-diagram/src/components/nodes/**/*.{ts,tsx} : Each node type must have a Model class extending NodeModel, a Factory class implementing the factory pattern, and a Widget React component for visual representation

Applied to files:

  • workspaces/ballerina/ballerina-side-panel/src/components/editors/EditorFactory.tsx
🧬 Code graph analysis (2)
workspaces/ballerina/ballerina-visualizer/src/views/BI/FunctionForm/index.tsx (1)
workspaces/ballerina/ballerina-core/src/utils/form-property-utils.ts (2)
  • getPrimaryInputType (21-24)
  • isTemplateType (26-30)
workspaces/ballerina/ballerina-side-panel/src/components/editors/EditorFactory.tsx (1)
workspaces/ballerina/ballerina-core/src/utils/form-property-utils.ts (2)
  • isTemplateType (26-30)
  • getPrimaryInputType (21-24)
🔇 Additional comments (2)
workspaces/ballerina/ballerina-visualizer/src/views/BI/FunctionForm/index.tsx (1)

117-121: LGTM: Properly handles template-based parameter description.

The logic correctly identifies template types and sets the nested parameterDescription type to "TEXTAREA". The as any casts are acceptable here given the dynamic nature of the template structure.

workspaces/ballerina/ballerina-side-panel/src/components/editors/EditorFactory.tsx (1)

206-209: Good fix aligning with the refactored property model.

The conditional routing based on isTemplateType correctly distinguishes between template-based repeatable properties (using ParamManagerEditor) and others (using FormMapEditor). This properly replaces the removed PARAM_MANAGER type-specific branch.

Note: getPrimaryInputType returns InputType | undefined, and while isTemplateType handles this safely at runtime (the typeof value === "object" check returns false for undefined), you may want to add an explicit null check for defensive robustness, depending on your code standards.

// Skip this property
return <></>;
} else if (field.type === "PARAM_MANAGER") {
} else if (field.type === "REPEATABLE_PROPERTY" && isTemplateType(getPrimaryInputType(field.types))) {
Copy link
Contributor

Choose a reason for hiding this comment

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

if we are removing PARAM_MANAGER from the editor factory we need to refactor all the forms which right now uses the PARAM_MANAGER and verify if those apis as well support this new REPEATABLE_PROPERTY type to generate source from the model.

@kanushka kanushka changed the base branch from main to bi-1.6.x December 23, 2025 15:14
@kanushka kanushka merged commit 0636ad8 into wso2:bi-1.6.x Dec 23, 2025
6 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.

4 participants