-
Notifications
You must be signed in to change notification settings - Fork 59
[BI Data Mapper] Add support for the join clause #885
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
…ClauseConnector from the node index
…tioning in Diagram
…d DataMapperNodeModel
…eryExprLabelWidget references and clean up QueryOutputNode by removing unused query handling code
…el signature to include query inputs
…nputOutputPortModel
…eft outer equijoin
WalkthroughThis pull request adds JOIN clause support to the data mapper. Changes include a new JOIN enum member, updated data structures to track join expressions and root input focusing, new ClauseConnectorNode and related factories for UI rendering, support for ArrayJoin mapping type, and adjustments to node/port handling to accommodate multi-input field references and clause integration. Changes
Sequence Diagram(s)sequenceDiagram
participant User
participant ClauseEditor
participant Store as DMQueryClausesPanelStore
participant ClauseConnectorNode
participant LinkCreation
User->>ClauseEditor: Opens clause editor
ClauseEditor->>Store: Get clauseToAdd state
ClauseEditor->>ClauseEditor: Derive current clause from store or props
User->>ClauseEditor: Selects JOIN type
ClauseEditor->>ClauseEditor: Show lhsExpression & rhsExpression fields
User->>ClauseEditor: Fills join parameters
User->>ClauseEditor: Submit form
ClauseEditor->>Store: setClauseToAdd(undefined)
ClauseEditor->>Store: Submit clause to panel
Note over ClauseConnectorNode: Clause model created
ClauseConnectorNode->>ClauseConnectorNode: initPorts() - gather source inputs
ClauseConnectorNode->>ClauseConnectorNode: initLinks() - create mappings
ClauseConnectorNode->>LinkCreation: Create source→inPort links
LinkCreation->>LinkCreation: Wire selection listeners
ClauseConnectorNode->>LinkCreation: Create outPort→target link
Note over LinkCreation: Array inputs mapped to join operation
Estimated code review effort🎯 4 (Complex) | ⏱️ ~60 minutes Areas requiring extra attention:
Suggested labels
Suggested reviewers
Poem
Pre-merge checks and finishing touches❌ Failed checks (2 warnings)
✅ Passed checks (3 passed)
✨ Finishing touches
🧪 Generate unit tests (beta)
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. Comment |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 4
🧹 Nitpick comments (1)
workspaces/ballerina/data-mapper/src/components/DataMapper/SidePanel/QueryClauses/ClausesPanel.tsx (1)
84-84: Clarify the width change rationale.The panel width increased from 312 to 400 pixels. Consider documenting the reason for this change (e.g., accommodating wider clause content, improved UX).
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (36)
workspaces/ballerina/ballerina-core/src/interfaces/data-mapper.ts(4 hunks)workspaces/ballerina/ballerina-extension/src/rpc-managers/data-mapper/utils.ts(3 hunks)workspaces/ballerina/ballerina-visualizer/src/views/DataMapper/DataMapperView.tsx(1 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/ExpressionLabelModel.ts
- workspaces/ballerina/data-mapper/src/components/Diagram/Node/QueryOutput/QueryOutputNode.ts
- workspaces/ballerina/data-mapper/src/components/Diagram/Label/QueryExprLabelWidget.tsx
🧰 Additional context used
🧬 Code graph analysis (22)
workspaces/ballerina/data-mapper/src/components/Diagram/utils/port-utils.ts (1)
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)
workspaces/ballerina/data-mapper/src/components/Diagram/utils/modification-utils.ts (1)
mapWithJoin(179-202)
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/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/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/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/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/Actions/utils.ts (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/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/store/store.ts (1)
workspaces/ballerina/ballerina-core/src/interfaces/data-mapper.ts (1)
IntermediateClause(216-219)
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/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/utils/common-utils.ts (1)
workspaces/ballerina/data-mapper/src/utils/DataMapperContext/DataMapperContext.ts (1)
IDataMapperContext(21-35)
workspaces/ballerina/data-mapper/src/components/DataMapper/SidePanel/QueryClauses/ClauseEditor.tsx (3)
workspaces/ballerina/data-mapper/src/store/store.ts (1)
useDMQueryClausesPanelStore(171-180)workspaces/ballerina/ballerina-core/src/interfaces/bi.ts (1)
OptionProps(495-500)workspaces/ballerina/ballerina-core/src/interfaces/data-mapper.ts (4)
DMFormField(260-271)DMFormFieldValues(273-275)IntermediateClause(216-219)IntermediateClauseProps(206-214)
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/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/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/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/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)
🔇 Additional comments (33)
workspaces/ballerina/data-mapper/src/components/Diagram/hooks/useDiagramModel.ts (2)
50-50: Well-structured serialization for query IO tracking.The
queryIOsvariable correctly derives a string representation frommodel.query.inputsandmodel.query.output, following a pattern similar to the existingmappingsandsubMappingsserialization. This enables cache invalidation when query inputs or outputs change, which is essential for JOIN clause support.Verify that
model.query.outputis a primitive or string type (not a complex object) to ensure.toString()produces stable, meaningful cache keys rather than[object Object].
103-104: Correctly extends queryKey for JOIN support.Adding
subMappingsandqueryIOsto the React QueryqueryKeyarray ensures the diagram model refetches when subMappings or query IOs change. This aligns perfectly with the PR objective of adding JOIN clause support, as changes to query inputs/outputs will now properly trigger diagram updates.workspaces/ballerina/data-mapper/src/components/Diagram/Actions/utils.ts (2)
28-30: LGTM! ClauseConnectorNode properly classified.The addition of
ClauseConnectorNodeto the imports andINTERMEDIATE_NODESset correctly integrates the new node type into the diagram action system.
46-50: LGTM! INTERMEDIATE_NODES array updated correctly.The
ClauseConnectorNodeis properly added to theINTERMEDIATE_NODESarray, enabling it to be recognized byisIntermediateNode()checks throughout the codebase.workspaces/ballerina/data-mapper/src/components/Diagram/Link/DataMapperLink/DataMapperLink.ts (1)
27-35: LGTM! ArrayJoin mapping type added.The new
ArrayJoinenum member is properly added to support JOIN clause mappings. The naming follows the existing convention and integrates cleanly with the MappingType enum.workspaces/ballerina/data-mapper/src/components/Diagram/Node/Input/InputNode.ts (1)
57-60: LGTM! Correctly adapted to sourceFields array.The change properly handles the new
sourceFieldsarray by usingflatMapto flatten the array-of-arrays andfilter(Boolean)to remove falsy values. This maintains correct behavior for multi-input JOIN scenarios.workspaces/ballerina/data-mapper/src/utils/DataMapperContext/DataMapperContext.ts (2)
21-35: LGTM! Context interface extended with change tracking flag.The addition of
hasInputsOutputsChangedboolean property to theIDataMapperContextinterface is clean and enables tracking input/output changes for JOIN support.
37-54: LGTM! Constructor parameter added with safe default.The
hasInputsOutputsChangedparameter is properly added to the constructor with a default value offalse, preventing breaking changes for existing instantiations.workspaces/ballerina/data-mapper/src/components/Diagram/Label/ExpressionLabelFactory.tsx (1)
37-45: All verification checks passed—code changes are intentional and correct.The verification confirms:
- QueryExprLabelWidget removal is complete: No references exist anywhere in the codebase
- ArrayJoin empty rendering is intentional: ArrayJoin has special handling upstream (mapWithJoin is called explicitly in InputOutputPortModel.ts:79 when mapping type is ArrayJoin), indicating no widget/label should be displayed for this case
- MappingType.ArrayJoin is properly defined and consistently handled across the codebase (common-utils.ts returns it based on port naming conventions)
The rendering logic correctly routes:
- ArrayJoin → empty fragment (no label/options shown, handled separately elsewhere)
- Other pending mappings → MappingOptionsWidget
- Default → ExpressionLabelWidget
workspaces/ballerina/data-mapper/src/components/Diagram/Node/QueryExprConnector/QueryExprConnectorNodeWidget.tsx (1)
76-76: No backward compatibility issues identified.The change from
mapping.inputs[0]tomapping.inputsis properly supported byexpandArrayFn. The function acceptsinputIds: string[]and directly assigns it tosourceFieldswithout assuming array length, so both single-element arrays (existing behavior) and multi-element arrays (new JOIN behavior) work identically.workspaces/ballerina/data-mapper/src/components/Diagram/Node/commons/DataMapperNode.ts (1)
383-391: Verification inconclusive — request manual testing of array focusing behavior.Based on codebase search:
focusedMemberIdandresolveArrayMemberFieldare completely removed (no remaining references)- The simplification to direct
attributes.field?.memberaccess is correct in isolation- Array focus behavior is now handled via a different mechanism (
focusedFieldFQNs)However, without executing the actual test suite, I cannot confirm that focused array member selection still works correctly in all scenarios. The existing test at
dataMapper.spec.ts:430covers array mapping but may not specifically validate focused member behavior.workspaces/ballerina/data-mapper/src/components/DataMapper/Views/DataMapperView.ts (1)
18-23: All View consumers properly updated for breaking interface change.Verification confirms the breaking change from
sourceField?: stringtosourceFields?: string[]has been correctly implemented:
- View creation at
common-utils.ts:248-251assignssourceFields: inputIdswhereinputIdsis explicitly typed asstring[]- View consumption at
InputNode.ts:58correctly usesflatMap(view => view.sourceFields)for array handling- Initial View creation at
DataMapperEditor.tsx:153properly omits the optionalsourceFieldsproperty- No references to the old singular
sourceFieldproperty on View objects exist in the ballerina workspaceworkspaces/ballerina/data-mapper/src/components/Diagram/Node/index.ts (1)
28-28: LGTM!The export addition for ClauseConnector follows the existing pattern and properly extends the public API surface to include the new clause connector functionality.
workspaces/ballerina/data-mapper/src/utils/model-utils.ts (3)
19-19: LGTM!The Query import is necessary for the new traverseQuery functionality.
46-49: LGTM!The query traversal logic correctly uses optional chaining and follows the established pattern for visiting model elements.
85-88: LGTM!The traverseQuery function follows the same pattern as other traverse functions (traverseInputType, traverseOutputType, traverseSubMappingType) and correctly delegates to the visitor's beginVisitQuery and endVisitQuery methods.
workspaces/ballerina/ballerina-visualizer/src/views/DataMapper/DataMapperView.tsx (1)
717-717: LGTM!The signature calculation correctly extends the inputs array to include query-level inputs using optional chaining and appropriate fallback handling.
workspaces/ballerina/data-mapper/src/components/Diagram/utils/focus-positioning-utils.ts (2)
20-20: LGTM!The import addition is necessary for the updated intermediate node handling logic.
160-160: LGTM!The type union correctly includes ClauseConnectorNode alongside other intermediate connector types, following the established pattern for intermediate node resolution.
workspaces/ballerina/data-mapper/src/components/DataMapper/SidePanel/QueryClauses/ClausesPanel.tsx (1)
71-78: Verify the effect cleanup behavior.The cleanup function resets
clauseToAddtoundefinedon every render when dependencies change. This means ifclauses.lengthchanges whileclauseToAddis defined, it will reset the clause addition state, which might not be the intended behavior.Consider whether the cleanup should only run on component unmount:
useEffect(() => { if (clauseToAdd) { setAdding(clauses.length - 1); } return () => { setClauseToAdd(undefined); } }, [clauseToAdd]); // Remove clauses.length if it shouldn't reset on length changeworkspaces/ballerina/data-mapper/src/components/Diagram/Node/ClauseConnector/index.ts (1)
18-20: LGTM!The barrel export file follows the standard pattern and correctly re-exports the ClauseConnector components for centralized access.
workspaces/ballerina/data-mapper/src/components/Diagram/Diagram.tsx (3)
39-39: LGTM!The import addition enables ClauseConnectorNode integration in the diagram engine.
90-90: LGTM!The factory registration follows the established pattern and enables the diagram engine to create and render ClauseConnectorNode instances.
161-164: LGTM!The filter condition and type union correctly include ClauseConnectorNode, ensuring its position updates are handled alongside other connector node types.
workspaces/ballerina/data-mapper/src/components/Diagram/Port/model/InputOutputPortModel.ts (2)
23-23: LGTM!The import addition is necessary for the new ArrayJoin mapping type handling.
78-80: LGTM!The ArrayJoin handling correctly delegates to
mapWithJoinand returns early, preventing the defaultcreateNewMappingflow. This aligns with the PR objective of adding JOIN clause support by opening the query clauses panel instead of creating a direct mapping.workspaces/ballerina/data-mapper/src/components/Diagram/utils/port-utils.ts (1)
26-37: Typing update aligns with SubMappingNode usage.Allowing
SubMappingNodehere keeps the port resolution path consistent with the new clause connectors.workspaces/ballerina/data-mapper/src/components/Diagram/utils/modification-utils.ts (1)
176-203: JOIN helper integrates cleanly.
mapWithJoinwires the pending ArrayJoin flow into the clauses panel, so users get the dialog immediately with sensible defaults.workspaces/ballerina/data-mapper/src/visitors/BaseVisitor.ts (1)
19-38: Query visit hooks look good.The new optional callbacks extend the visitor contract without breaking implementers.
workspaces/ballerina/data-mapper/src/visitors/IntermediateNodeInitVisitor.ts (1)
18-50: Clause connector initialization is consistent.Creating a
ClauseConnectorNodeduring query traversal keeps intermediate nodes in sync with the new JOIN UI.workspaces/ballerina/data-mapper/src/components/Diagram/LinkState/CreateLinkState.ts (1)
33-188: Link-state tweaks accommodate ClauseConnector nodes.Forwarding intermediate ports to
ClauseConnectorNode.targetMappedPortensures JOIN connectors behave like existing link connectors.workspaces/ballerina/ballerina-extension/src/rpc-managers/data-mapper/utils.ts (1)
456-611: Focus root tracking fits the new JOIN UX.Populating
focusInputRootMapwhile traversing arrays gives the front-end enough context to highlight source roots after JOIN setup.workspaces/ballerina/data-mapper/src/components/DataMapper/SidePanel/QueryClauses/ClauseEditor.tsx (1)
23-164: JOIN form fields are thoughtfully added.Including LHS/RHS expressions plus a default alias makes the JOIN workflow ready for immediate user input.
Purpose
Summary by CodeRabbit
Release Notes
New Features
Improvements