Skip to content

Sync release/bi-1/8.x with the feature/persist-improvements branch#1486

Merged
sachiniSam merged 12 commits intorelease/bi-1.8.xfrom
feature/persist-improvements
Feb 19, 2026
Merged

Sync release/bi-1/8.x with the feature/persist-improvements branch#1486
sachiniSam merged 12 commits intorelease/bi-1.8.xfrom
feature/persist-improvements

Conversation

@sachiniSam
Copy link
Contributor

@sachiniSam sachiniSam commented Feb 18, 2026

Purpose

$Subject

This includes the feature of multiple persist connection support and Dependent Type editor support

Goals

Describe the solutions that this feature/fix will introduce to resolve the problems described above

Approach

Describe how you are implementing the solutions. Include an animated GIF or screenshot if the change affects the UI (email documentation@wso2.com to review all UI text). Include a link to a Markdown file or Google doc if the feature write-up is too long to paste here.

UI Component Development

Specify the reason if following are not followed.

  • Added reusable UI components to the ui-toolkit. Follow the intructions when adding the componenent.
  • Use ui-toolkit components wherever possible. Run npm run storybook from the root directory to view current components.
  • Matches with the native VSCode look and feel.

Manage Icons

Specify the reason if following are not followed.

  • Added Icons to the font-wso2-vscode. Follow the instructions.

User stories

Summary of user stories addressed by this change>

Release note

Brief description of the new feature or bug fix as it will appear in the release notes

Documentation

Link(s) to product documentation that addresses the changes of this PR. If no doc impact, enter “N/A” plus brief explanation of why there’s no doc impact

Training

Link to the PR for changes to the training content in https://github.com/wso2/WSO2-Training, if applicable

Certification

Type “Sent” when you have provided new/updated certification questions, plus four answers for each question (correct answer highlighted in bold), based on this change. Certification questions/answers should be sent to certification@wso2.com and NOT pasted in this PR. If there is no impact on certification exams, type “N/A” and explain why.

Marketing

Link to drafts of marketing content that will describe and promote this feature, including product page changes, technical articles, blog posts, videos, etc., if applicable

Automation tests

  • Unit tests

    Code coverage information

  • Integration tests

    Details about the test cases and coverage

Security checks

Samples

Provide high-level details about the samples related to this feature

Related PRs

List any other related PRs

Migrations (if applicable)

Describe migration steps and platforms on which migration has been tested

Test environment

List all JDK versions, operating systems, databases, and browser/versions on which this feature/fix was tested

Learning

Describe the research phase and any blog posts, patterns, libraries, or add-ons you used to solve the problem.

Summary by CodeRabbit

  • New Features

    • Tree-based record field selector with search, expand/collapse, and "Select All" for choosing nested fields.
    • Form support for a record-field selection input type so editors can present the new selector.
  • Improvements

    • Checkboxes now support indeterminate state for partial selections.
    • Overlay/listener components accept custom styling via an sx prop.
  • API

    • Minor optional properties added to member metadata types.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Feb 18, 2026

📝 Walkthrough

Walkthrough

Adds a record-field selector feature: new type definitions, a DependentTypeEditor React component for hierarchical record-field selection, EditorFactory routing for the new input type, and small UI toolkit enhancements (checkbox indeterminate and ClickAwayListener sx prop).

Changes

Cohort / File(s) Summary
Type System
workspaces/ballerina/ballerina-core/src/interfaces/bi.ts, workspaces/ballerina/ballerina-core/src/interfaces/extended-lang-client.ts
Adds RecordFieldSelectorType and RecordSelectorType, extends FormFieldInputType and InputType unions to include the new selector; Member gains optional selected? and typeName?.
Field Selection UI
workspaces/ballerina/ballerina-side-panel/src/components/editors/DependentTypeEditor.tsx, workspaces/ballerina/ballerina-side-panel/src/components/editors/EditorFactory.tsx
New DependentTypeEditor component implements a searchable, expandable checkbox tree with recursive selection, cycle guards, and form integration. EditorFactory routes RECORD_FIELD_SELECTOR + PARAM_FOR_TYPE_INFER to this editor.
UI Component Enhancements
workspaces/common-libs/ui-toolkit/src/components/CheckBoxGroup/CheckBoxGroup.tsx, workspaces/common-libs/ui-toolkit/src/components/ClickAwayListener/ClickAwayListener.tsx
CheckBox gains indeterminate support via ref and effect; ClickAwayListener accepts optional sx prop for inline styling.

Sequence Diagram

sequenceDiagram
    participant User
    participant DependentTypeEditor
    participant TypeResolver
    participant FormContext

    User->>DependentTypeEditor: Mount with RecordSelectorType value
    DependentTypeEditor->>TypeResolver: Resolve rootType and referencedTypes -> members
    TypeResolver-->>DependentTypeEditor: Return hierarchical members

    User->>DependentTypeEditor: Toggle field checkbox
    DependentTypeEditor->>DependentTypeEditor: toggleSelection (recursive, cycle-guarded)
    DependentTypeEditor->>DependentTypeEditor: compute indeterminate / full-selected states
    DependentTypeEditor->>FormContext: Sync updated selection payload
    FormContext-->>User: Form value updated
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

Suggested reviewers

  • hevayo
  • gigara
  • kanushka

Poem

🐰 I nibble fields from root to leaf,
Checkbox branches rustle—tick, tick, brief.
I guard the loops and cascade every click,
A tiny hop, selections spread quick.
Hooray—records bloom, tidy and neat! ✨

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Description check ⚠️ Warning The description is largely incomplete; it contains only the template structure with minimal content filled in (Purpose field shows '$ Subject' placeholder). Critical sections like Goals, Approach, User stories, Release note, Documentation, and test/security results are empty or contain only template prompts. Complete the required sections: provide concrete Goals, describe the Approach with UI screenshots/GIFs, add User stories, Release note, Documentation links, and document test environment and security checks.
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly summarizes the main change: syncing a release branch with a feature branch, which aligns with the commit history showing UI/editor functionality work.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feature/persist-improvements

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

🧹 Nitpick comments (3)
workspaces/ballerina/ballerina-side-panel/src/components/editors/DependentTypeEditor.tsx (3)

310-315: Mutable ref + forceUpdate is a recognized pattern, but consider documenting the rationale.

The "mutate ref then force re-render" pattern works but is non-obvious to future maintainers. A brief comment explaining why mutable data + forceUpdate was chosen over useState with immutable updates (presumably for performance with deep tree mutations) would help.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@workspaces/ballerina/ballerina-side-panel/src/components/editors/DependentTypeEditor.tsx`
around lines 310 - 315, The code uses a mutable ref plus a dummy state re-render
pattern (see forceUpdate, triggerUpdate, useState and syncToForm) which is
non-obvious to future readers; add a concise comment above the
useState/triggerUpdate block that explains the rationale (e.g., using a mutable
ref for in-place deep-tree updates for performance and calling triggerUpdate to
force a lightweight re-render and then syncToForm), mention any trade-offs and
that this is intentional (not a bug), and reference the mutable ref usage so
maintainers know why useState immutable updates were avoided.

274-276: Avoid as any — use the discriminated union type.

The recordSelectorEntry can be typed using RecordFieldSelectorType from the core interfaces instead of as any, which would provide type-safe access to recordSelectorType.

Proposed fix
+    import type { RecordFieldSelectorType } from "@wso2/ballerina-core";
+
     const recordSelectorEntry = field.types?.find(
-        (t: any) => t.fieldType === "RECORD_FIELD_SELECTOR"
-    ) as any;
-
-    const initialData = recordSelectorEntry?.recordSelectorType as RecordSelectorType | undefined;
+        (t): t is RecordFieldSelectorType => t.fieldType === "RECORD_FIELD_SELECTOR"
+    );
+
+    const initialData = recordSelectorEntry?.recordSelectorType;
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@workspaces/ballerina/ballerina-side-panel/src/components/editors/DependentTypeEditor.tsx`
around lines 274 - 276, The code uses a loose cast for recordSelectorEntry —
replace the `as any` with the proper discriminated-union type so TypeScript can
narrow the shape; locate the `recordSelectorEntry` assignment in
DependentTypeEditor (the find over `field.types` that checks `t.fieldType ===
"RECORD_FIELD_SELECTOR"`) and cast/annotate the result as
`RecordFieldSelectorType` (importing it from the core interfaces) so you can
safely access `recordSelectorType` without `any`.

291-295: syncToForm is called inside the effect but excluded from its dependency array.

The eslint-disable suppresses the warning, but this means the effect captures a stale closure of syncToForm if data, field, or setValue change between mount and the next render. Since the effect is intended as mount-only initialization, confirm that setValue and field are stable references at mount time.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@workspaces/ballerina/ballerina-side-panel/src/components/editors/DependentTypeEditor.tsx`
around lines 291 - 295, The effect calls register(field.key) and syncToForm()
but excludes syncToForm from dependencies, risking a stale closure; make
syncToForm stable (wrap it in useCallback capturing setValue and field) and then
include that memoized syncToForm in the useEffect dependency array (remove the
eslint-disable). Ensure the useCallback for syncToForm references only stable
values (e.g., setValue and field.key) so the effect remains effectively
mount-only while avoiding stale closures.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In
`@workspaces/ballerina/ballerina-side-panel/src/components/editors/DependentTypeEditor.tsx`:
- Around line 358-360: The current filter on members in DependentTypeEditor.tsx
only keeps FIELD members whose own name matches search, so children that match
while their parent does not are dropped; update the filter logic to perform a
hierarchical match: implement a helper (e.g., memberMatchesSearch(member,
search) or hasDescendantMatch(member, search)) that returns true if the member's
name matches OR any descendant's name matches recursively, and use that helper
in place of the second .filter to ensure parents are kept when any nested child
matches the search term.
- Around line 383-392: The TypeTag currently renders even when m?.typeName is
undefined, producing an empty styled badge; update the JSX in
DependentTypeEditor to conditionally render the TypeTag only when m.typeName is
present (or render a small fallback string like "-" if you prefer), leaving the
CheckBox, FieldLabel, and their handlers (handleToggleField, m.name,
selected/isRequired/isPartial) unchanged so the layout and click behavior remain
consistent.

---

Nitpick comments:
In
`@workspaces/ballerina/ballerina-side-panel/src/components/editors/DependentTypeEditor.tsx`:
- Around line 310-315: The code uses a mutable ref plus a dummy state re-render
pattern (see forceUpdate, triggerUpdate, useState and syncToForm) which is
non-obvious to future readers; add a concise comment above the
useState/triggerUpdate block that explains the rationale (e.g., using a mutable
ref for in-place deep-tree updates for performance and calling triggerUpdate to
force a lightweight re-render and then syncToForm), mention any trade-offs and
that this is intentional (not a bug), and reference the mutable ref usage so
maintainers know why useState immutable updates were avoided.
- Around line 274-276: The code uses a loose cast for recordSelectorEntry —
replace the `as any` with the proper discriminated-union type so TypeScript can
narrow the shape; locate the `recordSelectorEntry` assignment in
DependentTypeEditor (the find over `field.types` that checks `t.fieldType ===
"RECORD_FIELD_SELECTOR"`) and cast/annotate the result as
`RecordFieldSelectorType` (importing it from the core interfaces) so you can
safely access `recordSelectorType` without `any`.
- Around line 291-295: The effect calls register(field.key) and syncToForm() but
excludes syncToForm from dependencies, risking a stale closure; make syncToForm
stable (wrap it in useCallback capturing setValue and field) and then include
that memoized syncToForm in the useEffect dependency array (remove the
eslint-disable). Ensure the useCallback for syncToForm references only stable
values (e.g., setValue and field.key) so the effect remains effectively
mount-only while avoiding stale closures.

Comment on lines +358 to +360
return members
.filter(m => m.kind === "FIELD" && m.name)
.filter(m => !search || m.name!.toLowerCase().includes(search.toLowerCase()))
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Search filter doesn't propagate to nested children.

The search filter on line 360 only matches immediate members by name. If a child field matches the search term but its parent does not, the child will be invisible because the parent is filtered out first. This is a common tree-search limitation.

If hierarchical search is expected (show parent when child matches), this needs adjustment to check descendants recursively before filtering.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@workspaces/ballerina/ballerina-side-panel/src/components/editors/DependentTypeEditor.tsx`
around lines 358 - 360, The current filter on members in DependentTypeEditor.tsx
only keeps FIELD members whose own name matches search, so children that match
while their parent does not are dropped; update the filter logic to perform a
hierarchical match: implement a helper (e.g., memberMatchesSearch(member,
search) or hasDescendantMatch(member, search)) that returns true if the member's
name matches OR any descendant's name matches recursively, and use that helper
in place of the second .filter to ensure parents are kept when any nested child
matches the search term.

Comment on lines +383 to +392
<CheckBox
label=""
checked={m.selected || isRequired}
indeterminate={isPartial}
disabled={isRequired}
onChange={() => handleToggleField(m)}
/>

<FieldLabel onClick={() => handleToggleField(m)}>{m.name}</FieldLabel>
<TypeTag>{m?.typeName}</TypeTag>
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Empty TypeTag rendered when typeName is undefined.

Line 392 renders <TypeTag>{m?.typeName}</TypeTag> unconditionally. When typeName is undefined, this renders an empty styled badge (with background color and padding but no text).

Proposed fix
-                            <TypeTag>{m?.typeName}</TypeTag>
+                            {m?.typeName && <TypeTag>{m.typeName}</TypeTag>}
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
<CheckBox
label=""
checked={m.selected || isRequired}
indeterminate={isPartial}
disabled={isRequired}
onChange={() => handleToggleField(m)}
/>
<FieldLabel onClick={() => handleToggleField(m)}>{m.name}</FieldLabel>
<TypeTag>{m?.typeName}</TypeTag>
<CheckBox
label=""
checked={m.selected || isRequired}
indeterminate={isPartial}
disabled={isRequired}
onChange={() => handleToggleField(m)}
/>
<FieldLabel onClick={() => handleToggleField(m)}>{m.name}</FieldLabel>
{m?.typeName && <TypeTag>{m.typeName}</TypeTag>}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@workspaces/ballerina/ballerina-side-panel/src/components/editors/DependentTypeEditor.tsx`
around lines 383 - 392, The TypeTag currently renders even when m?.typeName is
undefined, producing an empty styled badge; update the JSX in
DependentTypeEditor to conditionally render the TypeTag only when m.typeName is
present (or render a small fallback string like "-" if you prefer), leaving the
CheckBox, FieldLabel, and their handlers (handleToggleField, m.name,
selected/isRequired/isPartial) unchanged so the layout and click behavior remain
consistent.

@sachiniSam sachiniSam requested a review from kanushka February 19, 2026 08:28
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: 2

🧹 Nitpick comments (1)
workspaces/ballerina/ballerina-side-panel/src/components/editors/DependentTypeEditor.tsx (1)

326-329: dataRef is never re-initialized if field changes after mount.

The guard if (!dataRef.current && initialData) at lines 326–328 ensures the clone is created only once. If the parent re-renders the component with a different field, the ref keeps the original snapshot. Although the component likely renders one field per form, adding a defensive reset mechanism would make the invariant explicit and prevent silent staleness.

The useEffect watches field.key but doesn't reset dataRef, so the component lacks proper lifecycle handling. Either track field identity with prevFieldKeyRef to clear the ref on change, or add key={field.key} at the usage site so React remounts the component when field identity changes.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@workspaces/ballerina/ballerina-side-panel/src/components/editors/DependentTypeEditor.tsx`
around lines 326 - 329, dataRef is only initialized once and will hold a stale
snapshot when the parent passes a different field; update the component to
reset/re-initialize dataRef when the field identity changes by watching
field.key (the same value used in the existing useEffect) and clearing or
re-cloning initialData into dataRef.current; implement this by adding a
useEffect that compares field.key (or tracks prevFieldKeyRef) and sets
dataRef.current = undefined (or = JSON.parse(JSON.stringify(initialData))) when
the key changes, or alternatively ensure the component is remounted by adding
key={field.key} where the editor is used.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In
`@workspaces/ballerina/ballerina-side-panel/src/components/editors/DependentTypeEditor.tsx`:
- Around line 155-181: The cycle-guard bug is that hasPartialSelection (and
renderTree) build newVisited (adding member.refs[0]) but then call
resolveChildren with the old visited set, so self-referential types bypass the
guard; fix by passing the updated set (newVisited) into resolveChildren instead
of visited, ensuring resolveChildren sees the added ref for cycle detection —
update calls in hasPartialSelection (and the analogous call in renderTree) to
use newVisited when resolving children.
- Around line 489-497: The render uses rootType.members directly while other
functions (e.g., handleSelectAll) guard against missing members; to fix,
normalize and guard members once (e.g., compute a validated members array from
rootType like const members = rootType?.members || []) and use that variable in
the JSX and calls to renderTree, areAllSelected, and any other places (instead
of rootType.members), and/or add a short early return when rootType or
rootType.members is falsy so renderTree and TreeContainer never receive
undefined.

---

Duplicate comments:
In
`@workspaces/ballerina/ballerina-side-panel/src/components/editors/DependentTypeEditor.tsx`:
- Line 444: The TypeTag badge is rendered even when m?.typeName is undefined,
producing an empty badge; update the JSX in DependentTypeEditor (the <TypeTag>
usage showing <TypeTag>{m?.typeName}</TypeTag>) to render the TypeTag only when
m?.typeName is a non-empty string (e.g., guard with a conditional or &&) so that
no empty styled badge is output when typeName is undefined or empty.
- Around line 410-412: The current filter on members (in
DependentTypeEditor.tsx) only checks m.name for matches and thus hides matching
descendant members when their parent doesn't match; modify the predicate to
perform a recursive/recursive-like check that returns true if the member's name
matches OR any descendant matches. Create/use a helper (e.g.,
memberMatchesRecursive(member, search)) that walks child collections (e.g.,
m.children or m.members) and checks names case-insensitively, then replace the
current .filter(...) with one that calls that helper so parents are kept when
any child matches.

---

Nitpick comments:
In
`@workspaces/ballerina/ballerina-side-panel/src/components/editors/DependentTypeEditor.tsx`:
- Around line 326-329: dataRef is only initialized once and will hold a stale
snapshot when the parent passes a different field; update the component to
reset/re-initialize dataRef when the field identity changes by watching
field.key (the same value used in the existing useEffect) and clearing or
re-cloning initialData into dataRef.current; implement this by adding a
useEffect that compares field.key (or tracks prevFieldKeyRef) and sets
dataRef.current = undefined (or = JSON.parse(JSON.stringify(initialData))) when
the key changes, or alternatively ensure the component is remounted by adding
key={field.key} where the editor is used.

Comment on lines +489 to +497
label=""
checked={areAllSelected(rootType.members, referencedTypes)}
onChange={handleSelectAll}
/>
<SelectAllText>Select All Fields</SelectAllText>
</SelectAllRow>

<TreeContainer>
{renderTree(rootType.members, "", 0)}
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

🧩 Analysis chain

🏁 Script executed:

git ls-files | grep -i dependenttypeeditor

Repository: wso2/vscode-extensions

Length of output: 154


🏁 Script executed:

find . -name "DependentTypeEditor.tsx" -o -name "DependentTypeEditor.ts"

Repository: wso2/vscode-extensions

Length of output: 156


🏁 Script executed:

# Check the file contents around the suspected lines
cat -n workspaces/ballerina/ballerina-side-panel/src/components/editors/DependentTypeEditor.tsx | head -n 500 | tail -n 100

Repository: wso2/vscode-extensions

Length of output: 4591


🏁 Script executed:

# Find Type definition to check if members is optional
rg -n "interface Type|type Type" --type ts

Repository: wso2/vscode-extensions

Length of output: 9093


🏁 Script executed:

# Check the resolveChildren and handleSelectAll functions referenced in the review
rg -n "resolveChildren|handleSelectAll" workspaces/ballerina/ballerina-side-panel/src/components/editors/DependentTypeEditor.tsx

Repository: wso2/vscode-extensions

Length of output: 664


🏁 Script executed:

cat -n workspaces/ballerina/ballerina-core/src/interfaces/extended-lang-client.ts | sed -n '1439,1460p'

Repository: wso2/vscode-extensions

Length of output: 787


🏁 Script executed:

# Get more context around Type interface
cat -n workspaces/ballerina/ballerina-core/src/interfaces/extended-lang-client.ts | sed -n '1439,1500p'

Repository: wso2/vscode-extensions

Length of output: 2092


🏁 Script executed:

# Also check the Member interface referenced in renderTree
rg -n "interface Member" --type ts

Repository: wso2/vscode-extensions

Length of output: 270


🏁 Script executed:

# Look for areAllSelected function to understand its expectations
rg -n "areAllSelected" workspaces/ballerina/ballerina-side-panel/src/components/editors/DependentTypeEditor.tsx -B3 -A8

Repository: wso2/vscode-extensions

Length of output: 1903


🏁 Script executed:

cat -n workspaces/ballerina/ballerina-side-panel/src/components/editors/DependentTypeEditor.tsx | sed -n '37,60p'

Repository: wso2/vscode-extensions

Length of output: 1246


🏁 Script executed:

# View more of resolveChildren context
cat -n workspaces/ballerina/ballerina-side-panel/src/components/editors/DependentTypeEditor.tsx | sed -n '1,100p'

Repository: wso2/vscode-extensions

Length of output: 4464


Inconsistent handling of rootType.members — add guard for consistency.

The code inconsistently handles rootType.members:

  • Line 383 (handleSelectAll): guards with if (!rootType?.members) return;
  • Lines 490 and 497 (main render): directly use rootType.members without checking

Although Type.members is typed as required (members: Member[]), the defensive checks throughout the codebase (e.g., line 51 in resolveChildren: if (!typeObj.members) return []) suggest members can be undefined in practice.

To align with the guard at line 383 and prevent potential crashes if a Type object lacks members:

     if (!rootType) {
         return ( /* error UI */ );
     }
+
+    if (!rootType.members) {
+        return ( /* error UI */ );
+    }

Or consolidate the check before use and reference a validated variable:

-    if (!rootType) {
+    if (!rootType?.members) {
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@workspaces/ballerina/ballerina-side-panel/src/components/editors/DependentTypeEditor.tsx`
around lines 489 - 497, The render uses rootType.members directly while other
functions (e.g., handleSelectAll) guard against missing members; to fix,
normalize and guard members once (e.g., compute a validated members array from
rootType like const members = rootType?.members || []) and use that variable in
the JSX and calls to renderTree, areAllSelected, and any other places (instead
of rootType.members), and/or add a short early return when rootType or
rootType.members is falsy so renderTree and TreeContainer never receive
undefined.

@sachiniSam sachiniSam merged commit b35229e into release/bi-1.8.x Feb 19, 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