Skip to content

Conversation

@KCSAbeywickrama
Copy link
Contributor

@KCSAbeywickrama KCSAbeywickrama commented Nov 13, 2025

Purpose

Resolve wso2/product-ballerina-integrator#1792

Summary by CodeRabbit

Release Notes

  • New Features

    • Added JOIN clause support for relational data operations
    • Introduced dedicated code completion suggestions for the data mapper editor
  • Improvements

    • Enhanced data mapper field metadata to support structured data annotations
    • Refined expression completion handling for improved accuracy in form generation

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

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Nov 13, 2025

Note

Other AI code review bot(s) detected

CodeRabbit has detected other AI code review bot(s) in this pull request and will avoid duplicating their findings in the review comments. This may lead to a less comprehensive review.

Walkthrough

Adds a dedicated getDataMapperCompletions RPC endpoint throughout the stack for data mapper expression editors, extending core type definitions to support join operations and structured metadata in form fields via a new codedata property.

Changes

Cohort / File(s) Summary
Core Type Definitions
workspaces/ballerina/ballerina-core/src/interfaces/data-mapper.ts
Extended IntermediateClauseType with JOIN member; added focusInputRootMap to ExpandedDMModel and DMModel; added traversingRoot to DMModel; extended IntermediateClauseProps with lhsExpression, rhsExpression, isOuter; added codedata property to DMFormField; removed focusedMemberId from IOType.
RPC Type Layer
workspaces/ballerina/ballerina-core/src/rpc-types/bi-diagram/index.ts, workspaces/ballerina/ballerina-core/src/rpc-types/bi-diagram/rpc-type.ts
Added getDataMapperCompletions method to BIDiagramAPI interface and exported RequestType constant with same signature as getExpressionCompletions.
Extended Language Client
workspaces/ballerina/ballerina-extension/src/core/extended-language-client.ts
Added BI_DATA_MAPPER_COMPLETIONS to EXTENDED_APIS enum; renamed DATA_MAPPER_PROPERTY key from 'dataMapper/fieldPosition' to 'dataMapper/targetFieldPosition'; added async getDataMapperCompletions() method to ExtendedLangClient.
RPC Manager Layer
workspaces/ballerina/ballerina-extension/src/rpc-managers/bi-diagram/rpc-handler.ts, workspaces/ballerina/ballerina-extension/src/rpc-managers/bi-diagram/rpc-manager.ts, workspaces/ballerina/ballerina-rpc-client/src/rpc-clients/bi-diagram/rpc-client.ts
Imported and registered getDataMapperCompletions handler; added async getDataMapperCompletions() method to BiDiagramRpcManager; added getDataMapperCompletions() method to BiDiagramRpcClient with messenger delegation.
UI Components
workspaces/ballerina/ballerina-visualizer/src/views/BI/Forms/FormGeneratorNew/index.tsx, workspaces/ballerina/ballerina-visualizer/src/views/DataMapper/DataMapperView.tsx
Added isDataMapperEditor?: boolean prop to FormProps; imported completion request/response types; branched completion logic to call getDataMapperCompletions when isDataMapperEditor is true, else getExpressionCompletions; updated DataMapperView to pass targetLineRange and use property.codedata.lineRange instead of codedata.lineRange.

Sequence Diagram

sequenceDiagram
    participant UI as FormGeneratorNew
    participant Client as BiDiagramRpcClient
    participant Manager as BiDiagramRpcManager
    participant ExtLang as ExtendedLangClient
    participant LS as Language Server

    rect rgb(240, 248, 255)
        Note over UI: isDataMapperEditor = true
        UI->>Client: getDataMapperCompletions(params)
    end
    
    rect rgb(255, 250, 240)
        Note over UI: isDataMapperEditor = false
        UI->>Client: getExpressionCompletions(params)
    end

    Client->>Manager: messenger.request()
    Manager->>ExtLang: getDataMapperCompletions(params)
    ExtLang->>LS: /expressionEditor/dataMapperCompletion
    LS-->>ExtLang: ExpressionCompletionsResponse
    ExtLang-->>Manager: response
    Manager-->>Client: response
    Client-->>UI: CompletionItem[]
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

  • Context payload change: DataMapperView passes property directly instead of spread with valueType; verify the context structure aligns across components
  • LineRange handling: Confirm property.codedata.lineRange vs. codedata.lineRange distinction is correctly applied in both view components
  • Prop threading: Verify isDataMapperEditor prop is correctly propagated from DataMapperView through FormGeneratorNew to the completion branching logic
  • Property key rename: Validate 'dataMapper/fieldPosition''dataMapper/targetFieldPosition' doesn't break upstream consumers

Possibly related PRs

Suggested reviewers

  • hevayo
  • gigara
  • kanushka

Poem

🐰 A mapper's joy, at last complete,
New completions make the flow so sweet!
Joins and focus, tracked with care,
Codedata fields beyond compare. 🎯
The editor blooms, contexts aligned,
Better expressions, finally designed!

Pre-merge checks and finishing touches

❌ Failed checks (2 warnings, 1 inconclusive)
Check name Status Explanation Resolution
Description check ⚠️ Warning The PR description is minimal, containing only the linked issue reference but missing critical sections from the template including Goals, Approach, UI Component Development, and other required documentation. Expand the description to include Goals, Approach, and other relevant template sections to document the implementation details and rationale for the changes.
Docstring Coverage ⚠️ Warning Docstring coverage is 11.11% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
Out of Scope Changes check ❓ Inconclusive Changes are scoped to completion support improvements. However, the removal of focusedMemberId from IOType and data model refactoring (traversingRoot, focusInputRootMap) appear tangential to the stated objective of cursor position handling. Clarify whether IOType removal and data model changes are necessary for the completion cursor position feature or if they should be separated into a different PR.
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The PR title clearly summarizes the main change: introducing frontend improvements for data mapper completion support in the expression bar.
Linked Issues check ✅ Passed The PR implements the required objective from issue #1792 by updating completion support with correct cursor position handling through new getDataMapperCompletions endpoints and targetLineRange propagation.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

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.

@KCSAbeywickrama KCSAbeywickrama changed the title [BI Data Mapper] Improve completion support [BI Data Mapper] Improve completion support - frontend changes for expression bar Nov 17, 2025
@KCSAbeywickrama KCSAbeywickrama marked this pull request as ready for review November 17, 2025 11:22
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: 8

🧹 Nitpick comments (9)
workspaces/ballerina/ballerina-extension/src/rpc-managers/data-mapper/utils.ts (1)

470-472: Consider initializing focusInputRootMap before conditional processing.

When processInputs is false, the model.focusInputRootMap might be undefined since it's only initialized inside processInputRoots (line 490). While this may be acceptable if the type allows undefined, consider initializing it at the start of expandDMModel to ensure consistency.

Consider applying this diff:

 ): ExpandedDMModel {
     const {
         processInputs = true,
         processOutput = true,
         processSubMappings = true,
         previousModel
     } = options;
 
+    // Initialize focusInputRootMap if not already present
+    if (!model.focusInputRootMap) {
+        model.focusInputRootMap = {};
+    }
+
     return {
         inputs: processInputs
             ? processInputRoots(model)
workspaces/ballerina/data-mapper/src/components/DataMapper/SidePanel/QueryClauses/ClausesPanel.tsx (1)

84-84: Consider documenting the width increase rationale.

The side panel width increased from 312 to 400 pixels. While this likely accommodates JOIN clause UI elements, consider whether this is the optimal width or if it should be configurable.

workspaces/ballerina/ballerina-visualizer/src/views/BI/Forms/FormGeneratorNew/index.tsx (1)

460-465: Clarify the default behavior when isDataMapperEditor is undefined.

The conditional logic branches on !isDataMapperEditor to choose between getExpressionCompletions and getDataMapperCompletions. When isDataMapperEditor is undefined, it will call getExpressionCompletions (since !undefined is true).

Consider making this behavior explicit for clarity:

-                    if (!isDataMapperEditor) {
-                        completions = await rpcClient.getBIDiagramRpcClient().getExpressionCompletions(completionRequest);
-                    } else {
-                        completions = await rpcClient.getBIDiagramRpcClient().getDataMapperCompletions(completionRequest);
-                    }
+                    if (isDataMapperEditor) {
+                        completions = await rpcClient.getBIDiagramRpcClient().getDataMapperCompletions(completionRequest);
+                    } else {
+                        completions = await rpcClient.getBIDiagramRpcClient().getExpressionCompletions(completionRequest);
+                    }
workspaces/ballerina/data-mapper/src/components/DataMapper/SidePanel/QueryClauses/ClauseEditor.tsx (3)

34-38: Store access via getState() is fine for initial data, but won’t react to later changes

Using useDMQueryClausesPanelStore.getState() to read { clauseToAdd, setClauseToAdd } is adequate if ClauseEditor is only ever mounted after the store has been primed (e.g., by mapWithJoin) and you just need initial values.

If you ever need ClauseEditor to react to subsequent clauseToAdd changes while it’s open (for example, reusing the same component instance for different clauses), you’ll want to switch to the hook form:

const { clauseToAdd, setClauseToAdd } = useDMQueryClausesPanelStore();

so it subscribes to store updates.


98-120: JOIN-on fields are wired correctly; consider pre-populating or validating later

The new lhsExpressionField/rhsExpressionField for JOIN-on conditions are configured as non-optional in the form while defaulting to empty strings. That’s reasonable for a first iteration.

At some point, you may want to:

  • Pre-populate one side (typically LHS) from the source field when invoked from a link, or
  • Add minimal validation on submit to prevent empty join-on conditions.

Not a blocker for this PR; the basics are in place.


122-163: JOIN submit normalization aligns with core types but may constrain future outer-join support

handleSubmit clearing clauseToAdd and building:

const clause: IntermediateClause = {
    type: clauseType as IntermediateClauseType,
    properties: data as IntermediateClauseProps
};
if (clauseType === IntermediateClauseType.JOIN) {
    clause.properties.type = "var";
    clause.properties.isOuter = false;
}

is consistent with the updated IntermediateClauseProps (mandatory expression, optional isOuter, etc.) and the ClauseEditor form, where JOIN does not render a type field.

For future outer-join support, you’ll likely want to:

  • Add an isOuter checkbox/select to the JOIN form, and
  • Stop hard-coding isOuter = false so user input isn’t overridden.

For now, this is fine and clearly captures “inner join” semantics.

workspaces/ballerina/data-mapper/src/components/Diagram/utils/modification-utils.ts (1)

179-202: mapWithJoin correctly seeds the JOIN clause; consider minor hardening

The new mapWithJoin:

  • Validates the presence of a source port.
  • Derives a default JOIN clause with:
    • name: <fieldName>Item
    • type: "var"
    • expression: fieldFQN
    • isOuter: false
    • lhsExpression/rhsExpression: ""
  • Opens the query clauses panel via the shared store.

This lines up with the updated IntermediateClause/IntermediateClauseProps and the new JOIN handling in ClauseEditor.

Two minor robustness tweaks to consider (non-blocking):

  • Guard against missing field metadata on the port to avoid runtime errors in unusual cases:
const field = sourcePortModel.attributes.field;
if (!field) {
    return;
}
setClauseToAdd({
    // ...
    properties: {
        name: field.name + "Item",
        expression: sourcePortModel.attributes.fieldFQN,
        // ...
    }
});
  • In future, you might pre-populate at least one of lhsExpression/rhsExpression to a sensible default based on the current mapping context to reduce user effort.
workspaces/ballerina/ballerina-visualizer/src/views/DataMapper/DataMapperView.tsx (1)

575-617: Completion request now carries accurate cursor and location context

The updated debounced retrieveCompeletions:

  • Extracts lineOffset/charOffset via calculateExpressionOffsets(value, cursorPosition).
  • Derives startLine from property.codedata.lineRange and expressionOffsetRef using updateLineRange, which lets you account for imports or other edits shifting the expression.
  • Calls getDataMapperCompletions with a context that includes:
    • The full expression,
    • startLine, lineOffset, and offset,
    • The current viewState.codedata,
    • The resolved property from getProperty.

This is exactly the kind of richer context needed to get correct cursor-relative completions for the expression bar and integrates cleanly with the new BI diagram completions API.

One thing to keep an eye on: property.codedata is assumed to be non-null here. If the backend ever returns a property without codedata, this would throw. If that’s a realistic scenario, a defensive early return when !property.codedata could be added later.

workspaces/ballerina/data-mapper/src/components/Diagram/Diagram.tsx (1)

39-40: ClauseConnectorNode integration into the diagram engine looks correct

Including ClauseConnectorNode in the node imports, factory registration, and the repositioning pass (filtering by instanceof and using targetMappedPort for coordinates) is consistent with how LinkConnectorNode and QueryExprConnectorNode are handled. This should keep clause connectors aligned with their target output ports without changing existing behavior.

If you later refactor positioning, it might be worth centralizing this into a shared helper (e.g., a polymorphic updatePosition on connector nodes) instead of hard‑coding offsets in the effect, but not required for this PR.

Also applies to: 82-91, 157-165

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 95c93ef and 7bb63bd.

📒 Files selected for processing (43)
  • workspaces/ballerina/ballerina-core/src/interfaces/data-mapper.ts (5 hunks)
  • workspaces/ballerina/ballerina-core/src/rpc-types/bi-diagram/index.ts (1 hunks)
  • workspaces/ballerina/ballerina-core/src/rpc-types/bi-diagram/rpc-type.ts (1 hunks)
  • workspaces/ballerina/ballerina-extension/src/core/extended-language-client.ts (3 hunks)
  • workspaces/ballerina/ballerina-extension/src/rpc-managers/bi-diagram/rpc-handler.ts (2 hunks)
  • workspaces/ballerina/ballerina-extension/src/rpc-managers/bi-diagram/rpc-manager.ts (2 hunks)
  • workspaces/ballerina/ballerina-extension/src/rpc-managers/data-mapper/utils.ts (3 hunks)
  • workspaces/ballerina/ballerina-rpc-client/src/rpc-clients/bi-diagram/rpc-client.ts (2 hunks)
  • workspaces/ballerina/ballerina-visualizer/src/views/BI/Forms/FormGeneratorNew/index.tsx (5 hunks)
  • workspaces/ballerina/ballerina-visualizer/src/views/DataMapper/DataMapperView.tsx (3 hunks)
  • workspaces/ballerina/data-mapper/src/components/DataMapper/DataMapperEditor.tsx (2 hunks)
  • workspaces/ballerina/data-mapper/src/components/DataMapper/SidePanel/QueryClauses/ClauseEditor.tsx (6 hunks)
  • workspaces/ballerina/data-mapper/src/components/DataMapper/SidePanel/QueryClauses/ClausesPanel.tsx (3 hunks)
  • workspaces/ballerina/data-mapper/src/components/DataMapper/Views/DataMapperView.ts (1 hunks)
  • workspaces/ballerina/data-mapper/src/components/Diagram/Actions/IONodesScrollCanvasAction.ts (2 hunks)
  • workspaces/ballerina/data-mapper/src/components/Diagram/Actions/utils.ts (2 hunks)
  • workspaces/ballerina/data-mapper/src/components/Diagram/Diagram.tsx (3 hunks)
  • workspaces/ballerina/data-mapper/src/components/Diagram/Label/ExpressionLabelFactory.tsx (2 hunks)
  • workspaces/ballerina/data-mapper/src/components/Diagram/Label/ExpressionLabelModel.ts (0 hunks)
  • workspaces/ballerina/data-mapper/src/components/Diagram/Label/QueryExprLabelWidget.tsx (0 hunks)
  • workspaces/ballerina/data-mapper/src/components/Diagram/Link/DataMapperLink/DataMapperLink.ts (1 hunks)
  • workspaces/ballerina/data-mapper/src/components/Diagram/LinkState/CreateLinkState.ts (4 hunks)
  • workspaces/ballerina/data-mapper/src/components/Diagram/Node/ClauseConnector/ClauseConnectorNode.ts (1 hunks)
  • workspaces/ballerina/data-mapper/src/components/Diagram/Node/ClauseConnector/ClauseConnectorNodeFactory.tsx (1 hunks)
  • workspaces/ballerina/data-mapper/src/components/Diagram/Node/ClauseConnector/ClauseConnectorNodeWidget.tsx (1 hunks)
  • workspaces/ballerina/data-mapper/src/components/Diagram/Node/ClauseConnector/index.ts (1 hunks)
  • workspaces/ballerina/data-mapper/src/components/Diagram/Node/Input/InputNode.ts (1 hunks)
  • workspaces/ballerina/data-mapper/src/components/Diagram/Node/QueryExprConnector/QueryExprConnectorNodeWidget.tsx (1 hunks)
  • workspaces/ballerina/data-mapper/src/components/Diagram/Node/QueryOutput/QueryOutputNode.ts (0 hunks)
  • workspaces/ballerina/data-mapper/src/components/Diagram/Node/commons/DataMapperNode.ts (1 hunks)
  • workspaces/ballerina/data-mapper/src/components/Diagram/Node/index.ts (1 hunks)
  • workspaces/ballerina/data-mapper/src/components/Diagram/Port/model/InputOutputPortModel.ts (2 hunks)
  • workspaces/ballerina/data-mapper/src/components/Diagram/hooks/useDiagramModel.ts (2 hunks)
  • workspaces/ballerina/data-mapper/src/components/Diagram/utils/common-utils.ts (3 hunks)
  • workspaces/ballerina/data-mapper/src/components/Diagram/utils/focus-positioning-utils.ts (2 hunks)
  • workspaces/ballerina/data-mapper/src/components/Diagram/utils/modification-utils.ts (2 hunks)
  • workspaces/ballerina/data-mapper/src/components/Diagram/utils/node-utils.ts (1 hunks)
  • workspaces/ballerina/data-mapper/src/components/Diagram/utils/port-utils.ts (1 hunks)
  • workspaces/ballerina/data-mapper/src/store/store.ts (2 hunks)
  • workspaces/ballerina/data-mapper/src/utils/DataMapperContext/DataMapperContext.ts (2 hunks)
  • workspaces/ballerina/data-mapper/src/utils/model-utils.ts (3 hunks)
  • workspaces/ballerina/data-mapper/src/visitors/BaseVisitor.ts (2 hunks)
  • workspaces/ballerina/data-mapper/src/visitors/IntermediateNodeInitVisitor.ts (2 hunks)
💤 Files with no reviewable changes (3)
  • workspaces/ballerina/data-mapper/src/components/Diagram/Label/QueryExprLabelWidget.tsx
  • workspaces/ballerina/data-mapper/src/components/Diagram/Label/ExpressionLabelModel.ts
  • workspaces/ballerina/data-mapper/src/components/Diagram/Node/QueryOutput/QueryOutputNode.ts
🧰 Additional context used
🧠 Learnings (2)
📚 Learning: 2025-11-10T15:05:11.309Z
Learnt from: madushajg
Repo: wso2/vscode-extensions PR: 868
File: workspaces/bi/bi-extension/src/utils.ts:224-242
Timestamp: 2025-11-10T15:05:11.309Z
Learning: The workspaces/bi/bi-extension and workspaces/ballerina/ballerina-extension are separate VS Code extensions that are packaged and distributed independently, so they cannot share code via imports and must maintain their own implementations of common utilities.

Applied to files:

  • workspaces/ballerina/ballerina-extension/src/core/extended-language-client.ts
📚 Learning: 2025-11-10T15:04:50.474Z
Learnt from: madushajg
Repo: wso2/vscode-extensions PR: 868
File: workspaces/bi/bi-extension/src/utils.ts:153-169
Timestamp: 2025-11-10T15:04:50.474Z
Learning: The workspaces/bi/bi-extension and workspaces/ballerina/ballerina-extension are separate, independently deployable VSCode extensions in the wso2/vscode-extensions repository. Code duplication between these extensions is acceptable and often necessary to maintain their independence, rather than creating cross-extension dependencies.

Applied to files:

  • workspaces/ballerina/ballerina-extension/src/core/extended-language-client.ts
🧬 Code graph analysis (30)
workspaces/ballerina/ballerina-core/src/rpc-types/bi-diagram/rpc-type.ts (4)
workspaces/ballerina/ballerina-extension/src/core/extended-language-client.ts (1)
  • getDataMapperCompletions (1127-1129)
workspaces/ballerina/ballerina-extension/src/rpc-managers/bi-diagram/rpc-manager.ts (1)
  • getDataMapperCompletions (856-867)
workspaces/ballerina/ballerina-rpc-client/src/rpc-clients/bi-diagram/rpc-client.ts (1)
  • getDataMapperCompletions (306-308)
workspaces/ballerina/ballerina-core/src/interfaces/extended-lang-client.ts (2)
  • ExpressionCompletionsRequest (1088-1095)
  • ExpressionCompletionsResponse (1112-1112)
workspaces/ballerina/data-mapper/src/components/Diagram/utils/port-utils.ts (2)
workspaces/ballerina/data-mapper/src/components/Diagram/Node/Input/InputNode.ts (1)
  • InputNode (29-160)
workspaces/ballerina/data-mapper/src/components/Diagram/Port/model/InputOutputPortModel.ts (1)
  • InputOutputPortModel (54-123)
workspaces/ballerina/data-mapper/src/components/Diagram/Node/ClauseConnector/ClauseConnectorNodeWidget.tsx (5)
workspaces/ballerina/data-mapper/src/components/Diagram/Node/ClauseConnector/ClauseConnectorNode.ts (1)
  • ClauseConnectorNode (36-187)
workspaces/ballerina/data-mapper/src/components/styles.ts (1)
  • useIntermediateNodeStyles (297-336)
workspaces/ballerina/data-mapper/src/store/store.ts (2)
  • useDMExpressionBarStore (135-161)
  • useDMQueryClausesPanelStore (171-180)
workspaces/ballerina/data-mapper/src/components/Diagram/Node/LinkConnector/LinkConnectorWidgetComponents.tsx (1)
  • renderPortWidget (26-32)
workspaces/common-libs/ui-toolkit/src/components/Codicon/Codicon.tsx (1)
  • Codicon (44-56)
workspaces/ballerina/data-mapper/src/components/Diagram/Node/QueryExprConnector/QueryExprConnectorNodeWidget.tsx (1)
workspaces/ballerina/data-mapper/src/components/Diagram/utils/common-utils.ts (1)
  • expandArrayFn (226-266)
workspaces/ballerina/data-mapper/src/components/Diagram/Node/ClauseConnector/ClauseConnectorNodeFactory.tsx (2)
workspaces/ballerina/data-mapper/src/components/Diagram/Node/ClauseConnector/ClauseConnectorNode.ts (2)
  • ClauseConnectorNode (36-187)
  • CLAUSE_CONNECTOR_NODE_TYPE (33-33)
workspaces/ballerina/data-mapper/src/components/Diagram/Node/ClauseConnector/ClauseConnectorNodeWidget.tsx (1)
  • ClauseConnectorNodeWidget (35-84)
workspaces/ballerina/data-mapper/src/store/store.ts (1)
workspaces/ballerina/ballerina-core/src/interfaces/data-mapper.ts (1)
  • IntermediateClause (216-219)
workspaces/ballerina/data-mapper/src/components/DataMapper/SidePanel/QueryClauses/ClausesPanel.tsx (1)
workspaces/ballerina/data-mapper/src/store/store.ts (1)
  • useDMQueryClausesPanelStore (171-180)
workspaces/ballerina/data-mapper/src/components/Diagram/Actions/utils.ts (1)
workspaces/ballerina/data-mapper/src/components/Diagram/Node/ClauseConnector/ClauseConnectorNode.ts (1)
  • ClauseConnectorNode (36-187)
workspaces/ballerina/ballerina-core/src/rpc-types/bi-diagram/index.ts (1)
workspaces/ballerina/ballerina-core/src/interfaces/extended-lang-client.ts (2)
  • ExpressionCompletionsRequest (1088-1095)
  • ExpressionCompletionsResponse (1112-1112)
workspaces/ballerina/data-mapper/src/components/Diagram/Diagram.tsx (1)
workspaces/ballerina/data-mapper/src/components/Diagram/Node/ClauseConnector/ClauseConnectorNode.ts (1)
  • ClauseConnectorNode (36-187)
workspaces/ballerina/ballerina-extension/src/rpc-managers/data-mapper/utils.ts (1)
workspaces/ballerina/ballerina-core/src/interfaces/data-mapper.ts (1)
  • DMModel (131-144)
workspaces/ballerina/data-mapper/src/components/Diagram/Actions/IONodesScrollCanvasAction.ts (1)
workspaces/ballerina/data-mapper/src/components/Diagram/Node/ClauseConnector/ClauseConnectorNode.ts (1)
  • ClauseConnectorNode (36-187)
workspaces/ballerina/ballerina-extension/src/rpc-managers/bi-diagram/rpc-manager.ts (2)
workspaces/ballerina/ballerina-core/src/interfaces/extended-lang-client.ts (2)
  • ExpressionCompletionsRequest (1088-1095)
  • ExpressionCompletionsResponse (1112-1112)
workspaces/ballerina/ballerina-extension/src/stateMachine.ts (1)
  • StateMachine (653-676)
workspaces/ballerina/ballerina-extension/src/rpc-managers/bi-diagram/rpc-handler.ts (5)
workspaces/ballerina/ballerina-extension/src/core/extended-language-client.ts (1)
  • getDataMapperCompletions (1127-1129)
workspaces/ballerina/ballerina-extension/src/rpc-managers/bi-diagram/rpc-manager.ts (1)
  • getDataMapperCompletions (856-867)
workspaces/ballerina/ballerina-core/src/rpc-types/bi-diagram/rpc-type.ts (1)
  • getDataMapperCompletions (152-152)
workspaces/ballerina/ballerina-rpc-client/src/rpc-clients/bi-diagram/rpc-client.ts (1)
  • getDataMapperCompletions (306-308)
workspaces/ballerina/ballerina-core/src/interfaces/extended-lang-client.ts (1)
  • ExpressionCompletionsRequest (1088-1095)
workspaces/ballerina/data-mapper/src/components/Diagram/LinkState/CreateLinkState.ts (2)
workspaces/ballerina/data-mapper/src/components/Diagram/Port/model/InputOutputPortModel.ts (1)
  • InputOutputPortModel (54-123)
workspaces/ballerina/data-mapper/src/components/Diagram/Node/ClauseConnector/ClauseConnectorNode.ts (1)
  • ClauseConnectorNode (36-187)
workspaces/ballerina/data-mapper/src/components/Diagram/utils/node-utils.ts (2)
workspaces/ballerina/data-mapper/src/components/DataMapper/Views/DataMapperView.ts (1)
  • View (18-23)
workspaces/ballerina/data-mapper/src/components/Diagram/Node/Input/InputNode.ts (1)
  • InputNode (29-160)
workspaces/ballerina/data-mapper/src/components/Diagram/Node/ClauseConnector/ClauseConnectorNode.ts (8)
workspaces/ballerina/data-mapper/src/components/Diagram/Port/model/InputOutputPortModel.ts (1)
  • InputOutputPortModel (54-123)
workspaces/ballerina/ballerina-core/src/interfaces/data-mapper.ts (1)
  • DMDiagnostic (70-83)
workspaces/ballerina/data-mapper/src/utils/DataMapperContext/DataMapperContext.ts (1)
  • IDataMapperContext (21-35)
workspaces/ballerina/data-mapper/src/store/store.ts (1)
  • useDMSearchStore (83-89)
workspaces/ballerina/data-mapper/src/components/Diagram/utils/node-utils.ts (1)
  • findInputNode (23-47)
workspaces/ballerina/data-mapper/src/components/Diagram/utils/port-utils.ts (2)
  • getInputPort (26-37)
  • getTargetPortPrefix (60-73)
workspaces/ballerina/data-mapper/src/components/Diagram/Node/QueryOutput/QueryOutputNode.ts (1)
  • QueryOutputNode (37-186)
workspaces/ballerina/data-mapper/src/components/Diagram/Link/DataMapperLink/DataMapperLink.ts (1)
  • DataMapperLinkModel (37-95)
workspaces/ballerina/data-mapper/src/components/DataMapper/SidePanel/QueryClauses/ClauseEditor.tsx (2)
workspaces/ballerina/data-mapper/src/store/store.ts (1)
  • useDMQueryClausesPanelStore (171-180)
workspaces/ballerina/ballerina-core/src/interfaces/data-mapper.ts (4)
  • DMFormField (260-272)
  • DMFormFieldValues (274-276)
  • IntermediateClause (216-219)
  • IntermediateClauseProps (206-214)
workspaces/ballerina/data-mapper/src/visitors/IntermediateNodeInitVisitor.ts (2)
workspaces/ballerina/ballerina-core/src/interfaces/data-mapper.ts (1)
  • Query (191-198)
workspaces/ballerina/data-mapper/src/components/Diagram/Node/ClauseConnector/ClauseConnectorNode.ts (1)
  • ClauseConnectorNode (36-187)
workspaces/ballerina/ballerina-extension/src/core/extended-language-client.ts (1)
workspaces/ballerina/ballerina-core/src/interfaces/extended-lang-client.ts (2)
  • ExpressionCompletionsRequest (1088-1095)
  • ExpressionCompletionsResponse (1112-1112)
workspaces/ballerina/data-mapper/src/components/Diagram/utils/focus-positioning-utils.ts (1)
workspaces/ballerina/data-mapper/src/components/Diagram/Node/ClauseConnector/ClauseConnectorNode.ts (1)
  • ClauseConnectorNode (36-187)
workspaces/ballerina/data-mapper/src/components/DataMapper/DataMapperEditor.tsx (1)
workspaces/ballerina/data-mapper/src/components/DataMapper/Views/DataMapperView.ts (1)
  • View (18-23)
workspaces/ballerina/data-mapper/src/visitors/BaseVisitor.ts (1)
workspaces/ballerina/ballerina-core/src/interfaces/data-mapper.ts (1)
  • ExpandedDMModel (118-129)
workspaces/ballerina/data-mapper/src/components/Diagram/utils/modification-utils.ts (3)
workspaces/ballerina/data-mapper/src/components/Diagram/utils/common-utils.ts (1)
  • expandArrayFn (226-266)
workspaces/ballerina/data-mapper/src/components/Diagram/Port/model/InputOutputPortModel.ts (1)
  • InputOutputPortModel (54-123)
workspaces/ballerina/data-mapper/src/store/store.ts (1)
  • useDMQueryClausesPanelStore (171-180)
workspaces/ballerina/ballerina-rpc-client/src/rpc-clients/bi-diagram/rpc-client.ts (4)
workspaces/ballerina/ballerina-core/src/interfaces/extended-lang-client.ts (2)
  • ExpressionCompletionsRequest (1088-1095)
  • ExpressionCompletionsResponse (1112-1112)
workspaces/ballerina/ballerina-extension/src/core/extended-language-client.ts (1)
  • getDataMapperCompletions (1127-1129)
workspaces/ballerina/ballerina-extension/src/rpc-managers/bi-diagram/rpc-manager.ts (1)
  • getDataMapperCompletions (856-867)
workspaces/ballerina/ballerina-core/src/rpc-types/bi-diagram/rpc-type.ts (1)
  • getDataMapperCompletions (152-152)
workspaces/ballerina/data-mapper/src/components/Diagram/Port/model/InputOutputPortModel.ts (1)
workspaces/ballerina/data-mapper/src/components/Diagram/utils/modification-utils.ts (1)
  • mapWithJoin (179-202)
workspaces/ballerina/data-mapper/src/components/Diagram/utils/common-utils.ts (1)
workspaces/ballerina/data-mapper/src/utils/DataMapperContext/DataMapperContext.ts (1)
  • IDataMapperContext (21-35)
workspaces/ballerina/data-mapper/src/utils/model-utils.ts (2)
workspaces/ballerina/ballerina-core/src/interfaces/data-mapper.ts (1)
  • ExpandedDMModel (118-129)
workspaces/ballerina/data-mapper/src/visitors/BaseVisitor.ts (1)
  • BaseVisitor (21-40)
workspaces/ballerina/ballerina-visualizer/src/views/DataMapper/DataMapperView.tsx (1)
workspaces/ballerina/ballerina-visualizer/src/utils/bi.tsx (1)
  • updateLineRange (538-557)
workspaces/ballerina/ballerina-visualizer/src/views/BI/Forms/FormGeneratorNew/index.tsx (1)
workspaces/ballerina/ballerina-core/src/interfaces/extended-lang-client.ts (2)
  • ExpressionCompletionsRequest (1088-1095)
  • ExpressionCompletionsResponse (1112-1112)
🔇 Additional comments (36)
workspaces/ballerina/ballerina-extension/src/rpc-managers/data-mapper/utils.ts (2)

490-500: LGTM! Clear tracking of input roots during traversal.

The initialization of focusInputRootMap followed by setting traversingRoot for each input provides a clean mechanism to track which root input is being processed. The shallow copy behavior ensures that mutations to focusInputRootMap are properly propagated.


609-611: LGTM! Correctly tracks focus input to root mapping.

The conditional check ensures traversingRoot is set before recording the mapping, and the logic correctly associates focused fields with their originating root input.

workspaces/ballerina/data-mapper/src/components/Diagram/hooks/useDiagramModel.ts (1)

103-104: LGTM - Dependency array correctly updated.

Adding queryIOs to the dependency array ensures the diagram model refetches when query inputs or outputs change, which aligns with the PR objective to improve completion support. This follows the established pattern used for other dependencies like mappings and subMappings.

Note: The correctness of this dependency relies on the proper serialization of queryIOs at line 50. Please address the concerns raised in the previous comment.

workspaces/ballerina/data-mapper/src/components/Diagram/Node/QueryExprConnector/QueryExprConnectorNodeWidget.tsx (1)

76-76: LGTM! Multi-input expansion now supported.

The change correctly passes the entire mapping.inputs array to expandArrayFn, aligning with its updated signature that accepts inputIds: string[]. This enables JOIN clause support by expanding based on multiple inputs.

workspaces/ballerina/data-mapper/src/components/DataMapper/DataMapperEditor.tsx (2)

153-153: Good addition of explicit type annotation.

Adding the View[] type annotation improves code clarity and type safety.


228-242: Constructor signature matches call site correctly.

The DataMapperContext constructor signature (lines 39-52 in workspaces/ballerina/data-mapper/src/utils/DataMapperContext/DataMapperContext.ts) shows that hasInputsOutputsChanged is at position 3, which matches the call site in DataMapperEditor.tsx. All 13 parameters are in the correct order.

workspaces/ballerina/data-mapper/src/components/Diagram/Node/ClauseConnector/index.ts (1)

18-20: LGTM! Standard barrel export pattern.

The file follows the standard barrel export pattern for aggregating public ClauseConnector module exports, consistent with other Node module exports in the codebase.

workspaces/ballerina/data-mapper/src/components/Diagram/Actions/IONodesScrollCanvasAction.ts (2)

30-30: LGTM! Import added for ClauseConnectorNode.

The import correctly adds ClauseConnectorNode to support the new intermediate node type in repositioning logic.


164-164: LGTM! Repositioning logic extended for ClauseConnectorNode.

The instanceof check now includes ClauseConnectorNode, ensuring it's repositioned consistently with other intermediate connector nodes when the output node scrolls.

workspaces/ballerina/data-mapper/src/components/Diagram/Actions/utils.ts (2)

28-29: LGTM! Imports updated for new node types.

The imports correctly add SubMappingNode and ClauseConnectorNode. Note that SubMappingNode is already part of the INPUT_NODES array on line 36.


48-49: LGTM! ClauseConnectorNode added to intermediate nodes.

The addition of ClauseConnectorNode to the INTERMEDIATE_NODES array properly extends the intermediate node handling, consistent with its role alongside LinkConnectorNode and QueryExprConnectorNode.

workspaces/ballerina/data-mapper/src/components/Diagram/Node/index.ts (1)

28-28: LGTM! ClauseConnector added to public API.

The export statement correctly adds ClauseConnector to the Node module's public API, consistent with the barrel export pattern used for other node types.

workspaces/ballerina/ballerina-extension/src/rpc-managers/bi-diagram/rpc-handler.ts (2)

76-76: LGTM! Import added for data mapper completions.

The import correctly adds getDataMapperCompletions to support the new data mapper-specific completions endpoint.


182-182: LGTM! RPC handler registered for data mapper completions.

The handler registration correctly wires getDataMapperCompletions requests to the RPC manager, following the same pattern as the existing getExpressionCompletions handler. This directly supports the PR objective to improve completion support for the expression bar.

workspaces/ballerina/data-mapper/src/components/Diagram/Link/DataMapperLink/DataMapperLink.ts (1)

31-31: LGTM! ArrayJoin mapping type added.

The ArrayJoin enum member correctly extends MappingType to support JOIN clause scenarios in the data mapper. This aligns with the broader JOIN support introduced in this PR.

workspaces/ballerina/data-mapper/src/components/Diagram/utils/focus-positioning-utils.ts (1)

20-20: LGTM! Consistent extension for ClauseConnectorNode support.

The addition of ClauseConnectorNode to the imports and type assertion follows the established pattern for intermediate nodes (LinkConnectorNode, QueryExprConnectorNode). The implementation correctly enables target node resolution through ClauseConnectorNode intermediates.

Also applies to: 160-160

workspaces/ballerina/data-mapper/src/components/Diagram/Port/model/InputOutputPortModel.ts (1)

78-80: LGTM! Proper handling for ArrayJoin mapping flow.

The special-case handling for MappingType.ArrayJoin correctly delegates to mapWithJoin() and returns early to prevent automatic mapping creation. This aligns with the JOIN clause UI flow where users configure the join properties before the mapping is created.

workspaces/ballerina/data-mapper/src/components/Diagram/Node/commons/DataMapperNode.ts (1)

383-391: Verify behavior change in array member field resolution.

The simplified logic now directly uses attributes.field?.member instead of a dedicated resolver method. Per the AI summary, this removes focused-member resolution during array field port creation, which could alter behavior when focusing is involved in array contexts.

Confirm that removing the focused-member resolution path doesn't break existing array-related focus scenarios or JOIN flows.

workspaces/ballerina/data-mapper/src/utils/model-utils.ts (1)

46-49: LGTM! Proper Query traversal implementation.

The addition of Query traversal follows the established visitor pattern correctly, with beginVisitQuery and endVisitQuery hooks properly called. The traversal is appropriately positioned after sub-mappings, maintaining the expected visitation order.

Also applies to: 85-88

workspaces/ballerina/ballerina-core/src/rpc-types/bi-diagram/index.ts (1)

149-149: LGTM! Dedicated completions endpoint for data mapper context.

The new getDataMapperCompletions method provides a data mapper-specific completions endpoint, which aligns with the PR objective to include correct cursor positioning for the expression bar. While it shares the same signature as getExpressionCompletions, having a dedicated endpoint allows for context-specific completion logic.

workspaces/ballerina/data-mapper/src/components/Diagram/Label/ExpressionLabelFactory.tsx (1)

38-43: LGTM! Appropriate conditional rendering for pending mappings.

The logic correctly handles pending mapping types:

  • MappingType.ArrayJoin returns an empty fragment (no inline label) since the JOIN configuration uses the side panel flow
  • Other pending types display MappingOptionsWidget for inline configuration
  • Non-pending mappings continue to render ExpressionLabelWidget as before

The empty fragment for ArrayJoin aligns with the user flow where JOIN clauses are configured via the Query Filters panel rather than inline labels.

workspaces/ballerina/data-mapper/src/components/DataMapper/Views/DataMapperView.ts (1)

20-20: Interface change successfully migrated with all consumers properly updated.

Verification confirms the interface change from sourceField?: string to sourceFields?: string[] is complete and correct:

  • Interface defined correctly in DataMapperView.ts
  • View instantiation in common-utils.ts properly creates the array via sourceFields: inputIds
  • Consumer in InputNode.ts correctly handles it with .flatMap(view => view.sourceFields)

No remaining singular property references found.

workspaces/ballerina/ballerina-core/src/rpc-types/bi-diagram/rpc-type.ts (1)

152-152: LGTM!

The new getDataMapperCompletions endpoint follows the same pattern as getExpressionCompletions and reuses the same request/response types, which promotes consistency and code reuse.

workspaces/ballerina/data-mapper/src/components/Diagram/utils/port-utils.ts (1)

26-37: LGTM!

The function signature extension to support SubMappingNode is well-implemented:

  • Uses a type union for flexibility
  • Branches cleanly on instanceof to compute the appropriate portId
  • Maintains backward compatibility for InputNode
workspaces/ballerina/data-mapper/src/visitors/IntermediateNodeInitVisitor.ts (1)

47-50: LGTM!

The new beginVisitQuery method follows the visitor pattern consistently and correctly instantiates a ClauseConnectorNode for query processing.

workspaces/ballerina/ballerina-extension/src/rpc-managers/bi-diagram/rpc-manager.ts (1)

856-867: LGTM!

The getDataMapperCompletions method implementation correctly mirrors the existing getExpressionCompletions pattern with appropriate error messaging specific to data mapper completions.

workspaces/ballerina/data-mapper/src/visitors/BaseVisitor.ts (1)

37-38: LGTM!

The new beginVisitQuery and endVisitQuery optional methods follow the established visitor pattern and are consistent with other visitor hooks in the interface.

workspaces/ballerina/ballerina-visualizer/src/views/BI/Forms/FormGeneratorNew/index.tsx (1)

444-458: LGTM!

The restructured completion request using ExpressionCompletionsRequest object is cleaner and more maintainable than passing individual parameters. The request correctly includes:

  • File path
  • Expression context with proper offsets
  • Completion context with trigger information
workspaces/ballerina/data-mapper/src/components/Diagram/Node/Input/InputNode.ts (1)

58-58: Breaking change from sourceField to sourceFields has been properly implemented.

Verification confirms:

  1. Interface updated: The View interface at workspaces/ballerina/data-mapper/src/components/DataMapper/Views/DataMapperView.ts line 20 correctly defines sourceFields?: string[] (plural, optional array).

  2. Code updated: The usage at InputNode.ts line 58 correctly calls view.sourceFields with flatMap, which appropriately handles the array structure and chains with .filter(Boolean) to handle undefined/null values.

  3. No legacy references: No remaining references to the old singular sourceField pattern were found in the Ballerina data-mapper codebase.

The optional property provides backward compatibility while supporting the new plural array structure.

workspaces/ballerina/data-mapper/src/components/DataMapper/SidePanel/QueryClauses/ClauseEditor.tsx (1)

49-83: JOIN-specific field labels and docs are consistent with the new clause semantics

The dynamic labels/documentation for name (Item Alias) and expression (Join With Collection) when clauseType === IntermediateClauseType.JOIN look consistent with the backend IntermediateClauseProps (where expression is the join collection and name is the item alias).

No issues from a behavior perspective; this should improve UX without impacting non-JOIN clauses.

workspaces/ballerina/data-mapper/src/components/Diagram/utils/modification-utils.ts (1)

153-177: expandArrayFn call matches new API and preserves existing behavior

Updating mapWithQuery to call:

expandArrayFn(context, [input], output, viewId);

is consistent with the new expandArrayFn(context, inputIds: string[], ...) signature. Passing [input] preserves the previous single-input semantics while allowing future multi-input expansion.

No issues here.

workspaces/ballerina/ballerina-visualizer/src/views/DataMapper/DataMapperView.tsx (2)

281-289: Passing targetLineRange to FormGeneratorNew correctly propagates source location

Wiring targetLineRange={viewState.codedata.lineRange} into FormGeneratorNew aligns with the updated DMFormProps and ensures forms have access to the underlying source location, which is useful for things like context-aware completions and navigation.

Given viewState.codedata is already required for RPC calls in this view, reusing its lineRange here is consistent.


717-722: Including query.inputs in the model signature is a sensible trigger for re-expansion

Updating getModelSignature to:

inputs: [...model.inputs.map(i => i.name), ...(model.query?.inputs || [])],

ensures that changes to query inputs (e.g., from JOIN/FROM clauses) participate in the signature comparison, so downstream logic will reprocess the expanded model when query inputs change.

This is a good, minimal way to keep the expanded model in sync without over-triggering.

workspaces/ballerina/ballerina-core/src/interfaces/data-mapper.ts (1)

56-63: Interface extensions for JOIN, focus roots, and form codedata are coherent and backward compatible

The additions in this file are internally consistent and align with how they’re consumed elsewhere in the PR:

  • IntermediateClauseType.JOIN = "join" matches the new JOIN clause flows (ClauseEditor, mapWithJoin, etc.).
  • IntermediateClauseProps now exposes lhsExpression?, rhsExpression?, and isOuter?, which map directly to the JOIN form fields and submit normalization.
  • ExpandedDMModel/DMModel gain optional focusInputRootMap (and DMModel.traversingRoot?), giving the diagram layer a place to track focus roots without impacting existing callers.
  • DMFormField.codedata? provides a hook for attaching source metadata to individual form fields, used by the new completion flows.

All new properties are optional, so existing consumers remain source- and binary-compatible.

Also applies to: 118-129, 131-144, 206-214, 260-272

workspaces/ballerina/data-mapper/src/components/Diagram/utils/common-utils.ts (1)

226-265: All call sites are correctly updated with array arguments—no migration needed

Verification confirms both callers of expandArrayFn are already passing arrays:

  1. modification-utils.ts:176: expandArrayFn(context, [input], output, viewId) — explicitly wraps single input in array
  2. QueryExprConnectorNodeWidget.tsx:76: expandArrayFn(context, mapping.inputs, mapping.output, lastView.targetField)mapping.inputs is already an array (type Mapping has inputs as array, confirmed by .join('_') usage throughout the codebase)

The function signature is consistent with both call sites. No runtime surprises expected.

workspaces/ballerina/data-mapper/src/components/Diagram/Node/ClauseConnector/ClauseConnectorNodeWidget.tsx (1)

35-41: Widget wiring and diagnostics behavior look consistent

The widget correctly wires intermediate ports, opens the clause panel via the store, and reuses DiagnosticWidget to route error clicks into the expression bar, mirroring existing connector widgets. Data‑test IDs and styling hooks align with the rest of the diagram.

Also applies to: 60-81

@madushajg madushajg requested a review from Copilot November 20, 2025 09:02
Copilot finished reviewing on behalf of madushajg November 20, 2025 09:05
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull Request Overview

This PR enhances the data mapper functionality with JOIN clause support for relational queries and improves expression bar completion capabilities. The changes introduce a new data mapper-specific completions API to provide better autocomplete support, extend query clauses to support JOIN operations with LHS/RHS expressions, and refactor the data flow to track multiple input sources.

  • Added JOIN clause type with dedicated UI components and expressions for join conditions
  • Introduced getDataMapperCompletions RPC API endpoint for enhanced expression editor autocomplete
  • Refactored input tracking from single sourceField to multiple sourceFields with focus root mapping

Reviewed Changes

Copilot reviewed 43 out of 43 changed files in this pull request and generated 18 comments.

Show a summary per file
File Description
IntermediateNodeInitVisitor.ts Added visitor method for Query nodes to initialize ClauseConnector nodes
BaseVisitor.ts Extended interface with Query traversal methods
model-utils.ts Added Query traversal logic to node traversal
DataMapperContext.ts Reordered constructor parameters for consistency
store.ts Added clauseToAdd state for managing JOIN clause creation
port-utils.ts Extended getInputPort to accept SubMappingNode
node-utils.ts Refactored findInputNode to use focusInputRootMap for improved input tracking
modification-utils.ts Added mapWithJoin function to handle JOIN mapping type
focus-positioning-utils.ts Added ClauseConnectorNode to intermediate node type checks
common-utils.ts Added ArrayJoin mapping type detection and changed expandArrayFn to accept multiple input IDs
useDiagramModel.ts Added query I/O to dependency array for model regeneration
InputOutputPortModel.ts Added handling for ArrayJoin mapping type
Node/index.ts Exported ClauseConnector components
DataMapperNode.ts Removed resolveArrayMemberField method (unused after focusedMemberId removal)
QueryOutputNode.ts Removed manual query input-to-output link creation
QueryExprConnectorNodeWidget.tsx Changed to pass multiple inputs to expandArrayFn
InputNode.ts Changed to use sourceFields array and removed focusedMemberId logic
ClauseConnector/index.ts New file exporting ClauseConnector components
ClauseConnectorNodeWidget.tsx New widget component for rendering clause connector nodes
ClauseConnectorNodeFactory.tsx New factory for creating ClauseConnector node widgets
ClauseConnectorNode.ts New node model for representing query clauses in the diagram
CreateLinkState.ts Added ClauseConnectorNode handling and removed query header port checks
DataMapperLink.ts Added ArrayJoin mapping type enum value
QueryExprLabelWidget.tsx Removed file (functionality moved to ClauseConnectorNode)
ExpressionLabelModel.ts Removed isQuery property
ExpressionLabelFactory.tsx Removed QueryExprLabelWidget rendering, added ArrayJoin handling
Diagram.tsx Registered ClauseConnectorNodeFactory and added ClauseConnectorNode to repositioning logic
Actions/utils.ts Added ClauseConnectorNode to intermediate nodes list
IONodesScrollCanvasAction.ts Added ClauseConnectorNode to repositioning logic
DataMapperView.ts Changed to use sourceFields array in View interface
ClausesPanel.tsx Added width increase, useEffect for clauseToAdd initialization
ClauseEditor.tsx Added JOIN clause support with LHS/RHS expression fields and dynamic labels
DataMapperEditor.tsx Added View type annotation and reordered context constructor parameters
DataMapperView.tsx Changed to use getDataMapperCompletions API and updated property handling
FormGeneratorNew/index.tsx Added isDataMapperEditor flag to conditionally use data mapper completions API
rpc-client.ts Added getDataMapperCompletions RPC method
utils.ts Added focusInputRootMap to expanded model and populated it during input processing
rpc-manager.ts Implemented getDataMapperCompletions handler
rpc-handler.ts Registered getDataMapperCompletions RPC endpoint
extended-language-client.ts Added getDataMapperCompletions method and renamed API constant
rpc-type.ts Added getDataMapperCompletions request type
bi-diagram/index.ts Added getDataMapperCompletions to API interface
data-mapper.ts Added JOIN clause type, LHS/RHS expression properties, removed focusedMemberId, added focusInputRootMap and codedata to form field

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

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 (2)
workspaces/ballerina/ballerina-visualizer/src/views/DataMapper/DataMapperView.tsx (2)

281-289: Passing targetLineRange into FormGeneratorNew aligns the editor state

Using targetLineRange={viewState.codedata.lineRange} gives the form/expression bar the precise range to work with, which should help cursor-aware features like completions behave correctly. If there are any flows where codedata.lineRange can be absent, consider a small guard or fallback to avoid runtime errors in those edge cases.


575-645: Data Mapper completion request now uses property-codedata and dedicated endpoint

The updated retrieveCompeletions logic looks sound and matches the stated objective:

  • It first resolves the specific property via getProperty, then derives startLine from property.codedata.lineRange (adjusted via updateLineRange and expressionOffsetRef), plus lineOffset/offset from calculateExpressionOffsets, giving the LS an accurate cursor position.
  • It switches to getDataMapperCompletions and enriches the context with both codedata: viewState.codedata and the resolved property, which should let the LS specialize completions for the Data Mapper expression bar.
  • The existing client-side filtering and caching behavior is preserved.

Two minor robustness nits you may optionally address:

  • Add a defensive check around property.codedata?.lineRange before calling updateLineRange, with a sensible fallback (e.g., viewState.codedata.lineRange) to avoid hard failures if the server ever returns a property without line info.
  • Rename the local let completions = await ... to something like lsCompletions to avoid shadowing the state-level completions variable and make the code easier to follow.
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 7bb63bd and 7d41d15.

📒 Files selected for processing (8)
  • workspaces/ballerina/ballerina-core/src/rpc-types/bi-diagram/index.ts (1 hunks)
  • workspaces/ballerina/ballerina-core/src/rpc-types/bi-diagram/rpc-type.ts (1 hunks)
  • workspaces/ballerina/ballerina-extension/src/core/extended-language-client.ts (3 hunks)
  • workspaces/ballerina/ballerina-extension/src/rpc-managers/bi-diagram/rpc-handler.ts (2 hunks)
  • workspaces/ballerina/ballerina-extension/src/rpc-managers/bi-diagram/rpc-manager.ts (2 hunks)
  • workspaces/ballerina/ballerina-rpc-client/src/rpc-clients/bi-diagram/rpc-client.ts (2 hunks)
  • workspaces/ballerina/ballerina-visualizer/src/views/BI/Forms/FormGeneratorNew/index.tsx (5 hunks)
  • workspaces/ballerina/ballerina-visualizer/src/views/DataMapper/DataMapperView.tsx (2 hunks)
🚧 Files skipped from review as they are similar to previous changes (3)
  • workspaces/ballerina/ballerina-core/src/rpc-types/bi-diagram/index.ts
  • workspaces/ballerina/ballerina-visualizer/src/views/BI/Forms/FormGeneratorNew/index.tsx
  • workspaces/ballerina/ballerina-extension/src/rpc-managers/bi-diagram/rpc-manager.ts
🧰 Additional context used
🧠 Learnings (1)
📚 Learning: 2025-11-10T15:05:11.309Z
Learnt from: madushajg
Repo: wso2/vscode-extensions PR: 868
File: workspaces/bi/bi-extension/src/utils.ts:224-242
Timestamp: 2025-11-10T15:05:11.309Z
Learning: The workspaces/bi/bi-extension and workspaces/ballerina/ballerina-extension are separate VS Code extensions that are packaged and distributed independently, so they cannot share code via imports and must maintain their own implementations of common utilities.

Applied to files:

  • workspaces/ballerina/ballerina-extension/src/core/extended-language-client.ts
🧬 Code graph analysis (5)
workspaces/ballerina/ballerina-extension/src/core/extended-language-client.ts (1)
workspaces/ballerina/ballerina-core/src/interfaces/extended-lang-client.ts (2)
  • ExpressionCompletionsRequest (1088-1095)
  • ExpressionCompletionsResponse (1112-1112)
workspaces/ballerina/ballerina-rpc-client/src/rpc-clients/bi-diagram/rpc-client.ts (4)
workspaces/ballerina/ballerina-core/src/interfaces/extended-lang-client.ts (2)
  • ExpressionCompletionsRequest (1088-1095)
  • ExpressionCompletionsResponse (1112-1112)
workspaces/ballerina/ballerina-extension/src/rpc-managers/bi-diagram/rpc-manager.ts (1)
  • getDataMapperCompletions (897-908)
workspaces/ballerina/ballerina-extension/src/core/extended-language-client.ts (1)
  • getDataMapperCompletions (1149-1151)
workspaces/ballerina/ballerina-core/src/rpc-types/bi-diagram/rpc-type.ts (1)
  • getDataMapperCompletions (155-155)
workspaces/ballerina/ballerina-visualizer/src/views/DataMapper/DataMapperView.tsx (1)
workspaces/ballerina/ballerina-visualizer/src/utils/bi.tsx (1)
  • updateLineRange (538-557)
workspaces/ballerina/ballerina-extension/src/rpc-managers/bi-diagram/rpc-handler.ts (5)
workspaces/ballerina/ballerina-extension/src/rpc-managers/bi-diagram/rpc-manager.ts (1)
  • getDataMapperCompletions (897-908)
workspaces/ballerina/ballerina-extension/src/core/extended-language-client.ts (1)
  • getDataMapperCompletions (1149-1151)
workspaces/ballerina/ballerina-core/src/rpc-types/bi-diagram/rpc-type.ts (1)
  • getDataMapperCompletions (155-155)
workspaces/ballerina/ballerina-rpc-client/src/rpc-clients/bi-diagram/rpc-client.ts (1)
  • getDataMapperCompletions (313-315)
workspaces/ballerina/ballerina-core/src/interfaces/extended-lang-client.ts (1)
  • ExpressionCompletionsRequest (1088-1095)
workspaces/ballerina/ballerina-core/src/rpc-types/bi-diagram/rpc-type.ts (4)
workspaces/ballerina/ballerina-extension/src/rpc-managers/bi-diagram/rpc-manager.ts (1)
  • getDataMapperCompletions (897-908)
workspaces/ballerina/ballerina-extension/src/core/extended-language-client.ts (1)
  • getDataMapperCompletions (1149-1151)
workspaces/ballerina/ballerina-rpc-client/src/rpc-clients/bi-diagram/rpc-client.ts (1)
  • getDataMapperCompletions (313-315)
workspaces/ballerina/ballerina-core/src/interfaces/extended-lang-client.ts (2)
  • ExpressionCompletionsRequest (1088-1095)
  • ExpressionCompletionsResponse (1112-1112)
🔇 Additional comments (4)
workspaces/ballerina/ballerina-core/src/rpc-types/bi-diagram/rpc-type.ts (1)

155-155: New Data Mapper completions RPC type looks consistent

getDataMapperCompletions mirrors getExpressionCompletions in both type parameters and prefix-based method path, so the core RPC surface is coherent.

workspaces/ballerina/ballerina-rpc-client/src/rpc-clients/bi-diagram/rpc-client.ts (1)

152-152: BiDiagramRpcClient plumbing for Data Mapper completions is correct

The new import and getDataMapperCompletions method are wired identically to getExpressionCompletions, delegating through the messenger with the correct RPC type and host. No functional issues spotted.

Also applies to: 313-315

workspaces/ballerina/ballerina-extension/src/rpc-managers/bi-diagram/rpc-handler.ts (1)

78-78: New handler registration cleanly wires Data Mapper completions

The added import and messenger.onRequest(getDataMapperCompletions, ...) line correctly forward ExpressionCompletionsRequest to rpcManger.getDataMapperCompletions, parallel to the existing expression completions handler.

Also applies to: 186-186

workspaces/ballerina/ballerina-extension/src/core/extended-language-client.ts (1)

357-357: Extended language client additions for Data Mapper completions are consistent

  • EXTENDED_APIS.BI_DATA_MAPPER_COMPLETIONS follows the existing expression editor naming pattern and is used by getDataMapperCompletions exactly like BI_EXPRESSION_COMPLETIONS is by getExpressionCompletions.
  • Updating DATA_MAPPER_PROPERTY to 'dataMapper/targetFieldPosition' is fine as long as the language server exposes this new endpoint; all existing callers will transparently use the new route.
  • The new getDataMapperCompletions method cleanly exposes the LS API without extra behavior.

No structural or typing issues detected here.

Also applies to: 373-373, 1149-1151

madushajg
madushajg previously approved these changes Nov 21, 2025
@madushajg madushajg merged commit c7443cd into wso2:main Nov 21, 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.

[Data Mapper] Improve completion support - frontend changes for expression bar

2 participants